diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2012-12-12 19:05:31 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2012-12-14 01:12:41 -0500 |
commit | 1360b28b477f980a2c58659ffc298d0dd2cda20b (patch) | |
tree | 446e6c4aba4f8414687ebd884ea98ab983e475f4 | |
parent | 34b7826f9814b09dcd6aba15552bef1c330f3db2 (diff) |
bnc#791706: Support multiple selection in page fields.
This change allows selecting multiple items in page field popups in
pivot table.
Change-Id: I692e13c0815211bac6da47fefd83bba18c901c5c
28 files changed, 394 insertions, 408 deletions
diff --git a/sc/inc/attrib.hxx b/sc/inc/attrib.hxx index 5706b273afe0..9b12f085955a 100644 --- a/sc/inc/attrib.hxx +++ b/sc/inc/attrib.hxx @@ -94,10 +94,12 @@ public: bool IsOverlapped() const { return ( GetValue() & ( SC_MF_HOR | SC_MF_VER ) ) != 0; } bool HasAutoFilter() const { return ( GetValue() & SC_MF_AUTO ) != 0; } - bool HasButton() const { return ( GetValue() & SC_MF_BUTTON ) != 0; } bool HasDPTable() const { return ( GetValue() & SC_MF_DP_TABLE ) != 0; } bool IsScenario() const { return ( GetValue() & SC_MF_SCENARIO ) != 0; } + + bool HasPivotButton() const; + bool HasPivotPopupButton() const; }; //------------------------------------------------------------------------ diff --git a/sc/inc/dpoutputgeometry.hxx b/sc/inc/dpoutputgeometry.hxx index 4cc254a4081a..e275cd87d947 100644 --- a/sc/inc/dpoutputgeometry.hxx +++ b/sc/inc/dpoutputgeometry.hxx @@ -28,7 +28,7 @@ class ScAddress; class SC_DLLPUBLIC ScDPOutputGeometry { public: - enum FieldType { Column, Row, Page, Data, None }; + enum FieldType { Column = 0, Row, Page, Data, None }; ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter); ~ScDPOutputGeometry(); @@ -40,6 +40,7 @@ public: void setColumnFieldCount(sal_uInt32 nCount); void setPageFieldCount(sal_uInt32 nCount); void setDataFieldCount(sal_uInt32 nCount); + void setDataLayoutType(FieldType eType); void getColumnFieldPositions(::std::vector<ScAddress>& rAddrs) const; void getRowFieldPositions(::std::vector<ScAddress>& rAddrs) const; @@ -52,13 +53,15 @@ public: private: ScDPOutputGeometry(); // disabled + void adjustFieldsForDataLayout(sal_uInt32& rColumnFields, sal_uInt32& rRowFields) const; + private: ScRange maOutRange; sal_uInt32 mnRowFields; /// number of row fields sal_uInt32 mnColumnFields; sal_uInt32 mnPageFields; sal_uInt32 mnDataFields; - + FieldType meDataLayoutType; bool mbShowFilter; }; diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx index 948117b90180..5bca23b4d939 100644 --- a/sc/inc/dpsave.hxx +++ b/sc/inc/dpsave.hxx @@ -197,8 +197,6 @@ public: void SetLayoutInfo(const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pNew); void SetCurrentPage( const ::rtl::OUString* pPage ); // NULL = no selection (all) - bool HasCurrentPage() const; - const ::rtl::OUString& GetCurrentPage() const; sal_uInt16 GetOrientation() const { return nOrientation; } diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx index 458953d80caf..23d0f9b94d34 100644 --- a/sc/inc/fillinfo.hxx +++ b/sc/inc/fillinfo.hxx @@ -123,8 +123,8 @@ struct CellInfo sal_Bool bHOverlapped : 1; sal_Bool bVOverlapped : 1; sal_Bool bAutoFilter : 1; - sal_Bool bPushButton : 1; - bool bPopupButton: 1; + bool bPivotButton:1; + bool bPivotPopupButton:1; bool bFilterActive:1; sal_Bool bPrinted : 1; // when required (pagebreak mode) @@ -155,11 +155,11 @@ struct RowInfo SCROW nRowNo; SCCOL nRotMaxCol; // SC_ROTMAX_NONE, if nothing - sal_Bool bEmptyBack; - sal_Bool bEmptyText; - sal_Bool bAutoFilter; - sal_Bool bPushButton; - sal_Bool bChanged; // TRUE, if not tested + bool bEmptyBack:1; + bool bEmptyText:1; + bool bAutoFilter:1; + bool bPivotButton:1; + bool bChanged:1; // TRUE, if not tested inline explicit RowInfo() : pCellInfo( 0 ) {} diff --git a/sc/inc/miscuno.hxx b/sc/inc/miscuno.hxx index de953af08cc7..646d2613d294 100644 --- a/sc/inc/miscuno.hxx +++ b/sc/inc/miscuno.hxx @@ -188,6 +188,15 @@ public: any <<= rVal; SetOptionalPropertyValue(rPropSet, pPropName, any); } + + template<typename ValueType> + static com::sun::star::uno::Sequence<ValueType> VectorToSequence( const std::vector<ValueType>& rVector ) + { + if (rVector.empty()) + return com::sun::star::uno::Sequence<ValueType>(); + + return com::sun::star::uno::Sequence<ValueType>(&rVector[0], static_cast<sal_Int32>(rVector.size())); + } }; diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index 19ad415e129a..2849c9fd53e9 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -755,6 +755,7 @@ #define SCSTR_COLUMN_USER (STR_START + 60) #define SCSTR_FIELDSEP (STR_START + 61) #define SCSTR_TEXTSEP (STR_START + 62) +#define SCSTR_MULTIPLE (STR_START + 63) #define SCSTR_CFG_INPUT (STR_START + 65) diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 842a13cc19ff..2f3290aac5c8 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -2115,6 +2115,7 @@ void Test::testPivotTableFilters() CPPUNIT_ASSERT_MESSAGE("Incorrect formula value that references a cell in the pivot table output.", fTest == 80.0); // Set current page of 'Group2' to 'A'. + pDPObj->BuildAllDimensionMembers(); ScDPSaveData aSaveData(*pDPObj->GetSaveData()); ScDPSaveDimension* pPageDim = aSaveData.GetDimensionByName( OUString("Group2")); diff --git a/sc/source/core/data/attrib.cxx b/sc/source/core/data/attrib.cxx index bd179613f7a1..8bb813a0a81c 100644 --- a/sc/source/core/data/attrib.cxx +++ b/sc/source/core/data/attrib.cxx @@ -184,6 +184,16 @@ ScMergeFlagAttr::~ScMergeFlagAttr() { } +bool ScMergeFlagAttr::HasPivotButton() const +{ + return (GetValue() & SC_MF_BUTTON) != 0; +} + +bool ScMergeFlagAttr::HasPivotPopupButton() const +{ + return (GetValue() & SC_MF_BUTTON_POPUP) != 0; +} + //------------------------------------------------------------------------ // Protection //------------------------------------------------------------------------ diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 0c835cf687b6..e55a9c864422 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -810,7 +810,7 @@ const ScRange ScDPObject::GetOutputRangeByType( sal_Int32 nType ) static sal_Bool lcl_HasButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab ) { - return ((const ScMergeFlagAttr*)pDoc->GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->HasButton(); + return ((const ScMergeFlagAttr*)pDoc->GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->HasPivotButton(); } void ScDPObject::RefreshAfterLoad() @@ -833,12 +833,6 @@ void ScDPObject::RefreshAfterLoad() pDoc->IsBlockEmpty( nTab, nFirstCol, nFirstRow + nInitial, nFirstCol, nFirstRow + nInitial ) && aOutRange.aEnd.Col() > nFirstCol ) { - sal_Bool bFilterButton = IsSheetData(); // when available, filter button setting must be checked here - - SCROW nSkip = bFilterButton ? 1 : 0; - for (SCROW nPos=nSkip; nPos<nInitial; nPos++) - pDoc->ApplyAttr( nFirstCol + 1, nFirstRow + nPos, nTab, ScMergeFlagAttr(SC_MF_AUTO) ); - nHeaderRows = nInitial; } else diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx index 5038d43c65f6..1a3022d6d82e 100644 --- a/sc/source/core/data/dpoutput.cxx +++ b/sc/source/core/data/dpoutput.cxx @@ -86,9 +86,10 @@ struct ScDPOutLevelData rtl::OUString maCaption; /// Caption is the name visible in the output table. bool mbHasHiddenMember:1; bool mbDataLayout:1; + bool mbPageDim:1; ScDPOutLevelData() : - nDim(-1), nHier(-1), nLevel(-1), nDimPos(-1), mbHasHiddenMember(false), mbDataLayout(false) + nDim(-1), nHier(-1), nLevel(-1), nDimPos(-1), mbHasHiddenMember(false), mbDataLayout(false), mbPageDim(false) {} bool operator<(const ScDPOutLevelData& r) const @@ -465,40 +466,49 @@ bool lcl_MemberEmpty( const uno::Sequence<sheet::MemberResult>& rSeq ) return true; // no member data -> empty } -uno::Sequence<sheet::MemberResult> lcl_GetSelectedPageAsResult( const uno::Reference<beans::XPropertySet>& xDimProp ) +/** + * Get visible page dimension members as results, except that, if all + * members are visible, then this function returns empty result. + */ +uno::Sequence<sheet::MemberResult> getVisiblePageMembersAsResults( const uno::Reference<uno::XInterface>& xLevel ) { - uno::Sequence<sheet::MemberResult> aRet; - if ( xDimProp.is() ) + if (!xLevel.is()) + return uno::Sequence<sheet::MemberResult>(); + + uno::Reference<sheet::XMembersSupplier> xMSupplier(xLevel, UNO_QUERY); + if (!xMSupplier.is()) + return uno::Sequence<sheet::MemberResult>(); + + uno::Reference<container::XNameAccess> xNA = xMSupplier->getMembers(); + if (!xNA.is()) + return uno::Sequence<sheet::MemberResult>(); + + std::vector<sheet::MemberResult> aRes; + uno::Sequence<OUString> aNames = xNA->getElementNames(); + for (sal_Int32 i = 0; i < aNames.getLength(); ++i) { - try - { - //! merge with ScDPDimension::setPropertyValue? + const OUString& rName = aNames[i]; + xNA->getByName(rName); - uno::Any aValue = xDimProp->getPropertyValue( rtl::OUString(SC_UNO_DP_FILTER) ); + uno::Reference<beans::XPropertySet> xMemPS(xNA->getByName(rName), UNO_QUERY); + if (!xMemPS.is()) + continue; - uno::Sequence<sheet::TableFilterField> aSeq; - if (aValue >>= aSeq) - { - if ( aSeq.getLength() == 1 ) - { - const sheet::TableFilterField& rField = aSeq[0]; - if ( rField.Field == 0 && rField.Operator == sheet::FilterOperator_EQUAL && !rField.IsNumeric ) - { - rtl::OUString aSelectedPage( rField.StringValue ); - //! different name/caption string? - sheet::MemberResult aResult( aSelectedPage, aSelectedPage, 0 ); - aRet = uno::Sequence<sheet::MemberResult>( &aResult, 1 ); - } - } - // else return empty sequence - } - } - catch ( uno::Exception& ) - { - // recent addition - allow source to not handle it (no error) - } + OUString aCaption = ScUnoHelpFunctions::GetStringProperty(xMemPS, SC_UNO_DP_LAYOUTNAME, OUString()); + if (aCaption.isEmpty()) + aCaption = rName; + + bool bVisible = ScUnoHelpFunctions::GetBoolProperty(xMemPS, SC_UNO_DP_ISVISIBLE, false); + + if (bVisible) + aRes.push_back(sheet::MemberResult(rName, aCaption, 0)); } - return aRet; + + if (aNames.getLength() == static_cast<sal_Int32>(aRes.size())) + // All members are visible. Return empty result. + return uno::Sequence<sheet::MemberResult>(); + + return ScUnoHelpFunctions::VectorToSequence(aRes); } } @@ -631,10 +641,11 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS pPageFields[nPageFieldCount].nHier = nHierarchy; pPageFields[nPageFieldCount].nLevel = nLev; pPageFields[nPageFieldCount].nDimPos = nDimPos; - pPageFields[nPageFieldCount].aResult = lcl_GetSelectedPageAsResult(xDimProp); + pPageFields[nPageFieldCount].aResult = getVisiblePageMembersAsResults(xLevel); pPageFields[nPageFieldCount].maName = aName; pPageFields[nPageFieldCount].maCaption= aCaption; pPageFields[nPageFieldCount].mbHasHiddenMember = bHasHiddenMember; + pPageFields[nPageFieldCount].mbPageDim = true; // no check on results for page fields ++nPageFieldCount; break; @@ -824,13 +835,25 @@ void ScDPOutput::FieldCell( if (bInTable) lcl_SetFrame( pDoc,nTab, nCol,nRow, nCol,nRow, 20 ); - // Button - sal_uInt16 nMergeFlag = SC_MF_BUTTON; - if (!rData.mbDataLayout) - nMergeFlag |= SC_MF_BUTTON_POPUP; + // For field button drawing + sal_uInt16 nMergeFlag = 0; if (rData.mbHasHiddenMember) nMergeFlag |= SC_MF_HIDDEN_MEMBER; - pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, nMergeFlag); + + if (rData.mbPageDim) + { + nMergeFlag |= SC_MF_BUTTON_POPUP; + pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON); + pDoc->ApplyFlagsTab(nCol+1, nRow, nCol+1, nRow, nTab, nMergeFlag); + } + else + { + nMergeFlag |= SC_MF_BUTTON; + if (!rData.mbDataLayout) + nMergeFlag |= SC_MF_BUTTON_POPUP; + pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, nMergeFlag); + } + lcl_SetStyleById( pDoc,nTab, nCol,nRow, nCol,nRow, STR_PIVOT_STYLE_FIELDNAME ); } @@ -981,17 +1004,17 @@ void ScDPOutput::Output() FieldCell(nHdrCol, nHdrRow, nTab, pPageFields[nField], false); SCCOL nFldCol = nHdrCol + 1; - rtl::OUString aPageValue; - if ( pPageFields[nField].aResult.getLength() == 1 ) - aPageValue = pPageFields[nField].aResult[0].Caption; - else - aPageValue = SC_RESSTR(SCSTR_ALL); //! separate string? + OUString aPageValue = ScResId(SCSTR_ALL).toString(); + const uno::Sequence<sheet::MemberResult>& rRes = pPageFields[nField].aResult; + sal_Int32 n = rRes.getLength(); + if (n == 1) + aPageValue = rRes[0].Caption; + else if (n > 1) + aPageValue = ScResId(SCSTR_MULTIPLE).toString(); pDoc->SetString( nFldCol, nHdrRow, nTab, aPageValue ); lcl_SetFrame( pDoc,nTab, nFldCol,nHdrRow, nFldCol,nHdrRow, 20 ); - pDoc->ApplyAttr( nFldCol, nHdrRow, nTab, ScMergeFlagAttr(SC_MF_AUTO) ); - //! which style? } // data description diff --git a/sc/source/core/data/dpoutputgeometry.cxx b/sc/source/core/data/dpoutputgeometry.cxx index 25b44099f94d..fe8947aa5d3d 100644 --- a/sc/source/core/data/dpoutputgeometry.cxx +++ b/sc/source/core/data/dpoutputgeometry.cxx @@ -30,6 +30,7 @@ ScDPOutputGeometry::ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilte mnColumnFields(0), mnPageFields(0), mnDataFields(0), + meDataLayoutType(None), mbShowFilter(bShowFilter) { } @@ -58,10 +59,18 @@ void ScDPOutputGeometry::setDataFieldCount(sal_uInt32 nCount) mnDataFields = nCount; } +void ScDPOutputGeometry::setDataLayoutType(FieldType eType) +{ + meDataLayoutType = eType; +} + void ScDPOutputGeometry::getColumnFieldPositions(vector<ScAddress>& rAddrs) const { + sal_uInt32 nColumnFields, nRowFields; + adjustFieldsForDataLayout(nColumnFields, nRowFields); + vector<ScAddress> aAddrs; - if (!mnColumnFields) + if (!nColumnFields) { rAddrs.swap(aAddrs); return; @@ -80,8 +89,8 @@ void ScDPOutputGeometry::getColumnFieldPositions(vector<ScAddress>& rAddrs) cons SCROW nRow = nCurRow; SCTAB nTab = maOutRange.aStart.Tab(); - SCCOL nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + mnRowFields); - SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnColumnFields-1); + SCCOL nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + nRowFields); + SCCOL nColEnd = nColStart + static_cast<SCCOL>(nColumnFields-1); for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol) aAddrs.push_back(ScAddress(nCol, nRow, nTab)); @@ -90,8 +99,11 @@ void ScDPOutputGeometry::getColumnFieldPositions(vector<ScAddress>& rAddrs) cons void ScDPOutputGeometry::getRowFieldPositions(vector<ScAddress>& rAddrs) const { + sal_uInt32 nColumnFields, nRowFields; + adjustFieldsForDataLayout(nColumnFields, nRowFields); + vector<ScAddress> aAddrs; - if (!mnRowFields) + if (!nRowFields) { rAddrs.swap(aAddrs); return; @@ -100,7 +112,7 @@ void ScDPOutputGeometry::getRowFieldPositions(vector<ScAddress>& rAddrs) const SCROW nRow = getRowFieldHeaderRow(); SCTAB nTab = maOutRange.aStart.Tab(); SCCOL nColStart = maOutRange.aStart.Col(); - SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnRowFields-1); + SCCOL nColEnd = nColStart + static_cast<SCCOL>(nRowFields-1); for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol) aAddrs.push_back(ScAddress(nCol, nRow, nTab)); @@ -130,6 +142,8 @@ void ScDPOutputGeometry::getPageFieldPositions(vector<ScAddress>& rAddrs) const SCROW ScDPOutputGeometry::getRowFieldHeaderRow() const { SCROW nCurRow = maOutRange.aStart.Row(); + sal_uInt32 nColumnFields, nRowFields; + adjustFieldsForDataLayout(nColumnFields, nRowFields); if (mnPageFields) { @@ -140,20 +154,43 @@ SCROW ScDPOutputGeometry::getRowFieldHeaderRow() const else if (mbShowFilter) nCurRow += 2; - if (mnColumnFields) - nCurRow += static_cast<SCROW>(mnColumnFields); - else if (mnRowFields) + if (nColumnFields) + nCurRow += static_cast<SCROW>(nColumnFields); + else if (nRowFields) ++nCurRow; return nCurRow; } +void ScDPOutputGeometry::adjustFieldsForDataLayout(sal_uInt32& rColumnFields, sal_uInt32& rRowFields) const +{ + rRowFields = mnRowFields; + rColumnFields = mnColumnFields; + + if (mnDataFields < 2) + { + // Data layout field can be either row or column field, never page field. + switch (meDataLayoutType) + { + case Column: + if (rColumnFields > 0) + rColumnFields -= 1; + break; + case Row: + if (rRowFields > 0) + rRowFields -= 1; + default: + ; + } + } +} + std::pair<ScDPOutputGeometry::FieldType, size_t> ScDPOutputGeometry::getFieldButtonType(const ScAddress& rPos) const { - // We will ignore the table position for now. - SCROW nCurRow = maOutRange.aStart.Row(); + sal_uInt32 nColumnFields, nRowFields; + adjustFieldsForDataLayout(nColumnFields, nRowFields); if (mnPageFields) { @@ -171,26 +208,26 @@ ScDPOutputGeometry::getFieldButtonType(const ScAddress& rPos) const else if (mbShowFilter) nCurRow += 2; - if (mnColumnFields) + if (nColumnFields) { SCROW nRow = nCurRow; - SCCOL nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + mnRowFields); - SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnColumnFields-1); + SCCOL nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + nRowFields); + SCCOL nColEnd = nColStart + static_cast<SCCOL>(nColumnFields-1); if (rPos.Row() == nRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd) { size_t nPos = static_cast<size_t>(rPos.Col() - nColStart); return std::pair<FieldType, size_t>(Column, nPos); } - nCurRow += static_cast<SCROW>(mnColumnFields); + nCurRow += static_cast<SCROW>(nColumnFields); } else ++nCurRow; - if (mnRowFields) + if (nRowFields) { SCCOL nColStart = maOutRange.aStart.Col(); - SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnRowFields-1); + SCCOL nColEnd = nColStart + static_cast<SCCOL>(nRowFields-1); if (rPos.Row() == nCurRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd) { size_t nPos = static_cast<size_t>(rPos.Col() - nColStart); diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx index 5fcd8d79313b..981eace3e908 100644 --- a/sc/source/core/data/dpsave.cxx +++ b/sc/source/core/data/dpsave.cxx @@ -171,7 +171,6 @@ void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMemb ScDPSaveDimension::ScDPSaveDimension(const ::rtl::OUString& rName, bool bDataLayout) : aName( rName ), - pSelectedPage( NULL ), mpLayoutName(NULL), mpSubtotalName(NULL), bIsDataLayout( bDataLayout ), @@ -234,10 +233,6 @@ ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) : pLayoutInfo = new sheet::DataPilotFieldLayoutInfo( *(r.pLayoutInfo) ); else pLayoutInfo = NULL; - if (r.pSelectedPage) - pSelectedPage = new ::rtl::OUString( *(r.pSelectedPage) ); - else - pSelectedPage = NULL; if (r.mpLayoutName) mpLayoutName.reset(new OUString(*r.mpLayoutName)); if (r.mpSubtotalName) @@ -252,7 +247,6 @@ ScDPSaveDimension::~ScDPSaveDimension() delete pSortInfo; delete pAutoShowInfo; delete pLayoutInfo; - delete pSelectedPage; delete [] pSubTotalFuncs; } @@ -286,17 +280,6 @@ bool ScDPSaveDimension::operator== ( const ScDPSaveDimension& r ) const if (!(**a == **b)) return false; - if ( this->HasCurrentPage() && r.HasCurrentPage() ) - { - if ( this->GetCurrentPage() != r.GetCurrentPage() ) - { - return false; - } - } - else if ( this->HasCurrentPage() || r.HasCurrentPage() ) - { - return false; - } if( pReferenceValue && r.pReferenceValue ) { if ( !(*pReferenceValue == *r.pReferenceValue) ) @@ -486,24 +469,16 @@ void ScDPSaveDimension::SetLayoutInfo(const sheet::DataPilotFieldLayoutInfo* pNe void ScDPSaveDimension::SetCurrentPage( const ::rtl::OUString* pPage ) { - delete pSelectedPage; - if (pPage) - pSelectedPage = new ::rtl::OUString( *pPage ); - else - pSelectedPage = NULL; -} + // We use member's visibility attribute to filter by page dimension. -bool ScDPSaveDimension::HasCurrentPage() const -{ - return ( pSelectedPage != NULL ); -} - -const ::rtl::OUString& ScDPSaveDimension::GetCurrentPage() const -{ - static const ::rtl::OUString emptyOUString = ::rtl::OUString(); - if (pSelectedPage) - return *pSelectedPage; - return emptyOUString; + // pPage == NULL -> all members visible. + MemberList::iterator it = maMemberList.begin(), itEnd = maMemberList.end(); + for (; it != itEnd; ++it) + { + ScDPSaveMember* pMem = *it; + bool bVisible = !pPage || pMem->GetName() == *pPage; + pMem->SetIsVisible(bVisible); + } } ScDPSaveMember* ScDPSaveDimension::GetExistingMemberByName(const ::rtl::OUString& rName) @@ -567,18 +542,6 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD xDimProp->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_REFVALUE)), aAny ); } - uno::Sequence<sheet::TableFilterField> aFilter; - // set the selected page field only if the dimension is used as page dimension - if ( pSelectedPage && nOrientation == sheet::DataPilotFieldOrientation_PAGE ) - { - // single filter field: first field equal to selected string - sheet::TableFilterField aField( sheet::FilterConnection_AND, 0, - sheet::FilterOperator_EQUAL, false, 0.0, *pSelectedPage ); - aFilter = uno::Sequence<sheet::TableFilterField>( &aField, 1 ); - } - // else keep empty sequence - - ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_FILTER, aFilter); if (mpLayoutName) ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_DP_LAYOUTNAME, *mpLayoutName); diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx index 9856d29f109f..d9501646c282 100644 --- a/sc/source/core/data/fillinfo.cxx +++ b/sc/source/core/data/fillinfo.cxx @@ -241,7 +241,7 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX pThisRowInfo->bEmptyText = true; pThisRowInfo->bChanged = true; pThisRowInfo->bAutoFilter = false; - pThisRowInfo->bPushButton = false; + pThisRowInfo->bPivotButton = false; pThisRowInfo->nRotMaxCol = SC_ROTMAX_NONE; ++nArrY; @@ -317,8 +317,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX pInfo->bHOverlapped = false; pInfo->bVOverlapped = false; pInfo->bAutoFilter = false; - pInfo->bPushButton = false; - pInfo->bPopupButton = false; + pInfo->bPivotButton = false; + pInfo->bPivotPopupButton = false; pInfo->bFilterActive = false; pInfo->nRotateDir = SC_ROTDIR_NONE; @@ -453,9 +453,9 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX bool bHOverlapped = ((nOverlap & SC_MF_HOR) != 0); bool bVOverlapped = ((nOverlap & SC_MF_VER) != 0); bool bAutoFilter = ((nOverlap & SC_MF_AUTO) != 0); - bool bPushButton = ((nOverlap & SC_MF_BUTTON) != 0); + bool bPivotButton = ((nOverlap & SC_MF_BUTTON) != 0); bool bScenario = ((nOverlap & SC_MF_SCENARIO) != 0); - bool bPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0); + bool bPivotPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0); bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0); if (bMerged||bHOverlapped||bVOverlapped) bAnyMerged = true; // intern @@ -487,8 +487,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX pThisRowInfo->bEmptyBack = false; if (bAutoFilter) pThisRowInfo->bAutoFilter = true; - if (bPushButton) - pThisRowInfo->bPushButton = true; + if (bPivotButton || bPivotPopupButton) + pThisRowInfo->bPivotButton = true; CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX]; pInfo->pBackground = pBackground; @@ -497,8 +497,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX pInfo->bHOverlapped = bHOverlapped; pInfo->bVOverlapped = bVOverlapped; pInfo->bAutoFilter = bAutoFilter; - pInfo->bPushButton = bPushButton; - pInfo->bPopupButton = bPopupButton; + pInfo->bPivotButton = bPivotButton; + pInfo->bPivotPopupButton = bPivotPopupButton; pInfo->bFilterActive = bFilterActive; pInfo->pLinesAttr = pLinesAttr; pInfo->mpTLBRLine = pTLBRLine; diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx index ec58f5874272..7db32451f825 100644 --- a/sc/source/filter/excel/xepivot.cxx +++ b/sc/source/filter/excel/xepivot.cxx @@ -1136,12 +1136,7 @@ void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim ) if( eOrient == DataPilotFieldOrientation_PAGE ) { maPageInfo.mnField = GetFieldIndex(); - - // selected item - if( rSaveDim.HasCurrentPage() ) - maPageInfo.mnSelItem = GetItemIndex( rSaveDim.GetCurrentPage(), EXC_SXPI_ALLITEMS ); - else - maPageInfo.mnSelItem = EXC_SXPI_ALLITEMS; + maPageInfo.mnSelItem = EXC_SXPI_ALLITEMS; } // item properties diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index 1ce17fbb6cc2..f20550207a89 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -1477,14 +1477,15 @@ void XclImpPivotTable::ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveD vector<ScAddress>::const_iterator itr = aFieldBtns.begin(), itrEnd = aFieldBtns.end(); for (; itr != itrEnd; ++itr) { - sal_uInt16 nMFlag = SC_MF_BUTTON; + rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), SC_MF_BUTTON); + + sal_uInt16 nMFlag = SC_MF_BUTTON_POPUP; rtl::OUString aName; rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName); if (rSaveData.HasInvisibleMember(aName)) nMFlag |= SC_MF_HIDDEN_MEMBER; - rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag); - rDoc.ApplyFlagsTab(itr->Col()+1, itr->Row(), itr->Col()+1, itr->Row(), itr->Tab(), SC_MF_AUTO); + rDoc.ApplyFlagsTab(itr->Col()+1, itr->Row(), itr->Col()+1, itr->Row(), itr->Tab(), nMFlag); } aGeometry.getColumnFieldPositions(aFieldBtns); diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx index 896f36c49317..fd0fd4754093 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.cxx +++ b/sc/source/filter/xml/XMLExportDataPilot.cxx @@ -692,9 +692,6 @@ void ScXMLExportDataPilot::WriteDimension(ScDPSaveDimension* pDim, const ScDPDim (sheet::DataPilotFieldOrientation) pDim->GetOrientation() ); if( !sValueStr.isEmpty() ) rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, sValueStr ); - if (pDim->GetOrientation() == sheet::DataPilotFieldOrientation_PAGE) - if (pDim->HasCurrentPage()) - rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, pDim->GetCurrentPage()); if (pDim->GetUsedHierarchy() != 1) { rtl::OUStringBuffer sBuffer; @@ -765,7 +762,7 @@ void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreads while (pAttr) { ScMergeFlagAttr& rItem = (ScMergeFlagAttr&)pAttr->GetItem(ATTR_MERGE_FLAG); - if (rItem.HasButton()) + if (rItem.HasPivotButton()) { for (SCROW nButtonRow = nRow1; nButtonRow <= nRow2; ++nButtonRow) { diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index 3b9cc4b7394f..229db29e6355 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -45,6 +45,7 @@ #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp> #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp> #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp> +#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> using namespace com::sun::star; using namespace xmloff::token; @@ -119,6 +120,7 @@ ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport, mnColFieldCount(0), mnPageFieldCount(0), mnDataFieldCount(0), + mnDataLayoutType(sheet::DataPilotFieldOrientation_HIDDEN), bIsNative(true), bIgnoreEmptyRows(false), bIdentifyCategories(false), @@ -284,6 +286,7 @@ namespace { const ScDPSaveDimension* getDimension( const std::vector<const ScDPSaveDimension*>& rRowDims, const std::vector<const ScDPSaveDimension*>& rColDims, + const std::vector<const ScDPSaveDimension*>& rPageDims, ScDPOutputGeometry::FieldType eType, size_t nPos) { switch (eType) @@ -302,12 +305,43 @@ const ScDPSaveDimension* getDimension( return rRowDims[nPos]; } + case ScDPOutputGeometry::Page: + { + if (rPageDims.size() <= nPos) + return NULL; + + return rPageDims[nPos]; + } + break; + case ScDPOutputGeometry::Data: + break; + case ScDPOutputGeometry::None: + break; default: ; } return NULL; } +ScDPOutputGeometry::FieldType toFieldType(sal_uInt16 nOrient) +{ + switch (nOrient) + { + case sheet::DataPilotFieldOrientation_COLUMN: + return ScDPOutputGeometry::Column; + case sheet::DataPilotFieldOrientation_DATA: + return ScDPOutputGeometry::Data; + case sheet::DataPilotFieldOrientation_PAGE: + return ScDPOutputGeometry::Page; + case sheet::DataPilotFieldOrientation_ROW: + return ScDPOutputGeometry::Row; + case sheet::DataPilotFieldOrientation_HIDDEN: + default: + ; + } + return ScDPOutputGeometry::None; +} + } void ScXMLDataPilotTableContext::SetButtons() @@ -317,10 +351,12 @@ void ScXMLDataPilotTableContext::SetButtons() aGeometry.setRowFieldCount(mnRowFieldCount); aGeometry.setPageFieldCount(mnPageFieldCount); aGeometry.setDataFieldCount(mnDataFieldCount); + aGeometry.setDataLayoutType(toFieldType(mnDataLayoutType)); - std::vector<const ScDPSaveDimension*> aRowDims, aColDims; + std::vector<const ScDPSaveDimension*> aRowDims, aColDims, aPageDims; pDPSave->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aRowDims); pDPSave->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aColDims); + pDPSave->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_PAGE, aPageDims); OUString sAddress; sal_Int32 nOffset = 0; @@ -335,19 +371,42 @@ void ScXMLDataPilotTableContext::SetButtons() { std::pair<ScDPOutputGeometry::FieldType, size_t> aBtnType = aGeometry.getFieldButtonType(aScAddress); const ScDPSaveDimension* pDim = getDimension( - aRowDims, aColDims, aBtnType.first, aBtnType.second); + aRowDims, aColDims, aPageDims, aBtnType.first, aBtnType.second); + bool bDimension = pDim != NULL; bool bDataLayout = pDim && pDim->IsDataLayout(); bool bHasHidden = pDim && pDim->HasInvisibleMember(); + bool bPageDim = pDim && pDim->GetOrientation() == sheet::DataPilotFieldOrientation_PAGE; - sal_Int16 nMFlag = SC_MF_BUTTON; - if (bHasHidden) - nMFlag |= SC_MF_HIDDEN_MEMBER; + if (bPageDim) + { + // Page dimension needs 2 buttons. - if (!bDataLayout) - nMFlag |= SC_MF_BUTTON_POPUP; + pDoc->ApplyFlagsTab(aScAddress.Col(), aScAddress.Row(), aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), SC_MF_BUTTON); - pDoc->ApplyFlagsTab(aScAddress.Col(), aScAddress.Row(), aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), nMFlag); + sal_Int16 nMFlag = SC_MF_BUTTON_POPUP; + if (bHasHidden) + nMFlag |= SC_MF_HIDDEN_MEMBER; + pDoc->ApplyFlagsTab(aScAddress.Col()+1, aScAddress.Row(), aScAddress.Col()+1, aScAddress.Row(), aScAddress.Tab(), nMFlag); + } + else + { + sal_Int16 nMFlag = SC_MF_BUTTON; + if (bDataLayout) + { + // Data layout dimension only has a plain button with no popup. + } + else if (bDimension) + { + // Normal dimension has a popup arrow button. + if (bHasHidden) + nMFlag |= SC_MF_HIDDEN_MEMBER; + + nMFlag |= SC_MF_BUTTON_POPUP; + } + + pDoc->ApplyFlagsTab(aScAddress.Col(), aScAddress.Row(), aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), nMFlag); + } } } } @@ -360,6 +419,9 @@ void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim) { if (pDPSave) { + if (pDim->IsDataLayout()) + mnDataLayoutType = pDim->GetOrientation(); + // if a dimension with that name has already been inserted, // mark the new one as duplicate if ( !pDim->IsDataLayout() && diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx index e1721f901434..b37b2665fe4b 100644 --- a/sc/source/filter/xml/xmldpimp.hxx +++ b/sc/source/filter/xml/xmldpimp.hxx @@ -104,6 +104,7 @@ class ScXMLDataPilotTableContext : public SvXMLImportContext sal_uInt32 mnColFieldCount; sal_uInt32 mnPageFieldCount; sal_uInt32 mnDataFieldCount; + sal_uInt16 mnDataLayoutType; bool bIsNative:1; bool bIgnoreEmptyRows:1; bool bIdentifyCategories:1; diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx index 09012ded90fc..ccc47c029e64 100644 --- a/sc/source/ui/cctrl/checklistmenu.cxx +++ b/sc/source/ui/cctrl/checklistmenu.cxx @@ -860,7 +860,7 @@ void ScMenuFloatingWindow::terminateAllPopupMenus() // ============================================================================ ScCheckListMenuWindow::Config::Config() : - mbAllowEmptySet(true) + mbAllowEmptySet(true), mbRTL(false) { } @@ -1349,7 +1349,13 @@ void ScCheckListMenuWindow::launch(const Rectangle& rRect) maBtnOk.Enable(maChecks.GetCheckedEntryCount() != 0); Rectangle aRect(rRect); - if (maWndSize.Width() < aRect.GetWidth()) + if (maConfig.mbRTL) + { + // In RTL mode, the logical "left" is visual "right". + long nLeft = aRect.Left() - aRect.GetWidth(); + aRect.Left() = nLeft; + } + else if (maWndSize.Width() < aRect.GetWidth()) { // Target rectangle (i.e. cell width) is wider than the window. // Simulate right-aligned launch by modifying the target rectangle diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx index c35e5f9f1cee..cabddc553dc3 100644 --- a/sc/source/ui/inc/checklistmenu.hxx +++ b/sc/source/ui/inc/checklistmenu.hxx @@ -226,6 +226,7 @@ public: struct Config { bool mbAllowEmptySet; + bool mbRTL; Config(); }; diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index fcd4dbfe941f..965242a326b6 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -190,7 +190,7 @@ private: bool DoPageFieldSelection( SCCOL nCol, SCROW nRow ); bool DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt ); - void DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt ); + void DoPushPivotButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt, bool bButton, bool bPopup ); void DPMouseMove( const MouseEvent& rMEvt ); void DPMouseButtonUp( const MouseEvent& rMEvt ); @@ -199,10 +199,10 @@ private: /** * Check if the mouse click is on a field popup button. * - * @return bool true if the field popup menu has been launched and no - * further mouse event handling is necessary, false otherwise. + * @return true if the field popup menu has been launched and no further + * mouse event handling is necessary, false otherwise. */ - bool DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj); + bool DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, const ScAddress& rDimPos, ScDPObject* pDPObj); void DPLaunchFieldPopupMenu( const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj); @@ -331,8 +331,7 @@ public: ::com::sun::star::sheet::DataPilotFieldOrientation GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const; - void DrawButtons( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, - ScTableInfo& rTabInfo, OutputDevice* pContentDev ); + void DrawButtons( SCCOL nX1, SCCOL nX2, ScTableInfo& rTabInfo, OutputDevice* pContentDev); using Window::Draw; void Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx index 48bdc7cfc5ae..2ea9689e2412 100644 --- a/sc/source/ui/inc/viewdata.hxx +++ b/sc/source/ui/inc/viewdata.hxx @@ -355,7 +355,7 @@ public: sal_uInt8 GetFillMode() { return nFillMode; } // TRUE: Cell is merged - sal_Bool GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& rSizeYPix ); + bool GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& rSizeYPix ) const; sal_Bool GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich, SCsCOL& rPosX, SCsROW& rPosY, sal_Bool bTestMerge = sal_True, sal_Bool bRepair = false, diff --git a/sc/source/ui/src/scstring.src b/sc/source/ui/src/scstring.src index fa707f695aa1..c71f0fb3b352 100644 --- a/sc/source/ui/src/scstring.src +++ b/sc/source/ui/src/scstring.src @@ -167,6 +167,11 @@ String SCSTR_ALL Text [ en-US ] = "- all -" ; }; +String SCSTR_MULTIPLE +{ + Text [ en-US ] = "- multiple -" ; +}; + String SCSTR_STDFILTER { Text [ en-US ] = "~Standard Filter..." ; diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index cfcab8966b37..feb8b4c744fd 100644 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -2235,10 +2235,6 @@ void ScDataPilotFieldObj::setSubtotals( const Sequence< GeneralFunction >& rSubt OUString ScDataPilotFieldObj::getCurrentPage() const { - SolarMutexGuard aGuard; - ScDPSaveDimension* pDim = GetDPDimension(); - if( pDim && pDim->HasCurrentPage() ) - return pDim->GetCurrentPage(); return OUString(); } @@ -2255,9 +2251,7 @@ void ScDataPilotFieldObj::setCurrentPage( const OUString& rPage ) sal_Bool ScDataPilotFieldObj::getUseCurrentPage() const { - SolarMutexGuard aGuard; - ScDPSaveDimension* pDim = GetDPDimension(); - return pDim && pDim->HasCurrentPage(); + return false; } void ScDataPilotFieldObj::setUseCurrentPage( sal_Bool bUse ) @@ -2270,11 +2264,8 @@ void ScDataPilotFieldObj::setUseCurrentPage( sal_Bool bUse ) { /* It is somehow useless to set the property "HasSelectedPage" to true, because it is still needed to set an explicit page name. */ - if( !pDim->HasCurrentPage() ) - { - const ::rtl::OUString aPage; - pDim->SetCurrentPage( &aPage ); - } + const ::rtl::OUString aPage; + pDim->SetCurrentPage( &aPage ); } else pDim->SetCurrentPage( 0 ); diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index be9520d9acc9..a7033fe4d943 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -721,6 +721,7 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow) ScCheckListMenuWindow::Config aConfig; aConfig.mbAllowEmptySet = false; + aConfig.mbRTL = pViewData->GetDocument()->IsLayoutRTL(pViewData->GetTabNo()); mpAutoFilterPopup->setConfig(aConfig); mpAutoFilterPopup->launch(aCellRect); } @@ -859,158 +860,36 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode) pDBData->SetQueryParam(aParam); } -void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow ) -{ - //! merge position/size handling with DoAutoFilterMenue - - delete pFilterBox; - delete pFilterFloat; - - ScDocument* pDoc = pViewData->GetDocument(); - SCTAB nTab = pViewData->GetTabNo(); - sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); - - long nSizeX = 0; - long nSizeY = 0; - long nHeight = 0; - pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); - Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich ); - if ( bLayoutRTL ) - aPos.X() -= nSizeX; - - Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) ); - - aPos.X() -= 1; - aPos.Y() += nSizeY - 1; - - pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // not resizable etc. - pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) ); - pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_PAGEFIELD ); - if ( bLayoutRTL ) - pFilterBox->EnableMirroring(); - - nSizeX += 1; - - { - Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() ); - MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL ); - - nHeight = GetTextHeight(); - nHeight *= SC_FILTERLISTBOX_LINES; - - SetMapMode( aOldMode ); - SetFont( aOldFont ); - } - - // SetSize comes later - - std::vector<rtl::OUString> aStrings; - - // get list box entries and selection - sal_Bool bHasCurrentPage = false; - String aCurrentPage; - ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab); - if ( pDPObj && nCol > 0 ) - { - // look for the dimension header left of the drop-down arrow - sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN; - long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient ); - if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE ) - { - pDPObj->FillPageList( aStrings, nField ); - - // get current page from SaveData - - ScDPSaveData* pSaveData = pDPObj->GetSaveData(); - bool bIsDataLayout; - OUString aDimName = pDPObj->GetDimName( nField, bIsDataLayout ); - if ( pSaveData && !bIsDataLayout ) - { - ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName(aDimName); - if ( pDim && pDim->HasCurrentPage() ) - { - aCurrentPage = pDim->GetCurrentPage(); - bHasCurrentPage = sal_True; - } - } - } - } - - // include all entry widths for the size of the drop-down - long nMaxText = 0; - { - std::vector<rtl::OUString>::const_iterator it = aStrings.begin(), itEnd = aStrings.end(); - for (; it != itEnd; ++it) - { - long nTextWidth = pFilterBox->GetTextWidth(*it); - if ( nTextWidth > nMaxText ) - nMaxText = nTextWidth; - } - } - - // add scrollbar width if needed (string entries are counted here) - // (scrollbar is shown if the box is exactly full?) - if (aStrings.size() >= SC_FILTERLISTBOX_LINES) - nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize(); - - nMaxText += 4; // for borders - - if ( nMaxText > nSizeX ) - nSizeX = nMaxText; // just modify width - starting position is unchanged - - // adjust position and size to window - - Size aParentSize = GetParent()->GetOutputSizePixel(); - Size aSize( nSizeX, nHeight ); - - if ( aSize.Height() > aParentSize.Height() ) - aSize.Height() = aParentSize.Height(); - if ( aPos.Y() + aSize.Height() > aParentSize.Height() ) - aPos.Y() = aParentSize.Height() - aSize.Height(); - - pFilterBox->SetSizePixel( aSize ); - pFilterBox->Show(); // Show must be called before SetUpdateMode - pFilterBox->SetUpdateMode(false); - - pFilterFloat->SetOutputSizePixel( aSize ); - pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS); - - // fill the list box - bool bWait = aStrings.size() > 100; - - if (bWait) - EnterWait(); - - { - std::vector<rtl::OUString>::const_iterator it = aStrings.begin(), itEnd = aStrings.end(); - for (; it != itEnd; ++it) - pFilterBox->InsertEntry(*it); - } - - pFilterBox->SetSeparatorPos( 0 ); - - if (bWait) - LeaveWait(); - - pFilterBox->SetUpdateMode(true); +namespace { - sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND; - if (bHasCurrentPage) - nSelPos = pFilterBox->GetEntryPos( aCurrentPage ); +void getCellGeometry(Point& rScrPos, Size& rScrSize, const ScViewData* pViewData, SCCOL nCol, SCROW nRow, ScSplitPos eWhich) +{ + // Get the screen position of the cell. + rScrPos = pViewData->GetScrPos(nCol, nRow, eWhich); - if ( nSelPos == LISTBOX_ENTRY_NOTFOUND ) - nSelPos = 0; // first entry + // Get the screen size of the cell. + long nSizeX, nSizeY; + pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY); + rScrSize = Size(nSizeX-1, nSizeY-1); +} - pFilterBox->GrabFocus(); +} - // call Select after GrabFocus, so the focus rectangle ends up in the right position - if ( nSelPos != LISTBOX_ENTRY_NOTFOUND ) - pFilterBox->SelectEntryPos( nSelPos ); +void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow ) +{ + if (nCol == 0) + // We assume that the page field button is located in cell to the immediate left. + return; - pFilterBox->EndInit(); + SCTAB nTab = pViewData->GetTabNo(); + ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab); + if (!pDPObj) + return; - nMouseStatus = SC_GM_FILTER; - CaptureMouse(); + Point aScrPos; + Size aScrSize; + getCellGeometry(aScrPos, aScrSize, pViewData, nCol, nRow, eWhich); + DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol-1, nRow, nTab), pDPObj); } void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow ) @@ -1020,12 +899,9 @@ void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow ) if (!pDPObj) return; - // Get the geometry of the cell. - Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich); - long nSizeX, nSizeY; - pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY); - Size aScrSize(nSizeX-1, nSizeY-1); - + Point aScrPos; + Size aScrSize; + getCellGeometry(aScrPos, aScrSize, pViewData, nCol, nRow, eWhich); DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj); } @@ -1947,9 +1823,10 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta return; } } - if (pAttr->HasButton()) + + if (pAttr->HasPivotButton() || pAttr->HasPivotPopupButton()) { - DoPushButton( nPosX, nPosY, rMEvt ); // setzt evtl. bPivotMouse / bDPMouse + DoPushPivotButton(nPosX, nPosY, rMEvt, pAttr->HasPivotButton(), pAttr->HasPivotPopupButton()); rState.mbActivatePart = false; return; } diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index f352b82e86e6..3ec36a25cef9 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -153,7 +153,7 @@ bool ScGridWindow::DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& return false; } -void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt ) +void ScGridWindow::DoPushPivotButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt, bool bButton, bool bPopup ) { ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); @@ -164,23 +164,30 @@ void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt { sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN; ScAddress aPos( nCol, nRow, nTab ); - long nField = pDPObj->GetHeaderDim( aPos, nOrient ); + ScAddress aDimPos = aPos; + if (!bButton && bPopup && aDimPos.Col() > 0) + // For page field selection cell, the real field position is to the left. + aDimPos.IncCol(-1); + + long nField = pDPObj->GetHeaderDim(aDimPos, nOrient); if ( nField >= 0 ) { - bDPMouse = true; + bDPMouse = false; nDPField = nField; pDragDPObj = pDPObj; - - if (DPTestFieldPopupArrow(rMEvt, aPos, pDPObj)) + if (bPopup && DPTestFieldPopupArrow(rMEvt, aPos, aDimPos, pDPObj)) { // field name pop up menu has been launched. Don't activate // field move. - bDPMouse = false; return; } - DPTestMouse( rMEvt, sal_True ); - StartTracking(); + if (bButton) + { + bDPMouse = true; + DPTestMouse( rMEvt, sal_True ); + StartTracking(); + } } else if ( pDPObj->IsFilterButton(aPos) ) { @@ -347,7 +354,8 @@ void ScGridWindow::DPTestMouse( const MouseEvent& rMEvt, sal_Bool bMove ) pViewData->GetView()->ResetTimer(); } -bool ScGridWindow::DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj) +bool ScGridWindow::DPTestFieldPopupArrow( + const MouseEvent& rMEvt, const ScAddress& rPos, const ScAddress& rDimPos, ScDPObject* pDPObj) { sal_Bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() ); @@ -368,7 +376,7 @@ bool ScGridWindow::DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddres if (aRec.IsInside(rMEvt.GetPosPixel())) { // Mouse cursor inside the popup arrow box. Launch the field menu. - DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, rPos, pDPObj); + DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, rDimPos, pDPObj); return true; } @@ -436,10 +444,20 @@ private: void ScGridWindow::DPLaunchFieldPopupMenu( const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj) { - // We need to get the list of field members. auto_ptr<DPFieldPopupData> pDPData(new DPFieldPopupData); sal_uInt16 nOrient; pDPData->mnDim = pDPObj->GetHeaderDim(rPos, nOrient); + + bool bIsDataLayout; + OUString aDimName = pDPObj->GetDimName(pDPData->mnDim, bIsDataLayout); + pDPObj->BuildAllDimensionMembers(); + const ScDPSaveData* pSaveData = pDPObj->GetSaveData(); + const ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName(aDimName); + if (!pDim) + // This should never happen. + return; + + // We need to get the list of field members. pDPObj->FillLabelData(pDPData->mnDim, pDPData->maLabels); pDPData->mpDPObj = pDPObj; @@ -466,58 +484,51 @@ void ScGridWindow::DPLaunchFieldPopupMenu( mpDPFieldPopup->initMembers(); } - vector<OUString> aUserSortNames; - ScUserList* pUserList = ScGlobal::GetUserList(); - if (pUserList) + if (pDim->GetOrientation() != sheet::DataPilotFieldOrientation_PAGE) { - size_t n = pUserList->size(); - aUserSortNames.reserve(n); - for (size_t i = 0; i < n; ++i) + vector<OUString> aUserSortNames; + ScUserList* pUserList = ScGlobal::GetUserList(); + if (pUserList) { - const ScUserListData* pData = (*pUserList)[i]; - aUserSortNames.push_back(pData->GetString()); + size_t n = pUserList->size(); + aUserSortNames.reserve(n); + for (size_t i = 0; i < n; ++i) + { + const ScUserListData* pData = (*pUserList)[i]; + aUserSortNames.push_back(pData->GetString()); + } } - } - // Populate the menus. - ScTabViewShell* pViewShell = pViewData->GetViewShell(); - mpDPFieldPopup->addMenuItem( - ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_ASC).GetString(), true, - new PopupSortAction(rPos, PopupSortAction::ASCENDING, 0, pViewShell)); - mpDPFieldPopup->addMenuItem( - ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_DESC).GetString(), true, - new PopupSortAction(rPos, PopupSortAction::DESCENDING, 0, pViewShell)); - ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem( - ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_CUSTOM).GetString(), !aUserSortNames.empty()); - - if (pSubMenu && !aUserSortNames.empty()) - { - size_t n = aUserSortNames.size(); - for (size_t i = 0; i < n; ++i) + // Populate the menus. + ScTabViewShell* pViewShell = pViewData->GetViewShell(); + mpDPFieldPopup->addMenuItem( + ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_ASC).GetString(), true, + new PopupSortAction(rPos, PopupSortAction::ASCENDING, 0, pViewShell)); + mpDPFieldPopup->addMenuItem( + ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_DESC).GetString(), true, + new PopupSortAction(rPos, PopupSortAction::DESCENDING, 0, pViewShell)); + ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem( + ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_CUSTOM).GetString(), !aUserSortNames.empty()); + + if (pSubMenu && !aUserSortNames.empty()) { - pSubMenu->addMenuItem( - aUserSortNames[i], true, - new PopupSortAction(rPos, PopupSortAction::CUSTOM, static_cast<sal_uInt16>(i), pViewShell)); + size_t n = aUserSortNames.size(); + for (size_t i = 0; i < n; ++i) + { + pSubMenu->addMenuItem( + aUserSortNames[i], true, + new PopupSortAction(rPos, PopupSortAction::CUSTOM, static_cast<sal_uInt16>(i), pViewShell)); + } } } - bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL(pViewData->GetTabNo()); - Rectangle aCellRect(rScrPos, rScrSize); - const Size& rPopupSize = mpDPFieldPopup->getWindowSize(); - if (bLayoutRTL) - { - // RTL: rScrPos is logical-left (visual right) position, always right-align with that - aCellRect.SetPos(Point(rScrPos.X() - rPopupSize.Width() + 1, rScrPos.Y())); - } - else if (rScrSize.getWidth() > rPopupSize.getWidth()) - { - // If the cell width is larger than the popup window width, launch it - // right-aligned with the cell. - long nXOffset = rScrSize.getWidth() - rPopupSize.getWidth(); - aCellRect.SetPos(Point(rScrPos.X() + nXOffset, rScrPos.Y())); - } + mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) ); + ScCheckListMenuWindow::Config aConfig; + aConfig.mbAllowEmptySet = false; + aConfig.mbRTL = pViewData->GetDocument()->IsLayoutRTL(pViewData->GetTabNo()); + mpDPFieldPopup->setConfig(aConfig); mpDPFieldPopup->launch(aCellRect); } @@ -533,7 +544,6 @@ void ScGridWindow::UpdateDPFromFieldPopupMenu() return; ScDPObject* pDPObj = pDPData->mpDPObj; - pDPObj->BuildAllDimensionMembers(); ScDPSaveData* pSaveData = pDPObj->GetSaveData(); bool bIsDataLayout; diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index aedcf22225f5..64e4bbcff241 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -719,7 +719,7 @@ void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMod // Autofilter- und Pivot-Buttons - DrawButtons( nX1, nY1, nX2, nY2, aTabInfo, pContentDev ); // Pixel + DrawButtons( nX1, nX2, aTabInfo, pContentDev ); // Pixel // Notiz-Anzeiger @@ -1110,7 +1110,7 @@ void ScGridWindow::DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, } } -void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2*/, ScTableInfo& rTabInfo, OutputDevice* pContentDev ) +void ScGridWindow::DrawButtons( SCCOL nX1, SCCOL nX2, ScTableInfo& rTabInfo, OutputDevice* pContentDev) { aComboButton.SetOutputDevice( pContentDev ); @@ -1211,33 +1211,33 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2 } } - if ( pRowInfo[nArrY].bPushButton && pRowInfo[nArrY].bChanged ) + if ( pRowInfo[nArrY].bPivotButton && pRowInfo[nArrY].bChanged ) { RowInfo* pThisRowInfo = &pRowInfo[nArrY]; nRow = pThisRowInfo->nRowNo; for (nCol=nX1; nCol<=nX2; nCol++) { CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1]; - if ( pInfo->bPushButton && !pInfo->bHOverlapped && !pInfo->bVOverlapped ) - { - Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich ); - long nSizeX; - long nSizeY; - pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); - long nPosX = aScrPos.X(); - long nPosY = aScrPos.Y(); - // bLayoutRTL is handled in setBoundingBox - - String aStr; - pDoc->GetString(nCol, nRow, nTab, aStr); - aCellBtn.setText(aStr); - aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1), bLayoutRTL); - aCellBtn.setPopupLeft(false); // DataPilot popup is always right-aligned for now - aCellBtn.setDrawBaseButton(true); - aCellBtn.setDrawPopupButton(pInfo->bPopupButton); - aCellBtn.setHasHiddenMember(pInfo->bFilterActive); - aCellBtn.draw(); - } + if (pInfo->bHOverlapped || pInfo->bVOverlapped) + continue; + + Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich ); + long nSizeX; + long nSizeY; + pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); + long nPosX = aScrPos.X(); + long nPosY = aScrPos.Y(); + // bLayoutRTL is handled in setBoundingBox + + String aStr; + pDoc->GetString(nCol, nRow, nTab, aStr); + aCellBtn.setText(aStr); + aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1), bLayoutRTL); + aCellBtn.setPopupLeft(false); // DataPilot popup is always right-aligned for now + aCellBtn.setDrawBaseButton(pInfo->bPivotButton); + aCellBtn.setDrawPopupButton(pInfo->bPivotPopupButton); + aCellBtn.setHasHiddenMember(pInfo->bFilterActive); + aCellBtn.draw(); } } diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index 3079b5dc8942..c1ce5ff2dc65 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -1690,7 +1690,7 @@ SCROW ScViewData::PrevCellsY( ScVSplitPos eWhichY ) const } -sal_Bool ScViewData::GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& rSizeYPix ) +bool ScViewData::GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& rSizeYPix ) const { const ScMergeAttr* pMerge = (const ScMergeAttr*) pDoc->GetAttr( nX,nY,nTabNo, ATTR_MERGE ); if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 ) @@ -1717,7 +1717,7 @@ sal_Bool ScViewData::GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, lon rSizeXPix = nOutWidth; rSizeYPix = nOutHeight; - return sal_True; + return true; } else { |