merge the formfield patch from ooo-build
[ooovba.git] / applied_patches / 0006-cws-koheidatapilot03-sc.diff
blob2427c76b98e81adfa978f80a2caa34129fa3c2eb
1 diff --git sc/inc/AccessibleFilterMenu.hxx sc/inc/AccessibleFilterMenu.hxx
2 new file mode 100644
3 index 0000000..2495b4c
4 --- /dev/null
5 +++ sc/inc/AccessibleFilterMenu.hxx
6 @@ -0,0 +1,191 @@
7 +/*************************************************************************
8 + *
9 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10 + *
11 + * Copyright 2008 by Sun Microsystems, Inc.
12 + *
13 + * OpenOffice.org - a multi-platform office productivity suite
14 + *
15 + * $RCSfile: AccessibleDataPilotControl.hxx,v $
16 + * $Revision: 1.6 $
17 + *
18 + * This file is part of OpenOffice.org.
19 + *
20 + * OpenOffice.org is free software: you can redistribute it and/or modify
21 + * it under the terms of the GNU Lesser General Public License version 3
22 + * only, as published by the Free Software Foundation.
23 + *
24 + * OpenOffice.org is distributed in the hope that it will be useful,
25 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 + * GNU Lesser General Public License version 3 for more details
28 + * (a copy is included in the LICENSE file that accompanied this code).
29 + *
30 + * You should have received a copy of the GNU Lesser General Public License
31 + * version 3 along with OpenOffice.org. If not, see
32 + * <http://www.openoffice.org/license.html>
33 + * for a copy of the LGPLv3 License.
34 + *
35 + ************************************************************************/
37 +#ifndef SC_ACCESSIBLEFILTERMENU_HXX
38 +#define SC_ACCESSIBLEFILTERMENU_HXX
40 +#include "AccessibleContextBase.hxx"
41 +#include "cppuhelper/implbase1.hxx"
43 +#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
44 +#include <com/sun/star/accessibility/XAccessibleText.hpp>
45 +#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
46 +#include <com/sun/star/accessibility/TextSegment.hpp>
48 +#include <vector>
50 +namespace com { namespace sun { namespace star {
51 + namespace accessibility {
52 + struct AccessibleEventObject;
53 + }
54 +}}}
56 +class ScDocument;
57 +class ScMenuFloatingWindow;
59 +typedef ::cppu::ImplHelper1<
60 + ::com::sun::star::accessibility::XAccessibleSelection > ScAccessibleFilterMenu_BASE;
62 +class ScAccessibleFilterMenu :
63 + public ScAccessibleContextBase,
64 + public ScAccessibleFilterMenu_BASE
66 +public:
67 + explicit ScAccessibleFilterMenu(
68 + const ::com::sun::star::uno::Reference<
69 + ::com::sun::star::accessibility::XAccessible>& rxParent,
70 + ScMenuFloatingWindow* pWin, const ::rtl::OUString& rName, size_t nMenuPos, ScDocument* pDoc);
71 + virtual ~ScAccessibleFilterMenu();
73 + // XAccessibleComponent
75 + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
76 + SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& rPoint )
77 + throw (::com::sun::star::uno::RuntimeException);
79 + virtual sal_Bool SAL_CALL isVisible()
80 + throw (::com::sun::star::uno::RuntimeException);
82 + virtual void SAL_CALL grabFocus()
83 + throw (::com::sun::star::uno::RuntimeException);
85 + virtual sal_Int32 SAL_CALL getForeground()
86 + throw (::com::sun::star::uno::RuntimeException);
88 + virtual sal_Int32 SAL_CALL getBackground()
89 + throw (::com::sun::star::uno::RuntimeException);
91 + // XAccessibleContext
93 + virtual ::rtl::OUString SAL_CALL getAccessibleName()
94 + throw (::com::sun::star::uno::RuntimeException);
96 + virtual sal_Int32 SAL_CALL getAccessibleChildCount()
97 + throw (::com::sun::star::uno::RuntimeException);
99 + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
100 + getAccessibleChild(sal_Int32 nIndex)
101 + throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException);
103 + virtual ::com::sun::star::uno::Reference<
104 + ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
105 + getAccessibleStateSet()
106 + throw (::com::sun::star::uno::RuntimeException);
108 + virtual ::rtl::OUString SAL_CALL getImplementationName()
109 + throw (::com::sun::star::uno::RuntimeException);
111 + // XAccessibleEventBroadcaster
113 + virtual void SAL_CALL
114 + addEventListener(
115 + const ::com::sun::star::uno::Reference<
116 + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
117 + throw (com::sun::star::uno::RuntimeException);
119 + // Remove an existing event listener.
120 + virtual void SAL_CALL
121 + removeEventListener(
122 + const ::com::sun::star::uno::Reference<
123 + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
124 + throw (com::sun::star::uno::RuntimeException);
126 + // XAccessibleSelection
128 + virtual void SAL_CALL selectAccessibleChild(sal_Int32 nChildIndex)
129 + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
131 + virtual sal_Bool SAL_CALL isAccessibleChildSelected(sal_Int32 nChildIndex)
132 + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
134 + virtual void SAL_CALL clearAccessibleSelection()
135 + throw (::com::sun::star::uno::RuntimeException);
137 + virtual void SAL_CALL selectAllAccessibleChildren()
138 + throw (::com::sun::star::uno::RuntimeException);
140 + virtual ::sal_Int32 SAL_CALL getSelectedAccessibleChildCount()
141 + throw (::com::sun::star::uno::RuntimeException);
143 + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
144 + getSelectedAccessibleChild(sal_Int32 nChildIndex)
145 + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
147 + virtual void SAL_CALL deselectAccessibleChild(sal_Int32 nChildIndex)
148 + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
150 + // XInterface
152 + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
153 + ::com::sun::star::uno::Type const & rType )
154 + throw (::com::sun::star::uno::RuntimeException);
156 + virtual void SAL_CALL acquire() throw ();
157 + virtual void SAL_CALL release() throw ();
159 + // XTypeProvider
161 + virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL getImplementationId()
162 + throw (::com::sun::star::uno::RuntimeException);
164 + // non-UNO methods
166 + void appendMenuItem(const ::rtl::OUString& rName, bool bEnabled, size_t nMenuPos);
167 + void setMenuPos(size_t nMenuPos);
168 + void setEnabled(bool bEnabled);
170 +protected:
172 + sal_Int32 getMenuItemCount() const;
174 + virtual Rectangle GetBoundingBoxOnScreen() const
175 + throw (::com::sun::star::uno::RuntimeException);
177 + virtual Rectangle GetBoundingBox() const
178 + throw (::com::sun::star::uno::RuntimeException);
180 +private:
181 + bool isSelected() const;
182 + bool isFocused() const;
184 + void updateStates();
186 +private:
187 + ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > > maMenuItems;
188 + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > mxStateSet;
190 + size_t mnMenuPos;
191 + ScMenuFloatingWindow* mpWindow;
192 + ScDocument* mpDoc;
194 + bool mbEnabled:1;
197 +#endif
198 diff --git sc/inc/AccessibleFilterMenuItem.hxx sc/inc/AccessibleFilterMenuItem.hxx
199 new file mode 100644
200 index 0000000..b9a3485
201 --- /dev/null
202 +++ sc/inc/AccessibleFilterMenuItem.hxx
203 @@ -0,0 +1,124 @@
204 +/*************************************************************************
206 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
207 + *
208 + * Copyright 2008 by Sun Microsystems, Inc.
210 + * OpenOffice.org - a multi-platform office productivity suite
212 + * $RCSfile: AccessibleDataPilotControl.hxx,v $
213 + * $Revision: 1.6 $
215 + * This file is part of OpenOffice.org.
217 + * OpenOffice.org is free software: you can redistribute it and/or modify
218 + * it under the terms of the GNU Lesser General Public License version 3
219 + * only, as published by the Free Software Foundation.
221 + * OpenOffice.org is distributed in the hope that it will be useful,
222 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
223 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
224 + * GNU Lesser General Public License version 3 for more details
225 + * (a copy is included in the LICENSE file that accompanied this code).
227 + * You should have received a copy of the GNU Lesser General Public License
228 + * version 3 along with OpenOffice.org. If not, see
229 + * <http://www.openoffice.org/license.html>
230 + * for a copy of the LGPLv3 License.
232 + ************************************************************************/
234 +#ifndef SC_ACCESSIBLEFILTERMENUITEM_HXX
235 +#define SC_ACCESSIBLEFILTERMENUITEM_HXX
237 +#include "AccessibleContextBase.hxx"
238 +#include "cppuhelper/implbase1.hxx"
240 +#include <com/sun/star/accessibility/XAccessibleAction.hpp>
242 +class ScMenuFloatingWindow;
244 +typedef ::cppu::ImplHelper1<
245 + ::com::sun::star::accessibility::XAccessibleAction > ScAccessibleFilterMenuItem_BASE;
247 +class ScAccessibleFilterMenuItem :
248 + public ScAccessibleContextBase,
249 + public ScAccessibleFilterMenuItem_BASE
251 +public:
252 + explicit ScAccessibleFilterMenuItem(
253 + const ::com::sun::star::uno::Reference<
254 + ::com::sun::star::accessibility::XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const ::rtl::OUString& rName, size_t nMenuPos);
256 + virtual ~ScAccessibleFilterMenuItem();
258 + // XAccessibleContext
260 + virtual sal_Int32 SAL_CALL getAccessibleChildCount()
261 + throw (::com::sun::star::uno::RuntimeException);
263 + virtual ::com::sun::star::uno::Reference<
264 + ::com::sun::star::accessibility::XAccessible > SAL_CALL
265 + getAccessibleChild(sal_Int32 nIndex)
266 + throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException);
268 + virtual ::com::sun::star::uno::Reference<
269 + ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
270 + getAccessibleStateSet()
271 + throw (::com::sun::star::uno::RuntimeException);
273 + virtual ::rtl::OUString SAL_CALL getImplementationName()
274 + throw (::com::sun::star::uno::RuntimeException);
276 + // XAccessibleAction
278 + virtual ::sal_Int32 SAL_CALL getAccessibleActionCount()
279 + throw (::com::sun::star::uno::RuntimeException);
281 + virtual ::sal_Bool SAL_CALL doAccessibleAction(sal_Int32 nIndex)
282 + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
284 + virtual ::rtl::OUString SAL_CALL getAccessibleActionDescription(sal_Int32 nIndex)
285 + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
287 + virtual ::com::sun::star::uno::Reference<
288 + ::com::sun::star::accessibility::XAccessibleKeyBinding > SAL_CALL
289 + getAccessibleActionKeyBinding(sal_Int32 nIndex)
290 + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
292 + // XInterface
294 + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
295 + ::com::sun::star::uno::Type const & rType )
296 + throw (::com::sun::star::uno::RuntimeException);
298 + virtual void SAL_CALL acquire() throw ();
299 + virtual void SAL_CALL release() throw ();
301 + // Non-UNO Methods
303 + void setEnabled(bool bEnabled);
305 +protected:
307 + virtual Rectangle GetBoundingBoxOnScreen() const
308 + throw (::com::sun::star::uno::RuntimeException);
310 + virtual Rectangle GetBoundingBox() const
311 + throw (::com::sun::star::uno::RuntimeException);
313 +private:
314 + bool isSelected() const;
315 + bool isFocused() const;
316 + void updateStateSet();
318 +private:
319 + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > mxStateSet;
321 + ScMenuFloatingWindow* mpWindow;
322 + ::rtl::OUString maName;
323 + size_t mnMenuPos;
324 + bool mbEnabled;
327 +#endif
328 diff --git sc/inc/AccessibleFilterTopWindow.hxx sc/inc/AccessibleFilterTopWindow.hxx
329 new file mode 100644
330 index 0000000..c13c494
331 --- /dev/null
332 +++ sc/inc/AccessibleFilterTopWindow.hxx
333 @@ -0,0 +1,104 @@
334 +/*************************************************************************
336 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
337 + *
338 + * Copyright 2008 by Sun Microsystems, Inc.
340 + * OpenOffice.org - a multi-platform office productivity suite
342 + * $RCSfile: AccessibleDataPilotControl.hxx,v $
343 + * $Revision: 1.6 $
345 + * This file is part of OpenOffice.org.
347 + * OpenOffice.org is free software: you can redistribute it and/or modify
348 + * it under the terms of the GNU Lesser General Public License version 3
349 + * only, as published by the Free Software Foundation.
351 + * OpenOffice.org is distributed in the hope that it will be useful,
352 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
353 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
354 + * GNU Lesser General Public License version 3 for more details
355 + * (a copy is included in the LICENSE file that accompanied this code).
357 + * You should have received a copy of the GNU Lesser General Public License
358 + * version 3 along with OpenOffice.org. If not, see
359 + * <http://www.openoffice.org/license.html>
360 + * for a copy of the LGPLv3 License.
362 + ************************************************************************/
364 +#ifndef SC_ACCESSIBLEFILTERTOPWINDOW_HXX
365 +#define SC_ACCESSIBLEFILTERTOPWINDOW_HXX
367 +//#include "AccessibleContextBase.hxx"
368 +#include "AccessibleFilterMenu.hxx"
369 +#include "cppuhelper/implbase1.hxx"
371 +class ScDPFieldPopupWindow;
372 +class ScDocument;
374 +class ScAccessibleFilterTopWindow : public ScAccessibleFilterMenu
376 +public:
377 + ScAccessibleFilterTopWindow(
378 + const ::com::sun::star::uno::Reference<
379 + ::com::sun::star::accessibility::XAccessible>& rxParent,
380 + ScDPFieldPopupWindow* pWin, const ::rtl::OUString& rName, ScDocument* pDoc);
381 + virtual ~ScAccessibleFilterTopWindow();
383 + // XAccessibleContext
385 + virtual sal_Int32 SAL_CALL getAccessibleChildCount()
386 + throw (::com::sun::star::uno::RuntimeException);
388 + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
389 + getAccessibleChild(sal_Int32 nIndex)
390 + throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException);
392 + virtual ::rtl::OUString SAL_CALL getImplementationName()
393 + throw (::com::sun::star::uno::RuntimeException);
395 + // Non-UNO Methods
397 + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
398 + getAccessibleChildMenu();
400 + enum ChildControlType {
401 + LISTBOX, TOGGLE_ALL, SINGLE_ON_BTN, SINGLE_OFF_BTN, OK_BTN, CANCEL_BTN
402 + };
403 + void setAccessibleChild(
404 + const ::com::sun::star::uno::Reference<
405 + ::com::sun::star::accessibility::XAccessible >& rAccessible,
406 + ChildControlType eType);
408 +private:
409 + /** The top menu part */
410 + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
411 + mxAccMenu;
413 + /** check list box for field member visibility */
414 + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
415 + mxAccListBox;
417 + /** check box for toggling all field member's visibility. */
418 + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
419 + mxAccToggleAll;
421 + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
422 + mxAccSingleOnBtn;
424 + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
425 + mxAccSingleOffBtn;
427 + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
428 + mxAccOkBtn;
430 + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
431 + mxAccCancelBtn;
433 + ScDPFieldPopupWindow* mpWindow;
434 + ScDocument* mpDoc;
437 +#endif
438 diff --git sc/inc/AccessibleGlobal.hxx sc/inc/AccessibleGlobal.hxx
439 new file mode 100644
440 index 0000000..5e75bf4
441 --- /dev/null
442 +++ sc/inc/AccessibleGlobal.hxx
443 @@ -0,0 +1,72 @@
444 +/*************************************************************************
446 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
447 + *
448 + * Copyright 2008 by Sun Microsystems, Inc.
450 + * OpenOffice.org - a multi-platform office productivity suite
452 + * $RCSfile: AccessibleDataPilotControl.hxx,v $
453 + * $Revision: 1.6 $
455 + * This file is part of OpenOffice.org.
457 + * OpenOffice.org is free software: you can redistribute it and/or modify
458 + * it under the terms of the GNU Lesser General Public License version 3
459 + * only, as published by the Free Software Foundation.
461 + * OpenOffice.org is distributed in the hope that it will be useful,
462 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
463 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
464 + * GNU Lesser General Public License version 3 for more details
465 + * (a copy is included in the LICENSE file that accompanied this code).
467 + * You should have received a copy of the GNU Lesser General Public License
468 + * version 3 along with OpenOffice.org. If not, see
469 + * <http://www.openoffice.org/license.html>
470 + * for a copy of the LGPLv3 License.
472 + ************************************************************************/
474 +#ifndef SC_ACCESSIBLEGLOBAL_HXX
475 +#define SC_ACCESSIBLEGLOBAL_HXX
477 +#include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
478 +#include "cppuhelper/implbase1.hxx"
480 +#include <set>
482 +/**
483 + * Generic XAccessibleStateSet implementation.
484 + */
485 +class ScAccessibleStateSet : public ::cppu::WeakImplHelper1< ::com::sun::star::accessibility::XAccessibleStateSet >
487 +public:
488 + ScAccessibleStateSet();
489 + virtual ~ScAccessibleStateSet();
491 + // XAccessibleStateSet
493 + virtual ::sal_Bool SAL_CALL isEmpty()
494 + throw (::com::sun::star::uno::RuntimeException);
496 + virtual ::sal_Bool SAL_CALL contains(sal_Int16 nState)
497 + throw (::com::sun::star::uno::RuntimeException);
499 + virtual ::sal_Bool SAL_CALL containsAll(
500 + const ::com::sun::star::uno::Sequence<sal_Int16>& aStateSet)
501 + throw (::com::sun::star::uno::RuntimeException);
503 + virtual ::com::sun::star::uno::Sequence<sal_Int16> SAL_CALL getStates()
504 + throw (::com::sun::star::uno::RuntimeException);
506 + // Non-UNO Methods
508 + void insert(sal_Int16 nState);
509 + void clear();
511 +private:
512 + ::std::set<sal_Int16> maStates;
515 +#endif
516 diff --git sc/inc/attrib.hxx sc/inc/attrib.hxx
517 index 72a4769..25caeb1 100644
518 --- sc/inc/attrib.hxx
519 +++ sc/inc/attrib.hxx
520 @@ -42,13 +42,16 @@
522 // Flags fuer durch Merge verdeckte Zellen
523 // und Control fuer Auto-Filter
524 -#define SC_MF_HOR 1
525 -#define SC_MF_VER 2
526 -#define SC_MF_AUTO 4
527 -#define SC_MF_BUTTON 8
528 -#define SC_MF_SCENARIO 16
529 +#define SC_MF_HOR 0x0001
530 +#define SC_MF_VER 0x0002
531 +#define SC_MF_AUTO 0x0004 /// autofilter arrow
532 +#define SC_MF_BUTTON 0x0008 /// field button for datapilot
533 +#define SC_MF_SCENARIO 0x0010
534 +#define SC_MF_BUTTON_POPUP 0x0020 /// dp button with popup arrow
535 +#define SC_MF_HIDDEN_MEMBER 0x0040 /// dp field button with presence of hidden member
536 +#define SC_MF_DP_TABLE 0x0080 /// dp table output
538 -#define SC_MF_ALL 31
539 +#define SC_MF_ALL 0x00FF
542 class EditTextObject;
543 @@ -103,6 +106,7 @@ public:
545 BOOL HasAutoFilter() const { return ( GetValue() & SC_MF_AUTO ) != 0; }
546 BOOL HasButton() const { return ( GetValue() & SC_MF_BUTTON ) != 0; }
547 + bool HasDPTable() const { return ( GetValue() & SC_MF_DP_TABLE ) != 0; }
549 BOOL IsScenario() const { return ( GetValue() & SC_MF_SCENARIO ) != 0; }
551 diff --git sc/inc/column.hxx sc/inc/column.hxx
552 index fd2473b..ec87323 100644
553 --- sc/inc/column.hxx
554 +++ sc/inc/column.hxx
555 @@ -162,7 +162,7 @@ public:
556 SCSIZE GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const;
557 BOOL HasDataAt(SCROW nRow) const;
558 BOOL HasVisibleDataAt(SCROW nRow) const;
559 -//UNUSED2009-05 SCROW GetFirstDataPos() const;
560 + SCROW GetFirstDataPos() const;
561 SCROW GetLastDataPos() const;
562 SCROW GetLastVisDataPos(BOOL bNotes) const; // ohne Broadcaster
563 SCROW GetFirstVisDataPos(BOOL bNotes) const;
564 diff --git sc/inc/document.hxx sc/inc/document.hxx
565 index f0f9189..14d606e 100644
566 --- sc/inc/document.hxx
567 +++ sc/inc/document.hxx
568 @@ -859,6 +859,8 @@ public:
570 USHORT GetErrCode( const ScAddress& ) const;
572 + bool ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const;
574 void GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
575 SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld );
576 SC_DLLPUBLIC BOOL GetCellArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const;
577 diff --git sc/inc/dpgroup.hxx sc/inc/dpgroup.hxx
578 index f81ff66..07be632 100644
579 --- sc/inc/dpgroup.hxx
580 +++ sc/inc/dpgroup.hxx
581 @@ -33,6 +33,7 @@
583 #include <vector>
584 #include <hash_set>
585 +#include <boost/shared_ptr.hpp>
587 #include "dptabdat.hxx"
588 #include "scdllapi.h"
589 @@ -182,7 +183,7 @@ class ScDPGroupTableData : public ScDPTableData
591 typedef ::std::hash_set< ::rtl::OUString, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > StringHashSet;
593 - ScDPTableData* pSourceData;
594 + ::boost::shared_ptr<ScDPTableData> pSourceData;
595 long nSourceCount;
596 ScDPGroupDimensionVec aGroups;
597 ScDPNumGroupDimension* pNumGroups; // array[nSourceCount]
598 @@ -200,7 +201,7 @@ class ScDPGroupTableData : public ScDPTableData
600 public:
601 // takes ownership of pSource
602 - ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDocument );
603 + ScDPGroupTableData( const ::boost::shared_ptr<ScDPTableData>& pSource, ScDocument* pDocument );
604 virtual ~ScDPGroupTableData();
606 void AddGroupDimension( const ScDPGroupDimension& rGroup );
607 diff --git sc/inc/dpobject.hxx sc/inc/dpobject.hxx
608 index e968007..d7fbbfe 100644
609 --- sc/inc/dpobject.hxx
610 +++ sc/inc/dpobject.hxx
611 @@ -36,8 +36,11 @@
612 #include "address.hxx"
613 #include "collect.hxx"
614 #include "dpoutput.hxx"
615 +#include "pivot.hxx"
616 #include <com/sun/star/sheet/XDimensionsSupplier.hpp>
618 +#include <boost/shared_ptr.hpp>
620 //------------------------------------------------------------------
622 namespace com { namespace sun { namespace star { namespace sheet {
623 @@ -64,6 +67,7 @@ class ScStrCollection;
624 class TypedScStrCollection;
625 struct PivotField;
626 class ScDPCacheTable;
627 +class ScDPTableData;
629 struct ScDPServiceDesc
631 @@ -99,15 +103,19 @@ private:
632 ScSheetSourceDesc* pSheetDesc; // for sheet data
633 ScImportSourceDesc* pImpDesc; // for database data
634 ScDPServiceDesc* pServDesc; // for external service
635 + ::boost::shared_ptr<ScDPTableData> mpTableData;
636 // cached data
637 com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier> xSource;
638 ScDPOutput* pOutput;
639 BOOL bSettingsChanged;
640 BOOL bAlive; // FALSE if only used to hold settings
641 + sal_uInt16 mnAutoFormatIndex;
642 BOOL bAllowMove;
643 long nHeaderRows; // page fields plus filter button
644 + bool mbHeaderLayout; // TRUE : grid, FALSE : standard
647 + SC_DLLPRIVATE ScDPTableData* GetTableData();
648 SC_DLLPRIVATE void CreateObjects();
649 SC_DLLPRIVATE void CreateOutput();
651 @@ -135,6 +143,12 @@ public:
652 void SetOutRange(const ScRange& rRange);
653 const ScRange& GetOutRange() const { return aOutRange; }
655 + void SetAutoFormatIndex (const sal_uInt16 nIndex);
656 + sal_uInt16 GetAutoFormatIndex() const;
658 + void SetHeaderLayout(bool bUseGrid);
659 + bool GetHeaderLayout() const;
661 void SetSheetDesc(const ScSheetSourceDesc& rDesc);
662 void SetImportDesc(const ScImportSourceDesc& rDesc);
663 void SetServiceData(const ScDPServiceDesc& rDesc);
664 @@ -157,7 +171,14 @@ public:
665 void SetTag(const String& rNew);
666 const String& GetTag() const { return aTableTag; }
668 - BOOL IsDimNameInUse( const String& rName ) const;
669 + /**
670 + * Data description cell displays the description of a data dimension if
671 + * and only if there is only one data dimension. It's usually located at
672 + * the upper-left corner of the table output.
673 + */
674 + bool IsDataDescriptionCell(const ScAddress& rPos);
676 + bool IsDimNameInUse(const ::rtl::OUString& rName) const;
677 String GetDimName( long nDim, BOOL& rIsDataLayout );
678 BOOL IsDuplicated( long nDim );
679 long GetDimCount();
680 @@ -190,16 +211,10 @@ public:
681 sal_Int32 GetUsedHierarchy( sal_Int32 nDim );
683 BOOL GetMembersNA( sal_Int32 nDim, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers );
684 - BOOL GetMembers( sal_Int32 nDim,
685 - com::sun::star::uno::Sequence< rtl::OUString >& rMembers,
686 - com::sun::star::uno::Sequence< sal_Bool >* pVisible = 0,
687 - com::sun::star::uno::Sequence< sal_Bool >* pShowDet = 0 );
689 BOOL GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers );
690 - BOOL GetMembers( sal_Int32 nDim, sal_Int32 nHier,
691 - com::sun::star::uno::Sequence< rtl::OUString >& rMembers,
692 - com::sun::star::uno::Sequence< sal_Bool >* pVisible = 0,
693 - com::sun::star::uno::Sequence< sal_Bool >* pShowDet = 0 );
695 + bool GetMemberNames( sal_Int32 nDim, ::com::sun::star::uno::Sequence< ::rtl::OUString >& rNames );
696 + bool GetMembers( sal_Int32 nDim, sal_Int32 nHier, ::std::vector<ScDPLabelData::Member>& rMembers );
698 void UpdateReference( UpdateRefMode eUpdateRefMode,
699 const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
700 @@ -221,6 +236,8 @@ public:
701 // (button attribute must be present)
702 void RefreshAfterLoad();
704 + void BuildAllDimensionMembers();
706 static BOOL HasRegisteredSources();
707 static com::sun::star::uno::Sequence<rtl::OUString> GetRegisteredSources();
708 static com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier>
709 @@ -291,6 +308,11 @@ public:
711 ScSimpleSharedString& GetSharedString();
713 + void FreeTable(ScDPObject* pDPObj);
714 + SC_DLLPUBLIC bool InsertNewTable(ScDPObject* pDPObj);
716 + bool HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const;
718 ScDPCacheCell* getCacheCellFromPool(const ScDPCacheCell& rCell);
719 void clearCacheCellPool();
721 diff --git sc/inc/dpoutput.hxx sc/inc/dpoutput.hxx
722 index 4a071de..c28f901 100644
723 --- sc/inc/dpoutput.hxx
724 +++ sc/inc/dpoutput.hxx
725 @@ -94,6 +94,7 @@ private:
726 com::sun::star::uno::Sequence<
727 com::sun::star::sheet::DataResult> > aData;
728 BOOL bResultsError;
729 + bool mbHasDataLayout;
730 String aDataDescription;
732 // Number format related parameters
733 @@ -109,6 +110,7 @@ private:
734 long nColCount;
735 long nRowCount;
736 long nHeaderSize;
737 + bool mbHeaderLayout; // TRUE : grid, FALSE : standard
738 SCCOL nTabStartCol;
739 SCROW nTabStartRow;
740 SCCOL nMemberStartCol;
741 @@ -123,8 +125,8 @@ private:
742 void HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
743 const com::sun::star::sheet::MemberResult& rData,
744 BOOL bColHeader, long nLevel );
745 - void FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption,
746 - BOOL bFrame = TRUE );
747 + void FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption,
748 + bool bInTable, bool bPopup, bool bHasHiddenMember );
749 void CalcSizes();
751 /** Query which sub-area of the table the cell is in. See
752 @@ -162,6 +164,9 @@ public:
754 void GetMemberResultNames( ScStrCollection& rNames, long nDimension );
756 + void SetHeaderLayout(bool bUseGrid);
757 + bool GetHeaderLayout() const;
759 static void GetDataDimensionNames( String& rSourceName, String& rGivenName,
760 const com::sun::star::uno::Reference<
761 com::sun::star::uno::XInterface>& xDim );
762 diff --git sc/inc/dpoutputgeometry.hxx sc/inc/dpoutputgeometry.hxx
763 new file mode 100644
764 index 0000000..d423d18
765 --- /dev/null
766 +++ sc/inc/dpoutputgeometry.hxx
767 @@ -0,0 +1,80 @@
768 +/*************************************************************************
770 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
771 + *
772 + * Copyright 2008 by Sun Microsystems, Inc.
774 + * OpenOffice.org - a multi-platform office productivity suite
776 + * $RCSfile: xmldpimp.cxx,v $
777 + * $Revision: 1.27.134.1 $
779 + * This file is part of OpenOffice.org.
781 + * OpenOffice.org is free software: you can redistribute it and/or modify
782 + * it under the terms of the GNU Lesser General Public License version 3
783 + * only, as published by the Free Software Foundation.
785 + * OpenOffice.org is distributed in the hope that it will be useful,
786 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
787 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
788 + * GNU Lesser General Public License version 3 for more details
789 + * (a copy is included in the LICENSE file that accompanied this code).
791 + * You should have received a copy of the GNU Lesser General Public License
792 + * version 3 along with OpenOffice.org. If not, see
793 + * <http://www.openoffice.org/license.html>
794 + * for a copy of the LGPLv3 License.
796 + ************************************************************************/
798 +#ifndef SC_DPOUTPUTGEOMETRY_HXX
799 +#define SC_DPOUTPUTGEOMETRY_HXX
801 +#include "address.hxx"
802 +#include <vector>
804 +class ScAddress;
806 +class SC_DLLPUBLIC ScDPOutputGeometry
808 +public:
809 + enum FieldType { Column, Row, Page, Data, None };
810 + enum ImportType { ODF, XLS };
812 + ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter, ImportType eImportType);
813 + ~ScDPOutputGeometry();
815 + /**
816 + * @param nCount number of row fields, <b>excluding the data layout
817 + * field if exists</b>.
818 + */
819 + void setRowFieldCount(sal_uInt32 nCount);
820 + void setColumnFieldCount(sal_uInt32 nCount);
821 + void setPageFieldCount(sal_uInt32 nCount);
822 + void setDataFieldCount(sal_uInt32 nCount);
824 + void getColumnFieldPositions(::std::vector<ScAddress>& rAddrs) const;
825 + void getRowFieldPositions(::std::vector<ScAddress>& rAddrs) const;
826 + void getPageFieldPositions(::std::vector<ScAddress>& rAddrs) const;
828 + SCROW getRowFieldHeaderRow() const;
830 + FieldType getFieldButtonType(const ScAddress& rPos) const;
832 +private:
833 + ScDPOutputGeometry(); // disabled
835 +private:
836 + ScRange maOutRange;
837 + sal_uInt32 mnRowFields; /// number of row fields (data layout field NOT included!)
838 + sal_uInt32 mnColumnFields;
839 + sal_uInt32 mnPageFields;
840 + sal_uInt32 mnDataFields;
842 + ImportType meImportType;
844 + bool mbShowFilter;
847 +#endif
848 diff --git sc/inc/dpsave.hxx sc/inc/dpsave.hxx
849 index 11ed5d7..0f9c6fe 100644
850 --- sc/inc/dpsave.hxx
851 +++ sc/inc/dpsave.hxx
852 @@ -34,9 +34,11 @@
853 #include <tools/string.hxx>
854 #include <tools/list.hxx>
855 #include <com/sun/star/sheet/XDimensionsSupplier.hpp>
856 +#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
857 #include "scdllapi.h"
858 #include <hash_map>
859 #include <list>
860 +#include <memory>
862 namespace com { namespace sun { namespace star { namespace sheet {
863 struct DataPilotFieldReference;
864 @@ -46,6 +48,7 @@ namespace com { namespace sun { namespace star { namespace sheet {
865 } } } }
867 class ScDPDimensionSaveData;
868 +class ScDPTableData;
870 // --------------------------------------------------------------------
872 @@ -57,6 +60,7 @@ class ScDPSaveMember
874 private:
875 String aName;
876 + ::std::auto_ptr<rtl::OUString> mpLayoutName; // custom name to be displayed in the table.
877 USHORT nVisibleMode;
878 USHORT nShowDetailsMode;
880 @@ -77,18 +81,23 @@ public:
882 void SetName( const String& rNew ); // used if the source member was renamed (groups)
884 + SC_DLLPUBLIC void SetLayoutName( const ::rtl::OUString& rName );
885 + SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const;
886 + void RemoveLayoutName();
888 void WriteToSource( const com::sun::star::uno::Reference<
889 com::sun::star::uno::XInterface>& xMember,
890 sal_Int32 nPosition );
894 -class ScDPSaveDimension
895 +class SC_DLLPUBLIC ScDPSaveDimension
897 private:
898 String aName;
899 - String* pLayoutName; // alternative name for layout, not used (yet)
900 String* pSelectedPage;
901 + ::std::auto_ptr<rtl::OUString> mpLayoutName;
902 + ::std::auto_ptr<rtl::OUString> mpSubtotalName;
903 BOOL bIsDataLayout;
904 BOOL bDupFlag;
905 USHORT nOrientation;
906 @@ -127,43 +136,52 @@ public:
908 void SetName( const String& rNew ); // used if the source dim was renamed (groups)
910 - SC_DLLPUBLIC void SetOrientation(USHORT nNew);
911 - SC_DLLPUBLIC void SetSubTotals(long nCount, const USHORT* pFuncs);
912 + void SetOrientation(USHORT nNew);
913 + void SetSubTotals(long nCount, const USHORT* pFuncs);
914 long GetSubTotalsCount() const { return nSubTotalCount; }
915 USHORT GetSubTotalFunc(long nIndex) const { return pSubTotalFuncs[nIndex]; }
916 - SC_DLLPUBLIC void SetShowEmpty(BOOL bSet);
917 + void SetShowEmpty(BOOL bSet);
918 BOOL GetShowEmpty() const { return BOOL(nShowEmptyMode); }
919 - SC_DLLPUBLIC void SetFunction(USHORT nNew); // enum GeneralFunction
920 + void SetFunction(USHORT nNew); // enum GeneralFunction
921 USHORT GetFunction() const { return nFunction; }
922 void SetUsedHierarchy(long nNew);
923 long GetUsedHierarchy() const { return nUsedHierarchy; }
924 - SC_DLLPUBLIC void SetLayoutName(const String* pName);
925 - SC_DLLPUBLIC const String& GetLayoutName() const;
926 - SC_DLLPUBLIC BOOL HasLayoutName() const;
928 + void SetLayoutName(const ::rtl::OUString& rName);
929 + const ::rtl::OUString* GetLayoutName() const;
930 + void RemoveLayoutName();
931 + void SetSubtotalName(const ::rtl::OUString& rName);
932 + const ::rtl::OUString* GetSubtotalName() const;
934 + bool IsMemberNameInUse(const ::rtl::OUString& rName) const;
936 const ::com::sun::star::sheet::DataPilotFieldReference* GetReferenceValue() const { return pReferenceValue; }
937 - SC_DLLPUBLIC void SetReferenceValue(const ::com::sun::star::sheet::DataPilotFieldReference* pNew);
938 + void SetReferenceValue(const ::com::sun::star::sheet::DataPilotFieldReference* pNew);
940 const ::com::sun::star::sheet::DataPilotFieldSortInfo* GetSortInfo() const { return pSortInfo; }
941 - SC_DLLPUBLIC void SetSortInfo(const ::com::sun::star::sheet::DataPilotFieldSortInfo* pNew);
942 + void SetSortInfo(const ::com::sun::star::sheet::DataPilotFieldSortInfo* pNew);
943 const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* GetAutoShowInfo() const { return pAutoShowInfo; }
944 - SC_DLLPUBLIC void SetAutoShowInfo(const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pNew);
945 + void SetAutoShowInfo(const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pNew);
946 const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* GetLayoutInfo() const { return pLayoutInfo; }
947 - SC_DLLPUBLIC void SetLayoutInfo(const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pNew);
948 + void SetLayoutInfo(const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pNew);
950 - SC_DLLPUBLIC void SetCurrentPage( const String* pPage ); // NULL = no selection (all)
951 - SC_DLLPUBLIC BOOL HasCurrentPage() const;
952 - SC_DLLPUBLIC const String& GetCurrentPage() const;
953 + void SetCurrentPage( const String* pPage ); // NULL = no selection (all)
954 + BOOL HasCurrentPage() const;
955 + const String& GetCurrentPage() const;
957 USHORT GetOrientation() const { return nOrientation; }
959 ScDPSaveMember* GetExistingMemberByName(const String& rName);
960 - SC_DLLPUBLIC ScDPSaveMember* GetMemberByName(const String& rName);
961 + ScDPSaveMember* GetMemberByName(const String& rName);
963 void SetMemberPosition( const String& rName, sal_Int32 nNewPos );
965 void WriteToSource( const com::sun::star::uno::Reference<
966 com::sun::star::uno::XInterface>& xDim );
968 + void UpdateMemberVisibility(const ::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rData);
970 + bool HasInvisibleMember() const;
974 @@ -179,6 +197,12 @@ private:
975 BOOL bFilterButton; // not passed to DataPilotSource
976 BOOL bDrillDown; // not passed to DataPilotSource
978 + /** if true, all dimensions already have all of their member instances
979 + * created. */
980 + bool mbDimensionMembersBuilt;
982 + ::std::auto_ptr<rtl::OUString> mpGrandTotalName;
984 public:
985 SC_DLLPUBLIC ScDPSaveData();
986 ScDPSaveData(const ScDPSaveData& r);
987 @@ -188,21 +212,26 @@ public:
989 BOOL operator== ( const ScDPSaveData& r ) const;
991 + SC_DLLPUBLIC void SetGrandTotalName(const ::rtl::OUString& rName);
992 + SC_DLLPUBLIC const ::rtl::OUString* GetGrandTotalName() const;
994 const List& GetDimensions() const { return aDimList; }
995 void AddDimension(ScDPSaveDimension* pDim) { aDimList.Insert(pDim, LIST_APPEND); }
997 ScDPSaveDimension* GetDimensionByName(const String& rName);
998 SC_DLLPUBLIC ScDPSaveDimension* GetDataLayoutDimension();
999 + SC_DLLPUBLIC ScDPSaveDimension* GetExistingDataLayoutDimension() const;
1001 ScDPSaveDimension* DuplicateDimension(const String& rName);
1002 SC_DLLPUBLIC ScDPSaveDimension& DuplicateDimension(const ScDPSaveDimension& rDim);
1004 - SC_DLLPUBLIC ScDPSaveDimension* GetExistingDimensionByName(const String& rName);
1005 + SC_DLLPUBLIC ScDPSaveDimension* GetExistingDimensionByName(const String& rName) const;
1006 SC_DLLPUBLIC ScDPSaveDimension* GetNewDimensionByName(const String& rName);
1008 void RemoveDimensionByName(const String& rName);
1010 ScDPSaveDimension* GetInnermostDimension(USHORT nOrientation);
1011 + ScDPSaveDimension* GetFirstDimension(::com::sun::star::sheet::DataPilotFieldOrientation eOrientation);
1012 long GetDataDimensionCount() const;
1015 @@ -229,6 +258,14 @@ public:
1016 const ScDPDimensionSaveData* GetExistingDimensionData() const { return pDimensionData; }
1017 SC_DLLPUBLIC ScDPDimensionSaveData* GetDimensionData(); // create if not there
1018 void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied
1019 + void BuildAllDimensionMembers(ScDPTableData* pData);
1021 + /**
1022 + * Check whether a dimension has one or more invisible members.
1024 + * @param rDimName dimension name
1025 + */
1026 + SC_DLLPUBLIC bool HasInvisibleMember(const ::rtl::OUString& rDimName) const;
1030 diff --git sc/inc/dptabres.hxx sc/inc/dptabres.hxx
1031 index 0712cc9..4e05c19 100644
1032 --- sc/inc/dptabres.hxx
1033 +++ sc/inc/dptabres.hxx
1034 @@ -41,6 +41,7 @@
1035 #include <hash_map>
1036 #include <hash_set>
1037 #include <vector>
1038 +#include <memory>
1040 namespace com { namespace sun { namespace star { namespace sheet {
1041 struct DataPilotFieldReference;
1042 @@ -262,7 +263,7 @@ public:
1044 long GetMeasureCount() const { return nMeasCount; }
1045 ScSubTotalFunc GetMeasureFunction(long nMeasure) const;
1046 - String GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc) const;
1047 + String GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const;
1048 String GetMeasureDimensionName(long nMeasure) const;
1049 const ::com::sun::star::sheet::DataPilotFieldReference& GetMeasureRefVal(long nMeasure) const;
1050 USHORT GetMeasureRefOrient(long nMeasure) const;
1051 @@ -284,6 +285,8 @@ public:
1052 const ScDPItemData& rBaseData, long nBaseIndex ) const;
1053 BOOL HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex,
1054 const ScDPItemData& rSecondData, long nSecondIndex ) const;
1056 + const ScDPSource* GetSource() const;
1060 diff --git sc/inc/dptabsrc.hxx sc/inc/dptabsrc.hxx
1061 index 670f314..deb0498 100644
1062 --- sc/inc/dptabsrc.hxx
1063 +++ sc/inc/dptabsrc.hxx
1064 @@ -33,6 +33,7 @@
1066 #include <vector>
1067 #include <hash_map>
1068 +#include <memory>
1069 #include <tools/string.hxx>
1070 #include <tools/list.hxx>
1071 #include "global.hxx" // enum ScSubTotalFunc
1072 @@ -108,7 +109,7 @@ class ScDPSource : public cppu::WeakImplHelper6<
1073 com::sun::star::lang::XServiceInfo >
1075 private:
1076 - ScDPTableData* pData; // data source
1077 + ScDPTableData* pData; // data source (ScDPObject manages its life time)
1078 ScDPDimensions* pDimensions; // api objects
1079 // settings:
1080 long nColDims[SC_DAPI_MAXFIELDS];
1081 @@ -136,6 +137,8 @@ private:
1082 List aRowLevelList;
1083 BOOL bResultOverflow;
1085 + ::std::auto_ptr<rtl::OUString> mpGrandTotalName;
1087 void CreateRes_Impl();
1088 void FillMemberResults();
1089 void FillLevelList( USHORT nOrientation, List& rList );
1090 @@ -162,11 +165,15 @@ public:
1091 ScDPTableData* GetData() { return pData; }
1092 const ScDPTableData* GetData() const { return pData; }
1094 + void SetGrandTotalName(const ::rtl::OUString& rName);
1095 + const ::rtl::OUString* GetGrandTotalName() const;
1097 USHORT GetOrientation(long nColumn);
1098 void SetOrientation(long nColumn, USHORT nNew);
1099 long GetPosition(long nColumn);
1101 long GetDataDimensionCount();
1102 + ScDPDimension* GetDataDimension(long nIndex);
1103 String GetDataDimName(long nIndex);
1104 BOOL IsDataLayoutDimension(long nDim);
1105 USHORT GetDataLayoutOrientation();
1106 @@ -333,12 +340,15 @@ private:
1107 long nUsedHier;
1108 USHORT nFunction; // enum GeneralFunction
1109 String aName; // if empty, take from source
1110 + ::std::auto_ptr<rtl::OUString> mpLayoutName;
1111 + ::std::auto_ptr<rtl::OUString> mpSubtotalName;
1112 long nSourceDim; // >=0 if dup'ed
1113 ::com::sun::star::sheet::DataPilotFieldReference
1114 aReferenceValue; // settings for "show data as" / "displayed value"
1115 BOOL bHasSelectedPage;
1116 String aSelectedPage;
1117 ScDPItemData* pSelectedData; // internal, temporary, created from aSelectedPage
1118 + sal_Bool mbHasHiddenMember;
1120 public:
1121 ScDPDimension( ScDPSource* pSrc, long nD );
1122 @@ -350,6 +360,9 @@ public:
1123 ScDPDimension* CreateCloneObject();
1124 ScDPHierarchies* GetHierarchiesObject();
1126 + SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const;
1127 + const ::rtl::OUString* GetSubtotalName() const;
1129 // XNamed
1130 virtual ::rtl::OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
1131 virtual void SAL_CALL setName( const ::rtl::OUString& aName )
1132 @@ -736,7 +749,7 @@ private:
1133 long nLev;
1135 ScDPItemData maData;
1136 -// String aCaption; // visible name (changeable by user)
1137 + ::std::auto_ptr<rtl::OUString> mpLayoutName;
1139 sal_Int32 nPosition; // manual sorting
1140 BOOL bVisible;
1141 @@ -750,6 +763,7 @@ public:
1142 BOOL IsNamedItem( const ScDPItemData& r ) const;
1143 String GetNameStr() const;
1144 void FillItemData( ScDPItemData& rData ) const;
1145 + SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const;
1147 sal_Int32 Compare( const ScDPMember& rOther ) const; // visible order
1149 diff --git sc/inc/fillinfo.hxx sc/inc/fillinfo.hxx
1150 index a75f3c1..4d97133 100644
1151 --- sc/inc/fillinfo.hxx
1152 +++ sc/inc/fillinfo.hxx
1153 @@ -99,6 +99,8 @@ struct CellInfo
1154 BOOL bVOverlapped : 1;
1155 BOOL bAutoFilter : 1;
1156 BOOL bPushButton : 1;
1157 + bool bPopupButton: 1;
1158 + bool bFilterActive:1;
1160 BOOL bPrinted : 1; // bei Bedarf (Pagebreak-Modus)
1162 diff --git sc/inc/global.hxx sc/inc/global.hxx
1163 index 3e31be4..e207691 100644
1164 --- sc/inc/global.hxx
1165 +++ sc/inc/global.hxx
1166 @@ -87,8 +87,6 @@ extern "C" {
1167 #endif
1169 //------------------------------------------------------------------------
1170 -struct LabelData;
1171 -//------------------------------------------------------------------------
1173 // die 1000 Namen des Calc...
1174 // Clipboard-Namen sind jetzt in so3/soapp.hxx
1175 diff --git sc/inc/miscuno.hxx sc/inc/miscuno.hxx
1176 index 3402f5a..7ce4c90 100644
1177 --- sc/inc/miscuno.hxx
1178 +++ sc/inc/miscuno.hxx
1179 @@ -285,12 +285,29 @@ public:
1180 static sal_Int32 GetEnumProperty( const com::sun::star::uno::Reference<
1181 com::sun::star::beans::XPropertySet>& xProp,
1182 const ::rtl::OUString& rName, long nDefault );
1183 + static ::rtl::OUString GetStringProperty(
1184 + const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xProp,
1185 + const ::rtl::OUString& rName, const ::rtl::OUString& rDefault );
1187 static sal_Bool GetBoolFromAny( const com::sun::star::uno::Any& aAny );
1188 static sal_Int16 GetInt16FromAny( const com::sun::star::uno::Any& aAny );
1189 static sal_Int32 GetInt32FromAny( const com::sun::star::uno::Any& aAny );
1190 static sal_Int32 GetEnumFromAny( const com::sun::star::uno::Any& aAny );
1191 static void SetBoolInAny( com::sun::star::uno::Any& rAny, sal_Bool bValue );
1193 + static void SetOptionalPropertyValue(
1194 + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rPropSet,
1195 + const sal_Char* pPropName, const ::com::sun::star::uno::Any& rVal );
1197 + template<typename ValueType>
1198 + static void SetOptionalPropertyValue(
1199 + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rPropSet,
1200 + const sal_Char* pPropName, const ValueType& rVal )
1202 + ::com::sun::star::uno::Any any;
1203 + any <<= rVal;
1204 + SetOptionalPropertyValue(rPropSet, pPropName, any);
1209 diff --git sc/inc/pivot.hxx sc/inc/pivot.hxx
1210 index d1b0fb9..680da7d 100644
1211 --- sc/inc/pivot.hxx
1212 +++ sc/inc/pivot.hxx
1213 @@ -53,6 +53,7 @@
1214 #include "address.hxx"
1216 #include <vector>
1217 +#include <boost/shared_ptr.hpp>
1219 class SubTotal;
1220 #include "collect.hxx"
1221 @@ -69,7 +70,9 @@ class SvStream;
1222 class ScDocument;
1223 class ScUserListData;
1224 class ScProgress;
1225 -struct LabelData;
1226 +struct ScDPLabelData;
1228 +typedef ::boost::shared_ptr<ScDPLabelData> ScDPLabelDataRef;
1230 // -----------------------------------------------------------------------
1232 @@ -93,8 +96,7 @@ struct ScPivotParam
1233 SCCOL nCol; // Cursor Position /
1234 SCROW nRow; // bzw. Anfang des Zielbereiches
1235 SCTAB nTab;
1236 - LabelData** ppLabelArr;
1237 - SCSIZE nLabels;
1238 + ::std::vector<ScDPLabelDataRef> maLabelArray;
1239 PivotField aPageArr[PIVOT_MAXPAGEFIELD];
1240 PivotField aColArr[PIVOT_MAXFIELD];
1241 PivotField aRowArr[PIVOT_MAXFIELD];
1242 @@ -115,10 +117,8 @@ struct ScPivotParam
1243 ScPivotParam& operator= ( const ScPivotParam& r );
1244 BOOL operator== ( const ScPivotParam& r ) const;
1245 //UNUSED2009-05 void Clear ();
1246 - void ClearLabelData ();
1247 void ClearPivotArrays();
1248 - void SetLabelData ( LabelData** ppLabArr,
1249 - SCSIZE nLab );
1250 + void SetLabelData (const ::std::vector<ScDPLabelDataRef>& r);
1251 void SetPivotArrays ( const PivotField* pPageArr,
1252 const PivotField* pColArr,
1253 const PivotField* pRowArr,
1254 @@ -136,24 +136,45 @@ typedef PivotField PivotPageFieldArr[PIVOT_MAXPAGEFIELD];
1256 //------------------------------------------------------------------------
1258 -struct LabelData
1259 +struct ScDPLabelData
1261 - String maName; /// Visible name of the dimension.
1262 + ::rtl::OUString maName; /// Original name of the dimension.
1263 + ::rtl::OUString maLayoutName; /// Layout name (display name)
1264 SCsCOL mnCol;
1265 USHORT mnFuncMask; /// Page/Column/Row subtotal function.
1266 sal_Int32 mnUsedHier; /// Used hierarchy.
1267 bool mbShowAll; /// true = Show all (also empty) results.
1268 bool mbIsValue; /// true = Sum or count in data field.
1270 + struct Member
1272 + ::rtl::OUString maName;
1273 + ::rtl::OUString maLayoutName;
1274 + bool mbVisible;
1275 + bool mbShowDetails;
1277 + Member();
1279 + /**
1280 + * return the name that should be displayed in the dp dialogs i.e.
1281 + * when the layout name is present, use it, or else use the original
1282 + * name.
1283 + */
1284 + ::rtl::OUString SC_DLLPUBLIC getDisplayName() const;
1285 + };
1286 + ::std::vector<Member> maMembers;
1287 ::com::sun::star::uno::Sequence< ::rtl::OUString > maHiers; /// Hierarchies.
1288 - ::com::sun::star::uno::Sequence< ::rtl::OUString > maMembers; /// Members.
1289 - ::com::sun::star::uno::Sequence< sal_Bool > maVisible; /// Visibility of members.
1290 - ::com::sun::star::uno::Sequence< sal_Bool > maShowDet; /// Show details of members.
1291 ::com::sun::star::sheet::DataPilotFieldSortInfo maSortInfo; /// Sorting info.
1292 ::com::sun::star::sheet::DataPilotFieldLayoutInfo maLayoutInfo; /// Layout info.
1293 ::com::sun::star::sheet::DataPilotFieldAutoShowInfo maShowInfo; /// AutoShow info.
1295 - explicit LabelData( const String& rName, short nCol, bool bIsValue );
1296 + explicit ScDPLabelData( const String& rName, short nCol, bool bIsValue );
1298 + /**
1299 + * return the name that should be displayed in the dp dialogs i.e. when
1300 + * the layout name is present, use it, or else use the original name.
1301 + */
1302 + ::rtl::OUString SC_DLLPUBLIC getDisplayName() const;
1305 // ============================================================================
1306 @@ -171,7 +192,6 @@ struct ScDPFuncData
1308 // ============================================================================
1310 -typedef LabelData ScDPLabelData;
1311 typedef std::vector< ScDPLabelData > ScDPLabelDataVec;
1312 typedef std::vector< String > ScDPNameVec;
1314 diff --git sc/inc/sc.hrc sc/inc/sc.hrc
1315 index e823b40..3e0a1f8 100644
1316 --- sc/inc/sc.hrc
1317 +++ sc/inc/sc.hrc
1318 @@ -1444,6 +1444,8 @@
1319 #define RID_IMG_H_DROP_URL (BMP_START + 5)
1320 #define RID_IMG_H_DROP_LINK (BMP_START + 6)
1321 #define RID_IMG_H_DROP_COPY (BMP_START + 7)
1322 +#define RID_IMG_SELECT_CURRENT (BMP_START + 8)
1323 +#define RID_IMG_UNSELECT_CURRENT (BMP_START + 9)
1325 #define RID_SCPTR_PIVOTCOL (BMP_START + 81)
1326 #define RID_SCPTR_PIVOTROW (BMP_START + 82)
1327 @@ -1635,8 +1637,9 @@
1328 #define RID_SCDLG_DOCPROTECTION (SC_DIALOGS_START + 149)
1329 #define RID_SCDLG_RETYPEPASS (SC_DIALOGS_START + 150)
1330 #define RID_SCDLG_RETYPEPASS_INPUT (SC_DIALOGS_START + 151)
1331 +#define RID_POPUP_FILTER (SC_DIALOGS_START + 152)
1333 -#define SC_DIALOGS_END (SC_DIALOGS_START + 152)
1334 +#define SC_DIALOGS_END (SC_DIALOGS_START + 153)
1336 #ifndef STD_MASKCOLOR
1337 #define STD_MASKCOLOR Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; }
1338 diff --git sc/inc/scabstdlg.hxx sc/inc/scabstdlg.hxx
1339 index 2e1a33d..de99888 100644
1340 --- sc/inc/scabstdlg.hxx
1341 +++ sc/inc/scabstdlg.hxx
1342 @@ -243,7 +243,7 @@ class AbstractScDPSubtotalDlg : public VclAbstractDialog //add for ScDPSubtotal
1344 public:
1345 virtual USHORT GetFuncMask() const = 0;
1346 - virtual void FillLabelData( LabelData& rLabelData ) const = 0;
1347 + virtual void FillLabelData( ScDPLabelData& rLabelData ) const = 0;
1350 class AbstractScDPNumGroupDlg : public VclAbstractDialog
1351 diff --git sc/inc/table.hxx sc/inc/table.hxx
1352 index a33ebb9..715e119 100644
1353 --- sc/inc/table.hxx
1354 +++ sc/inc/table.hxx
1355 @@ -291,6 +291,7 @@ public:
1357 ScBaseCell* GetCell( SCCOL nCol, SCROW nRow ) const;
1359 + void GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const;
1360 void GetLastDataPos(SCCOL& rCol, SCROW& rRow) const;
1362 /** Returns the pointer to a cell note object at the passed cell address. */
1363 diff --git sc/inc/unonames.hxx sc/inc/unonames.hxx
1364 index c7ce536..faa463f 100644
1365 --- sc/inc/unonames.hxx
1366 +++ sc/inc/unonames.hxx
1367 @@ -561,6 +561,10 @@
1368 #define SC_UNO_ROWFIELDCOUNT "RowFieldCount"
1369 #define SC_UNO_COLUMNFIELDCOUNT "ColumnFieldCount"
1370 #define SC_UNO_DATAFIELDCOUNT "DataFieldCount"
1371 +#define SC_UNO_LAYOUTNAME "LayoutName"
1372 +#define SC_UNO_FIELD_SUBTOTALNAME "FieldSubtotalName"
1373 +#define SC_UNO_GRANDTOTAL_NAME "GrandTotalName"
1374 +#define SC_UNO_HAS_HIDDEN_MEMBER "HasHiddenMember"
1376 // (preliminary:)
1377 #define SC_UNO_REFVALUE "ReferenceValue"
1378 diff --git sc/source/core/data/column2.cxx sc/source/core/data/column2.cxx
1379 index 067f074..9fc2ea5 100644
1380 --- sc/source/core/data/column2.cxx
1381 +++ sc/source/core/data/column2.cxx
1382 @@ -1376,13 +1376,13 @@ SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirecti
1383 return nLines;
1386 -//UNUSED2009-05 SCROW ScColumn::GetFirstDataPos() const
1387 -//UNUSED2009-05 {
1388 -//UNUSED2009-05 if (nCount)
1389 -//UNUSED2009-05 return pItems[0].nRow;
1390 -//UNUSED2009-05 else
1391 -//UNUSED2009-05 return 0;
1392 -//UNUSED2009-05 }
1393 +SCROW ScColumn::GetFirstDataPos() const
1395 + if (nCount)
1396 + return pItems[0].nRow;
1397 + else
1398 + return 0;
1401 SCROW ScColumn::GetLastDataPos() const
1403 diff --git sc/source/core/data/documen8.cxx sc/source/core/data/documen8.cxx
1404 index 19d6d94..448c339 100644
1405 --- sc/source/core/data/documen8.cxx
1406 +++ sc/source/core/data/documen8.cxx
1407 @@ -96,6 +96,7 @@
1408 #include "globstr.hrc"
1409 #include "sc.hrc"
1410 #include "charthelper.hxx"
1411 +#include "dpobject.hxx"
1413 #define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue()
1415 @@ -713,8 +714,13 @@ BOOL ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpe
1416 // skip everything left of rSpellPos:
1417 while ( pCell && nRow == rSpellPos.Row() && nCol < rSpellPos.Col() )
1418 pCell = aIter.GetNext( nCol, nRow );
1419 - while ( pCell )
1421 + for (; pCell; pCell = aIter.GetNext(nCol, nRow))
1423 + if (pDPCollection && pDPCollection->HasDPTable(nCol, nRow, nTab))
1424 + // Don't spell check within datapilot table.
1425 + continue;
1427 CellType eType = pCell->GetCellType();
1428 if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT )
1430 @@ -799,8 +805,6 @@ BOOL ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpe
1432 if ( ++nCellCount >= SPELL_MAXCELLS ) // seen enough cells?
1433 break;
1435 - pCell = aIter.GetNext( nCol, nRow );
1438 if ( pCell )
1439 diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
1440 index 39ff75e..efb9693 100644
1441 --- sc/source/core/data/document.cxx
1442 +++ sc/source/core/data/document.cxx
1443 @@ -608,6 +608,32 @@ BOOL ScDocument::GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) cons
1444 return FALSE;
1447 +bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const
1449 + if (!ValidTab(nTab) || !pTab[nTab])
1450 + return false;
1452 + SCCOL nCol1, nCol2;
1453 + SCROW nRow1, nRow2;
1454 + pTab[nTab]->GetFirstDataPos(nCol1, nRow1);
1455 + pTab[nTab]->GetLastDataPos(nCol2, nRow2);
1457 + if (nCol1 > nCol2 || nRow1 > nRow2)
1458 + // invalid range.
1459 + return false;
1461 + // Make sure the area only shrinks, and doesn't grow.
1462 + if (rStartCol < nCol1)
1463 + rStartCol = nCol1;
1464 + if (nCol2 < rEndCol)
1465 + rEndCol = nCol2;
1466 + if (rStartRow < nRow1)
1467 + rStartRow = nRow1;
1468 + if (nRow2 < rEndRow)
1469 + rEndRow = nRow2;
1471 + return true; // success!
1474 // zusammenhaengender Bereich
1476 diff --git sc/source/core/data/dpgroup.cxx sc/source/core/data/dpgroup.cxx
1477 index b4e3568..96ed464 100644
1478 --- sc/source/core/data/dpgroup.cxx
1479 +++ sc/source/core/data/dpgroup.cxx
1480 @@ -70,6 +70,7 @@ using ::rtl::OUStringHash;
1481 using ::std::vector;
1482 using ::std::hash_set;
1483 using ::std::hash_map;
1484 +using ::boost::shared_ptr;
1486 #define D_TIMEFACTOR 86400.0
1488 @@ -977,7 +978,7 @@ String lcl_GetNumGroupForValue( double fValue, const ScDPNumGroupInfo& rInfo, bo
1489 return lcl_GetNumGroupName( fGroupStart, rInfo, bHasNonInteger, cDecSeparator, pFormatter );
1492 -ScDPGroupTableData::ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDocument ) :
1493 +ScDPGroupTableData::ScDPGroupTableData( const shared_ptr<ScDPTableData>& pSource, ScDocument* pDocument ) :
1494 ScDPTableData(pDocument),
1495 pSourceData( pSource ),
1496 pDoc( pDocument )
1497 @@ -992,7 +993,6 @@ ScDPGroupTableData::ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDoc
1498 ScDPGroupTableData::~ScDPGroupTableData()
1500 delete[] pNumGroups;
1501 - delete pSourceData;
1504 void ScDPGroupTableData::AddGroupDimension( const ScDPGroupDimension& rGroup )
1505 diff --git sc/source/core/data/dpobject.cxx sc/source/core/data/dpobject.cxx
1506 index ff15b82..ede7316 100644
1507 --- sc/source/core/data/dpobject.cxx
1508 +++ sc/source/core/data/dpobject.cxx
1509 @@ -75,9 +75,11 @@
1510 #include <svtools/zforlist.hxx> // IsNumberFormat
1512 #include <vector>
1513 +#include <stdio.h>
1515 using namespace com::sun::star;
1516 using ::std::vector;
1517 +using ::boost::shared_ptr;
1518 using ::com::sun::star::uno::Sequence;
1519 using ::com::sun::star::uno::Reference;
1520 using ::com::sun::star::uno::UNO_QUERY;
1521 @@ -162,11 +164,14 @@ ScDPObject::ScDPObject( ScDocument* pD ) :
1522 pSheetDesc( NULL ),
1523 pImpDesc( NULL ),
1524 pServDesc( NULL ),
1525 + mpTableData(static_cast<ScDPTableData*>(NULL)),
1526 pOutput( NULL ),
1527 bSettingsChanged( FALSE ),
1528 bAlive( FALSE ),
1529 + mnAutoFormatIndex( 65535 ),
1530 bAllowMove( FALSE ),
1531 - nHeaderRows( 0 )
1532 + nHeaderRows( 0 ),
1533 + mbHeaderLayout(false)
1537 @@ -180,11 +185,14 @@ ScDPObject::ScDPObject(const ScDPObject& r) :
1538 pSheetDesc( NULL ),
1539 pImpDesc( NULL ),
1540 pServDesc( NULL ),
1541 + mpTableData(static_cast<ScDPTableData*>(NULL)),
1542 pOutput( NULL ),
1543 bSettingsChanged( FALSE ),
1544 bAlive( FALSE ),
1545 + mnAutoFormatIndex( r.mnAutoFormatIndex ),
1546 bAllowMove( FALSE ),
1547 - nHeaderRows( r.nHeaderRows )
1548 + nHeaderRows( r.nHeaderRows ),
1549 + mbHeaderLayout( r.mbHeaderLayout )
1551 if (r.pSaveData)
1552 pSaveData = new ScDPSaveData(*r.pSaveData);
1553 @@ -232,6 +240,26 @@ void ScDPObject::SetSaveData(const ScDPSaveData& rData)
1554 InvalidateData(); // re-init source from SaveData
1557 +void ScDPObject::SetAutoFormatIndex(const sal_uInt16 nIndex)
1559 + mnAutoFormatIndex = nIndex;
1562 +sal_uInt16 ScDPObject::GetAutoFormatIndex() const
1564 + return mnAutoFormatIndex;
1567 +void ScDPObject::SetHeaderLayout (bool bUseGrid)
1569 + mbHeaderLayout = bUseGrid;
1572 +bool ScDPObject::GetHeaderLayout() const
1574 + return mbHeaderLayout;
1577 void ScDPObject::SetOutRange(const ScRange& rRange)
1579 aOutRange = rRange;
1580 @@ -325,6 +353,22 @@ void ScDPObject::SetTag(const String& rNew)
1581 aTableTag = rNew;
1584 +bool ScDPObject::IsDataDescriptionCell(const ScAddress& rPos)
1586 + if (!pSaveData)
1587 + return false;
1589 + long nDataDimCount = pSaveData->GetDataDimensionCount();
1590 + if (nDataDimCount != 1)
1591 + // There has to be exactly one data dimension for the description to
1592 + // appear at top-left corner.
1593 + return false;
1595 + CreateOutput();
1596 + ScRange aTabRange = pOutput->GetOutputRange(sheet::DataPilotOutputRangeType::TABLE);
1597 + return (rPos == aTabRange.aStart);
1600 uno::Reference<sheet::XDimensionsSupplier> ScDPObject::GetSource()
1602 CreateObjects();
1603 @@ -338,6 +382,7 @@ void ScDPObject::CreateOutput()
1605 BOOL bFilterButton = IsSheetData() && pSaveData && pSaveData->GetFilterButton();
1606 pOutput = new ScDPOutput( pDoc, xSource, aOutRange.aStart, bFilterButton );
1607 + pOutput->SetHeaderLayout ( mbHeaderLayout );
1609 long nOldRows = nHeaderRows;
1610 nHeaderRows = pOutput->GetHeaderRows();
1611 @@ -365,11 +410,43 @@ void ScDPObject::CreateOutput()
1615 +ScDPTableData* ScDPObject::GetTableData()
1617 + if (!mpTableData)
1619 + if ( pImpDesc )
1621 + // database data
1622 + mpTableData.reset(new ScDatabaseDPData(pDoc, *pImpDesc));
1624 + else
1626 + // cell data
1627 + if (!pSheetDesc)
1629 + DBG_ERROR("no source descriptor");
1630 + pSheetDesc = new ScSheetSourceDesc; // dummy defaults
1632 + mpTableData.reset(new ScSheetDPData(pDoc, *pSheetDesc));
1635 + // grouping (for cell or database data)
1636 + if ( pSaveData && pSaveData->GetExistingDimensionData() )
1638 + shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(mpTableData, pDoc));
1639 + pSaveData->GetExistingDimensionData()->WriteToData(*pGroupData);
1640 + mpTableData = pGroupData;
1644 + return mpTableData.get();
1647 void ScDPObject::CreateObjects()
1649 // if groups are involved, create a new source with the ScDPGroupTableData
1650 if ( bSettingsChanged && pSaveData && pSaveData->GetExistingDimensionData() )
1651 - xSource = NULL;
1652 + InvalidateSource();
1654 if (!xSource.is())
1656 @@ -387,33 +464,9 @@ void ScDPObject::CreateObjects()
1657 if ( !xSource.is() ) // database or sheet data, or error in CreateSource
1659 DBG_ASSERT( !pServDesc, "DPSource could not be created" );
1661 - ScDPTableData* pData = NULL;
1662 - if ( pImpDesc )
1664 - // database data
1665 - pData = new ScDatabaseDPData( pDoc, *pImpDesc );
1667 - else
1669 - // cell data
1670 - if (!pSheetDesc)
1672 - DBG_ERROR("no source descriptor");
1673 - pSheetDesc = new ScSheetSourceDesc; // dummy defaults
1675 - pData = new ScSheetDPData( pDoc, *pSheetDesc );
1678 - // grouping (for cell or database data)
1679 - if ( pSaveData && pSaveData->GetExistingDimensionData() )
1681 - ScDPGroupTableData* pGroupData = new ScDPGroupTableData( pData, pDoc );
1682 - pSaveData->GetExistingDimensionData()->WriteToData( *pGroupData );
1683 - pData = pGroupData;
1686 - xSource = new ScDPSource( pData );
1687 + ScDPTableData* pData = GetTableData();
1688 + ScDPSource* pSource = new ScDPSource( pData );
1689 + xSource = pSource;
1692 if (pSaveData)
1693 @@ -450,6 +503,7 @@ void ScDPObject::InvalidateData()
1694 void ScDPObject::InvalidateSource()
1696 xSource = NULL;
1697 + mpTableData.reset();
1700 ScRange ScDPObject::GetNewOutputRange( BOOL& rOverflow )
1701 @@ -484,6 +538,9 @@ void ScDPObject::Output( const ScAddress& rPos )
1703 // aOutRange is always the range that was last output to the document
1704 aOutRange = pOutput->GetOutputRange();
1705 + const ScAddress& s = aOutRange.aStart;
1706 + const ScAddress& e = aOutRange.aEnd;
1707 + pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
1710 const ScRange ScDPObject::GetOutputRangeByType( sal_Int32 nType )
1711 @@ -533,6 +590,63 @@ void ScDPObject::RefreshAfterLoad()
1712 nHeaderRows = 0; // nothing found, no drop-down lists
1715 +void ScDPObject::BuildAllDimensionMembers()
1717 + if (!pSaveData)
1718 + return;
1720 + pSaveData->BuildAllDimensionMembers(GetTableData());
1723 +bool ScDPObject::GetMemberNames( sal_Int32 nDim, Sequence<OUString>& rNames )
1725 + vector<ScDPLabelData::Member> aMembers;
1726 + if (!GetMembers(nDim, GetUsedHierarchy(nDim), aMembers))
1727 + return false;
1729 + size_t n = aMembers.size();
1730 + rNames.realloc(n);
1731 + for (size_t i = 0; i < n; ++i)
1732 + rNames[i] = aMembers[i].maName;
1734 + return true;
1737 +bool ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, vector<ScDPLabelData::Member>& rMembers )
1739 + Reference< container::XNameAccess > xMembersNA;
1740 + if (!GetMembersNA( nDim, nHier, xMembersNA ))
1741 + return false;
1743 + Reference<container::XIndexAccess> xMembersIA( new ScNameToIndexAccess(xMembersNA) );
1744 + sal_Int32 nCount = xMembersIA->getCount();
1745 + vector<ScDPLabelData::Member> aMembers;
1746 + aMembers.reserve(nCount);
1748 + for (sal_Int32 i = 0; i < nCount; ++i)
1750 + Reference<container::XNamed> xMember(xMembersIA->getByIndex(i), UNO_QUERY);
1751 + ScDPLabelData::Member aMem;
1753 + if (xMember.is())
1754 + aMem.maName = xMember->getName();
1756 + Reference<beans::XPropertySet> xMemProp(xMember, UNO_QUERY);
1757 + if (xMemProp.is())
1759 + aMem.mbVisible = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_ISVISIBL));
1760 + aMem.mbShowDetails = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_SHOWDETA));
1762 + aMem.maLayoutName = ScUnoHelpFunctions::GetStringProperty(
1763 + xMemProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
1766 + aMembers.push_back(aMem);
1768 + rMembers.swap(aMembers);
1769 + return true;
1772 void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode,
1773 const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
1775 @@ -655,23 +769,33 @@ void ScDPObject::GetDrillDownData(const ScAddress& rPos, Sequence< Sequence<Any>
1776 rTableData = xDrillDownData->getDrillDownData(filters);
1779 -BOOL ScDPObject::IsDimNameInUse( const String& rName ) const
1780 +bool ScDPObject::IsDimNameInUse(const OUString& rName) const
1782 - if ( xSource.is() )
1783 + if (!xSource.is())
1784 + return false;
1786 + Reference<container::XNameAccess> xDims = xSource->getDimensions();
1787 + Sequence<OUString> aDimNames = xDims->getElementNames();
1788 + sal_Int32 n = aDimNames.getLength();
1789 + for (sal_Int32 i = 0; i < n; ++i)
1791 - uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1792 - if ( xDimsName.is() )
1793 + const OUString& rDimName = aDimNames[i];
1794 + if (rDimName.equalsIgnoreAsciiCase(rName))
1795 + return true;
1797 + Reference<beans::XPropertySet> xPropSet(xDims->getByName(rDimName), UNO_QUERY);
1798 + if (!xPropSet.is())
1799 + continue;
1801 + Any any = xPropSet->getPropertyValue(OUString::createFromAscii(SC_UNO_LAYOUTNAME));
1802 + OUString aLayoutName;
1803 + if (any >>= aLayoutName)
1805 - rtl::OUString aCompare( rName );
1806 - uno::Sequence<rtl::OUString> aNames = xDimsName->getElementNames();
1807 - long nCount = aNames.getLength();
1808 - const rtl::OUString* pArr = aNames.getConstArray();
1809 - for (long nPos=0; nPos<nCount; nPos++)
1810 - if ( pArr[nPos] == aCompare ) //! ignore case
1811 - return TRUE;
1812 + if (aLayoutName.equalsIgnoreAsciiCase(rName))
1813 + return true;
1816 - return FALSE; // not found
1817 + return false;
1820 String ScDPObject::GetDimName( long nDim, BOOL& rIsDataLayout )
1821 @@ -1732,7 +1856,7 @@ BOOL ScDPObject::FillOldParam(ScPivotParam& rParam, BOOL bForFile) const
1822 return TRUE;
1825 -void lcl_FillLabelData( LabelData& rData, const uno::Reference< beans::XPropertySet >& xDimProp )
1826 +void lcl_FillLabelData( ScDPLabelData& rData, const uno::Reference< beans::XPropertySet >& xDimProp )
1828 uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDimProp, uno::UNO_QUERY );
1829 if ( xDimProp.is() && xDimSupp.is() )
1830 @@ -1778,6 +1902,8 @@ void lcl_FillLabelData( LabelData& rData, const uno::Reference< beans::XProperty
1832 BOOL ScDPObject::FillLabelData(ScPivotParam& rParam)
1834 + rParam.maLabelArray.clear();
1836 ((ScDPObject*)this)->CreateObjects();
1838 uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1839 @@ -1788,8 +1914,6 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam)
1840 if (!nDimCount)
1841 return FALSE;
1843 - SCSIZE nOutCount = 0;
1844 - LabelData** aLabelArr = new LabelData*[nDimCount];
1845 for (long nDim=0; nDim < nDimCount; nDim++)
1847 String aFieldName;
1848 @@ -1819,29 +1943,24 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam)
1852 + OUString aLayoutName = ScUnoHelpFunctions::GetStringProperty(
1853 + xDimProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
1855 if ( aFieldName.Len() && !bData && !bDuplicated )
1857 SCsCOL nCol = static_cast< SCsCOL >( nDim ); //! ???
1858 bool bIsValue = true; //! check
1860 - aLabelArr[nOutCount] = new LabelData( aFieldName, nCol, bIsValue );
1862 - LabelData& rLabelData = *aLabelArr[nOutCount];
1863 - GetHierarchies( nDim, rLabelData.maHiers );
1864 - GetMembers( nDim, rLabelData.maMembers, &rLabelData.maVisible, &rLabelData.maShowDet );
1865 - lcl_FillLabelData( rLabelData, xDimProp );
1867 - ++nOutCount;
1868 + ScDPLabelDataRef pNewLabel(new ScDPLabelData(aFieldName, nCol, bIsValue));
1869 + pNewLabel->maLayoutName = aLayoutName;
1870 + GetHierarchies(nDim, pNewLabel->maHiers);
1871 + GetMembers(nDim, GetUsedHierarchy(nDim), pNewLabel->maMembers);
1872 + lcl_FillLabelData(*pNewLabel, xDimProp);
1873 + rParam.maLabelArray.push_back(pNewLabel);
1878 - rParam.SetLabelData( aLabelArr, nOutCount );
1880 - for (SCSIZE i=0; i<nOutCount; i++)
1881 - delete aLabelArr[i];
1882 - delete[] aLabelArr;
1884 return TRUE;
1887 @@ -1890,14 +2009,6 @@ BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, uno::Reference< container::XNameA
1888 return GetMembersNA( nDim, GetUsedHierarchy( nDim ), xMembers );
1891 -BOOL ScDPObject::GetMembers( sal_Int32 nDim,
1892 - uno::Sequence< rtl::OUString >& rMembers,
1893 - uno::Sequence< sal_Bool >* pVisible,
1894 - uno::Sequence< sal_Bool >* pShowDet )
1896 - return GetMembers( nDim, GetUsedHierarchy( nDim ), rMembers, pVisible, pShowDet );
1899 BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference< container::XNameAccess >& xMembers )
1901 BOOL bRet = FALSE;
1902 @@ -1933,55 +2044,6 @@ BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference<
1903 return bRet;
1906 -BOOL ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier,
1907 - uno::Sequence< rtl::OUString >& rMembers,
1908 - uno::Sequence< sal_Bool >* pVisible,
1909 - uno::Sequence< sal_Bool >* pShowDet )
1911 - BOOL bRet = FALSE;
1912 - uno::Reference< container::XNameAccess > xMembersNA;
1913 - if( GetMembersNA( nDim, nHier, xMembersNA ) )
1915 - uno::Reference< container::XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) );
1916 - sal_Int32 nCount = xMembersIA->getCount();
1917 - rMembers.realloc( nCount );
1918 - if( pVisible )
1919 - pVisible->realloc( nCount );
1920 - if( pShowDet )
1921 - pShowDet->realloc( nCount );
1923 - rtl::OUString* pAry = rMembers.getArray();
1924 - for( sal_Int32 nItem = 0; nItem < nCount; ++nItem )
1926 - uno::Reference< container::XNamed > xMember( xMembersIA->getByIndex( nItem ), uno::UNO_QUERY );
1927 - if( xMember.is() )
1928 - pAry[ nItem ] = xMember->getName();
1929 - if( pVisible || pShowDet )
1931 - uno::Reference< beans::XPropertySet > xMemProp( xMember, uno::UNO_QUERY );
1932 - if( pVisible )
1934 - sal_Bool bVis = sal_True;
1935 - if( xMemProp.is() )
1936 - bVis = ScUnoHelpFunctions::GetBoolProperty( xMemProp,
1937 - rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ISVISIBL ) ) );
1938 - (*pVisible)[ nItem ] = bVis;
1940 - if( pShowDet )
1942 - sal_Bool bShow = sal_True;
1943 - if( xMemProp.is() )
1944 - bShow = ScUnoHelpFunctions::GetBoolProperty( xMemProp,
1945 - rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWDETA ) ) );
1946 - (*pShowDet)[ nItem ] = bShow;
1950 - bRet = TRUE;
1952 - return bRet;
1955 //------------------------------------------------------------------------
1956 // convert old pivot tables into new datapilot tables
1958 @@ -2376,7 +2438,7 @@ void ScDPCollection::WriteRefsTo( ScDPCollection& r ) const
1960 ScDPObject* pDestObj = new ScDPObject( *pSourceObj );
1961 pDestObj->SetAlive(TRUE);
1962 - if ( !r.Insert(pDestObj) )
1963 + if ( !r.InsertNewTable(pDestObj) )
1965 DBG_ERROR("cannot insert DPObject");
1966 DELETEZ( pDestObj );
1967 @@ -2411,6 +2473,39 @@ ScSimpleSharedString& ScDPCollection::GetSharedString()
1968 return maSharedString;
1971 +void ScDPCollection::FreeTable(ScDPObject* pDPObj)
1973 + const ScRange& rOutRange = pDPObj->GetOutRange();
1974 + const ScAddress& s = rOutRange.aStart;
1975 + const ScAddress& e = rOutRange.aEnd;
1976 + pDoc->RemoveFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
1977 + Free(pDPObj);
1980 +bool ScDPCollection::InsertNewTable(ScDPObject* pDPObj)
1982 + bool bSuccess = Insert(pDPObj);
1983 + if (bSuccess)
1985 + const ScRange& rOutRange = pDPObj->GetOutRange();
1986 + const ScAddress& s = rOutRange.aStart;
1987 + const ScAddress& e = rOutRange.aEnd;
1988 + pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
1990 + return bSuccess;
1993 +bool ScDPCollection::HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const
1995 + const ScMergeFlagAttr* pMergeAttr = static_cast<const ScMergeFlagAttr*>(
1996 + pDoc->GetAttr(nCol, nRow, nTab, ATTR_MERGE_FLAG));
1998 + if (!pMergeAttr)
1999 + return false;
2001 + return pMergeAttr->HasDPTable();
2004 ScDPCacheCell* ScDPCollection::getCacheCellFromPool(const ScDPCacheCell& rCell)
2006 ScDPCacheCell aCell(rCell);
2007 diff --git sc/source/core/data/dpoutput.cxx sc/source/core/data/dpoutput.cxx
2008 index 0699892..e472dbf 100644
2009 --- sc/source/core/data/dpoutput.cxx
2010 +++ sc/source/core/data/dpoutput.cxx
2011 @@ -81,6 +81,7 @@
2013 using namespace com::sun::star;
2014 using ::std::vector;
2015 +using ::com::sun::star::beans::XPropertySet;
2016 using ::com::sun::star::uno::Sequence;
2017 using ::com::sun::star::uno::UNO_QUERY;
2018 using ::com::sun::star::uno::Reference;
2019 @@ -98,7 +99,6 @@ using ::rtl::OUString;
2020 #define DP_PROP_ORIENTATION "Orientation"
2021 #define DP_PROP_POSITION "Position"
2022 #define DP_PROP_USEDHIERARCHY "UsedHierarchy"
2023 -#define DP_PROP_DATADESCR "DataDescription"
2024 #define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension"
2025 #define DP_PROP_NUMBERFORMAT "NumberFormat"
2026 #define DP_PROP_FILTER "Filter"
2027 @@ -119,9 +119,15 @@ struct ScDPOutLevelData
2028 long nLevel;
2029 long nDimPos;
2030 uno::Sequence<sheet::MemberResult> aResult;
2031 - String aCaption;
2033 - ScDPOutLevelData() { nDim = nHier = nLevel = nDimPos = -1; }
2034 + String maName; /// Name is the internal field name.
2035 + String aCaption; /// Caption is the name visible in the output table.
2036 + bool mbHasHiddenMember;
2038 + ScDPOutLevelData()
2039 + {
2040 + nDim = nHier = nLevel = nDimPos = -1;
2041 + mbHasHiddenMember = false;
2044 BOOL operator<(const ScDPOutLevelData& r) const
2045 { return nDimPos<r.nDimPos || ( nDimPos==r.nDimPos && nHier<r.nHier ) ||
2046 @@ -370,13 +376,15 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
2047 aStartPos( rPos ),
2048 bDoFilter( bFilter ),
2049 bResultsError( FALSE ),
2050 + mbHasDataLayout(false),
2051 pColNumFmt( NULL ),
2052 pRowNumFmt( NULL ),
2053 nColFmtCount( 0 ),
2054 nRowFmtCount( 0 ),
2055 nSingleNumFmt( 0 ),
2056 bSizesValid( FALSE ),
2057 - bSizeOverflow( FALSE )
2058 + bSizeOverflow( FALSE ),
2059 + mbHeaderLayout( false )
2061 nTabStartCol = nMemberStartCol = nDataStartCol = nTabEndCol = 0;
2062 nTabStartRow = nMemberStartRow = nDataStartRow = nTabEndRow = 0;
2063 @@ -413,6 +421,8 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
2064 BOOL bIsDataLayout = ScUnoHelpFunctions::GetBoolProperty(
2065 xDimProp,
2066 rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
2067 + bool bHasHiddenMember = ScUnoHelpFunctions::GetBoolProperty(
2068 + xDimProp, OUString::createFromAscii(SC_UNO_HAS_HIDDEN_MEMBER));
2070 if ( eDimOrient != sheet::DataPilotFieldOrientation_HIDDEN )
2072 @@ -443,7 +453,17 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
2073 xLevel, uno::UNO_QUERY );
2074 if ( xLevNam.is() && xLevRes.is() )
2076 - String aCaption = String(xLevNam->getName()); //! Caption...
2077 + String aName = xLevNam->getName();
2078 + OUString aCaption = aName; // Caption equals the field name by default.
2079 + Reference<XPropertySet> xPropSet(xLevel, UNO_QUERY);
2080 + if (xPropSet.is())
2082 + Any any = xPropSet->getPropertyValue(
2083 + OUString::createFromAscii(SC_UNO_LAYOUTNAME));
2084 + any >>= aCaption;
2087 + bool bRowFieldHasMember = false;
2088 switch ( eDimOrient )
2090 case sheet::DataPilotFieldOrientation_COLUMN:
2091 @@ -452,7 +472,9 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
2092 pColFields[nColFieldCount].nLevel = nLev;
2093 pColFields[nColFieldCount].nDimPos = nDimPos;
2094 pColFields[nColFieldCount].aResult = xLevRes->getResults();
2095 + pColFields[nColFieldCount].maName = aName;
2096 pColFields[nColFieldCount].aCaption= aCaption;
2097 + pColFields[nColFieldCount].mbHasHiddenMember = bHasHiddenMember;
2098 if (!lcl_MemberEmpty(pColFields[nColFieldCount].aResult))
2099 ++nColFieldCount;
2100 break;
2101 @@ -462,9 +484,14 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
2102 pRowFields[nRowFieldCount].nLevel = nLev;
2103 pRowFields[nRowFieldCount].nDimPos = nDimPos;
2104 pRowFields[nRowFieldCount].aResult = xLevRes->getResults();
2105 + pRowFields[nRowFieldCount].maName = aName;
2106 pRowFields[nRowFieldCount].aCaption= aCaption;
2107 + pRowFields[nRowFieldCount].mbHasHiddenMember = bHasHiddenMember;
2108 if (!lcl_MemberEmpty(pRowFields[nRowFieldCount].aResult))
2109 + {
2110 ++nRowFieldCount;
2111 + bRowFieldHasMember = true;
2113 break;
2114 case sheet::DataPilotFieldOrientation_PAGE:
2115 pPageFields[nPageFieldCount].nDim = nDim;
2116 @@ -472,7 +499,9 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
2117 pPageFields[nPageFieldCount].nLevel = nLev;
2118 pPageFields[nPageFieldCount].nDimPos = nDimPos;
2119 pPageFields[nPageFieldCount].aResult = lcl_GetSelectedPageAsResult(xDimProp);
2120 + pPageFields[nPageFieldCount].maName = aName;
2121 pPageFields[nPageFieldCount].aCaption= aCaption;
2122 + pPageFields[nPageFieldCount].mbHasHiddenMember = bHasHiddenMember;
2123 // no check on results for page fields
2124 ++nPageFieldCount;
2125 break;
2126 @@ -485,6 +514,9 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
2127 // get number formats from data dimensions
2128 if ( bIsDataLayout )
2130 + if (bRowFieldHasMember)
2131 + mbHasDataLayout = true;
2133 DBG_ASSERT( nLevCount == 1, "data layout: multiple levels?" );
2134 if ( eDimOrient == sheet::DataPilotFieldOrientation_COLUMN )
2135 lcl_FillNumberFormats( pColNumFmt, nColFmtCount, xLevRes, xDims );
2136 @@ -528,7 +560,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
2139 uno::Any aAny = xSrcProp->getPropertyValue(
2140 - rtl::OUString::createFromAscii(DP_PROP_DATADESCR) );
2141 + rtl::OUString::createFromAscii(SC_UNO_DATADESC) );
2142 rtl::OUString aUStr;
2143 aAny >>= aUStr;
2144 aDataDescription = String( aUStr );
2145 @@ -605,9 +637,16 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
2146 const sheet::MemberResult& rData, BOOL bColHeader, long nLevel )
2148 long nFlags = rData.Flags;
2150 + rtl::OUStringBuffer aCaptionBuf;
2151 + if (!(nFlags & sheet::MemberResultFlags::NUMERIC))
2152 + // This caption is not a number. Make sure it won't get parsed as one.
2153 + aCaptionBuf.append(sal_Unicode('\''));
2154 + aCaptionBuf.append(rData.Caption);
2156 if ( nFlags & sheet::MemberResultFlags::HASMEMBER )
2158 - pDoc->SetString( nCol, nRow, nTab, rData.Caption );
2159 + pDoc->SetString( nCol, nRow, nTab, aCaptionBuf.makeStringAndClear() );
2161 else
2163 @@ -638,14 +677,20 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
2167 -void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption, BOOL bFrame )
2168 +void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption,
2169 + bool bInTable, bool bPopup, bool bHasHiddenMember )
2171 pDoc->SetString( nCol, nRow, nTab, rCaption );
2172 - if (bFrame)
2173 + if (bInTable)
2174 lcl_SetFrame( pDoc,nTab, nCol,nRow, nCol,nRow, 20 );
2176 // Button
2177 - pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr(SC_MF_BUTTON) );
2178 + sal_uInt16 nMergeFlag = SC_MF_BUTTON;
2179 + if (bPopup)
2180 + nMergeFlag |= SC_MF_BUTTON_POPUP;
2181 + if (bHasHiddenMember)
2182 + nMergeFlag |= SC_MF_HIDDEN_MEMBER;
2183 + pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, nMergeFlag);
2185 lcl_SetStyleById( pDoc,nTab, nCol,nRow, nCol,nRow, STR_PIVOT_STYLE_FIELDNAME );
2187 @@ -653,7 +698,7 @@ void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rC
2188 void lcl_DoFilterButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
2190 pDoc->SetString( nCol, nRow, nTab, ScGlobal::GetRscString(STR_CELL_FILTER) );
2191 - pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr(SC_MF_BUTTON) );
2192 + pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON);
2195 void ScDPOutput::CalcSizes()
2196 @@ -666,7 +711,11 @@ void ScDPOutput::CalcSizes()
2197 nRowCount = aData.getLength();
2198 const uno::Sequence<sheet::DataResult>* pRowAry = aData.getConstArray();
2199 nColCount = nRowCount ? ( pRowAry[0].getLength() ) : 0;
2200 - nHeaderSize = 1; // one row for field names
2202 + nHeaderSize = 1;
2203 + if (GetHeaderLayout() && nColFieldCount == 0)
2204 + // Insert an extra header row only when there is no column field.
2205 + nHeaderSize = 2;
2207 // calculate output positions and sizes
2209 @@ -775,7 +824,7 @@ void ScDPOutput::Output()
2210 SCCOL nHdrCol = aStartPos.Col();
2211 SCROW nHdrRow = aStartPos.Row() + nField + ( bDoFilter ? 1 : 0 );
2212 // draw without frame for consistency with filter button:
2213 - FieldCell( nHdrCol, nHdrRow, nTab, pPageFields[nField].aCaption, FALSE );
2214 + FieldCell( nHdrCol, nHdrRow, nTab, pPageFields[nField].aCaption, false, false, pPageFields[nField].mbHasHiddenMember );
2215 SCCOL nFldCol = nHdrCol + 1;
2217 String aPageValue;
2218 @@ -814,7 +863,7 @@ void ScDPOutput::Output()
2219 for (nField=0; nField<nColFieldCount; nField++)
2221 SCCOL nHdrCol = nDataStartCol + (SCCOL)nField; //! check for overflow
2222 - FieldCell( nHdrCol, nTabStartRow, nTab, pColFields[nField].aCaption );
2223 + FieldCell( nHdrCol, nTabStartRow, nTab, pColFields[nField].aCaption, true, true, pColFields[nField].mbHasHiddenMember );
2225 SCROW nRowPos = nMemberStartRow + (SCROW)nField; //! check for overflow
2226 const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nField].aResult;
2227 @@ -849,9 +898,12 @@ void ScDPOutput::Output()
2229 for (nField=0; nField<nRowFieldCount; nField++)
2231 + bool bDataLayout = mbHasDataLayout && (nField == nRowFieldCount-1);
2233 SCCOL nHdrCol = nTabStartCol + (SCCOL)nField; //! check for overflow
2234 SCROW nHdrRow = nDataStartRow - 1;
2235 - FieldCell( nHdrCol, nHdrRow, nTab, pRowFields[nField].aCaption );
2236 + FieldCell( nHdrCol, nHdrRow, nTab, pRowFields[nField].aCaption, true, !bDataLayout,
2237 + pRowFields[nField].mbHasHiddenMember );
2239 SCCOL nColPos = nMemberStartCol + (SCCOL)nField; //! check for overflow
2240 const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nField].aResult;
2241 @@ -993,6 +1045,16 @@ void ScDPOutput::GetMemberResultNames( ScStrCollection& rNames, long nDimension
2245 +void ScDPOutput::SetHeaderLayout(bool bUseGrid)
2247 + mbHeaderLayout = bUseGrid;
2248 + bSizesValid = false;
2251 +bool ScDPOutput::GetHeaderLayout() const
2253 + return mbHeaderLayout;
2256 void ScDPOutput::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData)
2258 @@ -1146,7 +1208,7 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>&
2259 for (SCCOL nColField = 0; nColField < nColFieldCount && bFilterByCol; ++nColField)
2261 sheet::DataPilotFieldFilter filter;
2262 - filter.FieldName = pColFields[nColField].aCaption;
2263 + filter.FieldName = pColFields[nColField].maName;
2265 const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nColField].aResult;
2266 const sheet::MemberResult* pArray = rSequence.getConstArray();
2267 @@ -1163,10 +1225,15 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>&
2270 // row fields
2271 + bool bDataLayoutExists = (nDataFieldCount > 1);
2272 for (SCROW nRowField = 0; nRowField < nRowFieldCount && bFilterByRow; ++nRowField)
2274 + if (bDataLayoutExists && nRowField == nRowFieldCount - 1)
2275 + // There is no sense including the data layout field for filtering.
2276 + continue;
2278 sheet::DataPilotFieldFilter filter;
2279 - filter.FieldName = pRowFields[nRowField].aCaption;
2280 + filter.FieldName = pRowFields[nRowField].maName;
2282 const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nRowField].aResult;
2283 const sheet::MemberResult* pArray = rSequence.getConstArray();
2284 @@ -1199,7 +1199,7 @@ bool lcl_IsNamedDataField( const ScDPGetPivotDataField& rTarget, const String& r
2285 bool lcl_IsNamedCategoryField( const ScDPGetPivotDataField& rFilter, const ScDPOutLevelData& rField )
2287 //! name from source instead of caption?
2288 - return ScGlobal::GetpTransliteration()->isEqual( rFilter.maFieldName, rField.aCaption );
2289 + return ScGlobal::GetpTransliteration()->isEqual( rFilter.maFieldName, rField.maName );
2292 bool lcl_IsCondition( const sheet::MemberResult& rResultEntry, const ScDPGetPivotDataField& rFilter )
2293 diff --git sc/source/core/data/dpoutputgeometry.cxx sc/source/core/data/dpoutputgeometry.cxx
2294 new file mode 100644
2295 index 0000000..999ab28
2296 --- /dev/null
2297 +++ sc/source/core/data/dpoutputgeometry.cxx
2298 @@ -0,0 +1,217 @@
2299 +/*************************************************************************
2301 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2302 + *
2303 + * Copyright 2008 by Sun Microsystems, Inc.
2305 + * OpenOffice.org - a multi-platform office productivity suite
2307 + * $RCSfile: xmldpimp.cxx,v $
2308 + * $Revision: 1.27.134.1 $
2310 + * This file is part of OpenOffice.org.
2312 + * OpenOffice.org is free software: you can redistribute it and/or modify
2313 + * it under the terms of the GNU Lesser General Public License version 3
2314 + * only, as published by the Free Software Foundation.
2316 + * OpenOffice.org is distributed in the hope that it will be useful,
2317 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2318 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2319 + * GNU Lesser General Public License version 3 for more details
2320 + * (a copy is included in the LICENSE file that accompanied this code).
2322 + * You should have received a copy of the GNU Lesser General Public License
2323 + * version 3 along with OpenOffice.org. If not, see
2324 + * <http://www.openoffice.org/license.html>
2325 + * for a copy of the LGPLv3 License.
2327 + ************************************************************************/
2329 +// MARKER(update_precomp.py): autogen include statement, do not remove
2330 +#include "precompiled_sc.hxx"
2334 +// INCLUDE ---------------------------------------------------------------
2336 +#include "dpoutputgeometry.hxx"
2337 +#include "address.hxx"
2339 +#include <vector>
2341 +using ::std::vector;
2343 +ScDPOutputGeometry::ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter, ImportType eImportType) :
2344 + maOutRange(rOutRange),
2345 + mnRowFields(0),
2346 + mnColumnFields(0),
2347 + mnPageFields(0),
2348 + mnDataFields(0),
2349 + meImportType(eImportType),
2350 + mbShowFilter(bShowFilter)
2354 +ScDPOutputGeometry::~ScDPOutputGeometry()
2358 +void ScDPOutputGeometry::setRowFieldCount(sal_uInt32 nCount)
2360 + mnRowFields = nCount;
2363 +void ScDPOutputGeometry::setColumnFieldCount(sal_uInt32 nCount)
2365 + mnColumnFields = nCount;
2368 +void ScDPOutputGeometry::setPageFieldCount(sal_uInt32 nCount)
2370 + mnPageFields = nCount;
2373 +void ScDPOutputGeometry::setDataFieldCount(sal_uInt32 nCount)
2375 + mnDataFields = nCount;
2378 +void ScDPOutputGeometry::getColumnFieldPositions(vector<ScAddress>& rAddrs) const
2380 + vector<ScAddress> aAddrs;
2381 + if (!mnColumnFields)
2383 + rAddrs.swap(aAddrs);
2384 + return;
2387 + bool bDataLayout = mnDataFields > 1;
2389 + SCROW nCurRow = maOutRange.aStart.Row();
2391 + if (mnPageFields)
2393 + SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
2394 + SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
2395 + nCurRow = nRowEnd + 2;
2397 + else if (mbShowFilter)
2398 + nCurRow += 2;
2400 + SCROW nRow = nCurRow;
2401 + SCTAB nTab = maOutRange.aStart.Tab();
2402 + SCCOL nColStart = maOutRange.aStart.Col() + mnRowFields + bDataLayout;
2403 + SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnColumnFields-1);
2405 + for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
2406 + aAddrs.push_back(ScAddress(nCol, nRow, nTab));
2407 + rAddrs.swap(aAddrs);
2410 +void ScDPOutputGeometry::getRowFieldPositions(vector<ScAddress>& rAddrs) const
2412 + vector<ScAddress> aAddrs;
2413 + if (!mnRowFields)
2415 + rAddrs.swap(aAddrs);
2416 + return;
2419 + SCROW nRow = getRowFieldHeaderRow();
2420 + SCTAB nTab = maOutRange.aStart.Tab();
2421 + SCCOL nColStart = maOutRange.aStart.Col();
2422 + SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnRowFields-1);
2424 + for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
2425 + aAddrs.push_back(ScAddress(nCol, nRow, nTab));
2426 + rAddrs.swap(aAddrs);
2429 +void ScDPOutputGeometry::getPageFieldPositions(vector<ScAddress>& rAddrs) const
2431 + vector<ScAddress> aAddrs;
2432 + if (!mnPageFields)
2434 + rAddrs.swap(aAddrs);
2435 + return;
2438 + SCTAB nTab = maOutRange.aStart.Tab();
2439 + SCCOL nCol = maOutRange.aStart.Col();
2441 + SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
2442 + SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
2444 + for (SCROW nRow = nRowStart; nRow <= nRowEnd; ++nRow)
2445 + aAddrs.push_back(ScAddress(nCol, nRow, nTab));
2446 + rAddrs.swap(aAddrs);
2449 +SCROW ScDPOutputGeometry::getRowFieldHeaderRow() const
2451 + SCROW nCurRow = maOutRange.aStart.Row();
2453 + if (mnPageFields)
2455 + SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
2456 + SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
2457 + nCurRow = nRowEnd + 2;
2459 + else if (mbShowFilter)
2460 + nCurRow += 2;
2462 + if (mnColumnFields)
2463 + nCurRow += static_cast<SCROW>(mnColumnFields);
2464 + else if (mnRowFields)
2465 + ++nCurRow;
2467 + return nCurRow;
2470 +ScDPOutputGeometry::FieldType ScDPOutputGeometry::getFieldButtonType(const ScAddress& rPos) const
2472 + // We will ignore the table position for now.
2474 + bool bExtraTitleRow = (mnColumnFields == 0 && meImportType == ScDPOutputGeometry::XLS);
2475 + bool bDataLayout = mnDataFields > 1;
2477 + SCROW nCurRow = maOutRange.aStart.Row();
2479 + if (mnPageFields)
2481 + SCCOL nCol = maOutRange.aStart.Col();
2482 + SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
2483 + SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
2484 + if (rPos.Col() == nCol && nRowStart <= rPos.Row() && rPos.Row() <= nRowEnd)
2485 + return Page;
2487 + nCurRow = nRowEnd + 2;
2489 + else if (mbShowFilter)
2490 + nCurRow += 2;
2492 + if (mnColumnFields)
2494 + SCROW nRow = nCurRow;
2495 + SCCOL nColStart = maOutRange.aStart.Col() + mnRowFields + bDataLayout;
2496 + SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnColumnFields-1);
2497 + if (rPos.Row() == nRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd)
2498 + return Column;
2500 + nCurRow += static_cast<SCROW>(mnColumnFields);
2503 + if (bExtraTitleRow)
2504 + ++nCurRow;
2506 + if (mnRowFields)
2508 + SCCOL nColStart = maOutRange.aStart.Col();
2509 + SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnRowFields-1);
2510 + if (rPos.Row() == nCurRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd)
2511 + return Row;
2514 + return None;
2516 diff --git sc/source/core/data/dpsave.cxx sc/source/core/data/dpsave.cxx
2517 index b7e04fc..3161155 100644
2518 --- sc/source/core/data/dpsave.cxx
2519 +++ sc/source/core/data/dpsave.cxx
2520 @@ -58,7 +58,15 @@
2521 #include <com/sun/star/container/XNamed.hpp>
2522 #include <com/sun/star/util/XCloneable.hpp>
2524 +#include <hash_map>
2526 using namespace com::sun::star;
2527 +using ::com::sun::star::uno::Reference;
2528 +using ::com::sun::star::uno::Any;
2529 +using ::rtl::OUString;
2530 +using ::rtl::OUStringHash;
2531 +using ::std::hash_map;
2532 +using ::std::auto_ptr;
2534 // -----------------------------------------------------------------------
2536 @@ -99,6 +107,7 @@ void lcl_SetBoolProperty( const uno::Reference<beans::XPropertySet>& xProp,
2538 ScDPSaveMember::ScDPSaveMember(const String& rName) :
2539 aName( rName ),
2540 + mpLayoutName(NULL),
2541 nVisibleMode( SC_DPSAVEMODE_DONTKNOW ),
2542 nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW )
2544 @@ -106,9 +115,12 @@ ScDPSaveMember::ScDPSaveMember(const String& rName) :
2546 ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember& r) :
2547 aName( r.aName ),
2548 + mpLayoutName(NULL),
2549 nVisibleMode( r.nVisibleMode ),
2550 nShowDetailsMode( r.nShowDetailsMode )
2552 + if (r.mpLayoutName.get())
2553 + mpLayoutName.reset(new OUString(*r.mpLayoutName));
2556 ScDPSaveMember::~ScDPSaveMember()
2557 @@ -153,12 +165,23 @@ void ScDPSaveMember::SetName( const String& rNew )
2558 aName = rNew;
2561 -void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
2562 +void ScDPSaveMember::SetLayoutName( const OUString& rName )
2564 - // nothing to do?
2565 - if ( nVisibleMode == SC_DPSAVEMODE_DONTKNOW && nShowDetailsMode == SC_DPSAVEMODE_DONTKNOW && nPosition < 0 )
2566 - return;
2567 + mpLayoutName.reset(new OUString(rName));
2570 +const OUString* ScDPSaveMember::GetLayoutName() const
2572 + return mpLayoutName.get();
2575 +void ScDPSaveMember::RemoveLayoutName()
2577 + mpLayoutName.reset(NULL);
2580 +void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
2582 uno::Reference<beans::XPropertySet> xMembProp( xMember, uno::UNO_QUERY );
2583 DBG_ASSERT( xMembProp.is(), "no properties at member" );
2584 if ( xMembProp.is() )
2585 @@ -173,17 +196,11 @@ void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMemb
2586 lcl_SetBoolProperty( xMembProp,
2587 rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS), (BOOL)nShowDetailsMode );
2589 + if (mpLayoutName.get())
2590 + ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_LAYOUTNAME, *mpLayoutName);
2592 if ( nPosition >= 0 )
2594 - try
2596 - xMembProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_POSITION), uno::Any(nPosition) );
2598 - catch ( uno::Exception& )
2600 - // position is optional - exception must be ignored
2603 + ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, DP_PROP_POSITION, nPosition);
2607 @@ -191,8 +208,9 @@ void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMemb
2609 ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) :
2610 aName( rName ),
2611 - pLayoutName( NULL ),
2612 pSelectedPage( NULL ),
2613 + mpLayoutName(NULL),
2614 + mpSubtotalName(NULL),
2615 bIsDataLayout( bDataLayout ),
2616 bDupFlag( FALSE ),
2617 nOrientation( sheet::DataPilotFieldOrientation_HIDDEN ),
2618 @@ -211,6 +229,8 @@ ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) :
2620 ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) :
2621 aName( r.aName ),
2622 + mpLayoutName(NULL),
2623 + mpSubtotalName(NULL),
2624 bIsDataLayout( r.bIsDataLayout ),
2625 bDupFlag( r.bDupFlag ),
2626 nOrientation( r.nOrientation ),
2627 @@ -251,14 +271,14 @@ ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) :
2628 pLayoutInfo = new sheet::DataPilotFieldLayoutInfo( *(r.pLayoutInfo) );
2629 else
2630 pLayoutInfo = NULL;
2631 - if (r.pLayoutName)
2632 - pLayoutName = new String( *(r.pLayoutName) );
2633 - else
2634 - pLayoutName = NULL;
2635 if (r.pSelectedPage)
2636 pSelectedPage = new String( *(r.pSelectedPage) );
2637 else
2638 pSelectedPage = NULL;
2639 + if (r.mpLayoutName.get())
2640 + mpLayoutName.reset(new OUString(*r.mpLayoutName));
2641 + if (r.mpSubtotalName.get())
2642 + mpSubtotalName.reset(new OUString(*r.mpSubtotalName));
2645 ScDPSaveDimension::~ScDPSaveDimension()
2646 @@ -269,7 +289,6 @@ ScDPSaveDimension::~ScDPSaveDimension()
2647 delete pSortInfo;
2648 delete pAutoShowInfo;
2649 delete pLayoutInfo;
2650 - delete pLayoutName;
2651 delete pSelectedPage;
2652 delete [] pSubTotalFuncs;
2654 @@ -370,25 +389,45 @@ void ScDPSaveDimension::SetUsedHierarchy(long nNew)
2655 nUsedHierarchy = nNew;
2658 -BOOL ScDPSaveDimension::HasLayoutName() const
2659 +void ScDPSaveDimension::SetSubtotalName(const OUString& rName)
2661 - return ( pLayoutName != NULL );
2662 + mpSubtotalName.reset(new OUString(rName));
2665 -void ScDPSaveDimension::SetLayoutName(const String* pName)
2666 +const OUString* ScDPSaveDimension::GetSubtotalName() const
2668 - delete pLayoutName;
2669 - if (pName)
2670 - pLayoutName = new String( *pName );
2671 - else
2672 - pLayoutName = NULL;
2673 + return mpSubtotalName.get();
2676 +bool ScDPSaveDimension::IsMemberNameInUse(const OUString& rName) const
2678 + MemberList::const_iterator itr = maMemberList.begin(), itrEnd = maMemberList.end();
2679 + for (; itr != itrEnd; ++itr)
2681 + const ScDPSaveMember* pMem = *itr;
2682 + if (rName.equalsIgnoreAsciiCase(pMem->GetName()))
2683 + return true;
2685 + const OUString* pLayoutName = pMem->GetLayoutName();
2686 + if (pLayoutName && rName.equalsIgnoreAsciiCase(*pLayoutName))
2687 + return true;
2689 + return false;
2692 +void ScDPSaveDimension::SetLayoutName(const OUString& rName)
2694 + mpLayoutName.reset(new OUString(rName));
2697 -const String& ScDPSaveDimension::GetLayoutName() const
2698 +const OUString* ScDPSaveDimension::GetLayoutName() const
2700 - if (pLayoutName)
2701 - return *pLayoutName;
2702 - return aName;
2703 + return mpLayoutName.get();
2706 +void ScDPSaveDimension::RemoveLayoutName()
2708 + mpLayoutName.reset(NULL);
2711 void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference* pNew)
2712 @@ -520,15 +559,15 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
2713 aFilter = uno::Sequence<sheet::TableFilterField>( &aField, 1 );
2715 // else keep empty sequence
2716 - try
2718 - aAny <<= aFilter;
2719 - xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FILTER), aAny );
2721 - catch ( beans::UnknownPropertyException& )
2723 - // recent addition - allow source to not handle it (no error)
2726 + ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, DP_PROP_FILTER, aFilter);
2727 + if (mpLayoutName.get())
2728 + ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_LAYOUTNAME, *mpLayoutName);
2730 + const OUString* pSubTotalName = GetSubtotalName();
2731 + if (pSubTotalName)
2732 + // Custom subtotal name, with '?' being replaced by the visible field name later.
2733 + ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_FIELD_SUBTOTALNAME, *pSubTotalName);
2736 // Level loop outside of maMemberList loop
2737 @@ -546,6 +585,8 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
2738 nHierCount = xHiers->getCount();
2741 + sal_Bool bHasHiddenMember = false;
2743 for (long nHier=0; nHier<nHierCount; nHier++)
2745 uno::Reference<uno::XInterface> xHierarchy = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHier) );
2746 @@ -585,41 +626,13 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
2747 rtl::OUString::createFromAscii(DP_PROP_SHOWEMPTY), (BOOL)nShowEmptyMode );
2749 if ( pSortInfo )
2751 - aAny <<= *pSortInfo;
2752 - try
2754 - xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_SORTING), aAny );
2756 - catch ( beans::UnknownPropertyException& )
2758 - // recent addition - allow source to not handle it (no error)
2761 + ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_SORTING, *pSortInfo);
2763 if ( pAutoShowInfo )
2765 - aAny <<= *pAutoShowInfo;
2766 - try
2768 - xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_AUTOSHOW), aAny );
2770 - catch ( beans::UnknownPropertyException& )
2772 - // recent addition - allow source to not handle it (no error)
2775 + ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_AUTOSHOW, *pAutoShowInfo);
2777 if ( pLayoutInfo )
2779 - aAny <<= *pLayoutInfo;
2780 - try
2782 - xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_LAYOUT), aAny );
2784 - catch ( beans::UnknownPropertyException& )
2786 - // recent addition - allow source to not handle it (no error)
2789 + ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_LAYOUT, *pLayoutInfo);
2791 // exceptions are caught at ScDPSaveData::WriteToSource
2793 @@ -638,12 +651,15 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
2795 for (MemberList::const_iterator i=maMemberList.begin(); i != maMemberList.end() ; i++)
2797 - rtl::OUString aMemberName = (*i)->GetName();
2798 + ScDPSaveMember* pMember = *i;
2799 + if (!pMember->GetIsVisible())
2800 + bHasHiddenMember = true;
2801 + rtl::OUString aMemberName = pMember->GetName();
2802 if ( xMembers->hasByName( aMemberName ) )
2804 uno::Reference<uno::XInterface> xMemberInt = ScUnoHelpFunctions::AnyToInterface(
2805 xMembers->getByName( aMemberName ) );
2806 - (*i)->WriteToSource( xMemberInt, nPosition );
2807 + pMember->WriteToSource( xMemberInt, nPosition );
2809 if ( nPosition >= 0 )
2810 ++nPosition; // increase if initialized
2811 @@ -655,6 +671,35 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
2816 + if (xDimProp.is())
2817 + ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_HAS_HIDDEN_MEMBER, bHasHiddenMember);
2820 +void ScDPSaveDimension::UpdateMemberVisibility(const hash_map<OUString, bool, OUStringHash>& rData)
2822 + typedef hash_map<OUString, bool, OUStringHash> DataMap;
2823 + MemberList::iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
2824 + for (; itrMem != itrMemEnd; ++itrMem)
2826 + ScDPSaveMember* pMem = *itrMem;
2827 + const String& rMemName = pMem->GetName();
2828 + DataMap::const_iterator itr = rData.find(rMemName);
2829 + if (itr != rData.end())
2830 + pMem->SetIsVisible(itr->second);
2834 +bool ScDPSaveDimension::HasInvisibleMember() const
2836 + MemberList::const_iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
2837 + for (; itrMem != itrMemEnd; ++itrMem)
2839 + const ScDPSaveMember* pMem = *itrMem;
2840 + if (!pMem->GetIsVisible())
2841 + return true;
2843 + return false;
2846 // -----------------------------------------------------------------------
2847 @@ -666,7 +711,9 @@ ScDPSaveData::ScDPSaveData() :
2848 nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
2849 nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
2850 bFilterButton( TRUE ),
2851 - bDrillDown( TRUE )
2852 + bDrillDown( TRUE ),
2853 + mbDimensionMembersBuilt(false),
2854 + mpGrandTotalName(NULL)
2858 @@ -676,7 +723,9 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) :
2859 nIgnoreEmptyMode( r.nIgnoreEmptyMode ),
2860 nRepeatEmptyMode( r.nRepeatEmptyMode ),
2861 bFilterButton( r.bFilterButton ),
2862 - bDrillDown( r.bDrillDown )
2863 + bDrillDown( r.bDrillDown ),
2864 + mbDimensionMembersBuilt(r.mbDimensionMembersBuilt),
2865 + mpGrandTotalName(NULL)
2867 if ( r.pDimensionData )
2868 pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData );
2869 @@ -689,6 +738,9 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) :
2870 ScDPSaveDimension* pNew = new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) );
2871 aDimList.Insert( pNew, LIST_APPEND );
2874 + if (r.mpGrandTotalName.get())
2875 + mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
2878 ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
2879 @@ -707,6 +759,7 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
2880 nRepeatEmptyMode = r.nRepeatEmptyMode;
2881 bFilterButton = r.bFilterButton;
2882 bDrillDown = r.bDrillDown;
2883 + mbDimensionMembersBuilt = r.mbDimensionMembersBuilt;
2885 // remove old dimensions
2887 @@ -725,6 +778,9 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
2888 new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) );
2889 aDimList.Insert( pNew, LIST_APPEND );
2892 + if (r.mpGrandTotalName.get())
2893 + mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
2895 return *this;
2897 @@ -736,7 +792,8 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const
2898 nIgnoreEmptyMode != r.nIgnoreEmptyMode ||
2899 nRepeatEmptyMode != r.nRepeatEmptyMode ||
2900 bFilterButton != r.bFilterButton ||
2901 - bDrillDown != r.bDrillDown )
2902 + bDrillDown != r.bDrillDown ||
2903 + mbDimensionMembersBuilt != r.mbDimensionMembersBuilt)
2904 return FALSE;
2906 if ( pDimensionData || r.pDimensionData )
2907 @@ -752,6 +809,16 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const
2908 *(ScDPSaveDimension*)r.aDimList.GetObject(i) ) )
2909 return FALSE;
2911 + if (mpGrandTotalName.get())
2913 + if (!r.mpGrandTotalName.get())
2914 + return false;
2915 + if (!mpGrandTotalName->equals(*r.mpGrandTotalName))
2916 + return false;
2918 + else if (r.mpGrandTotalName.get())
2919 + return false;
2921 return TRUE;
2924 @@ -765,6 +832,16 @@ ScDPSaveData::~ScDPSaveData()
2925 delete pDimensionData;
2928 +void ScDPSaveData::SetGrandTotalName(const OUString& rName)
2930 + mpGrandTotalName.reset(new OUString(rName));
2933 +const OUString* ScDPSaveData::GetGrandTotalName() const
2935 + return mpGrandTotalName.get();
2938 ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName)
2940 long nCount = aDimList.Count();
2941 @@ -779,7 +856,7 @@ ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName)
2942 return pNew;
2945 -ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName)
2946 +ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName) const
2948 long nCount = aDimList.Count();
2949 for (long i=0; i<nCount; i++)
2950 @@ -807,16 +884,25 @@ ScDPSaveDimension* ScDPSaveData::GetNewDimensionByName(const String& rName)
2952 ScDPSaveDimension* ScDPSaveData::GetDataLayoutDimension()
2954 - ULONG nCount = aDimList.Count();
2955 - for (ULONG i=0; i<nCount; i++)
2956 + ScDPSaveDimension* pDim = GetExistingDataLayoutDimension();
2957 + if (pDim)
2958 + return pDim;
2960 + ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), TRUE );
2961 + aDimList.Insert( pNew, LIST_APPEND );
2962 + return pNew;
2965 +ScDPSaveDimension* ScDPSaveData::GetExistingDataLayoutDimension() const
2967 + long nCount = aDimList.Count();
2968 + for (long i=0; i<nCount; i++)
2970 ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
2971 if ( pDim->IsDataLayout() )
2972 return pDim;
2974 - ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), TRUE );
2975 - aDimList.Insert( pNew, LIST_APPEND );
2976 - return pNew;
2977 + return NULL;
2980 ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const String& rName)
2981 @@ -870,6 +956,18 @@ ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(USHORT nOrientation)
2982 return pInner; // the last matching one
2985 +ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation)
2987 + long nCount = aDimList.Count();
2988 + for (long i = 0; i < nCount; ++i)
2990 + ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
2991 + if (pDim->GetOrientation() == eOrientation && !pDim->IsDataLayout())
2992 + return pDim;
2994 + return NULL;
2997 long ScDPSaveData::GetDataDimensionCount() const
2999 long nDataCount = 0;
3000 @@ -982,6 +1080,10 @@ void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplie
3002 // no error
3005 + const OUString* pGrandTotalName = GetGrandTotalName();
3006 + if (pGrandTotalName)
3007 + ScUnoHelpFunctions::SetOptionalPropertyValue(xSourceProp, SC_UNO_GRANDTOTAL_NAME, *pGrandTotalName);
3010 // exceptions in the other calls are errors
3011 @@ -1100,3 +1202,58 @@ void ScDPSaveData::SetDimensionData( const ScDPDimensionSaveData* pNew )
3012 pDimensionData = NULL;
3015 +void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData)
3017 + if (mbDimensionMembersBuilt)
3018 + return;
3020 + // First, build a dimension name-to-index map.
3021 + typedef hash_map<OUString, long, ::rtl::OUStringHash> NameIndexMap;
3022 + NameIndexMap aMap;
3023 + long nColCount = pData->GetColumnCount();
3024 + for (long i = 0; i < nColCount; ++i)
3025 + aMap.insert( NameIndexMap::value_type(pData->getDimensionName(i), i));
3027 + NameIndexMap::const_iterator itrEnd = aMap.end();
3029 + sal_uInt32 n = aDimList.Count();
3030 + for (sal_uInt32 i = 0; i < n; ++i)
3032 + ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
3033 + const String& rDimName = pDim->GetName();
3034 + if (!rDimName.Len())
3035 + // empty dimension name. It must be data layout.
3036 + continue;
3038 + NameIndexMap::const_iterator itr = aMap.find(rDimName);
3039 + if (itr == itrEnd)
3040 + // dimension name not in the data. This should never happen!
3041 + continue;
3043 + long nDimIndex = itr->second;
3044 + const TypedScStrCollection& rMembers = pData->GetColumnEntries(nDimIndex);
3045 + sal_uInt16 nMemberCount = rMembers.GetCount();
3046 + for (sal_uInt16 j = 0; j < nMemberCount; ++j)
3048 + const String& rMemName = rMembers[j]->GetString();
3049 + if (pDim->GetExistingMemberByName(rMemName))
3050 + // this member instance already exists. nothing to do.
3051 + continue;
3053 + auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(rMemName));
3054 + pNewMember->SetIsVisible(true);
3055 + pDim->AddMember(pNewMember.release());
3059 + mbDimensionMembersBuilt = true;
3062 +bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const
3064 + ScDPSaveDimension* pDim = GetExistingDimensionByName(rDimName);
3065 + if (!pDim)
3066 + return false;
3068 + return pDim->HasInvisibleMember();
3070 diff --git sc/source/core/data/dptabres.cxx sc/source/core/data/dptabres.cxx
3071 index 675a0a5..0494bc6 100644
3072 --- sc/source/core/data/dptabres.cxx
3073 +++ sc/source/core/data/dptabres.cxx
3074 @@ -67,6 +67,7 @@ using ::std::vector;
3075 using ::std::pair;
3076 using ::std::hash_map;
3077 using ::com::sun::star::uno::Sequence;
3078 +using ::rtl::OUString;
3080 // -----------------------------------------------------------------------
3082 @@ -825,11 +826,11 @@ USHORT ScDPResultData::GetMeasureRefOrient(long nMeasure) const
3083 return pMeasRefOrient[nMeasure];
3086 -String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc) const
3087 +String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const
3089 // with bForce==TRUE, return function instead of "result" for single measure
3090 // with eForceFunc != SUBTOTAL_FUNC_NONE, always use eForceFunc
3092 + rbTotalResult = false;
3093 if ( nMeasure < 0 || ( nMeasCount == 1 && !bForce && eForceFunc == SUBTOTAL_FUNC_NONE ) )
3095 // for user-specified subtotal function with all measures,
3096 @@ -837,12 +838,19 @@ String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFu
3097 if ( eForceFunc != SUBTOTAL_FUNC_NONE )
3098 return ScGlobal::GetRscString(nFuncStrIds[eForceFunc]);
3100 + rbTotalResult = true;
3101 return ScGlobal::GetRscString(STR_TABLE_ERGEBNIS);
3103 else
3105 DBG_ASSERT( pMeasNames && nMeasure < nMeasCount, "bumm" );
3107 + ScDPDimension* pDataDim = pSource->GetDataDimension(nMeasure);
3108 + if (pDataDim)
3110 + const OUString* pLayoutName = pDataDim->GetLayoutName();
3111 + if (pLayoutName)
3112 + return *pLayoutName;
3114 String aRet;
3115 ScSubTotalFunc eFunc = ( eForceFunc == SUBTOTAL_FUNC_NONE ) ?
3116 GetMeasureFunction(nMeasure) : eForceFunc;
3117 @@ -896,6 +904,11 @@ BOOL ScDPResultData::HasCommonElement( const ScDPItemData& rFirstData, long nFir
3118 return pSource->GetData()->HasCommonElement( rFirstData, nFirstIndex, rSecondData, nSecondIndex );
3121 +const ScDPSource* ScDPResultData::GetSource() const
3123 + return pSource;
3126 // -----------------------------------------------------------------------
3129 @@ -1172,6 +1185,33 @@ void ScDPResultMember::ProcessData( const vector<ScDPItemData>& aChildMembers, c
3133 +/**
3134 + * Parse subtotal string and replace all occurrences of '?' with the caption
3135 + * string. Do ensure that escaped characters are not translated.
3136 + */
3137 +static String lcl_parseSubtotalName(const String& rSubStr, const String& rCaption)
3139 + String aNewStr;
3140 + xub_StrLen n = rSubStr.Len();
3141 + bool bEscaped = false;
3142 + for (xub_StrLen i = 0; i < n; ++i)
3144 + sal_Unicode c = rSubStr.GetChar(i);
3145 + if (!bEscaped && c == sal_Unicode('\\'))
3147 + bEscaped = true;
3148 + continue;
3151 + if (!bEscaped && c == sal_Unicode('?'))
3152 + aNewStr.Append(rCaption);
3153 + else
3154 + aNewStr.Append(c);
3155 + bEscaped = false;
3157 + return aNewStr;
3160 void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pSequences,
3161 long& rPos, long nMeasure, BOOL bRoot,
3162 const String* pMemberName,
3163 @@ -1204,17 +1244,25 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS
3166 String aCaption = aName;
3167 + if (pMemberDesc)
3169 + const OUString* pLayoutName = pMemberDesc->GetLayoutName();
3170 + if (pLayoutName)
3172 + aCaption = *pLayoutName;
3173 + bIsNumeric = false; // layout name is always non-numeric.
3177 if ( pMemberCaption ) // use pMemberCaption if != NULL
3178 aCaption = *pMemberCaption;
3179 if (!aCaption.Len())
3180 aCaption = ScGlobal::GetRscString(STR_EMPTYDATA);
3182 - if ( !bIsNumeric )
3184 - // add a "'" character so a string isn't parsed as value in the output cell
3185 - //! have a separate bit in Flags (MemberResultFlags) instead?
3186 - aCaption.Insert( (sal_Unicode) '\'', 0 );
3188 + if (bIsNumeric)
3189 + pArray[rPos].Flags |= sheet::MemberResultFlags::NUMERIC;
3190 + else
3191 + pArray[rPos].Flags &= ~sheet::MemberResultFlags::NUMERIC;
3193 if ( nSize && !bRoot ) // root is overwritten by first dimension
3195 @@ -1277,9 +1325,30 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS
3196 if (bHasChild)
3197 eForce = lcl_GetForceFunc( pParentLevel, nUserPos );
3199 - String aSubStr = aName; //! caption?
3200 + bool bTotalResult = false;
3201 + String aSubStr = aCaption;
3202 aSubStr += ' ';
3203 - aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce);
3204 + aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce, bTotalResult);
3206 + if (bTotalResult)
3208 + if (pMemberDesc)
3210 + // single data field layout.
3211 + const OUString* pSubtotalName = pParentDim->GetSubtotalName();
3212 + if (pSubtotalName)
3213 + aSubStr = lcl_parseSubtotalName(*pSubtotalName, aCaption);
3214 + pArray[rPos].Flags &= ~sheet::MemberResultFlags::GRANDTOTAL;
3216 + else
3218 + // root member - subtotal (grand total?) for multi-data field layout.
3219 + const rtl::OUString* pGrandTotalName = pResultData->GetSource()->GetGrandTotalName();
3220 + if (pGrandTotalName)
3221 + aSubStr = *pGrandTotalName;
3222 + pArray[rPos].Flags |= sheet::MemberResultFlags::GRANDTOTAL;
3226 pArray[rPos].Name = rtl::OUString(aName);
3227 pArray[rPos].Caption = rtl::OUString(aSubStr);
3228 @@ -2796,8 +2865,9 @@ void ScDPResultDimension::FillMemberResults( uno::Sequence<sheet::MemberResult>*
3229 // in data layout dimension, use first member with different measures/names
3230 if ( bIsDataLayout )
3232 + bool bTotalResult = false;
3233 String aMbrName = pResultData->GetMeasureDimensionName( nSorted );
3234 - String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE );
3235 + String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE, bTotalResult );
3236 maMemberArray[0]->FillMemberResults( pSequences, nPos, nSorted, FALSE, &aMbrName, &aMbrCapt );
3238 else if ( pMember->IsVisible() )
3239 diff --git sc/source/core/data/dptabsrc.cxx sc/source/core/data/dptabsrc.cxx
3240 index 3b5a6e0..1216202 100644
3241 --- sc/source/core/data/dptabsrc.cxx
3242 +++ sc/source/core/data/dptabsrc.cxx
3243 @@ -85,6 +85,7 @@ using ::com::sun::star::uno::Reference;
3244 using ::com::sun::star::uno::Sequence;
3245 using ::com::sun::star::uno::Any;
3246 using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
3247 +using ::rtl::OUString;
3249 // -----------------------------------------------------------------------
3251 @@ -141,15 +142,14 @@ ScDPSource::ScDPSource( ScDPTableData* pD ) :
3252 pRowResRoot( NULL ),
3253 pColResults( NULL ),
3254 pRowResults( NULL ),
3255 - bResultOverflow( FALSE )
3256 + bResultOverflow( FALSE ),
3257 + mpGrandTotalName(NULL)
3259 pData->SetEmptyFlags( bIgnoreEmptyRows, bRepeatIfEmpty );
3262 ScDPSource::~ScDPSource()
3264 - delete pData; // ScDPTableData is not ref-counted
3266 if (pDimensions)
3267 pDimensions->release(); // ref-counted
3269 @@ -163,6 +163,16 @@ ScDPSource::~ScDPSource()
3270 delete pResData;
3273 +void ScDPSource::SetGrandTotalName(const ::rtl::OUString& rName)
3275 + mpGrandTotalName.reset(new ::rtl::OUString(rName));
3278 +const ::rtl::OUString* ScDPSource::GetGrandTotalName() const
3280 + return mpGrandTotalName.get();
3283 USHORT ScDPSource::GetOrientation(long nColumn)
3285 long i;
3286 @@ -186,16 +196,21 @@ long ScDPSource::GetDataDimensionCount()
3287 return nDataDimCount;
3290 +ScDPDimension* ScDPSource::GetDataDimension(long nIndex)
3292 + if (nIndex < 0 || nIndex >= nDataDimCount)
3293 + return NULL;
3295 + long nDimIndex = nDataDims[nIndex];
3296 + return GetDimensionsObject()->getByIndex(nDimIndex);
3299 String ScDPSource::GetDataDimName( long nIndex )
3301 String aRet;
3302 - if ( nIndex >= 0 && nIndex < nDataDimCount )
3304 - long nDimIndex = nDataDims[nIndex];
3305 - ScDPDimension* pDim = GetDimensionsObject()->getByIndex(nDimIndex);
3306 - if (pDim)
3307 - aRet = String( pDim->getName() );
3309 + ScDPDimension* pDim = GetDataDimension(nIndex);
3310 + if (pDim)
3311 + aRet = String(pDim->getName());
3312 return aRet;
3315 @@ -488,7 +503,10 @@ String ScDPSource::getDataDescription()
3317 String aRet;
3318 if ( pResData->GetMeasureCount() == 1 )
3319 - aRet = pResData->GetMeasureString( 0, TRUE, SUBTOTAL_FUNC_NONE );
3321 + bool bTotalResult = false;
3322 + aRet = pResData->GetMeasureString( 0, TRUE, SUBTOTAL_FUNC_NONE, bTotalResult );
3325 // empty for more than one measure
3327 @@ -1132,6 +1150,7 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPSource::getPropertySetInfo(
3328 throw(uno::RuntimeException)
3330 ScUnoGuard aGuard;
3331 + using beans::PropertyAttribute::READONLY;
3333 static SfxItemPropertyMapEntry aDPSourceMap_Impl[] =
3335 @@ -1140,6 +1159,10 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPSource::getPropertySetInfo(
3336 {MAP_CHAR_LEN(SC_UNO_IGNOREEM), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
3337 {MAP_CHAR_LEN(SC_UNO_REPEATIF), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
3338 {MAP_CHAR_LEN(SC_UNO_ROWGRAND), 0, &getBooleanCppuType(), 0, 0 },
3339 + {MAP_CHAR_LEN(SC_UNO_ROWFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
3340 + {MAP_CHAR_LEN(SC_UNO_COLUMNFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
3341 + {MAP_CHAR_LEN(SC_UNO_DATAFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
3342 + {MAP_CHAR_LEN(SC_UNO_GRANDTOTAL_NAME), 0, &getCppuType(static_cast<OUString*>(0)), 0, 0 },
3343 {0,0,0,0,0,0}
3345 static uno::Reference<beans::XPropertySetInfo> aRef =
3346 @@ -1161,6 +1184,12 @@ void SAL_CALL ScDPSource::setPropertyValue( const rtl::OUString& aPropertyName,
3347 setIgnoreEmptyRows( lcl_GetBoolFromAny( aValue ) );
3348 else if ( aNameStr.EqualsAscii( SC_UNO_REPEATIF ) )
3349 setRepeatIfEmpty( lcl_GetBoolFromAny( aValue ) );
3350 + else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME))
3352 + OUString aName;
3353 + if (aValue >>= aName)
3354 + mpGrandTotalName.reset(new OUString(aName));
3356 else
3358 DBG_ERROR("unknown property");
3359 @@ -1190,6 +1219,11 @@ uno::Any SAL_CALL ScDPSource::getPropertyValue( const rtl::OUString& aPropertyNa
3360 aRet <<= static_cast<sal_Int32>(nColDimCount);
3361 else if ( aNameStr.EqualsAscii( SC_UNO_DATAFIELDCOUNT ) ) // read-only
3362 aRet <<= static_cast<sal_Int32>(nDataDimCount);
3363 + else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME))
3365 + if (mpGrandTotalName.get())
3366 + aRet <<= *mpGrandTotalName;
3368 else
3370 DBG_ERROR("unknown property");
3371 @@ -1337,9 +1371,12 @@ ScDPDimension::ScDPDimension( ScDPSource* pSrc, long nD ) :
3372 pHierarchies( NULL ),
3373 nUsedHier( 0 ),
3374 nFunction( SUBTOTAL_FUNC_SUM ), // sum is default
3375 + mpLayoutName(NULL),
3376 + mpSubtotalName(NULL),
3377 nSourceDim( -1 ),
3378 bHasSelectedPage( FALSE ),
3379 - pSelectedData( NULL )
3380 + pSelectedData( NULL ),
3381 + mbHasHiddenMember(false)
3383 //! hold pSource
3385 @@ -1364,6 +1401,16 @@ ScDPHierarchies* ScDPDimension::GetHierarchiesObject()
3386 return pHierarchies;
3389 +const rtl::OUString* ScDPDimension::GetLayoutName() const
3391 + return mpLayoutName.get();
3394 +const rtl::OUString* ScDPDimension::GetSubtotalName() const
3396 + return mpSubtotalName.get();
3399 uno::Reference<container::XNameAccess> SAL_CALL ScDPDimension::getHierarchies()
3400 throw(uno::RuntimeException)
3402 @@ -1523,6 +1570,9 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPDimension::getPropertySetIn
3403 {MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 },
3404 {MAP_CHAR_LEN(SC_UNO_REFVALUE), 0, &getCppuType((sheet::DataPilotFieldReference*)0), 0, 0 },
3405 {MAP_CHAR_LEN(SC_UNO_USEDHIER), 0, &getCppuType((sal_Int32*)0), 0, 0 },
3406 + {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
3407 + {MAP_CHAR_LEN(SC_UNO_FIELD_SUBTOTALNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
3408 + {MAP_CHAR_LEN(SC_UNO_HAS_HIDDEN_MEMBER), 0, &getBooleanCppuType(), 0, 0 },
3409 {0,0,0,0,0,0}
3411 static uno::Reference<beans::XPropertySetInfo> aRef =
3412 @@ -1593,6 +1643,20 @@ void SAL_CALL ScDPDimension::setPropertyValue( const rtl::OUString& aPropertyNam
3414 DELETEZ( pSelectedData ); // invalid after changing aSelectedPage
3416 + else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
3418 + OUString aTmpName;
3419 + if (aValue >>= aTmpName)
3420 + mpLayoutName.reset(new OUString(aTmpName));
3422 + else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME))
3424 + OUString aTmpName;
3425 + if (aValue >>= aTmpName)
3426 + mpSubtotalName.reset(new OUString(aTmpName));
3428 + else if (aNameStr.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER))
3429 + aValue >>= mbHasHiddenMember;
3430 else
3432 DBG_ERROR("unknown property");
3433 @@ -1652,6 +1716,12 @@ uno::Any SAL_CALL ScDPDimension::getPropertyValue( const rtl::OUString& aPropert
3434 else
3435 aRet <<= uno::Sequence<sheet::TableFilterField>(0);
3437 + else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
3438 + aRet <<= mpLayoutName.get() ? *mpLayoutName : OUString::createFromAscii("");
3439 + else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME))
3440 + aRet <<= mpSubtotalName.get() ? *mpSubtotalName : OUString::createFromAscii("");
3441 + else if (aNameStr.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER))
3442 + aRet <<= mbHasHiddenMember;
3443 else
3445 DBG_ERROR("unknown property");
3446 @@ -2155,7 +2225,11 @@ uno::Sequence<sheet::MemberResult> SAL_CALL ScDPLevel::getResults() throw(uno::R
3447 return aRet;
3450 - return pSource->GetData()->getDimensionName( nSrcDim ); // (original) dimension name
3451 + ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
3452 + if (!pDim)
3453 + return rtl::OUString();
3455 + return pDim->getName();
3458 void SAL_CALL ScDPLevel::setName( const ::rtl::OUString& /* rNewName */ ) throw(uno::RuntimeException)
3459 @@ -2258,6 +2332,20 @@ uno::Any SAL_CALL ScDPLevel::getPropertyValue( const rtl::OUString& aPropertyNam
3460 aRet <<= aAutoShowInfo;
3461 else if ( aNameStr.EqualsAscii( SC_UNO_LAYOUT ) )
3462 aRet <<= aLayoutInfo;
3463 + else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
3465 + // read only property
3466 + long nSrcDim = pSource->GetSourceDim(nDim);
3467 + ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
3468 + if (!pDim)
3469 + return aRet;
3471 + const OUString* pLayoutName = pDim->GetLayoutName();
3472 + if (!pLayoutName)
3473 + return aRet;
3475 + aRet <<= *pLayoutName;
3477 else
3479 DBG_ERROR("unknown property");
3480 @@ -2550,6 +2638,7 @@ ScDPMember::ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL,
3481 nHier( nH ),
3482 nLev( nL ),
3483 maData( rN, fV, bHV ),
3484 + mpLayoutName(NULL),
3485 nPosition( -1 ),
3486 bVisible( TRUE ),
3487 bShowDet( TRUE )
3488 @@ -2610,6 +2699,11 @@ void ScDPMember::FillItemData( ScDPItemData& rData ) const
3489 rData = maData;
3492 +const OUString* ScDPMember::GetLayoutName() const
3494 + return mpLayoutName.get();
3497 String ScDPMember::GetNameStr() const
3499 return maData.aString;
3500 @@ -2669,6 +2763,7 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPMember::getPropertySetInfo(
3501 {MAP_CHAR_LEN(SC_UNO_ISVISIBL), 0, &getBooleanCppuType(), 0, 0 },
3502 {MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 },
3503 {MAP_CHAR_LEN(SC_UNO_SHOWDETA), 0, &getBooleanCppuType(), 0, 0 },
3504 + {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
3505 {0,0,0,0,0,0}
3507 static uno::Reference<beans::XPropertySetInfo> aRef =
3508 @@ -2692,6 +2787,12 @@ void SAL_CALL ScDPMember::setPropertyValue( const rtl::OUString& aPropertyName,
3509 if (aValue >>= nInt)
3510 setPosition( nInt );
3512 + else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
3514 + rtl::OUString aName;
3515 + if (aValue >>= aName)
3516 + mpLayoutName.reset(new rtl::OUString(aName));
3518 else
3520 DBG_ERROR("unknown property");
3521 @@ -2711,6 +2812,8 @@ uno::Any SAL_CALL ScDPMember::getPropertyValue( const rtl::OUString& aPropertyNa
3522 lcl_SetBoolInAny( aRet, getShowDetails() );
3523 else if ( aNameStr.EqualsAscii( SC_UNO_POSITION ) )
3524 aRet <<= (sal_Int32) getPosition();
3525 + else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
3526 + aRet <<= mpLayoutName.get() ? *mpLayoutName : rtl::OUString();
3527 else
3529 DBG_ERROR("unknown property");
3530 diff --git sc/source/core/data/fillinfo.cxx sc/source/core/data/fillinfo.cxx
3531 index 1de2385..54ffe10 100644
3532 --- sc/source/core/data/fillinfo.cxx
3533 +++ sc/source/core/data/fillinfo.cxx
3534 @@ -332,6 +332,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
3535 pInfo->bVOverlapped = FALSE;
3536 pInfo->bAutoFilter = FALSE;
3537 pInfo->bPushButton = FALSE;
3538 + pInfo->bPopupButton = false;
3539 + pInfo->bFilterActive = false;
3540 pInfo->nRotateDir = SC_ROTDIR_NONE;
3542 pInfo->bPrinted = FALSE; // view-intern
3543 @@ -458,6 +460,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
3544 BOOL bAutoFilter = ((nOverlap & SC_MF_AUTO) != 0);
3545 BOOL bPushButton = ((nOverlap & SC_MF_BUTTON) != 0);
3546 BOOL bScenario = ((nOverlap & SC_MF_SCENARIO) != 0);
3547 + bool bPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0);
3548 + bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0);
3549 if (bMerged||bHOverlapped||bVOverlapped)
3550 bAnyMerged = TRUE; // intern
3552 @@ -498,6 +502,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
3553 pInfo->bVOverlapped = bVOverlapped;
3554 pInfo->bAutoFilter = bAutoFilter;
3555 pInfo->bPushButton = bPushButton;
3556 + pInfo->bPopupButton = bPopupButton;
3557 + pInfo->bFilterActive = bFilterActive;
3558 pInfo->pLinesAttr = pLinesAttr;
3559 pInfo->mpTLBRLine = pTLBRLine;
3560 pInfo->mpBLTRLine = pBLTRLine;
3561 @@ -512,7 +518,7 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
3562 nCurRow >= aEmbedRange.aStart.Row() &&
3563 nCurRow <= aEmbedRange.aEnd.Row();
3565 - if (bPushButton || bScenario)
3566 + if (bScenario)
3568 pInfo->pBackground = ScGlobal::GetButtonBrushItem();
3569 pThisRowInfo->bEmptyBack = FALSE;
3570 diff --git sc/source/core/data/global2.cxx sc/source/core/data/global2.cxx
3571 index 925f34e..f71b842 100644
3572 --- sc/source/core/data/global2.cxx
3573 +++ sc/source/core/data/global2.cxx
3574 @@ -56,6 +56,7 @@
3575 #include "sc.hrc"
3576 #include "globstr.hrc"
3578 +using ::std::vector;
3580 // -----------------------------------------------------------------------
3582 @@ -817,7 +818,6 @@ bool PivotField::operator==( const PivotField& r ) const
3584 ScPivotParam::ScPivotParam()
3585 : nCol(0), nRow(0), nTab(0),
3586 - ppLabelArr( NULL ), nLabels(0),
3587 nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0),
3588 bIgnoreEmptyRows(FALSE), bDetectCategories(FALSE),
3589 bMakeTotalCol(TRUE), bMakeTotalRow(TRUE)
3590 @@ -828,23 +828,22 @@ ScPivotParam::ScPivotParam()
3592 ScPivotParam::ScPivotParam( const ScPivotParam& r )
3593 : nCol( r.nCol ), nRow( r.nRow ), nTab( r.nTab ),
3594 - ppLabelArr( NULL ), nLabels(0),
3595 nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0),
3596 bIgnoreEmptyRows(r.bIgnoreEmptyRows),
3597 bDetectCategories(r.bDetectCategories),
3598 bMakeTotalCol(r.bMakeTotalCol),
3599 bMakeTotalRow(r.bMakeTotalRow)
3601 - SetLabelData ( r.ppLabelArr, r.nLabels );
3602 SetPivotArrays ( r.aPageArr, r.aColArr, r.aRowArr, r.aDataArr,
3603 r.nPageCount, r.nColCount, r.nRowCount, r.nDataCount );
3605 + SetLabelData(r.maLabelArray);
3608 //------------------------------------------------------------------------
3610 __EXPORT ScPivotParam::~ScPivotParam()
3612 - ClearLabelData();
3615 //------------------------------------------------------------------------
3616 @@ -860,22 +859,6 @@ __EXPORT ScPivotParam::~ScPivotParam()
3617 //UNUSED2009-05 ClearPivotArrays();
3618 //UNUSED2009-05 }
3620 -//------------------------------------------------------------------------
3622 -void __EXPORT ScPivotParam::ClearLabelData()
3624 - if ( (nLabels > 0) && ppLabelArr )
3626 - for ( SCSIZE i=0; i<nLabels; i++ )
3627 - delete ppLabelArr[i];
3628 - delete [] ppLabelArr;
3629 - ppLabelArr = NULL;
3630 - nLabels = 0;
3634 -//------------------------------------------------------------------------
3636 void __EXPORT ScPivotParam::ClearPivotArrays()
3638 memset( aPageArr, 0, PIVOT_MAXPAGEFIELD * sizeof(PivotField) );
3639 @@ -888,20 +871,17 @@ void __EXPORT ScPivotParam::ClearPivotArrays()
3640 nDataCount = 0;
3643 -//------------------------------------------------------------------------
3645 -void __EXPORT ScPivotParam::SetLabelData( LabelData** pLabArr,
3646 - SCSIZE nLab )
3647 +void ScPivotParam::SetLabelData(const vector<ScDPLabelDataRef>& r)
3649 - ClearLabelData();
3651 - if ( (nLab > 0) && pLabArr )
3652 + vector<ScDPLabelDataRef> aNewArray;
3653 + aNewArray.reserve(r.size());
3654 + for (vector<ScDPLabelDataRef>::const_iterator itr = r.begin(), itrEnd = r.end();
3655 + itr != itrEnd; ++itr)
3657 - nLabels = (nLab>MAX_LABELS) ? MAX_LABELS : nLab;
3658 - ppLabelArr = new LabelData*[nLabels];
3659 - for ( SCSIZE i=0; i<nLabels; i++ )
3660 - ppLabelArr[i] = new LabelData( *(pLabArr[i]) );
3661 + ScDPLabelDataRef p(new ScDPLabelData(**itr));
3662 + aNewArray.push_back(p);
3664 + maLabelArray.swap(aNewArray);
3667 //------------------------------------------------------------------------
3668 @@ -943,10 +923,9 @@ ScPivotParam& __EXPORT ScPivotParam::operator=( const ScPivotParam& r )
3669 bMakeTotalCol = r.bMakeTotalCol;
3670 bMakeTotalRow = r.bMakeTotalRow;
3672 - SetLabelData ( r.ppLabelArr, r.nLabels );
3673 SetPivotArrays ( r.aPageArr, r.aColArr, r.aRowArr, r.aDataArr,
3674 r.nPageCount, r.nColCount, r.nRowCount, r.nDataCount );
3676 + SetLabelData(r.maLabelArray);
3677 return *this;
3680 @@ -961,7 +940,7 @@ BOOL __EXPORT ScPivotParam::operator==( const ScPivotParam& r ) const
3681 && (bDetectCategories == r.bDetectCategories)
3682 && (bMakeTotalCol == r.bMakeTotalCol)
3683 && (bMakeTotalRow == r.bMakeTotalRow)
3684 - && (nLabels == r.nLabels)
3685 + && (maLabelArray.size() == r.maLabelArray.size())
3686 && (nPageCount == r.nPageCount)
3687 && (nColCount == r.nColCount)
3688 && (nRowCount == r.nRowCount)
3689 diff --git sc/source/core/data/makefile.mk sc/source/core/data/makefile.mk
3690 index 29618da..6a2898b 100644
3691 --- sc/source/core/data/makefile.mk
3692 +++ sc/source/core/data/makefile.mk
3693 @@ -78,6 +78,7 @@ SLOFILES = \
3694 $(SLO)$/dpgroup.obj \
3695 $(SLO)$/dpobject.obj \
3696 $(SLO)$/dpoutput.obj \
3697 + $(SLO)$/dpoutputgeometry.obj \
3698 $(SLO)$/dpsave.obj \
3699 $(SLO)$/dpsdbtab.obj \
3700 $(SLO)$/dpshttab.obj \
3701 @@ -140,6 +141,7 @@ EXCEPTIONSFILES= \
3702 $(SLO)$/dpsdbtab.obj \
3703 $(SLO)$/dpobject.obj \
3704 $(SLO)$/dpoutput.obj \
3705 + $(SLO)$/dpoutputgeometry.obj \
3706 $(SLO)$/dpsave.obj \
3707 $(SLO)$/dbdocutl.obj \
3708 $(SLO)$/dptabsrc.obj \
3709 diff --git sc/source/core/data/pivot2.cxx sc/source/core/data/pivot2.cxx
3710 index 70f48dc..7365e6d 100644
3711 --- sc/source/core/data/pivot2.cxx
3712 +++ sc/source/core/data/pivot2.cxx
3713 @@ -61,11 +61,26 @@
3714 #include "stlsheet.hxx"
3716 using ::com::sun::star::sheet::DataPilotFieldReference;
3717 +using ::rtl::OUString;
3719 // STATIC DATA -----------------------------------------------------------
3720 // ============================================================================
3722 -LabelData::LabelData( const String& rName, short nCol, bool bIsValue ) :
3723 +ScDPLabelData::Member::Member() :
3724 + mbVisible(true),
3725 + mbShowDetails(true)
3729 +OUString ScDPLabelData::Member::getDisplayName() const
3731 + if (maLayoutName.getLength())
3732 + return maLayoutName;
3734 + return maName;
3737 +ScDPLabelData::ScDPLabelData( const String& rName, short nCol, bool bIsValue ) :
3738 maName( rName ),
3739 mnCol( nCol ),
3740 mnFuncMask( PIVOT_FUNC_NONE ),
3741 @@ -76,6 +91,14 @@ LabelData::LabelData( const String& rName, short nCol, bool bIsValue ) :
3745 +OUString ScDPLabelData::getDisplayName() const
3747 + if (maLayoutName.getLength())
3748 + return maLayoutName;
3750 + return maName;
3753 // ============================================================================
3755 ScDPFuncData::ScDPFuncData( short nCol, USHORT nFuncMask ) :
3756 diff --git sc/source/core/data/table2.cxx sc/source/core/data/table2.cxx
3757 index 464bf4c..eac760e 100644
3758 --- sc/source/core/data/table2.cxx
3759 +++ sc/source/core/data/table2.cxx
3760 @@ -962,6 +962,14 @@ ScBaseCell* ScTable::GetCell( SCCOL nCol, SCROW nRow ) const
3761 return NULL;
3764 +void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
3766 + rCol = 0;
3767 + rRow = 0;
3768 + while (aCol[rCol].IsEmptyData() && rCol < MAXCOL)
3769 + ++rCol;
3770 + rRow = aCol[rCol].GetFirstDataPos();
3773 void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const
3775 diff --git sc/source/filter/excel/read.cxx sc/source/filter/excel/read.cxx
3776 index da460a2..6876c90 100644
3777 --- sc/source/filter/excel/read.cxx
3778 +++ sc/source/filter/excel/read.cxx
3779 @@ -1146,6 +1146,7 @@ FltError ImportExcel8::Read( void )
3780 case EXC_ID_SXDI: rPTableMgr.ReadSxdi( maStrm ); break;
3781 case EXC_ID_SXVDEX: rPTableMgr.ReadSxvdex( maStrm ); break;
3782 case EXC_ID_SXEX: rPTableMgr.ReadSxex( maStrm ); break;
3783 + case EXC_ID_SXVIEWEX9: rPTableMgr.ReadSxViewEx9( maStrm ); break;
3786 break;
3787 @@ -1180,6 +1181,9 @@ FltError ImportExcel8::Read( void )
3788 eLastErr = SCWARN_IMPORT_ROW_OVERFLOW;
3789 else if( rAddrConv.IsColTruncated() )
3790 eLastErr = SCWARN_IMPORT_COLUMN_OVERFLOW;
3792 + if( GetBiff() == EXC_BIFF8 )
3793 + GetPivotTableManager().MaybeRefreshPivotTables();
3796 return eLastErr;
3797 diff --git sc/source/filter/excel/xepivot.cxx sc/source/filter/excel/xepivot.cxx
3798 index d7bf0b3..e475661 100644
3799 --- sc/source/filter/excel/xepivot.cxx
3800 +++ sc/source/filter/excel/xepivot.cxx
3801 @@ -67,6 +67,7 @@ using ::com::sun::star::sheet::DataPilotFieldSortInfo;
3802 using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
3803 using ::com::sun::star::sheet::DataPilotFieldLayoutInfo;
3804 using ::com::sun::star::sheet::DataPilotFieldReference;
3805 +using ::rtl::OUString;
3807 using ::rtl::OString;
3808 using ::rtl::OUString;
3809 @@ -972,6 +973,11 @@ void XclExpPTItem::SetPropertiesFromMember( const ScDPSaveMember& rSaveMem )
3811 ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN, !rSaveMem.GetIsVisible() );
3812 ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL, !rSaveMem.GetShowDetails() );
3814 + // visible name
3815 + const OUString* pVisName = rSaveMem.GetLayoutName();
3816 + if (pVisName && !pVisName->equals(GetItemName()))
3817 + maItemInfo.SetVisName(*pVisName);
3820 void XclExpPTItem::WriteBody( XclExpStream& rStrm )
3821 @@ -1029,6 +1035,31 @@ sal_uInt16 XclExpPTField::GetItemIndex( const String& rName, sal_uInt16 nDefault
3823 // fill data --------------------------------------------------------------
3825 +/**
3826 + * Calc's subtotal names are escaped with backslashes ('\'), while Excel's
3827 + * are not escaped at all.
3828 + */
3829 +static OUString lcl_convertCalcSubtotalName(const OUString& rName)
3831 + OUStringBuffer aBuf;
3832 + const sal_Unicode* p = rName.getStr();
3833 + sal_Int32 n = rName.getLength();
3834 + bool bEscaped = false;
3835 + for (sal_Int32 i = 0; i < n; ++i)
3837 + const sal_Unicode c = p[i];
3838 + if (!bEscaped && c == sal_Unicode('\\'))
3840 + bEscaped = true;
3841 + continue;
3844 + aBuf.append(c);
3845 + bEscaped = false;
3847 + return aBuf.makeStringAndClear();
3850 void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
3852 // orientation
3853 @@ -1040,8 +1071,16 @@ void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
3854 ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL, rSaveDim.GetShowEmpty() );
3856 // visible name
3857 - if( rSaveDim.HasLayoutName() && (rSaveDim.GetLayoutName() != GetFieldName()) )
3858 - maFieldInfo.SetVisName( rSaveDim.GetLayoutName() );
3859 + const OUString* pLayoutName = rSaveDim.GetLayoutName();
3860 + if (pLayoutName && !pLayoutName->equals(GetFieldName()))
3861 + maFieldInfo.SetVisName(*pLayoutName);
3863 + const rtl::OUString* pSubtotalName = rSaveDim.GetSubtotalName();
3864 + if (pSubtotalName)
3866 + OUString aSubName = lcl_convertCalcSubtotalName(*pSubtotalName);
3867 + maFieldExtInfo.mpFieldTotalName.reset(new rtl::OUString(aSubName));
3870 // subtotals
3871 XclPTSubtotalVec aSubtotals;
3872 @@ -1108,7 +1147,11 @@ void XclExpPTField::SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim
3873 rDataInfo.SetApiAggFunc( eFunc );
3875 // visible name
3876 - rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) );
3877 + const rtl::OUString* pVisName = rSaveDim.GetLayoutName();
3878 + if (pVisName)
3879 + rDataInfo.SetVisName(*pVisName);
3880 + else
3881 + rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) );
3883 // result field reference
3884 if( const DataPilotFieldReference* pFieldRef = rSaveDim.GetReferenceValue() )
3885 @@ -1217,9 +1260,10 @@ XclExpPivotTable::XclExpPivotTable( const XclExpRoot& rRoot, const ScDPObject& r
3886 // pivot table properties from DP object
3887 mnOutScTab = rOutScRange.aStart.Tab();
3888 maPTInfo.maTableName = rDPObj.GetName();
3889 - maPTInfo.maDataName = ScGlobal::GetRscString( STR_PIVOT_DATA );
3890 maPTInfo.mnCacheIdx = mrPCache.GetCacheIndex();
3892 + maPTViewEx9Info.Init( rDPObj );
3894 if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() )
3896 // additional properties from ScDPSaveData
3897 @@ -1299,6 +1343,10 @@ void XclExpPivotTable::Save( XclExpStream& rStrm )
3898 WriteSxli( rStrm, maPTInfo.mnDataCols, maPTInfo.mnColFields );
3899 // SXEX
3900 WriteSxex( rStrm );
3901 + // QSISXTAG
3902 + WriteQsiSxTag( rStrm );
3903 + // SXVIEWEX9
3904 + WriteSxViewEx9( rStrm );
3908 @@ -1332,6 +1380,15 @@ void XclExpPivotTable::SetPropertiesFromDP( const ScDPSaveData& rSaveData )
3909 ::set_flag( maPTInfo.mnFlags, EXC_SXVIEW_COLGRAND, rSaveData.GetColumnGrand() );
3910 ::set_flag( maPTExtInfo.mnFlags, EXC_SXEX_DRILLDOWN, rSaveData.GetDrillDown() );
3911 mbFilterBtn = rSaveData.GetFilterButton();
3912 + const ScDPSaveDimension* pDim = rSaveData.GetExistingDataLayoutDimension();
3913 + if (!pDim)
3914 + return;
3916 + const rtl::OUString* pLayoutName = pDim->GetLayoutName();
3917 + if (pLayoutName)
3918 + maPTInfo.maDataName = *pLayoutName;
3919 + else
3920 + maPTInfo.maDataName = ScGlobal::GetRscString(STR_PIVOT_DATA);
3923 void XclExpPivotTable::SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
3924 @@ -1439,13 +1496,21 @@ void XclExpPivotTable::Finalize()
3925 rnDataXclRow = rnXclRow1 + maPTInfo.mnColFields + 1;
3926 if( maDataFields.empty() )
3927 ++rnDataXclRow;
3929 + bool bExtraHeaderRow = (0 == maPTViewEx9Info.mnGridLayout && maPTInfo.mnColFields == 0);
3930 + if (bExtraHeaderRow)
3931 + // Insert an extra row only when there is no column field.
3932 + ++rnDataXclRow;
3934 rnXclCol2 = ::std::max( rnXclCol2, rnDataXclCol );
3935 rnXclRow2 = ::std::max( rnXclRow2, rnDataXclRow );
3936 maPTInfo.mnDataCols = rnXclCol2 - rnDataXclCol + 1;
3937 maPTInfo.mnDataRows = rnXclRow2 - rnDataXclRow + 1;
3939 // first heading
3940 - maPTInfo.mnFirstHeadRow = rnXclRow1 + 1;
3941 + maPTInfo.mnFirstHeadRow = rnXclRow1;
3942 + if (bExtraHeaderRow)
3943 + maPTInfo.mnFirstHeadRow += 2;
3946 // records ----------------------------------------------------------------
3947 @@ -1525,6 +1590,72 @@ void XclExpPivotTable::WriteSxex( XclExpStream& rStrm ) const
3948 rStrm.EndRecord();
3951 +void XclExpPivotTable::WriteQsiSxTag( XclExpStream& rStrm ) const
3953 + rStrm.StartRecord( 0x0802, 32 );
3955 + sal_uInt16 nRecordType = 0x0802;
3956 + sal_uInt16 nDummyFlags = 0x0000;
3957 + sal_uInt16 nTableType = 1; // 0 = query table : 1 = pivot table
3959 + rStrm << nRecordType << nDummyFlags << nTableType;
3961 + // General flags
3962 + bool bEnableRefresh = true;
3963 + bool bPCacheInvalid = false;
3964 + bool bOlapPTReport = false;
3966 + sal_uInt16 nFlags = 0x0000;
3967 + if (bEnableRefresh) nFlags |= 0x0001;
3968 + if (bPCacheInvalid) nFlags |= 0x0002;
3969 + if (bOlapPTReport) nFlags |= 0x0004;
3970 + rStrm << nFlags;
3972 + // Feature-specific options. The value differs depending on the table
3973 + // type, but we assume the table type is always pivot table.
3974 + sal_uInt32 nOptions = 0x00000000;
3975 + bool bNoStencil = false;
3976 + bool bHideTotal = false;
3977 + bool bEmptyRows = false;
3978 + bool bEmptyCols = false;
3979 + if (bNoStencil) nOptions |= 0x00000001;
3980 + if (bHideTotal) nOptions |= 0x00000002;
3981 + if (bEmptyRows) nOptions |= 0x00000008;
3982 + if (bEmptyCols) nOptions |= 0x00000010;
3983 + rStrm << nOptions;
3985 + enum ExcelVersion
3987 + Excel2000 = 0,
3988 + ExcelXP = 1,
3989 + Excel2003 = 2,
3990 + Excel2007 = 3
3991 + };
3992 + ExcelVersion eXclVer = Excel2000;
3993 + sal_uInt8 nOffsetBytes = 16;
3994 + rStrm << static_cast<sal_uInt8>(eXclVer) // version table last refreshed
3995 + << static_cast<sal_uInt8>(eXclVer) // minimum version to refresh
3996 + << nOffsetBytes
3997 + << static_cast<sal_uInt8>(eXclVer); // first version created
3999 + rStrm << XclExpString(maPTInfo.maTableName);
4000 + rStrm << static_cast<sal_uInt16>(0x0001); // no idea what this is for.
4002 + rStrm.EndRecord();
4005 +void XclExpPivotTable::WriteSxViewEx9( XclExpStream& rStrm ) const
4007 + // Until we sync the autoformat ids only export if using grid header layout
4008 + // That could only have been set via xls import so far.
4009 + if ( 0 == maPTViewEx9Info.mnGridLayout )
4011 + rStrm.StartRecord( EXC_ID_SXVIEWEX9, 17 );
4012 + rStrm << maPTViewEx9Info;
4013 + rStrm.EndRecord();
4017 // ============================================================================
4019 namespace {
4020 diff --git sc/source/filter/excel/xestring.cxx sc/source/filter/excel/xestring.cxx
4021 index eb36b4a..c210911 100644
4022 --- sc/source/filter/excel/xestring.cxx
4023 +++ sc/source/filter/excel/xestring.cxx
4024 @@ -423,7 +423,8 @@ void XclExpString::WriteFormats( XclExpStream& rStrm, bool bWriteSize ) const
4026 void XclExpString::Write( XclExpStream& rStrm ) const
4028 - WriteHeader( rStrm );
4029 + if (!mbSkipHeader)
4030 + WriteHeader( rStrm );
4031 WriteBuffer( rStrm );
4032 if( IsWriteFormats() ) // only in BIFF8 included in string
4033 WriteFormats( rStrm );
4034 @@ -589,6 +590,7 @@ void XclExpString::Init( sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMax
4035 mbSmartFlags = bBiff8 && ::get_flag( nFlags, EXC_STR_SMARTFLAGS );
4036 mbSkipFormats = ::get_flag( nFlags, EXC_STR_SEPARATEFORMATS );
4037 mbWrapped = false;
4038 + mbSkipHeader = ::get_flag( nFlags, EXC_STR_NOHEADER );
4039 mnMaxLen = nMaxLen;
4040 SetStrLen( nCurrLen );
4042 diff --git sc/source/filter/excel/xipivot.cxx sc/source/filter/excel/xipivot.cxx
4043 index acd371f..bae2192 100644
4044 --- sc/source/filter/excel/xipivot.cxx
4045 +++ sc/source/filter/excel/xipivot.cxx
4046 @@ -48,7 +48,9 @@
4047 #include "dpdimsave.hxx"
4048 #include "dpobject.hxx"
4049 #include "dpshttab.hxx"
4050 +#include "dpoutputgeometry.hxx"
4051 #include "scitems.hxx"
4052 +#include "attrib.hxx"
4054 #include "xltracer.hxx"
4055 #include "xistream.hxx"
4056 @@ -60,13 +62,17 @@
4057 #include "excform.hxx"
4058 #include "xltable.hxx"
4060 +#include <vector>
4062 using ::rtl::OUString;
4063 +using ::rtl::OUStringBuffer;
4064 using ::com::sun::star::sheet::DataPilotFieldOrientation;
4065 using ::com::sun::star::sheet::DataPilotFieldOrientation_DATA;
4066 using ::com::sun::star::sheet::DataPilotFieldSortInfo;
4067 using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
4068 using ::com::sun::star::sheet::DataPilotFieldLayoutInfo;
4069 using ::com::sun::star::sheet::DataPilotFieldReference;
4070 +using ::std::vector;
4072 // ============================================================================
4073 // Pivot cache
4074 @@ -847,6 +853,11 @@ void XclImpPivotCache::ReadPivotCacheStream( XclImpStream& rStrm )
4078 +bool XclImpPivotCache::IsRefreshOnLoad() const
4080 + return static_cast<bool>(maPCInfo.mnFlags & 0x0004);
4083 // ============================================================================
4084 // Pivot table
4085 // ============================================================================
4086 @@ -882,6 +893,8 @@ void XclImpPTItem::ConvertItem( ScDPSaveDimension& rSaveDim ) const
4087 ScDPSaveMember& rMember = *rSaveDim.GetMemberByName( *pItemName );
4088 rMember.SetIsVisible( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN ) );
4089 rMember.SetShowDetails( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL ) );
4090 + if (maItemInfo.HasVisName())
4091 + rMember.SetLayoutName(*maItemInfo.GetVisName());
4095 @@ -1022,6 +1035,28 @@ void XclImpPTField::ConvertDataField( ScDPSaveData& rSaveData ) const
4097 // private --------------------------------------------------------------------
4099 +/**
4100 + * Convert Excel-encoded subtotal name to a Calc-encoded one.
4101 + */
4102 +static OUString lcl_convertExcelSubtotalName(const OUString& rName)
4104 + OUStringBuffer aBuf;
4105 + const sal_Unicode* p = rName.getStr();
4106 + sal_Int32 n = rName.getLength();
4107 + for (sal_Int32 i = 0; i < n; ++i)
4109 + const sal_Unicode c = p[i];
4110 + if (c == sal_Unicode('\\'))
4112 + aBuf.append(c);
4113 + aBuf.append(c);
4115 + else
4116 + aBuf.append(c);
4118 + return aBuf.makeStringAndClear();
4121 ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) const
4123 const String& rFieldName = GetFieldName();
4124 @@ -1043,7 +1078,7 @@ ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) con
4125 // visible name
4126 if( const String* pVisName = maFieldInfo.GetVisName() )
4127 if( pVisName->Len() > 0 )
4128 - rSaveDim.SetLayoutName( pVisName );
4129 + rSaveDim.SetLayoutName( *pVisName );
4131 // subtotal function(s)
4132 XclPTSubtotalVec aSubtotalVec;
4133 @@ -1075,6 +1110,13 @@ ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) con
4134 // grouping info
4135 pCacheField->ConvertGroupField( rSaveData, mrPTable.GetVisFieldNames() );
4137 + // custom subtotal name
4138 + if (maFieldExtInfo.mpFieldTotalName.get())
4140 + OUString aSubName = lcl_convertExcelSubtotalName(*maFieldExtInfo.mpFieldTotalName);
4141 + rSaveDim.SetSubtotalName(aSubName);
4144 return &rSaveDim;
4147 @@ -1099,7 +1141,7 @@ void XclImpPTField::ConvertDataFieldInfo( ScDPSaveDimension& rSaveDim, const Xcl
4148 // visible name
4149 if( const String* pVisName = rDataInfo.GetVisName() )
4150 if( pVisName->Len() > 0 )
4151 - rSaveDim.SetLayoutName( pVisName );
4152 + rSaveDim.SetLayoutName( *pVisName );
4154 // aggregation function
4155 rSaveDim.SetFunction( static_cast< USHORT >( rDataInfo.GetApiAggFunc() ) );
4156 @@ -1134,7 +1176,8 @@ void XclImpPTField::ConvertItems( ScDPSaveDimension& rSaveDim ) const
4158 XclImpPivotTable::XclImpPivotTable( const XclImpRoot& rRoot ) :
4159 XclImpRoot( rRoot ),
4160 - maDataOrientField( *this, EXC_SXIVD_DATA )
4161 + maDataOrientField( *this, EXC_SXIVD_DATA ),
4162 + mpDPObj(NULL)
4166 @@ -1296,6 +1339,11 @@ void XclImpPivotTable::ReadSxex( XclImpStream& rStrm )
4167 rStrm >> maPTExtInfo;
4170 +void XclImpPivotTable::ReadSxViewEx9( XclImpStream& rStrm )
4172 + rStrm >> maPTViewEx9Info;
4175 // ----------------------------------------------------------------------------
4177 void XclImpPivotTable::Convert()
4178 @@ -1331,6 +1379,10 @@ void XclImpPivotTable::Convert()
4179 if( const XclImpPTField* pField = GetField( *aIt ) )
4180 pField->ConvertPageField( aSaveData );
4182 + // We need to import hidden fields because hidden fields may contain
4183 + // special settings for subtotals (aggregation function, filters, custom
4184 + // name etc.) and members (hidden, custom name etc.).
4186 // hidden fields
4187 for( sal_uInt16 nField = 0, nCount = GetFieldCount(); nField < nCount; ++nField )
4188 if( const XclImpPTField* pField = GetField( nField ) )
4189 @@ -1359,11 +1411,111 @@ void XclImpPivotTable::Convert()
4190 // create the DataPilot
4191 ScDPObject* pDPObj = new ScDPObject( GetDocPtr() );
4192 pDPObj->SetName( maPTInfo.maTableName );
4193 + if (maPTInfo.maDataName.Len() > 0)
4194 + aSaveData.GetDataLayoutDimension()->SetLayoutName(maPTInfo.maDataName);
4196 + if (maPTViewEx9Info.maGrandTotalName.Len() > 0)
4197 + aSaveData.SetGrandTotalName(maPTViewEx9Info.maGrandTotalName);
4199 pDPObj->SetSaveData( aSaveData );
4200 pDPObj->SetSheetDesc( aDesc );
4201 pDPObj->SetOutRange( aOutRange );
4202 pDPObj->SetAlive( TRUE );
4203 - GetDoc().GetDPCollection()->Insert( pDPObj );
4204 + pDPObj->SetHeaderLayout( maPTViewEx9Info.mnGridLayout == 0 );
4206 + GetDoc().GetDPCollection()->InsertNewTable(pDPObj);
4207 + mpDPObj = pDPObj;
4209 + ApplyMergeFlags(aOutRange, aSaveData);
4212 +void XclImpPivotTable::MaybeRefresh()
4214 + if (mpDPObj && mxPCache->IsRefreshOnLoad())
4216 + // 'refresh table on load' flag is set. Refresh the table now. Some
4217 + // Excel files contain partial table output when this flag is set.
4218 + mpDPObj->Output(maOutScRange.aStart);
4222 +void XclImpPivotTable::ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveData& rSaveData)
4224 + // Apply merge flags for varoius datapilot controls.
4226 + ScDPOutputGeometry aGeometry(rOutRange, false, ScDPOutputGeometry::XLS);
4227 + aGeometry.setColumnFieldCount(maPTInfo.mnColFields);
4228 + aGeometry.setPageFieldCount(maPTInfo.mnPageFields);
4229 + aGeometry.setDataFieldCount(maPTInfo.mnDataFields);
4231 + // Excel includes data layout field in the row field count. We need to
4232 + // subtract it.
4233 + bool bDataLayout = maPTInfo.mnDataFields > 1;
4234 + aGeometry.setRowFieldCount(maPTInfo.mnRowFields - static_cast<sal_uInt32>(bDataLayout));
4236 + ScDocument& rDoc = GetDoc();
4238 + vector<ScAddress> aPageBtns;
4239 + aGeometry.getPageFieldPositions(aPageBtns);
4240 + vector<ScAddress>::const_iterator itr = aPageBtns.begin(), itrEnd = aPageBtns.end();
4241 + for (; itr != itrEnd; ++itr)
4243 + sal_uInt16 nMFlag = SC_MF_BUTTON;
4244 + String aName;
4245 + rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
4246 + if (rSaveData.HasInvisibleMember(aName))
4247 + nMFlag |= SC_MF_HIDDEN_MEMBER;
4249 + rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
4250 + rDoc.ApplyFlagsTab(itr->Col()+1, itr->Row(), itr->Col()+1, itr->Row(), itr->Tab(), SC_MF_AUTO);
4253 + vector<ScAddress> aColBtns;
4254 + aGeometry.getColumnFieldPositions(aColBtns);
4255 + itr = aColBtns.begin();
4256 + itrEnd = aColBtns.end();
4257 + for (; itr != itrEnd; ++itr)
4259 + sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP;
4260 + String aName;
4261 + rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
4262 + if (rSaveData.HasInvisibleMember(aName))
4263 + nMFlag |= SC_MF_HIDDEN_MEMBER;
4264 + rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
4267 + vector<ScAddress> aRowBtns;
4268 + aGeometry.getRowFieldPositions(aRowBtns);
4269 + if (aRowBtns.empty())
4271 + if (bDataLayout)
4273 + // No row fields, but the data layout button exists.
4274 + SCROW nRow = aGeometry.getRowFieldHeaderRow();
4275 + SCCOL nCol = rOutRange.aStart.Col();
4276 + SCTAB nTab = rOutRange.aStart.Tab();
4277 + rDoc.ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON);
4280 + else
4282 + itr = aRowBtns.begin();
4283 + itrEnd = aRowBtns.end();
4284 + for (; itr != itrEnd; ++itr)
4286 + sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP;
4287 + String aName;
4288 + rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
4289 + if (rSaveData.HasInvisibleMember(aName))
4290 + nMFlag |= SC_MF_HIDDEN_MEMBER;
4291 + rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
4293 + if (bDataLayout)
4295 + --itr; // move back to the last row field position.
4296 + rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), SC_MF_BUTTON);
4301 // ============================================================================
4302 @@ -1458,6 +1610,12 @@ void XclImpPivotTableManager::ReadSxex( XclImpStream& rStrm )
4303 maPTables.back()->ReadSxex( rStrm );
4306 +void XclImpPivotTableManager::ReadSxViewEx9( XclImpStream& rStrm )
4308 + if( !maPTables.empty() )
4309 + maPTables.back()->ReadSxViewEx9( rStrm );
4312 // ----------------------------------------------------------------------------
4314 void XclImpPivotTableManager::ReadPivotCaches( XclImpStream& rStrm )
4315 @@ -1472,5 +1630,11 @@ void XclImpPivotTableManager::ConvertPivotTables()
4316 (*aIt)->Convert();
4319 +void XclImpPivotTableManager::MaybeRefreshPivotTables()
4321 + for( XclImpPivotTableVec::iterator aIt = maPTables.begin(), aEnd = maPTables.end(); aIt != aEnd; ++aIt )
4322 + (*aIt)->MaybeRefresh();
4325 // ============================================================================
4327 diff --git sc/source/filter/excel/xlpivot.cxx sc/source/filter/excel/xlpivot.cxx
4328 index e3544b5..c915903 100644
4329 --- sc/source/filter/excel/xlpivot.cxx
4330 +++ sc/source/filter/excel/xlpivot.cxx
4331 @@ -31,6 +31,7 @@
4332 // MARKER(update_precomp.py): autogen include statement, do not remove
4333 #include "precompiled_sc.hxx"
4334 #include "dpgroup.hxx"
4335 +#include "dpsave.hxx"
4336 #include "xestream.hxx"
4337 #include "xistream.hxx"
4338 #include "xestring.hxx"
4339 @@ -581,7 +582,9 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo )
4340 XclPTFieldExtInfo::XclPTFieldExtInfo() :
4341 mnFlags( EXC_SXVDEX_DEFAULTFLAGS ),
4342 mnSortField( EXC_SXVDEX_SORT_OWN ),
4343 - mnShowField( EXC_SXVDEX_SHOW_NONE )
4344 + mnShowField( EXC_SXVDEX_SHOW_NONE ),
4345 + mnNumFmt(0),
4346 + mpFieldTotalName(NULL)
4350 @@ -639,10 +642,19 @@ void XclPTFieldExtInfo::SetApiLayoutMode( sal_Int32 nLayoutMode )
4352 XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo )
4354 - return rStrm
4355 - >> rInfo.mnFlags
4356 - >> rInfo.mnSortField
4357 - >> rInfo.mnShowField;
4358 + sal_uInt8 nNameLen = 0;
4359 + rStrm >> rInfo.mnFlags
4360 + >> rInfo.mnSortField
4361 + >> rInfo.mnShowField
4362 + >> rInfo.mnNumFmt
4363 + >> nNameLen;
4365 + rStrm.Ignore(10);
4366 + if (nNameLen != 0xFF)
4367 + // Custom field total name is used. Pick it up.
4368 + rInfo.mpFieldTotalName.reset(new rtl::OUString(rStrm.ReadUniString(nNameLen, 0)));
4370 + return rStrm;
4373 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo )
4374 @@ -650,9 +662,23 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo )
4375 rStrm << rInfo.mnFlags
4376 << rInfo.mnSortField
4377 << rInfo.mnShowField
4378 - << EXC_SXVDEX_FORMAT_NONE
4379 - << sal_uInt16( 0xFFFF ); // unknown
4380 - rStrm.WriteZeroBytes( 8 ); // unknown
4381 + << EXC_SXVDEX_FORMAT_NONE;
4383 + if (rInfo.mpFieldTotalName.get() && rInfo.mpFieldTotalName->getLength() > 0)
4385 + rtl::OUString aFinalName = *rInfo.mpFieldTotalName;
4386 + if (aFinalName.getLength() >= 254)
4387 + aFinalName = aFinalName.copy(0, 254);
4388 + sal_uInt8 nNameLen = static_cast<sal_uInt8>(aFinalName.getLength());
4389 + rStrm << nNameLen;
4390 + rStrm.WriteZeroBytes(10);
4391 + rStrm << XclExpString(aFinalName, EXC_STR_NOHEADER);
4393 + else
4395 + rStrm << sal_uInt16(0xFFFF);
4396 + rStrm.WriteZeroBytes(8);
4398 return rStrm;
4401 @@ -923,3 +949,86 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo )
4403 // ============================================================================
4405 +// Pivot table autoformat settings ============================================
4407 +/**
4408 +classic : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
4409 +default : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
4410 +report01 : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00
4411 +report02 : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00
4412 +report03 : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00
4413 +report04 : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00
4414 +report05 : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00
4415 +report06 : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00
4416 +report07 : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00
4417 +report08 : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00
4418 +report09 : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00
4419 +report10 : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00
4420 +table01 : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00
4421 +table02 : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00
4422 +table03 : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00
4423 +table04 : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00
4424 +table05 : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00
4425 +table06 : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00
4426 +table07 : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00
4427 +table08 : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00
4428 +table09 : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00
4429 +table10 : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00
4430 +none : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00
4431 +**/
4433 +XclPTViewEx9Info::XclPTViewEx9Info() :
4434 + mbReport( 0 ),
4435 + mnAutoFormat( 0 ),
4436 + mnGridLayout( 0x10 )
4440 +void XclPTViewEx9Info::Init( const ScDPObject& rDPObj )
4442 + if( rDPObj.GetHeaderLayout() )
4444 + mbReport = 0;
4445 + mnAutoFormat = 1;
4446 + mnGridLayout = 0;
4448 + else
4450 + // Report1 for now
4451 + // TODO : sync with autoformat indicies
4452 + mbReport = 2;
4453 + mnAutoFormat = 1;
4454 + mnGridLayout = 0x10;
4457 + const ScDPSaveData* pData = rDPObj.GetSaveData();
4458 + if (pData)
4460 + const rtl::OUString* pGrandTotal = pData->GetGrandTotalName();
4461 + if (pGrandTotal)
4462 + maGrandTotalName = *pGrandTotal;
4466 +XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo )
4468 + rStrm.Ignore( 2 );
4469 + rStrm >> rInfo.mbReport; /// 2 for report* fmts ?
4470 + rStrm.Ignore( 6 );
4471 + rStrm >> rInfo.mnAutoFormat >> rInfo.mnGridLayout;
4472 + rInfo.maGrandTotalName = rStrm.ReadUniString();
4473 + return rStrm;
4476 +XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo )
4478 + return rStrm
4479 + << EXC_PT_AUTOFMT_HEADER
4480 + << rInfo.mbReport
4481 + << EXC_PT_AUTOFMT_ZERO
4482 + << EXC_PT_AUTOFMT_FLAGS
4483 + << rInfo.mnAutoFormat
4484 + << rInfo.mnGridLayout
4485 + << XclExpString(rInfo.maGrandTotalName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN);
4488 diff --git sc/source/filter/inc/xepivot.hxx sc/source/filter/inc/xepivot.hxx
4489 index 32ba1a0..de9d284 100644
4490 --- sc/source/filter/inc/xepivot.hxx
4491 +++ sc/source/filter/inc/xepivot.hxx
4492 @@ -413,6 +413,10 @@ private:
4493 /** Writes the SXEX records containing additional pivot table info. */
4494 void WriteSxex( XclExpStream& rStrm ) const;
4496 + void WriteQsiSxTag( XclExpStream& rStrm ) const;
4497 + /** Writes the SX_AUTOFORMAT records with the autoformat id and header layout */
4498 + void WriteSxViewEx9( XclExpStream& rStrm ) const;
4500 // ------------------------------------------------------------------------
4501 private:
4502 typedef XclExpRecordList< XclExpPTField > XclExpPTFieldList;
4503 @@ -422,6 +426,7 @@ private:
4504 const XclExpPivotCache& mrPCache; /// The pivot cache this pivot table bases on.
4505 XclPTInfo maPTInfo; /// Info about the pivot table (SXVIEW record).
4506 XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record).
4507 + XclPTViewEx9Info maPTViewEx9Info; /// The selected autoformat (SXVIEWEX9)
4508 XclExpPTFieldList maFieldList; /// All fields in pivot cache order.
4509 ScfUInt16Vec maRowFields; /// Row field indexes.
4510 ScfUInt16Vec maColFields; /// Column field indexes.
4511 diff --git sc/source/filter/inc/xestring.hxx sc/source/filter/inc/xestring.hxx
4512 index f023a12..706b12c 100644
4513 --- sc/source/filter/inc/xestring.hxx
4514 +++ sc/source/filter/inc/xestring.hxx
4515 @@ -323,6 +323,7 @@ private:
4516 bool mbSmartFlags; /// true = omit flags on empty string; false = always write flags.
4517 bool mbSkipFormats; /// true = skip formats on export; false = write complete formatted string.
4518 bool mbWrapped; /// true = text contains several paragraphs.
4519 + bool mbSkipHeader; /// ture = skip length and flags when writing string bytes.
4522 inline bool operator==( const XclExpString& rLeft, const XclExpString& rRight )
4523 diff --git sc/source/filter/inc/xipivot.hxx sc/source/filter/inc/xipivot.hxx
4524 index fffd4f0..d043a95 100644
4525 --- sc/source/filter/inc/xipivot.hxx
4526 +++ sc/source/filter/inc/xipivot.hxx
4527 @@ -186,6 +186,8 @@ public:
4528 /** Reads the entire pivot cache stream. Uses decrypter from passed stream. */
4529 void ReadPivotCacheStream( XclImpStream& rStrm );
4531 + bool IsRefreshOnLoad() const;
4533 private:
4534 typedef ::std::vector< XclImpPCFieldRef > XclImpPCFieldVec;
4536 @@ -350,12 +352,19 @@ public:
4537 void ReadSxdi( XclImpStream& rStrm );
4538 /** Reads an SXEX record containing additional settings for the pivot table. */
4539 void ReadSxex( XclImpStream& rStrm );
4540 + /** Reads an SXVIEWEX9 record that specifies the pivot tables
4541 + * autoformat. */
4542 + void ReadSxViewEx9( XclImpStream& rStrm );
4544 // ------------------------------------------------------------------------
4546 /** Inserts the pivot table into the Calc document. */
4547 void Convert();
4549 + void MaybeRefresh();
4551 + void ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveData& rSaveData);
4553 // ------------------------------------------------------------------------
4554 private:
4555 typedef ::std::vector< XclImpPTFieldRef > XclImpPTFieldVec;
4556 @@ -364,6 +373,7 @@ private:
4558 XclPTInfo maPTInfo; /// General info about the pivot table (SXVIEW record).
4559 XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record).
4560 + XclPTViewEx9Info maPTViewEx9Info; /// (SXVIEWEX9 record)
4561 XclImpPTFieldVec maFields; /// Vector containing all fields.
4562 XclImpPTFieldRef mxCurrField; /// Current field for importing additional info.
4563 ScfStringVec maVisFieldNames; /// Vector containing all visible field names.
4564 @@ -374,6 +384,7 @@ private:
4565 ScfUInt16Vec maFiltDataFields; /// Filtered data field indexes.
4566 XclImpPTField maDataOrientField; /// Special data field orientation field.
4567 ScRange maOutScRange; /// Output range in the Calc document.
4568 + ScDPObject* mpDPObj;
4571 typedef ScfRef< XclImpPivotTable > XclImpPivotTableRef;
4572 @@ -422,6 +433,9 @@ public:
4573 void ReadSxvi( XclImpStream& rStrm );
4574 /** Reads an SXEX record containing additional settings for a pivot table. */
4575 void ReadSxex( XclImpStream& rStrm );
4576 + /** Reads an SXVIEWEX9 record that specifies the pivot tables
4577 + * autoformat. */
4578 + void ReadSxViewEx9( XclImpStream& rStrm );
4580 // ------------------------------------------------------------------------
4582 @@ -430,6 +444,8 @@ public:
4583 /** Inserts all pivot tables into the Calc document. */
4584 void ConvertPivotTables();
4586 + void MaybeRefreshPivotTables();
4588 private:
4589 typedef ::std::vector< XclImpPivotCacheRef > XclImpPivotCacheVec;
4590 typedef ::std::vector< XclImpPivotTableRef > XclImpPivotTableVec;
4591 diff --git sc/source/filter/inc/xlpivot.hxx sc/source/filter/inc/xlpivot.hxx
4592 index 380a64d..8b5bd4e 100644
4593 --- sc/source/filter/inc/xlpivot.hxx
4594 +++ sc/source/filter/inc/xlpivot.hxx
4595 @@ -41,6 +41,9 @@
4596 #include <tools/datetime.hxx>
4597 #include "ftools.hxx"
4598 #include "xladdress.hxx"
4599 +#include "dpobject.hxx"
4601 +#include <memory>
4603 class XclImpStream;
4604 class XclExpStream;
4605 @@ -73,6 +76,10 @@ const sal_uInt16 EXC_PT_MAXDATACOUNT = 256;
4606 // pivot table items
4607 const sal_uInt16 EXC_PT_MAXITEMCOUNT = 32500;
4609 +const sal_uInt16 EXC_PT_AUTOFMT_HEADER = 0x810;
4610 +const sal_uInt16 EXC_PT_AUTOFMT_ZERO = 0;
4611 +const sal_uInt32 EXC_PT_AUTOFMT_FLAGS = 0x20;
4613 /** Data type of a pivot cache item. */
4614 enum XclPCItemType
4616 @@ -396,6 +403,9 @@ const double EXC_SXDBEX_CREATION_DATE = 51901.029652778;
4617 const sal_uInt16 EXC_ID_SXFDBTYPE = 0x01BB;
4618 const sal_uInt16 EXC_SXFDBTYPE_DEFAULT = 0x0000;
4620 +// (0x0810) SXVIEWEX9 ---------------------------------------------------------
4621 +const sal_uInt16 EXC_ID_SXVIEWEX9 = 0x0810;
4623 // ============================================================================
4624 // Pivot cache
4625 // ============================================================================
4626 @@ -663,6 +673,8 @@ struct XclPTFieldExtInfo
4627 sal_uInt32 mnFlags; /// Several flags and number of items for AutoShow.
4628 sal_uInt16 mnSortField; /// Index to data field sorting bases on.
4629 sal_uInt16 mnShowField; /// Index to data field AutoShow bases on.
4630 + sal_uInt16 mnNumFmt;
4631 + ::std::auto_ptr<rtl::OUString> mpFieldTotalName;
4633 explicit XclPTFieldExtInfo();
4635 @@ -786,5 +798,23 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo );
4637 // ============================================================================
4639 +// Pivot table autoformat settings ==============================================
4641 +/** Pivot table autoformat settings (SXVIEWEX9 record). */
4642 +struct XclPTViewEx9Info
4644 + sal_uInt32 mbReport; /// 2 for report* fmts ?
4645 + sal_uInt8 mnAutoFormat; /// AutoFormat ID
4646 + sal_uInt8 mnGridLayout; /// 0 == gridlayout, 0x10 == modern
4647 + String maGrandTotalName;
4649 + explicit XclPTViewEx9Info();
4650 + void Init( const ScDPObject& rDPObj );
4653 +XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo );
4654 +XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo );
4656 +// ============================================================================
4657 #endif
4659 diff --git sc/source/filter/inc/xlstring.hxx sc/source/filter/inc/xlstring.hxx
4660 index 626b11b..0a078a4 100644
4661 --- sc/source/filter/inc/xlstring.hxx
4662 +++ sc/source/filter/inc/xlstring.hxx
4663 @@ -43,6 +43,7 @@ const XclStrFlags EXC_STR_FORCEUNICODE = 0x0001; /// Always use UCS-2 cha
4664 const XclStrFlags EXC_STR_8BITLENGTH = 0x0002; /// 8-bit string length field (default: 16-bit).
4665 const XclStrFlags EXC_STR_SMARTFLAGS = 0x0004; /// Omit flags on empty string (default: read/write always). BIFF8 only.
4666 const XclStrFlags EXC_STR_SEPARATEFORMATS = 0x0008; /// Import: Keep old formats when reading unformatted string (default: clear formats); Export: Write unformatted string.
4667 +const XclStrFlags EXC_STR_NOHEADER = 0x0010; /// Export: Don't write the length and flag fields.
4669 // ----------------------------------------------------------------------------
4671 diff --git sc/source/filter/xml/XMLExportDataPilot.cxx sc/source/filter/xml/XMLExportDataPilot.cxx
4672 index a382a95..eeecd3b 100644
4673 --- sc/source/filter/xml/XMLExportDataPilot.cxx
4674 +++ sc/source/filter/xml/XMLExportDataPilot.cxx
4675 @@ -68,6 +68,7 @@
4677 using namespace com::sun::star;
4678 using namespace xmloff::token;
4679 +using ::rtl::OUString;
4681 ScXMLExportDataPilot::ScXMLExportDataPilot(ScXMLExport& rTempExport)
4682 : rExport(rTempExport),
4683 @@ -448,7 +449,10 @@ void ScXMLExportDataPilot::WriteLayoutInfo(ScDPSaveDimension* pDim)
4685 void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim)
4687 + using sheet::GeneralFunction;
4689 sal_Int32 nSubTotalCount = pDim->GetSubTotalsCount();
4690 + const OUString* pLayoutName = pDim->GetSubtotalName();
4691 if (nSubTotalCount > 0)
4693 SvXMLElementExport aElemSTs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, sal_True, sal_True);
4694 @@ -456,8 +460,11 @@ void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim)
4695 for (sal_Int32 nSubTotal = 0; nSubTotal < nSubTotalCount; nSubTotal++)
4697 rtl::OUString sFunction;
4698 - ScXMLConverter::GetStringFromFunction( sFunction, (sheet::GeneralFunction)pDim->GetSubTotalFunc(nSubTotal) );
4699 + GeneralFunction nFunc = static_cast<GeneralFunction>(pDim->GetSubTotalFunc(nSubTotal));
4700 + ScXMLConverter::GetStringFromFunction( sFunction, nFunc);
4701 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction);
4702 + if (pLayoutName && nFunc == sheet::GeneralFunction_AUTO)
4703 + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pLayoutName);
4704 SvXMLElementExport aElemST(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, sal_True, sal_True);
4707 @@ -473,6 +480,9 @@ void ScXMLExportDataPilot::WriteMembers(ScDPSaveDimension* pDim)
4708 for (ScDPSaveDimension::MemberList::const_iterator i=rMembers.begin(); i != rMembers.end() ; i++)
4710 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString((*i)->GetName()));
4711 + const OUString* pLayoutName = (*i)->GetLayoutName();
4712 + if (pLayoutName)
4713 + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pLayoutName);
4714 rtl::OUStringBuffer sBuffer;
4715 SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetIsVisible());
4716 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear());
4717 @@ -670,6 +680,10 @@ void ScXMLExportDataPilot::WriteGroupDimElements(ScDPSaveDimension* pDim, const
4718 void ScXMLExportDataPilot::WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData)
4720 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, rtl::OUString(pDim->GetName()));
4721 + const OUString* pLayoutName = pDim->GetLayoutName();
4722 + if (pLayoutName)
4723 + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pLayoutName);
4725 if (pDim->IsDataLayout())
4726 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TRUE);
4727 rtl::OUString sValueStr;
4728 @@ -707,6 +721,15 @@ void ScXMLExportDataPilot::WriteDimensions(ScDPSaveData* pDPSave)
4732 +void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const OUString* pGrandTotal)
4734 + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, bVisible ? XML_TRUE : XML_FALSE);
4735 + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, eOrient);
4736 + if (pGrandTotal)
4737 + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pGrandTotal);
4738 + SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True);
4741 void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreadsheetDocument>& /* xSpreadDoc */)
4743 pDoc = rExport.GetDocument();
4744 @@ -775,6 +798,20 @@ void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreads
4745 if (!pDPSave->GetDrillDown())
4746 rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DRILL_DOWN_ON_DOUBLE_CLICK, XML_FALSE);
4747 SvXMLElementExport aElemDP(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLE, sal_True, sal_True);
4749 + // grand total elements.
4751 + const OUString* pGrandTotalName = pDPSave->GetGrandTotalName();
4752 + if (bRowGrand && bColumnGrand)
4754 + WriteGrandTotal(XML_BOTH, true, pGrandTotalName);
4756 + else
4758 + WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName);
4759 + WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName);
4762 rExport.CheckAttrList();
4763 if ((*pDPs)[i]->IsSheetData())
4765 diff --git sc/source/filter/xml/XMLExportDataPilot.hxx sc/source/filter/xml/XMLExportDataPilot.hxx
4766 index 87c5894..a3f6cf8 100644
4767 --- sc/source/filter/xml/XMLExportDataPilot.hxx
4768 +++ sc/source/filter/xml/XMLExportDataPilot.hxx
4769 @@ -34,6 +34,7 @@
4770 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
4771 #include <rtl/ustring.hxx>
4772 #include "global.hxx"
4773 +#include "xmloff/xmltoken.hxx"
4775 class ScXMLExport;
4776 class ScDocument;
4777 @@ -69,6 +70,8 @@ class ScXMLExportDataPilot
4778 void WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData);
4779 void WriteDimensions(ScDPSaveData* pDPSave);
4781 + void WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const ::rtl::OUString* pGrandTotal);
4783 public:
4784 ScXMLExportDataPilot(ScXMLExport& rExport);
4785 ~ScXMLExportDataPilot();
4786 diff --git sc/source/filter/xml/xmldpimp.cxx sc/source/filter/xml/xmldpimp.cxx
4787 index 470827b..070fbc2 100644
4788 --- sc/source/filter/xml/xmldpimp.cxx
4789 +++ sc/source/filter/xml/xmldpimp.cxx
4790 @@ -48,6 +48,7 @@
4791 #include "dpgroup.hxx"
4792 #include "dpdimsave.hxx"
4793 #include "rangeutl.hxx"
4794 +#include "dpoutputgeometry.hxx"
4796 #include <xmloff/xmltkmap.hxx>
4797 #include <xmloff/nmspmap.hxx>
4798 @@ -65,6 +66,8 @@
4800 using namespace com::sun::star;
4801 using namespace xmloff::token;
4802 +using ::com::sun::star::uno::Reference;
4803 +using ::com::sun::star::xml::sax::XAttributeList;
4804 using ::rtl::OUString;
4806 //------------------------------------------------------------------
4807 @@ -113,6 +116,9 @@ void ScXMLDataPilotTablesContext::EndElement()
4811 +ScXMLDataPilotTableContext::GrandTotalItem::GrandTotalItem() :
4812 + mbVisible(false) {}
4814 ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport,
4815 USHORT nPrfx,
4816 const ::rtl::OUString& rLName,
4817 @@ -126,6 +132,10 @@ ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport,
4818 sDataPilotTableName(),
4819 sApplicationData(),
4820 sGrandTotal(GetXMLToken(XML_BOTH)),
4821 + mnRowFieldCount(0),
4822 + mnColFieldCount(0),
4823 + mnPageFieldCount(0),
4824 + mnDataFieldCount(0),
4825 bIsNative(sal_True),
4826 bIgnoreEmptyRows(sal_False),
4827 bIdentifyCategories(sal_False),
4828 @@ -159,6 +169,19 @@ ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport,
4829 case XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL :
4831 sGrandTotal = sValue;
4832 + if (IsXMLToken(sValue, XML_BOTH))
4833 + {
4834 + maRowGrandTotal.mbVisible = true;
4835 + maColGrandTotal.mbVisible = true;
4837 + else if (IsXMLToken(sValue, XML_ROW))
4838 + {
4839 + maRowGrandTotal.mbVisible = true;
4841 + else if (IsXMLToken(sValue, XML_COLUMN))
4842 + {
4843 + maColGrandTotal.mbVisible = true;
4846 break;
4847 case XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS :
4848 @@ -238,6 +261,11 @@ SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( USHORT nPref
4849 nSourceType = SERVICE;
4851 break;
4852 + case XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL:
4854 + pContext = new ScXMLDataPilotGrandTotalContext(GetScImport(), nPrefix, rLName, xAttrList, this);
4856 + break;
4857 case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE :
4859 pContext = new ScXMLSourceCellRangeContext(GetScImport(), nPrefix, rLName, xAttrList, this);
4860 @@ -256,7 +284,13 @@ SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( USHORT nPref
4863 void ScXMLDataPilotTableContext::SetButtons()
4866 + ScDPOutputGeometry aGeometry(aTargetRangeAddress, bShowFilter, ScDPOutputGeometry::ODF);
4867 + aGeometry.setColumnFieldCount(mnColFieldCount);
4868 + aGeometry.setRowFieldCount(mnRowFieldCount);
4869 + aGeometry.setPageFieldCount(mnPageFieldCount);
4870 + aGeometry.setDataFieldCount(mnDataFieldCount);
4872 OUString sAddress;
4873 sal_Int32 nOffset = 0;
4874 while( nOffset >= 0 )
4875 @@ -268,8 +302,21 @@ void ScXMLDataPilotTableContext::SetButtons()
4876 sal_Int32 nAddrOffset(0);
4877 if (pDoc && ScRangeStringConverter::GetAddressFromString( aScAddress, sAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nAddrOffset ))
4879 - ScMergeFlagAttr aAttr( SC_MF_BUTTON );
4880 - pDoc->ApplyAttr( aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), aAttr );
4881 + ScDPOutputGeometry::FieldType eType = aGeometry.getFieldButtonType(aScAddress);
4883 + sal_Int16 nMFlag = SC_MF_BUTTON;
4884 + if (eType == ScDPOutputGeometry::Column || eType == ScDPOutputGeometry::Row)
4885 + nMFlag |= SC_MF_BUTTON_POPUP;
4887 + // Use the cell's string value to see if this field contains a
4888 + // hidden member. Isn't there a better way? GetString() is
4889 + // quite expensive...
4890 + String aCellStr;
4891 + pDoc->GetString(aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), aCellStr);
4892 + if (maHiddenMemberFields.count(aCellStr))
4893 + nMFlag |= SC_MF_HIDDEN_MEMBER;
4895 + pDoc->ApplyFlagsTab(aScAddress.Col(), aScAddress.Row(), aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), nMFlag);
4899 @@ -278,7 +325,7 @@ void ScXMLDataPilotTableContext::SetButtons()
4900 pDPObject->RefreshAfterLoad();
4903 -void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim)
4904 +void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember)
4906 if (pDPSave)
4908 @@ -288,6 +335,38 @@ void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim)
4909 pDPSave->GetExistingDimensionByName(pDim->GetName()) )
4910 pDim->SetDupFlag( TRUE );
4912 + if (!pDim->IsDataLayout())
4914 + switch (pDim->GetOrientation())
4916 + case sheet::DataPilotFieldOrientation_ROW:
4917 + ++mnRowFieldCount;
4918 + break;
4919 + case sheet::DataPilotFieldOrientation_COLUMN:
4920 + ++mnColFieldCount;
4921 + break;
4922 + case sheet::DataPilotFieldOrientation_PAGE:
4923 + ++mnPageFieldCount;
4924 + break;
4925 + case sheet::DataPilotFieldOrientation_DATA:
4926 + ++mnDataFieldCount;
4927 + break;
4928 + case sheet::DataPilotFieldOrientation_HIDDEN:
4929 + default:
4933 + if (bHasHiddenMember)
4935 + // the layout name takes priority over the original name,
4936 + // since this data is used against cell values.
4937 + const OUString* pLayoutName = pDim->GetLayoutName();
4938 + if (pLayoutName)
4939 + maHiddenMemberFields.insert(*pLayoutName);
4940 + else
4941 + maHiddenMemberFields.insert(pDim->GetName());
4944 pDPSave->AddDimension(pDim);
4947 @@ -362,26 +441,15 @@ void ScXMLDataPilotTableContext::EndElement()
4949 break;
4951 - if (IsXMLToken(sGrandTotal, XML_BOTH))
4953 - pDPSave->SetRowGrand(sal_True);
4954 - pDPSave->SetColumnGrand(sal_True);
4956 - else if (IsXMLToken(sGrandTotal, XML_ROW))
4958 - pDPSave->SetRowGrand(sal_True);
4959 - pDPSave->SetColumnGrand(sal_False);
4961 - else if (IsXMLToken(sGrandTotal, XML_COLUMN))
4963 - pDPSave->SetRowGrand(sal_False);
4964 - pDPSave->SetColumnGrand(sal_True);
4966 - else
4968 - pDPSave->SetRowGrand(sal_False);
4969 - pDPSave->SetColumnGrand(sal_False);
4972 + pDPSave->SetRowGrand(maRowGrandTotal.mbVisible);
4973 + pDPSave->SetColumnGrand(maColGrandTotal.mbVisible);
4974 + if (maRowGrandTotal.maDisplayName.getLength())
4975 + // TODO: Right now, we only support one grand total name for both
4976 + // column and row totals. Take the value from the row total for
4977 + // now.
4978 + pDPSave->SetGrandTotalName(maRowGrandTotal.maDisplayName);
4980 pDPSave->SetIgnoreEmptyRows(bIgnoreEmptyRows);
4981 pDPSave->SetRepeatIfEmpty(bIdentifyCategories);
4982 pDPSave->SetFilterButton(bShowFilter);
4983 @@ -393,12 +461,36 @@ void ScXMLDataPilotTableContext::EndElement()
4985 ScDPCollection* pDPCollection = pDoc->GetDPCollection();
4986 pDPObject->SetAlive(sal_True);
4987 - pDPCollection->Insert(pDPObject);
4988 + pDPCollection->InsertNewTable(pDPObject);
4990 SetButtons();
4994 +void ScXMLDataPilotTableContext::SetGrandTotal(
4995 + XMLTokenEnum eOrientation, bool bVisible, const OUString& rDisplayName)
4997 + switch (eOrientation)
4999 + case XML_BOTH:
5000 + maRowGrandTotal.mbVisible = bVisible;
5001 + maRowGrandTotal.maDisplayName = rDisplayName;
5002 + maColGrandTotal.mbVisible = bVisible;
5003 + maColGrandTotal.maDisplayName = rDisplayName;
5004 + break;
5005 + case XML_ROW:
5006 + maRowGrandTotal.mbVisible = bVisible;
5007 + maRowGrandTotal.maDisplayName = rDisplayName;
5008 + break;
5009 + case XML_COLUMN:
5010 + maColGrandTotal.mbVisible = bVisible;
5011 + maColGrandTotal.maDisplayName = rDisplayName;
5012 + break;
5013 + default:
5018 ScXMLDPSourceSQLContext::ScXMLDPSourceSQLContext( ScXMLImport& rImport,
5019 USHORT nPrfx,
5020 const ::rtl::OUString& rLName,
5021 @@ -643,6 +735,80 @@ void ScXMLSourceServiceContext::EndElement()
5025 +ScXMLImport& ScXMLDataPilotGrandTotalContext::GetScImport()
5027 + return static_cast<ScXMLImport&>(GetImport());
5030 +ScXMLDataPilotGrandTotalContext::ScXMLDataPilotGrandTotalContext(
5031 + ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName, const Reference<XAttributeList>& xAttrList,
5032 + ScXMLDataPilotTableContext* pTableContext ) :
5033 + SvXMLImportContext( rImport, nPrefix, rLName ),
5034 + mpTableContext(pTableContext),
5035 + meOrientation(NONE),
5036 + mbVisible(false)
5038 + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
5039 + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotGrandTotalAttrTokenMap();
5040 + for (sal_Int16 i = 0; i < nAttrCount; ++i)
5042 + const OUString& rAttrName = xAttrList->getNameByIndex(i);
5043 + const OUString& rAttrValue = xAttrList->getValueByIndex(i);
5045 + OUString aLocalName;
5046 + USHORT nLocalPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
5047 + switch (rAttrTokenMap.Get(nLocalPrefix, aLocalName))
5049 + case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY:
5050 + mbVisible = IsXMLToken(rAttrValue, XML_TRUE);
5051 + break;
5052 + case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION:
5053 + if (IsXMLToken(rAttrValue, XML_BOTH))
5054 + meOrientation = BOTH;
5055 + else if (IsXMLToken(rAttrValue, XML_ROW))
5056 + meOrientation = ROW;
5057 + else if (IsXMLToken(rAttrValue, XML_COLUMN))
5058 + meOrientation = COLUMN;
5059 + break;
5060 + case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME:
5061 + maDisplayName = rAttrValue;
5062 + break;
5063 + default:
5069 +ScXMLDataPilotGrandTotalContext::~ScXMLDataPilotGrandTotalContext()
5073 +SvXMLImportContext* ScXMLDataPilotGrandTotalContext::CreateChildContext(
5074 + USHORT /*nPrefix*/, const ::rtl::OUString& /*rLocalName*/, const Reference<XAttributeList>& /*xAttrList*/ )
5076 + return NULL;
5079 +void ScXMLDataPilotGrandTotalContext::EndElement()
5081 + XMLTokenEnum eOrient = XML_NONE;
5082 + switch (meOrientation)
5084 + case BOTH:
5085 + eOrient = XML_BOTH;
5086 + break;
5087 + case ROW:
5088 + eOrient = XML_ROW;
5089 + break;
5090 + case COLUMN:
5091 + eOrient = XML_COLUMN;
5092 + break;
5093 + default:
5096 + mpTableContext->SetGrandTotal(eOrient, mbVisible, maDisplayName);
5099 ScXMLSourceCellRangeContext::ScXMLSourceCellRangeContext( ScXMLImport& rImport,
5100 USHORT nPrfx,
5101 const ::rtl::OUString& rLName,
5102 @@ -723,10 +889,12 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport,
5103 bIsGroupField(sal_False),
5104 bDateValue(sal_False),
5105 bAutoStart(sal_False),
5106 - bAutoEnd(sal_False)
5107 + bAutoEnd(sal_False),
5108 + mbHasHiddenMember(false)
5110 sal_Bool bHasName(sal_False);
5111 sal_Bool bDataLayout(sal_False);
5112 + OUString aDisplayName;
5113 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
5114 const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotFieldAttrTokenMap();
5115 for( sal_Int16 i=0; i < nAttrCount; ++i )
5116 @@ -745,6 +913,11 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport,
5117 bHasName = sal_True;
5119 break;
5120 + case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME:
5122 + aDisplayName = sValue;
5124 + break;
5125 case XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD :
5127 bDataLayout = IsXMLToken(sValue, XML_TRUE);
5128 @@ -774,7 +947,11 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport,
5131 if (bHasName)
5132 + {
5133 pDim = new ScDPSaveDimension(String(sName), bDataLayout);
5134 + if (aDisplayName.getLength())
5135 + pDim->SetLayoutName(aDisplayName);
5139 ScXMLDataPilotFieldContext::~ScXMLDataPilotFieldContext()
5140 @@ -808,6 +985,22 @@ SvXMLImportContext *ScXMLDataPilotFieldContext::CreateChildContext( USHORT nPref
5141 return pContext;
5144 +void ScXMLDataPilotFieldContext::AddMember(ScDPSaveMember* pMember)
5146 + if (pDim)
5147 + pDim->AddMember(pMember);
5149 + if (!pMember->GetIsVisible())
5150 + // This member is hidden.
5151 + mbHasHiddenMember = true;
5154 +void ScXMLDataPilotFieldContext::SetSubTotalName(const OUString& rName)
5156 + if (pDim)
5157 + pDim->SetSubtotalName(rName);
5160 void ScXMLDataPilotFieldContext::AddGroup(const ::std::vector<rtl::OUString>& rMembers, const rtl::OUString& rName)
5162 ScXMLDataPilotGroup aGroup;
5163 @@ -828,7 +1021,7 @@ void ScXMLDataPilotFieldContext::EndElement()
5164 String sPage(sSelectedPage);
5165 pDim->SetCurrentPage(&sPage);
5167 - pDataPilotTable->AddDimension(pDim);
5168 + pDataPilotTable->AddDimension(pDim, mbHasHiddenMember);
5169 if (bIsGroupField)
5171 ScDPNumGroupInfo aInfo;
5172 @@ -1199,6 +1392,8 @@ SvXMLImportContext *ScXMLDataPilotSubTotalsContext::CreateChildContext( USHORT n
5173 void ScXMLDataPilotSubTotalsContext::EndElement()
5175 pDataPilotField->SetSubTotals(pFunctions, nFunctionCount);
5176 + if (maDisplayName.getLength())
5177 + pDataPilotField->SetSubTotalName(maDisplayName);
5180 void ScXMLDataPilotSubTotalsContext::AddFunction(sal_Int16 nFunction)
5181 @@ -1221,6 +1416,11 @@ void ScXMLDataPilotSubTotalsContext::AddFunction(sal_Int16 nFunction)
5185 +void ScXMLDataPilotSubTotalsContext::SetDisplayName(const OUString& rName)
5187 + maDisplayName = rName;
5190 ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImport,
5191 USHORT nPrfx,
5192 const ::rtl::OUString& rLName,
5193 @@ -1247,6 +1447,8 @@ ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImpo
5194 pDataPilotSubTotals->AddFunction( sal::static_int_cast<sal_Int16>(
5195 ScXMLConverter::GetFunctionFromString( sValue ) ) );
5197 + case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME:
5198 + pDataPilotSubTotals->SetDisplayName(sValue);
5199 break;
5202 @@ -1344,6 +1546,10 @@ ScXMLDataPilotMemberContext::ScXMLDataPilotMemberContext( ScXMLImport& rImport,
5203 bHasName = sal_True;
5205 break;
5206 + case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME:
5208 + maDisplayName = sValue;
5210 case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY :
5212 bDisplay = IsXMLToken(sValue, XML_TRUE);
5213 @@ -1380,6 +1586,8 @@ void ScXMLDataPilotMemberContext::EndElement()
5214 if (bHasName) // #i53407# don't check sName, empty name is allowed
5216 ScDPSaveMember* pMember = new ScDPSaveMember(String(sName));
5217 + if (maDisplayName.getLength())
5218 + pMember->SetLayoutName(maDisplayName);
5219 pMember->SetIsVisible(bDisplay);
5220 pMember->SetShowDetails(bDisplayDetails);
5221 pDataPilotField->AddMember(pMember);
5222 diff --git sc/source/filter/xml/xmldpimp.hxx sc/source/filter/xml/xmldpimp.hxx
5223 index dfbba92..b4df6b1 100644
5224 --- sc/source/filter/xml/xmldpimp.hxx
5225 +++ sc/source/filter/xml/xmldpimp.hxx
5226 @@ -41,6 +41,8 @@
5227 #include "dpobject.hxx"
5228 #include "dpsave.hxx"
5230 +#include <hash_set>
5232 class ScXMLImport;
5233 class ScDPSaveNumGroupDimension;
5234 class ScDPSaveGroupDimension;
5235 @@ -79,10 +81,21 @@ public:
5237 class ScXMLDataPilotTableContext : public SvXMLImportContext
5239 + typedef ::std::hash_set< ::rtl::OUString, ::rtl::OUStringHash > StringSet;
5240 + StringSet maHiddenMemberFields;
5242 + struct GrandTotalItem
5244 + ::rtl::OUString maDisplayName;
5245 + bool mbVisible;
5246 + GrandTotalItem();
5247 + };
5248 ScDocument* pDoc;
5249 ScDPObject* pDPObject;
5250 ScDPSaveData* pDPSave;
5251 ScDPDimensionSaveData* pDPDimSaveData;
5252 + GrandTotalItem maRowGrandTotal;
5253 + GrandTotalItem maColGrandTotal;
5254 rtl::OUString sDataPilotTableName;
5255 rtl::OUString sApplicationData;
5256 rtl::OUString sGrandTotal;
5257 @@ -100,6 +113,10 @@ class ScXMLDataPilotTableContext : public SvXMLImportContext
5258 ScAddress aFilterOutputPosition;
5259 ScQueryParam aSourceQueryParam;
5260 ScMySourceType nSourceType;
5261 + sal_uInt32 mnRowFieldCount;
5262 + sal_uInt32 mnColFieldCount;
5263 + sal_uInt32 mnPageFieldCount;
5264 + sal_uInt32 mnDataFieldCount;
5265 sal_Bool bIsNative;
5266 sal_Bool bIgnoreEmptyRows;
5267 sal_Bool bIdentifyCategories;
5268 @@ -131,6 +148,7 @@ public:
5270 virtual void EndElement();
5272 + void SetGrandTotal(::xmloff::token::XMLTokenEnum eOrientation, bool bVisible, const ::rtl::OUString& rDisplayName);
5273 void SetDatabaseName(const rtl::OUString& sValue) { sDatabaseName = sValue; }
5274 void SetSourceObject(const rtl::OUString& sValue) { sSourceObject = sValue; }
5275 void SetNative(const sal_Bool bValue) { bIsNative = bValue; }
5276 @@ -147,7 +165,7 @@ public:
5277 void SetFilterSourceRange(const ScRange& aValue) { aFilterSourceRange = aValue; }
5278 // void SetFilterIsCaseSensitive(const sal_Bool bValue) { aSourceQueryParam.bCaseSens = bValue; }
5279 // void SetFilterSkipDuplicates(const sal_Bool bValue) { aSourceQueryParam.bDuplicate = !bValue; }
5280 - void AddDimension(ScDPSaveDimension* pDim);
5281 + void AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember);
5282 void AddGroupDim(const ScDPSaveNumGroupDimension& aNumGroupDim);
5283 void AddGroupDim(const ScDPSaveGroupDimension& aGroupDim);
5284 void SetButtons();
5285 @@ -253,6 +271,34 @@ public:
5286 virtual void EndElement();
5289 +class ScXMLDataPilotGrandTotalContext : public SvXMLImportContext
5291 + enum Orientation { COLUMN, ROW, BOTH, NONE };
5293 + ScXMLImport& GetScImport();
5295 + ScXMLDataPilotTableContext* mpTableContext;
5296 + ::rtl::OUString maDisplayName;
5297 + Orientation meOrientation;
5298 + bool mbVisible;
5300 +public:
5301 + ScXMLDataPilotGrandTotalContext(
5302 + ScXMLImport& rImport, USHORT nPrefix, const ::rtl::OUString& rLName,
5303 + const ::com::sun::star::uno::Reference<
5304 + ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
5305 + ScXMLDataPilotTableContext* pTableContext );
5307 + virtual ~ScXMLDataPilotGrandTotalContext();
5309 + virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
5310 + const ::rtl::OUString& rLocalName,
5311 + const ::com::sun::star::uno::Reference<
5312 + ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
5314 + virtual void EndElement();
5317 class ScXMLSourceCellRangeContext : public SvXMLImportContext
5319 ScXMLDataPilotTableContext* pDataPilotTable;
5320 @@ -300,12 +346,13 @@ class ScXMLDataPilotFieldContext : public SvXMLImportContext
5321 sal_Int32 nGroupPart;
5322 sal_Int16 nFunction;
5323 sal_Int16 nOrientation;
5324 - sal_Bool bShowEmpty;
5325 - sal_Bool bSelectedPage;
5326 - sal_Bool bIsGroupField;
5327 - sal_Bool bDateValue;
5328 - sal_Bool bAutoStart;
5329 - sal_Bool bAutoEnd;
5330 + sal_Bool bShowEmpty:1;
5331 + sal_Bool bSelectedPage:1;
5332 + sal_Bool bIsGroupField:1;
5333 + sal_Bool bDateValue:1;
5334 + sal_Bool bAutoStart:1;
5335 + sal_Bool bAutoEnd:1;
5336 + bool mbHasHiddenMember:1;
5338 const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
5339 ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
5340 @@ -329,7 +376,8 @@ public:
5342 void SetShowEmpty(const sal_Bool bValue) { if (pDim) pDim->SetShowEmpty(bValue); }
5343 void SetSubTotals(const sal_uInt16* pFunctions, const sal_Int16 nCount) { if(pDim) pDim->SetSubTotals(nCount, pFunctions); }
5344 - void AddMember(ScDPSaveMember* pMember) { if (pDim) pDim->AddMember(pMember); }
5345 + void AddMember(ScDPSaveMember* pMember);
5346 + void SetSubTotalName(const ::rtl::OUString& rName);
5347 void SetFieldReference(const com::sun::star::sheet::DataPilotFieldReference& aRef) { if (pDim) pDim->SetReferenceValue(&aRef); }
5348 void SetAutoShowInfo(const com::sun::star::sheet::DataPilotFieldAutoShowInfo& aInfo) { if (pDim) pDim->SetAutoShowInfo(&aInfo); }
5349 void SetSortInfo(const com::sun::star::sheet::DataPilotFieldSortInfo& aInfo) { if (pDim) pDim->SetSortInfo(&aInfo); }
5350 @@ -453,6 +501,7 @@ class ScXMLDataPilotSubTotalsContext : public SvXMLImportContext
5352 sal_Int16 nFunctionCount;
5353 sal_uInt16* pFunctions;
5354 + ::rtl::OUString maDisplayName;
5356 const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
5357 ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
5358 @@ -476,6 +525,7 @@ public:
5360 virtual void EndElement();
5361 void AddFunction(sal_Int16 nFunction);
5362 + void SetDisplayName(const ::rtl::OUString& rName);
5365 class ScXMLDataPilotSubTotalContext : public SvXMLImportContext
5366 @@ -533,6 +583,7 @@ class ScXMLDataPilotMemberContext : public SvXMLImportContext
5367 ScXMLDataPilotFieldContext* pDataPilotField;
5369 rtl::OUString sName;
5370 + rtl::OUString maDisplayName;
5371 sal_Bool bDisplay;
5372 sal_Bool bDisplayDetails;
5373 sal_Bool bHasName;
5374 diff --git sc/source/filter/xml/xmlimprt.cxx sc/source/filter/xml/xmlimprt.cxx
5375 index a45add1..7d9e882 100644
5376 --- sc/source/filter/xml/xmlimprt.cxx
5377 +++ sc/source/filter/xml/xmlimprt.cxx
5378 @@ -1345,6 +1345,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotTableElemTokenMap()
5380 { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL },
5381 { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE },
5382 + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL },
5383 { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY },
5384 { XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE },
5385 { XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE },
5386 @@ -1378,6 +1379,24 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceServiceAttrTokenMap()
5387 return *pDataPilotTableSourceServiceAttrTokenMap;
5390 +const SvXMLTokenMap& ScXMLImport::GetDataPilotGrandTotalAttrTokenMap()
5392 + if (!pDataPilotGrandTotalAttrTokenMap)
5394 + static __FAR_DATA SvXMLTokenMapEntry aDataPilotGrandTotalAttrTokenMap[] =
5396 + { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY },
5397 + { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION },
5398 + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME },
5399 + XML_TOKEN_MAP_END
5400 + };
5402 + pDataPilotGrandTotalAttrTokenMap = new SvXMLTokenMap( aDataPilotGrandTotalAttrTokenMap );
5405 + return *pDataPilotGrandTotalAttrTokenMap;
5408 const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceCellRangeAttrTokenMap()
5410 if( !pDataPilotTableSourceCellRangeAttrTokenMap )
5411 @@ -1417,6 +1436,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotFieldAttrTokenMap()
5412 static __FAR_DATA SvXMLTokenMapEntry aDataPilotFieldAttrTokenMap[] =
5414 { XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME },
5415 + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME },
5416 { XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD },
5417 { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION },
5418 { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION },
5419 @@ -1508,6 +1528,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotSubTotalAttrTokenMap()
5420 static __FAR_DATA SvXMLTokenMapEntry aDataPilotSubTotalAttrTokenMap[] =
5422 { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION },
5423 + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME },
5424 XML_TOKEN_MAP_END
5427 @@ -1540,6 +1561,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotMemberAttrTokenMap()
5428 static __FAR_DATA SvXMLTokenMapEntry aDataPilotMemberAttrTokenMap[] =
5430 { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME },
5431 + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME },
5432 { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY },
5433 { XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS },
5434 XML_TOKEN_MAP_END
5435 @@ -1675,6 +1697,7 @@ ScXMLImport::ScXMLImport(
5436 pDataPilotTableAttrTokenMap( 0 ),
5437 pDataPilotTableElemTokenMap( 0 ),
5438 pDataPilotTableSourceServiceAttrTokenMap( 0 ),
5439 + pDataPilotGrandTotalAttrTokenMap(NULL),
5440 pDataPilotTableSourceCellRangeElemTokenMap( 0 ),
5441 pDataPilotTableSourceCellRangeAttrTokenMap( 0 ),
5442 pDataPilotFieldAttrTokenMap( 0 ),
5443 diff --git sc/source/filter/xml/xmlimprt.hxx sc/source/filter/xml/xmlimprt.hxx
5444 index f9cdfe0..139acf5 100644
5445 --- sc/source/filter/xml/xmlimprt.hxx
5446 +++ sc/source/filter/xml/xmlimprt.hxx
5447 @@ -489,6 +489,7 @@ enum ScXMLDataPilotTableElemTokens
5449 XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL,
5450 XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE,
5451 + XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL,
5452 XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY,
5453 XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE,
5454 XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE,
5455 @@ -504,6 +505,13 @@ enum ScXMLDataPilotTableSourceServiceAttrTokens
5456 XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD
5459 +enum ScXMLDataPilotGrandTotalAttrTokens
5461 + XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY,
5462 + XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION,
5463 + XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME
5466 enum ScXMLDataPilotTableSourceCellRangeElemTokens
5468 XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER
5469 @@ -517,6 +525,7 @@ enum ScXMLDataPilotTableSourceCellRangeAttrTokens
5470 enum ScXMLDataPilotFieldAttrTokens
5472 XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME,
5473 + XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME,
5474 XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD,
5475 XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION,
5476 XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION,
5477 @@ -552,7 +561,8 @@ enum ScXMLDataPilotSubTotalsElemTokens
5479 enum ScXMLDataPilotSubTotalAttrTokens
5481 - XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION
5482 + XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION,
5483 + XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME
5486 enum ScXMLDataPilotMembersElemTokens
5487 @@ -563,6 +573,7 @@ enum ScXMLDataPilotMembersElemTokens
5488 enum ScXMLDataPilotMemberAttrTokens
5490 XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME,
5491 + XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME,
5492 XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY,
5493 XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS
5495 @@ -723,6 +734,7 @@ class ScXMLImport: public SvXMLImport
5496 SvXMLTokenMap *pDataPilotTableAttrTokenMap;
5497 SvXMLTokenMap *pDataPilotTableElemTokenMap;
5498 SvXMLTokenMap *pDataPilotTableSourceServiceAttrTokenMap;
5499 + SvXMLTokenMap *pDataPilotGrandTotalAttrTokenMap;
5500 SvXMLTokenMap *pDataPilotTableSourceCellRangeElemTokenMap;
5501 SvXMLTokenMap *pDataPilotTableSourceCellRangeAttrTokenMap;
5502 SvXMLTokenMap *pDataPilotFieldAttrTokenMap;
5503 @@ -886,6 +898,7 @@ public:
5504 const SvXMLTokenMap& GetDataPilotTableAttrTokenMap();
5505 const SvXMLTokenMap& GetDataPilotTableElemTokenMap();
5506 const SvXMLTokenMap& GetDataPilotTableSourceServiceAttrTokenMap();
5507 + const SvXMLTokenMap& GetDataPilotGrandTotalAttrTokenMap();
5508 const SvXMLTokenMap& GetDataPilotTableSourceCellRangeElemTokenMap();
5509 const SvXMLTokenMap& GetDataPilotTableSourceCellRangeAttrTokenMap();
5510 const SvXMLTokenMap& GetDataPilotFieldAttrTokenMap();
5511 diff --git sc/source/ui/Accessibility/AccessibleContextBase.cxx sc/source/ui/Accessibility/AccessibleContextBase.cxx
5512 index efde039..8978bfa 100644
5513 --- sc/source/ui/Accessibility/AccessibleContextBase.cxx
5514 +++ sc/source/ui/Accessibility/AccessibleContextBase.cxx
5515 @@ -628,3 +628,8 @@ void ScAccessibleContextBase::IsObjectValid() const
5516 if (rBHelper.bDisposed || rBHelper.bInDispose)
5517 throw lang::DisposedException();
5520 +void ScAccessibleContextBase::SetRole(sal_Int16 nRole)
5522 + maRole = nRole;
5524 diff --git sc/source/ui/Accessibility/AccessibleFilterMenu.cxx sc/source/ui/Accessibility/AccessibleFilterMenu.cxx
5525 new file mode 100644
5526 index 0000000..8a76393
5527 --- /dev/null
5528 +++ sc/source/ui/Accessibility/AccessibleFilterMenu.cxx
5529 @@ -0,0 +1,402 @@
5530 +/*************************************************************************
5532 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5533 + *
5534 + * Copyright 2008 by Sun Microsystems, Inc.
5536 + * OpenOffice.org - a multi-platform office productivity suite
5538 + * $RCSfile: AccessibleDataPilotControl.hxx,v $
5539 + * $Revision: 1.6 $
5541 + * This file is part of OpenOffice.org.
5543 + * OpenOffice.org is free software: you can redistribute it and/or modify
5544 + * it under the terms of the GNU Lesser General Public License version 3
5545 + * only, as published by the Free Software Foundation.
5547 + * OpenOffice.org is distributed in the hope that it will be useful,
5548 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5549 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5550 + * GNU Lesser General Public License version 3 for more details
5551 + * (a copy is included in the LICENSE file that accompanied this code).
5553 + * You should have received a copy of the GNU Lesser General Public License
5554 + * version 3 along with OpenOffice.org. If not, see
5555 + * <http://www.openoffice.org/license.html>
5556 + * for a copy of the LGPLv3 License.
5558 + ************************************************************************/
5560 +// MARKER(update_precomp.py): autogen include statement, do not remove
5562 +#include "precompiled_sc.hxx"
5563 +#include "AccessibleGlobal.hxx"
5564 +#include "AccessibleFilterMenu.hxx"
5565 +#include "AccessibleFilterMenuItem.hxx"
5566 +#include "unoguard.hxx"
5567 +#include "global.hxx"
5568 +#include "document.hxx"
5569 +#include "docpool.hxx"
5571 +#include "tools/gen.hxx"
5572 +#include "svx/unoedsrc.hxx"
5573 +#include "svx/editdata.hxx"
5574 +#include "svx/outliner.hxx"
5575 +#include "svtools/itemset.hxx"
5576 +#include "vcl/unohelp.hxx"
5577 +#include "dpcontrol.hxx"
5579 +#include <com/sun/star/accessibility/XAccessible.hpp>
5580 +#include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
5581 +#include <com/sun/star/accessibility/AccessibleRole.hpp>
5582 +#include <com/sun/star/accessibility/AccessibleEventId.hpp>
5583 +#include <com/sun/star/accessibility/AccessibleStateType.hpp>
5585 +using namespace ::com::sun::star;
5586 +using namespace ::com::sun::star::accessibility;
5587 +using namespace ::com::sun::star::accessibility::AccessibleStateType;
5589 +using ::com::sun::star::uno::Any;
5590 +using ::com::sun::star::uno::Reference;
5591 +using ::com::sun::star::uno::Sequence;
5592 +using ::com::sun::star::uno::UNO_QUERY;
5593 +using ::com::sun::star::lang::IndexOutOfBoundsException;
5594 +using ::com::sun::star::lang::IllegalArgumentException;
5595 +using ::com::sun::star::uno::RuntimeException;
5596 +using ::rtl::OUString;
5597 +using ::std::for_each;
5598 +using ::std::vector;
5600 +// ============================================================================
5602 +namespace {
5604 +class AddRemoveEventListener : public ::std::unary_function<void, Reference<XAccessible> >
5606 +public:
5607 + explicit AddRemoveEventListener(const Reference<XAccessibleEventListener>& rListener, bool bAdd) :
5608 + mxListener(rListener), mbAdd(bAdd) {}
5610 + void operator() (const Reference<XAccessible>& xAccessible) const
5612 + if (!xAccessible.is())
5613 + return;
5615 + Reference<XAccessibleEventBroadcaster> xBc(xAccessible, UNO_QUERY);
5616 + if (xBc.is())
5618 + if (mbAdd)
5619 + xBc->addEventListener(mxListener);
5620 + else
5621 + xBc->removeEventListener(mxListener);
5624 +private:
5625 + Reference<XAccessibleEventListener> mxListener;
5626 + bool mbAdd;
5631 +// ============================================================================
5633 +ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos, ScDocument* pDoc) :
5634 + ScAccessibleContextBase(rxParent, AccessibleRole::MENU),
5635 + mnMenuPos(nMenuPos),
5636 + mpWindow(pWin),
5637 + mpDoc(pDoc),
5638 + mbEnabled(true)
5640 + SetName(rName);
5643 +ScAccessibleFilterMenu::~ScAccessibleFilterMenu()
5647 +// XAccessibleComponent
5649 +Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleAtPoint( const ::com::sun::star::awt::Point& /*rPoint*/ )
5650 + throw (RuntimeException)
5652 + return this;
5655 +sal_Bool ScAccessibleFilterMenu::isVisible() throw (RuntimeException)
5657 + return mpWindow->IsVisible();
5660 +void ScAccessibleFilterMenu::grabFocus()
5661 + throw (RuntimeException)
5665 +sal_Int32 ScAccessibleFilterMenu::getForeground()
5666 + throw (RuntimeException)
5668 + return 0;
5671 +sal_Int32 ScAccessibleFilterMenu::getBackground()
5672 + throw (RuntimeException)
5674 + return 0;
5677 +// XAccessibleContext
5679 +OUString ScAccessibleFilterMenu::getAccessibleName() throw (RuntimeException)
5681 + return ScAccessibleContextBase::getAccessibleName();
5684 +sal_Int32 ScAccessibleFilterMenu::getAccessibleChildCount()
5685 + throw (RuntimeException)
5687 + return getMenuItemCount();
5690 +Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleChild(sal_Int32 nIndex)
5691 + throw (RuntimeException, IndexOutOfBoundsException)
5693 + if (maMenuItems.size() <= static_cast<size_t>(nIndex))
5694 + throw IndexOutOfBoundsException();
5696 + return maMenuItems[nIndex];
5699 +Reference<XAccessibleStateSet> ScAccessibleFilterMenu::getAccessibleStateSet()
5700 + throw (RuntimeException)
5702 + updateStates();
5703 + return mxStateSet;
5706 +OUString ScAccessibleFilterMenu::getImplementationName()
5707 + throw (RuntimeException)
5709 + return OUString::createFromAscii("ScAccessibleFilterMenu");
5712 +// XAccessibleEventBroadcaster
5714 +void ScAccessibleFilterMenu::addEventListener(
5715 + const ::com::sun::star::uno::Reference<
5716 + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
5717 + throw (com::sun::star::uno::RuntimeException)
5719 + ScAccessibleContextBase::addEventListener(xListener);
5720 + for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, true));
5723 +void ScAccessibleFilterMenu::removeEventListener(
5724 + const ::com::sun::star::uno::Reference<
5725 + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
5726 + throw (com::sun::star::uno::RuntimeException)
5728 + ScAccessibleContextBase::removeEventListener(xListener);
5729 + for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, false));
5732 +// XAccessibleSelection
5734 +void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex)
5735 + throw (IndexOutOfBoundsException, RuntimeException)
5737 + if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
5738 + throw IndexOutOfBoundsException();
5740 + mpWindow->setSelectedMenuItem(nChildIndex, false, true);
5743 +sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex)
5744 + throw (IndexOutOfBoundsException, RuntimeException)
5746 + if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
5747 + throw IndexOutOfBoundsException();
5749 + return mpWindow->isMenuItemSelected(static_cast<size_t>(nChildIndex));
5752 +void ScAccessibleFilterMenu::clearAccessibleSelection() throw (RuntimeException)
5754 + mpWindow->clearSelectedMenuItem();
5757 +void ScAccessibleFilterMenu::selectAllAccessibleChildren() throw (RuntimeException)
5759 + // not suported - this is a menu, you can't select all menu items.
5762 +sal_Int32 ScAccessibleFilterMenu::getSelectedAccessibleChildCount() throw (RuntimeException)
5764 + // Since this is a menu, either one menu item is selected, or none at all.
5765 + return mpWindow->getSelectedMenuItem() == ScMenuFloatingWindow::MENU_NOT_SELECTED ? 0 : 1;
5768 +Reference<XAccessible> ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_Int32 nChildIndex)
5769 + throw (IndexOutOfBoundsException, RuntimeException)
5771 + if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
5772 + throw IndexOutOfBoundsException();
5774 + return maMenuItems[nChildIndex];
5777 +void ScAccessibleFilterMenu::deselectAccessibleChild(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException)
5779 + if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
5780 + throw IndexOutOfBoundsException();
5782 + mpWindow->selectMenuItem(nChildIndex, false, false);
5785 +// XInterface
5787 +uno::Any SAL_CALL ScAccessibleFilterMenu::queryInterface( uno::Type const & rType )
5788 + throw (RuntimeException)
5790 + Any any = ScAccessibleContextBase::queryInterface(rType);
5791 + if (any.hasValue())
5792 + return any;
5794 + return ScAccessibleFilterMenu_BASE::queryInterface(rType);
5797 +void SAL_CALL ScAccessibleFilterMenu::acquire() throw ()
5799 + ScAccessibleContextBase::acquire();
5802 +void SAL_CALL ScAccessibleFilterMenu::release() throw ()
5804 + ScAccessibleContextBase::release();
5807 +// XTypeProvider
5809 +Sequence<sal_Int8> ScAccessibleFilterMenu::getImplementationId()
5810 + throw (RuntimeException)
5812 + Sequence<sal_Int8> aId(16);
5813 + return aId;
5816 +Rectangle ScAccessibleFilterMenu::GetBoundingBoxOnScreen() const
5817 + throw (RuntimeException)
5819 + if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED)
5820 + return Rectangle();
5822 + // Menu object's bounding box is the bounding box of the menu item that
5823 + // launches the menu, which belongs to the parent window.
5824 + ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow();
5825 + if (!pParentWin)
5826 + return Rectangle();
5828 + if (!pParentWin->IsVisible())
5829 + return Rectangle();
5831 + Point aPos = pParentWin->OutputToAbsoluteScreenPixel(Point(0,0));
5832 + Point aMenuPos;
5833 + Size aMenuSize;
5834 + pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
5835 + Rectangle aRect(aPos + aMenuPos, aMenuSize);
5836 + return aRect;
5839 +Rectangle ScAccessibleFilterMenu::GetBoundingBox() const
5840 + throw (RuntimeException)
5842 + if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED)
5843 + return Rectangle();
5845 + // Menu object's bounding box is the bounding box of the menu item that
5846 + // launches the menu, which belongs to the parent window.
5847 + ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow();
5848 + if (!pParentWin)
5849 + return Rectangle();
5851 + if (!pParentWin->IsVisible())
5852 + return Rectangle();
5854 + Point aMenuPos;
5855 + Size aMenuSize;
5856 + pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
5857 + Rectangle aRect(aMenuPos, aMenuSize);
5858 + return aRect;
5861 +void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled, size_t nMenuPos)
5863 + // Check weather this menu item is a sub menu or a regular menu item.
5864 + ScMenuFloatingWindow* pSubMenu = mpWindow->getSubMenuWindow(nMenuPos);
5865 + Reference<XAccessible> xAccessible;
5866 + if (pSubMenu)
5868 + xAccessible = pSubMenu->CreateAccessible();
5869 + ScAccessibleFilterMenu* p =
5870 + static_cast<ScAccessibleFilterMenu*>(xAccessible.get());
5871 + p->setEnabled(bEnabled);
5872 + p->setMenuPos(nMenuPos);
5874 + else
5876 + xAccessible.set(new ScAccessibleFilterMenuItem(this, mpWindow, rName, nMenuPos));
5877 + ScAccessibleFilterMenuItem* p =
5878 + static_cast<ScAccessibleFilterMenuItem*>(xAccessible.get());
5879 + p->setEnabled(bEnabled);
5881 + maMenuItems.push_back(xAccessible);
5884 +void ScAccessibleFilterMenu::setMenuPos(size_t nMenuPos)
5886 + mnMenuPos = nMenuPos;
5889 +void ScAccessibleFilterMenu::setEnabled(bool bEnabled)
5891 + mbEnabled = bEnabled;
5894 +sal_Int32 ScAccessibleFilterMenu::getMenuItemCount() const
5896 + return maMenuItems.size();
5899 +bool ScAccessibleFilterMenu::isSelected() const
5901 + // Check to see if any of the child menu items is selected.
5902 + return mpWindow->isMenuItemSelected(mnMenuPos);
5905 +bool ScAccessibleFilterMenu::isFocused() const
5907 + return isSelected();
5910 +void ScAccessibleFilterMenu::updateStates()
5912 + if (!mxStateSet.is())
5913 + mxStateSet.set(new ScAccessibleStateSet);
5915 + ScAccessibleStateSet* p = static_cast<ScAccessibleStateSet*>(
5916 + mxStateSet.get());
5918 + p->clear();
5920 + p->insert(ENABLED);
5921 + p->insert(FOCUSABLE);
5922 + p->insert(SELECTABLE);
5923 + p->insert(SENSITIVE);
5924 + p->insert(OPAQUE);
5926 + if (isFocused())
5927 + p->insert(FOCUSED);
5929 + if (isSelected())
5930 + p->insert(SELECTED);
5932 diff --git sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx
5933 new file mode 100644
5934 index 0000000..7216819
5935 --- /dev/null
5936 +++ sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx
5937 @@ -0,0 +1,209 @@
5938 +/*************************************************************************
5940 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5941 + *
5942 + * Copyright 2008 by Sun Microsystems, Inc.
5944 + * OpenOffice.org - a multi-platform office productivity suite
5946 + * $RCSfile: AccessibleDataPilotControl.hxx,v $
5947 + * $Revision: 1.6 $
5949 + * This file is part of OpenOffice.org.
5951 + * OpenOffice.org is free software: you can redistribute it and/or modify
5952 + * it under the terms of the GNU Lesser General Public License version 3
5953 + * only, as published by the Free Software Foundation.
5955 + * OpenOffice.org is distributed in the hope that it will be useful,
5956 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5957 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5958 + * GNU Lesser General Public License version 3 for more details
5959 + * (a copy is included in the LICENSE file that accompanied this code).
5961 + * You should have received a copy of the GNU Lesser General Public License
5962 + * version 3 along with OpenOffice.org. If not, see
5963 + * <http://www.openoffice.org/license.html>
5964 + * for a copy of the LGPLv3 License.
5966 + ************************************************************************/
5968 +// MARKER(update_precomp.py): autogen include statement, do not remove
5970 +#include "precompiled_sc.hxx"
5971 +#include "AccessibleGlobal.hxx"
5972 +#include "AccessibleFilterMenuItem.hxx"
5973 +#include "dpcontrol.hxx"
5975 +#include <com/sun/star/accessibility/XAccessible.hpp>
5976 +#include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
5977 +#include <com/sun/star/accessibility/AccessibleRole.hpp>
5978 +#include <com/sun/star/accessibility/AccessibleEventId.hpp>
5979 +#include <com/sun/star/accessibility/AccessibleEventObject.hpp>
5980 +#include <com/sun/star/accessibility/AccessibleStateType.hpp>
5981 +#include <com/sun/star/accessibility/TextSegment.hpp>
5983 +using namespace ::com::sun::star;
5984 +using namespace ::com::sun::star::accessibility;
5985 +using namespace ::com::sun::star::accessibility::AccessibleStateType;
5987 +using ::com::sun::star::uno::Any;
5988 +using ::com::sun::star::uno::Reference;
5989 +using ::com::sun::star::uno::Sequence;
5990 +using ::com::sun::star::uno::UNO_QUERY;
5991 +using ::com::sun::star::lang::IndexOutOfBoundsException;
5992 +using ::com::sun::star::uno::RuntimeException;
5993 +using ::rtl::OUString;
5995 +ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem(
5996 + const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos) :
5997 + ScAccessibleContextBase(rxParent, AccessibleRole::MENU_ITEM),
5998 + mpWindow(pWin),
5999 + maName(rName),
6000 + mnMenuPos(nMenuPos),
6001 + mbEnabled(true)
6003 + SetName(rName);
6006 +ScAccessibleFilterMenuItem::~ScAccessibleFilterMenuItem()
6010 +sal_Int32 ScAccessibleFilterMenuItem::getAccessibleChildCount()
6011 + throw (RuntimeException)
6013 + return 0;
6016 +Reference<XAccessible> ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 /*nIndex*/)
6017 + throw (RuntimeException, IndexOutOfBoundsException)
6019 + throw IndexOutOfBoundsException();
6020 + return Reference<XAccessible>();
6023 +Reference<XAccessibleStateSet> ScAccessibleFilterMenuItem::getAccessibleStateSet()
6024 + throw (RuntimeException)
6026 + updateStateSet();
6027 + return mxStateSet;
6030 +OUString ScAccessibleFilterMenuItem::getImplementationName()
6031 + throw (RuntimeException)
6033 + return OUString::createFromAscii("ScAccessibleFilterMenuItem");
6036 +// XAccessibleAction
6038 +sal_Int32 ScAccessibleFilterMenuItem::getAccessibleActionCount() throw (RuntimeException)
6040 + return 1;
6043 +sal_Bool ScAccessibleFilterMenuItem::doAccessibleAction(sal_Int32 /*nIndex*/)
6044 + throw (IndexOutOfBoundsException, RuntimeException)
6046 + mpWindow->executeMenuItem(mnMenuPos);
6047 + return true;
6050 +OUString ScAccessibleFilterMenuItem::getAccessibleActionDescription(sal_Int32 /*nIndex*/)
6051 + throw (IndexOutOfBoundsException, RuntimeException)
6053 + return OUString::createFromAscii("click");
6056 +Reference<XAccessibleKeyBinding> ScAccessibleFilterMenuItem::getAccessibleActionKeyBinding(
6057 + sal_Int32 /*nIndex*/) throw (IndexOutOfBoundsException, RuntimeException)
6059 + return Reference<XAccessibleKeyBinding>();
6062 +Any SAL_CALL ScAccessibleFilterMenuItem::queryInterface( uno::Type const & rType )
6063 + throw (RuntimeException)
6065 + Any any = ScAccessibleContextBase::queryInterface(rType);
6066 + if (any.hasValue())
6067 + return any;
6069 + return ScAccessibleFilterMenuItem_BASE::queryInterface(rType);
6072 +void SAL_CALL ScAccessibleFilterMenuItem::acquire() throw ()
6074 + ScAccessibleContextBase::acquire();
6077 +void SAL_CALL ScAccessibleFilterMenuItem::release() throw ()
6079 + ScAccessibleContextBase::release();
6082 +bool ScAccessibleFilterMenuItem::isSelected() const
6084 + return mpWindow->isMenuItemSelected(mnMenuPos);
6087 +bool ScAccessibleFilterMenuItem::isFocused() const
6089 + return isSelected();
6092 +void ScAccessibleFilterMenuItem::setEnabled(bool bEnabled)
6094 + mbEnabled = bEnabled;
6097 +Rectangle ScAccessibleFilterMenuItem::GetBoundingBoxOnScreen() const
6098 + throw (RuntimeException)
6100 + if (!mpWindow->IsVisible())
6101 + return Rectangle();
6103 + Point aPos = mpWindow->OutputToAbsoluteScreenPixel(Point(0,0));
6104 + Point aMenuPos;
6105 + Size aMenuSize;
6106 + mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
6107 + Rectangle aRect(aPos + aMenuPos, aMenuSize);
6108 + return aRect;
6111 +Rectangle ScAccessibleFilterMenuItem::GetBoundingBox() const
6112 + throw (RuntimeException)
6114 + if (!mpWindow->IsVisible())
6115 + return Rectangle();
6117 + Point aMenuPos;
6118 + Size aMenuSize;
6119 + mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
6120 + Rectangle aRect(aMenuPos, aMenuSize);
6121 + return aRect;
6124 +void ScAccessibleFilterMenuItem::updateStateSet()
6126 + if (!mxStateSet.is())
6127 + mxStateSet.set(new ScAccessibleStateSet);
6129 + ScAccessibleStateSet* p = static_cast<ScAccessibleStateSet*>(
6130 + mxStateSet.get());
6132 + p->clear();
6134 + p->insert(ENABLED);
6135 + p->insert(FOCUSABLE);
6136 + p->insert(SELECTABLE);
6137 + p->insert(SENSITIVE);
6138 + p->insert(OPAQUE);
6140 + if (isFocused())
6141 + p->insert(FOCUSED);
6143 + if (isSelected())
6144 + p->insert(SELECTED);
6147 diff --git sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx
6148 new file mode 100644
6149 index 0000000..e9834f8
6150 --- /dev/null
6151 +++ sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx
6152 @@ -0,0 +1,137 @@
6153 +/*************************************************************************
6155 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6156 + *
6157 + * Copyright 2008 by Sun Microsystems, Inc.
6159 + * OpenOffice.org - a multi-platform office productivity suite
6161 + * $RCSfile: AccessibleDataPilotControl.hxx,v $
6162 + * $Revision: 1.6 $
6164 + * This file is part of OpenOffice.org.
6166 + * OpenOffice.org is free software: you can redistribute it and/or modify
6167 + * it under the terms of the GNU Lesser General Public License version 3
6168 + * only, as published by the Free Software Foundation.
6170 + * OpenOffice.org is distributed in the hope that it will be useful,
6171 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6172 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6173 + * GNU Lesser General Public License version 3 for more details
6174 + * (a copy is included in the LICENSE file that accompanied this code).
6176 + * You should have received a copy of the GNU Lesser General Public License
6177 + * version 3 along with OpenOffice.org. If not, see
6178 + * <http://www.openoffice.org/license.html>
6179 + * for a copy of the LGPLv3 License.
6181 + ************************************************************************/
6183 +// MARKER(update_precomp.py): autogen include statement, do not remove
6185 +#include "precompiled_sc.hxx"
6186 +#include "AccessibleFilterTopWindow.hxx"
6187 +#include "AccessibleFilterMenu.hxx"
6188 +#include "dpcontrol.hxx"
6190 +#include <com/sun/star/accessibility/AccessibleRole.hpp>
6192 +using namespace ::com::sun::star;
6193 +using namespace ::com::sun::star::accessibility;
6194 +using ::com::sun::star::lang::IndexOutOfBoundsException;
6195 +using ::com::sun::star::uno::Reference;
6196 +using ::com::sun::star::uno::RuntimeException;
6197 +using ::rtl::OUString;
6199 +ScAccessibleFilterTopWindow::ScAccessibleFilterTopWindow(
6200 + const Reference<XAccessible>& rxParent, ScDPFieldPopupWindow* pWin, const OUString& rName, ScDocument* pDoc) :
6201 + ScAccessibleFilterMenu(rxParent, pWin, rName, ScMenuFloatingWindow::MENU_NOT_SELECTED, pDoc),
6202 + mpWindow(pWin),
6203 + mpDoc(pDoc)
6205 + SetName(rName);
6208 +ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow()
6212 +// XAccessibleContext
6214 +sal_Int32 ScAccessibleFilterTopWindow::getAccessibleChildCount() throw (RuntimeException)
6216 + sal_Int32 nMenuCount = getMenuItemCount();
6217 + return nMenuCount + 6;
6220 +Reference<XAccessible> ScAccessibleFilterTopWindow::getAccessibleChild(
6221 + sal_Int32 nIndex) throw (RuntimeException, IndexOutOfBoundsException)
6223 + if (nIndex >= getAccessibleChildCount())
6224 + throw IndexOutOfBoundsException();
6226 + sal_Int32 nMenuCount = getMenuItemCount();
6227 + if (nIndex < nMenuCount)
6228 + return ScAccessibleFilterMenu::getAccessibleChild(nIndex);
6230 + nIndex -= nMenuCount;
6231 + switch (nIndex)
6233 + case 0:
6234 + return mxAccListBox;
6235 + case 1:
6236 + return mxAccToggleAll;
6237 + case 2:
6238 + return mxAccSingleOnBtn;
6239 + case 3:
6240 + return mxAccSingleOffBtn;
6241 + case 4:
6242 + return mxAccOkBtn;
6243 + case 5:
6244 + return mxAccCancelBtn;
6245 + default:
6249 + return Reference<XAccessible>();
6252 +OUString ScAccessibleFilterTopWindow::getImplementationName() throw (RuntimeException)
6254 + return OUString::createFromAscii("ScAccessibleFilterTopWindow");
6257 +Reference<XAccessible> ScAccessibleFilterTopWindow::getAccessibleChildMenu()
6259 + if (!mxAccMenu.is())
6260 + mxAccMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), ScMenuFloatingWindow::MENU_NOT_SELECTED, mpDoc));
6261 + return mxAccMenu;
6264 +void ScAccessibleFilterTopWindow::setAccessibleChild(
6265 + const Reference<XAccessible>& rAccessible, ChildControlType eType)
6267 + switch (eType)
6269 + case LISTBOX:
6270 + mxAccListBox = rAccessible;
6271 + break;
6272 + case TOGGLE_ALL:
6273 + mxAccToggleAll = rAccessible;
6274 + break;
6275 + case SINGLE_ON_BTN:
6276 + mxAccSingleOnBtn = rAccessible;
6277 + break;
6278 + case SINGLE_OFF_BTN:
6279 + mxAccSingleOffBtn = rAccessible;
6280 + break;
6281 + case OK_BTN:
6282 + mxAccOkBtn = rAccessible;
6283 + break;
6284 + case CANCEL_BTN:
6285 + mxAccCancelBtn = rAccessible;
6286 + break;
6290 diff --git sc/source/ui/Accessibility/AccessibleGlobal.cxx sc/source/ui/Accessibility/AccessibleGlobal.cxx
6291 new file mode 100644
6292 index 0000000..f37bd4b
6293 --- /dev/null
6294 +++ sc/source/ui/Accessibility/AccessibleGlobal.cxx
6295 @@ -0,0 +1,98 @@
6296 +/*************************************************************************
6298 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6299 + *
6300 + * Copyright 2008 by Sun Microsystems, Inc.
6302 + * OpenOffice.org - a multi-platform office productivity suite
6304 + * $RCSfile: AccessibleDataPilotControl.hxx,v $
6305 + * $Revision: 1.6 $
6307 + * This file is part of OpenOffice.org.
6309 + * OpenOffice.org is free software: you can redistribute it and/or modify
6310 + * it under the terms of the GNU Lesser General Public License version 3
6311 + * only, as published by the Free Software Foundation.
6313 + * OpenOffice.org is distributed in the hope that it will be useful,
6314 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6315 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6316 + * GNU Lesser General Public License version 3 for more details
6317 + * (a copy is included in the LICENSE file that accompanied this code).
6319 + * You should have received a copy of the GNU Lesser General Public License
6320 + * version 3 along with OpenOffice.org. If not, see
6321 + * <http://www.openoffice.org/license.html>
6322 + * for a copy of the LGPLv3 License.
6324 + ************************************************************************/
6326 +// MARKER(update_precomp.py): autogen include statement, do not remove
6328 +#include "precompiled_sc.hxx"
6329 +#include "AccessibleGlobal.hxx"
6331 +using ::com::sun::star::uno::RuntimeException;
6332 +using ::com::sun::star::uno::Reference;
6333 +using ::com::sun::star::uno::Sequence;
6334 +using ::std::set;
6336 +ScAccessibleStateSet::ScAccessibleStateSet()
6340 +ScAccessibleStateSet::~ScAccessibleStateSet()
6344 +// XAccessibleStateSet
6346 +sal_Bool SAL_CALL ScAccessibleStateSet::isEmpty() throw (RuntimeException)
6348 + return maStates.empty();
6351 +sal_Bool SAL_CALL ScAccessibleStateSet::contains(sal_Int16 nState)
6352 + throw (RuntimeException)
6354 + return maStates.count(nState) != 0;
6357 +sal_Bool SAL_CALL ScAccessibleStateSet::containsAll(
6358 + const Sequence<sal_Int16>& aStateSet) throw (RuntimeException)
6360 + sal_Int32 n = aStateSet.getLength();
6361 + for (sal_Int32 i = 0; i < n; ++i)
6363 + if (!maStates.count(aStateSet[i]))
6364 + // This state is not set.
6365 + return false;
6367 + // All specified states are set.
6368 + return true;
6371 +Sequence<sal_Int16> SAL_CALL ScAccessibleStateSet::getStates()
6372 + throw (RuntimeException)
6374 + Sequence<sal_Int16> aSeq(0);
6375 + set<sal_Int16>::const_iterator itr = maStates.begin(), itrEnd = maStates.end();
6376 + for (size_t i = 0; itr != itrEnd; ++itr, ++i)
6378 + aSeq.realloc(i+1);
6379 + aSeq[i] = *itr;
6381 + return aSeq;
6384 +void ScAccessibleStateSet::insert(sal_Int16 nState)
6386 + maStates.insert(nState);
6389 +void ScAccessibleStateSet::clear()
6391 + maStates.clear();
6394 diff --git sc/source/ui/Accessibility/makefile.mk sc/source/ui/Accessibility/makefile.mk
6395 index dfa5ac9..2942914 100644
6396 --- sc/source/ui/Accessibility/makefile.mk
6397 +++ sc/source/ui/Accessibility/makefile.mk
6398 @@ -47,12 +47,16 @@ SLOFILES = \
6399 $(SLO)$/AccessibleContextBase.obj \
6400 $(SLO)$/AccessibleTableBase.obj \
6401 $(SLO)$/AccessibleDocument.obj \
6402 + $(SLO)$/AccessibleGlobal.obj \
6403 $(SLO)$/AccessibleSpreadsheet.obj \
6404 $(SLO)$/AccessibleCell.obj \
6405 $(SLO)$/AccessibilityHints.obj \
6406 $(SLO)$/AccessibleDocumentBase.obj \
6407 $(SLO)$/AccessibleCellBase.obj \
6408 $(SLO)$/AccessibleDocumentPagePreview.obj \
6409 + $(SLO)$/AccessibleFilterMenu.obj \
6410 + $(SLO)$/AccessibleFilterMenuItem.obj \
6411 + $(SLO)$/AccessibleFilterTopWindow.obj \
6412 $(SLO)$/AccessiblePreviewTable.obj \
6413 $(SLO)$/AccessiblePreviewCell.obj \
6414 $(SLO)$/AccessiblePreviewHeaderCell.obj \
6415 @@ -68,11 +72,15 @@ EXCEPTIONSFILES= \
6416 $(SLO)$/AccessibleContextBase.obj \
6417 $(SLO)$/AccessibleTableBase.obj \
6418 $(SLO)$/AccessibleDocument.obj \
6419 + $(SLO)$/AccessibleGlobal.obj \
6420 $(SLO)$/AccessibleSpreadsheet.obj \
6421 $(SLO)$/AccessibleCell.obj \
6422 $(SLO)$/AccessibleDocumentBase.obj \
6423 $(SLO)$/AccessibleCellBase.obj \
6424 $(SLO)$/AccessibleDocumentPagePreview.obj \
6425 + $(SLO)$/AccessibleFilterMenu.obj \
6426 + $(SLO)$/AccessibleFilterMenuItem.obj \
6427 + $(SLO)$/AccessibleFilterTopWindow.obj \
6428 $(SLO)$/AccessiblePreviewTable.obj \
6429 $(SLO)$/AccessiblePreviewCell.obj \
6430 $(SLO)$/AccessiblePreviewHeaderCell.obj \
6431 diff --git sc/source/ui/cctrl/dpcontrol.cxx sc/source/ui/cctrl/dpcontrol.cxx
6432 new file mode 100644
6433 index 0000000..2f09c88
6434 --- /dev/null
6435 +++ sc/source/ui/cctrl/dpcontrol.cxx
6436 @@ -0,0 +1,1419 @@
6437 +/*************************************************************************
6439 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6441 + * Copyright 2008 by Sun Microsystems, Inc.
6443 + * OpenOffice.org - a multi-platform office productivity suite
6445 + * $RCSfile: document.hxx,v $
6446 + * $Revision: 1.115.36.9 $
6448 + * This file is part of OpenOffice.org.
6450 + * OpenOffice.org is free software: you can redistribute it and/or modify
6451 + * it under the terms of the GNU Lesser General Public License version 3
6452 + * only, as published by the Free Software Foundation.
6454 + * OpenOffice.org is distributed in the hope that it will be useful,
6455 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6456 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6457 + * GNU Lesser General Public License version 3 for more details
6458 + * (a copy is included in the LICENSE file that accompanied this code).
6460 + * You should have received a copy of the GNU Lesser General Public License
6461 + * version 3 along with OpenOffice.org. If not, see
6462 + * <http://www.openoffice.org/license.html>
6463 + * for a copy of the LGPLv3 License.
6465 + ************************************************************************/
6467 +// MARKER(update_precomp.py): autogen include statement, do not remove
6468 +#include "precompiled_sc.hxx"
6470 +// INCLUDE ---------------------------------------------------------------
6472 +#include "dpcontrol.hxx"
6473 +#include "dpcontrol.hrc"
6475 +#include "vcl/outdev.hxx"
6476 +#include "vcl/settings.hxx"
6477 +#include "vcl/wintypes.hxx"
6478 +#include "vcl/decoview.hxx"
6479 +#include "strload.hxx"
6480 +#include "global.hxx"
6482 +#include "AccessibleFilterMenu.hxx"
6483 +#include "AccessibleFilterTopWindow.hxx"
6485 +#include <com/sun/star/accessibility/XAccessible.hpp>
6486 +#include <com/sun/star/accessibility/XAccessibleContext.hpp>
6488 +using ::com::sun::star::uno::Reference;
6489 +using ::com::sun::star::accessibility::XAccessible;
6490 +using ::com::sun::star::accessibility::XAccessibleContext;
6491 +using ::rtl::OUString;
6492 +using ::rtl::OUStringHash;
6493 +using ::std::vector;
6494 +using ::std::hash_map;
6495 +using ::std::auto_ptr;
6497 +ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY) :
6498 + mpOutDev(pOutDev),
6499 + mpStyle(pStyle),
6500 + mbBaseButton(true),
6501 + mbPopupButton(false),
6502 + mbHasHiddenMember(false),
6503 + mbPopupPressed(false)
6505 + if (pZoomX)
6506 + maZoomX = *pZoomX;
6507 + else
6508 + maZoomX = Fraction(1, 1);
6510 + if (pZoomY)
6511 + maZoomY = *pZoomY;
6512 + else
6513 + maZoomY = Fraction(1, 1);
6516 +ScDPFieldButton::~ScDPFieldButton()
6520 +void ScDPFieldButton::setText(const OUString& rText)
6522 + maText = rText;
6525 +void ScDPFieldButton::setBoundingBox(const Point& rPos, const Size& rSize)
6527 + maPos = rPos;
6528 + maSize = rSize;
6531 +void ScDPFieldButton::setDrawBaseButton(bool b)
6533 + mbBaseButton = b;
6536 +void ScDPFieldButton::setDrawPopupButton(bool b)
6538 + mbPopupButton = b;
6541 +void ScDPFieldButton::setHasHiddenMember(bool b)
6543 + mbHasHiddenMember = b;
6546 +void ScDPFieldButton::setPopupPressed(bool b)
6548 + mbPopupPressed = b;
6551 +void ScDPFieldButton::draw()
6553 + const long nMargin = 2;
6554 + bool bOldMapEnablaed = mpOutDev->IsMapModeEnabled();
6555 + mpOutDev->EnableMapMode(false);
6557 + if (mbBaseButton)
6559 + // Background
6560 + Rectangle aRect(maPos, maSize);
6561 + mpOutDev->SetLineColor(mpStyle->GetFaceColor());
6562 + mpOutDev->SetFillColor(mpStyle->GetFaceColor());
6563 + mpOutDev->DrawRect(aRect);
6565 + // Border lines
6566 + mpOutDev->SetLineColor(mpStyle->GetLightColor());
6567 + mpOutDev->DrawLine(Point(maPos), Point(maPos.X(), maPos.Y()+maSize.Height()-1));
6568 + mpOutDev->DrawLine(Point(maPos), Point(maPos.X()+maSize.Width()-1, maPos.Y()));
6570 + mpOutDev->SetLineColor(mpStyle->GetShadowColor());
6571 + mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1),
6572 + Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
6573 + mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()),
6574 + Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
6576 + // Field name.
6577 + Font aTextFont( mpStyle->GetLabelFont() );
6578 + double fFontHeight = 12.0;
6579 + fFontHeight *= static_cast<double>(maZoomY.GetNumerator()) / static_cast<double>(maZoomY.GetDenominator());
6580 + aTextFont.SetHeight(fFontHeight);
6581 + mpOutDev->SetFont(aTextFont);
6583 + Point aTextPos = maPos;
6584 + long nTHeight = static_cast<long>(fFontHeight);
6585 + aTextPos.setX(maPos.getX() + nMargin);
6586 + aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2);
6587 + mpOutDev->DrawText(aTextPos, maText);
6590 + if (mbPopupButton)
6591 + drawPopupButton();
6593 + mpOutDev->EnableMapMode(bOldMapEnablaed);
6596 +void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const
6598 + long nW = maSize.getWidth()*0.5;
6599 + long nH = maSize.getHeight();
6600 + if (nW > 18)
6601 + nW = 18;
6602 + if (nH > 18)
6603 + nH = 18;
6605 + rPos.setX(maPos.getX() + maSize.getWidth() - nW);
6606 + rPos.setY(maPos.getY() + maSize.getHeight() - nH);
6607 + rSize.setWidth(nW);
6608 + rSize.setHeight(nH);
6611 +bool ScDPFieldButton::isPopupButton() const
6613 + return mbPopupButton;
6616 +void ScDPFieldButton::drawPopupButton()
6618 + Point aPos;
6619 + Size aSize;
6620 + getPopupBoundingBox(aPos, aSize);
6622 + // Background & outer black border
6623 + mpOutDev->SetLineColor(COL_BLACK);
6624 + mpOutDev->SetFillColor(mpStyle->GetFaceColor());
6625 + mpOutDev->DrawRect(Rectangle(aPos, aSize));
6627 + if (!mbPopupPressed)
6628 + {
6629 + // border lines
6630 + mpOutDev->SetLineColor(mpStyle->GetLightColor());
6631 + mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+1, aPos.Y()+aSize.Height()-2));
6632 + mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+aSize.Width()-2, aPos.Y()+1));
6634 + mpOutDev->SetLineColor(mpStyle->GetShadowColor());
6635 + mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+aSize.Height()-2),
6636 + Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
6637 + mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-2, aPos.Y()+1),
6638 + Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
6641 + // the arrowhead
6642 + Color aArrowColor = mbHasHiddenMember ? mpStyle->GetHighlightLinkColor() : mpStyle->GetButtonTextColor();
6643 + mpOutDev->SetLineColor(aArrowColor);
6644 + mpOutDev->SetFillColor(aArrowColor);
6645 + Point aCenter(aPos.X() + (aSize.Width() >> 1), aPos.Y() + (aSize.Height() >> 1));
6646 + Point aPos1, aPos2;
6647 + aPos1.X() = aCenter.X() - 4;
6648 + aPos2.X() = aCenter.X() + 4;
6649 + aPos1.Y() = aCenter.Y() - 3;
6650 + aPos2.Y() = aCenter.Y() - 3;
6652 + if (mbPopupPressed)
6654 + aPos1.X() += 1;
6655 + aPos2.X() += 1;
6656 + aPos1.Y() += 1;
6657 + aPos2.Y() += 1;
6660 + do
6662 + ++aPos1.X();
6663 + --aPos2.X();
6664 + ++aPos1.Y();
6665 + ++aPos2.Y();
6666 + mpOutDev->DrawLine(aPos1, aPos2);
6668 + while (aPos1 != aPos2);
6670 + if (mbHasHiddenMember)
6672 + // tiny little box to display in presence of hidden member(s).
6673 + Point aBoxPos(aPos.X() + aSize.Width() - 5, aPos.Y() + aSize.Height() - 5);
6674 + if (mbPopupPressed)
6676 + aBoxPos.X() += 1;
6677 + aBoxPos.Y() += 1;
6679 + Size aBoxSize(3, 3);
6680 + mpOutDev->DrawRect(Rectangle(aBoxPos, aBoxSize));
6684 +// ============================================================================
6686 +ScMenuFloatingWindow::MenuItemData::MenuItemData() :
6687 + mbEnabled(true),
6688 + mpAction(static_cast<ScDPFieldPopupWindow::Action*>(NULL)),
6689 + mpSubMenuWin(static_cast<ScMenuFloatingWindow*>(NULL))
6693 +// ----------------------------------------------------------------------------
6695 +ScMenuFloatingWindow::SubMenuItemData::SubMenuItemData(ScMenuFloatingWindow* pParent) :
6696 + mpSubMenu(NULL),
6697 + mnMenuPos(MENU_NOT_SELECTED),
6698 + mpParent(pParent)
6700 + maTimer.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl) );
6701 + maTimer.SetTimeout(mpParent->GetSettings().GetMouseSettings().GetMenuDelay());
6704 +void ScMenuFloatingWindow::SubMenuItemData::reset()
6706 + mpSubMenu = NULL;
6707 + mnMenuPos = MENU_NOT_SELECTED;
6708 + maTimer.Stop();
6711 +IMPL_LINK( ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl, void*, EMPTYARG )
6713 + mpParent->handleMenuTimeout(this);
6714 + return 0;
6717 +// ----------------------------------------------------------------------------
6719 +size_t ScMenuFloatingWindow::MENU_NOT_SELECTED = 999;
6721 +ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel) :
6722 + PopupMenuFloatingWindow(pParent),
6723 + maOpenTimer(this),
6724 + maCloseTimer(this),
6725 + maName(OUString::createFromAscii("ScMenuFloatingWindow")),
6726 + mnSelectedMenu(MENU_NOT_SELECTED),
6727 + mnClickedMenu(MENU_NOT_SELECTED),
6728 + mpDoc(pDoc),
6729 + mpParentMenu(dynamic_cast<ScMenuFloatingWindow*>(pParent)),
6730 + mpActiveSubMenu(NULL)
6732 + SetMenuStackLevel(nMenuStackLevel);
6734 + // TODO: How do we get the right font to use here ?
6735 + const sal_uInt16 nPopupFontHeight = 12;
6736 + const StyleSettings& rStyle = GetSettings().GetStyleSettings();
6737 + maLabelFont = rStyle.GetLabelFont();
6738 + maLabelFont.SetHeight(nPopupFontHeight);
6739 + SetFont(maLabelFont);
6741 + SetText(OUString::createFromAscii("ScMenuFloatingWindow"));
6742 + SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, PopupEndHdl) );
6745 +ScMenuFloatingWindow::~ScMenuFloatingWindow()
6747 + EndPopupMode();
6750 +void ScMenuFloatingWindow::MouseMove(const MouseEvent& rMEvt)
6752 + const Point& rPos = rMEvt.GetPosPixel();
6753 + size_t nSelectedMenu = getEnclosingMenuItem(rPos);
6754 + setSelectedMenuItem(nSelectedMenu, true, false);
6756 + Window::MouseMove(rMEvt);
6759 +void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent& rMEvt)
6761 + const Point& rPos = rMEvt.GetPosPixel();
6762 + mnClickedMenu = getEnclosingMenuItem(rPos);
6763 + Window::MouseButtonDown(rMEvt);
6766 +void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent& rMEvt)
6768 + executeMenuItem(mnClickedMenu);
6769 + mnClickedMenu = MENU_NOT_SELECTED;
6770 + Window::MouseButtonUp(rMEvt);
6773 +void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt)
6775 + const KeyCode& rKeyCode = rKEvt.GetKeyCode();
6776 + bool bHandled = true;
6777 + size_t nSelectedMenu = mnSelectedMenu;
6778 + size_t nLastMenuPos = maMenuItems.size() - 1;
6779 + switch (rKeyCode.GetCode())
6781 + case KEY_UP:
6782 + if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == 0)
6783 + nSelectedMenu = nLastMenuPos;
6784 + else
6785 + --nSelectedMenu;
6786 + setSelectedMenuItem(nSelectedMenu, false, false);
6787 + break;
6788 + case KEY_DOWN:
6789 + if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == nLastMenuPos)
6790 + nSelectedMenu = 0;
6791 + else
6792 + ++nSelectedMenu;
6793 + setSelectedMenuItem(nSelectedMenu, false, false);
6794 + break;
6795 + case KEY_LEFT:
6796 + if (mpParentMenu)
6797 + mpParentMenu->endSubMenu(this);
6798 + break;
6799 + case KEY_RIGHT:
6801 + if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED)
6802 + break;
6804 + const MenuItemData& rMenu = maMenuItems[mnSelectedMenu];
6805 + if (!rMenu.mbEnabled || !rMenu.mpSubMenuWin)
6806 + break;
6808 + maOpenTimer.mnMenuPos = mnSelectedMenu;
6809 + maOpenTimer.mpSubMenu = rMenu.mpSubMenuWin.get();
6810 + launchSubMenu(true);
6812 + break;
6813 + case KEY_RETURN:
6814 + if (nSelectedMenu != MENU_NOT_SELECTED)
6815 + executeMenuItem(nSelectedMenu);
6816 + break;
6817 + default:
6818 + bHandled = false;
6821 + if (!bHandled)
6822 + Window::KeyInput(rKEvt);
6825 +void ScMenuFloatingWindow::Paint(const Rectangle& /*rRect*/)
6827 + const StyleSettings& rStyle = GetSettings().GetStyleSettings();
6828 + Color aBackColor = rStyle.GetMenuColor();
6829 + Color aBorderColor = rStyle.GetShadowColor();
6831 + Rectangle aCtrlRect(Point(0, 0), GetOutputSizePixel());
6833 + // Window background
6834 + bool bNativeDrawn = true;
6835 + if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
6837 + SetClipRegion();
6838 + bNativeDrawn = DrawNativeControl(
6839 + CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, Region(aCtrlRect), CTRL_STATE_ENABLED,
6840 + ImplControlValue(), OUString());
6842 + else
6843 + bNativeDrawn = false;
6845 + if (!bNativeDrawn)
6847 + SetFillColor(aBackColor);
6848 + SetLineColor(aBorderColor);
6849 + DrawRect(aCtrlRect);
6852 + // Menu items
6853 + SetTextColor(rStyle.GetMenuTextColor());
6854 + drawAllMenuItems();
6857 +Reference<XAccessible> ScMenuFloatingWindow::CreateAccessible()
6859 + if (!mxAccessible.is())
6860 + {
6861 + Reference<XAccessible> xAccParent = mpParentMenu ?
6862 + mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible();
6864 + mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, 999, getDoc()));
6865 + ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>(
6866 + mxAccessible.get());
6868 + vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
6869 + for (itr = itrBeg; itr != itrEnd; ++itr)
6871 + size_t nPos = ::std::distance(itrBeg, itr);
6872 + p->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
6876 + return mxAccessible;
6879 +void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction)
6881 + MenuItemData aItem;
6882 + aItem.maText = rText;
6883 + aItem.mbEnabled = bEnabled;
6884 + aItem.mpAction.reset(pAction);
6885 + maMenuItems.push_back(aItem);
6888 +ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText, bool bEnabled)
6890 + MenuItemData aItem;
6891 + aItem.maText = rText;
6892 + aItem.mbEnabled = bEnabled;
6893 + aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc, GetMenuStackLevel()+1));
6894 + aItem.mpSubMenuWin->setName(rText);
6895 + maMenuItems.push_back(aItem);
6896 + return aItem.mpSubMenuWin.get();
6899 +void ScMenuFloatingWindow::drawMenuItem(size_t nPos)
6901 + if (nPos >= maMenuItems.size())
6902 + return;
6904 + Point aPos;
6905 + Size aSize;
6906 + getMenuItemPosSize(nPos, aPos, aSize);
6908 + DecorationView aDecoView(this);
6909 + long nXOffset = 5;
6910 + long nYOffset = (aSize.Height() - maLabelFont.GetHeight())/2;
6911 + DrawCtrlText(Point(aPos.X()+nXOffset, aPos.Y() + nYOffset), maMenuItems[nPos].maText, 0, STRING_LEN,
6912 + maMenuItems[nPos].mbEnabled ? TEXT_DRAW_MNEMONIC : TEXT_DRAW_DISABLE);
6914 + if (maMenuItems[nPos].mpSubMenuWin)
6916 + long nFontHeight = maLabelFont.GetHeight();
6917 + Point aMarkerPos = aPos;
6918 + aMarkerPos.Y() += aSize.Height()/2 - nFontHeight/4 + 1;
6919 + aMarkerPos.X() += aSize.Width() - nFontHeight + nFontHeight/4;
6920 + Size aMarkerSize(nFontHeight/2, nFontHeight/2);
6921 + aDecoView.DrawSymbol(Rectangle(aMarkerPos, aMarkerSize),
6922 + SYMBOL_SPIN_RIGHT, GetTextColor(), 0);
6926 +void ScMenuFloatingWindow::drawAllMenuItems()
6928 + size_t n = maMenuItems.size();
6929 + for (size_t i = 0; i < n; ++i)
6930 + highlightMenuItem(i, i == mnSelectedMenu);
6933 +const Font& ScMenuFloatingWindow::getLabelFont() const
6935 + return maLabelFont;
6938 +void ScMenuFloatingWindow::executeMenuItem(size_t nPos)
6940 + if (nPos >= maMenuItems.size())
6941 + return;
6943 + if (!maMenuItems[nPos].mpAction)
6944 + // no action is defined.
6945 + return;
6947 + maMenuItems[nPos].mpAction->execute();
6948 + terminateAllPopupMenus();
6951 +void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu)
6953 + if (mnSelectedMenu == nPos)
6954 + // nothing to do.
6955 + return;
6957 + if (bEnsureSubMenu)
6959 + // Dismiss any child popup menu windows.
6960 + if (mnSelectedMenu < maMenuItems.size() &&
6961 + maMenuItems[mnSelectedMenu].mpSubMenuWin &&
6962 + maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
6963 + {
6964 + maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
6967 + // The popup is not visible, yet a menu item is selected. The request
6968 + // most likely comes from the accessible object. Make sure this
6969 + // window, as well as all its parent windows are visible.
6970 + if (!IsVisible() && mpParentMenu)
6971 + mpParentMenu->ensureSubMenuVisible(this);
6974 + selectMenuItem(mnSelectedMenu, false, bSubMenuTimer);
6975 + selectMenuItem(nPos, true, bSubMenuTimer);
6976 + mnSelectedMenu = nPos;
6978 + fireMenuHighlightedEvent();
6981 +size_t ScMenuFloatingWindow::getSelectedMenuItem() const
6983 + return mnSelectedMenu;
6986 +void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItemData* pTimer)
6988 + if (pTimer == &maOpenTimer)
6990 + // Close any open submenu immediately.
6991 + if (maCloseTimer.mpSubMenu)
6993 + maCloseTimer.mpSubMenu->EndPopupMode();
6994 + maCloseTimer.mpSubMenu = NULL;
6995 + maCloseTimer.maTimer.Stop();
6998 + launchSubMenu(false);
7000 + else if (pTimer == &maCloseTimer)
7002 + // end submenu.
7003 + if (maCloseTimer.mpSubMenu)
7005 + maOpenTimer.mpSubMenu = NULL;
7007 + maCloseTimer.mpSubMenu->EndPopupMode();
7008 + maCloseTimer.mpSubMenu = NULL;
7010 + highlightMenuItem(maOpenTimer.mnMenuPos, false);
7011 + maOpenTimer.mnMenuPos = MENU_NOT_SELECTED;
7016 +void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu)
7018 + if (!pMenu)
7019 + return;
7021 + // Set the submenu on launch queue.
7022 + if (maOpenTimer.mpSubMenu)
7024 + if (maOpenTimer.mpSubMenu == pMenu)
7026 + if (pMenu == maCloseTimer.mpSubMenu)
7027 + maCloseTimer.reset();
7028 + return;
7031 + // new submenu is being requested.
7032 + queueCloseSubMenu();
7035 + maOpenTimer.mpSubMenu = pMenu;
7036 + maOpenTimer.mnMenuPos = nPos;
7037 + maOpenTimer.maTimer.Start();
7040 +void ScMenuFloatingWindow::queueCloseSubMenu()
7042 + if (!maOpenTimer.mpSubMenu)
7043 + // There is no submenu to close.
7044 + return;
7046 + // Stop any submenu on queue for opening.
7047 + maOpenTimer.maTimer.Stop();
7049 + maCloseTimer.mpSubMenu = maOpenTimer.mpSubMenu;
7050 + maCloseTimer.mnMenuPos = maOpenTimer.mnMenuPos;
7051 + maCloseTimer.maTimer.Start();
7054 +void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos)
7056 + Point aPos;
7057 + Size aSize;
7058 + getMenuItemPosSize(maOpenTimer.mnMenuPos, aPos, aSize);
7059 + ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu;
7061 + if (!pSubMenu)
7062 + return;
7064 + sal_uInt32 nOldFlags = GetPopupModeFlags();
7065 + SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
7066 + pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
7067 + pSubMenu->StartPopupMode(
7068 + Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
7069 + pSubMenu->AddPopupModeWindow(this);
7070 + if (bSetMenuPos)
7071 + pSubMenu->setSelectedMenuItem(0, false, false); // select menu item after the popup becomes fully visible.
7072 + SetPopupModeFlags(nOldFlags);
7075 +void ScMenuFloatingWindow::endSubMenu(ScMenuFloatingWindow* pSubMenu)
7077 + if (!pSubMenu)
7078 + return;
7080 + pSubMenu->EndPopupMode();
7081 + maOpenTimer.reset();
7083 + size_t nMenuPos = getSubMenuPos(pSubMenu);
7084 + if (nMenuPos != MENU_NOT_SELECTED)
7085 + {
7086 + highlightMenuItem(nMenuPos, true);
7087 + mnSelectedMenu = nMenuPos;
7088 + fireMenuHighlightedEvent();
7092 +void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const
7094 + vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
7095 + for (itr = itrBeg; itr != itrEnd; ++itr)
7097 + size_t nPos = ::std::distance(itrBeg, itr);
7098 + pAccMenu->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
7102 +ScDocument* ScMenuFloatingWindow::getDoc()
7104 + return mpDoc;
7107 +void ScMenuFloatingWindow::resizeToFitMenuItems()
7109 + if (maMenuItems.empty())
7110 + return;
7112 + vector<MenuItemData>::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end();
7113 + long nTextWidth = 0;
7114 + for (; itr != itrEnd; ++itr)
7115 + nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth);
7117 + size_t nLastPos = maMenuItems.size()-1;
7118 + Point aPos;
7119 + Size aSize;
7120 + getMenuItemPosSize(nLastPos, aPos, aSize);
7121 + aPos.X() += nTextWidth + 15;
7122 + aPos.Y() += aSize.Height() + 5;
7123 + SetOutputSizePixel(Size(aPos.X(), aPos.Y()));
7126 +void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer)
7128 + if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED)
7130 + queueCloseSubMenu();
7131 + return;
7134 + if (!maMenuItems[nPos].mbEnabled)
7135 + {
7136 + queueCloseSubMenu();
7137 + return;
7140 + highlightMenuItem(nPos, bSelected);
7142 + if (bSelected)
7144 + if (mpParentMenu)
7145 + mpParentMenu->setSubMenuFocused(this);
7147 + if (bSubMenuTimer)
7149 + if (maMenuItems[nPos].mpSubMenuWin)
7151 + ScMenuFloatingWindow* pSubMenu = maMenuItems[nPos].mpSubMenuWin.get();
7152 + queueLaunchSubMenu(nPos, pSubMenu);
7154 + else
7155 + queueCloseSubMenu();
7160 +void ScMenuFloatingWindow::clearSelectedMenuItem()
7162 + selectMenuItem(mnSelectedMenu, false, false);
7163 + mnSelectedMenu = MENU_NOT_SELECTED;
7166 +ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const
7168 + if (maMenuItems.size() <= nPos)
7169 + return NULL;
7171 + return maMenuItems[nPos].mpSubMenuWin.get();
7174 +size_t ScMenuFloatingWindow::getMenuItemCount() const
7176 + return maMenuItems.size();
7179 +OUString ScMenuFloatingWindow::getMenuItemName(size_t nPos) const
7181 + if (maMenuItems.size() <= nPos)
7182 + return ScGlobal::GetEmptyString();
7184 + return maMenuItems[nPos].maText;
7187 +bool ScMenuFloatingWindow::isMenuItemEnabled(size_t nPos) const
7189 + if (maMenuItems.size() <= nPos)
7190 + return false;
7192 + return maMenuItems[nPos].mbEnabled;
7195 +bool ScMenuFloatingWindow::isMenuItemSelected(size_t nPos) const
7197 + return nPos == mnSelectedMenu;
7200 +void ScMenuFloatingWindow::setName(const OUString& rName)
7202 + maName = rName;
7205 +const OUString& ScMenuFloatingWindow::getName() const
7207 + return maName;
7210 +void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected)
7212 + if (nPos == MENU_NOT_SELECTED)
7213 + return;
7215 + const StyleSettings& rStyle = GetSettings().GetStyleSettings();
7216 + Color aBackColor = rStyle.GetMenuColor();
7217 + SetFillColor(aBackColor);
7218 + SetLineColor(aBackColor);
7220 + Point aPos;
7221 + Size aSize;
7222 + getMenuItemPosSize(nPos, aPos, aSize);
7223 + Region aRegion(Rectangle(aPos,aSize));
7225 + if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
7227 + Push(PUSH_CLIPREGION);
7228 + IntersectClipRegion(Rectangle(aPos, aSize));
7229 + Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel());
7230 + DrawNativeControl(
7231 + CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, Region(aCtrlRect), CTRL_STATE_ENABLED,
7232 + ImplControlValue(), OUString());
7234 + Pop();
7237 + bool bNativeDrawn = true;
7238 + if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM))
7240 + ControlState nState = bSelected ? CTRL_STATE_SELECTED : 0;
7241 + if (maMenuItems[nPos].mbEnabled)
7242 + nState |= CTRL_STATE_ENABLED;
7243 + bNativeDrawn = DrawNativeControl(
7244 + CTRL_MENU_POPUP, PART_MENU_ITEM, aRegion, nState, ImplControlValue(), OUString());
7246 + else
7247 + bNativeDrawn = false;
7249 + if (!bNativeDrawn)
7251 + if (bSelected)
7253 + aBackColor = rStyle.GetMenuHighlightColor();
7254 + SetFillColor(aBackColor);
7255 + SetLineColor(aBackColor);
7257 + DrawRect(Rectangle(aPos,aSize));
7260 + Color aTextColor = bSelected ? rStyle.GetMenuHighlightTextColor() : rStyle.GetMenuTextColor();
7261 + SetTextColor(aTextColor);
7262 + drawMenuItem(nPos);
7265 +void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const
7267 + const sal_uInt16 nLeftMargin = 5;
7268 + const sal_uInt16 nTopMargin = 5;
7269 + const sal_uInt16 nMenuItemHeight = maLabelFont.GetHeight()*1.8;
7271 + Size aWndSize = GetSizePixel();
7273 + Point aPos1(nLeftMargin, nTopMargin);
7274 + Size aSize1(aWndSize.Width() - nLeftMargin*2, nMenuItemHeight);
7276 + rPos = aPos1;
7277 + rPos.Y() += aSize1.Height()*nPos;
7278 + rSize = aSize1;
7281 +ScMenuFloatingWindow* ScMenuFloatingWindow::getParentMenuWindow() const
7283 + return mpParentMenu;
7286 +size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const
7288 + size_t n = maMenuItems.size();
7289 + for (size_t i = 0; i < n; ++i)
7291 + Point aPos;
7292 + Size aSize;
7293 + getMenuItemPosSize(i, aPos, aSize);
7294 + Rectangle aRect(aPos, aSize);
7295 + if (aRect.IsInside(rPos))
7296 + return i;
7298 + return MENU_NOT_SELECTED;
7301 +size_t ScMenuFloatingWindow::getSubMenuPos(ScMenuFloatingWindow* pSubMenu)
7303 + size_t n = maMenuItems.size();
7304 + for (size_t i = 0; i < n; ++i)
7306 + if (maMenuItems[i].mpSubMenuWin.get() == pSubMenu)
7307 + return i;
7309 + return MENU_NOT_SELECTED;
7312 +void ScMenuFloatingWindow::fireMenuHighlightedEvent()
7314 + if (mnSelectedMenu == MENU_NOT_SELECTED)
7315 + return;
7317 + if (!mxAccessible.is())
7318 + return;
7320 + Reference<XAccessibleContext> xAccCxt = mxAccessible->getAccessibleContext();
7321 + if (!xAccCxt.is())
7322 + return;
7324 + Reference<XAccessible> xAccMenu = xAccCxt->getAccessibleChild(mnSelectedMenu);
7325 + if (!xAccMenu.is())
7326 + return;
7328 + VclAccessibleEvent aEvent(VCLEVENT_MENU_HIGHLIGHT, xAccMenu);
7329 + FireVclEvent(&aEvent);
7332 +void ScMenuFloatingWindow::setSubMenuFocused(ScMenuFloatingWindow* pSubMenu)
7334 + maCloseTimer.reset();
7335 + size_t nMenuPos = getSubMenuPos(pSubMenu);
7336 + if (mnSelectedMenu != nMenuPos)
7338 + highlightMenuItem(nMenuPos, true);
7339 + mnSelectedMenu = nMenuPos;
7343 +void ScMenuFloatingWindow::ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu)
7345 + if (mpParentMenu)
7346 + mpParentMenu->ensureSubMenuVisible(this);
7348 + if (pSubMenu->IsVisible())
7349 + return;
7351 + // Find the menu position of the submenu.
7352 + size_t nMenuPos = getSubMenuPos(pSubMenu);
7353 + if (nMenuPos != MENU_NOT_SELECTED)
7355 + setSelectedMenuItem(nMenuPos, false, false);
7357 + Point aPos;
7358 + Size aSize;
7359 + getMenuItemPosSize(nMenuPos, aPos, aSize);
7361 + sal_uInt32 nOldFlags = GetPopupModeFlags();
7362 + SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
7363 + pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
7364 + pSubMenu->StartPopupMode(
7365 + Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
7366 + pSubMenu->AddPopupModeWindow(this);
7367 + SetPopupModeFlags(nOldFlags);
7371 +void ScMenuFloatingWindow::ensureSubMenuNotVisible()
7373 + if (mnSelectedMenu <= maMenuItems.size() &&
7374 + maMenuItems[mnSelectedMenu].mpSubMenuWin &&
7375 + maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
7376 + {
7377 + maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
7380 + EndPopupMode();
7383 +void ScMenuFloatingWindow::terminateAllPopupMenus()
7385 + EndPopupMode();
7386 + if (mpParentMenu)
7387 + mpParentMenu->terminateAllPopupMenus();
7390 +IMPL_LINK( ScMenuFloatingWindow, PopupEndHdl, void*, EMPTYARG )
7392 + clearSelectedMenuItem();
7393 + return 0;
7396 +// ============================================================================
7398 +ScDPFieldPopupWindow::Member::Member() :
7399 + mbVisible(true)
7403 +// ----------------------------------------------------------------------------
7405 +ScDPFieldPopupWindow::CancelButton::CancelButton(ScDPFieldPopupWindow* pParent) :
7406 + ::CancelButton(pParent), mpParent(pParent) {}
7408 +void ScDPFieldPopupWindow::CancelButton::Click()
7410 + mpParent->EndPopupMode();
7411 + ::CancelButton::Click();
7414 +// ----------------------------------------------------------------------------
7416 +ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc) :
7417 + ScMenuFloatingWindow(pParent, pDoc),
7418 + maChecks(this, 0),
7419 + maChkToggleAll(this, 0),
7420 + maBtnSelectSingle (this, 0),
7421 + maBtnUnselectSingle(this, 0),
7422 + maBtnOk(this),
7423 + maBtnCancel(this),
7424 + mnCurTabStop(0),
7425 + mpExtendedData(NULL),
7426 + mpOKAction(NULL),
7427 + maWndSize(160, 330),
7428 + mePrevToggleAllState(STATE_DONTKNOW)
7430 + maTabStopCtrls.reserve(7);
7431 + maTabStopCtrls.push_back(this);
7432 + maTabStopCtrls.push_back(&maChecks);
7433 + maTabStopCtrls.push_back(&maChkToggleAll);
7434 + maTabStopCtrls.push_back(&maBtnSelectSingle);
7435 + maTabStopCtrls.push_back(&maBtnUnselectSingle);
7436 + maTabStopCtrls.push_back(&maBtnOk);
7437 + maTabStopCtrls.push_back(&maBtnCancel);
7439 + const StyleSettings& rStyle = GetSettings().GetStyleSettings();
7441 + Point aPos;
7442 + Size aSize;
7443 + getSectionPosSize(aPos, aSize, WHOLE);
7444 + SetOutputSizePixel(aSize);
7445 + Size aOutSize = GetOutputSizePixel();
7447 + getSectionPosSize(aPos, aSize, BTN_OK);
7448 + maBtnOk.SetPosSizePixel(aPos, aSize);
7449 + maBtnOk.SetFont(getLabelFont());
7450 + maBtnOk.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
7451 + maBtnOk.Show();
7453 + getSectionPosSize(aPos, aSize, BTN_CANCEL);
7454 + maBtnCancel.SetPosSizePixel(aPos, aSize);
7455 + maBtnCancel.SetFont(getLabelFont());
7456 + maBtnCancel.Show();
7458 + getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER);
7459 + maChecks.SetPosSizePixel(aPos, aSize);
7460 + maChecks.SetFont(getLabelFont());
7461 + maChecks.SetCheckButtonHdl( LINK(this, ScDPFieldPopupWindow, CheckHdl) );
7462 + maChecks.Show();
7464 + getSectionPosSize(aPos, aSize, CHECK_TOGGLE_ALL);
7465 + maChkToggleAll.SetPosSizePixel(aPos, aSize);
7466 + maChkToggleAll.SetFont(getLabelFont());
7467 + maChkToggleAll.SetText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_TOGGLE_ALL).GetString());
7468 + maChkToggleAll.SetControlBackground(rStyle.GetMenuColor());
7469 + maChkToggleAll.SetClickHdl( LINK(this, ScDPFieldPopupWindow, TriStateHdl) );
7470 + maChkToggleAll.Show();
7472 + getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT);
7473 + maBtnSelectSingle.SetPosSizePixel(aPos, aSize);
7474 + maBtnSelectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_SELECT_CURRENT).GetString());
7475 + maBtnSelectSingle.SetModeImage(Image(ScResId(RID_IMG_SELECT_CURRENT)), BMP_COLOR_NORMAL);
7476 + maBtnSelectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
7477 + maBtnSelectSingle.Show();
7479 + getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT);
7480 + maBtnUnselectSingle.SetPosSizePixel(aPos, aSize);
7481 + maBtnUnselectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_UNSELECT_CURRENT).GetString());
7482 + maBtnUnselectSingle.SetModeImage(Image(ScResId(RID_IMG_UNSELECT_CURRENT)), BMP_COLOR_NORMAL);
7483 + maBtnUnselectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
7484 + maBtnUnselectSingle.Show();
7487 +ScDPFieldPopupWindow::~ScDPFieldPopupWindow()
7491 +void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const
7493 + // constant parameters.
7494 + const sal_uInt16 nListBoxMargin = 5; // horizontal distance from the side of the dialog to the listbox border.
7495 + const sal_uInt16 nListBoxInnerPadding = 5;
7496 + const sal_uInt16 nTopMargin = 5;
7497 + const sal_uInt16 nMenuHeight = 60;
7498 + const sal_uInt16 nSingleItemBtnAreaHeight = 32; // height of the middle area below the list box where the single-action buttons are.
7499 + const sal_uInt16 nBottomBtnAreaHeight = 50; // height of the bottom area where the OK and Cancel buttons are.
7500 + const sal_uInt16 nBtnWidth = 60;
7501 + const sal_uInt16 nLabelHeight = getLabelFont().GetHeight();
7502 + const sal_uInt16 nBtnHeight = nLabelHeight*2;
7503 + const sal_uInt16 nBottomMargin = 10;
7504 + const sal_uInt16 nMenuListMargin = 20;
7506 + // parameters calculated from constants.
7507 + const sal_uInt16 nListBoxWidth = maWndSize.Width() - nListBoxMargin*2;
7508 + const sal_uInt16 nListBoxHeight = maWndSize.Height() - nTopMargin - nMenuHeight -
7509 + nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight;
7511 + const sal_uInt16 nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1;
7513 + switch (eType)
7515 + case WHOLE:
7517 + rPos = Point(0, 0);
7518 + rSize = maWndSize;
7520 + break;
7521 + case LISTBOX_AREA_OUTER:
7523 + rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
7524 + rSize = Size(nListBoxWidth, nListBoxHeight);
7526 + break;
7527 + case LISTBOX_AREA_INNER:
7529 + rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
7530 + rPos.X() += nListBoxInnerPadding;
7531 + rPos.Y() += nListBoxInnerPadding;
7533 + rSize = Size(nListBoxWidth, nListBoxHeight);
7534 + rSize.Width() -= nListBoxInnerPadding*2;
7535 + rSize.Height() -= nListBoxInnerPadding*2;
7537 + break;
7538 + case SINGLE_BTN_AREA:
7540 + rPos = Point(nListBoxMargin, nSingleBtnAreaY);
7541 + rSize = Size(nListBoxWidth, nSingleItemBtnAreaHeight);
7543 + break;
7544 + case CHECK_TOGGLE_ALL:
7546 + long h = nLabelHeight*3/2; // check box height is heuristically 150% of the text height.
7547 + rPos = Point(nListBoxMargin, nSingleBtnAreaY);
7548 + rPos.X() += 5;
7549 + rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
7550 + rSize = Size(70, h);
7552 + break;
7553 + case BTN_SINGLE_SELECT:
7555 + long h = 26;
7556 + rPos = Point(nListBoxMargin, nSingleBtnAreaY);
7557 + rPos.X() += 75;
7558 + rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
7559 + rSize = Size(h, h);
7561 + break;
7562 + case BTN_SINGLE_UNSELECT:
7564 + long h = 26;
7565 + rPos = Point(nListBoxMargin, nSingleBtnAreaY);
7566 + rPos.X() += 75 + h + 10;
7567 + rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
7568 + rSize = Size(h, h);
7570 + break;
7571 + case BTN_OK:
7573 + long x = (maWndSize.Width() - nBtnWidth*2)/3;
7574 + long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
7575 + rPos = Point(x, y);
7576 + rSize = Size(nBtnWidth, nBtnHeight);
7578 + break;
7579 + case BTN_CANCEL:
7581 + long x = (maWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth;
7582 + long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
7583 + rPos = Point(x, y);
7584 + rSize = Size(nBtnWidth, nBtnHeight);
7586 + break;
7587 + default:
7592 +void ScDPFieldPopupWindow::setAllMemberState(bool bSet)
7594 + size_t n = maMembers.size();
7595 + for (size_t i = 0; i < n; ++i)
7596 + maChecks.CheckEntryPos(i, bSet);
7599 +void ScDPFieldPopupWindow::selectCurrentMemberOnly(bool bSet)
7601 + setAllMemberState(!bSet);
7602 + sal_uInt16 nSelected = maChecks.GetSelectEntryPos();
7603 + maChecks.CheckEntryPos(nSelected, bSet);
7606 +void ScDPFieldPopupWindow::cycleFocus(bool bReverse)
7608 + maTabStopCtrls[mnCurTabStop]->SetFakeFocus(false);
7609 + maTabStopCtrls[mnCurTabStop]->LoseFocus();
7610 + if (mnCurTabStop == 0)
7611 + clearSelectedMenuItem();
7613 + if (bReverse)
7615 + if (mnCurTabStop > 0)
7616 + --mnCurTabStop;
7617 + else
7618 + mnCurTabStop = maTabStopCtrls.size() - 1;
7620 + else
7622 + ++mnCurTabStop;
7623 + if (mnCurTabStop >= maTabStopCtrls.size())
7624 + mnCurTabStop = 0;
7626 + maTabStopCtrls[mnCurTabStop]->SetFakeFocus(true);
7627 + maTabStopCtrls[mnCurTabStop]->GrabFocus();
7630 +IMPL_LINK( ScDPFieldPopupWindow, ButtonHdl, Button*, pBtn )
7632 + if (pBtn == &maBtnOk)
7633 + close(true);
7634 + else if (pBtn == &maBtnSelectSingle)
7635 + {
7636 + selectCurrentMemberOnly(true);
7637 + CheckHdl(&maChecks);
7639 + else if (pBtn == &maBtnUnselectSingle)
7640 + {
7641 + selectCurrentMemberOnly(false);
7642 + CheckHdl(&maChecks);
7644 + return 0;
7647 +IMPL_LINK( ScDPFieldPopupWindow, TriStateHdl, TriStateBox*, EMPTYARG )
7649 + switch (mePrevToggleAllState)
7651 + case STATE_NOCHECK:
7652 + maChkToggleAll.SetState(STATE_CHECK);
7653 + setAllMemberState(true);
7654 + break;
7655 + case STATE_CHECK:
7656 + maChkToggleAll.SetState(STATE_NOCHECK);
7657 + setAllMemberState(false);
7658 + break;
7659 + case STATE_DONTKNOW:
7660 + default:
7661 + maChkToggleAll.SetState(STATE_CHECK);
7662 + setAllMemberState(true);
7663 + break;
7666 + mePrevToggleAllState = maChkToggleAll.GetState();
7667 + return 0;
7670 +IMPL_LINK( ScDPFieldPopupWindow, CheckHdl, SvTreeListBox*, pChecks )
7672 + if (pChecks != &maChecks)
7673 + return 0;
7675 + size_t nNumChecked = maChecks.GetCheckedEntryCount();
7676 + if (nNumChecked == maMembers.size())
7677 + // all members visible
7678 + maChkToggleAll.SetState(STATE_CHECK);
7679 + else if (nNumChecked == 0)
7680 + // no members visible
7681 + maChkToggleAll.SetState(STATE_NOCHECK);
7682 + else
7683 + maChkToggleAll.SetState(STATE_DONTKNOW);
7685 + mePrevToggleAllState = maChkToggleAll.GetState();
7686 + return 0;
7689 +void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt)
7691 + ScMenuFloatingWindow::MouseMove(rMEvt);
7693 + size_t nSelectedMenu = getSelectedMenuItem();
7694 + if (nSelectedMenu == MENU_NOT_SELECTED)
7695 + queueCloseSubMenu();
7698 +long ScDPFieldPopupWindow::Notify(NotifyEvent& rNEvt)
7700 + switch (rNEvt.GetType())
7702 + case EVENT_KEYUP:
7704 + const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
7705 + const KeyCode& rCode = pKeyEvent->GetKeyCode();
7706 + bool bShift = rCode.IsShift();
7707 + if (rCode.GetCode() == KEY_TAB)
7709 + cycleFocus(bShift);
7710 + return true;
7713 + break;
7715 + return ScMenuFloatingWindow::Notify(rNEvt);
7718 +void ScDPFieldPopupWindow::Paint(const Rectangle& rRect)
7720 + ScMenuFloatingWindow::Paint(rRect);
7722 + const StyleSettings& rStyle = GetSettings().GetStyleSettings();
7723 + Color aMemberBackColor = rStyle.GetFieldColor();
7724 + Color aBorderColor = rStyle.GetShadowColor();
7726 + Point aPos;
7727 + Size aSize;
7728 + getSectionPosSize(aPos, aSize, LISTBOX_AREA_OUTER);
7730 + // Member list box background
7731 + SetFillColor(aMemberBackColor);
7732 + SetLineColor(aBorderColor);
7733 + DrawRect(Rectangle(aPos,aSize));
7735 + // Single-action button box
7736 + getSectionPosSize(aPos, aSize, SINGLE_BTN_AREA);
7737 + SetFillColor(rStyle.GetMenuColor());
7738 + DrawRect(Rectangle(aPos,aSize));
7741 +Window* ScDPFieldPopupWindow::GetPreferredKeyInputWindow()
7743 + return maTabStopCtrls[mnCurTabStop];
7746 +Reference<XAccessible> ScDPFieldPopupWindow::CreateAccessible()
7748 + if (!mxAccessible.is())
7749 + {
7750 + mxAccessible.set(new ScAccessibleFilterTopWindow(
7751 + GetAccessibleParentWindow()->GetAccessible(), this, getName(), getDoc()));
7752 + ScAccessibleFilterTopWindow* pAccTop = static_cast<ScAccessibleFilterTopWindow*>(mxAccessible.get());
7753 + fillMenuItemsToAccessible(pAccTop);
7755 + pAccTop->setAccessibleChild(
7756 + maChecks.CreateAccessible(), ScAccessibleFilterTopWindow::LISTBOX);
7757 + pAccTop->setAccessibleChild(
7758 + maChkToggleAll.CreateAccessible(), ScAccessibleFilterTopWindow::TOGGLE_ALL);
7759 + pAccTop->setAccessibleChild(
7760 + maBtnSelectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_ON_BTN);
7761 + pAccTop->setAccessibleChild(
7762 + maBtnUnselectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_OFF_BTN);
7763 + pAccTop->setAccessibleChild(
7764 + maBtnOk.CreateAccessible(), ScAccessibleFilterTopWindow::OK_BTN);
7765 + pAccTop->setAccessibleChild(
7766 + maBtnCancel.CreateAccessible(), ScAccessibleFilterTopWindow::CANCEL_BTN);
7769 + return mxAccessible;
7772 +void ScDPFieldPopupWindow::setMemberSize(size_t n)
7774 + maMembers.reserve(n);
7777 +void ScDPFieldPopupWindow::addMember(const OUString& rName, bool bVisible)
7779 + Member aMember;
7780 + aMember.maName = rName;
7781 + aMember.mbVisible = bVisible;
7782 + maMembers.push_back(aMember);
7785 +void ScDPFieldPopupWindow::initMembers()
7787 + size_t n = maMembers.size();
7788 + size_t nVisMemCount = 0;
7789 + for (size_t i = 0; i < n; ++i)
7791 + maChecks.InsertEntry(maMembers[i].maName);
7792 + maChecks.CheckEntryPos(i, maMembers[i].mbVisible);
7793 + if (maMembers[i].mbVisible)
7794 + ++nVisMemCount;
7796 + if (nVisMemCount == n)
7797 + {
7798 + // all members visible
7799 + maChkToggleAll.SetState(STATE_CHECK);
7800 + mePrevToggleAllState = STATE_CHECK;
7802 + else if (nVisMemCount == 0)
7803 + {
7804 + // no members visible
7805 + maChkToggleAll.SetState(STATE_NOCHECK);
7806 + mePrevToggleAllState = STATE_NOCHECK;
7808 + else
7809 + {
7810 + maChkToggleAll.SetState(STATE_DONTKNOW);
7811 + mePrevToggleAllState = STATE_DONTKNOW;
7815 +const Size& ScDPFieldPopupWindow::getWindowSize() const
7817 + return maWndSize;
7820 +void ScDPFieldPopupWindow::getResult(hash_map<OUString, bool, OUStringHash>& rResult)
7822 + typedef hash_map<OUString, bool, OUStringHash> ResultMap;
7823 + ResultMap aResult;
7824 + size_t n = maMembers.size();
7825 + for (size_t i = 0; i < n; ++i)
7827 + bool bState = maChecks.IsChecked(i);
7828 + aResult.insert(ResultMap::value_type(maMembers[i].maName, bState));
7830 + rResult.swap(aResult);
7833 +void ScDPFieldPopupWindow::close(bool bOK)
7835 + if (bOK && mpOKAction.get())
7836 + mpOKAction->execute();
7838 + EndPopupMode();
7841 +void ScDPFieldPopupWindow::setExtendedData(ExtendedData* p)
7843 + mpExtendedData.reset(p);
7846 +ScDPFieldPopupWindow::ExtendedData* ScDPFieldPopupWindow::getExtendedData()
7848 + return mpExtendedData.get();
7851 +void ScDPFieldPopupWindow::setOKAction(Action* p)
7853 + mpOKAction.reset(p);
7856 diff --git sc/source/ui/cctrl/dpcontrol.src sc/source/ui/cctrl/dpcontrol.src
7857 new file mode 100644
7858 index 0000000..31cbb62
7859 --- /dev/null
7860 +++ sc/source/ui/cctrl/dpcontrol.src
7861 @@ -0,0 +1,82 @@
7862 +/*************************************************************************
7864 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7866 + * Copyright 2008 by Sun Microsystems, Inc.
7868 + * OpenOffice.org - a multi-platform office productivity suite
7870 + * $RCSfile: globstr.src,v $
7871 + * $Revision: 1.74.96.1 $
7873 + * This file is part of OpenOffice.org.
7875 + * OpenOffice.org is free software: you can redistribute it and/or modify
7876 + * it under the terms of the GNU Lesser General Public License version 3
7877 + * only, as published by the Free Software Foundation.
7879 + * OpenOffice.org is distributed in the hope that it will be useful,
7880 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7881 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7882 + * GNU Lesser General Public License version 3 for more details
7883 + * (a copy is included in the LICENSE file that accompanied this code).
7885 + * You should have received a copy of the GNU Lesser General Public License
7886 + * version 3 along with OpenOffice.org. If not, see
7887 + * <http://www.openoffice.org/license.html>
7888 + * for a copy of the LGPLv3 License.
7890 + ************************************************************************/
7892 +#include "dpcontrol.hrc"
7894 +Resource RID_POPUP_FILTER
7896 + String STR_MENU_SORT_ASC
7898 + Text [ en-US ] = "Sort Ascending" ;
7899 + };
7901 + String STR_MENU_SORT_DESC
7903 + Text [ en-US ] = "Sort Descending" ;
7904 + };
7906 + String STR_MENU_SORT_CUSTOM
7908 + Text [ en-US ] = "Custom Sort" ;
7909 + };
7911 + String STR_BTN_TOGGLE_ALL
7913 + Text [ en-US ] = "All" ;
7914 + };
7916 + String STR_BTN_SELECT_CURRENT
7918 + Text [ en-US ] = "Show only the current item." ;
7919 + };
7921 + String STR_BTN_UNSELECT_CURRENT
7923 + Text [ en-US ] = "Hide only the current item." ;
7924 + };
7927 +Image RID_IMG_SELECT_CURRENT
7929 + ImageBitmap = Bitmap
7931 + File = "popup_select_current.png";
7932 + };
7933 + MaskColor = STD_MASKCOLOR;
7936 +Image RID_IMG_UNSELECT_CURRENT
7938 + ImageBitmap = Bitmap
7940 + File = "popup_unselect_current.png";
7941 + };
7942 + MaskColor = STD_MASKCOLOR;
7944 diff --git sc/source/ui/cctrl/makefile.mk sc/source/ui/cctrl/makefile.mk
7945 index e7b96af..43ff4bd 100644
7946 --- sc/source/ui/cctrl/makefile.mk
7947 +++ sc/source/ui/cctrl/makefile.mk
7948 @@ -45,22 +45,30 @@ LIBTARGET=NO
7949 # --- Files --------------------------------------------------------
7951 EXCEPTIONSFILES= \
7952 - $(SLO)$/tbzoomsliderctrl.obj
7953 + $(SLO)$/tbzoomsliderctrl.obj \
7954 + $(SLO)$/dpcontrol.obj
7956 SLOFILES = \
7957 $(SLO)$/popmenu.obj \
7958 $(SLO)$/tbinsert.obj \
7959 $(SLO)$/cbuttonw.obj \
7960 + $(SLO)$/dpcontrol.obj \
7961 $(SLO)$/editfield.obj \
7962 $(EXCEPTIONSFILES)
7964 +SRS1NAME=$(TARGET)
7965 +SRC1FILES = \
7966 + dpcontrol.src
7968 LIB1TARGET=$(SLB)$/$(TARGET).lib
7969 LIB1OBJFILES= \
7970 $(SLO)$/popmenu.obj \
7971 $(SLO)$/tbinsert.obj \
7972 $(SLO)$/cbuttonw.obj \
7973 + $(SLO)$/dpcontrol.obj \
7974 $(SLO)$/tbzoomsliderctrl.obj
7977 # --- Tagets -------------------------------------------------------
7979 .INCLUDE : target.mk
7980 diff --git sc/source/ui/dbgui/pvfundlg.cxx sc/source/ui/dbgui/pvfundlg.cxx
7981 index 08a5e03..ec140d8 100644
7982 --- sc/source/ui/dbgui/pvfundlg.cxx
7983 +++ sc/source/ui/dbgui/pvfundlg.cxx
7984 @@ -48,12 +48,15 @@
7985 #include "pvfundlg.hrc"
7986 #include "globstr.hrc"
7988 +#include <vector>
7990 // ============================================================================
7992 using namespace ::com::sun::star::sheet;
7994 using ::rtl::OUString;
7995 using ::com::sun::star::uno::Sequence;
7996 +using ::std::vector;
7998 // ============================================================================
8000 @@ -86,6 +89,25 @@ bool lclFillListBox( ListBoxType& rLBox, const Sequence< OUString >& rStrings, U
8001 return bEmpty;
8004 +template< typename ListBoxType >
8005 +bool lclFillListBox( ListBoxType& rLBox, const vector<ScDPLabelData::Member>& rMembers, USHORT nEmptyPos = LISTBOX_APPEND )
8007 + bool bEmpty = false;
8008 + vector<ScDPLabelData::Member>::const_iterator itr = rMembers.begin(), itrEnd = rMembers.end();
8009 + for (; itr != itrEnd; ++itr)
8011 + OUString aName = itr->getDisplayName();
8012 + if (aName.getLength())
8013 + rLBox.InsertEntry(aName);
8014 + else
8016 + rLBox.InsertEntry(ScGlobal::GetRscString(STR_EMPTYDATA), nEmptyPos);
8017 + bEmpty = true;
8020 + return bEmpty;
8023 /** Searches for a listbox entry, starts search at specified position. */
8024 USHORT lclFindListBoxEntry( const ListBox& rLBox, const String& rEntry, USHORT nStartPos )
8026 @@ -253,7 +275,7 @@ void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData&
8027 maLbFunc.SetSelection( nFuncMask );
8029 // field name
8030 - maFtName.SetText( rLabelData.maName );
8031 + maFtName.SetText(rLabelData.getDisplayName());
8033 // "More button" controls
8034 maBtnMore.AddWindow( &maFlDisplay );
8035 @@ -271,7 +293,7 @@ void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData&
8037 // base field list box
8038 for( ScDPLabelDataVec::const_iterator aIt = mrLabelVec.begin(), aEnd = mrLabelVec.end(); aIt != aEnd; ++aIt )
8039 - maLbBaseField.InsertEntry( aIt->maName );
8040 + maLbBaseField.InsertEntry(aIt->getDisplayName());
8042 // base item list box
8043 maLbBaseItem.SetSeparatorPos( SC_BASEITEM_USER_POS - 1 );
8044 @@ -414,8 +436,6 @@ void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const
8045 rLabelData.mnUsedHier = maLabelData.mnUsedHier;
8046 rLabelData.mbShowAll = maCbShowAll.IsChecked();
8047 rLabelData.maMembers = maLabelData.maMembers;
8048 - rLabelData.maVisible = maLabelData.maVisible;
8049 - rLabelData.maShowDet = maLabelData.maShowDet;
8050 rLabelData.maSortInfo = maLabelData.maSortInfo;
8051 rLabelData.maLayoutInfo = maLabelData.maLayoutInfo;
8052 rLabelData.maShowInfo = maLabelData.maShowInfo;
8053 @@ -424,7 +444,7 @@ void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const
8054 void ScDPSubtotalDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData )
8056 // field name
8057 - maFtName.SetText( rLabelData.maName );
8058 + maFtName.SetText(rLabelData.getDisplayName());
8060 // radio buttons
8061 maRbNone.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
8062 @@ -547,9 +567,8 @@ void ScDPSubtotalOptDlg::FillLabelData( ScDPLabelData& rLabelData ) const
8064 rLabelData.maMembers = maLabelData.maMembers;
8065 ULONG nVisCount = maLbHide.GetEntryCount();
8066 - rLabelData.maVisible.realloc( nVisCount );
8067 for( USHORT nPos = 0; nPos < nVisCount; ++nPos )
8068 - rLabelData.maVisible[ nPos ] = !maLbHide.IsChecked( nPos );
8069 + rLabelData.maMembers[nPos].mbVisible = !maLbHide.IsChecked(nPos);
8071 // *** HIERARCHY ***
8073 @@ -563,7 +582,8 @@ void ScDPSubtotalOptDlg::Init( const ScDPNameVec& rDataFields, bool bEnableLayou
8074 sal_Int32 nSortMode = maLabelData.maSortInfo.Mode;
8076 // sort fields list box
8077 - maLbSortBy.InsertEntry( maLabelData.maName );
8078 + maLbSortBy.InsertEntry(maLabelData.getDisplayName());
8080 for( ScDPNameVec::const_iterator aIt = rDataFields.begin(), aEnd = rDataFields.end(); aIt != aEnd; ++aIt )
8082 maLbSortBy.InsertEntry( *aIt );
8083 @@ -656,8 +676,9 @@ void ScDPSubtotalOptDlg::InitHideListBox()
8085 maLbHide.Clear();
8086 lclFillListBox( maLbHide, maLabelData.maMembers );
8087 - for( sal_Int32 nVisIdx = 0, nVisSize = maLabelData.maVisible.getLength(); nVisIdx < nVisSize; ++nVisIdx )
8088 - maLbHide.CheckEntryPos( static_cast< USHORT >( nVisIdx ), !maLabelData.maVisible[ nVisIdx ] );
8089 + size_t n = maLabelData.maMembers.size();
8090 + for (size_t i = 0; i < n; ++i)
8091 + maLbHide.CheckEntryPos(static_cast<USHORT>(i), !maLabelData.maMembers[i].mbVisible);
8092 bool bEnable = maLbHide.GetEntryCount() > 0;
8093 maFlHide.Enable( bEnable );
8094 maLbHide.Enable( bEnable );
8095 @@ -690,8 +711,7 @@ IMPL_LINK( ScDPSubtotalOptDlg, SelectHdl, ListBox*, pLBox )
8097 if( pLBox == &maLbHierarchy )
8099 - mrDPObj.GetMembers( maLabelData.mnCol, maLbHierarchy.GetSelectEntryPos(),
8100 - maLabelData.maMembers, &maLabelData.maVisible, &maLabelData.maShowDet );
8101 + mrDPObj.GetMembers(maLabelData.mnCol, maLbHierarchy.GetSelectEntryPos(), maLabelData.maMembers);
8102 InitHideListBox();
8104 return 0;
8105 @@ -705,7 +725,9 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHOR
8106 maLbDims ( this, ScResId( LB_DIMS ) ),
8107 maBtnOk ( this, ScResId( BTN_OK ) ),
8108 maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
8109 - maBtnHelp ( this, ScResId( BTN_HELP ) )
8110 + maBtnHelp ( this, ScResId( BTN_HELP ) ),
8112 + mrDPObj(rDPObj)
8114 FreeResource();
8116 @@ -719,7 +741,13 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHOR
8118 const ScDPSaveDimension* pDimension = pSaveData ? pSaveData->GetExistingDimensionByName(aName) : 0;
8119 if ( !pDimension || (pDimension->GetOrientation() != nOrient) )
8121 + const OUString* pLayoutName = pDimension->GetLayoutName();
8122 + if (pLayoutName)
8123 + aName = *pLayoutName;
8124 maLbDims.InsertEntry( aName );
8125 + maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim));
8129 if( maLbDims.GetEntryCount() )
8130 @@ -735,7 +763,17 @@ short ScDPShowDetailDlg::Execute()
8132 String ScDPShowDetailDlg::GetDimensionName() const
8134 - return maLbDims.GetSelectEntry();
8135 + // Look up the internal dimension name which may be different from the
8136 + // displayed field name.
8137 + String aSelectedName = maLbDims.GetSelectEntry();
8138 + DimNameIndexMap::const_iterator itr = maNameIndexMap.find(aSelectedName);
8139 + if (itr == maNameIndexMap.end())
8140 + // This should never happen!
8141 + return aSelectedName;
8143 + long nDim = itr->second;
8144 + BOOL bIsDataLayout = false;
8145 + return mrDPObj.GetDimName(nDim, bIsDataLayout);
8148 IMPL_LINK( ScDPShowDetailDlg, DblClickHdl, ListBox*, pLBox )
8149 diff --git sc/source/ui/dbgui/pvlaydlg.cxx sc/source/ui/dbgui/pvlaydlg.cxx
8150 index 21b2706..7392386 100644
8151 --- sc/source/ui/dbgui/pvlaydlg.cxx
8152 +++ sc/source/ui/dbgui/pvlaydlg.cxx
8153 @@ -63,6 +63,8 @@
8154 #include "sc.hrc" //CHINA001
8155 #include "scabstdlg.hxx" //CHINA001
8156 using namespace com::sun::star;
8157 +using ::rtl::OUString;
8158 +using ::std::vector;
8160 //----------------------------------------------------------------------------
8162 @@ -378,24 +380,23 @@ void ScDPLayoutDlg::StateChanged( StateChangedType nStateChange )
8164 //----------------------------------------------------------------------------
8166 -void ScDPLayoutDlg::InitWndSelect( LabelData** ppLabelArr, long nLabels )
8167 +void ScDPLayoutDlg::InitWndSelect( const vector<ScDPLabelDataRef>& rLabels )
8169 - if ( ppLabelArr )
8170 + size_t nLabelCount = rLabels.size();
8171 + if (nLabelCount > MAX_LABELS)
8172 + nLabelCount = MAX_LABELS;
8173 + size_t nLast = (nLabelCount > PAGE_SIZE) ? (PAGE_SIZE - 1) : (nLabelCount - 1);
8175 + aLabelDataArr.clear();
8176 + aLabelDataArr.reserve( nLabelCount );
8177 + for ( size_t i=0; i < nLabelCount; i++ )
8179 - size_t nLabelCount = static_cast< size_t >( (nLabels > MAX_LABELS) ? MAX_LABELS : nLabels );
8180 - size_t nLast = (nLabelCount > PAGE_SIZE) ? (PAGE_SIZE - 1) : (nLabelCount - 1);
8181 + aLabelDataArr.push_back(*rLabels[i]);
8183 - aLabelDataArr.clear();
8184 - aLabelDataArr.reserve( nLabelCount );
8185 - for ( size_t i=0; i < nLabelCount; i++ )
8186 + if ( i <= nLast )
8188 - aLabelDataArr.push_back( *ppLabelArr[i] );
8190 - if ( i <= nLast )
8192 - aWndSelect.AddField( aLabelDataArr[i].maName, i );
8193 - aSelectArr[i].reset( new ScDPFuncData( aLabelDataArr[i].mnCol, aLabelDataArr[i].mnFuncMask ) );
8195 + aWndSelect.AddField(aLabelDataArr[i].getDisplayName(), i);
8196 + aSelectArr[i].reset( new ScDPFuncData( aLabelDataArr[i].mnCol, aLabelDataArr[i].mnFuncMask ) );
8200 @@ -493,18 +494,19 @@ void ScDPLayoutDlg::InitFocus()
8202 void ScDPLayoutDlg::InitFields()
8204 - InitWndSelect( thePivotData.ppLabelArr, static_cast<long>(thePivotData.nLabels) );
8205 + InitWndSelect(thePivotData.maLabelArray);
8206 InitWnd( thePivotData.aPageArr, static_cast<long>(thePivotData.nPageCount), TYPE_PAGE );
8207 InitWnd( thePivotData.aColArr, static_cast<long>(thePivotData.nColCount), TYPE_COL );
8208 InitWnd( thePivotData.aRowArr, static_cast<long>(thePivotData.nRowCount), TYPE_ROW );
8209 InitWnd( thePivotData.aDataArr, static_cast<long>(thePivotData.nDataCount), TYPE_DATA );
8211 + size_t nLabels = thePivotData.maLabelArray.size();
8212 aSlider.SetPageSize( PAGE_SIZE );
8213 aSlider.SetVisibleSize( PAGE_SIZE );
8214 aSlider.SetLineSize( LINE_SIZE );
8215 - aSlider.SetRange( Range( 0, static_cast<long>(((thePivotData.nLabels+LINE_SIZE-1)/LINE_SIZE)*LINE_SIZE) ) );
8216 + aSlider.SetRange( Range( 0, static_cast<long>(((nLabels+LINE_SIZE-1)/LINE_SIZE)*LINE_SIZE) ) );
8218 - if ( thePivotData.nLabels > PAGE_SIZE )
8219 + if ( nLabels > PAGE_SIZE )
8221 aSlider.SetEndScrollHdl( LINK( this, ScDPLayoutDlg, ScrollHdl ) );
8222 aSlider.Show();
8223 @@ -594,7 +596,7 @@ void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Po
8225 if ( !bDataArr )
8227 - if ( toWnd->AddField( rData.maName,
8228 + if ( toWnd->AddField( rData.getDisplayName(),
8229 DlgPos2WndPos( rAtPos, *toWnd ),
8230 nAddedAt ) )
8232 @@ -605,9 +607,9 @@ void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Po
8233 else
8235 USHORT nMask = fData.mnFuncMask;
8236 - String aStr( GetFuncString( nMask, rData.mbIsValue ) );
8238 - aStr += rData.maName;
8239 + OUString aStr = GetFuncString( nMask, rData.mbIsValue );
8241 + aStr += rData.getDisplayName();
8243 if ( toWnd->AddField( aStr,
8244 DlgPos2WndPos( rAtPos, *toWnd ),
8245 @@ -1215,7 +1217,7 @@ String ScDPLayoutDlg::GetLabelString( SCsCOL nCol )
8246 ScDPLabelData* pData = GetLabelData( nCol );
8247 DBG_ASSERT( pData, "LabelData not found" );
8248 if (pData)
8249 - return pData->maName;
8250 + return pData->getDisplayName();
8251 return String();
8254 @@ -1491,6 +1493,8 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG )
8255 nPageCount, nColCount, nRowCount, nDataCount );
8256 if ( bFit )
8258 + ScDPSaveData* pOldSaveData = xDlgDPObject->GetSaveData();
8260 ScRange aOutRange( aAdrDest ); // bToNewTable is passed separately
8262 ScDPSaveData aSaveData;
8263 @@ -1522,31 +1526,63 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG )
8264 pDim->SetSortInfo( &aIt->maSortInfo );
8265 pDim->SetLayoutInfo( &aIt->maLayoutInfo );
8266 pDim->SetAutoShowInfo( &aIt->maShowInfo );
8267 + ScDPSaveDimension* pOldDim = NULL;
8268 + if (pOldSaveData)
8270 + // Transfer the existing layout names to new dimension instance.
8271 + pOldDim = pOldSaveData->GetExistingDimensionByName(aIt->maName);
8272 + if (pOldDim)
8274 + const OUString* pLayoutName = pOldDim->GetLayoutName();
8275 + if (pLayoutName)
8276 + pDim->SetLayoutName(*pLayoutName);
8278 + const OUString* pSubtotalName = pOldDim->GetSubtotalName();
8279 + if (pSubtotalName)
8280 + pDim->SetSubtotalName(*pSubtotalName);
8284 bool bManualSort = ( aIt->maSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL );
8286 // visibility of members
8287 - if( const rtl::OUString* pItem = aIt->maMembers.getConstArray() )
8288 + for (vector<ScDPLabelData::Member>::const_iterator itr = aIt->maMembers.begin(), itrEnd = aIt->maMembers.end();
8289 + itr != itrEnd; ++itr)
8291 - sal_Int32 nIdx = 0;
8292 - sal_Int32 nVisSize = aIt->maVisible.getLength();
8293 - sal_Int32 nShowSize = aIt->maShowDet.getLength();
8294 - for( const rtl::OUString* pEnd = pItem + aIt->maMembers.getLength(); pItem != pEnd; ++pItem, ++nIdx )
8295 + ScDPSaveMember* pMember = pDim->GetMemberByName(itr->maName);
8297 + // #i40054# create/access members only if flags are not default
8298 + // (or in manual sorting mode - to keep the order)
8299 + if (bManualSort || !itr->mbVisible || !itr->mbShowDetails)
8301 + pMember->SetIsVisible(itr->mbVisible);
8302 + pMember->SetShowDetails(itr->mbShowDetails);
8304 + if (pOldDim)
8306 - // #i40054# create/access members only if flags are not default
8307 - // (or in manual sorting mode - to keep the order)
8308 - bool bIsVisible = (nIdx >= nVisSize) || aIt->maVisible[ nIdx ];
8309 - bool bShowDetails = (nIdx >= nShowSize) || aIt->maShowDet[ nIdx ];
8310 - if( bManualSort || !bIsVisible || !bShowDetails )
8311 + // Transfer the existing layout name.
8312 + ScDPSaveMember* pOldMember = pOldDim->GetMemberByName(itr->maName);
8313 + if (pOldMember)
8315 - ScDPSaveMember* pMember = pDim->GetMemberByName( *pItem );
8316 - pMember->SetIsVisible( bIsVisible );
8317 - pMember->SetShowDetails( bShowDetails );
8318 + const OUString* pLayoutName = pOldMember->GetLayoutName();
8319 + if (pLayoutName)
8320 + pMember->SetLayoutName(*pLayoutName);
8326 + ScDPSaveDimension* pDim = aSaveData.GetDataLayoutDimension();
8327 + if (pDim && pOldSaveData)
8329 + ScDPSaveDimension* pOldDim = pOldSaveData->GetDataLayoutDimension();
8330 + if (pOldDim)
8332 + const OUString* pLayoutName = pOldDim->GetLayoutName();
8333 + if (pLayoutName)
8334 + pDim->SetLayoutName(*pLayoutName);
8338 USHORT nWhichPivot = SC_MOD()->GetPool().GetWhich( SID_PIVOT_TABLE );
8339 ScPivotItem aOutItem( nWhichPivot, &aSaveData, &aOutRange, bToNewTable );
8340 @@ -1720,7 +1756,7 @@ IMPL_LINK( ScDPLayoutDlg, ScrollHdl, ScrollBar *, EMPTYARG )
8341 for ( i=0; i<nFields; i++ )
8343 const ScDPLabelData& rData = aLabelDataArr[nOffset+i];
8344 - aWndSelect.AddField( rData.maName, i );
8345 + aWndSelect.AddField(rData.getDisplayName(), i);
8346 aSelectArr[i].reset( new ScDPFuncData( rData.mnCol, rData.mnFuncMask ) );
8348 for ( ; i<aSelectArr.size(); i++ )
8349 diff --git sc/source/ui/docshell/dbdocfun.cxx sc/source/ui/docshell/dbdocfun.cxx
8350 index 0fc36d7..8ee336e 100644
8351 --- sc/source/ui/docshell/dbdocfun.cxx
8352 +++ sc/source/ui/docshell/dbdocfun.cxx
8353 @@ -1234,7 +1234,7 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb
8354 aRange.aEnd.Col(), aRange.aEnd.Row(),
8355 nTab, SC_MF_AUTO );
8357 - pDoc->GetDPCollection()->Free( pOldObj ); // object is deleted here
8358 + pDoc->GetDPCollection()->FreeTable( pOldObj ); // object is deleted here
8360 rDocShell.PostPaintGridAll(); //! only necessary parts
8361 rDocShell.PostPaint( aRange.aStart.Col(), aRange.aStart.Row(), nTab,
8362 @@ -1278,7 +1278,7 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb
8364 pDestObj = new ScDPObject( *pNewObj );
8365 pDestObj->SetAlive(TRUE);
8366 - if ( !pDoc->GetDPCollection()->Insert(pDestObj) )
8367 + if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) )
8369 DBG_ERROR("cannot insert DPObject");
8370 DELETEZ( pDestObj );
8371 diff --git sc/source/ui/inc/AccessibleContextBase.hxx sc/source/ui/inc/AccessibleContextBase.hxx
8372 index 5cb0723..fdc378a 100644
8373 --- sc/source/ui/inc/AccessibleContextBase.hxx
8374 +++ sc/source/ui/inc/AccessibleContextBase.hxx
8375 @@ -319,6 +319,8 @@ protected:
8376 /// Use this method to set initial Description without notification
8377 void SetDescription(const rtl::OUString& rDesc) { msDescription = rDesc; }
8379 + void SetRole(sal_Int16 nRole);
8381 /// Reference to the parent object.
8382 ::com::sun::star::uno::Reference<
8383 ::com::sun::star::accessibility::XAccessible> mxParent;
8384 diff --git sc/source/ui/inc/dbfunc.hxx sc/source/ui/inc/dbfunc.hxx
8385 index fcdb170..bb43553 100644
8386 --- sc/source/ui/inc/dbfunc.hxx
8387 +++ sc/source/ui/inc/dbfunc.hxx
8388 @@ -80,7 +80,7 @@ public:
8389 void GotoDBArea( const String& rDBName );
8391 // DB-Bereich vom Cursor
8392 - ScDBData* GetDBData( BOOL bMarkArea = TRUE, ScGetDBMode eMode = SC_DB_MAKE );
8393 + ScDBData* GetDBData( BOOL bMarkArea = TRUE, ScGetDBMode eMode = SC_DB_MAKE, bool bShrinkToData = false );
8395 void NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const List& rDelAreaList );
8397 @@ -99,6 +99,7 @@ public:
8398 void UngroupDataPilot();
8399 void DataPilotInput( const ScAddress& rPos, const String& rString );
8401 + bool DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId = NULL );
8402 BOOL DataPilotMove( const ScRange& rSource, const ScAddress& rDest );
8404 BOOL HasSelectionForDrillDown( USHORT& rOrientation );
8405 diff --git sc/source/ui/inc/dpcontrol.hrc sc/source/ui/inc/dpcontrol.hrc
8406 new file mode 100644
8407 index 0000000..6d21b56
8408 --- /dev/null
8409 +++ sc/source/ui/inc/dpcontrol.hrc
8410 @@ -0,0 +1,43 @@
8411 +/*************************************************************************
8413 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8414 + *
8415 + * Copyright 2008 by Sun Microsystems, Inc.
8417 + * OpenOffice.org - a multi-platform office productivity suite
8419 + * $RCSfile: protectiondlg.hrc,v $
8420 + * $Revision: 1.1.2.1 $
8422 + * This file is part of OpenOffice.org.
8424 + * OpenOffice.org is free software: you can redistribute it and/or modify
8425 + * it under the terms of the GNU Lesser General Public License version 3
8426 + * only, as published by the Free Software Foundation.
8428 + * OpenOffice.org is distributed in the hope that it will be useful,
8429 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8430 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8431 + * GNU Lesser General Public License version 3 for more details
8432 + * (a copy is included in the LICENSE file that accompanied this code).
8434 + * You should have received a copy of the GNU Lesser General Public License
8435 + * version 3 along with OpenOffice.org. If not, see
8436 + * <http://www.openoffice.org/license.html>
8437 + * for a copy of the LGPLv3 License.
8439 + ************************************************************************/
8441 +#ifndef __DPCONTROL_HRC__
8442 +#define __DPCONTROL_HRC__
8444 +#include <sc.hrc>
8446 +#define STR_MENU_SORT_ASC 1
8447 +#define STR_MENU_SORT_DESC 2
8448 +#define STR_MENU_SORT_CUSTOM 3
8449 +#define STR_BTN_TOGGLE_ALL 4
8450 +#define STR_BTN_SELECT_CURRENT 5
8451 +#define STR_BTN_UNSELECT_CURRENT 6
8453 +#endif
8454 diff --git sc/source/ui/inc/dpcontrol.hxx sc/source/ui/inc/dpcontrol.hxx
8455 new file mode 100644
8456 index 0000000..2380d5d
8457 --- /dev/null
8458 +++ sc/source/ui/inc/dpcontrol.hxx
8459 @@ -0,0 +1,366 @@
8460 +/*************************************************************************
8462 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8464 + * Copyright 2008 by Sun Microsystems, Inc.
8466 + * OpenOffice.org - a multi-platform office productivity suite
8468 + * $RCSfile: document.hxx,v $
8469 + * $Revision: 1.115.36.9 $
8471 + * This file is part of OpenOffice.org.
8473 + * OpenOffice.org is free software: you can redistribute it and/or modify
8474 + * it under the terms of the GNU Lesser General Public License version 3
8475 + * only, as published by the Free Software Foundation.
8477 + * OpenOffice.org is distributed in the hope that it will be useful,
8478 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8479 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8480 + * GNU Lesser General Public License version 3 for more details
8481 + * (a copy is included in the LICENSE file that accompanied this code).
8483 + * You should have received a copy of the GNU Lesser General Public License
8484 + * version 3 along with OpenOffice.org. If not, see
8485 + * <http://www.openoffice.org/license.html>
8486 + * for a copy of the LGPLv3 License.
8488 + ************************************************************************/
8490 +#ifndef SC_DPCONTROL_HXX
8491 +#define SC_DPCONTROL_HXX
8493 +#include "rtl/ustring.hxx"
8494 +#include "tools/gen.hxx"
8495 +#include "tools/fract.hxx"
8496 +#include "vcl/popupmenuwindow.hxx"
8497 +#include "vcl/button.hxx"
8498 +#include "vcl/scrbar.hxx"
8499 +#include "vcl/timer.hxx"
8500 +#include "svx/checklbx.hxx"
8502 +#include <boost/shared_ptr.hpp>
8503 +#include <memory>
8504 +#include <hash_map>
8506 +namespace com { namespace sun { namespace star {
8508 + namespace accessibility {
8509 + class XAccessible;
8512 +}}}
8514 +class OutputDevice;
8515 +class Point;
8516 +class Size;
8517 +class StyleSettings;
8518 +class Window;
8519 +class ScDocument;
8520 +class ScAccessibleFilterMenu;
8522 +/**
8523 + * This class takes care of physically drawing field button controls inside
8524 + * data pilot tables.
8525 + */
8526 +class ScDPFieldButton
8528 +public:
8529 + ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX = NULL, const Fraction* pZoomY = NULL);
8530 + ~ScDPFieldButton();
8532 + void setText(const ::rtl::OUString& rText);
8533 + void setBoundingBox(const Point& rPos, const Size& rSize);
8534 + void setDrawBaseButton(bool b);
8535 + void setDrawPopupButton(bool b);
8536 + void setHasHiddenMember(bool b);
8537 + void setPopupPressed(bool b);
8538 + void draw();
8540 + void getPopupBoundingBox(Point& rPos, Size& rSize) const;
8541 + bool isPopupButton() const;
8543 +private:
8544 + void drawPopupButton();
8546 +private:
8547 + Point maPos;
8548 + Size maSize;
8549 + ::rtl::OUString maText;
8550 + Fraction maZoomX;
8551 + Fraction maZoomY;
8552 + OutputDevice* mpOutDev;
8553 + const StyleSettings* mpStyle;
8554 + bool mbBaseButton;
8555 + bool mbPopupButton;
8556 + bool mbHasHiddenMember;
8557 + bool mbPopupPressed;
8560 +// ============================================================================
8562 +class ScMenuFloatingWindow : public PopupMenuFloatingWindow
8564 +public:
8565 + static size_t MENU_NOT_SELECTED;
8566 + /**
8567 + * Action to perform when an event takes place. Create a sub-class of
8568 + * this to implement the desired action.
8569 + */
8570 + class Action
8572 + public:
8573 + virtual void execute() = 0;
8574 + };
8576 + explicit ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel = 0);
8577 + virtual ~ScMenuFloatingWindow();
8579 + virtual void MouseMove(const MouseEvent& rMEvt);
8580 + virtual void MouseButtonDown(const MouseEvent& rMEvt);
8581 + virtual void MouseButtonUp(const MouseEvent& rMEvt);
8582 + virtual void KeyInput(const KeyEvent& rKEvt);
8583 + virtual void Paint(const Rectangle& rRect);
8584 + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
8586 + void addMenuItem(const ::rtl::OUString& rText, bool bEnabled, Action* pAction);
8587 + ScMenuFloatingWindow* addSubMenuItem(const ::rtl::OUString& rText, bool bEnabled);
8588 + void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu);
8589 + void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer);
8590 + void clearSelectedMenuItem();
8591 + ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const;
8592 + size_t getMenuItemCount() const;
8593 + ::rtl::OUString getMenuItemName(size_t nPos) const;
8594 + bool isMenuItemEnabled(size_t nPos) const;
8595 + bool isMenuItemSelected(size_t nPos) const;
8596 + size_t getSelectedMenuItem() const;
8598 + void setName(const ::rtl::OUString& rName);
8599 + const ::rtl::OUString& getName() const;
8601 + void executeMenuItem(size_t nPos);
8602 + void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const;
8603 + ScMenuFloatingWindow* getParentMenuWindow() const;
8605 +protected:
8607 + void drawMenuItem(size_t nPos);
8608 + void drawAllMenuItems();
8609 + const Font& getLabelFont() const;
8611 + void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu);
8612 + void queueCloseSubMenu();
8613 + void launchSubMenu(bool bSetMenuPos);
8614 + void endSubMenu(ScMenuFloatingWindow* pSubMenu);
8616 + void fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const;
8618 + ScDocument* getDoc();
8620 +protected:
8621 + ::com::sun::star::uno::Reference<
8622 + ::com::sun::star::accessibility::XAccessible > mxAccessible;
8624 +private:
8625 + struct SubMenuItemData;
8626 + void handleMenuTimeout(SubMenuItemData* pTimer);
8628 + void resizeToFitMenuItems();
8629 + void highlightMenuItem(size_t nPos, bool bSelected);
8631 + size_t getEnclosingMenuItem(const Point& rPos) const;
8632 + size_t getSubMenuPos(ScMenuFloatingWindow* pSubMenu);
8634 + /**
8635 + * Fire a menu highlight event since the accessibility framework needs
8636 + * this to track focus on menu items.
8637 + */
8638 + void fireMenuHighlightedEvent();
8640 + /**
8641 + * Make sure that the specified submenu is permanently up, the submenu
8642 + * close timer is not active, and the correct menu item associated with
8643 + * the submenu is highlighted.
8644 + */
8645 + void setSubMenuFocused(ScMenuFloatingWindow* pSubMenu);
8647 + /**
8648 + * When a menu item of an invisible submenu is selected, we need to make
8649 + * sure that all its parent menu(s) are visible, with the right menu item
8650 + * highlighted in each of the parents. Calling this method ensures it.
8651 + */
8652 + void ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu);
8654 + /**
8655 + * Dismiss any visible child submenus when a menu item of a parent menu is
8656 + * selected.
8657 + */
8658 + void ensureSubMenuNotVisible();
8660 + /**
8661 + * Dismiss all visible popup menus and set focus back to the application
8662 + * window. This method is called e.g. when a menu action is fired.
8663 + */
8664 + void terminateAllPopupMenus();
8666 + DECL_LINK( PopupEndHdl, void* );
8668 +private:
8670 + struct MenuItemData
8672 + ::rtl::OUString maText;
8673 + bool mbEnabled;
8675 + ::boost::shared_ptr<Action> mpAction;
8676 + ::boost::shared_ptr<ScMenuFloatingWindow> mpSubMenuWin;
8678 + MenuItemData();
8679 + };
8681 + ::std::vector<MenuItemData> maMenuItems;
8683 + struct SubMenuItemData
8685 + Timer maTimer;
8686 + ScMenuFloatingWindow* mpSubMenu;
8687 + size_t mnMenuPos;
8689 + DECL_LINK( TimeoutHdl, void* );
8691 + SubMenuItemData(ScMenuFloatingWindow* pParent);
8692 + void reset();
8694 + private:
8695 + ScMenuFloatingWindow* mpParent;
8696 + };
8697 + SubMenuItemData maOpenTimer;
8698 + SubMenuItemData maCloseTimer;
8700 + Font maLabelFont;
8702 + // Name of this menu window, taken from the menu item of the parent window
8703 + // that launches it (if this is a sub menu). If this is a top-level menu
8704 + // window, then this name can be anything.
8705 + ::rtl::OUString maName;
8707 + size_t mnSelectedMenu;
8708 + size_t mnClickedMenu;
8710 + ScDocument* mpDoc;
8712 + ScMenuFloatingWindow* mpParentMenu;
8713 + ScMenuFloatingWindow* mpActiveSubMenu;
8716 +// ============================================================================
8718 +/**
8719 + * This class implements a popup window for field button, for quick access
8720 + * of hide-item list, and possibly more stuff related to field options.
8721 + */
8722 +class ScDPFieldPopupWindow : public ScMenuFloatingWindow
8724 +public:
8725 + /**
8726 + * Extended data that the client code may need to store. Create a
8727 + * sub-class of this and store data there.
8728 + */
8729 + struct ExtendedData {};
8731 + explicit ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc);
8732 + virtual ~ScDPFieldPopupWindow();
8734 + virtual void MouseMove(const MouseEvent& rMEvt);
8735 + virtual long Notify(NotifyEvent& rNEvt);
8736 + virtual void Paint(const Rectangle& rRect);
8737 + virtual Window* GetPreferredKeyInputWindow();
8738 + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
8740 + void setMemberSize(size_t n);
8741 + void addMember(const ::rtl::OUString& rName, bool bVisible);
8742 + void initMembers();
8744 + const Size& getWindowSize() const;
8746 + void getResult(::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rResult);
8747 + void close(bool bOK);
8749 + /**
8750 + * Set auxiliary data that the client code might need. Note that this
8751 + * popup window class manages its life time; no explicit deletion of the
8752 + * instance is needed in the client code.
8753 + */
8754 + void setExtendedData(ExtendedData* p);
8756 + /**
8757 + * Get the store auxiliary data, or NULL if no such data is stored.
8758 + */
8759 + ExtendedData* getExtendedData();
8761 + void setOKAction(Action* p);
8763 +private:
8764 + struct Member
8766 + ::rtl::OUString maName;
8767 + bool mbVisible;
8769 + Member();
8770 + };
8772 + class CancelButton : public ::CancelButton
8774 + public:
8775 + CancelButton(ScDPFieldPopupWindow* pParent);
8777 + virtual void Click();
8779 + private:
8780 + ScDPFieldPopupWindow* mpParent;
8781 + };
8783 + enum SectionType {
8784 + WHOLE, // entire window
8785 + LISTBOX_AREA_OUTER, // box enclosing the check box items.
8786 + LISTBOX_AREA_INNER, // box enclosing the check box items.
8787 + SINGLE_BTN_AREA, // box enclosing the single-action buttons.
8788 + CHECK_TOGGLE_ALL, // check box for toggling all items.
8789 + BTN_SINGLE_SELECT,
8790 + BTN_SINGLE_UNSELECT,
8791 + BTN_OK, // OK button
8792 + BTN_CANCEL, // Cancel button
8793 + };
8794 + void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const;
8796 + void setAllMemberState(bool bSet);
8797 + void selectCurrentMemberOnly(bool bSet);
8798 + void cycleFocus(bool bReverse = false);
8800 + DECL_LINK( ButtonHdl, Button* );
8801 + DECL_LINK( TriStateHdl, TriStateBox* );
8802 + DECL_LINK( CheckHdl, SvTreeListBox* );
8804 +private:
8805 + SvxCheckListBox maChecks;
8807 + TriStateBox maChkToggleAll;
8808 + ImageButton maBtnSelectSingle;
8809 + ImageButton maBtnUnselectSingle;
8811 + OKButton maBtnOk;
8812 + CancelButton maBtnCancel;
8814 + ::std::vector<Window*> maTabStopCtrls;
8815 + size_t mnCurTabStop;
8817 + ::std::vector<Member> maMembers;
8818 + ::std::auto_ptr<ExtendedData> mpExtendedData;
8819 + ::std::auto_ptr<Action> mpOKAction;
8821 + const Size maWndSize; /// hard-coded window size.
8822 + TriState mePrevToggleAllState;
8825 +#endif
8826 diff --git sc/source/ui/inc/gridwin.hxx sc/source/ui/inc/gridwin.hxx
8827 index 914ae51..4013e1a 100644
8828 --- sc/source/ui/inc/gridwin.hxx
8829 +++ sc/source/ui/inc/gridwin.hxx
8830 @@ -37,15 +37,19 @@
8831 #include "viewdata.hxx"
8832 #include "cbutton.hxx"
8833 #include <svx/sdr/overlay/overlayobject.hxx>
8834 +#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
8835 #include <basegfx/matrix/b2dhommatrix.hxx>
8837 #include <vector>
8838 +#include <memory>
8840 // ---------------------------------------------------------------------------
8842 struct ScTableInfo;
8843 class ScViewSelectionEngine;
8844 class ScDPObject;
8845 +class ScDPFieldPopupWindow;
8846 +class ScDPFieldButton;
8847 class ScOutputData;
8848 class ScFilterListBox;
8849 class AutoFilterPopup;
8850 @@ -121,6 +125,8 @@ private:
8852 ScFilterListBox* pFilterBox;
8853 FloatingWindow* pFilterFloat;
8854 + ::std::auto_ptr<ScDPFieldPopupWindow> mpDPFieldPopup;
8855 + ::std::auto_ptr<ScDPFieldButton> mpFilterButton;
8857 USHORT nCursorHideCount;
8859 @@ -187,12 +193,23 @@ private:
8860 BOOL TestMouse( const MouseEvent& rMEvt, BOOL bAction );
8862 BOOL DoPageFieldSelection( SCCOL nCol, SCROW nRow );
8863 + bool DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt );
8864 void DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt );
8866 void DPMouseMove( const MouseEvent& rMEvt );
8867 void DPMouseButtonUp( const MouseEvent& rMEvt );
8868 void DPTestMouse( const MouseEvent& rMEvt, BOOL bMove );
8870 + /**
8871 + * Check if the mouse click is on a field popup button.
8872 + *
8873 + * @return bool true if the field popup menu has been launched and no
8874 + * further mouse event handling is necessary, false otherwise.
8875 + */
8876 + bool DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj);
8877 + void DPLaunchFieldPopupMenu(
8878 + const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj);
8880 void RFMouseMove( const MouseEvent& rMEvt, BOOL bUp );
8882 void PagebreakMove( const MouseEvent& rMEvt, BOOL bUp );
8883 @@ -315,9 +332,11 @@ public:
8885 void DoAutoFilterMenue( SCCOL nCol, SCROW nRow, BOOL bDataSelect );
8886 void DoScenarioMenue( const ScRange& rScenRange );
8887 - void DoPageFieldMenue( SCCOL nCol, SCROW nRow );
8889 - BOOL HasPageFieldData( SCCOL nCol, SCROW nRow ) const;
8890 + void LaunchPageFieldMenu( SCCOL nCol, SCROW nRow );
8891 + void LaunchDPFieldMenu( SCCOL nCol, SCROW nRow );
8893 + ::com::sun::star::sheet::DataPilotFieldOrientation GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const;
8895 void DrawButtons( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
8896 ScTableInfo& rTabInfo, OutputDevice* pContentDev );
8897 @@ -357,6 +376,8 @@ public:
8899 void CheckNeedsRepaint();
8901 + void UpdateDPFromFieldPopupMenu();
8903 // #114409#
8904 void CursorChanged();
8905 void DrawLayerCreated();
8906 diff --git sc/source/ui/inc/pvfundlg.hxx sc/source/ui/inc/pvfundlg.hxx
8907 index 804f162..1707cd6 100644
8908 --- sc/source/ui/inc/pvfundlg.hxx
8909 +++ sc/source/ui/inc/pvfundlg.hxx
8910 @@ -55,6 +55,8 @@
8911 #include <sfx2/itemconnect.hxx>
8912 #include "pivot.hxx"
8914 +#include <hash_map>
8916 // ============================================================================
8918 typedef sfx::ListBoxWrapper< sal_Int32 > ScDPListBoxWrapper;
8919 @@ -217,6 +219,11 @@ public:
8921 virtual short Execute();
8923 + /**
8924 + * @return String internal name of the selected field. Note that this may
8925 + * be different from the name displayed in the dialog if the field
8926 + * has a layout name.
8927 + */
8928 String GetDimensionName() const;
8930 private:
8931 @@ -228,6 +235,10 @@ private:
8932 OKButton maBtnOk;
8933 CancelButton maBtnCancel;
8934 HelpButton maBtnHelp;
8936 + typedef ::std::hash_map<String, long, ScStringHashCode> DimNameIndexMap;
8937 + DimNameIndexMap maNameIndexMap;
8938 + ScDPObject& mrDPObj;
8941 // ============================================================================
8942 diff --git sc/source/ui/inc/pvlaydlg.hxx sc/source/ui/inc/pvlaydlg.hxx
8943 index f94a7ed..2f7e628 100644
8944 --- sc/source/ui/inc/pvlaydlg.hxx
8945 +++ sc/source/ui/inc/pvlaydlg.hxx
8946 @@ -193,7 +193,7 @@ private:
8947 private:
8948 ScDPFieldWindow& GetFieldWindow ( ScDPFieldType eType );
8949 void Init ();
8950 - void InitWndSelect ( LabelData** ppLabelArr, long nLabels );
8951 + void InitWndSelect ( const ::std::vector<ScDPLabelDataRef>& rLabels );
8952 void InitWnd ( PivotField* pArr, long nCount, ScDPFieldType eType );
8953 void InitFocus ();
8954 void InitFields ();
8955 diff --git sc/source/ui/undo/undodat.cxx sc/source/ui/undo/undodat.cxx
8956 index 73ebf38..f4fb524 100644
8957 --- sc/source/ui/undo/undodat.cxx
8958 +++ sc/source/ui/undo/undodat.cxx
8959 @@ -1879,7 +1879,7 @@ void __EXPORT ScUndoDataPilot::Undo()
8960 else
8962 // delete inserted object
8963 - pDoc->GetDPCollection()->Free(pDocObj);
8964 + pDoc->GetDPCollection()->FreeTable(pDocObj);
8968 @@ -1889,7 +1889,7 @@ void __EXPORT ScUndoDataPilot::Undo()
8970 ScDPObject* pDestObj = new ScDPObject( *pOldDPObject );
8971 pDestObj->SetAlive(TRUE);
8972 - if ( !pDoc->GetDPCollection()->Insert(pDestObj) )
8973 + if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) )
8975 DBG_ERROR("cannot insert DPObject");
8976 DELETEZ( pDestObj );
8977 diff --git sc/source/ui/unoobj/dapiuno.cxx sc/source/ui/unoobj/dapiuno.cxx
8978 index a4ec67a..2039ea0 100644
8979 --- sc/source/ui/unoobj/dapiuno.cxx
8980 +++ sc/source/ui/unoobj/dapiuno.cxx
8981 @@ -1626,8 +1626,13 @@ OUString SAL_CALL ScDataPilotFieldObj::getName() throw(RuntimeException)
8982 if( pDim->IsDataLayout() )
8983 aName = OUString( RTL_CONSTASCII_USTRINGPARAM( SC_DATALAYOUT_NAME ) );
8984 else
8985 - aName = pDim->GetLayoutName();
8987 + {
8988 + const rtl::OUString* pLayoutName = pDim->GetLayoutName();
8989 + if (pLayoutName)
8990 + aName = *pLayoutName;
8991 + else
8992 + aName = pDim->GetName();
8993 + } }
8994 return aName;
8997 @@ -1639,7 +1644,7 @@ void SAL_CALL ScDataPilotFieldObj::setName( const OUString& rName ) throw(Runtim
8998 if( pDim && !pDim->IsDataLayout() )
9000 String aName( rName );
9001 - pDim->SetLayoutName( &aName );
9002 + pDim->SetLayoutName(aName);
9003 SetDPObject( pDPObj );
9006 @@ -3069,7 +3074,7 @@ Sequence<OUString> SAL_CALL ScDataPilotItemsObj::getElementNames()
9007 ScUnoGuard aGuard;
9008 Sequence< OUString > aSeq;
9009 if( ScDPObject* pDPObj = GetDPObject() )
9010 - pDPObj->GetMembers( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
9011 + pDPObj->GetMemberNames( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
9012 return aSeq;
9015 diff --git sc/source/ui/unoobj/miscuno.cxx sc/source/ui/unoobj/miscuno.cxx
9016 index 0f6a291..0c9122a 100644
9017 --- sc/source/ui/unoobj/miscuno.cxx
9018 +++ sc/source/ui/unoobj/miscuno.cxx
9019 @@ -39,6 +39,9 @@
9020 #include "unoguard.hxx"
9022 using namespace com::sun::star;
9023 +using ::com::sun::star::uno::Reference;
9024 +using ::com::sun::star::uno::Any;
9025 +using ::rtl::OUString;
9027 //------------------------------------------------------------------------
9029 @@ -137,6 +140,26 @@ sal_Int32 ScUnoHelpFunctions::GetEnumProperty( const uno::Reference<beans::XProp
9030 return nRet;
9033 +// static
9034 +OUString ScUnoHelpFunctions::GetStringProperty(
9035 + const Reference<beans::XPropertySet>& xProp, const OUString& rName, const OUString& rDefault )
9037 + OUString aRet = rDefault;
9038 + if (!xProp.is())
9039 + return aRet;
9041 + try
9043 + Any any = xProp->getPropertyValue(rName);
9044 + any >>= aRet;
9046 + catch (const uno::Exception&)
9050 + return aRet;
9053 // static
9054 sal_Bool ScUnoHelpFunctions::GetBoolFromAny( const uno::Any& aAny )
9056 @@ -180,6 +203,20 @@ void ScUnoHelpFunctions::SetBoolInAny( uno::Any& rAny, sal_Bool bValue )
9057 rAny.setValue( &bValue, getBooleanCppuType() );
9060 +// static
9061 +void ScUnoHelpFunctions::SetOptionalPropertyValue(
9062 + Reference<beans::XPropertySet>& rPropSet, const sal_Char* pPropName, const Any& rVal )
9064 + try
9066 + rPropSet->setPropertyValue(OUString::createFromAscii(pPropName), rVal);
9068 + catch (const beans::UnknownPropertyException&)
9070 + // ignored - not supported.
9074 //------------------------------------------------------------------------
9076 ScIndexEnumeration::ScIndexEnumeration(const uno::Reference<container::XIndexAccess>& rInd,
9077 diff --git sc/source/ui/view/cellsh2.cxx sc/source/ui/view/cellsh2.cxx
9078 index d07feb0..90c6883 100644
9079 --- sc/source/ui/view/cellsh2.cxx
9080 +++ sc/source/ui/view/cellsh2.cxx
9081 @@ -764,7 +764,7 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
9083 // select database range or data
9084 pTabViewShell->GetDBData( TRUE, SC_DB_OLD );
9085 - const ScMarkData& rMark = GetViewData()->GetMarkData();
9086 + ScMarkData& rMark = GetViewData()->GetMarkData();
9087 if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
9088 pTabViewShell->MarkDataArea( FALSE );
9090 @@ -830,6 +830,19 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
9091 ScMarkType eType = GetViewData()->GetSimpleArea(aRange);
9092 if ( (eType & SC_MARK_SIMPLE) == SC_MARK_SIMPLE )
9094 + // Shrink the range to the data area.
9095 + SCCOL nStartCol = aRange.aStart.Col(), nEndCol = aRange.aEnd.Col();
9096 + SCROW nStartRow = aRange.aStart.Row(), nEndRow = aRange.aEnd.Row();
9097 + if (pDoc->ShrinkToDataArea(aRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow))
9099 + aRange.aStart.SetCol(nStartCol);
9100 + aRange.aStart.SetRow(nStartRow);
9101 + aRange.aEnd.SetCol(nEndCol);
9102 + aRange.aEnd.SetRow(nEndRow);
9103 + rMark.SetMarkArea(aRange);
9104 + pTabViewShell->MarkRange(aRange);
9107 BOOL bOK = TRUE;
9108 if ( pDoc->HasSubTotalCells( aRange ) )
9110 diff --git sc/source/ui/view/dbfunc.cxx sc/source/ui/view/dbfunc.cxx
9111 index b372240..05dce54 100644
9112 --- sc/source/ui/view/dbfunc.cxx
9113 +++ sc/source/ui/view/dbfunc.cxx
9114 @@ -107,14 +107,30 @@ void ScDBFunc::GotoDBArea( const String& rDBName )
9116 // aktuellen Datenbereich fuer Sortieren / Filtern suchen
9118 -ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode )
9119 +ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode, bool bShrinkToData )
9121 ScDocShell* pDocSh = GetViewData()->GetDocShell();
9122 ScDBData* pData = NULL;
9123 ScRange aRange;
9124 ScMarkType eMarkType = GetViewData()->GetSimpleArea(aRange);
9125 if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED )
9127 + if (bShrinkToData)
9129 + // Shrink the range to only include data area.
9130 + ScDocument* pDoc = pDocSh->GetDocument();
9131 + SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col();
9132 + SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row();
9133 + if (pDoc->ShrinkToDataArea(aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2))
9135 + aRange.aStart.SetCol(nCol1);
9136 + aRange.aEnd.SetCol(nCol2);
9137 + aRange.aStart.SetRow(nRow1);
9138 + aRange.aEnd.SetRow(nRow2);
9141 pData = pDocSh->GetDBData( aRange, eMode, FALSE );
9143 else if ( eMode != SC_DB_OLD )
9144 pData = pDocSh->GetDBData(
9145 ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
9146 diff --git sc/source/ui/view/dbfunc3.cxx sc/source/ui/view/dbfunc3.cxx
9147 index 4b50b5b..86fc703 100644
9148 --- sc/source/ui/view/dbfunc3.cxx
9149 +++ sc/source/ui/view/dbfunc3.cxx
9150 @@ -44,19 +44,17 @@
9151 #include <vcl/waitobj.hxx>
9152 #include <svtools/zforlist.hxx>
9153 #include <sfx2/app.hxx>
9154 +#include <com/sun/star/beans/XPropertySet.hpp>
9155 +#include <com/sun/star/container/XNameAccess.hpp>
9156 +#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
9157 +#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
9158 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
9159 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
9160 -#include <com/sun/star/sheet/MemberResultFlags.hpp>
9162 -#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
9163 #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
9164 +#include <com/sun/star/sheet/GeneralFunction.hpp>
9165 #include <com/sun/star/sheet/MemberResultFlags.hpp>
9166 -#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
9167 -#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
9168 -#include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
9169 #include <com/sun/star/sheet/XDimensionsSupplier.hpp>
9170 -#include <com/sun/star/beans/XPropertySet.hpp>
9171 -#include <com/sun/star/container/XNameAccess.hpp>
9172 +#include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
9174 #include "global.hxx"
9175 #include "globstr.hrc"
9176 @@ -81,9 +79,13 @@
9177 #include "patattr.hxx"
9178 #include "unonames.hxx"
9179 #include "cell.hxx"
9180 +#include "userlist.hxx"
9182 #include <hash_set>
9183 +#include <hash_map>
9184 #include <memory>
9185 +#include <list>
9186 +#include <vector>
9188 using namespace com::sun::star;
9189 using ::com::sun::star::uno::Any;
9190 @@ -91,7 +93,16 @@ using ::com::sun::star::uno::Sequence;
9191 using ::com::sun::star::uno::Reference;
9192 using ::com::sun::star::uno::UNO_QUERY;
9193 using ::com::sun::star::beans::XPropertySet;
9194 +using ::com::sun::star::container::XNameAccess;
9195 +using ::com::sun::star::sheet::XDimensionsSupplier;
9196 +using ::rtl::OUString;
9197 +using ::rtl::OUStringHash;
9198 +using ::rtl::OUStringBuffer;
9199 using ::std::auto_ptr;
9200 +using ::std::list;
9201 +using ::std::vector;
9202 +using ::std::hash_map;
9203 +using ::std::hash_set;
9205 // STATIC DATA -----------------------------------------------------------
9207 @@ -1351,123 +1362,323 @@ void ScDBFunc::UngroupDataPilot()
9211 +static OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName)
9213 + sal_Int32 n = rSubtotal.getLength();
9214 + const sal_Unicode* p = rSubtotal.getStr();
9215 + OUStringBuffer aBuf, aWordBuf;
9216 + for (sal_Int32 i = 0; i < n; ++i)
9218 + sal_Unicode c = p[i];
9219 + if (c == sal_Unicode(' '))
9221 + OUString aWord = aWordBuf.makeStringAndClear();
9222 + if (aWord.equals(rMemberName))
9223 + aBuf.append(sal_Unicode('?'));
9224 + else
9225 + aBuf.append(aWord);
9226 + aBuf.append(c);
9228 + else if (c == sal_Unicode('\\'))
9230 + // Escape a backslash character.
9231 + aWordBuf.append(c);
9232 + aWordBuf.append(c);
9234 + else if (c == sal_Unicode('?'))
9236 + // A literal '?' must be escaped with a backslash ('\');
9237 + aWordBuf.append(sal_Unicode('\\'));
9238 + aWordBuf.append(c);
9240 + else
9241 + aWordBuf.append(c);
9244 + if (aWordBuf.getLength() > 0)
9246 + OUString aWord = aWordBuf.makeStringAndClear();
9247 + if (aWord.equals(rMemberName))
9248 + aBuf.append(sal_Unicode('?'));
9249 + else
9250 + aBuf.append(aWord);
9253 + return aBuf.makeStringAndClear();
9256 void ScDBFunc::DataPilotInput( const ScAddress& rPos, const String& rString )
9258 + using namespace ::com::sun::star::sheet;
9260 String aNewName( rString );
9262 ScDocument* pDoc = GetViewData()->GetDocument();
9263 ScDPObject* pDPObj = pDoc->GetDPAtCursor( rPos.Col(), rPos.Row(), rPos.Tab() );
9264 - if ( pDPObj )
9265 + if (!pDPObj)
9266 + return;
9268 + String aOldText;
9269 + pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText );
9271 + if ( aOldText == rString )
9273 - String aOldText;
9274 - pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText );
9275 + // nothing to do: silently exit
9276 + return;
9279 + USHORT nErrorId = 0;
9281 - if ( aOldText == rString )
9282 + pDPObj->BuildAllDimensionMembers();
9283 + ScDPSaveData aData( *pDPObj->GetSaveData() );
9284 + BOOL bChange = FALSE;
9286 + USHORT nOrient = DataPilotFieldOrientation_HIDDEN;
9287 + long nField = pDPObj->GetHeaderDim( rPos, nOrient );
9288 + if ( nField >= 0 )
9290 + // changing a field title
9291 + if ( aData.GetExistingDimensionData() )
9293 - // nothing to do: silently exit
9294 - return;
9296 + // only group dimensions can be renamed
9298 - USHORT nErrorId = 0;
9299 + ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
9300 + ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText );
9301 + if ( pGroupDim )
9303 + // valid name: not empty, no existing dimension (group or other)
9304 + if ( rString.Len() && !pDPObj->IsDimNameInUse(rString) )
9306 + pGroupDim->Rename( aNewName );
9308 - ScDPSaveData aData( *pDPObj->GetSaveData() );
9309 - BOOL bChange = FALSE;
9310 + // also rename in SaveData to preserve the field settings
9311 + ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText );
9312 + pSaveDim->SetName( aNewName );
9314 - USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
9315 - long nField = pDPObj->GetHeaderDim( rPos, nOrient );
9316 - if ( nField >= 0 )
9317 + bChange = TRUE;
9319 + else
9320 + nErrorId = STR_INVALIDNAME;
9323 + else if (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW)
9325 + BOOL bDataLayout = false;
9326 + String aDimName = pDPObj->GetDimName(nField, bDataLayout);
9327 + ScDPSaveDimension* pDim = bDataLayout ? aData.GetDataLayoutDimension() : aData.GetDimensionByName(aDimName);
9328 + if (pDim)
9330 + if (rString.Len())
9332 + if (rString.EqualsIgnoreCaseAscii(aDimName))
9333 + {
9334 + pDim->RemoveLayoutName();
9335 + bChange = true;
9337 + else if (!pDPObj->IsDimNameInUse(rString))
9339 + pDim->SetLayoutName(rString);
9340 + bChange = true;
9342 + else
9343 + nErrorId = STR_INVALIDNAME;
9345 + else
9346 + nErrorId = STR_INVALIDNAME;
9350 + else if (pDPObj->IsDataDescriptionCell(rPos))
9352 + // There is only one data dimension.
9353 + ScDPSaveDimension* pDim = aData.GetFirstDimension(sheet::DataPilotFieldOrientation_DATA);
9354 + if (pDim)
9356 - // changing a field title
9357 + if (rString.Len())
9359 + if (rString.EqualsIgnoreCaseAscii(pDim->GetName()))
9361 + pDim->RemoveLayoutName();
9362 + bChange = true;
9364 + else if (!pDPObj->IsDimNameInUse(rString))
9366 + pDim->SetLayoutName(rString);
9367 + bChange = true;
9369 + else
9370 + nErrorId = STR_INVALIDNAME;
9372 + else
9373 + nErrorId = STR_INVALIDNAME;
9376 + else
9378 + // This is not a field header.
9379 + sheet::DataPilotTableHeaderData aPosData;
9380 + pDPObj->GetHeaderPositionData(rPos, aPosData);
9382 - if ( aData.GetExistingDimensionData() )
9383 + if ( (aPosData.Flags & MemberResultFlags::HASMEMBER) && aOldText.Len() )
9385 + if ( aData.GetExistingDimensionData() && !(aPosData.Flags & MemberResultFlags::SUBTOTAL))
9387 - // only group dimensions can be renamed
9388 + BOOL bIsDataLayout;
9389 + String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout );
9391 ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
9392 - ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText );
9393 + ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
9394 if ( pGroupDim )
9396 - // valid name: not empty, no existing dimension (group or other)
9397 - if ( aNewName.Len() && !pDPObj->IsDimNameInUse( aNewName ) )
9398 + // valid name: not empty, no existing group in this dimension
9399 + //! ignore case?
9400 + if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) )
9402 - pGroupDim->Rename( aNewName );
9403 + ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText );
9404 + if ( pGroup )
9405 + pGroup->Rename( aNewName ); // rename the existing group
9406 + else
9408 + // create a new group to replace the automatic group
9409 + ScDPSaveGroupItem aGroup( aNewName );
9410 + aGroup.AddElement( aOldText );
9411 + pGroupDim->AddGroupItem( aGroup );
9414 - // also rename in SaveData to preserve the field settings
9415 - ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText );
9416 - pSaveDim->SetName( aNewName );
9417 + // in both cases also adjust savedata, to preserve member settings (show details)
9418 + ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName );
9419 + ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText );
9420 + if ( pSaveMember )
9421 + pSaveMember->SetName( aNewName );
9423 bChange = TRUE;
9425 else
9426 nErrorId = STR_INVALIDNAME;
9431 - else
9433 - // renaming a group (item)?
9434 - // allow only on the item name itself - not on empty cells, not on subtotals
9436 - sheet::DataPilotTableHeaderData aPosData;
9437 - pDPObj->GetHeaderPositionData(rPos, aPosData);
9438 - if ( ( aPosData.Flags & sheet::MemberResultFlags::HASMEMBER ) &&
9439 - ! ( aPosData.Flags & sheet::MemberResultFlags::SUBTOTAL ) &&
9440 - aOldText.Len() )
9441 + else if ((aPosData.Flags & MemberResultFlags::GRANDTOTAL))
9443 - if ( aData.GetExistingDimensionData() )
9444 + aData.SetGrandTotalName(rString);
9445 + bChange = true;
9447 + else if (aPosData.Dimension >= 0 && aPosData.MemberName.getLength() > 0)
9449 + BOOL bDataLayout = false;
9450 + String aDimName = pDPObj->GetDimName(static_cast<long>(aPosData.Dimension), bDataLayout);
9451 + if (bDataLayout)
9453 - BOOL bIsDataLayout;
9454 - String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout );
9455 + // data dimension
9456 + do
9458 + if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
9459 + break;
9461 + ScDPSaveDimension* pDim = aData.GetDimensionByName(aPosData.MemberName);
9462 + if (!pDim)
9463 + break;
9465 - ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
9466 - ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
9467 - if ( pGroupDim )
9468 + if (!rString.Len())
9470 + nErrorId = STR_INVALIDNAME;
9471 + break;
9474 + if (aPosData.MemberName.equalsIgnoreAsciiCase(rString))
9476 + pDim->RemoveLayoutName();
9477 + bChange = true;
9479 + else if (!pDPObj->IsDimNameInUse(rString))
9481 + pDim->SetLayoutName(rString);
9482 + bChange = true;
9484 + else
9485 + nErrorId = STR_INVALIDNAME;
9487 + while (false);
9489 + else
9491 + // field member
9492 + do
9494 - // valid name: not empty, no existing group in this dimension
9495 - //! ignore case?
9496 - if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) )
9497 + ScDPSaveDimension* pDim = aData.GetDimensionByName(aDimName);
9498 + if (!pDim)
9499 + break;
9501 + ScDPSaveMember* pMem = pDim->GetExistingMemberByName(aPosData.MemberName);
9502 + if (!pMem)
9503 + break;
9505 + if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
9507 - ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText );
9508 - if ( pGroup )
9509 - pGroup->Rename( aNewName ); // rename the existing group
9510 - else
9512 - // create a new group to replace the automatic group
9513 - ScDPSaveGroupItem aGroup( aNewName );
9514 - aGroup.AddElement( aOldText );
9515 - pGroupDim->AddGroupItem( aGroup );
9517 + // Change subtotal only when the table has one data dimension.
9518 + if (aData.GetDataDimensionCount() > 1)
9519 + break;
9521 - // in both cases also adjust savedata, to preserve member settings (show details)
9522 - ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName );
9523 - ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText );
9524 - if ( pSaveMember )
9525 - pSaveMember->SetName( aNewName );
9526 + // display name for subtotal is allowed only if the subtotal type is 'Automatic'.
9527 + if (pDim->GetSubTotalsCount() != 1)
9528 + break;
9530 - bChange = TRUE;
9531 + if (pDim->GetSubTotalFunc(0) != sheet::GeneralFunction_AUTO)
9532 + break;
9534 + const OUString* pLayoutName = pMem->GetLayoutName();
9535 + String aMemberName;
9536 + if (pLayoutName)
9537 + aMemberName = *pLayoutName;
9538 + else
9539 + aMemberName = aPosData.MemberName;
9541 + String aNew = lcl_replaceMemberNameInSubtotal(rString, aMemberName);
9542 + pDim->SetSubtotalName(aNew);
9543 + bChange = true;
9545 else
9546 - nErrorId = STR_INVALIDNAME;
9548 + // Check to make sure the member name isn't
9549 + // already used.
9550 + if (rString.Len())
9552 + if (rString.EqualsIgnoreCaseAscii(pMem->GetName()))
9554 + pMem->RemoveLayoutName();
9555 + bChange = true;
9557 + else if (!pDim->IsMemberNameInUse(rString))
9559 + pMem->SetLayoutName(rString);
9560 + bChange = true;
9562 + else
9563 + nErrorId = STR_INVALIDNAME;
9565 + else
9566 + nErrorId = STR_INVALIDNAME;
9569 + while (false);
9575 - if ( bChange )
9577 - // apply changes
9578 - ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
9579 - ScDPObject* pNewObj = new ScDPObject( *pDPObj );
9580 - pNewObj->SetSaveData( aData );
9581 - aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
9582 - delete pNewObj;
9584 - else
9586 - if ( !nErrorId )
9587 - nErrorId = STR_ERR_DATAPILOT_INPUT;
9588 - ErrorMessage( nErrorId );
9590 + if ( bChange )
9592 + // apply changes
9593 + ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
9594 + ScDPObject* pNewObj = new ScDPObject( *pDPObj );
9595 + pNewObj->SetSaveData( aData );
9596 + aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
9597 + delete pNewObj;
9599 + else
9601 + if ( !nErrorId )
9602 + nErrorId = STR_ERR_DATAPILOT_INPUT;
9603 + ErrorMessage( nErrorId );
9607 @@ -1484,6 +1695,134 @@ void lcl_MoveToEnd( ScDPSaveDimension& rDim, const String& rItemName )
9608 // puts it to the end of the list even if it was in the list before.
9611 +bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId )
9613 + ScDocument* pDoc = GetViewData()->GetDocument();
9614 + ScDPObject* pDPObj = pDoc->GetDPAtCursor(rPos.Col(), rPos.Row(), rPos.Tab());
9615 + if (!pDPObj)
9616 + return false;
9618 + // We need to run this to get all members later.
9619 + pDPObj->BuildAllDimensionMembers();
9621 + USHORT nOrientation;
9622 + long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation);
9623 + if (nDimIndex < 0)
9624 + // Invalid dimension index. Bail out.
9625 + return false;
9627 + BOOL bDataLayout;
9628 + ScDPSaveData* pSaveData = pDPObj->GetSaveData();
9629 + if (!pSaveData)
9630 + return false;
9632 + ScDPSaveData aNewSaveData(*pSaveData);
9633 + String aDimName = pDPObj->GetDimName(nDimIndex, bDataLayout);
9634 + ScDPSaveDimension* pSaveDim = aNewSaveData.GetDimensionByName(aDimName);
9635 + if (!pSaveDim)
9636 + return false;
9638 + typedef ScDPSaveDimension::MemberList MemList;
9639 + const MemList& rDimMembers = pSaveDim->GetMembers();
9640 + list<OUString> aMembers;
9641 + hash_set<OUString, ::rtl::OUStringHash> aMemberSet;
9642 + size_t nMemberCount = 0;
9643 + for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end();
9644 + itr != itrEnd; ++itr)
9646 + ScDPSaveMember* pMem = *itr;
9647 + aMembers.push_back(pMem->GetName());
9648 + aMemberSet.insert(pMem->GetName());
9649 + ++nMemberCount;
9652 + // Sort the member list in ascending order.
9653 + aMembers.sort();
9655 + // Collect and rank those custom sort strings that also exist in the member name list.
9657 + typedef hash_map<OUString, sal_uInt16, OUStringHash> UserSortMap;
9658 + UserSortMap aSubStrs;
9659 + sal_uInt16 nSubCount = 0;
9660 + if (pUserListId)
9662 + ScUserList* pUserList = ScGlobal::GetUserList();
9663 + if (!pUserList)
9664 + return false;
9667 + sal_uInt16 n = pUserList->GetCount();
9668 + if (!n || *pUserListId >= n)
9669 + return false;
9672 + ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[*pUserListId]);
9673 + if (pData)
9675 + sal_uInt16 n = pData->GetSubCount();
9676 + for (sal_uInt16 i = 0; i < n; ++i)
9678 + OUString aSub = pData->GetSubStr(i);
9679 + if (!aMemberSet.count(aSub))
9680 + // This string doesn't exist in the member name set. Don't add this.
9681 + continue;
9683 + aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++));
9688 + // Rank all members.
9690 + vector<OUString> aRankedNames(nMemberCount);
9691 + sal_uInt16 nCurStrId = 0;
9692 + for (list<OUString>::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end();
9693 + itr != itrEnd; ++itr)
9695 + OUString aName = *itr;
9696 + sal_uInt16 nRank = 0;
9697 + UserSortMap::const_iterator itrSub = aSubStrs.find(aName);
9698 + if (itrSub == aSubStrs.end())
9699 + nRank = nSubCount + nCurStrId++;
9700 + else
9701 + nRank = itrSub->second;
9703 + if (!bAscending)
9704 + nRank = nMemberCount - nRank - 1;
9706 + aRankedNames[nRank] = aName;
9709 + // Re-order ScDPSaveMember instances with the new ranks.
9711 + for (vector<OUString>::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end();
9712 + itr != itrEnd; ++itr)
9714 + const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr);
9715 + if (!pOldMem)
9716 + // All members are supposed to be present.
9717 + continue;
9719 + ScDPSaveMember* pNewMem = new ScDPSaveMember(*pOldMem);
9720 + pSaveDim->AddMember(pNewMem);
9723 + // Set the sorting mode to manual for now. We may introduce a new sorting
9724 + // mode later on.
9726 + sheet::DataPilotFieldSortInfo aSortInfo;
9727 + aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL;
9728 + pSaveDim->SetSortInfo(&aSortInfo);
9730 + // Update the datapilot with the newly sorted field members.
9732 + auto_ptr<ScDPObject> pNewObj(new ScDPObject(*pDPObj));
9733 + pNewObj->SetSaveData(aNewSaveData);
9734 + ScDBDocFunc aFunc(*GetViewData()->GetDocShell());
9736 + return aFunc.DataPilotUpdate(pDPObj, pNewObj.get(), true, false);
9739 BOOL ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest )
9741 BOOL bRet = FALSE;
9742 @@ -1529,7 +1868,7 @@ BOOL ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest )
9744 // get all member names in source order
9745 uno::Sequence<rtl::OUString> aMemberNames;
9746 - pDPObj->GetMembers( aDestData.Dimension, aMemberNames );
9747 + pDPObj->GetMemberNames( aDestData.Dimension, aMemberNames );
9749 bool bInserted = false;
9751 diff --git sc/source/ui/view/gridwin.cxx sc/source/ui/view/gridwin.cxx
9752 index 2b65eb8..42b22a6 100644
9753 --- sc/source/ui/view/gridwin.cxx
9754 +++ sc/source/ui/view/gridwin.cxx
9755 @@ -121,6 +121,7 @@
9756 #include "validat.hxx"
9757 #include "tabprotection.hxx"
9758 #include "postit.hxx"
9759 +#include "dpcontrol.hxx"
9761 #include "drawview.hxx"
9762 #include <svx/sdrpagewindow.hxx>
9763 @@ -369,6 +370,8 @@ ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhic
9764 pNoteMarker( NULL ),
9765 pFilterBox( NULL ),
9766 pFilterFloat( NULL ),
9767 + mpDPFieldPopup(NULL),
9768 + mpFilterButton(NULL),
9769 nCursorHideCount( 0 ),
9770 bMarking( FALSE ),
9771 nButtonDown( 0 ),
9772 @@ -445,14 +448,26 @@ void __EXPORT ScGridWindow::Resize( const Size& )
9774 void ScGridWindow::ClickExtern()
9776 - // #i81298# don't delete the filter box when called from its select handler
9777 - // (possible through row header size update)
9778 - // #i84277# when initializing the filter box, a Basic error can deactivate the view
9779 - if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) )
9780 - return;
9781 + do
9783 + // #i81298# don't delete the filter box when called from its select handler
9784 + // (possible through row header size update)
9785 + // #i84277# when initializing the filter box, a Basic error can deactivate the view
9786 + if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) )
9788 + break;
9791 + DELETEZ(pFilterBox);
9792 + DELETEZ(pFilterFloat);
9794 + while (false);
9796 - DELETEZ(pFilterBox);
9797 - DELETEZ(pFilterFloat);
9798 + if (mpDPFieldPopup.get())
9800 + mpDPFieldPopup->close(false);
9801 + mpDPFieldPopup.reset();
9805 IMPL_LINK( ScGridWindow, PopupModeEndHdl, FloatingWindow*, EMPTYARG )
9806 @@ -507,7 +522,7 @@ void ScGridWindow::ExecPageFieldSelect( SCCOL nCol, SCROW nRow, BOOL bHasSelecti
9810 -void ScGridWindow::DoPageFieldMenue( SCCOL nCol, SCROW nRow )
9811 +void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow )
9813 //! merge position/size handling with DoAutoFilterMenue
9815 @@ -658,6 +673,22 @@ void ScGridWindow::DoPageFieldMenue( SCCOL nCol, SCROW nRow )
9816 CaptureMouse();
9819 +void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow )
9821 + SCTAB nTab = pViewData->GetTabNo();
9822 + ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab);
9823 + if (!pDPObj)
9824 + return;
9826 + // Get the geometry of the cell.
9827 + Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
9828 + long nSizeX, nSizeY;
9829 + pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY);
9830 + Size aScrSize(nSizeX-1, nSizeY-1);
9832 + DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj);
9835 void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange )
9837 delete pFilterBox;
9838 @@ -1619,52 +1650,8 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt )
9839 pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG );
9840 if (pAttr->HasAutoFilter())
9842 - Point aScrPos = pViewData->GetScrPos(nPosX,nPosY,eWhich);
9843 - long nSizeX;
9844 - long nSizeY;
9845 - Point aDiffPix = aPos;
9847 - aDiffPix -= aScrPos;
9848 - BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
9849 - if ( bLayoutRTL )
9850 - aDiffPix.X() = -aDiffPix.X();
9852 - pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
9854 - // Breite des Buttons ist nicht von der Zellhoehe abhaengig
9855 - Size aButSize = aComboButton.GetSizePixel();
9856 - long nButWidth = Min( aButSize.Width(), nSizeX );
9857 - long nButHeight = Min( aButSize.Height(), nSizeY );
9859 - if ( aDiffPix.X() >= nSizeX - nButWidth &&
9860 - aDiffPix.Y() >= nSizeY - nButHeight )
9862 - if ( DoPageFieldSelection( nPosX, nPosY ) )
9863 - return;
9865 - BOOL bFilterActive = IsAutoFilterActive( nPosX, nPosY,
9866 - pViewData->GetTabNo() );
9868 - aComboButton.SetOptSizePixel();
9869 - DrawComboButton( aScrPos, nSizeX, nSizeY, bFilterActive, TRUE );
9871 -#if 0
9872 - if ( bWasFilterBox
9873 - && (SCsCOL)nOldColFBox == nPosX
9874 - && (SCsROW)nOldRowFBox == nPosY )
9876 - // Verhindern, dass an gleicher Stelle eine
9877 - // FilterBox geoeffnet wird, wenn diese gerade
9878 - // geloescht wurde
9880 - nMouseStatus = SC_GM_FILTER; // fuer ButtonDraw im MouseButtonUp();
9881 - return;
9883 -#endif
9884 - DoAutoFilterMenue( nPosX, nPosY, FALSE );
9886 + if (DoAutoFilterButton(nPosX, nPosY, rMEvt))
9887 return;
9890 if (pAttr->HasButton())
9892 @@ -1794,11 +1781,17 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
9894 if ( pFilterBox && pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
9896 - BOOL bFilterActive = IsAutoFilterActive( pFilterBox->GetCol(), pFilterBox->GetRow(),
9897 - pViewData->GetTabNo() );
9898 - HideCursor();
9899 - aComboButton.Draw( bFilterActive );
9900 - ShowCursor();
9901 + if (mpFilterButton.get())
9903 + bool bFilterActive = IsAutoFilterActive(
9904 + pFilterBox->GetCol(), pFilterBox->GetRow(), pViewData->GetTabNo() );
9906 + mpFilterButton->setHasHiddenMember(bFilterActive);
9907 + mpFilterButton->setPopupPressed(false);
9908 + HideCursor();
9909 + mpFilterButton->draw();
9910 + ShowCursor();
9913 nMouseStatus = SC_GM_NONE;
9914 ReleaseMouse();
9915 @@ -2218,9 +2211,14 @@ void __EXPORT ScGridWindow::MouseMove( const MouseEvent& rMEvt )
9916 nMouseStatus = SC_GM_NONE;
9917 if ( pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
9919 - HideCursor();
9920 - aComboButton.Draw( FALSE );
9921 - ShowCursor();
9922 + if (mpFilterButton.get())
9924 + mpFilterButton->setHasHiddenMember(false);
9925 + mpFilterButton->setPopupPressed(false);
9926 + HideCursor();
9927 + mpFilterButton->draw();
9928 + ShowCursor();
9931 ReleaseMouse();
9932 pFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT ) );
9933 diff --git sc/source/ui/view/gridwin2.cxx sc/source/ui/view/gridwin2.cxx
9934 index 7c59936..f5386d2 100644
9935 --- sc/source/ui/view/gridwin2.cxx
9936 +++ sc/source/ui/view/gridwin2.cxx
9937 @@ -55,48 +55,124 @@
9938 #include "dpoutput.hxx" // ScDPPositionData
9939 #include "dpshttab.hxx"
9940 #include "dbdocfun.hxx"
9941 +#include "dpcontrol.hxx"
9942 +#include "dpcontrol.hrc"
9943 +#include "strload.hxx"
9944 +#include "userlist.hxx"
9946 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
9947 #include "scabstdlg.hxx" //CHINA001
9948 -using namespace com::sun::star;
9950 +#include <vector>
9951 +#include <hash_map>
9953 +using namespace com::sun::star;
9954 +using ::com::sun::star::sheet::DataPilotFieldOrientation;
9955 +using ::std::vector;
9956 +using ::std::auto_ptr;
9957 +using ::std::hash_map;
9958 +using ::rtl::OUString;
9959 +using ::rtl::OUStringHash;
9961 // STATIC DATA -----------------------------------------------------------
9963 // -----------------------------------------------------------------------
9965 -BOOL ScGridWindow::HasPageFieldData( SCCOL nCol, SCROW nRow ) const
9966 +DataPilotFieldOrientation ScGridWindow::GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const
9968 + using namespace ::com::sun::star::sheet;
9970 ScDocument* pDoc = pViewData->GetDocument();
9971 SCTAB nTab = pViewData->GetTabNo();
9972 - ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
9973 - if ( pDPObj && nCol > 0 )
9974 + ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
9975 + if (!pDPObj)
9976 + return DataPilotFieldOrientation_HIDDEN;
9978 + USHORT nOrient = DataPilotFieldOrientation_HIDDEN;
9980 + // Check for page field first.
9981 + if (nCol > 0)
9983 // look for the dimension header left of the drop-down arrow
9984 - USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
9985 long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
9986 - if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
9987 + if ( nField >= 0 && nOrient == DataPilotFieldOrientation_PAGE )
9989 BOOL bIsDataLayout = FALSE;
9990 String aFieldName = pDPObj->GetDimName( nField, bIsDataLayout );
9991 if ( aFieldName.Len() && !bIsDataLayout )
9992 - return TRUE;
9993 + return DataPilotFieldOrientation_PAGE;
9996 - return FALSE;
9998 + nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
10000 + // Now, check for row/column field.
10001 + long nField = pDPObj->GetHeaderDim(ScAddress(nCol, nRow, nTab), nOrient);
10002 + if (nField >= 0 && (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW) )
10004 + BOOL bIsDataLayout = FALSE;
10005 + String aFieldName = pDPObj->GetDimName(nField, bIsDataLayout);
10006 + if (aFieldName.Len() && !bIsDataLayout)
10007 + return static_cast<DataPilotFieldOrientation>(nOrient);
10010 + return DataPilotFieldOrientation_HIDDEN;
10013 // private method for mouse button handling
10014 BOOL ScGridWindow::DoPageFieldSelection( SCCOL nCol, SCROW nRow )
10016 - if ( HasPageFieldData( nCol, nRow ) )
10017 + if (GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE)
10019 - DoPageFieldMenue( nCol, nRow );
10020 + LaunchPageFieldMenu( nCol, nRow );
10021 return TRUE;
10023 return FALSE;
10026 +bool ScGridWindow::DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt )
10028 + ScDocument* pDoc = pViewData->GetDocument();
10029 + SCTAB nTab = pViewData->GetTabNo();
10030 + Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
10031 + Point aDiffPix = rMEvt.GetPosPixel();
10033 + aDiffPix -= aScrPos;
10034 + BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
10035 + if ( bLayoutRTL )
10036 + aDiffPix.X() = -aDiffPix.X();
10038 + long nSizeX, nSizeY;
10039 + pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
10040 + Size aScrSize(nSizeX-1, nSizeY-1);
10042 + // Check if the mouse cursor is clicking on the popup arrow box.
10043 + mpFilterButton.reset(new ScDPFieldButton(this, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY()));
10044 + mpFilterButton->setBoundingBox(aScrPos, aScrSize);
10045 + Point aPopupPos;
10046 + Size aPopupSize;
10047 + mpFilterButton->getPopupBoundingBox(aPopupPos, aPopupSize);
10048 + Rectangle aRec(aPopupPos, aPopupSize);
10049 + if (aRec.IsInside(rMEvt.GetPosPixel()))
10051 + if ( DoPageFieldSelection( nCol, nRow ) )
10052 + return true;
10054 + bool bFilterActive = IsAutoFilterActive(nCol, nRow, nTab);
10055 + mpFilterButton->setHasHiddenMember(bFilterActive);
10056 + mpFilterButton->setDrawBaseButton(false);
10057 + mpFilterButton->setDrawPopupButton(true);
10058 + mpFilterButton->setPopupPressed(true);
10059 + HideCursor();
10060 + mpFilterButton->draw();
10061 + ShowCursor();
10062 + DoAutoFilterMenue(nCol, nRow, false);
10063 + return true;
10066 + return false;
10069 void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt )
10071 ScDocument* pDoc = pViewData->GetDocument();
10072 @@ -114,6 +190,15 @@ void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt
10073 bDPMouse = TRUE;
10074 nDPField = nField;
10075 pDragDPObj = pDPObj;
10077 + if (DPTestFieldPopupArrow(rMEvt, aPos, pDPObj))
10078 + {
10079 + // field name pop up menu has been launched. Don't activate
10080 + // field move.
10081 + bDPMouse = false;
10082 + return;
10085 DPTestMouse( rMEvt, TRUE );
10086 StartTracking();
10088 @@ -282,6 +367,223 @@ void ScGridWindow::DPTestMouse( const MouseEvent& rMEvt, BOOL bMove )
10089 pViewData->GetView()->ResetTimer();
10092 +bool ScGridWindow::DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj)
10094 + // Get the geometry of the cell.
10095 + Point aScrPos = pViewData->GetScrPos(rPos.Col(), rPos.Row(), eWhich);
10096 + long nSizeX, nSizeY;
10097 + pViewData->GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeX, nSizeY);
10098 + Size aScrSize(nSizeX-1, nSizeY-1);
10100 + // Check if the mouse cursor is clicking on the popup arrow box.
10101 + ScDPFieldButton aBtn(this, &GetSettings().GetStyleSettings());
10102 + aBtn.setBoundingBox(aScrPos, aScrSize);
10103 + Point aPopupPos;
10104 + Size aPopupSize;
10105 + aBtn.getPopupBoundingBox(aPopupPos, aPopupSize);
10106 + Rectangle aRec(aPopupPos, aPopupSize);
10107 + if (aRec.IsInside(rMEvt.GetPosPixel()))
10109 + // Mouse cursor inside the popup arrow box. Launch the field menu.
10110 + DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, rPos, pDPObj);
10111 + return true;
10114 + return false;
10117 +namespace {
10119 +struct DPFieldPopupData : public ScDPFieldPopupWindow::ExtendedData
10121 + ScPivotParam maDPParam;
10122 + ScDPObject* mpDPObj;
10123 + long mnDim;
10126 +class DPFieldPopupOKAction : public ScMenuFloatingWindow::Action
10128 +public:
10129 + explicit DPFieldPopupOKAction(ScGridWindow* p) :
10130 + mpGridWindow(p) {}
10132 + virtual void execute()
10134 + mpGridWindow->UpdateDPFromFieldPopupMenu();
10136 +private:
10137 + ScGridWindow* mpGridWindow;
10140 +class PopupSortAction : public ScMenuFloatingWindow::Action
10142 +public:
10143 + enum SortType { ASCENDING, DESCENDING, CUSTOM };
10145 + explicit PopupSortAction(const ScAddress& rPos, SortType eType, sal_uInt16 nUserListIndex, ScTabViewShell* pViewShell) :
10146 + maPos(rPos), meType(eType), mnUserListIndex(nUserListIndex), mpViewShell(pViewShell) {}
10148 + virtual void execute()
10150 + switch (meType)
10152 + case ASCENDING:
10153 + mpViewShell->DataPilotSort(maPos, true);
10154 + break;
10155 + case DESCENDING:
10156 + mpViewShell->DataPilotSort(maPos, false);
10157 + break;
10158 + case CUSTOM:
10159 + mpViewShell->DataPilotSort(maPos, true, &mnUserListIndex);
10160 + break;
10161 + default:
10166 +private:
10167 + ScAddress maPos;
10168 + SortType meType;
10169 + sal_uInt16 mnUserListIndex;
10170 + ScTabViewShell* mpViewShell;
10175 +void ScGridWindow::DPLaunchFieldPopupMenu(
10176 + const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj)
10178 + // We need to get the list of field members.
10179 + auto_ptr<DPFieldPopupData> pDPData(new DPFieldPopupData);
10180 + pDPObj->FillLabelData(pDPData->maDPParam);
10181 + pDPData->mpDPObj = pDPObj;
10183 + USHORT nOrient;
10184 + pDPData->mnDim = pDPObj->GetHeaderDim(rPos, nOrient);
10186 + if (pDPData->maDPParam.maLabelArray.size() <= static_cast<size_t>(pDPData->mnDim))
10187 + // out-of-bound dimension ID. This should never happen!
10188 + return;
10190 + const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim];
10192 + mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this, pViewData->GetDocument()));
10193 + mpDPFieldPopup->setName(OUString::createFromAscii("DataPilot field member popup"));
10194 + mpDPFieldPopup->setExtendedData(pDPData.release());
10195 + mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this));
10197 + // Populate field members.
10198 + size_t n = rLabelData.maMembers.size();
10199 + mpDPFieldPopup->setMemberSize(n);
10200 + for (size_t i = 0; i < n; ++i)
10202 + const ScDPLabelData::Member& rMem = rLabelData.maMembers[i];
10203 + mpDPFieldPopup->addMember(rMem.getDisplayName(), rMem.mbVisible);
10205 + mpDPFieldPopup->initMembers();
10208 + vector<OUString> aUserSortNames;
10209 + ScUserList* pUserList = ScGlobal::GetUserList();
10210 + if (pUserList)
10212 + sal_uInt16 n = pUserList->GetCount();
10213 + aUserSortNames.reserve(n);
10214 + for (sal_uInt16 i = 0; i < n; ++i)
10216 + ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[i]);
10217 + aUserSortNames.push_back(pData->GetString());
10221 + // Populate the menus.
10222 + ScTabViewShell* pViewShell = pViewData->GetViewShell();
10223 + mpDPFieldPopup->addMenuItem(
10224 + ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_ASC).GetString(), true,
10225 + new PopupSortAction(rPos, PopupSortAction::ASCENDING, 0, pViewShell));
10226 + mpDPFieldPopup->addMenuItem(
10227 + ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_DESC).GetString(), true,
10228 + new PopupSortAction(rPos, PopupSortAction::DESCENDING, 0, pViewShell));
10229 + ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem(
10230 + ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_CUSTOM).GetString(), !aUserSortNames.empty());
10232 + if (pSubMenu && !aUserSortNames.empty())
10234 + size_t n = aUserSortNames.size();
10235 + for (size_t i = 0; i < n; ++i)
10236 + {
10237 + pSubMenu->addMenuItem(
10238 + aUserSortNames[i], true,
10239 + new PopupSortAction(rPos, PopupSortAction::CUSTOM, i, pViewShell));
10243 + Rectangle aCellRect(rScrPos, rScrSize);
10244 + const Size& rPopupSize = mpDPFieldPopup->getWindowSize();
10245 + if (rScrSize.getWidth() > rPopupSize.getWidth())
10247 + // If the cell width is larger than the popup window width, launch it
10248 + // right-aligned with the cell.
10249 + long nXOffset = rScrSize.getWidth() - rPopupSize.getWidth();
10250 + aCellRect.SetPos(Point(rScrPos.X() + nXOffset, rScrPos.Y()));
10252 + mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) );
10253 + mpDPFieldPopup->StartPopupMode(aCellRect, (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_GRABFOCUS));
10256 +void ScGridWindow::UpdateDPFromFieldPopupMenu()
10258 + typedef hash_map<OUString, OUString, OUStringHash> MemNameMapType;
10259 + typedef hash_map<OUString, bool, OUStringHash> MemVisibilityType;
10261 + if (!mpDPFieldPopup.get())
10262 + return;
10264 + DPFieldPopupData* pDPData = static_cast<DPFieldPopupData*>(mpDPFieldPopup->getExtendedData());
10265 + if (!pDPData)
10266 + return;
10268 + ScDPObject* pDPObj = pDPData->mpDPObj;
10269 + ScDPObject aNewDPObj(*pDPObj);
10270 + aNewDPObj.BuildAllDimensionMembers();
10271 + ScDPSaveData* pSaveData = aNewDPObj.GetSaveData();
10273 + BOOL bIsDataLayout;
10274 + String aDimName = pDPObj->GetDimName(pDPData->mnDim, bIsDataLayout);
10275 + ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(aDimName);
10276 + if (!pDim)
10277 + return;
10279 + // Build a map of layout names to original names.
10280 + const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim];
10281 + MemNameMapType aMemNameMap;
10282 + for (vector<ScDPLabelData::Member>::const_iterator itr = rLabelData.maMembers.begin(), itrEnd = rLabelData.maMembers.end();
10283 + itr != itrEnd; ++itr)
10284 + aMemNameMap.insert(MemNameMapType::value_type(itr->maLayoutName, itr->maName));
10286 + // The raw result may contain a mixture of layout names and original names.
10287 + MemVisibilityType aRawResult;
10288 + mpDPFieldPopup->getResult(aRawResult);
10290 + MemVisibilityType aResult;
10291 + for (MemVisibilityType::const_iterator itr = aRawResult.begin(), itrEnd = aRawResult.end(); itr != itrEnd; ++itr)
10293 + MemNameMapType::const_iterator itrNameMap = aMemNameMap.find(itr->first);
10294 + if (itrNameMap == aMemNameMap.end())
10295 + // This is an original member name. Use it as-is.
10296 + aResult.insert(MemVisibilityType::value_type(itr->first, itr->second));
10297 + else
10299 + // This is a layout name. Get the original member name and use it.
10300 + aResult.insert(MemVisibilityType::value_type(itrNameMap->second, itr->second));
10303 + pDim->UpdateMemberVisibility(aResult);
10305 + ScDBDocFunc aFunc(*pViewData->GetDocShell());
10306 + aFunc.DataPilotUpdate(pDPObj, &aNewDPObj, true, false);
10309 void ScGridWindow::DPMouseMove( const MouseEvent& rMEvt )
10311 DPTestMouse( rMEvt, TRUE );
10312 diff --git sc/source/ui/view/gridwin4.cxx sc/source/ui/view/gridwin4.cxx
10313 index 76d6e02..1cd54a2 100644
10314 --- sc/source/ui/view/gridwin4.cxx
10315 +++ sc/source/ui/view/gridwin4.cxx
10316 @@ -73,6 +73,7 @@
10317 #include "editutil.hxx"
10318 #include "inputopt.hxx"
10319 #include "fillinfo.hxx"
10320 +#include "dpcontrol.hxx"
10321 #include "sc.hrc"
10322 #include <vcl/virdev.hxx>
10324 @@ -1203,6 +1204,8 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2
10326 aComboButton.SetOutputDevice( pContentDev );
10328 + ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY());
10330 SCCOL nCol;
10331 SCROW nRow;
10332 SCSIZE nArrY;
10333 @@ -1284,14 +1287,14 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2
10334 bool bArrowState = bSimpleQuery && bColumnFound;
10335 long nSizeX;
10336 long nSizeY;
10338 pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
10339 - aComboButton.SetOptSizePixel();
10340 - DrawComboButton( pViewData->GetScrPos( nCol, nRow, eWhich ),
10341 - nSizeX, nSizeY, bArrowState );
10342 + Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich );
10344 - aComboButton.SetPosPixel( aOldPos ); // alten Zustand
10345 - aComboButton.SetSizePixel( aOldSize ); // fuer MouseUp/Down
10346 + aCellBtn.setBoundingBox(aScrPos, Size(nSizeX-1, nSizeY-1));
10347 + aCellBtn.setDrawBaseButton(false);
10348 + aCellBtn.setDrawPopupButton(true);
10349 + aCellBtn.setHasHiddenMember(bArrowState);
10350 + aCellBtn.draw();
10354 @@ -1318,13 +1321,14 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2
10355 nPosX -= nSizeX - 2;
10358 - pContentDev->SetLineColor( GetSettings().GetStyleSettings().GetLightColor() );
10359 - pContentDev->DrawLine( Point(nPosX,nPosY), Point(nPosX,nPosY+nSizeY-1) );
10360 - pContentDev->DrawLine( Point(nPosX,nPosY), Point(nPosX+nSizeX-1,nPosY) );
10361 - pContentDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
10362 - pContentDev->DrawLine( Point(nPosX,nPosY+nSizeY-1), Point(nPosX+nSizeX-1,nPosY+nSizeY-1) );
10363 - pContentDev->DrawLine( Point(nPosX+nSizeX-1,nPosY), Point(nPosX+nSizeX-1,nPosY+nSizeY-1) );
10364 - pContentDev->SetLineColor( COL_BLACK );
10365 + String aStr;
10366 + pDoc->GetString(nCol, nRow, nTab, aStr);
10367 + aCellBtn.setText(aStr);
10368 + aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1));
10369 + aCellBtn.setDrawBaseButton(true);
10370 + aCellBtn.setDrawPopupButton(pInfo->bPopupButton);
10371 + aCellBtn.setHasHiddenMember(pInfo->bFilterActive);
10372 + aCellBtn.draw();
10376 diff --git sc/source/ui/view/tabview.cxx sc/source/ui/view/tabview.cxx
10377 index 917d7ff..925a2b7 100644
10378 --- sc/source/ui/view/tabview.cxx
10379 +++ sc/source/ui/view/tabview.cxx
10380 @@ -200,6 +200,8 @@
10381 #include "AccessibilityHints.hxx"
10382 #include "appoptio.hxx"
10384 +#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
10386 #include <string>
10387 #include <algorithm>
10389 @@ -212,6 +214,8 @@
10390 // fuer Rad-Maus
10391 #define SC_DELTA_ZOOM 10
10393 +using namespace ::com::sun::star;
10395 // STATIC DATA -----------------------------------------------------------
10398 @@ -2476,7 +2480,7 @@ sal_Bool ScTabView::HasPageFieldDataAtCursor() const
10399 SCCOL nCol = aViewData.GetCurX();
10400 SCROW nRow = aViewData.GetCurY();
10401 if (pWin)
10402 - return pWin->HasPageFieldData( nCol, nRow );
10403 + return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE;
10405 return sal_False;
10407 @@ -2486,15 +2490,23 @@ void ScTabView::StartDataSelect()
10408 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
10409 SCCOL nCol = aViewData.GetCurX();
10410 SCROW nRow = aViewData.GetCurY();
10411 - if (pWin)
10413 - // #i36598# If the cursor is on a page field's data cell,
10414 - // no meaningful input is possible anyway, so this function
10415 - // can be used to select a page field entry.
10417 - if ( pWin->HasPageFieldData( nCol, nRow ) )
10418 - pWin->DoPageFieldMenue( nCol, nRow );
10419 - else
10420 + if (!pWin)
10421 + return;
10423 + switch (pWin->GetDPFieldOrientation(nCol, nRow))
10425 + case sheet::DataPilotFieldOrientation_PAGE:
10426 + // #i36598# If the cursor is on a page field's data cell,
10427 + // no meaningful input is possible anyway, so this function
10428 + // can be used to select a page field entry.
10429 + pWin->LaunchPageFieldMenu( nCol, nRow );
10430 + break;
10431 + case sheet::DataPilotFieldOrientation_COLUMN:
10432 + case sheet::DataPilotFieldOrientation_ROW:
10433 + pWin->LaunchDPFieldMenu( nCol, nRow );
10434 + break;
10435 + default:
10436 pWin->DoAutoFilterMenue( nCol, nRow, TRUE );
10439 diff --git sc/util/makefile.mk sc/util/makefile.mk
10440 index 4fdc5ac..2b56e37 100644
10441 --- sc/util/makefile.mk
10442 +++ sc/util/makefile.mk
10443 @@ -58,6 +58,7 @@ RESLIB1LIST=\
10444 $(SRS)$/formdlgs.srs \
10445 $(SRS)$/pagedlg.srs \
10446 $(SRS)$/navipi.srs \
10447 + $(SRS)$/cctrl.srs \
10448 $(SOLARCOMMONRESDIR)$/sfx.srs
10450 RESLIB1NAME=sc