From 7425283183cc26795bc3c655b2bc5cd6931091e2 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 19 Jun 2009 00:54:35 +0000 Subject: adding autoformat index member to dp object. --- sc/inc/dpobject.hxx | 4 ++++ sc/source/core/data/dpobject.cxx | 12 ++++++++++++ 2 files changed, 16 insertions(+) (limited to 'sc') diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 5f3dfe9eb489..9dd014aac1f8 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -106,6 +106,7 @@ private: ScDPOutput* pOutput; BOOL bSettingsChanged; BOOL bAlive; // FALSE if only used to hold settings + sal_uInt16 nAutoFormatIndex; BOOL bAllowMove; long nHeaderRows; // page fields plus filter button @@ -136,6 +137,9 @@ public: void SetOutRange(const ScRange& rRange); const ScRange& GetOutRange() const { return aOutRange; } + void SetAutoFormatIndex (const sal_uInt16 nIndex); + sal_uInt16 GetAutoFormatIndex() const; + void SetSheetDesc(const ScSheetSourceDesc& rDesc); void SetImportDesc(const ScImportSourceDesc& rDesc); void SetServiceData(const ScDPServiceDesc& rDesc); diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 12af06a773ed..4cf5d1e8a602 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -165,6 +165,7 @@ ScDPObject::ScDPObject( ScDocument* pD ) : pOutput( NULL ), bSettingsChanged( FALSE ), bAlive( FALSE ), + nAutoFormatIndex( 65535 ), bAllowMove( FALSE ), nHeaderRows( 0 ) { @@ -183,6 +184,7 @@ ScDPObject::ScDPObject(const ScDPObject& r) : pOutput( NULL ), bSettingsChanged( FALSE ), bAlive( FALSE ), + nAutoFormatIndex( r.nAutoFormatIndex ), bAllowMove( FALSE ), nHeaderRows( r.nHeaderRows ) { @@ -232,6 +234,16 @@ void ScDPObject::SetSaveData(const ScDPSaveData& rData) InvalidateData(); // re-init source from SaveData } +void ScDPObject::SetAutoFormatIndex(const sal_uInt16 nIndex) +{ + nAutoFormatIndex = nIndex; +} + +sal_uInt16 ScDPObject::GetAutoFormatIndex() const +{ + return nAutoFormatIndex; +} + void ScDPObject::SetOutRange(const ScRange& rRange) { aOutRange = rRange; -- cgit From acd89bd93d510281d1e46ca1617ff8545d0e981b Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 19 Jun 2009 01:30:32 +0000 Subject: added grid layout bits. --- sc/inc/dpobject.hxx | 6 ++- sc/inc/dpoutput.hxx | 4 ++ sc/source/core/data/dpobject.cxx | 25 +++++++--- sc/source/core/data/dpoutput.cxx | 19 +++++++- sc/source/filter/excel/read.cxx | 1 + sc/source/filter/excel/xepivot.cxx | 20 ++++++++ sc/source/filter/excel/xipivot.cxx | 93 ++++++++++++++++++++++++++++++++++++++ sc/source/filter/inc/xepivot.hxx | 3 ++ sc/source/filter/inc/xipivot.hxx | 7 +++ sc/source/filter/inc/xlpivot.hxx | 25 ++++++++++ 10 files changed, 194 insertions(+), 9 deletions(-) (limited to 'sc') diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 9dd014aac1f8..1c50c773b4df 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -106,9 +106,10 @@ private: ScDPOutput* pOutput; BOOL bSettingsChanged; BOOL bAlive; // FALSE if only used to hold settings - sal_uInt16 nAutoFormatIndex; + sal_uInt16 mnAutoFormatIndex; BOOL bAllowMove; long nHeaderRows; // page fields plus filter button + bool mbHeaderLayout; // TRUE : grid, FALSE : standard SC_DLLPRIVATE void CreateObjects(); @@ -140,6 +141,9 @@ public: void SetAutoFormatIndex (const sal_uInt16 nIndex); sal_uInt16 GetAutoFormatIndex() const; + void SetHeaderLayout(bool bUseGrid); + bool GetHeaderLayout() const; + void SetSheetDesc(const ScSheetSourceDesc& rDesc); void SetImportDesc(const ScImportSourceDesc& rDesc); void SetServiceData(const ScDPServiceDesc& rDesc); diff --git a/sc/inc/dpoutput.hxx b/sc/inc/dpoutput.hxx index 58001e1183a6..65108761b2ec 100644 --- a/sc/inc/dpoutput.hxx +++ b/sc/inc/dpoutput.hxx @@ -109,6 +109,7 @@ private: long nColCount; long nRowCount; long nHeaderSize; + bool mbHeaderLayout; // TRUE : grid, FALSE : standard SCCOL nTabStartCol; SCROW nTabStartRow; SCCOL nMemberStartCol; @@ -162,6 +163,9 @@ public: void GetMemberResultNames( ScStrCollection& rNames, long nDimension ); + void SetHeaderLayout(bool bUseGrid); + bool GetHeaderLayout() const; + static void GetDataDimensionNames( String& rSourceName, String& rGivenName, const com::sun::star::uno::Reference< com::sun::star::uno::XInterface>& xDim ); diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 4cf5d1e8a602..fa58a8b3c277 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -165,9 +165,10 @@ ScDPObject::ScDPObject( ScDocument* pD ) : pOutput( NULL ), bSettingsChanged( FALSE ), bAlive( FALSE ), - nAutoFormatIndex( 65535 ), + mnAutoFormatIndex( 65535 ), bAllowMove( FALSE ), - nHeaderRows( 0 ) + nHeaderRows( 0 ), + mbHeaderLayout(false) { } @@ -184,9 +185,10 @@ ScDPObject::ScDPObject(const ScDPObject& r) : pOutput( NULL ), bSettingsChanged( FALSE ), bAlive( FALSE ), - nAutoFormatIndex( r.nAutoFormatIndex ), + mnAutoFormatIndex( r.mnAutoFormatIndex ), bAllowMove( FALSE ), - nHeaderRows( r.nHeaderRows ) + nHeaderRows( r.nHeaderRows ), + mbHeaderLayout( r.mbHeaderLayout ) { if (r.pSaveData) pSaveData = new ScDPSaveData(*r.pSaveData); @@ -236,12 +238,22 @@ void ScDPObject::SetSaveData(const ScDPSaveData& rData) void ScDPObject::SetAutoFormatIndex(const sal_uInt16 nIndex) { - nAutoFormatIndex = nIndex; + mnAutoFormatIndex = nIndex; } sal_uInt16 ScDPObject::GetAutoFormatIndex() const { - return nAutoFormatIndex; + return mnAutoFormatIndex; +} + +void ScDPObject::SetHeaderLayout (bool bUseGrid) +{ + mbHeaderLayout = bUseGrid; +} + +bool ScDPObject::GetHeaderLayout() const +{ + return mbHeaderLayout; } void ScDPObject::SetOutRange(const ScRange& rRange) @@ -350,6 +362,7 @@ void ScDPObject::CreateOutput() { BOOL bFilterButton = IsSheetData() && pSaveData && pSaveData->GetFilterButton(); pOutput = new ScDPOutput( pDoc, xSource, aOutRange.aStart, bFilterButton ); + pOutput->SetHeaderLayout ( mbHeaderLayout ); long nOldRows = nHeaderRows; nHeaderRows = pOutput->GetHeaderRows(); diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx index 63acede160c9..567dcc7991f3 100644 --- a/sc/source/core/data/dpoutput.cxx +++ b/sc/source/core/data/dpoutput.cxx @@ -376,7 +376,8 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference* pRowAry = aData.getConstArray(); nColCount = nRowCount ? ( pRowAry[0].getLength() ) : 0; - nHeaderSize = 1; // one row for field names + + nHeaderSize = 1; + if (GetHeaderLayout() && nColFieldCount == 0) + // Insert an extra header row only when there is no column field. + nHeaderSize = 2; // calculate output positions and sizes @@ -993,6 +998,16 @@ void ScDPOutput::GetMemberResultNames( ScStrCollection& rNames, long nDimension } } +void ScDPOutput::SetHeaderLayout(bool bUseGrid) +{ + mbHeaderLayout = bUseGrid; + bSizesValid = false; +} + +bool ScDPOutput::GetHeaderLayout() const +{ + return mbHeaderLayout; +} void ScDPOutput::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData) { diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index a06cf041e7cf..d1ae00376cde 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -1143,6 +1143,7 @@ FltError ImportExcel8::Read( void ) case EXC_ID_SXDI: rPTableMgr.ReadSxdi( maStrm ); break; case EXC_ID_SXVDEX: rPTableMgr.ReadSxvdex( maStrm ); break; case EXC_ID_SXEX: rPTableMgr.ReadSxex( maStrm ); break; + case EXC_ID_SXVIEWEX9: rPTableMgr.ReadSxViewEx9( maStrm ); break; } } break; diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx index 457cdd2a17e4..0b10ded5aa9e 100644 --- a/sc/source/filter/excel/xepivot.cxx +++ b/sc/source/filter/excel/xepivot.cxx @@ -1220,6 +1220,8 @@ XclExpPivotTable::XclExpPivotTable( const XclExpRoot& rRoot, const ScDPObject& r maPTInfo.maDataName = ScGlobal::GetRscString( STR_PIVOT_DATA ); maPTInfo.mnCacheIdx = mrPCache.GetCacheIndex(); + maPTAutoFormat.Init( rDPObj ); + if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() ) { // additional properties from ScDPSaveData @@ -1299,6 +1301,8 @@ void XclExpPivotTable::Save( XclExpStream& rStrm ) WriteSxli( rStrm, maPTInfo.mnDataCols, maPTInfo.mnColFields ); // SXEX WriteSxex( rStrm ); + // SX_AUTOFORMAT + WriteSxAutoformat( rStrm ); } } @@ -1439,6 +1443,8 @@ void XclExpPivotTable::Finalize() rnDataXclRow = rnXclRow1 + maPTInfo.mnColFields + 1; if( maDataFields.empty() ) ++rnDataXclRow; + if( 0 == maPTAutoFormat.mnGridLayout ) + ++rnDataXclRow; rnXclCol2 = ::std::max( rnXclCol2, rnDataXclCol ); rnXclRow2 = ::std::max( rnXclRow2, rnDataXclRow ); maPTInfo.mnDataCols = rnXclCol2 - rnDataXclCol + 1; @@ -1446,6 +1452,8 @@ void XclExpPivotTable::Finalize() // first heading maPTInfo.mnFirstHeadRow = rnXclRow1 + 1; + if( 0 == maPTAutoFormat.mnGridLayout ) + maPTInfo.mnFirstHeadRow++; } // records ---------------------------------------------------------------- @@ -1525,6 +1533,18 @@ void XclExpPivotTable::WriteSxex( XclExpStream& rStrm ) const rStrm.EndRecord(); } +void XclExpPivotTable::WriteSxAutoformat( XclExpStream& rStrm ) const +{ + // Until we sync the autoformat ids only export if using grid header layout + // That could only have been set via xls import so far. + if ( 0 == maPTAutoFormat.mnGridLayout ) + { + rStrm.StartRecord( EXC_ID_SXVIEWEX9, 17 ); + rStrm << maPTAutoFormat; + rStrm.EndRecord(); + } +} + // ============================================================================ namespace { diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index acd371f43f7d..495f73d75a68 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -1296,6 +1296,11 @@ void XclImpPivotTable::ReadSxex( XclImpStream& rStrm ) rStrm >> maPTExtInfo; } +void XclImpPivotTable::ReadSxViewEx9( XclImpStream& rStrm ) +{ + rStrm >> maPTAutoFormat; +} + // ---------------------------------------------------------------------------- void XclImpPivotTable::Convert() @@ -1363,6 +1368,7 @@ void XclImpPivotTable::Convert() pDPObj->SetSheetDesc( aDesc ); pDPObj->SetOutRange( aOutRange ); pDPObj->SetAlive( TRUE ); + pDPObj->SetHeaderLayout( maPTAutoFormat.mnGridLayout == 0 ); GetDoc().GetDPCollection()->Insert( pDPObj ); } @@ -1458,6 +1464,12 @@ void XclImpPivotTableManager::ReadSxex( XclImpStream& rStrm ) maPTables.back()->ReadSxex( rStrm ); } +void XclImpPivotTableManager::ReadSxViewEx9( XclImpStream& rStrm ) +{ + if( !maPTables.empty() ) + maPTables.back()->ReadSxViewEx9( rStrm ); +} + // ---------------------------------------------------------------------------- void XclImpPivotTableManager::ReadPivotCaches( XclImpStream& rStrm ) @@ -1474,3 +1486,84 @@ void XclImpPivotTableManager::ConvertPivotTables() // ============================================================================ +// Pivot table autoformat settings ============================================ + +/** +classic : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00 +default : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00 +report01 : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00 +report02 : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00 +report03 : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00 +report04 : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00 +report05 : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00 +report06 : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00 +report07 : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00 +report08 : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00 +report09 : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00 +report10 : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00 +table01 : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00 +table02 : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00 +table03 : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00 +table04 : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00 +table05 : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00 +table06 : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00 +table07 : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00 +table08 : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00 +table09 : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00 +table10 : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00 +none : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00 +**/ + +XclPTAutoFormat::XclPTAutoFormat() : + mbReport( 0 ), + mnAutoFormat( 0 ), + mnGridLayout( 0x10 ) +{ +} + +void XclPTAutoFormat::Init( const ScDPObject& rDPObj ) +{ + if( rDPObj.GetHeaderLayout() ) + { + mbReport = 0; + mnAutoFormat = 1; + mnGridLayout = 0; + } + else + { + // Report1 for now + // TODO : sync with autoformat indicies + mbReport = 2; + mnAutoFormat = 1; + mnGridLayout = 0x10; + } +} + +XclImpStream& operator>>( XclImpStream& rStrm, XclPTAutoFormat& rInfo ) +{ + rStrm.Ignore( 2 ); + rStrm >> rInfo.mbReport; /// 2 for report* fmts ? + rStrm.Ignore( 6 ); + sal_uInt8 nDummy; + return rStrm + >> rInfo.mnAutoFormat + >> rInfo.mnGridLayout + >> nDummy >> nDummy >> nDummy; +} + +XclExpStream& operator<<( XclExpStream& rStrm, const XclPTAutoFormat& rInfo ) +{ + return rStrm + << EXC_PT_AUTOFMT_HEADER + << rInfo.mbReport + << EXC_PT_AUTOFMT_ZERO + << EXC_PT_AUTOFMT_FLAGS + << rInfo.mnAutoFormat + << rInfo.mnGridLayout + << static_cast(0x00) + << static_cast(0x00) + << static_cast(0x00); +} + +// ============================================================================ + diff --git a/sc/source/filter/inc/xepivot.hxx b/sc/source/filter/inc/xepivot.hxx index 80356d41f4a8..67ef2ff6fcd8 100644 --- a/sc/source/filter/inc/xepivot.hxx +++ b/sc/source/filter/inc/xepivot.hxx @@ -412,6 +412,8 @@ private: void WriteSxli( XclExpStream& rStrm, sal_uInt16 nLineCount, sal_uInt16 nIndexCount ) const; /** Writes the SXEX records containing additional pivot table info. */ void WriteSxex( XclExpStream& rStrm ) const; + /** Writes the SX_AUTOFORMAT records with the autoformat id and header layout */ + void WriteSxAutoformat( XclExpStream& rStrm ) const; // ------------------------------------------------------------------------ private: @@ -422,6 +424,7 @@ private: const XclExpPivotCache& mrPCache; /// The pivot cache this pivot table bases on. XclPTInfo maPTInfo; /// Info about the pivot table (SXVIEW record). XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record). + XclPTAutoFormat maPTAutoFormat; /// The selected autoformat (SXVIEWEX9) XclExpPTFieldList maFieldList; /// All fields in pivot cache order. ScfUInt16Vec maRowFields; /// Row field indexes. ScfUInt16Vec maColFields; /// Column field indexes. diff --git a/sc/source/filter/inc/xipivot.hxx b/sc/source/filter/inc/xipivot.hxx index 52b55509219b..5a98c0793740 100644 --- a/sc/source/filter/inc/xipivot.hxx +++ b/sc/source/filter/inc/xipivot.hxx @@ -350,6 +350,9 @@ public: void ReadSxdi( XclImpStream& rStrm ); /** Reads an SXEX record containing additional settings for the pivot table. */ void ReadSxex( XclImpStream& rStrm ); + /** Reads an SXVIEWEX9 record that specifies the pivot tables + * autoformat. */ + void ReadSxViewEx9( XclImpStream& rStrm ); // ------------------------------------------------------------------------ @@ -364,6 +367,7 @@ private: XclPTInfo maPTInfo; /// General info about the pivot table (SXVIEW record). XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record). + XclPTAutoFormat maPTAutoFormat; /// The selected autoformat (SX_AUTOFORMAT) XclImpPTFieldVec maFields; /// Vector containing all fields. XclImpPTFieldRef mxCurrField; /// Current field for importing additional info. ScfStringVec maVisFieldNames; /// Vector containing all visible field names. @@ -422,6 +426,9 @@ public: void ReadSxvi( XclImpStream& rStrm ); /** Reads an SXEX record containing additional settings for a pivot table. */ void ReadSxex( XclImpStream& rStrm ); + /** Reads an SXVIEWEX9 record that specifies the pivot tables + * autoformat. */ + void ReadSxViewEx9( XclImpStream& rStrm ); // ------------------------------------------------------------------------ diff --git a/sc/source/filter/inc/xlpivot.hxx b/sc/source/filter/inc/xlpivot.hxx index 9604c7b1d17d..52251ed62294 100644 --- a/sc/source/filter/inc/xlpivot.hxx +++ b/sc/source/filter/inc/xlpivot.hxx @@ -41,6 +41,7 @@ #include #include "ftools.hxx" #include "xladdress.hxx" +#include "dpobject.hxx" class XclImpStream; class XclExpStream; @@ -73,6 +74,10 @@ const sal_uInt16 EXC_PT_MAXDATACOUNT = 256; // pivot table items const sal_uInt16 EXC_PT_MAXITEMCOUNT = 32500; +const sal_uInt16 EXC_PT_AUTOFMT_HEADER = 0x810; +const sal_uInt16 EXC_PT_AUTOFMT_ZERO = 0; +const sal_uInt32 EXC_PT_AUTOFMT_FLAGS = 0x20; + /** Data type of a pivot cache item. */ enum XclPCItemType { @@ -396,6 +401,9 @@ const double EXC_SXDBEX_CREATION_DATE = 51901.029652778; const sal_uInt16 EXC_ID_SXFDBTYPE = 0x01BB; const sal_uInt16 EXC_SXFDBTYPE_DEFAULT = 0x0000; +// (0x0810) SXVIEWEX9 --------------------------------------------------------- +const sal_uInt16 EXC_ID_SXVIEWEX9 = 0x0810; + // ============================================================================ // Pivot cache // ============================================================================ @@ -786,5 +794,22 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo ); // ============================================================================ +// Pivot table autoformat settings ============================================== + +/** Pivot table autoformat settings (SX_AUTOFORMAT record). */ +struct XclPTAutoFormat +{ + sal_uInt32 mbReport; /// 2 for report* fmts ? + sal_uInt8 mnAutoFormat; /// AutoFormat ID + sal_uInt8 mnGridLayout; /// 0 == gridlayout, 0x10 == modern + + explicit XclPTAutoFormat(); + void Init( const ScDPObject& rDPObj ); +}; + +XclImpStream& operator>>( XclImpStream& rStrm, XclPTAutoFormat& rInfo ); +XclExpStream& operator<<( XclExpStream& rStrm, const XclPTAutoFormat& rInfo ); + +// ============================================================================ #endif -- cgit From 621ea5f0e56231a7d5063e6d12cce8aab55af37c Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 19 Jun 2009 02:29:09 +0000 Subject: #i22029# #i81335# applied & adjusted the patch from ooo-build. This enables changing the names of fields, field members and grand total names. --- sc/inc/dpgroup.hxx | 5 +- sc/inc/dpobject.hxx | 16 +- sc/inc/dpsave.hxx | 62 +++++-- sc/inc/dptabres.hxx | 5 +- sc/inc/dptabsrc.hxx | 17 +- sc/inc/unonames.hxx | 3 + sc/source/core/data/dpgroup.cxx | 4 +- sc/source/core/data/dpobject.cxx | 126 +++++++++----- sc/source/core/data/dpoutput.cxx | 41 ++++- sc/source/core/data/dpsave.cxx | 233 ++++++++++++++++++++++--- sc/source/core/data/dptabres.cxx | 86 +++++++-- sc/source/core/data/dptabsrc.cxx | 121 +++++++++++-- sc/source/filter/excel/read.cxx | 3 + sc/source/filter/excel/xepivot.cxx | 111 ++++++++++-- sc/source/filter/excel/xestring.cxx | 4 +- sc/source/filter/excel/xipivot.cxx | 124 +++++-------- sc/source/filter/excel/xlpivot.cxx | 125 ++++++++++++- sc/source/filter/inc/xepivot.hxx | 6 +- sc/source/filter/inc/xestring.hxx | 1 + sc/source/filter/inc/xipivot.hxx | 9 +- sc/source/filter/inc/xlpivot.hxx | 15 +- sc/source/filter/inc/xlstring.hxx | 1 + sc/source/ui/dbgui/pvfundlg.cxx | 22 ++- sc/source/ui/dbgui/pvlaydlg.cxx | 41 +++++ sc/source/ui/inc/pvfundlg.hxx | 11 ++ sc/source/ui/unoobj/dapiuno.cxx | 11 +- sc/source/ui/view/dbfunc3.cxx | 337 ++++++++++++++++++++++++++++-------- 27 files changed, 1219 insertions(+), 321 deletions(-) (limited to 'sc') diff --git a/sc/inc/dpgroup.hxx b/sc/inc/dpgroup.hxx index 99dac0e517db..cb933f4d2a98 100644 --- a/sc/inc/dpgroup.hxx +++ b/sc/inc/dpgroup.hxx @@ -33,6 +33,7 @@ #include #include +#include #include "dptabdat.hxx" #include "scdllapi.h" @@ -182,7 +183,7 @@ class ScDPGroupTableData : public ScDPTableData { typedef ::std::hash_set< ::rtl::OUString, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > StringHashSet; - ScDPTableData* pSourceData; + ::boost::shared_ptr pSourceData; long nSourceCount; ScDPGroupDimensionVec aGroups; ScDPNumGroupDimension* pNumGroups; // array[nSourceCount] @@ -200,7 +201,7 @@ class ScDPGroupTableData : public ScDPTableData public: // takes ownership of pSource - ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDocument ); + ScDPGroupTableData( const ::boost::shared_ptr& pSource, ScDocument* pDocument ); virtual ~ScDPGroupTableData(); void AddGroupDimension( const ScDPGroupDimension& rGroup ); diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 1c50c773b4df..f90277769cba 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -38,6 +38,8 @@ #include "dpoutput.hxx" #include +#include + //------------------------------------------------------------------ namespace com { namespace sun { namespace star { namespace sheet { @@ -66,6 +68,7 @@ class ScStrCollection; class TypedScStrCollection; struct PivotField; class ScDPCacheTable; +class ScDPTableData; struct ScDPServiceDesc { @@ -101,6 +104,7 @@ private: ScSheetSourceDesc* pSheetDesc; // for sheet data ScImportSourceDesc* pImpDesc; // for database data ScDPServiceDesc* pServDesc; // for external service + ::boost::shared_ptr mpTableData; // cached data com::sun::star::uno::Reference xSource; ScDPOutput* pOutput; @@ -112,6 +116,7 @@ private: bool mbHeaderLayout; // TRUE : grid, FALSE : standard + SC_DLLPRIVATE ScDPTableData* GetTableData(); SC_DLLPRIVATE void CreateObjects(); SC_DLLPRIVATE void CreateOutput(); @@ -166,7 +171,14 @@ public: void SetTag(const String& rNew); const String& GetTag() const { return aTableTag; } - BOOL IsDimNameInUse( const String& rName ) const; + /** + * Data description cell displays the description of a data dimension if + * and only if there is only one data dimension. It's usually located at + * the upper-left corner of the table output. + */ + bool IsDataDescriptionCell(const ScAddress& rPos); + + bool IsDimNameInUse(const ::rtl::OUString& rName) const; String GetDimName( long nDim, BOOL& rIsDataLayout ); BOOL IsDuplicated( long nDim ); long GetDimCount(); @@ -230,6 +242,8 @@ public: // (button attribute must be present) void RefreshAfterLoad(); + void BuildAllDimensionMembers(); + static BOOL HasRegisteredSources(); static com::sun::star::uno::Sequence GetRegisteredSources(); static com::sun::star::uno::Reference diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx index 44689bcf0772..9d680dfa3856 100644 --- a/sc/inc/dpsave.hxx +++ b/sc/inc/dpsave.hxx @@ -34,9 +34,11 @@ #include #include #include +#include #include "scdllapi.h" #include #include +#include namespace com { namespace sun { namespace star { namespace sheet { struct DataPilotFieldReference; @@ -46,6 +48,7 @@ namespace com { namespace sun { namespace star { namespace sheet { } } } } class ScDPDimensionSaveData; +class ScDPTableData; // -------------------------------------------------------------------- // @@ -57,6 +60,7 @@ class ScDPSaveMember { private: String aName; + ::std::auto_ptr mpLayoutName; // custom name to be displayed in the table. USHORT nVisibleMode; USHORT nShowDetailsMode; @@ -77,18 +81,23 @@ public: void SetName( const String& rNew ); // used if the source member was renamed (groups) + SC_DLLPUBLIC void SetLayoutName( const ::rtl::OUString& rName ); + SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const; + void RemoveLayoutName(); + void WriteToSource( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface>& xMember, sal_Int32 nPosition ); }; -class ScDPSaveDimension +class SC_DLLPUBLIC ScDPSaveDimension { private: String aName; - String* pLayoutName; // alternative name for layout, not used (yet) String* pSelectedPage; + ::std::auto_ptr mpLayoutName; + ::std::auto_ptr mpSubtotalName; BOOL bIsDataLayout; BOOL bDupFlag; USHORT nOrientation; @@ -127,39 +136,44 @@ public: void SetName( const String& rNew ); // used if the source dim was renamed (groups) - SC_DLLPUBLIC void SetOrientation(USHORT nNew); + void SetOrientation(USHORT nNew); void SetSubTotals(BOOL bSet); // to be removed! - SC_DLLPUBLIC void SetSubTotals(long nCount, const USHORT* pFuncs); + void SetSubTotals(long nCount, const USHORT* pFuncs); long GetSubTotalsCount() const { return nSubTotalCount; } USHORT GetSubTotalFunc(long nIndex) const { return pSubTotalFuncs[nIndex]; } - SC_DLLPUBLIC void SetShowEmpty(BOOL bSet); + void SetShowEmpty(BOOL bSet); BOOL GetShowEmpty() const { return BOOL(nShowEmptyMode); } - SC_DLLPUBLIC void SetFunction(USHORT nNew); // enum GeneralFunction + void SetFunction(USHORT nNew); // enum GeneralFunction USHORT GetFunction() const { return nFunction; } void SetUsedHierarchy(long nNew); long GetUsedHierarchy() const { return nUsedHierarchy; } - SC_DLLPUBLIC void SetLayoutName(const String* pName); - SC_DLLPUBLIC const String& GetLayoutName() const; - SC_DLLPUBLIC BOOL HasLayoutName() const; + + void SetLayoutName(const ::rtl::OUString& rName); + const ::rtl::OUString* GetLayoutName() const; + void RemoveLayoutName(); + void SetSubtotalName(const ::rtl::OUString& rName); + const ::rtl::OUString* GetSubtotalName() const; + + bool IsMemberNameInUse(const ::rtl::OUString& rName) const; const ::com::sun::star::sheet::DataPilotFieldReference* GetReferenceValue() const { return pReferenceValue; } - SC_DLLPUBLIC void SetReferenceValue(const ::com::sun::star::sheet::DataPilotFieldReference* pNew); + void SetReferenceValue(const ::com::sun::star::sheet::DataPilotFieldReference* pNew); const ::com::sun::star::sheet::DataPilotFieldSortInfo* GetSortInfo() const { return pSortInfo; } - SC_DLLPUBLIC void SetSortInfo(const ::com::sun::star::sheet::DataPilotFieldSortInfo* pNew); + void SetSortInfo(const ::com::sun::star::sheet::DataPilotFieldSortInfo* pNew); const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* GetAutoShowInfo() const { return pAutoShowInfo; } - SC_DLLPUBLIC void SetAutoShowInfo(const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pNew); + void SetAutoShowInfo(const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pNew); const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* GetLayoutInfo() const { return pLayoutInfo; } - SC_DLLPUBLIC void SetLayoutInfo(const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pNew); + void SetLayoutInfo(const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pNew); - SC_DLLPUBLIC void SetCurrentPage( const String* pPage ); // NULL = no selection (all) - SC_DLLPUBLIC BOOL HasCurrentPage() const; - SC_DLLPUBLIC const String& GetCurrentPage() const; + void SetCurrentPage( const String* pPage ); // NULL = no selection (all) + BOOL HasCurrentPage() const; + const String& GetCurrentPage() const; USHORT GetOrientation() const { return nOrientation; } ScDPSaveMember* GetExistingMemberByName(const String& rName); - SC_DLLPUBLIC ScDPSaveMember* GetMemberByName(const String& rName); + ScDPSaveMember* GetMemberByName(const String& rName); void SetMemberPosition( const String& rName, sal_Int32 nNewPos ); @@ -180,6 +194,12 @@ private: BOOL bFilterButton; // not passed to DataPilotSource BOOL bDrillDown; // not passed to DataPilotSource + /** if true, all dimensions already have all of their member instances + * created. */ + bool mbDimensionMembersBuilt; + + ::std::auto_ptr mpGrandTotalName; + public: SC_DLLPUBLIC ScDPSaveData(); ScDPSaveData(const ScDPSaveData& r); @@ -189,21 +209,26 @@ public: BOOL operator== ( const ScDPSaveData& r ) const; + SC_DLLPUBLIC void SetGrandTotalName(const ::rtl::OUString& rName); + SC_DLLPUBLIC const ::rtl::OUString* GetGrandTotalName() const; + const List& GetDimensions() const { return aDimList; } void AddDimension(ScDPSaveDimension* pDim) { aDimList.Insert(pDim, LIST_APPEND); } ScDPSaveDimension* GetDimensionByName(const String& rName); SC_DLLPUBLIC ScDPSaveDimension* GetDataLayoutDimension(); + SC_DLLPUBLIC ScDPSaveDimension* GetExistingDataLayoutDimension() const; ScDPSaveDimension* DuplicateDimension(const String& rName); SC_DLLPUBLIC ScDPSaveDimension& DuplicateDimension(const ScDPSaveDimension& rDim); - SC_DLLPUBLIC ScDPSaveDimension* GetExistingDimensionByName(const String& rName); + SC_DLLPUBLIC ScDPSaveDimension* GetExistingDimensionByName(const String& rName) const; SC_DLLPUBLIC ScDPSaveDimension* GetNewDimensionByName(const String& rName); void RemoveDimensionByName(const String& rName); ScDPSaveDimension* GetInnermostDimension(USHORT nOrientation); + ScDPSaveDimension* GetFirstDimension(::com::sun::star::sheet::DataPilotFieldOrientation eOrientation); long GetDataDimensionCount() const; @@ -230,6 +255,7 @@ public: const ScDPDimensionSaveData* GetExistingDimensionData() const { return pDimensionData; } SC_DLLPUBLIC ScDPDimensionSaveData* GetDimensionData(); // create if not there void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied + void BuildAllDimensionMembers(ScDPTableData* pData); }; diff --git a/sc/inc/dptabres.hxx b/sc/inc/dptabres.hxx index 6dfb782b2313..670c5eb566a4 100644 --- a/sc/inc/dptabres.hxx +++ b/sc/inc/dptabres.hxx @@ -41,6 +41,7 @@ #include #include #include +#include namespace com { namespace sun { namespace star { namespace sheet { struct DataPilotFieldReference; @@ -262,7 +263,7 @@ public: long GetMeasureCount() const { return nMeasCount; } ScSubTotalFunc GetMeasureFunction(long nMeasure) const; - String GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc) const; + String GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const; String GetMeasureDimensionName(long nMeasure) const; const ::com::sun::star::sheet::DataPilotFieldReference& GetMeasureRefVal(long nMeasure) const; USHORT GetMeasureRefOrient(long nMeasure) const; @@ -284,6 +285,8 @@ public: const ScDPItemData& rBaseData, long nBaseIndex ) const; BOOL HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex, const ScDPItemData& rSecondData, long nSecondIndex ) const; + + const ScDPSource* GetSource() const; }; diff --git a/sc/inc/dptabsrc.hxx b/sc/inc/dptabsrc.hxx index 59996d08b8aa..5538959b2dfc 100644 --- a/sc/inc/dptabsrc.hxx +++ b/sc/inc/dptabsrc.hxx @@ -33,6 +33,7 @@ #include #include +#include #include #include #include "global.hxx" // enum ScSubTotalFunc @@ -108,7 +109,7 @@ class ScDPSource : public cppu::WeakImplHelper6< com::sun::star::lang::XServiceInfo > { private: - ScDPTableData* pData; // data source + ScDPTableData* pData; // data source (ScDPObject manages its life time) ScDPDimensions* pDimensions; // api objects // settings: long nColDims[SC_DAPI_MAXFIELDS]; @@ -136,6 +137,8 @@ private: List aRowLevelList; BOOL bResultOverflow; + ::std::auto_ptr mpGrandTotalName; + void CreateRes_Impl(); void FillMemberResults(); void FillLevelList( USHORT nOrientation, List& rList ); @@ -162,11 +165,15 @@ public: ScDPTableData* GetData() { return pData; } const ScDPTableData* GetData() const { return pData; } + void SetGrandTotalName(const ::rtl::OUString& rName); + const ::rtl::OUString* GetGrandTotalName() const; + USHORT GetOrientation(long nColumn); void SetOrientation(long nColumn, USHORT nNew); long GetPosition(long nColumn); long GetDataDimensionCount(); + ScDPDimension* GetDataDimension(long nIndex); String GetDataDimName(long nIndex); BOOL IsDataLayoutDimension(long nDim); USHORT GetDataLayoutOrientation(); @@ -333,6 +340,8 @@ private: long nUsedHier; USHORT nFunction; // enum GeneralFunction String aName; // if empty, take from source + ::std::auto_ptr mpLayoutName; + ::std::auto_ptr mpSubtotalName; long nSourceDim; // >=0 if dup'ed ::com::sun::star::sheet::DataPilotFieldReference aReferenceValue; // settings for "show data as" / "displayed value" @@ -350,6 +359,9 @@ public: ScDPDimension* CreateCloneObject(); ScDPHierarchies* GetHierarchiesObject(); + SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const; + const ::rtl::OUString* GetSubtotalName() const; + // XNamed virtual ::rtl::OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setName( const ::rtl::OUString& aName ) @@ -736,7 +748,7 @@ private: long nLev; ScDPItemData maData; -// String aCaption; // visible name (changeable by user) + ::std::auto_ptr mpLayoutName; sal_Int32 nPosition; // manual sorting BOOL bVisible; @@ -750,6 +762,7 @@ public: BOOL IsNamedItem( const ScDPItemData& r ) const; String GetNameStr() const; void FillItemData( ScDPItemData& rData ) const; + SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const; sal_Int32 Compare( const ScDPMember& rOther ) const; // visible order diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx index 367e7d7cfe35..bfc5aa9de831 100644 --- a/sc/inc/unonames.hxx +++ b/sc/inc/unonames.hxx @@ -558,6 +558,9 @@ #define SC_UNO_ROWFIELDCOUNT "RowFieldCount" #define SC_UNO_COLUMNFIELDCOUNT "ColumnFieldCount" #define SC_UNO_DATAFIELDCOUNT "DataFieldCount" +#define SC_UNO_LAYOUTNAME "LayoutName" +#define SC_UNO_FIELD_SUBTOTALNAME "FieldSubtotalName" +#define SC_UNO_GRANDTOTAL_NAME "GrandTotalName" // (preliminary:) #define SC_UNO_REFVALUE "ReferenceValue" diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx index a92d1681ec0e..037a232bbd2a 100644 --- a/sc/source/core/data/dpgroup.cxx +++ b/sc/source/core/data/dpgroup.cxx @@ -70,6 +70,7 @@ using ::rtl::OUStringHash; using ::std::vector; using ::std::hash_set; using ::std::hash_map; +using ::boost::shared_ptr; #define D_TIMEFACTOR 86400.0 @@ -977,7 +978,7 @@ String lcl_GetNumGroupForValue( double fValue, const ScDPNumGroupInfo& rInfo, bo return lcl_GetNumGroupName( fGroupStart, rInfo, bHasNonInteger, cDecSeparator, pFormatter ); } -ScDPGroupTableData::ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDocument ) : +ScDPGroupTableData::ScDPGroupTableData( const shared_ptr& pSource, ScDocument* pDocument ) : ScDPTableData(pDocument), pSourceData( pSource ), pDoc( pDocument ) @@ -992,7 +993,6 @@ ScDPGroupTableData::ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDoc ScDPGroupTableData::~ScDPGroupTableData() { delete[] pNumGroups; - delete pSourceData; } void ScDPGroupTableData::AddGroupDimension( const ScDPGroupDimension& rGroup ) diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index fa58a8b3c277..cd7d58964a96 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -78,6 +78,7 @@ using namespace com::sun::star; using ::std::vector; +using ::boost::shared_ptr; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY; @@ -162,6 +163,7 @@ ScDPObject::ScDPObject( ScDocument* pD ) : pSheetDesc( NULL ), pImpDesc( NULL ), pServDesc( NULL ), + mpTableData(static_cast(NULL)), pOutput( NULL ), bSettingsChanged( FALSE ), bAlive( FALSE ), @@ -182,6 +184,7 @@ ScDPObject::ScDPObject(const ScDPObject& r) : pSheetDesc( NULL ), pImpDesc( NULL ), pServDesc( NULL ), + mpTableData(static_cast(NULL)), pOutput( NULL ), bSettingsChanged( FALSE ), bAlive( FALSE ), @@ -349,6 +352,22 @@ void ScDPObject::SetTag(const String& rNew) aTableTag = rNew; } +bool ScDPObject::IsDataDescriptionCell(const ScAddress& rPos) +{ + if (!pSaveData) + return false; + + long nDataDimCount = pSaveData->GetDataDimensionCount(); + if (nDataDimCount != 1) + // There has to be exactly one data dimension for the description to + // appear at top-left corner. + return false; + + CreateOutput(); + ScRange aTabRange = pOutput->GetOutputRange(sheet::DataPilotOutputRangeType::TABLE); + return (rPos == aTabRange.aStart); +} + uno::Reference ScDPObject::GetSource() { CreateObjects(); @@ -390,11 +409,43 @@ void ScDPObject::CreateOutput() } } +ScDPTableData* ScDPObject::GetTableData() +{ + if (!mpTableData) + { + if ( pImpDesc ) + { + // database data + mpTableData.reset(new ScDatabaseDPData(pDoc, *pImpDesc)); + } + else + { + // cell data + if (!pSheetDesc) + { + DBG_ERROR("no source descriptor"); + pSheetDesc = new ScSheetSourceDesc; // dummy defaults + } + mpTableData.reset(new ScSheetDPData(pDoc, *pSheetDesc)); + } + + // grouping (for cell or database data) + if ( pSaveData && pSaveData->GetExistingDimensionData() ) + { + shared_ptr pGroupData(new ScDPGroupTableData(mpTableData, pDoc)); + pSaveData->GetExistingDimensionData()->WriteToData(*pGroupData); + mpTableData = pGroupData; + } + } + + return mpTableData.get(); +} + void ScDPObject::CreateObjects() { // if groups are involved, create a new source with the ScDPGroupTableData if ( bSettingsChanged && pSaveData && pSaveData->GetExistingDimensionData() ) - xSource = NULL; + InvalidateSource(); if (!xSource.is()) { @@ -412,33 +463,9 @@ void ScDPObject::CreateObjects() if ( !xSource.is() ) // database or sheet data, or error in CreateSource { DBG_ASSERT( !pServDesc, "DPSource could not be created" ); - - ScDPTableData* pData = NULL; - if ( pImpDesc ) - { - // database data - pData = new ScDatabaseDPData( pDoc, *pImpDesc ); - } - else - { - // cell data - if (!pSheetDesc) - { - DBG_ERROR("no source descriptor"); - pSheetDesc = new ScSheetSourceDesc; // dummy defaults - } - pData = new ScSheetDPData( pDoc, *pSheetDesc ); - } - - // grouping (for cell or database data) - if ( pSaveData && pSaveData->GetExistingDimensionData() ) - { - ScDPGroupTableData* pGroupData = new ScDPGroupTableData( pData, pDoc ); - pSaveData->GetExistingDimensionData()->WriteToData( *pGroupData ); - pData = pGroupData; - } - - xSource = new ScDPSource( pData ); + ScDPTableData* pData = GetTableData(); + ScDPSource* pSource = new ScDPSource( pData ); + xSource = pSource; } if (pSaveData) @@ -475,6 +502,7 @@ void ScDPObject::InvalidateData() void ScDPObject::InvalidateSource() { xSource = NULL; + mpTableData.reset(); } ScRange ScDPObject::GetNewOutputRange( BOOL& rOverflow ) @@ -556,6 +584,14 @@ void ScDPObject::RefreshAfterLoad() nHeaderRows = 0; // nothing found, no drop-down lists } +void ScDPObject::BuildAllDimensionMembers() +{ + if (!pSaveData) + return; + + pSaveData->BuildAllDimensionMembers(GetTableData()); +} + void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode, const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ) { @@ -678,23 +714,33 @@ void ScDPObject::GetDrillDownData(const ScAddress& rPos, Sequence< Sequence rTableData = xDrillDownData->getDrillDownData(filters); } -BOOL ScDPObject::IsDimNameInUse( const String& rName ) const +bool ScDPObject::IsDimNameInUse(const OUString& rName) const { - if ( xSource.is() ) + if (!xSource.is()) + return false; + + Reference xDims = xSource->getDimensions(); + Sequence aDimNames = xDims->getElementNames(); + sal_Int32 n = aDimNames.getLength(); + for (sal_Int32 i = 0; i < n; ++i) { - uno::Reference xDimsName = xSource->getDimensions(); - if ( xDimsName.is() ) + const OUString& rDimName = aDimNames[i]; + if (rDimName.equalsIgnoreAsciiCase(rName)) + return true; + + Reference xPropSet(xDims->getByName(rDimName), UNO_QUERY); + if (!xPropSet.is()) + continue; + + Any any = xPropSet->getPropertyValue(OUString::createFromAscii(SC_UNO_LAYOUTNAME)); + OUString aLayoutName; + if (any >>= aLayoutName) { - rtl::OUString aCompare( rName ); - uno::Sequence aNames = xDimsName->getElementNames(); - long nCount = aNames.getLength(); - const rtl::OUString* pArr = aNames.getConstArray(); - for (long nPos=0; nPos aResult; - String aCaption; + String maName; /// Name is the internal field name. + String aCaption; /// Caption is the name visible in the output table. ScDPOutLevelData() { nDim = nHier = nLevel = nDimPos = -1; } @@ -444,7 +445,15 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::ReferencegetName()); //! Caption... + String aName = xLevNam->getName(); + OUString aCaption = aName; // Caption equals the field name by default. + Reference xPropSet(xLevel, UNO_QUERY); + if (xPropSet.is()) + { + Any any = xPropSet->getPropertyValue( + OUString::createFromAscii(SC_UNO_LAYOUTNAME)); + any >>= aCaption; + } switch ( eDimOrient ) { case sheet::DataPilotFieldOrientation_COLUMN: @@ -453,6 +462,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::ReferencegetResults(); + pColFields[nColFieldCount].maName = aName; pColFields[nColFieldCount].aCaption= aCaption; if (!lcl_MemberEmpty(pColFields[nColFieldCount].aResult)) ++nColFieldCount; @@ -463,6 +473,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::ReferencegetResults(); + pRowFields[nRowFieldCount].maName = aName; pRowFields[nRowFieldCount].aCaption= aCaption; if (!lcl_MemberEmpty(pRowFields[nRowFieldCount].aResult)) ++nRowFieldCount; @@ -473,6 +484,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::ReferencegetPropertyValue( - rtl::OUString::createFromAscii(DP_PROP_DATADESCR) ); + rtl::OUString::createFromAscii(SC_UNO_DATADESC) ); rtl::OUString aUStr; aAny >>= aUStr; aDataDescription = String( aUStr ); @@ -606,9 +618,16 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const sheet::MemberResult& rData, BOOL bColHeader, long nLevel ) { long nFlags = rData.Flags; + + rtl::OUStringBuffer aCaptionBuf; + if (!(nFlags & sheet::MemberResultFlags::NUMERIC)) + // This caption is not a number. Make sure it won't get parsed as one. + aCaptionBuf.append(sal_Unicode('\'')); + aCaptionBuf.append(rData.Caption); + if ( nFlags & sheet::MemberResultFlags::HASMEMBER ) { - pDoc->SetString( nCol, nRow, nTab, rData.Caption ); + pDoc->SetString( nCol, nRow, nTab, aCaptionBuf.makeStringAndClear() ); } else { @@ -1161,7 +1180,7 @@ bool ScDPOutput::GetDataResultPositionData(vector& for (SCCOL nColField = 0; nColField < nColFieldCount && bFilterByCol; ++nColField) { sheet::DataPilotFieldFilter filter; - filter.FieldName = pColFields[nColField].aCaption; + filter.FieldName = pColFields[nColField].maName; const uno::Sequence rSequence = pColFields[nColField].aResult; const sheet::MemberResult* pArray = rSequence.getConstArray(); @@ -1178,10 +1197,15 @@ bool ScDPOutput::GetDataResultPositionData(vector& } // row fields + bool bDataLayoutExists = (nDataFieldCount > 1); for (SCROW nRowField = 0; nRowField < nRowFieldCount && bFilterByRow; ++nRowField) { + if (bDataLayoutExists && nRowField == nRowFieldCount - 1) + // There is no sense including the data layout field for filtering. + continue; + sheet::DataPilotFieldFilter filter; - filter.FieldName = pRowFields[nRowField].aCaption; + filter.FieldName = pRowFields[nRowField].maName; const uno::Sequence rSequence = pRowFields[nRowField].aResult; const sheet::MemberResult* pArray = rSequence.getConstArray(); @@ -1213,8 +1237,7 @@ bool lcl_IsNamedDataField( const ScDPGetPivotDataField& rTarget, const String& r bool lcl_IsNamedCategoryField( const ScDPGetPivotDataField& rFilter, const ScDPOutLevelData& rField ) { - //! name from source instead of caption? - return ScGlobal::pTransliteration->isEqual( rFilter.maFieldName, rField.aCaption ); + return ScGlobal::pTransliteration->isEqual( rFilter.maFieldName, rField.maName ); } bool lcl_IsCondition( const sheet::MemberResult& rResultEntry, const ScDPGetPivotDataField& rFilter ) diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx index f4180312ce0d..ba1acc97a83a 100644 --- a/sc/source/core/data/dpsave.cxx +++ b/sc/source/core/data/dpsave.cxx @@ -58,7 +58,12 @@ #include #include +#include + using namespace com::sun::star; +using ::rtl::OUString; +using ::std::hash_map; +using ::std::auto_ptr; // ----------------------------------------------------------------------- @@ -113,6 +118,7 @@ void lcl_SkipExtra( SvStream& rStream ) ScDPSaveMember::ScDPSaveMember(const String& rName) : aName( rName ), + mpLayoutName(NULL), nVisibleMode( SC_DPSAVEMODE_DONTKNOW ), nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW ) { @@ -120,9 +126,12 @@ ScDPSaveMember::ScDPSaveMember(const String& rName) : ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember& r) : aName( r.aName ), + mpLayoutName(NULL), nVisibleMode( r.nVisibleMode ), nShowDetailsMode( r.nShowDetailsMode ) { + if (r.mpLayoutName.get()) + mpLayoutName.reset(new OUString(*r.mpLayoutName)); } ScDPSaveMember::~ScDPSaveMember() @@ -167,6 +176,21 @@ void ScDPSaveMember::SetName( const String& rNew ) aName = rNew; } +void ScDPSaveMember::SetLayoutName( const OUString& rName ) +{ + mpLayoutName.reset(new OUString(rName)); +} + +const OUString* ScDPSaveMember::GetLayoutName() const +{ + return mpLayoutName.get(); +} + +void ScDPSaveMember::RemoveLayoutName() +{ + mpLayoutName.reset(NULL); +} + void ScDPSaveMember::WriteToSource( const uno::Reference& xMember, sal_Int32 nPosition ) { // nothing to do? @@ -187,6 +211,18 @@ void ScDPSaveMember::WriteToSource( const uno::Reference& xMemb lcl_SetBoolProperty( xMembProp, rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS), (BOOL)nShowDetailsMode ); + if (mpLayoutName.get()) + { + try + { + uno::Any any; + any <<= rtl::OUString(*mpLayoutName); + xMembProp->setPropertyValue(rtl::OUString::createFromAscii(SC_UNO_LAYOUTNAME), any); + } + catch (uno::Exception&) + { + } + } if ( nPosition >= 0 ) { try @@ -205,8 +241,9 @@ void ScDPSaveMember::WriteToSource( const uno::Reference& xMemb ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) : aName( rName ), - pLayoutName( NULL ), pSelectedPage( NULL ), + mpLayoutName(NULL), + mpSubtotalName(NULL), bIsDataLayout( bDataLayout ), bDupFlag( FALSE ), nOrientation( sheet::DataPilotFieldOrientation_HIDDEN ), @@ -225,6 +262,8 @@ ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) : ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) : aName( r.aName ), + mpLayoutName(NULL), + mpSubtotalName(NULL), bIsDataLayout( r.bIsDataLayout ), bDupFlag( r.bDupFlag ), nOrientation( r.nOrientation ), @@ -265,14 +304,14 @@ ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) : pLayoutInfo = new sheet::DataPilotFieldLayoutInfo( *(r.pLayoutInfo) ); else pLayoutInfo = NULL; - if (r.pLayoutName) - pLayoutName = new String( *(r.pLayoutName) ); - else - pLayoutName = NULL; if (r.pSelectedPage) pSelectedPage = new String( *(r.pSelectedPage) ); else pSelectedPage = NULL; + if (r.mpLayoutName.get()) + mpLayoutName.reset(new OUString(*r.mpLayoutName)); + if (r.mpSubtotalName.get()) + mpSubtotalName.reset(new OUString(*r.mpSubtotalName)); } ScDPSaveDimension::~ScDPSaveDimension() @@ -283,7 +322,6 @@ ScDPSaveDimension::~ScDPSaveDimension() delete pSortInfo; delete pAutoShowInfo; delete pLayoutInfo; - delete pLayoutName; delete pSelectedPage; delete [] pSubTotalFuncs; } @@ -395,25 +433,45 @@ void ScDPSaveDimension::SetUsedHierarchy(long nNew) nUsedHierarchy = nNew; } -BOOL ScDPSaveDimension::HasLayoutName() const +void ScDPSaveDimension::SetSubtotalName(const OUString& rName) { - return ( pLayoutName != NULL ); + mpSubtotalName.reset(new OUString(rName)); } -void ScDPSaveDimension::SetLayoutName(const String* pName) +const OUString* ScDPSaveDimension::GetSubtotalName() const { - delete pLayoutName; - if (pName) - pLayoutName = new String( *pName ); - else - pLayoutName = NULL; + return mpSubtotalName.get(); +} + +bool ScDPSaveDimension::IsMemberNameInUse(const OUString& rName) const +{ + MemberList::const_iterator itr = maMemberList.begin(), itrEnd = maMemberList.end(); + for (; itr != itrEnd; ++itr) + { + const ScDPSaveMember* pMem = *itr; + if (rName.equalsIgnoreAsciiCase(pMem->GetName())) + return true; + + const OUString* pLayoutName = pMem->GetLayoutName(); + if (pLayoutName && rName.equalsIgnoreAsciiCase(*pLayoutName)) + return true; + } + return false; +} + +void ScDPSaveDimension::SetLayoutName(const OUString& rName) +{ + mpLayoutName.reset(new OUString(rName)); } -const String& ScDPSaveDimension::GetLayoutName() const +const OUString* ScDPSaveDimension::GetLayoutName() const { - if (pLayoutName) - return *pLayoutName; - return aName; + return mpLayoutName.get(); +} + +void ScDPSaveDimension::RemoveLayoutName() +{ + mpLayoutName.reset(NULL); } void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference* pNew) @@ -549,6 +607,19 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference& xD { aAny <<= aFilter; xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FILTER), aAny ); + if (mpLayoutName.get()) + { + aAny <<= *mpLayoutName; + xDimProp->setPropertyValue(rtl::OUString::createFromAscii(SC_UNO_LAYOUTNAME), aAny); + } + + const OUString* pSubTotalName = GetSubtotalName(); + if (pSubTotalName) + { + // Custom subtotal name, with '?' being replaced by the visible field name later. + aAny <<= *pSubTotalName; + xDimProp->setPropertyValue(OUString::createFromAscii(SC_UNO_FIELD_SUBTOTALNAME), aAny); + } } catch ( beans::UnknownPropertyException& ) { @@ -691,7 +762,9 @@ ScDPSaveData::ScDPSaveData() : nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW ), nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ), bFilterButton( TRUE ), - bDrillDown( TRUE ) + bDrillDown( TRUE ), + mbDimensionMembersBuilt(false), + mpGrandTotalName(NULL) { } @@ -701,7 +774,9 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) : nIgnoreEmptyMode( r.nIgnoreEmptyMode ), nRepeatEmptyMode( r.nRepeatEmptyMode ), bFilterButton( r.bFilterButton ), - bDrillDown( r.bDrillDown ) + bDrillDown( r.bDrillDown ), + mbDimensionMembersBuilt(r.mbDimensionMembersBuilt), + mpGrandTotalName(NULL) { if ( r.pDimensionData ) pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData ); @@ -714,6 +789,9 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) : ScDPSaveDimension* pNew = new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) ); aDimList.Insert( pNew, LIST_APPEND ); } + + if (r.mpGrandTotalName.get()) + mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName)); } ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r ) @@ -732,6 +810,7 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r ) nRepeatEmptyMode = r.nRepeatEmptyMode; bFilterButton = r.bFilterButton; bDrillDown = r.bDrillDown; + mbDimensionMembersBuilt = r.mbDimensionMembersBuilt; // remove old dimensions @@ -750,6 +829,9 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r ) new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) ); aDimList.Insert( pNew, LIST_APPEND ); } + + if (r.mpGrandTotalName.get()) + mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName)); } return *this; } @@ -761,7 +843,8 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const nIgnoreEmptyMode != r.nIgnoreEmptyMode || nRepeatEmptyMode != r.nRepeatEmptyMode || bFilterButton != r.bFilterButton || - bDrillDown != r.bDrillDown ) + bDrillDown != r.bDrillDown || + mbDimensionMembersBuilt != r.mbDimensionMembersBuilt) return FALSE; if ( pDimensionData || r.pDimensionData ) @@ -777,6 +860,16 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const *(ScDPSaveDimension*)r.aDimList.GetObject(i) ) ) return FALSE; + if (mpGrandTotalName.get()) + { + if (!r.mpGrandTotalName.get()) + return false; + if (!mpGrandTotalName->equals(*r.mpGrandTotalName)) + return false; + } + else if (r.mpGrandTotalName.get()) + return false; + return TRUE; } @@ -790,6 +883,16 @@ ScDPSaveData::~ScDPSaveData() delete pDimensionData; } +void ScDPSaveData::SetGrandTotalName(const OUString& rName) +{ + mpGrandTotalName.reset(new OUString(rName)); +} + +const OUString* ScDPSaveData::GetGrandTotalName() const +{ + return mpGrandTotalName.get(); +} + ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName) { long nCount = aDimList.Count(); @@ -804,7 +907,7 @@ ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName) return pNew; } -ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName) +ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName) const { long nCount = aDimList.Count(); for (long i=0; iIsDataLayout() ) return pDim; } - ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), TRUE ); - aDimList.Insert( pNew, LIST_APPEND ); - return pNew; + return NULL; } ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const String& rName) @@ -895,6 +1007,18 @@ ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(USHORT nOrientation) return pInner; // the last matching one } +ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation) +{ + long nCount = aDimList.Count(); + for (long i = 0; i < nCount; ++i) + { + ScDPSaveDimension* pDim = static_cast(aDimList.GetObject(i)); + if (pDim->GetOrientation() == eOrientation && !pDim->IsDataLayout()) + return pDim; + } + return NULL; +} + long ScDPSaveData::GetDataDimensionCount() const { long nDataCount = 0; @@ -1002,6 +1126,14 @@ void ScDPSaveData::WriteToSource( const uno::ReferencesetPropertyValue(OUString::createFromAscii(SC_UNO_GRANDTOTAL_NAME), any); + } } catch(uno::Exception&) { @@ -1125,3 +1257,50 @@ void ScDPSaveData::SetDimensionData( const ScDPDimensionSaveData* pNew ) pDimensionData = NULL; } +void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData) +{ + if (mbDimensionMembersBuilt) + return; + + // First, build a dimension name-to-index map. + typedef hash_map NameIndexMap; + NameIndexMap aMap; + long nColCount = pData->GetColumnCount(); + for (long i = 0; i < nColCount; ++i) + aMap.insert( NameIndexMap::value_type(pData->getDimensionName(i), i)); + + NameIndexMap::const_iterator itrEnd = aMap.end(); + + sal_uInt32 n = aDimList.Count(); + for (sal_uInt32 i = 0; i < n; ++i) + { + ScDPSaveDimension* pDim = static_cast(aDimList.GetObject(i)); + const String& rDimName = pDim->GetName(); + if (!rDimName.Len()) + // empty dimension name. It must be data layout. + continue; + + NameIndexMap::const_iterator itr = aMap.find(rDimName); + if (itr == itrEnd) + // dimension name not in the data. This should never happen! + continue; + + long nDimIndex = itr->second; + const TypedScStrCollection& rMembers = pData->GetColumnEntries(nDimIndex); + sal_uInt16 nMemberCount = rMembers.GetCount(); + for (sal_uInt16 j = 0; j < nMemberCount; ++j) + { + const String& rMemName = rMembers[j]->GetString(); + if (pDim->GetExistingMemberByName(rMemName)) + // this member instance already exists. nothing to do. + continue; + + auto_ptr pNewMember(new ScDPSaveMember(rMemName)); + pNewMember->SetIsVisible(true); + pDim->AddMember(pNewMember.release()); + } + } + + mbDimensionMembersBuilt = true; +} + diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx index 398d4d1c7e01..07a783bdb2b1 100644 --- a/sc/source/core/data/dptabres.cxx +++ b/sc/source/core/data/dptabres.cxx @@ -67,6 +67,7 @@ using ::std::vector; using ::std::pair; using ::std::hash_map; using ::com::sun::star::uno::Sequence; +using ::rtl::OUString; // ----------------------------------------------------------------------- @@ -825,11 +826,11 @@ USHORT ScDPResultData::GetMeasureRefOrient(long nMeasure) const return pMeasRefOrient[nMeasure]; } -String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc) const +String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const { // with bForce==TRUE, return function instead of "result" for single measure // with eForceFunc != SUBTOTAL_FUNC_NONE, always use eForceFunc - + rbTotalResult = false; if ( nMeasure < 0 || ( nMeasCount == 1 && !bForce && eForceFunc == SUBTOTAL_FUNC_NONE ) ) { // for user-specified subtotal function with all measures, @@ -837,12 +838,19 @@ String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFu if ( eForceFunc != SUBTOTAL_FUNC_NONE ) return ScGlobal::GetRscString(nFuncStrIds[eForceFunc]); + rbTotalResult = true; return ScGlobal::GetRscString(STR_TABLE_ERGEBNIS); } else { DBG_ASSERT( pMeasNames && nMeasure < nMeasCount, "bumm" ); - + ScDPDimension* pDataDim = pSource->GetDataDimension(nMeasure); + if (pDataDim) + { + const OUString* pLayoutName = pDataDim->GetLayoutName(); + if (pLayoutName) + return *pLayoutName; + } String aRet; ScSubTotalFunc eFunc = ( eForceFunc == SUBTOTAL_FUNC_NONE ) ? GetMeasureFunction(nMeasure) : eForceFunc; @@ -896,6 +904,11 @@ BOOL ScDPResultData::HasCommonElement( const ScDPItemData& rFirstData, long nFir return pSource->GetData()->HasCommonElement( rFirstData, nFirstIndex, rSecondData, nSecondIndex ); } +const ScDPSource* ScDPResultData::GetSource() const +{ + return pSource; +} + // ----------------------------------------------------------------------- @@ -1172,6 +1185,25 @@ void ScDPResultMember::ProcessData( const vector& aChildMembers, c } } +/** + * Parse subtotal string and replace all occurrences of '?' with the + * caption string. + */ +static String lcl_parseSubtotalName(const String& rSubStr, const String& rCaption) +{ + String aNewStr; + xub_StrLen n = rSubStr.Len(); + for (xub_StrLen i = 0; i < n; ++i) + { + sal_Unicode c = rSubStr.GetChar(i); + if (c == sal_Unicode('?')) + aNewStr.Append(rCaption); + else + aNewStr.Append(c); + } + return aNewStr; +} + void ScDPResultMember::FillMemberResults( uno::Sequence* pSequences, long& rPos, long nMeasure, BOOL bRoot, const String* pMemberName, @@ -1204,17 +1236,25 @@ void ScDPResultMember::FillMemberResults( uno::Sequence* pS } String aCaption = aName; + if (pMemberDesc) + { + const OUString* pLayoutName = pMemberDesc->GetLayoutName(); + if (pLayoutName) + { + aCaption = *pLayoutName; + bIsNumeric = false; // layout name is always non-numeric. + } + } + if ( pMemberCaption ) // use pMemberCaption if != NULL aCaption = *pMemberCaption; if (!aCaption.Len()) aCaption = ScGlobal::GetRscString(STR_EMPTYDATA); - if ( !bIsNumeric ) - { - // add a "'" character so a string isn't parsed as value in the output cell - //! have a separate bit in Flags (MemberResultFlags) instead? - aCaption.Insert( (sal_Unicode) '\'', 0 ); - } + if (bIsNumeric) + pArray[rPos].Flags |= sheet::MemberResultFlags::NUMERIC; + else + pArray[rPos].Flags &= ~sheet::MemberResultFlags::NUMERIC; if ( nSize && !bRoot ) // root is overwritten by first dimension { @@ -1277,9 +1317,30 @@ void ScDPResultMember::FillMemberResults( uno::Sequence* pS if (bHasChild) eForce = lcl_GetForceFunc( pParentLevel, nUserPos ); - String aSubStr = aName; //! caption? + bool bTotalResult = false; + String aSubStr = aCaption; aSubStr += ' '; - aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce); + aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce, bTotalResult); + + if (bTotalResult) + { + if (pMemberDesc) + { + // single data field layout. + const OUString* pSubtotalName = pParentDim->GetSubtotalName(); + if (pSubtotalName) + aSubStr = lcl_parseSubtotalName(*pSubtotalName, aCaption); + pArray[rPos].Flags &= ~sheet::MemberResultFlags::GRANDTOTAL; + } + else + { + // root member - subtotal (grand total?) for multi-data field layout. + const rtl::OUString* pGrandTotalName = pResultData->GetSource()->GetGrandTotalName(); + if (pGrandTotalName) + aSubStr = *pGrandTotalName; + pArray[rPos].Flags |= sheet::MemberResultFlags::GRANDTOTAL; + } + } pArray[rPos].Name = rtl::OUString(aName); pArray[rPos].Caption = rtl::OUString(aSubStr); @@ -2796,8 +2857,9 @@ void ScDPResultDimension::FillMemberResults( uno::Sequence* // in data layout dimension, use first member with different measures/names if ( bIsDataLayout ) { + bool bTotalResult = false; String aMbrName = pResultData->GetMeasureDimensionName( nSorted ); - String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE ); + String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE, bTotalResult ); maMemberArray[0]->FillMemberResults( pSequences, nPos, nSorted, FALSE, &aMbrName, &aMbrCapt ); } else if ( pMember->IsVisible() ) diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx index 5fa5c393df37..bc1394307f26 100644 --- a/sc/source/core/data/dptabsrc.cxx +++ b/sc/source/core/data/dptabsrc.cxx @@ -85,6 +85,7 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Any; using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo; +using ::rtl::OUString; // ----------------------------------------------------------------------- @@ -141,15 +142,14 @@ ScDPSource::ScDPSource( ScDPTableData* pD ) : pRowResRoot( NULL ), pColResults( NULL ), pRowResults( NULL ), - bResultOverflow( FALSE ) + bResultOverflow( FALSE ), + mpGrandTotalName(NULL) { pData->SetEmptyFlags( bIgnoreEmptyRows, bRepeatIfEmpty ); } ScDPSource::~ScDPSource() { - delete pData; // ScDPTableData is not ref-counted - if (pDimensions) pDimensions->release(); // ref-counted @@ -163,6 +163,16 @@ ScDPSource::~ScDPSource() delete pResData; } +void ScDPSource::SetGrandTotalName(const ::rtl::OUString& rName) +{ + mpGrandTotalName.reset(new ::rtl::OUString(rName)); +} + +const ::rtl::OUString* ScDPSource::GetGrandTotalName() const +{ + return mpGrandTotalName.get(); +} + USHORT ScDPSource::GetOrientation(long nColumn) { long i; @@ -186,16 +196,21 @@ long ScDPSource::GetDataDimensionCount() return nDataDimCount; } +ScDPDimension* ScDPSource::GetDataDimension(long nIndex) +{ + if (nIndex < 0 || nIndex >= nDataDimCount) + return NULL; + + long nDimIndex = nDataDims[nIndex]; + return GetDimensionsObject()->getByIndex(nDimIndex); +} + String ScDPSource::GetDataDimName( long nIndex ) { String aRet; - if ( nIndex >= 0 && nIndex < nDataDimCount ) - { - long nDimIndex = nDataDims[nIndex]; - ScDPDimension* pDim = GetDimensionsObject()->getByIndex(nDimIndex); - if (pDim) - aRet = String( pDim->getName() ); - } + ScDPDimension* pDim = GetDataDimension(nIndex); + if (pDim) + aRet = String(pDim->getName()); return aRet; } @@ -488,7 +503,10 @@ String ScDPSource::getDataDescription() String aRet; if ( pResData->GetMeasureCount() == 1 ) - aRet = pResData->GetMeasureString( 0, TRUE, SUBTOTAL_FUNC_NONE ); + { + bool bTotalResult = false; + aRet = pResData->GetMeasureString( 0, TRUE, SUBTOTAL_FUNC_NONE, bTotalResult ); + } // empty for more than one measure @@ -1132,6 +1150,7 @@ uno::Reference SAL_CALL ScDPSource::getPropertySetInfo( throw(uno::RuntimeException) { ScUnoGuard aGuard; + using beans::PropertyAttribute::READONLY; static SfxItemPropertyMapEntry aDPSourceMap_Impl[] = { @@ -1140,6 +1159,10 @@ uno::Reference SAL_CALL ScDPSource::getPropertySetInfo( {MAP_CHAR_LEN(SC_UNO_IGNOREEM), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only {MAP_CHAR_LEN(SC_UNO_REPEATIF), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only {MAP_CHAR_LEN(SC_UNO_ROWGRAND), 0, &getBooleanCppuType(), 0, 0 }, + {MAP_CHAR_LEN(SC_UNO_ROWFIELDCOUNT), 0, &getCppuType(static_cast(0)), READONLY, 0 }, + {MAP_CHAR_LEN(SC_UNO_COLUMNFIELDCOUNT), 0, &getCppuType(static_cast(0)), READONLY, 0 }, + {MAP_CHAR_LEN(SC_UNO_DATAFIELDCOUNT), 0, &getCppuType(static_cast(0)), READONLY, 0 }, + {MAP_CHAR_LEN(SC_UNO_GRANDTOTAL_NAME), 0, &getCppuType(static_cast(0)), 0, 0 }, {0,0,0,0,0,0} }; static uno::Reference aRef = @@ -1161,6 +1184,12 @@ void SAL_CALL ScDPSource::setPropertyValue( const rtl::OUString& aPropertyName, setIgnoreEmptyRows( lcl_GetBoolFromAny( aValue ) ); else if ( aNameStr.EqualsAscii( SC_UNO_REPEATIF ) ) setRepeatIfEmpty( lcl_GetBoolFromAny( aValue ) ); + else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME)) + { + OUString aName; + if (aValue >>= aName) + mpGrandTotalName.reset(new OUString(aName)); + } else { DBG_ERROR("unknown property"); @@ -1190,6 +1219,11 @@ uno::Any SAL_CALL ScDPSource::getPropertyValue( const rtl::OUString& aPropertyNa aRet <<= static_cast(nColDimCount); else if ( aNameStr.EqualsAscii( SC_UNO_DATAFIELDCOUNT ) ) // read-only aRet <<= static_cast(nDataDimCount); + else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME)) + { + if (mpGrandTotalName.get()) + aRet <<= *mpGrandTotalName; + } else { DBG_ERROR("unknown property"); @@ -1337,6 +1371,8 @@ ScDPDimension::ScDPDimension( ScDPSource* pSrc, long nD ) : pHierarchies( NULL ), nUsedHier( 0 ), nFunction( SUBTOTAL_FUNC_SUM ), // sum is default + mpLayoutName(NULL), + mpSubtotalName(NULL), nSourceDim( -1 ), bHasSelectedPage( FALSE ), pSelectedData( NULL ) @@ -1364,6 +1400,16 @@ ScDPHierarchies* ScDPDimension::GetHierarchiesObject() return pHierarchies; } +const rtl::OUString* ScDPDimension::GetLayoutName() const +{ + return mpLayoutName.get(); +} + +const rtl::OUString* ScDPDimension::GetSubtotalName() const +{ + return mpSubtotalName.get(); +} + uno::Reference SAL_CALL ScDPDimension::getHierarchies() throw(uno::RuntimeException) { @@ -1523,6 +1569,8 @@ uno::Reference SAL_CALL ScDPDimension::getPropertySetIn {MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNO_REFVALUE), 0, &getCppuType((sheet::DataPilotFieldReference*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNO_USEDHIER), 0, &getCppuType((sal_Int32*)0), 0, 0 }, + {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast(0)), 0, 0 }, + {MAP_CHAR_LEN(SC_UNO_FIELD_SUBTOTALNAME), 0, &getCppuType(static_cast(0)), 0, 0 }, {0,0,0,0,0,0} }; static uno::Reference aRef = @@ -1593,6 +1641,18 @@ void SAL_CALL ScDPDimension::setPropertyValue( const rtl::OUString& aPropertyNam } DELETEZ( pSelectedData ); // invalid after changing aSelectedPage } + else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME)) + { + OUString aTmpName; + if (aValue >>= aTmpName) + mpLayoutName.reset(new OUString(aTmpName)); + } + else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME)) + { + OUString aTmpName; + if (aValue >>= aTmpName) + mpSubtotalName.reset(new OUString(aTmpName)); + } else { DBG_ERROR("unknown property"); @@ -1652,6 +1712,10 @@ uno::Any SAL_CALL ScDPDimension::getPropertyValue( const rtl::OUString& aPropert else aRet <<= uno::Sequence(0); } + else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME)) + aRet <<= mpLayoutName.get() ? *mpLayoutName : OUString::createFromAscii(""); + else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME)) + aRet <<= mpSubtotalName.get() ? *mpSubtotalName : OUString::createFromAscii(""); else { DBG_ERROR("unknown property"); @@ -2155,7 +2219,11 @@ uno::Sequence SAL_CALL ScDPLevel::getResults() throw(uno::R return aRet; } - return pSource->GetData()->getDimensionName( nSrcDim ); // (original) dimension name + ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim); + if (!pDim) + return rtl::OUString(); + + return pDim->getName(); } void SAL_CALL ScDPLevel::setName( const ::rtl::OUString& /* rNewName */ ) throw(uno::RuntimeException) @@ -2258,6 +2326,20 @@ uno::Any SAL_CALL ScDPLevel::getPropertyValue( const rtl::OUString& aPropertyNam aRet <<= aAutoShowInfo; else if ( aNameStr.EqualsAscii( SC_UNO_LAYOUT ) ) aRet <<= aLayoutInfo; + else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME)) + { + // read only property + long nSrcDim = pSource->GetSourceDim(nDim); + ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim); + if (!pDim) + return aRet; + + const OUString* pLayoutName = pDim->GetLayoutName(); + if (!pLayoutName) + return aRet; + + aRet <<= *pLayoutName; + } else { DBG_ERROR("unknown property"); @@ -2550,6 +2632,7 @@ ScDPMember::ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL, nHier( nH ), nLev( nL ), maData( rN, fV, bHV ), + mpLayoutName(NULL), nPosition( -1 ), bVisible( TRUE ), bShowDet( TRUE ) @@ -2610,6 +2693,11 @@ void ScDPMember::FillItemData( ScDPItemData& rData ) const rData = maData; } +const OUString* ScDPMember::GetLayoutName() const +{ + return mpLayoutName.get(); +} + String ScDPMember::GetNameStr() const { return maData.aString; @@ -2669,6 +2757,7 @@ uno::Reference SAL_CALL ScDPMember::getPropertySetInfo( {MAP_CHAR_LEN(SC_UNO_ISVISIBL), 0, &getBooleanCppuType(), 0, 0 }, {MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNO_SHOWDETA), 0, &getBooleanCppuType(), 0, 0 }, + {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast(0)), 0, 0 }, {0,0,0,0,0,0} }; static uno::Reference aRef = @@ -2692,6 +2781,12 @@ void SAL_CALL ScDPMember::setPropertyValue( const rtl::OUString& aPropertyName, if (aValue >>= nInt) setPosition( nInt ); } + else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME)) + { + rtl::OUString aName; + if (aValue >>= aName) + mpLayoutName.reset(new rtl::OUString(aName)); + } else { DBG_ERROR("unknown property"); @@ -2711,6 +2806,8 @@ uno::Any SAL_CALL ScDPMember::getPropertyValue( const rtl::OUString& aPropertyNa lcl_SetBoolInAny( aRet, getShowDetails() ); else if ( aNameStr.EqualsAscii( SC_UNO_POSITION ) ) aRet <<= (sal_Int32) getPosition(); + else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME)) + aRet <<= mpLayoutName.get() ? *mpLayoutName : rtl::OUString(); else { DBG_ERROR("unknown property"); diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index d1ae00376cde..f87c12f8c26d 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -1178,6 +1178,9 @@ FltError ImportExcel8::Read( void ) eLastErr = SCWARN_IMPORT_ROW_OVERFLOW; else if( rAddrConv.IsColTruncated() ) eLastErr = SCWARN_IMPORT_COLUMN_OVERFLOW; + + if( GetBiff() == EXC_BIFF8 ) + GetPivotTableManager().MaybeRefreshPivotTables(); } return eLastErr; diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx index 0b10ded5aa9e..78bc0e0b2f99 100644 --- a/sc/source/filter/excel/xepivot.cxx +++ b/sc/source/filter/excel/xepivot.cxx @@ -67,6 +67,7 @@ using ::com::sun::star::sheet::DataPilotFieldSortInfo; using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo; using ::com::sun::star::sheet::DataPilotFieldLayoutInfo; using ::com::sun::star::sheet::DataPilotFieldReference; +using ::rtl::OUString; using ::rtl::OString; using ::rtl::OUString; @@ -972,6 +973,11 @@ void XclExpPTItem::SetPropertiesFromMember( const ScDPSaveMember& rSaveMem ) { ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN, !rSaveMem.GetIsVisible() ); ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL, !rSaveMem.GetShowDetails() ); + + // visible name + const OUString* pVisName = rSaveMem.GetLayoutName(); + if (pVisName && !pVisName->equals(GetItemName())) + maItemInfo.SetVisName(*pVisName); } void XclExpPTItem::WriteBody( XclExpStream& rStrm ) @@ -1040,8 +1046,13 @@ void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim ) ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL, rSaveDim.GetShowEmpty() ); // visible name - if( rSaveDim.HasLayoutName() && (rSaveDim.GetLayoutName() != GetFieldName()) ) - maFieldInfo.SetVisName( rSaveDim.GetLayoutName() ); + const OUString* pLayoutName = rSaveDim.GetLayoutName(); + if (pLayoutName && !pLayoutName->equals(GetFieldName())) + maFieldInfo.SetVisName(*pLayoutName); + + const rtl::OUString* pSubtotalName = rSaveDim.GetSubtotalName(); + if (pSubtotalName) + maFieldExtInfo.mpFieldTotalName.reset(new rtl::OUString(*pSubtotalName)); // subtotals XclPTSubtotalVec aSubtotals; @@ -1108,7 +1119,11 @@ void XclExpPTField::SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim rDataInfo.SetApiAggFunc( eFunc ); // visible name - rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) ); + const rtl::OUString* pVisName = rSaveDim.GetLayoutName(); + if (pVisName) + rDataInfo.SetVisName(*pVisName); + else + rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) ); // result field reference if( const DataPilotFieldReference* pFieldRef = rSaveDim.GetReferenceValue() ) @@ -1217,10 +1232,9 @@ XclExpPivotTable::XclExpPivotTable( const XclExpRoot& rRoot, const ScDPObject& r // pivot table properties from DP object mnOutScTab = rOutScRange.aStart.Tab(); maPTInfo.maTableName = rDPObj.GetName(); - maPTInfo.maDataName = ScGlobal::GetRscString( STR_PIVOT_DATA ); maPTInfo.mnCacheIdx = mrPCache.GetCacheIndex(); - maPTAutoFormat.Init( rDPObj ); + maPTViewEx9Info.Init( rDPObj ); if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() ) { @@ -1301,8 +1315,10 @@ void XclExpPivotTable::Save( XclExpStream& rStrm ) WriteSxli( rStrm, maPTInfo.mnDataCols, maPTInfo.mnColFields ); // SXEX WriteSxex( rStrm ); - // SX_AUTOFORMAT - WriteSxAutoformat( rStrm ); + // QSISXTAG + WriteQsiSxTag( rStrm ); + // SXVIEWEX9 + WriteSxViewEx9( rStrm ); } } @@ -1336,6 +1352,15 @@ void XclExpPivotTable::SetPropertiesFromDP( const ScDPSaveData& rSaveData ) ::set_flag( maPTInfo.mnFlags, EXC_SXVIEW_COLGRAND, rSaveData.GetColumnGrand() ); ::set_flag( maPTExtInfo.mnFlags, EXC_SXEX_DRILLDOWN, rSaveData.GetDrillDown() ); mbFilterBtn = rSaveData.GetFilterButton(); + const ScDPSaveDimension* pDim = rSaveData.GetExistingDataLayoutDimension(); + if (!pDim) + return; + + const rtl::OUString* pLayoutName = pDim->GetLayoutName(); + if (pLayoutName) + maPTInfo.maDataName = *pLayoutName; + else + maPTInfo.maDataName = ScGlobal::GetRscString(STR_PIVOT_DATA); } void XclExpPivotTable::SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim ) @@ -1443,17 +1468,21 @@ void XclExpPivotTable::Finalize() rnDataXclRow = rnXclRow1 + maPTInfo.mnColFields + 1; if( maDataFields.empty() ) ++rnDataXclRow; - if( 0 == maPTAutoFormat.mnGridLayout ) + + bool bExtraHeaderRow = (0 == maPTViewEx9Info.mnGridLayout && maPTInfo.mnColFields == 0); + if (bExtraHeaderRow) + // Insert an extra row only when there is no column field. ++rnDataXclRow; + rnXclCol2 = ::std::max( rnXclCol2, rnDataXclCol ); rnXclRow2 = ::std::max( rnXclRow2, rnDataXclRow ); maPTInfo.mnDataCols = rnXclCol2 - rnDataXclCol + 1; maPTInfo.mnDataRows = rnXclRow2 - rnDataXclRow + 1; // first heading - maPTInfo.mnFirstHeadRow = rnXclRow1 + 1; - if( 0 == maPTAutoFormat.mnGridLayout ) - maPTInfo.mnFirstHeadRow++; + maPTInfo.mnFirstHeadRow = rnXclRow1; + if (bExtraHeaderRow) + maPTInfo.mnFirstHeadRow += 2; } // records ---------------------------------------------------------------- @@ -1533,14 +1562,68 @@ void XclExpPivotTable::WriteSxex( XclExpStream& rStrm ) const rStrm.EndRecord(); } -void XclExpPivotTable::WriteSxAutoformat( XclExpStream& rStrm ) const +void XclExpPivotTable::WriteQsiSxTag( XclExpStream& rStrm ) const +{ + rStrm.StartRecord( 0x0802, 32 ); + + sal_uInt16 nRecordType = 0x0802; + sal_uInt16 nDummyFlags = 0x0000; + sal_uInt16 nTableType = 1; // 0 = query table : 1 = pivot table + + rStrm << nRecordType << nDummyFlags << nTableType; + + // General flags + bool bEnableRefresh = true; + bool bPCacheInvalid = false; + bool bOlapPTReport = false; + + sal_uInt16 nFlags = 0x0000; + if (bEnableRefresh) nFlags |= 0x0001; + if (bPCacheInvalid) nFlags |= 0x0002; + if (bOlapPTReport) nFlags |= 0x0004; + rStrm << nFlags; + + // Feature-specific options. The value differs depending on the table + // type, but we assume the table type is always pivot table. + sal_uInt32 nOptions = 0x00000000; + bool bNoStencil = false; + bool bHideTotal = false; + bool bEmptyRows = false; + bool bEmptyCols = false; + if (bNoStencil) nOptions |= 0x00000001; + if (bHideTotal) nOptions |= 0x00000002; + if (bEmptyRows) nOptions |= 0x00000008; + if (bEmptyCols) nOptions |= 0x00000010; + rStrm << nOptions; + + enum ExcelVersion + { + Excel2000 = 0, + ExcelXP = 1, + Excel2003 = 2, + Excel2007 = 3 + }; + ExcelVersion eXclVer = Excel2000; + sal_uInt8 nOffsetBytes = 16; + rStrm << static_cast(eXclVer) // version table last refreshed + << static_cast(eXclVer) // minimum version to refresh + << nOffsetBytes + << static_cast(eXclVer); // first version created + + rStrm << XclExpString(maPTInfo.maTableName); + rStrm << static_cast(0x0001); // no idea what this is for. + + rStrm.EndRecord(); +} + +void XclExpPivotTable::WriteSxViewEx9( XclExpStream& rStrm ) const { // Until we sync the autoformat ids only export if using grid header layout // That could only have been set via xls import so far. - if ( 0 == maPTAutoFormat.mnGridLayout ) + if ( 0 == maPTViewEx9Info.mnGridLayout ) { rStrm.StartRecord( EXC_ID_SXVIEWEX9, 17 ); - rStrm << maPTAutoFormat; + rStrm << maPTViewEx9Info; rStrm.EndRecord(); } } diff --git a/sc/source/filter/excel/xestring.cxx b/sc/source/filter/excel/xestring.cxx index 9af8dbfdd851..b657e3b1f1d0 100644 --- a/sc/source/filter/excel/xestring.cxx +++ b/sc/source/filter/excel/xestring.cxx @@ -423,7 +423,8 @@ void XclExpString::WriteFormats( XclExpStream& rStrm, bool bWriteSize ) const void XclExpString::Write( XclExpStream& rStrm ) const { - WriteHeader( rStrm ); + if (!mbSkipHeader) + WriteHeader( rStrm ); WriteBuffer( rStrm ); if( IsWriteFormats() ) // only in BIFF8 included in string WriteFormats( rStrm ); @@ -589,6 +590,7 @@ void XclExpString::Init( sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMax mbSmartFlags = bBiff8 && ::get_flag( nFlags, EXC_STR_SMARTFLAGS ); mbSkipFormats = ::get_flag( nFlags, EXC_STR_SEPARATEFORMATS ); mbWrapped = false; + mbSkipHeader = ::get_flag( nFlags, EXC_STR_NOHEADER ); mnMaxLen = nMaxLen; SetStrLen( nCurrLen ); diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index 495f73d75a68..29e20e52e64a 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -847,6 +847,11 @@ void XclImpPivotCache::ReadPivotCacheStream( XclImpStream& rStrm ) } } +bool XclImpPivotCache::IsRefreshOnLoad() const +{ + return static_cast(maPCInfo.mnFlags & 0x0004); +} + // ============================================================================ // Pivot table // ============================================================================ @@ -882,6 +887,8 @@ void XclImpPTItem::ConvertItem( ScDPSaveDimension& rSaveDim ) const ScDPSaveMember& rMember = *rSaveDim.GetMemberByName( *pItemName ); rMember.SetIsVisible( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN ) ); rMember.SetShowDetails( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL ) ); + if (maItemInfo.HasVisName()) + rMember.SetLayoutName(*maItemInfo.GetVisName()); } } @@ -1043,7 +1050,7 @@ ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) con // visible name if( const String* pVisName = maFieldInfo.GetVisName() ) if( pVisName->Len() > 0 ) - rSaveDim.SetLayoutName( pVisName ); + rSaveDim.SetLayoutName( *pVisName ); // subtotal function(s) XclPTSubtotalVec aSubtotalVec; @@ -1075,6 +1082,10 @@ ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) con // grouping info pCacheField->ConvertGroupField( rSaveData, mrPTable.GetVisFieldNames() ); + // custom subtotal name + if (maFieldExtInfo.mpFieldTotalName.get()) + rSaveDim.SetSubtotalName(*maFieldExtInfo.mpFieldTotalName); + return &rSaveDim; } @@ -1099,7 +1110,7 @@ void XclImpPTField::ConvertDataFieldInfo( ScDPSaveDimension& rSaveDim, const Xcl // visible name if( const String* pVisName = rDataInfo.GetVisName() ) if( pVisName->Len() > 0 ) - rSaveDim.SetLayoutName( pVisName ); + rSaveDim.SetLayoutName( *pVisName ); // aggregation function rSaveDim.SetFunction( static_cast< USHORT >( rDataInfo.GetApiAggFunc() ) ); @@ -1134,7 +1145,8 @@ void XclImpPTField::ConvertItems( ScDPSaveDimension& rSaveDim ) const XclImpPivotTable::XclImpPivotTable( const XclImpRoot& rRoot ) : XclImpRoot( rRoot ), - maDataOrientField( *this, EXC_SXIVD_DATA ) + maDataOrientField( *this, EXC_SXIVD_DATA ), + mpDPObj(NULL) { } @@ -1298,7 +1310,7 @@ void XclImpPivotTable::ReadSxex( XclImpStream& rStrm ) void XclImpPivotTable::ReadSxViewEx9( XclImpStream& rStrm ) { - rStrm >> maPTAutoFormat; + rStrm >> maPTViewEx9Info; } // ---------------------------------------------------------------------------- @@ -1336,11 +1348,14 @@ void XclImpPivotTable::Convert() if( const XclImpPTField* pField = GetField( *aIt ) ) pField->ConvertPageField( aSaveData ); +#if 0 // Why do we do this ??? + // hidden fields for( sal_uInt16 nField = 0, nCount = GetFieldCount(); nField < nCount; ++nField ) if( const XclImpPTField* pField = GetField( nField ) ) if( (pField->GetAxes() & EXC_SXVD_AXIS_ROWCOLPAGE) == 0 ) pField->ConvertHiddenField( aSaveData ); +#endif // data fields for( aIt = maFiltDataFields.begin(), aEnd = maFiltDataFields.end(); aIt != aEnd; ++aIt ) @@ -1364,12 +1379,30 @@ void XclImpPivotTable::Convert() // create the DataPilot ScDPObject* pDPObj = new ScDPObject( GetDocPtr() ); pDPObj->SetName( maPTInfo.maTableName ); + if (maPTInfo.maDataName.Len() > 0) + aSaveData.GetDataLayoutDimension()->SetLayoutName(maPTInfo.maDataName); + + if (maPTViewEx9Info.maGrandTotalName.Len() > 0) + aSaveData.SetGrandTotalName(maPTViewEx9Info.maGrandTotalName); + pDPObj->SetSaveData( aSaveData ); pDPObj->SetSheetDesc( aDesc ); pDPObj->SetOutRange( aOutRange ); pDPObj->SetAlive( TRUE ); - pDPObj->SetHeaderLayout( maPTAutoFormat.mnGridLayout == 0 ); + pDPObj->SetHeaderLayout( maPTViewEx9Info.mnGridLayout == 0 ); + GetDoc().GetDPCollection()->Insert( pDPObj ); + mpDPObj = pDPObj; +} + +void XclImpPivotTable::MaybeRefresh() +{ + if (mpDPObj && mxPCache->IsRefreshOnLoad()) + { + // 'refresh table on load' flag is set. Refresh the table now. Some + // Excel files contain partial table output when this flag is set. + mpDPObj->Output(); + } } // ============================================================================ @@ -1484,85 +1517,10 @@ void XclImpPivotTableManager::ConvertPivotTables() (*aIt)->Convert(); } -// ============================================================================ - -// Pivot table autoformat settings ============================================ - -/** -classic : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00 -default : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00 -report01 : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00 -report02 : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00 -report03 : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00 -report04 : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00 -report05 : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00 -report06 : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00 -report07 : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00 -report08 : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00 -report09 : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00 -report10 : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00 -table01 : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00 -table02 : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00 -table03 : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00 -table04 : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00 -table05 : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00 -table06 : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00 -table07 : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00 -table08 : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00 -table09 : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00 -table10 : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00 -none : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00 -**/ - -XclPTAutoFormat::XclPTAutoFormat() : - mbReport( 0 ), - mnAutoFormat( 0 ), - mnGridLayout( 0x10 ) -{ -} - -void XclPTAutoFormat::Init( const ScDPObject& rDPObj ) -{ - if( rDPObj.GetHeaderLayout() ) - { - mbReport = 0; - mnAutoFormat = 1; - mnGridLayout = 0; - } - else - { - // Report1 for now - // TODO : sync with autoformat indicies - mbReport = 2; - mnAutoFormat = 1; - mnGridLayout = 0x10; - } -} - -XclImpStream& operator>>( XclImpStream& rStrm, XclPTAutoFormat& rInfo ) -{ - rStrm.Ignore( 2 ); - rStrm >> rInfo.mbReport; /// 2 for report* fmts ? - rStrm.Ignore( 6 ); - sal_uInt8 nDummy; - return rStrm - >> rInfo.mnAutoFormat - >> rInfo.mnGridLayout - >> nDummy >> nDummy >> nDummy; -} - -XclExpStream& operator<<( XclExpStream& rStrm, const XclPTAutoFormat& rInfo ) +void XclImpPivotTableManager::MaybeRefreshPivotTables() { - return rStrm - << EXC_PT_AUTOFMT_HEADER - << rInfo.mbReport - << EXC_PT_AUTOFMT_ZERO - << EXC_PT_AUTOFMT_FLAGS - << rInfo.mnAutoFormat - << rInfo.mnGridLayout - << static_cast(0x00) - << static_cast(0x00) - << static_cast(0x00); + for( XclImpPivotTableVec::iterator aIt = maPTables.begin(), aEnd = maPTables.end(); aIt != aEnd; ++aIt ) + (*aIt)->MaybeRefresh(); } // ============================================================================ diff --git a/sc/source/filter/excel/xlpivot.cxx b/sc/source/filter/excel/xlpivot.cxx index d36950b2494d..8f5d026379d9 100644 --- a/sc/source/filter/excel/xlpivot.cxx +++ b/sc/source/filter/excel/xlpivot.cxx @@ -31,6 +31,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include "dpgroup.hxx" +#include "dpsave.hxx" #include "xestream.hxx" #include "xistream.hxx" #include "xestring.hxx" @@ -581,7 +582,9 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo ) XclPTFieldExtInfo::XclPTFieldExtInfo() : mnFlags( EXC_SXVDEX_DEFAULTFLAGS ), mnSortField( EXC_SXVDEX_SORT_OWN ), - mnShowField( EXC_SXVDEX_SHOW_NONE ) + mnShowField( EXC_SXVDEX_SHOW_NONE ), + mnNumFmt(0), + mpFieldTotalName(NULL) { } @@ -639,10 +642,19 @@ void XclPTFieldExtInfo::SetApiLayoutMode( sal_Int32 nLayoutMode ) XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo ) { - return rStrm - >> rInfo.mnFlags - >> rInfo.mnSortField - >> rInfo.mnShowField; + sal_uInt8 nNameLen = 0; + rStrm >> rInfo.mnFlags + >> rInfo.mnSortField + >> rInfo.mnShowField + >> rInfo.mnNumFmt + >> nNameLen; + + rStrm.Ignore(10); + if (nNameLen != 0xFF) + // Custom field total name is used. Pick it up. + rInfo.mpFieldTotalName.reset(new rtl::OUString(rStrm.ReadUniString(nNameLen, 0))); + + return rStrm; } XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo ) @@ -650,9 +662,23 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo ) rStrm << rInfo.mnFlags << rInfo.mnSortField << rInfo.mnShowField - << EXC_SXVDEX_FORMAT_NONE - << sal_uInt16( 0xFFFF ); // unknown - rStrm.WriteZeroBytes( 8 ); // unknown + << EXC_SXVDEX_FORMAT_NONE; + + if (rInfo.mpFieldTotalName.get() && rInfo.mpFieldTotalName->getLength() > 0) + { + rtl::OUString aFinalName = *rInfo.mpFieldTotalName; + if (aFinalName.getLength() >= 254) + aFinalName = aFinalName.copy(0, 254); + sal_uInt8 nNameLen = static_cast(aFinalName.getLength()); + rStrm << nNameLen; + rStrm.WriteZeroBytes(10); + rStrm << XclExpString(aFinalName, EXC_STR_NOHEADER); + } + else + { + rStrm << sal_uInt16(0xFFFF); + rStrm.WriteZeroBytes(8); + } return rStrm; } @@ -923,3 +949,86 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo ) // ============================================================================ +// Pivot table autoformat settings ============================================ + +/** +classic : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00 +default : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00 +report01 : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00 +report02 : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00 +report03 : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00 +report04 : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00 +report05 : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00 +report06 : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00 +report07 : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00 +report08 : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00 +report09 : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00 +report10 : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00 +table01 : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00 +table02 : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00 +table03 : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00 +table04 : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00 +table05 : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00 +table06 : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00 +table07 : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00 +table08 : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00 +table09 : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00 +table10 : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00 +none : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00 +**/ + +XclPTViewEx9Info::XclPTViewEx9Info() : + mbReport( 0 ), + mnAutoFormat( 0 ), + mnGridLayout( 0x10 ) +{ +} + +void XclPTViewEx9Info::Init( const ScDPObject& rDPObj ) +{ + if( rDPObj.GetHeaderLayout() ) + { + mbReport = 0; + mnAutoFormat = 1; + mnGridLayout = 0; + } + else + { + // Report1 for now + // TODO : sync with autoformat indicies + mbReport = 2; + mnAutoFormat = 1; + mnGridLayout = 0x10; + } + + const ScDPSaveData* pData = rDPObj.GetSaveData(); + if (pData) + { + const rtl::OUString* pGrandTotal = pData->GetGrandTotalName(); + if (pGrandTotal) + maGrandTotalName = *pGrandTotal; + } +} + +XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo ) +{ + rStrm.Ignore( 2 ); + rStrm >> rInfo.mbReport; /// 2 for report* fmts ? + rStrm.Ignore( 6 ); + rStrm >> rInfo.mnAutoFormat >> rInfo.mnGridLayout; + rInfo.maGrandTotalName = rStrm.ReadUniString(); + return rStrm; +} + +XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo ) +{ + return rStrm + << EXC_PT_AUTOFMT_HEADER + << rInfo.mbReport + << EXC_PT_AUTOFMT_ZERO + << EXC_PT_AUTOFMT_FLAGS + << rInfo.mnAutoFormat + << rInfo.mnGridLayout + << XclExpString(rInfo.maGrandTotalName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN); +} + diff --git a/sc/source/filter/inc/xepivot.hxx b/sc/source/filter/inc/xepivot.hxx index 67ef2ff6fcd8..e9d2403c29f2 100644 --- a/sc/source/filter/inc/xepivot.hxx +++ b/sc/source/filter/inc/xepivot.hxx @@ -412,8 +412,10 @@ private: void WriteSxli( XclExpStream& rStrm, sal_uInt16 nLineCount, sal_uInt16 nIndexCount ) const; /** Writes the SXEX records containing additional pivot table info. */ void WriteSxex( XclExpStream& rStrm ) const; + + void WriteQsiSxTag( XclExpStream& rStrm ) const; /** Writes the SX_AUTOFORMAT records with the autoformat id and header layout */ - void WriteSxAutoformat( XclExpStream& rStrm ) const; + void WriteSxViewEx9( XclExpStream& rStrm ) const; // ------------------------------------------------------------------------ private: @@ -424,7 +426,7 @@ private: const XclExpPivotCache& mrPCache; /// The pivot cache this pivot table bases on. XclPTInfo maPTInfo; /// Info about the pivot table (SXVIEW record). XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record). - XclPTAutoFormat maPTAutoFormat; /// The selected autoformat (SXVIEWEX9) + XclPTViewEx9Info maPTViewEx9Info; /// The selected autoformat (SXVIEWEX9) XclExpPTFieldList maFieldList; /// All fields in pivot cache order. ScfUInt16Vec maRowFields; /// Row field indexes. ScfUInt16Vec maColFields; /// Column field indexes. diff --git a/sc/source/filter/inc/xestring.hxx b/sc/source/filter/inc/xestring.hxx index 69a1a7af09fb..5fe5e4fb813f 100644 --- a/sc/source/filter/inc/xestring.hxx +++ b/sc/source/filter/inc/xestring.hxx @@ -323,6 +323,7 @@ private: bool mbSmartFlags; /// true = omit flags on empty string; false = always write flags. bool mbSkipFormats; /// true = skip formats on export; false = write complete formatted string. bool mbWrapped; /// true = text contains several paragraphs. + bool mbSkipHeader; /// ture = skip length and flags when writing string bytes. }; inline bool operator==( const XclExpString& rLeft, const XclExpString& rRight ) diff --git a/sc/source/filter/inc/xipivot.hxx b/sc/source/filter/inc/xipivot.hxx index 5a98c0793740..15227b8fb1a3 100644 --- a/sc/source/filter/inc/xipivot.hxx +++ b/sc/source/filter/inc/xipivot.hxx @@ -186,6 +186,8 @@ public: /** Reads the entire pivot cache stream. Uses decrypter from passed stream. */ void ReadPivotCacheStream( XclImpStream& rStrm ); + bool IsRefreshOnLoad() const; + private: typedef ::std::vector< XclImpPCFieldRef > XclImpPCFieldVec; @@ -359,6 +361,8 @@ public: /** Inserts the pivot table into the Calc document. */ void Convert(); + void MaybeRefresh(); + // ------------------------------------------------------------------------ private: typedef ::std::vector< XclImpPTFieldRef > XclImpPTFieldVec; @@ -367,7 +371,7 @@ private: XclPTInfo maPTInfo; /// General info about the pivot table (SXVIEW record). XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record). - XclPTAutoFormat maPTAutoFormat; /// The selected autoformat (SX_AUTOFORMAT) + XclPTViewEx9Info maPTViewEx9Info; /// (SXVIEWEX9 record) XclImpPTFieldVec maFields; /// Vector containing all fields. XclImpPTFieldRef mxCurrField; /// Current field for importing additional info. ScfStringVec maVisFieldNames; /// Vector containing all visible field names. @@ -378,6 +382,7 @@ private: ScfUInt16Vec maFiltDataFields; /// Filtered data field indexes. XclImpPTField maDataOrientField; /// Special data field orientation field. ScRange maOutScRange; /// Output range in the Calc document. + ScDPObject* mpDPObj; }; typedef ScfRef< XclImpPivotTable > XclImpPivotTableRef; @@ -437,6 +442,8 @@ public: /** Inserts all pivot tables into the Calc document. */ void ConvertPivotTables(); + void MaybeRefreshPivotTables(); + private: typedef ::std::vector< XclImpPivotCacheRef > XclImpPivotCacheVec; typedef ::std::vector< XclImpPivotTableRef > XclImpPivotTableVec; diff --git a/sc/source/filter/inc/xlpivot.hxx b/sc/source/filter/inc/xlpivot.hxx index 52251ed62294..3ea464e7b919 100644 --- a/sc/source/filter/inc/xlpivot.hxx +++ b/sc/source/filter/inc/xlpivot.hxx @@ -43,6 +43,8 @@ #include "xladdress.hxx" #include "dpobject.hxx" +#include + class XclImpStream; class XclExpStream; @@ -671,6 +673,8 @@ struct XclPTFieldExtInfo sal_uInt32 mnFlags; /// Several flags and number of items for AutoShow. sal_uInt16 mnSortField; /// Index to data field sorting bases on. sal_uInt16 mnShowField; /// Index to data field AutoShow bases on. + sal_uInt16 mnNumFmt; + ::std::auto_ptr mpFieldTotalName; explicit XclPTFieldExtInfo(); @@ -796,19 +800,20 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo ); // Pivot table autoformat settings ============================================== -/** Pivot table autoformat settings (SX_AUTOFORMAT record). */ -struct XclPTAutoFormat +/** Pivot table autoformat settings (SXVIEWEX9 record). */ +struct XclPTViewEx9Info { sal_uInt32 mbReport; /// 2 for report* fmts ? sal_uInt8 mnAutoFormat; /// AutoFormat ID sal_uInt8 mnGridLayout; /// 0 == gridlayout, 0x10 == modern + String maGrandTotalName; - explicit XclPTAutoFormat(); + explicit XclPTViewEx9Info(); void Init( const ScDPObject& rDPObj ); }; -XclImpStream& operator>>( XclImpStream& rStrm, XclPTAutoFormat& rInfo ); -XclExpStream& operator<<( XclExpStream& rStrm, const XclPTAutoFormat& rInfo ); +XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo ); +XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo ); // ============================================================================ #endif diff --git a/sc/source/filter/inc/xlstring.hxx b/sc/source/filter/inc/xlstring.hxx index 0970fafd1ed6..32ee23f83d85 100644 --- a/sc/source/filter/inc/xlstring.hxx +++ b/sc/source/filter/inc/xlstring.hxx @@ -43,6 +43,7 @@ const XclStrFlags EXC_STR_FORCEUNICODE = 0x0001; /// Always use UCS-2 cha const XclStrFlags EXC_STR_8BITLENGTH = 0x0002; /// 8-bit string length field (default: 16-bit). const XclStrFlags EXC_STR_SMARTFLAGS = 0x0004; /// Omit flags on empty string (default: read/write always). BIFF8 only. const XclStrFlags EXC_STR_SEPARATEFORMATS = 0x0008; /// Import: Keep old formats when reading unformatted string (default: clear formats); Export: Write unformatted string. +const XclStrFlags EXC_STR_NOHEADER = 0x0010; /// Export: Don't write the length and flag fields. // ---------------------------------------------------------------------------- diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx index d44791ff6972..dac8ee1e5e04 100644 --- a/sc/source/ui/dbgui/pvfundlg.cxx +++ b/sc/source/ui/dbgui/pvfundlg.cxx @@ -705,7 +705,9 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHOR maLbDims ( this, ScResId( LB_DIMS ) ), maBtnOk ( this, ScResId( BTN_OK ) ), maBtnCancel ( this, ScResId( BTN_CANCEL ) ), - maBtnHelp ( this, ScResId( BTN_HELP ) ) + maBtnHelp ( this, ScResId( BTN_HELP ) ), + + mrDPObj(rDPObj) { FreeResource(); @@ -719,7 +721,13 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHOR { const ScDPSaveDimension* pDimension = pSaveData ? pSaveData->GetExistingDimensionByName(aName) : 0; if ( !pDimension || (pDimension->GetOrientation() != nOrient) ) + { + const OUString* pLayoutName = pDimension->GetLayoutName(); + if (pLayoutName) + aName = *pLayoutName; maLbDims.InsertEntry( aName ); + maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim)); + } } } if( maLbDims.GetEntryCount() ) @@ -735,7 +743,17 @@ short ScDPShowDetailDlg::Execute() String ScDPShowDetailDlg::GetDimensionName() const { - return maLbDims.GetSelectEntry(); + // Look up the internal dimension name which may be different from the + // displayed field name. + String aSelectedName = maLbDims.GetSelectEntry(); + DimNameIndexMap::const_iterator itr = maNameIndexMap.find(aSelectedName); + if (itr == maNameIndexMap.end()) + // This should never happen! + return aSelectedName; + + long nDim = itr->second; + BOOL bIsDataLayout = false; + return mrDPObj.GetDimName(nDim, bIsDataLayout); } IMPL_LINK( ScDPShowDetailDlg, DblClickHdl, ListBox*, pLBox ) diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx index 7b03e067a865..c23068b82200 100644 --- a/sc/source/ui/dbgui/pvlaydlg.cxx +++ b/sc/source/ui/dbgui/pvlaydlg.cxx @@ -63,6 +63,7 @@ #include "sc.hrc" //CHINA001 #include "scabstdlg.hxx" //CHINA001 using namespace com::sun::star; +using ::rtl::OUString; //---------------------------------------------------------------------------- @@ -1491,6 +1492,8 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG ) nPageCount, nColCount, nRowCount, nDataCount ); if ( bFit ) { + ScDPSaveData* pOldSaveData = xDlgDPObject->GetSaveData(); + ScRange aOutRange( aAdrDest ); // bToNewTable is passed separately ScDPSaveData aSaveData; @@ -1522,6 +1525,22 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG ) pDim->SetSortInfo( &aIt->maSortInfo ); pDim->SetLayoutInfo( &aIt->maLayoutInfo ); pDim->SetAutoShowInfo( &aIt->maShowInfo ); + ScDPSaveDimension* pOldDim = NULL; + if (pOldSaveData) + { + // Transfer the existing layout names to new dimension instance. + pOldDim = pOldSaveData->GetExistingDimensionByName(aIt->maName); + if (pOldDim) + { + const OUString* pLayoutName = pOldDim->GetLayoutName(); + if (pLayoutName) + pDim->SetLayoutName(*pLayoutName); + + const OUString* pSubtotalName = pOldDim->GetSubtotalName(); + if (pSubtotalName) + pDim->SetSubtotalName(*pSubtotalName); + } + } bool bManualSort = ( aIt->maSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL ); @@ -1542,11 +1561,33 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG ) ScDPSaveMember* pMember = pDim->GetMemberByName( *pItem ); pMember->SetIsVisible( bIsVisible ); pMember->SetShowDetails( bShowDetails ); + if (pOldDim) + { + // Transfer the existing layout name. + ScDPSaveMember* pOldMember = pOldDim->GetMemberByName(*pItem); + if (pOldMember) + { + const OUString* pLayoutName = pOldMember->GetLayoutName(); + if (pLayoutName) + pMember->SetLayoutName(*pLayoutName); + } + } } } } } } + ScDPSaveDimension* pDim = aSaveData.GetDataLayoutDimension(); + if (pDim && pOldSaveData) + { + ScDPSaveDimension* pOldDim = pOldSaveData->GetDataLayoutDimension(); + if (pOldDim) + { + const OUString* pLayoutName = pOldDim->GetLayoutName(); + if (pLayoutName) + pDim->SetLayoutName(*pLayoutName); + } + } USHORT nWhichPivot = SC_MOD()->GetPool().GetWhich( SID_PIVOT_TABLE ); ScPivotItem aOutItem( nWhichPivot, &aSaveData, &aOutRange, bToNewTable ); diff --git a/sc/source/ui/inc/pvfundlg.hxx b/sc/source/ui/inc/pvfundlg.hxx index eeeb9c4094c4..6b9aa62c37a3 100644 --- a/sc/source/ui/inc/pvfundlg.hxx +++ b/sc/source/ui/inc/pvfundlg.hxx @@ -55,6 +55,8 @@ #include #include "pivot.hxx" +#include + // ============================================================================ typedef sfx::ListBoxWrapper< sal_Int32 > ScDPListBoxWrapper; @@ -217,6 +219,11 @@ public: virtual short Execute(); + /** + * @return String internal name of the selected field. Note that this may + * be different from the name displayed in the dialog if the field + * has a layout name. + */ String GetDimensionName() const; private: @@ -228,6 +235,10 @@ private: OKButton maBtnOk; CancelButton maBtnCancel; HelpButton maBtnHelp; + + typedef ::std::hash_map DimNameIndexMap; + DimNameIndexMap maNameIndexMap; + ScDPObject& mrDPObj; }; // ============================================================================ diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index c68baf36ba2b..c52921f7c5de 100644 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -1626,8 +1626,13 @@ OUString SAL_CALL ScDataPilotFieldObj::getName() throw(RuntimeException) if( pDim->IsDataLayout() ) aName = OUString( RTL_CONSTASCII_USTRINGPARAM( SC_DATALAYOUT_NAME ) ); else - aName = pDim->GetLayoutName(); - } + { + const rtl::OUString* pLayoutName = pDim->GetLayoutName(); + if (pLayoutName) + aName = *pLayoutName; + else + aName = pDim->GetName(); + } } return aName; } @@ -1639,7 +1644,7 @@ void SAL_CALL ScDataPilotFieldObj::setName( const OUString& rName ) throw(Runtim if( pDim && !pDim->IsDataLayout() ) { String aName( rName ); - pDim->SetLayoutName( &aName ); + pDim->SetLayoutName(aName); SetDPObject( pDPObj ); } } diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 8dcb47c927a2..41a5e9d0e050 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -91,6 +91,10 @@ using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::beans::XPropertySet; +using ::com::sun::star::container::XNameAccess; +using ::com::sun::star::sheet::XDimensionsSupplier; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; using ::std::auto_ptr; // STATIC DATA ----------------------------------------------------------- @@ -1351,123 +1355,304 @@ void ScDBFunc::UngroupDataPilot() } } +OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName) +{ + sal_Int32 n = rSubtotal.getLength(); + const sal_Unicode* p = rSubtotal.getStr(); + OUStringBuffer aBuf, aWordBuf; + for (sal_Int32 i = 0; i < n; ++i) + { + sal_Unicode c = p[i]; + if (c == sal_Unicode(' ')) + { + OUString aWord = aWordBuf.makeStringAndClear(); + if (aWord.equals(rMemberName)) + aBuf.append(sal_Unicode('?')); + else + aBuf.append(aWord); + aBuf.append(c); + } + else + aWordBuf.append(c); + } + + if (aWordBuf.getLength() > 0) + { + OUString aWord = aWordBuf.makeStringAndClear(); + if (aWord.equals(rMemberName)) + aBuf.append(sal_Unicode('?')); + else + aBuf.append(aWord); + } + + return aBuf.makeStringAndClear(); +} + void ScDBFunc::DataPilotInput( const ScAddress& rPos, const String& rString ) { + using namespace ::com::sun::star::sheet; + String aNewName( rString ); ScDocument* pDoc = GetViewData()->GetDocument(); ScDPObject* pDPObj = pDoc->GetDPAtCursor( rPos.Col(), rPos.Row(), rPos.Tab() ); - if ( pDPObj ) + if (!pDPObj) + return; + + String aOldText; + pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText ); + + if ( aOldText == rString ) { - String aOldText; - pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText ); + // nothing to do: silently exit + return; + } - if ( aOldText == rString ) + USHORT nErrorId = 0; + + pDPObj->BuildAllDimensionMembers(); + ScDPSaveData aData( *pDPObj->GetSaveData() ); + BOOL bChange = FALSE; + + USHORT nOrient = DataPilotFieldOrientation_HIDDEN; + long nField = pDPObj->GetHeaderDim( rPos, nOrient ); + if ( nField >= 0 ) + { + // changing a field title + if ( aData.GetExistingDimensionData() ) { - // nothing to do: silently exit - return; - } + // only group dimensions can be renamed - USHORT nErrorId = 0; + ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); + ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText ); + if ( pGroupDim ) + { + // valid name: not empty, no existing dimension (group or other) + if ( rString.Len() && !pDPObj->IsDimNameInUse(rString) ) + { + pGroupDim->Rename( aNewName ); - ScDPSaveData aData( *pDPObj->GetSaveData() ); - BOOL bChange = FALSE; + // also rename in SaveData to preserve the field settings + ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText ); + pSaveDim->SetName( aNewName ); - USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN; - long nField = pDPObj->GetHeaderDim( rPos, nOrient ); - if ( nField >= 0 ) + bChange = TRUE; + } + else + nErrorId = STR_INVALIDNAME; + } + } + else if (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW) + { + BOOL bDataLayout = false; + String aDimName = pDPObj->GetDimName(nField, bDataLayout); + ScDPSaveDimension* pDim = bDataLayout ? aData.GetDataLayoutDimension() : aData.GetDimensionByName(aDimName); + if (pDim) + { + if (rString.Len()) + { + if (rString.EqualsIgnoreCaseAscii(aDimName)) + { + pDim->RemoveLayoutName(); + bChange = true; + } + else if (!pDPObj->IsDimNameInUse(rString)) + { + pDim->SetLayoutName(rString); + bChange = true; + } + else + nErrorId = STR_INVALIDNAME; + } + else + nErrorId = STR_INVALIDNAME; + } + } + } + else if (pDPObj->IsDataDescriptionCell(rPos)) + { + // There is only one data dimension. + ScDPSaveDimension* pDim = aData.GetFirstDimension(sheet::DataPilotFieldOrientation_DATA); + if (pDim) { - // changing a field title + if (rString.Len()) + { + if (rString.EqualsIgnoreCaseAscii(pDim->GetName())) + { + pDim->RemoveLayoutName(); + bChange = true; + } + else if (!pDPObj->IsDimNameInUse(rString)) + { + pDim->SetLayoutName(rString); + bChange = true; + } + else + nErrorId = STR_INVALIDNAME; + } + else + nErrorId = STR_INVALIDNAME; + } + } + else + { + // This is not a field header. + sheet::DataPilotTableHeaderData aPosData; + pDPObj->GetHeaderPositionData(rPos, aPosData); - if ( aData.GetExistingDimensionData() ) + if ( (aPosData.Flags & MemberResultFlags::HASMEMBER) && aOldText.Len() ) + { + if ( aData.GetExistingDimensionData() && !(aPosData.Flags & MemberResultFlags::SUBTOTAL)) { - // only group dimensions can be renamed + BOOL bIsDataLayout; + String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout ); ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); - ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText ); + ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName ); if ( pGroupDim ) { - // valid name: not empty, no existing dimension (group or other) - if ( aNewName.Len() && !pDPObj->IsDimNameInUse( aNewName ) ) + // valid name: not empty, no existing group in this dimension + //! ignore case? + if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) ) { - pGroupDim->Rename( aNewName ); + ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText ); + if ( pGroup ) + pGroup->Rename( aNewName ); // rename the existing group + else + { + // create a new group to replace the automatic group + ScDPSaveGroupItem aGroup( aNewName ); + aGroup.AddElement( aOldText ); + pGroupDim->AddGroupItem( aGroup ); + } - // also rename in SaveData to preserve the field settings - ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText ); - pSaveDim->SetName( aNewName ); + // in both cases also adjust savedata, to preserve member settings (show details) + ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName ); + ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText ); + if ( pSaveMember ) + pSaveMember->SetName( aNewName ); bChange = TRUE; } else nErrorId = STR_INVALIDNAME; - } + } } - } - else - { - // renaming a group (item)? - // allow only on the item name itself - not on empty cells, not on subtotals - - sheet::DataPilotTableHeaderData aPosData; - pDPObj->GetHeaderPositionData(rPos, aPosData); - if ( ( aPosData.Flags & sheet::MemberResultFlags::HASMEMBER ) && - ! ( aPosData.Flags & sheet::MemberResultFlags::SUBTOTAL ) && - aOldText.Len() ) + else if ((aPosData.Flags & MemberResultFlags::GRANDTOTAL)) { - if ( aData.GetExistingDimensionData() ) + aData.SetGrandTotalName(rString); + bChange = true; + } + else if (aPosData.Dimension >= 0 && aPosData.MemberName.getLength() > 0) + { + BOOL bDataLayout = false; + String aDimName = pDPObj->GetDimName(static_cast(aPosData.Dimension), bDataLayout); + if (bDataLayout) { - BOOL bIsDataLayout; - String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout ); + // data dimension + do + { + if ((aPosData.Flags & MemberResultFlags::SUBTOTAL)) + break; + + ScDPSaveDimension* pDim = aData.GetDimensionByName(aPosData.MemberName); + if (!pDim) + break; - ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); - ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName ); - if ( pGroupDim ) + if (!rString.Len()) + { + nErrorId = STR_INVALIDNAME; + break; + } + + if (aPosData.MemberName.equalsIgnoreAsciiCase(rString)) + { + pDim->RemoveLayoutName(); + bChange = true; + } + else if (!pDPObj->IsDimNameInUse(rString)) + { + pDim->SetLayoutName(rString); + bChange = true; + } + else + nErrorId = STR_INVALIDNAME; + } + while (false); + } + else + { + // field member + do { - // valid name: not empty, no existing group in this dimension - //! ignore case? - if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) ) + ScDPSaveDimension* pDim = aData.GetDimensionByName(aDimName); + if (!pDim) + break; + + ScDPSaveMember* pMem = pDim->GetExistingMemberByName(aPosData.MemberName); + if (!pMem) + break; + + if ((aPosData.Flags & MemberResultFlags::SUBTOTAL)) { - ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText ); - if ( pGroup ) - pGroup->Rename( aNewName ); // rename the existing group + // Change subtotal only when the table has one data dimension. + if (aData.GetDataDimensionCount() > 1) + break; + + const OUString* pLayoutName = pMem->GetLayoutName(); + String aMemberName; + if (pLayoutName) + aMemberName = *pLayoutName; else - { - // create a new group to replace the automatic group - ScDPSaveGroupItem aGroup( aNewName ); - aGroup.AddElement( aOldText ); - pGroupDim->AddGroupItem( aGroup ); - } + aMemberName = aPosData.MemberName; - // in both cases also adjust savedata, to preserve member settings (show details) - ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName ); - ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText ); - if ( pSaveMember ) - pSaveMember->SetName( aNewName ); - - bChange = TRUE; + String aNew = lcl_replaceMemberNameInSubtotal(rString, aMemberName); + pDim->SetSubtotalName(aNew); + bChange = true; } else - nErrorId = STR_INVALIDNAME; + { + // Check to make sure the member name isn't + // already used. + if (rString.Len()) + { + if (rString.EqualsIgnoreCaseAscii(pMem->GetName())) + { + pMem->RemoveLayoutName(); + bChange = true; + } + else if (!pDim->IsMemberNameInUse(rString)) + { + pMem->SetLayoutName(rString); + bChange = true; + } + else + nErrorId = STR_INVALIDNAME; + } + else + nErrorId = STR_INVALIDNAME; + } } + while (false); } } } + } - if ( bChange ) - { - // apply changes - ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); - ScDPObject* pNewObj = new ScDPObject( *pDPObj ); - pNewObj->SetSaveData( aData ); - aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE ); - delete pNewObj; - } - else - { - if ( !nErrorId ) - nErrorId = STR_ERR_DATAPILOT_INPUT; - ErrorMessage( nErrorId ); - } + if ( bChange ) + { + // apply changes + ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); + ScDPObject* pNewObj = new ScDPObject( *pDPObj ); + pNewObj->SetSaveData( aData ); + aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE ); + delete pNewObj; + } + else + { + if ( !nErrorId ) + nErrorId = STR_ERR_DATAPILOT_INPUT; + ErrorMessage( nErrorId ); } } -- cgit From 01414574680d3090b3b6631f2956469e023fb0bb Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 19 Jun 2009 02:56:29 +0000 Subject: Store custom display names with ods documents. Note that this relies on proposed file format change that is not yet officially in the ODF spec. --- sc/source/core/data/dptabres.cxx | 14 ++- sc/source/filter/excel/xepivot.cxx | 30 ++++- sc/source/filter/excel/xipivot.cxx | 28 ++++- sc/source/filter/xml/XMLExportDataPilot.cxx | 39 +++++- sc/source/filter/xml/XMLExportDataPilot.hxx | 3 + sc/source/filter/xml/xmldpimp.cxx | 181 +++++++++++++++++++++++++--- sc/source/filter/xml/xmldpimp.hxx | 41 +++++++ sc/source/filter/xml/xmlimprt.cxx | 23 ++++ sc/source/filter/xml/xmlimprt.hxx | 15 ++- sc/source/ui/view/dbfunc3.cxx | 14 ++- 10 files changed, 360 insertions(+), 28 deletions(-) (limited to 'sc') diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx index 07a783bdb2b1..e548db56d7ff 100644 --- a/sc/source/core/data/dptabres.cxx +++ b/sc/source/core/data/dptabres.cxx @@ -1186,20 +1186,28 @@ void ScDPResultMember::ProcessData( const vector& aChildMembers, c } /** - * Parse subtotal string and replace all occurrences of '?' with the - * caption string. + * Parse subtotal string and replace all occurrences of '?' with the caption + * string. Do ensure that escaped characters are not translated. */ static String lcl_parseSubtotalName(const String& rSubStr, const String& rCaption) { String aNewStr; xub_StrLen n = rSubStr.Len(); + bool bEscaped = false; for (xub_StrLen i = 0; i < n; ++i) { sal_Unicode c = rSubStr.GetChar(i); - if (c == sal_Unicode('?')) + if (!bEscaped && c == sal_Unicode('\\')) + { + bEscaped = true; + continue; + } + + if (!bEscaped && c == sal_Unicode('?')) aNewStr.Append(rCaption); else aNewStr.Append(c); + bEscaped = false; } return aNewStr; } diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx index 78bc0e0b2f99..80af288cce99 100644 --- a/sc/source/filter/excel/xepivot.cxx +++ b/sc/source/filter/excel/xepivot.cxx @@ -1035,6 +1035,31 @@ sal_uInt16 XclExpPTField::GetItemIndex( const String& rName, sal_uInt16 nDefault // fill data -------------------------------------------------------------- +/** + * Calc's subtotal names are escaped with backslashes ('\'), while Excel's + * are not escaped at all. + */ +static OUString lcl_convertCalcSubtotalName(const OUString& rName) +{ + OUStringBuffer aBuf; + const sal_Unicode* p = rName.getStr(); + sal_Int32 n = rName.getLength(); + bool bEscaped = false; + for (sal_Int32 i = 0; i < n; ++i) + { + const sal_Unicode c = p[i]; + if (!bEscaped && c == sal_Unicode('\\')) + { + bEscaped = true; + continue; + } + + aBuf.append(c); + bEscaped = false; + } + return aBuf.makeStringAndClear(); +} + void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim ) { // orientation @@ -1052,7 +1077,10 @@ void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim ) const rtl::OUString* pSubtotalName = rSaveDim.GetSubtotalName(); if (pSubtotalName) - maFieldExtInfo.mpFieldTotalName.reset(new rtl::OUString(*pSubtotalName)); + { + OUString aSubName = lcl_convertCalcSubtotalName(*pSubtotalName); + maFieldExtInfo.mpFieldTotalName.reset(new rtl::OUString(aSubName)); + } // subtotals XclPTSubtotalVec aSubtotals; diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index 29e20e52e64a..e6bf8ea01a2f 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -61,6 +61,7 @@ #include "xltable.hxx" using ::rtl::OUString; +using ::rtl::OUStringBuffer; using ::com::sun::star::sheet::DataPilotFieldOrientation; using ::com::sun::star::sheet::DataPilotFieldOrientation_DATA; using ::com::sun::star::sheet::DataPilotFieldSortInfo; @@ -1029,6 +1030,28 @@ void XclImpPTField::ConvertDataField( ScDPSaveData& rSaveData ) const // private -------------------------------------------------------------------- +/** + * Convert Excel-encoded subtotal name to a Calc-encoded one. + */ +static OUString lcl_convertExcelSubtotalName(const OUString& rName) +{ + OUStringBuffer aBuf; + const sal_Unicode* p = rName.getStr(); + sal_Int32 n = rName.getLength(); + for (sal_Int32 i = 0; i < n; ++i) + { + const sal_Unicode c = p[i]; + if (c == sal_Unicode('\\')) + { + aBuf.append(c); + aBuf.append(c); + } + else + aBuf.append(c); + } + return aBuf.makeStringAndClear(); +} + ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) const { const String& rFieldName = GetFieldName(); @@ -1084,7 +1107,10 @@ ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) con // custom subtotal name if (maFieldExtInfo.mpFieldTotalName.get()) - rSaveDim.SetSubtotalName(*maFieldExtInfo.mpFieldTotalName); + { + OUString aSubName = lcl_convertExcelSubtotalName(*maFieldExtInfo.mpFieldTotalName); + rSaveDim.SetSubtotalName(aSubName); + } return &rSaveDim; } diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx index 32cf92e08d1a..318606ca3c49 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.cxx +++ b/sc/source/filter/xml/XMLExportDataPilot.cxx @@ -68,6 +68,7 @@ using namespace com::sun::star; using namespace xmloff::token; +using ::rtl::OUString; ScXMLExportDataPilot::ScXMLExportDataPilot(ScXMLExport& rTempExport) : rExport(rTempExport), @@ -448,7 +449,10 @@ void ScXMLExportDataPilot::WriteLayoutInfo(ScDPSaveDimension* pDim) void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim) { + using sheet::GeneralFunction; + sal_Int32 nSubTotalCount = pDim->GetSubTotalsCount(); + const OUString* pLayoutName = pDim->GetSubtotalName(); if (nSubTotalCount > 0) { SvXMLElementExport aElemSTs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, sal_True, sal_True); @@ -456,8 +460,11 @@ void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim) for (sal_Int32 nSubTotal = 0; nSubTotal < nSubTotalCount; nSubTotal++) { rtl::OUString sFunction; - ScXMLConverter::GetStringFromFunction( sFunction, (sheet::GeneralFunction)pDim->GetSubTotalFunc(nSubTotal) ); + GeneralFunction nFunc = static_cast(pDim->GetSubTotalFunc(nSubTotal)); + ScXMLConverter::GetStringFromFunction( sFunction, nFunc); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction); + if (pLayoutName && nFunc == sheet::GeneralFunction_AUTO) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pLayoutName); SvXMLElementExport aElemST(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, sal_True, sal_True); } } @@ -473,6 +480,9 @@ void ScXMLExportDataPilot::WriteMembers(ScDPSaveDimension* pDim) for (ScDPSaveDimension::MemberList::const_iterator i=rMembers.begin(); i != rMembers.end() ; i++) { rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString((*i)->GetName())); + const OUString* pLayoutName = (*i)->GetLayoutName(); + if (pLayoutName) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pLayoutName); rtl::OUStringBuffer sBuffer; SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetIsVisible()); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear()); @@ -670,6 +680,10 @@ void ScXMLExportDataPilot::WriteGroupDimElements(ScDPSaveDimension* pDim, const void ScXMLExportDataPilot::WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData) { rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, rtl::OUString(pDim->GetName())); + const OUString* pLayoutName = pDim->GetLayoutName(); + if (pLayoutName) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pLayoutName); + if (pDim->IsDataLayout()) rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TRUE); rtl::OUString sValueStr; @@ -707,6 +721,15 @@ void ScXMLExportDataPilot::WriteDimensions(ScDPSaveData* pDPSave) } } +void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const OUString* pGrandTotal) +{ + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, bVisible ? XML_TRUE : XML_FALSE); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, eOrient); + if (pGrandTotal) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pGrandTotal); + SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True); +} + void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference & /* xSpreadDoc */) { pDoc = rExport.GetDocument(); @@ -775,6 +798,20 @@ void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference GetDrillDown()) rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DRILL_DOWN_ON_DOUBLE_CLICK, XML_FALSE); SvXMLElementExport aElemDP(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLE, sal_True, sal_True); + + // grand total elements. + + const OUString* pGrandTotalName = pDPSave->GetGrandTotalName(); + if (bRowGrand && bColumnGrand) + { + WriteGrandTotal(XML_BOTH, true, pGrandTotalName); + } + else + { + WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName); + WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName); + } + rExport.CheckAttrList(); if ((*pDPs)[i]->IsSheetData()) { diff --git a/sc/source/filter/xml/XMLExportDataPilot.hxx b/sc/source/filter/xml/XMLExportDataPilot.hxx index fb78a59d616b..8bf884ab2fd6 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.hxx +++ b/sc/source/filter/xml/XMLExportDataPilot.hxx @@ -34,6 +34,7 @@ #include #include #include "global.hxx" +#include "xmloff/xmltoken.hxx" class ScXMLExport; class ScDocument; @@ -69,6 +70,8 @@ class ScXMLExportDataPilot void WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData); void WriteDimensions(ScDPSaveData* pDPSave); + void WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const ::rtl::OUString* pGrandTotal); + public: ScXMLExportDataPilot(ScXMLExport& rExport); ~ScXMLExportDataPilot(); diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index 428e369a94dc..9cdca232c25a 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -65,6 +65,8 @@ using namespace com::sun::star; using namespace xmloff::token; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::xml::sax::XAttributeList; using ::rtl::OUString; //------------------------------------------------------------------ @@ -113,6 +115,9 @@ void ScXMLDataPilotTablesContext::EndElement() { } +ScXMLDataPilotTableContext::GrandTotalItem::GrandTotalItem() : + mbVisible(false) {} + ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName, @@ -159,6 +164,19 @@ ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport, case XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL : { sGrandTotal = sValue; + if (IsXMLToken(sValue, XML_BOTH)) + { + maRowGrandTotal.mbVisible = true; + maColGrandTotal.mbVisible = true; + } + else if (IsXMLToken(sValue, XML_ROW)) + { + maRowGrandTotal.mbVisible = true; + } + else if (IsXMLToken(sValue, XML_COLUMN)) + { + maColGrandTotal.mbVisible = true; + } } break; case XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS : @@ -238,6 +256,11 @@ SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( USHORT nPref nSourceType = SERVICE; } break; + case XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL: + { + pContext = new ScXMLDataPilotGrandTotalContext(GetScImport(), nPrefix, rLName, xAttrList, this); + } + break; case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE : { pContext = new ScXMLSourceCellRangeContext(GetScImport(), nPrefix, rLName, xAttrList, this); @@ -362,26 +385,15 @@ void ScXMLDataPilotTableContext::EndElement() } break; } - if (IsXMLToken(sGrandTotal, XML_BOTH)) - { - pDPSave->SetRowGrand(sal_True); - pDPSave->SetColumnGrand(sal_True); - } - else if (IsXMLToken(sGrandTotal, XML_ROW)) - { - pDPSave->SetRowGrand(sal_True); - pDPSave->SetColumnGrand(sal_False); - } - else if (IsXMLToken(sGrandTotal, XML_COLUMN)) - { - pDPSave->SetRowGrand(sal_False); - pDPSave->SetColumnGrand(sal_True); - } - else - { - pDPSave->SetRowGrand(sal_False); - pDPSave->SetColumnGrand(sal_False); - } + + pDPSave->SetRowGrand(maRowGrandTotal.mbVisible); + pDPSave->SetColumnGrand(maColGrandTotal.mbVisible); + if (maRowGrandTotal.maDisplayName.getLength()) + // TODO: Right now, we only support one grand total name for both + // column and row totals. Take the value from the row total for + // now. + pDPSave->SetGrandTotalName(maRowGrandTotal.maDisplayName); + pDPSave->SetIgnoreEmptyRows(bIgnoreEmptyRows); pDPSave->SetRepeatIfEmpty(bIdentifyCategories); pDPSave->SetFilterButton(bShowFilter); @@ -399,6 +411,30 @@ void ScXMLDataPilotTableContext::EndElement() } } +void ScXMLDataPilotTableContext::SetGrandTotal( + XMLTokenEnum eOrientation, bool bVisible, const OUString& rDisplayName) +{ + switch (eOrientation) + { + case XML_BOTH: + maRowGrandTotal.mbVisible = bVisible; + maRowGrandTotal.maDisplayName = rDisplayName; + maColGrandTotal.mbVisible = bVisible; + maColGrandTotal.maDisplayName = rDisplayName; + break; + case XML_ROW: + maRowGrandTotal.mbVisible = bVisible; + maRowGrandTotal.maDisplayName = rDisplayName; + break; + case XML_COLUMN: + maColGrandTotal.mbVisible = bVisible; + maColGrandTotal.maDisplayName = rDisplayName; + break; + default: + ; + } +} + ScXMLDPSourceSQLContext::ScXMLDPSourceSQLContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName, @@ -643,6 +679,80 @@ void ScXMLSourceServiceContext::EndElement() { } +ScXMLImport& ScXMLDataPilotGrandTotalContext::GetScImport() +{ + return static_cast(GetImport()); +} + +ScXMLDataPilotGrandTotalContext::ScXMLDataPilotGrandTotalContext( + ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName, const Reference& xAttrList, + ScXMLDataPilotTableContext* pTableContext ) : + SvXMLImportContext( rImport, nPrefix, rLName ), + mpTableContext(pTableContext), + meOrientation(NONE), + mbVisible(false) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotGrandTotalAttrTokenMap(); + for (sal_Int16 i = 0; i < nAttrCount; ++i) + { + const OUString& rAttrName = xAttrList->getNameByIndex(i); + const OUString& rAttrValue = xAttrList->getValueByIndex(i); + + OUString aLocalName; + USHORT nLocalPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName); + switch (rAttrTokenMap.Get(nLocalPrefix, aLocalName)) + { + case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY: + mbVisible = IsXMLToken(rAttrValue, XML_TRUE); + break; + case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION: + if (IsXMLToken(rAttrValue, XML_BOTH)) + meOrientation = BOTH; + else if (IsXMLToken(rAttrValue, XML_ROW)) + meOrientation = ROW; + else if (IsXMLToken(rAttrValue, XML_COLUMN)) + meOrientation = COLUMN; + break; + case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME: + maDisplayName = rAttrValue; + break; + default: + ; + } + } +} + +ScXMLDataPilotGrandTotalContext::~ScXMLDataPilotGrandTotalContext() +{ +} + +SvXMLImportContext* ScXMLDataPilotGrandTotalContext::CreateChildContext( + USHORT /*nPrefix*/, const ::rtl::OUString& /*rLocalName*/, const Reference& /*xAttrList*/ ) +{ + return NULL; +} + +void ScXMLDataPilotGrandTotalContext::EndElement() +{ + XMLTokenEnum eOrient = XML_NONE; + switch (meOrientation) + { + case BOTH: + eOrient = XML_BOTH; + break; + case ROW: + eOrient = XML_ROW; + break; + case COLUMN: + eOrient = XML_COLUMN; + break; + default: + ; + } + mpTableContext->SetGrandTotal(eOrient, mbVisible, maDisplayName); +} + ScXMLSourceCellRangeContext::ScXMLSourceCellRangeContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName, @@ -727,6 +837,7 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport, { sal_Bool bHasName(sal_False); sal_Bool bDataLayout(sal_False); + OUString aDisplayName; sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotFieldAttrTokenMap(); for( sal_Int16 i=0; i < nAttrCount; ++i ) @@ -745,6 +856,11 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport, bHasName = sal_True; } break; + case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME: + { + aDisplayName = sValue; + } + break; case XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD : { bDataLayout = IsXMLToken(sValue, XML_TRUE); @@ -774,7 +890,11 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport, } } if (bHasName) + { pDim = new ScDPSaveDimension(String(sName), bDataLayout); + if (aDisplayName.getLength()) + pDim->SetLayoutName(aDisplayName); + } } ScXMLDataPilotFieldContext::~ScXMLDataPilotFieldContext() @@ -875,6 +995,12 @@ void ScXMLDataPilotFieldContext::EndElement() } } +void ScXMLDataPilotFieldContext::SetSubTotalName(const OUString& rName) +{ + if (pDim) + pDim->SetSubtotalName(rName); +} + ScXMLDataPilotFieldReferenceContext::ScXMLDataPilotFieldReferenceContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName, const uno::Reference& xAttrList, @@ -1199,6 +1325,8 @@ SvXMLImportContext *ScXMLDataPilotSubTotalsContext::CreateChildContext( USHORT n void ScXMLDataPilotSubTotalsContext::EndElement() { pDataPilotField->SetSubTotals(pFunctions, nFunctionCount); + if (maDisplayName.getLength()) + pDataPilotField->SetSubTotalName(maDisplayName); } void ScXMLDataPilotSubTotalsContext::AddFunction(sal_Int16 nFunction) @@ -1221,6 +1349,11 @@ void ScXMLDataPilotSubTotalsContext::AddFunction(sal_Int16 nFunction) } } +void ScXMLDataPilotSubTotalsContext::SetDisplayName(const OUString& rName) +{ + maDisplayName = rName; +} + ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName, @@ -1247,6 +1380,8 @@ ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImpo pDataPilotSubTotals->AddFunction( sal::static_int_cast( ScXMLConverter::GetFunctionFromString( sValue ) ) ); } + case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME: + pDataPilotSubTotals->SetDisplayName(sValue); break; } } @@ -1344,6 +1479,10 @@ ScXMLDataPilotMemberContext::ScXMLDataPilotMemberContext( ScXMLImport& rImport, bHasName = sal_True; } break; + case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME: + { + maDisplayName = sValue; + } case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY : { bDisplay = IsXMLToken(sValue, XML_TRUE); @@ -1380,6 +1519,8 @@ void ScXMLDataPilotMemberContext::EndElement() if (bHasName) // #i53407# don't check sName, empty name is allowed { ScDPSaveMember* pMember = new ScDPSaveMember(String(sName)); + if (maDisplayName.getLength()) + pMember->SetLayoutName(maDisplayName); pMember->SetIsVisible(bDisplay); pMember->SetShowDetails(bDisplayDetails); pDataPilotField->AddMember(pMember); diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx index 874fe27654ba..fee4e36c02e5 100644 --- a/sc/source/filter/xml/xmldpimp.hxx +++ b/sc/source/filter/xml/xmldpimp.hxx @@ -79,10 +79,18 @@ public: class ScXMLDataPilotTableContext : public SvXMLImportContext { + struct GrandTotalItem + { + ::rtl::OUString maDisplayName; + bool mbVisible; + GrandTotalItem(); + }; ScDocument* pDoc; ScDPObject* pDPObject; ScDPSaveData* pDPSave; ScDPDimensionSaveData* pDPDimSaveData; + GrandTotalItem maRowGrandTotal; + GrandTotalItem maColGrandTotal; rtl::OUString sDataPilotTableName; rtl::OUString sApplicationData; rtl::OUString sGrandTotal; @@ -131,6 +139,7 @@ public: virtual void EndElement(); + void SetGrandTotal(::xmloff::token::XMLTokenEnum eOrientation, bool bVisible, const ::rtl::OUString& rDisplayName); void SetDatabaseName(const rtl::OUString& sValue) { sDatabaseName = sValue; } void SetSourceObject(const rtl::OUString& sValue) { sSourceObject = sValue; } void SetNative(const sal_Bool bValue) { bIsNative = bValue; } @@ -253,6 +262,34 @@ public: virtual void EndElement(); }; +class ScXMLDataPilotGrandTotalContext : public SvXMLImportContext +{ + enum Orientation { COLUMN, ROW, BOTH, NONE }; + + ScXMLImport& GetScImport(); + + ScXMLDataPilotTableContext* mpTableContext; + ::rtl::OUString maDisplayName; + Orientation meOrientation; + bool mbVisible; + +public: + ScXMLDataPilotGrandTotalContext( + ScXMLImport& rImport, USHORT nPrefix, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pTableContext ); + + virtual ~ScXMLDataPilotGrandTotalContext(); + + virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + class ScXMLSourceCellRangeContext : public SvXMLImportContext { ScXMLDataPilotTableContext* pDataPilotTable; @@ -329,6 +366,7 @@ public: void SetShowEmpty(const sal_Bool bValue) { if (pDim) pDim->SetShowEmpty(bValue); } void SetSubTotals(const sal_uInt16* pFunctions, const sal_Int16 nCount) { if(pDim) pDim->SetSubTotals(nCount, pFunctions); } + void SetSubTotalName(const ::rtl::OUString& rName); void AddMember(ScDPSaveMember* pMember) { if (pDim) pDim->AddMember(pMember); } void SetFieldReference(const com::sun::star::sheet::DataPilotFieldReference& aRef) { if (pDim) pDim->SetReferenceValue(&aRef); } void SetAutoShowInfo(const com::sun::star::sheet::DataPilotFieldAutoShowInfo& aInfo) { if (pDim) pDim->SetAutoShowInfo(&aInfo); } @@ -453,6 +491,7 @@ class ScXMLDataPilotSubTotalsContext : public SvXMLImportContext sal_Int16 nFunctionCount; sal_uInt16* pFunctions; + ::rtl::OUString maDisplayName; const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } @@ -476,6 +515,7 @@ public: virtual void EndElement(); void AddFunction(sal_Int16 nFunction); + void SetDisplayName(const ::rtl::OUString& rName); }; class ScXMLDataPilotSubTotalContext : public SvXMLImportContext @@ -533,6 +573,7 @@ class ScXMLDataPilotMemberContext : public SvXMLImportContext ScXMLDataPilotFieldContext* pDataPilotField; rtl::OUString sName; + rtl::OUString maDisplayName; sal_Bool bDisplay; sal_Bool bDisplayDetails; sal_Bool bHasName; diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx index 873e95168088..f025a97ce5ae 100644 --- a/sc/source/filter/xml/xmlimprt.cxx +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -1344,6 +1344,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotTableElemTokenMap() { { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL }, { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE }, + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL }, { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY }, { XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE }, { XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE }, @@ -1377,6 +1378,24 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceServiceAttrTokenMap() return *pDataPilotTableSourceServiceAttrTokenMap; } +const SvXMLTokenMap& ScXMLImport::GetDataPilotGrandTotalAttrTokenMap() +{ + if (!pDataPilotGrandTotalAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotGrandTotalAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY }, + { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION }, + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME }, + XML_TOKEN_MAP_END + }; + + pDataPilotGrandTotalAttrTokenMap = new SvXMLTokenMap( aDataPilotGrandTotalAttrTokenMap ); + } + + return *pDataPilotGrandTotalAttrTokenMap; +} + const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceCellRangeAttrTokenMap() { if( !pDataPilotTableSourceCellRangeAttrTokenMap ) @@ -1416,6 +1435,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotFieldAttrTokenMap() static __FAR_DATA SvXMLTokenMapEntry aDataPilotFieldAttrTokenMap[] = { { XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME }, + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME }, { XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD }, { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION }, { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION }, @@ -1507,6 +1527,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotSubTotalAttrTokenMap() static __FAR_DATA SvXMLTokenMapEntry aDataPilotSubTotalAttrTokenMap[] = { { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION }, + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME }, XML_TOKEN_MAP_END }; @@ -1539,6 +1560,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotMemberAttrTokenMap() static __FAR_DATA SvXMLTokenMapEntry aDataPilotMemberAttrTokenMap[] = { { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME }, + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME }, { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY }, { XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS }, XML_TOKEN_MAP_END @@ -1674,6 +1696,7 @@ ScXMLImport::ScXMLImport( pDataPilotTableAttrTokenMap( 0 ), pDataPilotTableElemTokenMap( 0 ), pDataPilotTableSourceServiceAttrTokenMap( 0 ), + pDataPilotGrandTotalAttrTokenMap(NULL), pDataPilotTableSourceCellRangeElemTokenMap( 0 ), pDataPilotTableSourceCellRangeAttrTokenMap( 0 ), pDataPilotFieldAttrTokenMap( 0 ), diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx index 052ef20c6022..ec8a9cd6640b 100644 --- a/sc/source/filter/xml/xmlimprt.hxx +++ b/sc/source/filter/xml/xmlimprt.hxx @@ -489,6 +489,7 @@ enum ScXMLDataPilotTableElemTokens { XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE, + XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE, @@ -504,6 +505,13 @@ enum ScXMLDataPilotTableSourceServiceAttrTokens XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD }; +enum ScXMLDataPilotGrandTotalAttrTokens +{ + XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY, + XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION, + XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME +}; + enum ScXMLDataPilotTableSourceCellRangeElemTokens { XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER @@ -517,6 +525,7 @@ enum ScXMLDataPilotTableSourceCellRangeAttrTokens enum ScXMLDataPilotFieldAttrTokens { XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME, + XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD, XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION, XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION, @@ -552,7 +561,8 @@ enum ScXMLDataPilotSubTotalsElemTokens enum ScXMLDataPilotSubTotalAttrTokens { - XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION + XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION, + XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME }; enum ScXMLDataPilotMembersElemTokens @@ -563,6 +573,7 @@ enum ScXMLDataPilotMembersElemTokens enum ScXMLDataPilotMemberAttrTokens { XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME, + XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY, XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS }; @@ -719,6 +730,7 @@ class ScXMLImport: public SvXMLImport SvXMLTokenMap *pDataPilotTableAttrTokenMap; SvXMLTokenMap *pDataPilotTableElemTokenMap; SvXMLTokenMap *pDataPilotTableSourceServiceAttrTokenMap; + SvXMLTokenMap *pDataPilotGrandTotalAttrTokenMap; SvXMLTokenMap *pDataPilotTableSourceCellRangeElemTokenMap; SvXMLTokenMap *pDataPilotTableSourceCellRangeAttrTokenMap; SvXMLTokenMap *pDataPilotFieldAttrTokenMap; @@ -882,6 +894,7 @@ public: const SvXMLTokenMap& GetDataPilotTableAttrTokenMap(); const SvXMLTokenMap& GetDataPilotTableElemTokenMap(); const SvXMLTokenMap& GetDataPilotTableSourceServiceAttrTokenMap(); + const SvXMLTokenMap& GetDataPilotGrandTotalAttrTokenMap(); const SvXMLTokenMap& GetDataPilotTableSourceCellRangeElemTokenMap(); const SvXMLTokenMap& GetDataPilotTableSourceCellRangeAttrTokenMap(); const SvXMLTokenMap& GetDataPilotFieldAttrTokenMap(); diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 41a5e9d0e050..c71bc31a1150 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -1355,7 +1355,7 @@ void ScDBFunc::UngroupDataPilot() } } -OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName) +static OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName) { sal_Int32 n = rSubtotal.getLength(); const sal_Unicode* p = rSubtotal.getStr(); @@ -1372,6 +1372,18 @@ OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUStri aBuf.append(aWord); aBuf.append(c); } + else if (c == sal_Unicode('\\')) + { + // Escape a backslash character. + aWordBuf.append(c); + aWordBuf.append(c); + } + else if (c == sal_Unicode('?')) + { + // A literal '?' must be escaped with a backslash ('\'); + aWordBuf.append(sal_Unicode('\\')); + aWordBuf.append(c); + } else aWordBuf.append(c); } -- cgit From b4249adba8d9ad20b16b1b0d0a9beb5aaa47ba5d Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 19 Jun 2009 15:19:28 +0000 Subject: Re-activate imports of hidden fields from xls per Daniel's input. --- sc/source/filter/excel/xipivot.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sc') diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index e6bf8ea01a2f..fd7622cce7c0 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -1374,14 +1374,15 @@ void XclImpPivotTable::Convert() if( const XclImpPTField* pField = GetField( *aIt ) ) pField->ConvertPageField( aSaveData ); -#if 0 // Why do we do this ??? + // We need to import hidden fields because hidden fields may contain + // special settings for subtotals (aggregation function, filters, custom + // name etc.) and members (hidden, custom name etc.). // hidden fields for( sal_uInt16 nField = 0, nCount = GetFieldCount(); nField < nCount; ++nField ) if( const XclImpPTField* pField = GetField( nField ) ) if( (pField->GetAxes() & EXC_SXVD_AXIS_ROWCOLPAGE) == 0 ) pField->ConvertHiddenField( aSaveData ); -#endif // data fields for( aIt = maFiltDataFields.begin(), aEnd = maFiltDataFields.end(); aIt != aEnd; ++aIt ) -- cgit From 81d6b090a680d432e33e4de4be9906043eed1139 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 19 Jun 2009 19:51:20 +0000 Subject: #i100619# initial commit of patches from ooo-build that implement new datapilot field popup window. --- sc/inc/attrib.hxx | 16 +- sc/inc/dpobject.hxx | 5 + sc/inc/dpoutput.hxx | 3 +- sc/inc/dpoutputgeometry.hxx | 75 +++ sc/inc/dpsave.hxx | 11 + sc/inc/dptabsrc.hxx | 1 + sc/inc/fillinfo.hxx | 2 + sc/inc/global.hxx | 2 - sc/inc/pivot.hxx | 17 +- sc/inc/sc.hrc | 2 + sc/inc/scabstdlg.hxx | 2 +- sc/inc/unonames.hxx | 1 + sc/source/core/data/documen8.cxx | 10 +- sc/source/core/data/dpobject.cxx | 63 +- sc/source/core/data/dpoutput.cxx | 44 +- sc/source/core/data/dpoutputgeometry.cxx | 211 +++++++ sc/source/core/data/dpsave.cxx | 52 +- sc/source/core/data/dptabsrc.cxx | 8 +- sc/source/core/data/fillinfo.cxx | 8 +- sc/source/core/data/global2.cxx | 49 +- sc/source/core/data/makefile.mk | 2 + sc/source/core/data/pivot2.cxx | 9 +- sc/source/filter/excel/xipivot.cxx | 74 ++- sc/source/filter/inc/xipivot.hxx | 2 + sc/source/filter/xml/xmldpimp.cxx | 83 ++- sc/source/filter/xml/xmldpimp.hxx | 26 +- sc/source/ui/cctrl/dpcontrol.cxx | 1009 ++++++++++++++++++++++++++++++ sc/source/ui/cctrl/dpcontrol.src | 49 ++ sc/source/ui/cctrl/makefile.mk | 10 +- sc/source/ui/dbgui/pvlaydlg.cxx | 35 +- sc/source/ui/docshell/dbdocfun.cxx | 4 +- sc/source/ui/inc/dbfunc.hxx | 1 + sc/source/ui/inc/dpcontrol.hrc | 40 ++ sc/source/ui/inc/dpcontrol.hxx | 289 +++++++++ sc/source/ui/inc/gridwin.hxx | 15 + sc/source/ui/inc/pvlaydlg.hxx | 2 +- sc/source/ui/undo/undodat.cxx | 4 +- sc/source/ui/view/dbfunc3.cxx | 137 ++++ sc/source/ui/view/gridwin.cxx | 2 + sc/source/ui/view/gridwin2.cxx | 202 +++++- sc/source/ui/view/gridwin4.cxx | 17 +- sc/util/makefile.mk | 1 + 42 files changed, 2449 insertions(+), 146 deletions(-) create mode 100644 sc/inc/dpoutputgeometry.hxx create mode 100644 sc/source/core/data/dpoutputgeometry.cxx create mode 100644 sc/source/ui/cctrl/dpcontrol.cxx create mode 100644 sc/source/ui/cctrl/dpcontrol.src create mode 100644 sc/source/ui/inc/dpcontrol.hrc create mode 100644 sc/source/ui/inc/dpcontrol.hxx (limited to 'sc') diff --git a/sc/inc/attrib.hxx b/sc/inc/attrib.hxx index cae72cf30cf5..e7e28083dec2 100644 --- a/sc/inc/attrib.hxx +++ b/sc/inc/attrib.hxx @@ -42,13 +42,16 @@ // Flags fuer durch Merge verdeckte Zellen // und Control fuer Auto-Filter -#define SC_MF_HOR 1 -#define SC_MF_VER 2 -#define SC_MF_AUTO 4 -#define SC_MF_BUTTON 8 -#define SC_MF_SCENARIO 16 +#define SC_MF_HOR 0x0001 +#define SC_MF_VER 0x0002 +#define SC_MF_AUTO 0x0004 /// autofilter arrow +#define SC_MF_BUTTON 0x0008 /// field button for datapilot +#define SC_MF_SCENARIO 0x0010 +#define SC_MF_BUTTON_POPUP 0x0020 /// dp button with popup arrow +#define SC_MF_HIDDEN_MEMBER 0x0040 /// dp field button with presence of hidden member +#define SC_MF_DP_TABLE 0x0080 /// dp table output -#define SC_MF_ALL 31 +#define SC_MF_ALL 0x00FF class EditTextObject; @@ -103,6 +106,7 @@ public: BOOL HasAutoFilter() const { return ( GetValue() & SC_MF_AUTO ) != 0; } BOOL HasButton() const { return ( GetValue() & SC_MF_BUTTON ) != 0; } + bool HasDPTable() const { return ( GetValue() & SC_MF_DP_TABLE ) != 0; } BOOL IsScenario() const { return ( GetValue() & SC_MF_SCENARIO ) != 0; } }; diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index f90277769cba..ea0093119f88 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -316,6 +316,11 @@ public: ScSimpleSharedString& GetSharedString(); + void FreeTable(ScDPObject* pDPObj); + SC_DLLPUBLIC bool InsertNewTable(ScDPObject* pDPObj); + + bool HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const; + ScDPCacheCell* getCacheCellFromPool(const ScDPCacheCell& rCell); void clearCacheCellPool(); }; diff --git a/sc/inc/dpoutput.hxx b/sc/inc/dpoutput.hxx index 65108761b2ec..e3ab86423d4b 100644 --- a/sc/inc/dpoutput.hxx +++ b/sc/inc/dpoutput.hxx @@ -94,6 +94,7 @@ private: com::sun::star::uno::Sequence< com::sun::star::sheet::DataResult> > aData; BOOL bResultsError; + bool mbHasDataLayout; String aDataDescription; // Number format related parameters @@ -125,7 +126,7 @@ private: const com::sun::star::sheet::MemberResult& rData, BOOL bColHeader, long nLevel ); void FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption, - BOOL bFrame = TRUE ); + bool bInTable, bool bPopup, bool bHasHiddenMember ); void CalcSizes(); /** Query which sub-area of the table the cell is in. See diff --git a/sc/inc/dpoutputgeometry.hxx b/sc/inc/dpoutputgeometry.hxx new file mode 100644 index 000000000000..dcf98f8f4ade --- /dev/null +++ b/sc/inc/dpoutputgeometry.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: xmldpimp.cxx,v $ + * $Revision: 1.27.134.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_DPOUTPUTGEOMETRY_HXX +#define SC_DPOUTPUTGEOMETRY_HXX + +#include "address.hxx" +#include + +class ScAddress; + +class SC_DLLPUBLIC ScDPOutputGeometry +{ +public: + enum FieldType { Column, Row, Page, Data, None }; + + ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter); + ~ScDPOutputGeometry(); + + /** + * @param nCount number of row fields, excluding the data layout + * field if exists. + */ + void setRowFieldCount(sal_uInt32 nCount); + void setColumnFieldCount(sal_uInt32 nCount); + void setPageFieldCount(sal_uInt32 nCount); + void setDataFieldCount(sal_uInt32 nCount); + + void getColumnFieldPositions(::std::vector& rAddrs) const; + void getRowFieldPositions(::std::vector& rAddrs) const; + void getPageFieldPositions(::std::vector& rAddrs) const; + + FieldType getFieldButtonType(const ScAddress& rPos) const; + +private: + ScDPOutputGeometry(); // disabled + +private: + ScRange maOutRange; + sal_uInt32 mnRowFields; + sal_uInt32 mnColumnFields; + sal_uInt32 mnPageFields; + sal_uInt32 mnDataFields; + + bool mbShowFilter; +}; + +#endif diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx index 9d680dfa3856..e8a7420ffcbc 100644 --- a/sc/inc/dpsave.hxx +++ b/sc/inc/dpsave.hxx @@ -179,6 +179,10 @@ public: void WriteToSource( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface>& xDim ); + + void UpdateMemberVisibility(const ::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rData); + + bool HasInvisibleMember() const; }; @@ -256,6 +260,13 @@ public: SC_DLLPUBLIC ScDPDimensionSaveData* GetDimensionData(); // create if not there void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied void BuildAllDimensionMembers(ScDPTableData* pData); + + /** + * Check whether a dimension has one or more invisible members. + * + * @param rDimName dimension name + */ + SC_DLLPUBLIC bool HasInvisibleMember(const ::rtl::OUString& rDimName) const; }; diff --git a/sc/inc/dptabsrc.hxx b/sc/inc/dptabsrc.hxx index 5538959b2dfc..2293135f9c11 100644 --- a/sc/inc/dptabsrc.hxx +++ b/sc/inc/dptabsrc.hxx @@ -348,6 +348,7 @@ private: BOOL bHasSelectedPage; String aSelectedPage; ScDPItemData* pSelectedData; // internal, temporary, created from aSelectedPage + sal_Bool mbHasHiddenMember; public: ScDPDimension( ScDPSource* pSrc, long nD ); diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx index b6d48254d06a..d0be5b0cb897 100644 --- a/sc/inc/fillinfo.hxx +++ b/sc/inc/fillinfo.hxx @@ -99,6 +99,8 @@ struct CellInfo BOOL bVOverlapped : 1; BOOL bAutoFilter : 1; BOOL bPushButton : 1; + bool bPopupButton: 1; + bool bFilterActive:1; BOOL bPrinted : 1; // bei Bedarf (Pagebreak-Modus) diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index 45df07deaf6c..408b77c4516c 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -93,8 +93,6 @@ extern "C" { // handling code. #define OLD_PIVOT_IMPLEMENTATION 0 -//------------------------------------------------------------------------ -struct LabelData; //------------------------------------------------------------------------ // die 1000 Namen des Calc... diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx index 66e87facfd9a..e2b8ef3e01fa 100644 --- a/sc/inc/pivot.hxx +++ b/sc/inc/pivot.hxx @@ -53,6 +53,7 @@ #include "address.hxx" #include +#include class SubTotal; #include "collect.hxx" @@ -80,7 +81,9 @@ class ScUserListData; class ScMultipleReadHeader; class ScMultipleWriteHeader; class ScProgress; -struct LabelData; +struct ScDPLabelData; + +typedef ::boost::shared_ptr ScDPLabelDataRef; // ----------------------------------------------------------------------- @@ -104,8 +107,7 @@ struct ScPivotParam SCCOL nCol; // Cursor Position / SCROW nRow; // bzw. Anfang des Zielbereiches SCTAB nTab; - LabelData** ppLabelArr; - SCSIZE nLabels; + ::std::vector maLabelArray; PivotField aPageArr[PIVOT_MAXPAGEFIELD]; PivotField aColArr[PIVOT_MAXFIELD]; PivotField aRowArr[PIVOT_MAXFIELD]; @@ -126,10 +128,8 @@ struct ScPivotParam ScPivotParam& operator= ( const ScPivotParam& r ); BOOL operator== ( const ScPivotParam& r ) const; void Clear (); - void ClearLabelData (); void ClearPivotArrays(); - void SetLabelData ( LabelData** ppLabArr, - SCSIZE nLab ); + void SetLabelData (const ::std::vector& r); void SetPivotArrays ( const PivotField* pPageArr, const PivotField* pColArr, const PivotField* pRowArr, @@ -366,7 +366,7 @@ public: //------------------------------------------------------------------------ -struct LabelData +struct ScDPLabelData { String maName; /// Visible name of the dimension. SCsCOL mnCol; @@ -383,7 +383,7 @@ struct LabelData ::com::sun::star::sheet::DataPilotFieldLayoutInfo maLayoutInfo; /// Layout info. ::com::sun::star::sheet::DataPilotFieldAutoShowInfo maShowInfo; /// AutoShow info. - explicit LabelData( const String& rName, short nCol, bool bIsValue ); + explicit ScDPLabelData( const String& rName, short nCol, bool bIsValue ); }; // ============================================================================ @@ -401,7 +401,6 @@ struct ScDPFuncData // ============================================================================ -typedef LabelData ScDPLabelData; typedef std::vector< ScDPLabelData > ScDPLabelDataVec; typedef std::vector< String > ScDPNameVec; diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index 35b6a403816d..13d8481fce16 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -1631,6 +1631,8 @@ #define RID_SCDLG_CONFLICTS (SC_DIALOGS_START + 145) #define RID_SCDLG_SHAREDOCUMENT (SC_DIALOGS_START + 146) +#define RID_POPUP_FILTER (SC_DIALOGS_START + 147) + #define SC_DIALOGS_END (SC_DIALOGS_START + 150) #ifndef STD_MASKCOLOR diff --git a/sc/inc/scabstdlg.hxx b/sc/inc/scabstdlg.hxx index ec381ce2ef07..e894ff96b98a 100644 --- a/sc/inc/scabstdlg.hxx +++ b/sc/inc/scabstdlg.hxx @@ -235,7 +235,7 @@ class AbstractScDPSubtotalDlg : public VclAbstractDialog //add for ScDPSubtotal { public: virtual USHORT GetFuncMask() const = 0; - virtual void FillLabelData( LabelData& rLabelData ) const = 0; + virtual void FillLabelData( ScDPLabelData& rLabelData ) const = 0; }; class AbstractScDPNumGroupDlg : public VclAbstractDialog diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx index bfc5aa9de831..83307c768563 100644 --- a/sc/inc/unonames.hxx +++ b/sc/inc/unonames.hxx @@ -561,6 +561,7 @@ #define SC_UNO_LAYOUTNAME "LayoutName" #define SC_UNO_FIELD_SUBTOTALNAME "FieldSubtotalName" #define SC_UNO_GRANDTOTAL_NAME "GrandTotalName" +#define SC_UNO_HAS_HIDDEN_MEMBER "HasHiddenMember" // (preliminary:) #define SC_UNO_REFVALUE "ReferenceValue" diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx index 0d12c82dec87..0bb3f96b0ca3 100644 --- a/sc/source/core/data/documen8.cxx +++ b/sc/source/core/data/documen8.cxx @@ -95,6 +95,7 @@ #include "globstr.hrc" #include "sc.hrc" #include "charthelper.hxx" +#include "dpobject.hxx" #define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue() @@ -712,8 +713,13 @@ BOOL ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpe // skip everything left of rSpellPos: while ( pCell && nRow == rSpellPos.Row() && nCol < rSpellPos.Col() ) pCell = aIter.GetNext( nCol, nRow ); - while ( pCell ) + + for (; pCell; pCell = aIter.GetNext(nCol, nRow)) { + if (pDPCollection && pDPCollection->HasDPTable(nCol, nRow, nTab)) + // Don't spell check within datapilot table. + continue; + CellType eType = pCell->GetCellType(); if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT ) { @@ -798,8 +804,6 @@ BOOL ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpe if ( ++nCellCount >= SPELL_MAXCELLS ) // seen enough cells? break; - - pCell = aIter.GetNext( nCol, nRow ); } if ( pCell ) diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index cd7d58964a96..9f009c455743 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -535,6 +535,9 @@ void ScDPObject::Output() // aOutRange is always the range that was last output to the document aOutRange = pOutput->GetOutputRange(); + const ScAddress& s = aOutRange.aStart; + const ScAddress& e = aOutRange.aEnd; + pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE); } const ScRange ScDPObject::GetOutputRangeByType( sal_Int32 nType ) @@ -1801,7 +1804,7 @@ BOOL ScDPObject::FillOldParam(ScPivotParam& rParam, BOOL bForFile) const return TRUE; } -void lcl_FillLabelData( LabelData& rData, const uno::Reference< beans::XPropertySet >& xDimProp ) +void lcl_FillLabelData( ScDPLabelData& rData, const uno::Reference< beans::XPropertySet >& xDimProp ) { uno::Reference xDimSupp( xDimProp, uno::UNO_QUERY ); if ( xDimProp.is() && xDimSupp.is() ) @@ -1847,6 +1850,8 @@ void lcl_FillLabelData( LabelData& rData, const uno::Reference< beans::XProperty BOOL ScDPObject::FillLabelData(ScPivotParam& rParam) { + rParam.maLabelArray.clear(); + ((ScDPObject*)this)->CreateObjects(); uno::Reference xDimsName = xSource->getDimensions(); @@ -1857,8 +1862,6 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam) if (!nDimCount) return FALSE; - SCSIZE nOutCount = 0; - LabelData** aLabelArr = new LabelData*[nDimCount]; for (long nDim=0; nDim < nDimCount; nDim++) { String aFieldName; @@ -1893,24 +1896,15 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam) SCsCOL nCol = static_cast< SCsCOL >( nDim ); //! ??? bool bIsValue = true; //! check - aLabelArr[nOutCount] = new LabelData( aFieldName, nCol, bIsValue ); - - LabelData& rLabelData = *aLabelArr[nOutCount]; - GetHierarchies( nDim, rLabelData.maHiers ); - GetMembers( nDim, rLabelData.maMembers, &rLabelData.maVisible, &rLabelData.maShowDet ); - lcl_FillLabelData( rLabelData, xDimProp ); - - ++nOutCount; + ScDPLabelDataRef pNewLabel(new ScDPLabelData(aFieldName, nCol, bIsValue)); + GetHierarchies(nDim, pNewLabel->maHiers); + GetMembers(nDim, pNewLabel->maMembers, &pNewLabel->maVisible, &pNewLabel->maShowDet); + lcl_FillLabelData(*pNewLabel, xDimProp); + rParam.maLabelArray.push_back(pNewLabel); } } } - rParam.SetLabelData( aLabelArr, nOutCount ); - - for (SCSIZE i=0; iSetAlive(TRUE); - if ( !r.Insert(pDestObj) ) + if ( !r.InsertNewTable(pDestObj) ) { DBG_ERROR("cannot insert DPObject"); DELETEZ( pDestObj ); @@ -2524,6 +2518,39 @@ ScSimpleSharedString& ScDPCollection::GetSharedString() return maSharedString; } +void ScDPCollection::FreeTable(ScDPObject* pDPObj) +{ + const ScRange& rOutRange = pDPObj->GetOutRange(); + const ScAddress& s = rOutRange.aStart; + const ScAddress& e = rOutRange.aEnd; + pDoc->RemoveFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE); + Free(pDPObj); +} + +bool ScDPCollection::InsertNewTable(ScDPObject* pDPObj) +{ + bool bSuccess = Insert(pDPObj); + if (bSuccess) + { + const ScRange& rOutRange = pDPObj->GetOutRange(); + const ScAddress& s = rOutRange.aStart; + const ScAddress& e = rOutRange.aEnd; + pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE); + } + return bSuccess; +} + +bool ScDPCollection::HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const +{ + const ScMergeFlagAttr* pMergeAttr = static_cast( + pDoc->GetAttr(nCol, nRow, nTab, ATTR_MERGE_FLAG)); + + if (!pMergeAttr) + return false; + + return pMergeAttr->HasDPTable(); +} + ScDPCacheCell* ScDPCollection::getCacheCellFromPool(const ScDPCacheCell& rCell) { ScDPCacheCell aCell(rCell); diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx index d376ed3cd396..325943f8b094 100644 --- a/sc/source/core/data/dpoutput.cxx +++ b/sc/source/core/data/dpoutput.cxx @@ -121,8 +121,13 @@ struct ScDPOutLevelData uno::Sequence aResult; String maName; /// Name is the internal field name. String aCaption; /// Caption is the name visible in the output table. + bool mbHasHiddenMember; - ScDPOutLevelData() { nDim = nHier = nLevel = nDimPos = -1; } + ScDPOutLevelData() + { + nDim = nHier = nLevel = nDimPos = -1; + mbHasHiddenMember = false; + } BOOL operator<(const ScDPOutLevelData& r) const { return nDimPos>= aCaption; } + + bool bRowFieldHasMember = false; switch ( eDimOrient ) { case sheet::DataPilotFieldOrientation_COLUMN: @@ -464,6 +474,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::ReferencegetResults(); pColFields[nColFieldCount].maName = aName; pColFields[nColFieldCount].aCaption= aCaption; + pColFields[nColFieldCount].mbHasHiddenMember = bHasHiddenMember; if (!lcl_MemberEmpty(pColFields[nColFieldCount].aResult)) ++nColFieldCount; break; @@ -475,8 +486,12 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::ReferencegetResults(); pRowFields[nRowFieldCount].maName = aName; pRowFields[nRowFieldCount].aCaption= aCaption; + pRowFields[nRowFieldCount].mbHasHiddenMember = bHasHiddenMember; if (!lcl_MemberEmpty(pRowFields[nRowFieldCount].aResult)) + { ++nRowFieldCount; + bRowFieldHasMember = true; + } break; case sheet::DataPilotFieldOrientation_PAGE: pPageFields[nPageFieldCount].nDim = nDim; @@ -486,6 +501,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::ReferenceSetString( nCol, nRow, nTab, rCaption ); - if (bFrame) + if (bInTable) lcl_SetFrame( pDoc,nTab, nCol,nRow, nCol,nRow, 20 ); // Button - pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr(SC_MF_BUTTON) ); + sal_uInt16 nMergeFlag = SC_MF_BUTTON; + if (bPopup) + nMergeFlag |= SC_MF_BUTTON_POPUP; + if (bHasHiddenMember) + nMergeFlag |= SC_MF_HIDDEN_MEMBER; + pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, nMergeFlag); lcl_SetStyleById( pDoc,nTab, nCol,nRow, nCol,nRow, STR_PIVOT_STYLE_FIELDNAME ); } @@ -673,7 +698,7 @@ void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rC void lcl_DoFilterButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab ) { pDoc->SetString( nCol, nRow, nTab, ScGlobal::GetRscString(STR_CELL_FILTER) ); - pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr(SC_MF_BUTTON) ); + pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON); } void ScDPOutput::CalcSizes() @@ -799,7 +824,7 @@ void ScDPOutput::Output() SCCOL nHdrCol = aStartPos.Col(); SCROW nHdrRow = aStartPos.Row() + nField + ( bDoFilter ? 1 : 0 ); // draw without frame for consistency with filter button: - FieldCell( nHdrCol, nHdrRow, nTab, pPageFields[nField].aCaption, FALSE ); + FieldCell( nHdrCol, nHdrRow, nTab, pPageFields[nField].aCaption, false, false, pPageFields[nField].mbHasHiddenMember ); SCCOL nFldCol = nHdrCol + 1; String aPageValue; @@ -838,7 +863,7 @@ void ScDPOutput::Output() for (nField=0; nField rSequence = pColFields[nField].aResult; @@ -873,9 +898,12 @@ void ScDPOutput::Output() for (nField=0; nField rSequence = pRowFields[nField].aResult; diff --git a/sc/source/core/data/dpoutputgeometry.cxx b/sc/source/core/data/dpoutputgeometry.cxx new file mode 100644 index 000000000000..1b8fc0b8435f --- /dev/null +++ b/sc/source/core/data/dpoutputgeometry.cxx @@ -0,0 +1,211 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: xmldpimp.cxx,v $ + * $Revision: 1.27.134.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "dpoutputgeometry.hxx" +#include "address.hxx" + +#include + +using ::std::vector; + +ScDPOutputGeometry::ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter) : + maOutRange(rOutRange), + mnRowFields(0), + mnColumnFields(0), + mnPageFields(0), + mnDataFields(0), + mbShowFilter(bShowFilter) +{ +} + +ScDPOutputGeometry::~ScDPOutputGeometry() +{ +} + +void ScDPOutputGeometry::setRowFieldCount(sal_uInt32 nCount) +{ + mnRowFields = nCount; +} + +void ScDPOutputGeometry::setColumnFieldCount(sal_uInt32 nCount) +{ + mnColumnFields = nCount; +} + +void ScDPOutputGeometry::setPageFieldCount(sal_uInt32 nCount) +{ + mnPageFields = nCount; +} + +void ScDPOutputGeometry::setDataFieldCount(sal_uInt32 nCount) +{ + mnDataFields = nCount; +} + +void ScDPOutputGeometry::getColumnFieldPositions(vector& rAddrs) const +{ + vector aAddrs; + if (!mnColumnFields) + { + rAddrs.swap(aAddrs); + return; + } + + bool bDataLayout = mnDataFields > 1; + + SCROW nCurRow = maOutRange.aStart.Row(); + + if (mnPageFields) + { + SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter; + SCROW nRowEnd = nRowStart + static_cast(mnPageFields-1); + nCurRow = nRowEnd + 2; + } + else if (mbShowFilter) + nCurRow += 2; + + SCROW nRow = nCurRow; + SCTAB nTab = maOutRange.aStart.Tab(); + SCCOL nColStart = maOutRange.aStart.Col() + mnRowFields + bDataLayout; + SCCOL nColEnd = nColStart + static_cast(mnColumnFields-1); + + for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol) + aAddrs.push_back(ScAddress(nCol, nRow, nTab)); + rAddrs.swap(aAddrs); +} + +void ScDPOutputGeometry::getRowFieldPositions(vector& rAddrs) const +{ + vector aAddrs; + if (!mnRowFields) + { + rAddrs.swap(aAddrs); + return; + } + + SCROW nCurRow = maOutRange.aStart.Row(); + + if (mnPageFields) + { + SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter; + SCROW nRowEnd = nRowStart + static_cast(mnPageFields-1); + nCurRow = nRowEnd + 2; + } + else if (mbShowFilter) + nCurRow += 2; + + if (mnColumnFields) + nCurRow += static_cast(mnColumnFields); + else + ++nCurRow; + + SCROW nRow = nCurRow; + SCTAB nTab = maOutRange.aStart.Tab(); + SCCOL nColStart = maOutRange.aStart.Col(); + SCCOL nColEnd = nColStart + static_cast(mnRowFields-1); + + for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol) + aAddrs.push_back(ScAddress(nCol, nRow, nTab)); + rAddrs.swap(aAddrs); +} + +void ScDPOutputGeometry::getPageFieldPositions(vector& rAddrs) const +{ + vector aAddrs; + if (!mnPageFields) + { + rAddrs.swap(aAddrs); + return; + } + + SCTAB nTab = maOutRange.aStart.Tab(); + SCCOL nCol = maOutRange.aStart.Col(); + + SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter; + SCROW nRowEnd = nRowStart + static_cast(mnPageFields-1); + + for (SCROW nRow = nRowStart; nRow <= nRowEnd; ++nRow) + aAddrs.push_back(ScAddress(nCol, nRow, nTab)); + rAddrs.swap(aAddrs); +} + +ScDPOutputGeometry::FieldType ScDPOutputGeometry::getFieldButtonType(const ScAddress& rPos) const +{ + // We will ignore the table position for now. + + bool bExtraTitleRow = (mnColumnFields == 0); + bool bDataLayout = mnDataFields > 1; + + SCROW nCurRow = maOutRange.aStart.Row(); + + if (mnPageFields) + { + SCCOL nCol = maOutRange.aStart.Col(); + SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter; + SCROW nRowEnd = nRowStart + static_cast(mnPageFields-1); + if (rPos.Col() == nCol && nRowStart <= rPos.Row() && rPos.Row() <= nRowEnd) + return Page; + + nCurRow = nRowEnd + 2; + } + else if (mbShowFilter) + nCurRow += 2; + + if (mnColumnFields) + { + SCROW nRow = nCurRow; + SCCOL nColStart = maOutRange.aStart.Col() + mnRowFields + bDataLayout; + SCCOL nColEnd = nColStart + static_cast(mnColumnFields-1); + if (rPos.Row() == nRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd) + return Column; + + nCurRow += static_cast(mnColumnFields); + } + + if (bExtraTitleRow) + ++nCurRow; + + if (mnRowFields) + { + SCCOL nColStart = maOutRange.aStart.Col(); + SCCOL nColEnd = nColStart + static_cast(mnRowFields-1); + if (rPos.Row() == nCurRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd) + return Row; + } + + return None; +} diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx index ba1acc97a83a..cc564457761f 100644 --- a/sc/source/core/data/dpsave.cxx +++ b/sc/source/core/data/dpsave.cxx @@ -62,6 +62,7 @@ using namespace com::sun::star; using ::rtl::OUString; +using ::rtl::OUStringHash; using ::std::hash_map; using ::std::auto_ptr; @@ -642,6 +643,8 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference& xD nHierCount = xHiers->getCount(); } + sal_Bool bHasHiddenMember = false; + for (long nHier=0; nHier xHierarchy = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHier) ); @@ -734,12 +737,15 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference& xD for (MemberList::const_iterator i=maMemberList.begin(); i != maMemberList.end() ; i++) { - rtl::OUString aMemberName = (*i)->GetName(); + ScDPSaveMember* pMember = *i; + if (!pMember->GetIsVisible()) + bHasHiddenMember = true; + rtl::OUString aMemberName = pMember->GetName(); if ( xMembers->hasByName( aMemberName ) ) { uno::Reference xMemberInt = ScUnoHelpFunctions::AnyToInterface( xMembers->getByName( aMemberName ) ); - (*i)->WriteToSource( xMemberInt, nPosition ); + pMember->WriteToSource( xMemberInt, nPosition ); if ( nPosition >= 0 ) ++nPosition; // increase if initialized @@ -751,6 +757,40 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference& xD } } } + + if (xDimProp.is()) + { + uno::Any any; + any <<= bHasHiddenMember; + xDimProp->setPropertyValue( + OUString::createFromAscii(SC_UNO_HAS_HIDDEN_MEMBER), any); + } +} + +void ScDPSaveDimension::UpdateMemberVisibility(const hash_map& rData) +{ + typedef hash_map DataMap; + MemberList::iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end(); + for (; itrMem != itrMemEnd; ++itrMem) + { + ScDPSaveMember* pMem = *itrMem; + const String& rMemName = pMem->GetName(); + DataMap::const_iterator itr = rData.find(rMemName); + if (itr != rData.end()) + pMem->SetIsVisible(itr->second); + } +} + +bool ScDPSaveDimension::HasInvisibleMember() const +{ + MemberList::const_iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end(); + for (; itrMem != itrMemEnd; ++itrMem) + { + const ScDPSaveMember* pMem = *itrMem; + if (!pMem->GetIsVisible()) + return true; + } + return false; } // ----------------------------------------------------------------------- @@ -1304,3 +1344,11 @@ void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData) mbDimensionMembersBuilt = true; } +bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const +{ + ScDPSaveDimension* pDim = GetExistingDimensionByName(rDimName); + if (!pDim) + return false; + + return pDim->HasInvisibleMember(); +} diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx index bc1394307f26..927035af62c9 100644 --- a/sc/source/core/data/dptabsrc.cxx +++ b/sc/source/core/data/dptabsrc.cxx @@ -1375,7 +1375,8 @@ ScDPDimension::ScDPDimension( ScDPSource* pSrc, long nD ) : mpSubtotalName(NULL), nSourceDim( -1 ), bHasSelectedPage( FALSE ), - pSelectedData( NULL ) + pSelectedData( NULL ), + mbHasHiddenMember(false) { //! hold pSource } @@ -1571,6 +1572,7 @@ uno::Reference SAL_CALL ScDPDimension::getPropertySetIn {MAP_CHAR_LEN(SC_UNO_USEDHIER), 0, &getCppuType((sal_Int32*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast(0)), 0, 0 }, {MAP_CHAR_LEN(SC_UNO_FIELD_SUBTOTALNAME), 0, &getCppuType(static_cast(0)), 0, 0 }, + {MAP_CHAR_LEN(SC_UNO_HAS_HIDDEN_MEMBER), 0, &getBooleanCppuType(), 0, 0 }, {0,0,0,0,0,0} }; static uno::Reference aRef = @@ -1653,6 +1655,8 @@ void SAL_CALL ScDPDimension::setPropertyValue( const rtl::OUString& aPropertyNam if (aValue >>= aTmpName) mpSubtotalName.reset(new OUString(aTmpName)); } + else if (aNameStr.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER)) + aValue >>= mbHasHiddenMember; else { DBG_ERROR("unknown property"); @@ -1716,6 +1720,8 @@ uno::Any SAL_CALL ScDPDimension::getPropertyValue( const rtl::OUString& aPropert aRet <<= mpLayoutName.get() ? *mpLayoutName : OUString::createFromAscii(""); else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME)) aRet <<= mpSubtotalName.get() ? *mpSubtotalName : OUString::createFromAscii(""); + else if (aNameStr.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER)) + aRet <<= mbHasHiddenMember; else { DBG_ERROR("unknown property"); diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx index c8eba91d2cc1..ac4cb9908a3f 100644 --- a/sc/source/core/data/fillinfo.cxx +++ b/sc/source/core/data/fillinfo.cxx @@ -332,6 +332,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX pInfo->bVOverlapped = FALSE; pInfo->bAutoFilter = FALSE; pInfo->bPushButton = FALSE; + pInfo->bPopupButton = false; + pInfo->bFilterActive = false; pInfo->nRotateDir = SC_ROTDIR_NONE; pInfo->bPrinted = FALSE; // view-intern @@ -458,6 +460,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX BOOL bAutoFilter = ((nOverlap & SC_MF_AUTO) != 0); BOOL bPushButton = ((nOverlap & SC_MF_BUTTON) != 0); BOOL bScenario = ((nOverlap & SC_MF_SCENARIO) != 0); + bool bPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0); + bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0); if (bMerged||bHOverlapped||bVOverlapped) bAnyMerged = TRUE; // intern @@ -498,6 +502,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX pInfo->bVOverlapped = bVOverlapped; pInfo->bAutoFilter = bAutoFilter; pInfo->bPushButton = bPushButton; + pInfo->bPopupButton = bPopupButton; + pInfo->bFilterActive = bFilterActive; pInfo->pLinesAttr = pLinesAttr; pInfo->mpTLBRLine = pTLBRLine; pInfo->mpBLTRLine = pBLTRLine; @@ -512,7 +518,7 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX nCurRow >= aEmbedRange.aStart.Row() && nCurRow <= aEmbedRange.aEnd.Row(); - if (bPushButton || bScenario) + if (bScenario) { pInfo->pBackground = ScGlobal::GetButtonBrushItem(); pThisRowInfo->bEmptyBack = FALSE; diff --git a/sc/source/core/data/global2.cxx b/sc/source/core/data/global2.cxx index c352dbb550d6..a6122c274d0d 100644 --- a/sc/source/core/data/global2.cxx +++ b/sc/source/core/data/global2.cxx @@ -56,6 +56,7 @@ #include "sc.hrc" #include "globstr.hrc" +using ::std::vector; // ----------------------------------------------------------------------- @@ -817,7 +818,6 @@ bool PivotField::operator==( const PivotField& r ) const ScPivotParam::ScPivotParam() : nCol(0), nRow(0), nTab(0), - ppLabelArr( NULL ), nLabels(0), nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0), bIgnoreEmptyRows(FALSE), bDetectCategories(FALSE), bMakeTotalCol(TRUE), bMakeTotalRow(TRUE) @@ -828,23 +828,22 @@ ScPivotParam::ScPivotParam() ScPivotParam::ScPivotParam( const ScPivotParam& r ) : nCol( r.nCol ), nRow( r.nRow ), nTab( r.nTab ), - ppLabelArr( NULL ), nLabels(0), nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0), bIgnoreEmptyRows(r.bIgnoreEmptyRows), bDetectCategories(r.bDetectCategories), bMakeTotalCol(r.bMakeTotalCol), bMakeTotalRow(r.bMakeTotalRow) { - SetLabelData ( r.ppLabelArr, r.nLabels ); SetPivotArrays ( r.aPageArr, r.aColArr, r.aRowArr, r.aDataArr, r.nPageCount, r.nColCount, r.nRowCount, r.nDataCount ); + + SetLabelData(r.maLabelArray); } //------------------------------------------------------------------------ __EXPORT ScPivotParam::~ScPivotParam() { - ClearLabelData(); } //------------------------------------------------------------------------ @@ -856,26 +855,10 @@ void __EXPORT ScPivotParam::Clear() nTab = 0; bIgnoreEmptyRows = bDetectCategories = FALSE; bMakeTotalCol = bMakeTotalRow = TRUE; - ClearLabelData(); ClearPivotArrays(); + maLabelArray.clear(); } -//------------------------------------------------------------------------ - -void __EXPORT ScPivotParam::ClearLabelData() -{ - if ( (nLabels > 0) && ppLabelArr ) - { - for ( SCSIZE i=0; i& r) { - ClearLabelData(); - - if ( (nLab > 0) && pLabArr ) + vector aNewArray; + aNewArray.reserve(r.size()); + for (vector::const_iterator itr = r.begin(), itrEnd = r.end(); + itr != itrEnd; ++itr) { - nLabels = (nLab>MAX_LABELS) ? MAX_LABELS : nLab; - ppLabelArr = new LabelData*[nLabels]; - for ( SCSIZE i=0; ipTab[nDestTab]) - { - ScPatternAttr aPattern( pDoc->GetPool() ); - aPattern.GetItemSet().Put( ScMergeFlagAttr(SC_MF_BUTTON) ); - pDoc->pTab[nDestTab]->ApplyPatternArea(nCol1, nRow1, nCol2, nRow2, aPattern); - } + pDoc->ApplyFlagsTab(nCol1, nRow1, nCol2, nRow2, nDestTab, SC_MF_BUTTON); } void ScPivot::SetStyle(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nId) @@ -492,7 +487,7 @@ ScDataObject* ScPivotCollection::Clone() const // ============================================================================ -LabelData::LabelData( const String& rName, short nCol, bool bIsValue ) : +ScDPLabelData::ScDPLabelData( const String& rName, short nCol, bool bIsValue ) : maName( rName ), mnCol( nCol ), mnFuncMask( PIVOT_FUNC_NONE ), diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index fd7622cce7c0..7ec0e5d2a694 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -48,7 +48,9 @@ #include "dpdimsave.hxx" #include "dpobject.hxx" #include "dpshttab.hxx" +#include "dpoutputgeometry.hxx" #include "scitems.hxx" +#include "attrib.hxx" #include "xltracer.hxx" #include "xistream.hxx" @@ -60,6 +62,8 @@ #include "excform.hxx" #include "xltable.hxx" +#include + using ::rtl::OUString; using ::rtl::OUStringBuffer; using ::com::sun::star::sheet::DataPilotFieldOrientation; @@ -68,6 +72,7 @@ using ::com::sun::star::sheet::DataPilotFieldSortInfo; using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo; using ::com::sun::star::sheet::DataPilotFieldLayoutInfo; using ::com::sun::star::sheet::DataPilotFieldReference; +using ::std::vector; // ============================================================================ // Pivot cache @@ -1418,8 +1423,10 @@ void XclImpPivotTable::Convert() pDPObj->SetAlive( TRUE ); pDPObj->SetHeaderLayout( maPTViewEx9Info.mnGridLayout == 0 ); - GetDoc().GetDPCollection()->Insert( pDPObj ); + GetDoc().GetDPCollection()->InsertNewTable(pDPObj); mpDPObj = pDPObj; + + ApplyMergeFlags(aOutRange, aSaveData); } void XclImpPivotTable::MaybeRefresh() @@ -1432,6 +1439,71 @@ void XclImpPivotTable::MaybeRefresh() } } +void XclImpPivotTable::ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveData& rSaveData) +{ + // Apply merge flags for varoius datapilot controls. + + ScDPOutputGeometry aGeometry(rOutRange, false); + aGeometry.setColumnFieldCount(maPTInfo.mnColFields); + aGeometry.setPageFieldCount(maPTInfo.mnPageFields); + aGeometry.setDataFieldCount(maPTInfo.mnDataFields); + + // Excel includes data layout field in the row field count. We need to + // subtract it. + bool bDataLayout = maPTInfo.mnDataFields > 1; + aGeometry.setRowFieldCount(maPTInfo.mnRowFields - static_cast(bDataLayout)); + + ScDocument& rDoc = GetDoc(); + + vector aPageBtns; + aGeometry.getPageFieldPositions(aPageBtns); + vector::const_iterator itr = aPageBtns.begin(), itrEnd = aPageBtns.end(); + for (; itr != itrEnd; ++itr) + { + sal_uInt16 nMFlag = SC_MF_BUTTON; + String aName; + rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName); + if (rSaveData.HasInvisibleMember(aName)) + nMFlag |= SC_MF_HIDDEN_MEMBER; + + rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag); + rDoc.ApplyFlagsTab(itr->Col()+1, itr->Row(), itr->Col()+1, itr->Row(), itr->Tab(), SC_MF_AUTO); + } + + vector aColBtns; + aGeometry.getColumnFieldPositions(aColBtns); + itr = aColBtns.begin(); + itrEnd = aColBtns.end(); + for (; itr != itrEnd; ++itr) + { + sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP; + String aName; + rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName); + if (rSaveData.HasInvisibleMember(aName)) + nMFlag |= SC_MF_HIDDEN_MEMBER; + rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag); + } + + vector aRowBtns; + aGeometry.getRowFieldPositions(aRowBtns); + itr = aRowBtns.begin(); + itrEnd = aRowBtns.end(); + for (; itr != itrEnd; ++itr) + { + sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP; + String aName; + rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName); + if (rSaveData.HasInvisibleMember(aName)) + nMFlag |= SC_MF_HIDDEN_MEMBER; + rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag); + } + if (bDataLayout) + { + --itr; // move back to the last row field position. + rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), SC_MF_BUTTON); + } +} + // ============================================================================ // ============================================================================ diff --git a/sc/source/filter/inc/xipivot.hxx b/sc/source/filter/inc/xipivot.hxx index 15227b8fb1a3..9e0e577b1756 100644 --- a/sc/source/filter/inc/xipivot.hxx +++ b/sc/source/filter/inc/xipivot.hxx @@ -363,6 +363,8 @@ public: void MaybeRefresh(); + void ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveData& rSaveData); + // ------------------------------------------------------------------------ private: typedef ::std::vector< XclImpPTFieldRef > XclImpPTFieldVec; diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index 9cdca232c25a..0a990416006e 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -48,6 +48,7 @@ #include "dpgroup.hxx" #include "dpdimsave.hxx" #include "rangeutl.hxx" +#include "dpoutputgeometry.hxx" #include #include @@ -131,6 +132,10 @@ ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport, sDataPilotTableName(), sApplicationData(), sGrandTotal(GetXMLToken(XML_BOTH)), + mnRowFieldCount(0), + mnColFieldCount(0), + mnPageFieldCount(0), + mnDataFieldCount(0), bIsNative(sal_True), bIgnoreEmptyRows(sal_False), bIdentifyCategories(sal_False), @@ -280,6 +285,12 @@ SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( USHORT nPref void ScXMLDataPilotTableContext::SetButtons() { + ScDPOutputGeometry aGeometry(aTargetRangeAddress, bShowFilter); + aGeometry.setColumnFieldCount(mnColFieldCount); + aGeometry.setRowFieldCount(mnRowFieldCount); + aGeometry.setPageFieldCount(mnPageFieldCount); + aGeometry.setDataFieldCount(mnDataFieldCount); + OUString sAddress; sal_Int32 nOffset = 0; while( nOffset >= 0 ) @@ -291,8 +302,21 @@ void ScXMLDataPilotTableContext::SetButtons() sal_Int32 nAddrOffset(0); if (pDoc && ScRangeStringConverter::GetAddressFromString( aScAddress, sAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nAddrOffset )) { - ScMergeFlagAttr aAttr( SC_MF_BUTTON ); - pDoc->ApplyAttr( aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), aAttr ); + ScDPOutputGeometry::FieldType eType = aGeometry.getFieldButtonType(aScAddress); + + sal_Int16 nMFlag = SC_MF_BUTTON; + if (eType == ScDPOutputGeometry::Column || eType == ScDPOutputGeometry::Row) + nMFlag |= SC_MF_BUTTON_POPUP; + + // Use the cell's string value to see if this field contains a + // hidden member. Isn't there a better way? GetString() is + // quite expensive... + String aCellStr; + pDoc->GetString(aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), aCellStr); + if (maHiddenMemberFields.count(aCellStr)) + nMFlag |= SC_MF_HIDDEN_MEMBER; + + pDoc->ApplyFlagsTab(aScAddress.Col(), aScAddress.Row(), aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), nMFlag); } } } @@ -301,7 +325,7 @@ void ScXMLDataPilotTableContext::SetButtons() pDPObject->RefreshAfterLoad(); } -void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim) +void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember) { if (pDPSave) { @@ -311,6 +335,30 @@ void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim) pDPSave->GetExistingDimensionByName(pDim->GetName()) ) pDim->SetDupFlag( TRUE ); + if (!pDim->IsDataLayout()) + { + switch (pDim->GetOrientation()) + { + case sheet::DataPilotFieldOrientation_ROW: + ++mnRowFieldCount; + break; + case sheet::DataPilotFieldOrientation_COLUMN: + ++mnColFieldCount; + break; + case sheet::DataPilotFieldOrientation_PAGE: + ++mnPageFieldCount; + break; + case sheet::DataPilotFieldOrientation_DATA: + ++mnDataFieldCount; + break; + case sheet::DataPilotFieldOrientation_HIDDEN: + default: + ; + } + + if (bHasHiddenMember) + maHiddenMemberFields.insert(pDim->GetName()); + } pDPSave->AddDimension(pDim); } } @@ -405,7 +453,7 @@ void ScXMLDataPilotTableContext::EndElement() { ScDPCollection* pDPCollection = pDoc->GetDPCollection(); pDPObject->SetAlive(sal_True); - pDPCollection->Insert(pDPObject); + pDPCollection->InsertNewTable(pDPObject); } SetButtons(); } @@ -833,7 +881,8 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport, bIsGroupField(sal_False), bDateValue(sal_False), bAutoStart(sal_False), - bAutoEnd(sal_False) + bAutoEnd(sal_False), + mbHasHiddenMember(false) { sal_Bool bHasName(sal_False); sal_Bool bDataLayout(sal_False); @@ -928,6 +977,22 @@ SvXMLImportContext *ScXMLDataPilotFieldContext::CreateChildContext( USHORT nPref return pContext; } +void ScXMLDataPilotFieldContext::AddMember(ScDPSaveMember* pMember) +{ + if (pDim) + pDim->AddMember(pMember); + + if (!pMember->GetIsVisible()) + // This member is hidden. + mbHasHiddenMember = true; +} + +void ScXMLDataPilotFieldContext::SetSubTotalName(const OUString& rName) +{ + if (pDim) + pDim->SetSubtotalName(rName); +} + void ScXMLDataPilotFieldContext::AddGroup(const ::std::vector& rMembers, const rtl::OUString& rName) { ScXMLDataPilotGroup aGroup; @@ -948,7 +1013,7 @@ void ScXMLDataPilotFieldContext::EndElement() String sPage(sSelectedPage); pDim->SetCurrentPage(&sPage); } - pDataPilotTable->AddDimension(pDim); + pDataPilotTable->AddDimension(pDim, mbHasHiddenMember); if (bIsGroupField) { ScDPNumGroupInfo aInfo; @@ -995,12 +1060,6 @@ void ScXMLDataPilotFieldContext::EndElement() } } -void ScXMLDataPilotFieldContext::SetSubTotalName(const OUString& rName) -{ - if (pDim) - pDim->SetSubtotalName(rName); -} - ScXMLDataPilotFieldReferenceContext::ScXMLDataPilotFieldReferenceContext( ScXMLImport& rImport, USHORT nPrfx, const ::rtl::OUString& rLName, const uno::Reference& xAttrList, diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx index fee4e36c02e5..50dc7e6d9c0d 100644 --- a/sc/source/filter/xml/xmldpimp.hxx +++ b/sc/source/filter/xml/xmldpimp.hxx @@ -41,6 +41,8 @@ #include "dpobject.hxx" #include "dpsave.hxx" +#include + class ScXMLImport; class ScDPSaveNumGroupDimension; class ScDPSaveGroupDimension; @@ -79,6 +81,9 @@ public: class ScXMLDataPilotTableContext : public SvXMLImportContext { + typedef ::std::hash_set< ::rtl::OUString, ::rtl::OUStringHash > StringSet; + StringSet maHiddenMemberFields; + struct GrandTotalItem { ::rtl::OUString maDisplayName; @@ -108,6 +113,10 @@ class ScXMLDataPilotTableContext : public SvXMLImportContext ScAddress aFilterOutputPosition; ScQueryParam aSourceQueryParam; ScMySourceType nSourceType; + sal_uInt32 mnRowFieldCount; + sal_uInt32 mnColFieldCount; + sal_uInt32 mnPageFieldCount; + sal_uInt32 mnDataFieldCount; sal_Bool bIsNative; sal_Bool bIgnoreEmptyRows; sal_Bool bIdentifyCategories; @@ -156,7 +165,7 @@ public: void SetFilterSourceRange(const ScRange& aValue) { aFilterSourceRange = aValue; } // void SetFilterIsCaseSensitive(const sal_Bool bValue) { aSourceQueryParam.bCaseSens = bValue; } // void SetFilterSkipDuplicates(const sal_Bool bValue) { aSourceQueryParam.bDuplicate = !bValue; } - void AddDimension(ScDPSaveDimension* pDim); + void AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember); void AddGroupDim(const ScDPSaveNumGroupDimension& aNumGroupDim); void AddGroupDim(const ScDPSaveGroupDimension& aGroupDim); void SetButtons(); @@ -337,12 +346,13 @@ class ScXMLDataPilotFieldContext : public SvXMLImportContext sal_Int32 nGroupPart; sal_Int16 nFunction; sal_Int16 nOrientation; - sal_Bool bShowEmpty; - sal_Bool bSelectedPage; - sal_Bool bIsGroupField; - sal_Bool bDateValue; - sal_Bool bAutoStart; - sal_Bool bAutoEnd; + sal_Bool bShowEmpty:1; + sal_Bool bSelectedPage:1; + sal_Bool bIsGroupField:1; + sal_Bool bDateValue:1; + sal_Bool bAutoStart:1; + sal_Bool bAutoEnd:1; + bool mbHasHiddenMember:1; const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } @@ -366,8 +376,8 @@ public: void SetShowEmpty(const sal_Bool bValue) { if (pDim) pDim->SetShowEmpty(bValue); } void SetSubTotals(const sal_uInt16* pFunctions, const sal_Int16 nCount) { if(pDim) pDim->SetSubTotals(nCount, pFunctions); } + void AddMember(ScDPSaveMember* pMember); void SetSubTotalName(const ::rtl::OUString& rName); - void AddMember(ScDPSaveMember* pMember) { if (pDim) pDim->AddMember(pMember); } void SetFieldReference(const com::sun::star::sheet::DataPilotFieldReference& aRef) { if (pDim) pDim->SetReferenceValue(&aRef); } void SetAutoShowInfo(const com::sun::star::sheet::DataPilotFieldAutoShowInfo& aInfo) { if (pDim) pDim->SetAutoShowInfo(&aInfo); } void SetSortInfo(const com::sun::star::sheet::DataPilotFieldSortInfo& aInfo) { if (pDim) pDim->SetSortInfo(&aInfo); } diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx new file mode 100644 index 000000000000..d6aa21ab79bb --- /dev/null +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -0,0 +1,1009 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: document.hxx,v $ + * $Revision: 1.115.36.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include "dpcontrol.hxx" + +#include "vcl/outdev.hxx" +#include "vcl/settings.hxx" +#include "vcl/wintypes.hxx" +#include "vcl/decoview.hxx" + +#define MENU_NOT_SELECTED 999 + +using ::rtl::OUString; +using ::rtl::OUStringHash; +using ::std::vector; +using ::std::hash_map; + +ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle) : + mpOutDev(pOutDev), + mpStyle(pStyle), + mbPopupButton(false), + mbHasHiddenMember(false) +{ +} + +ScDPFieldButton::~ScDPFieldButton() +{ +} + +void ScDPFieldButton::setText(const OUString& rText) +{ + maText = rText; +} + +void ScDPFieldButton::setBoundingBox(const Point& rPos, const Size& rSize) +{ + maPos = rPos; + maSize = rSize; +} + +void ScDPFieldButton::setDrawPopupButton(bool b) +{ + mbPopupButton = b; +} + +void ScDPFieldButton::setHasHiddenMember(bool b) +{ + mbHasHiddenMember = b; +} + +void ScDPFieldButton::draw() +{ + const long nMargin = 2; + + // Background + Rectangle aRect(maPos, maSize); + mpOutDev->SetLineColor(mpStyle->GetFaceColor()); + mpOutDev->SetFillColor(mpStyle->GetFaceColor()); + mpOutDev->DrawRect(aRect); + + // Border lines + mpOutDev->SetLineColor(mpStyle->GetLightColor()); + mpOutDev->DrawLine(Point(maPos), Point(maPos.X(), maPos.Y()+maSize.Height()-1)); + mpOutDev->DrawLine(Point(maPos), Point(maPos.X()+maSize.Width()-1, maPos.Y())); + + mpOutDev->SetLineColor(mpStyle->GetShadowColor()); + mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1), + Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1)); + mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()), + Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1)); + + // Field name + Font aTextFont( mpStyle->GetLabelFont() ); + aTextFont.SetHeight(12); + mpOutDev->SetFont(aTextFont); + + Point aTextPos = maPos; + long nTHeight = mpOutDev->GetTextHeight(); + aTextPos.setX(maPos.getX() + nMargin); + aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2); + mpOutDev->DrawText(aTextPos, maText); + + if (mbPopupButton) + drawPopupButton(); +} + +void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const +{ + long nW = maSize.getWidth()*0.5; + long nH = maSize.getHeight(); + if (nW > 16) + nW = 16; + if (nH > 18) + nH = 18; + + rPos.setX(maPos.getX() + maSize.getWidth() - nW); + rPos.setY(maPos.getY() + maSize.getHeight() - nH); + rSize.setWidth(nW); + rSize.setHeight(nH); +} + +bool ScDPFieldButton::isPopupButton() const +{ + return mbPopupButton; +} + +void ScDPFieldButton::drawPopupButton() +{ + Point aPos; + Size aSize; + getPopupBoundingBox(aPos, aSize); + + // border lines + mpOutDev->SetLineColor(mpStyle->GetLightColor()); + mpOutDev->DrawLine(aPos, Point(aPos.X(), aPos.Y()+aSize.Height()-1)); + mpOutDev->DrawLine(aPos, Point(aPos.X()+aSize.Width()-1, aPos.Y())); + + mpOutDev->SetLineColor(mpStyle->GetShadowColor()); + mpOutDev->DrawLine(Point(aPos.X(), aPos.Y()+aSize.Height()-1), + Point(aPos.X()+aSize.Width()-1, aPos.Y()+aSize.Height()-1)); + mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-1, aPos.Y()), + Point(aPos.X()+aSize.Width()-1, aPos.Y()+aSize.Height()-1)); + + // the arrowhead + Color aArrowColor = mbHasHiddenMember ? mpStyle->GetHighlightLinkColor() : mpStyle->GetButtonTextColor(); + mpOutDev->SetLineColor(aArrowColor); + mpOutDev->SetFillColor(aArrowColor); + Point aCenter(aPos.X() + (aSize.Width() >> 1), aPos.Y() + (aSize.Height() >> 1)); + Point aPos1, aPos2; + aPos1.X() = aCenter.X() - 4; + aPos2.X() = aCenter.X() + 4; + aPos1.Y() = aCenter.Y() - 3; + aPos2.Y() = aCenter.Y() - 3; + + do + { + ++aPos1.X(); + --aPos2.X(); + ++aPos1.Y(); + ++aPos2.Y(); + mpOutDev->DrawLine(aPos1, aPos2); + } + while (aPos1 != aPos2); + + if (mbHasHiddenMember) + { + // tiny little box to display in presence of hidden member(s). + Point aBoxPos(aPos.X() + aSize.Width() - 5, aPos.Y() + aSize.Height() - 5); + Size aBoxSize(3, 3); + mpOutDev->DrawRect(Rectangle(aBoxPos, aBoxSize)); + } +} + +// ============================================================================ + +ScMenuFloatingWindow::MenuItem::MenuItem() : + mbEnabled(true), + mpAction(static_cast(NULL)), + mpSubMenuWin(static_cast(NULL)) +{ +} + +// ---------------------------------------------------------------------------- + +ScMenuFloatingWindow::SubMenuItem::SubMenuItem(ScMenuFloatingWindow* pParent) : + mpSubMenu(NULL), + mnMenuPos(MENU_NOT_SELECTED), + mpParent(pParent) +{ + maTimer.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItem, TimeoutHdl) ); + maTimer.SetTimeout(mpParent->GetSettings().GetMouseSettings().GetMenuDelay()); +} + +void ScMenuFloatingWindow::SubMenuItem::reset() +{ + mpSubMenu = NULL; + mnMenuPos = MENU_NOT_SELECTED; + maTimer.Stop(); +} + +IMPL_LINK( ScMenuFloatingWindow::SubMenuItem, TimeoutHdl, void*, EMPTYARG ) +{ + mpParent->handleMenuTimeout(this); + return 0; +} + +// ---------------------------------------------------------------------------- + +ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent) : + FloatingWindow(pParent, (WB_SYSTEMFLOATWIN|WB_SYSTEMWINDOW|WB_NOBORDER)), + maOpenTimer(this), + maCloseTimer(this), + mnSelectedMenu(MENU_NOT_SELECTED), + mnClickedMenu(MENU_NOT_SELECTED), + mpParentMenu(dynamic_cast(pParent)), + mpActiveSubMenu(NULL), + mbActionFired(false) +{ + // TODO: How do we get the right font to use here ? + const sal_uInt16 nPopupFontHeight = 12; + const StyleSettings& rStyle = GetSettings().GetStyleSettings(); + maLabelFont = rStyle.GetLabelFont(); + maLabelFont.SetHeight(nPopupFontHeight); + SetFont(maLabelFont); + + SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, EndPopupHdl) ); +} + +ScMenuFloatingWindow::~ScMenuFloatingWindow() +{ + EndPopupMode(); +} + +void ScMenuFloatingWindow::MouseMove(const MouseEvent& rMEvt) +{ + const Point& rPos = rMEvt.GetPosPixel(); + size_t nSelectedMenu = getEnclosingMenuItem(rPos); + setSelectedMenuItem(nSelectedMenu); + + Window::MouseMove(rMEvt); +} + +void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent& rMEvt) +{ + const Point& rPos = rMEvt.GetPosPixel(); + mnClickedMenu = getEnclosingMenuItem(rPos); + Window::MouseButtonDown(rMEvt); +} + +void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent& rMEvt) +{ + executeMenu(mnClickedMenu); + mnClickedMenu = MENU_NOT_SELECTED; + Window::MouseButtonUp(rMEvt); +} + +void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt) +{ + const KeyCode& rKeyCode = rKEvt.GetKeyCode(); + bool bHandled = true; + size_t nSelectedMenu = mnSelectedMenu; + size_t nLastMenuPos = maMenuItems.size() - 1; + switch (rKeyCode.GetCode()) + { + case KEY_UP: + if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == 0) + nSelectedMenu = nLastMenuPos; + else + --nSelectedMenu; + setSelectedMenuItem(nSelectedMenu, false); + break; + case KEY_DOWN: + if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == nLastMenuPos) + nSelectedMenu = 0; + else + ++nSelectedMenu; + setSelectedMenuItem(nSelectedMenu, false); + break; + case KEY_LEFT: + if (mpParentMenu) + mpParentMenu->endSubMenu(); + break; + case KEY_RIGHT: + { + if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED) + break; + + const MenuItem& rMenu = maMenuItems[mnSelectedMenu]; + if (!rMenu.mbEnabled || !rMenu.mpSubMenuWin) + break; + + maOpenTimer.mnMenuPos = mnSelectedMenu; + maOpenTimer.mpSubMenu = rMenu.mpSubMenuWin.get(); + launchSubMenu(true); + } + break; + case KEY_RETURN: + if (nSelectedMenu != MENU_NOT_SELECTED) + executeMenu(nSelectedMenu); + break; + default: + bHandled = false; + } + + if (!bHandled) + Window::KeyInput(rKEvt); +} + +void ScMenuFloatingWindow::Paint(const Rectangle& /*rRect*/) +{ + const StyleSettings& rStyle = GetSettings().GetStyleSettings(); + Color aBackColor = rStyle.GetMenuColor(); + Color aBorderColor = rStyle.GetShadowColor(); + + Rectangle aCtrlRect(Point(0, 0), GetOutputSizePixel()); + + // Window background + bool bNativeDrawn = true; + if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL)) + { + SetClipRegion(); + bNativeDrawn = DrawNativeControl( + CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, Region(aCtrlRect), CTRL_STATE_ENABLED, + ImplControlValue(), OUString()); + } + else + bNativeDrawn = false; + + if (!bNativeDrawn) + { + SetFillColor(aBackColor); + SetLineColor(aBorderColor); + DrawRect(aCtrlRect); + } + + // Menu items + SetTextColor(rStyle.GetMenuTextColor()); + drawAllMenuItems(); +} + +void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction) +{ + MenuItem aItem; + aItem.maText = rText; + aItem.mbEnabled = bEnabled; + aItem.mpAction.reset(pAction); + maMenuItems.push_back(aItem); +} + +ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText, bool bEnabled) +{ + MenuItem aItem; + aItem.maText = rText; + aItem.mbEnabled = bEnabled; + aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this)); + maMenuItems.push_back(aItem); + return aItem.mpSubMenuWin.get(); +} + +void ScMenuFloatingWindow::drawMenuItem(size_t nPos) +{ + if (nPos >= maMenuItems.size()) + return; + + Point aPos; + Size aSize; + getMenuItemPosSize(aPos, aSize, nPos); + + DecorationView aDecoView(this); + long nXOffset = 5; + long nYOffset = (aSize.Height() - maLabelFont.GetHeight())/2; + DrawCtrlText(Point(aPos.X()+nXOffset, aPos.Y() + nYOffset), maMenuItems[nPos].maText, 0, STRING_LEN, + maMenuItems[nPos].mbEnabled ? TEXT_DRAW_MNEMONIC : TEXT_DRAW_DISABLE); + + if (maMenuItems[nPos].mpSubMenuWin) + { + long nFontHeight = maLabelFont.GetHeight(); + Point aMarkerPos = aPos; + aMarkerPos.Y() += aSize.Height()/2 - nFontHeight/4 + 1; + aMarkerPos.X() += aSize.Width() - nFontHeight + nFontHeight/4; + Size aMarkerSize(nFontHeight/2, nFontHeight/2); + aDecoView.DrawSymbol(Rectangle(aMarkerPos, aMarkerSize), + SYMBOL_SPIN_RIGHT, GetTextColor(), 0); + } +} + +void ScMenuFloatingWindow::drawAllMenuItems() +{ + size_t n = maMenuItems.size(); + for (size_t i = 0; i < n; ++i) + highlightMenuItem(i, i == mnSelectedMenu); +} + +const Font& ScMenuFloatingWindow::getLabelFont() const +{ + return maLabelFont; +} + +void ScMenuFloatingWindow::executeMenu(size_t nPos) +{ + if (nPos >= maMenuItems.size()) + return; + + if (!maMenuItems[nPos].mpAction) + // no action is defined. + return; + + maMenuItems[nPos].mpAction->execute(); + mbActionFired = true; + EndPopupMode(); +} + +void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer) +{ + if (mnSelectedMenu != nPos) + { + selectMenuItem(mnSelectedMenu, false, bSubMenuTimer); + selectMenuItem(nPos, true, bSubMenuTimer); + mnSelectedMenu = nPos; + } +} + +size_t ScMenuFloatingWindow::getSelectedMenuItem() const +{ + return mnSelectedMenu; +} + +void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItem* pTimer) +{ + if (pTimer == &maOpenTimer) + { + // Close any open submenu immediately. + if (maCloseTimer.mpSubMenu) + { + maCloseTimer.mpSubMenu->EndPopupMode(); + maCloseTimer.mpSubMenu = NULL; + maCloseTimer.maTimer.Stop(); + } + + launchSubMenu(false); + } + else if (pTimer == &maCloseTimer) + { + // end submenu. + if (maCloseTimer.mpSubMenu) + { + maOpenTimer.mpSubMenu = NULL; + + maCloseTimer.mpSubMenu->EndPopupMode(); + maCloseTimer.mpSubMenu = NULL; + + highlightMenuItem(maOpenTimer.mnMenuPos, false); + maOpenTimer.mnMenuPos = MENU_NOT_SELECTED; + } + } +} + +void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu) +{ + if (!pMenu) + return; + + // Set the submenu on launch queue. + if (maOpenTimer.mpSubMenu) + { + if (maOpenTimer.mpSubMenu == pMenu) + { + if (pMenu == maCloseTimer.mpSubMenu) + maCloseTimer.reset(); + return; + } + + // new submenu is being requested. + queueCloseSubMenu(); + } + + maOpenTimer.mpSubMenu = pMenu; + maOpenTimer.mnMenuPos = nPos; + maOpenTimer.maTimer.Start(); +} + +void ScMenuFloatingWindow::queueCloseSubMenu() +{ + if (!maOpenTimer.mpSubMenu) + // There is no submenu to close. + return; + + // Stop any submenu on queue for opening. + maOpenTimer.maTimer.Stop(); + + maCloseTimer.mpSubMenu = maOpenTimer.mpSubMenu; + maCloseTimer.mnMenuPos = maOpenTimer.mnMenuPos; + maCloseTimer.maTimer.Start(); +} + +void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos) +{ + Point aPos; + Size aSize; + getMenuItemPosSize(aPos, aSize, maOpenTimer.mnMenuPos); + ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu; + + if (!pSubMenu) + return; + + sal_uInt32 nOldFlags = GetPopupModeFlags(); + SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE); + pSubMenu->resetMenu(bSetMenuPos); + pSubMenu->StartPopupMode( + Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS)); + pSubMenu->AddPopupModeWindow(this); + SetPopupModeFlags(nOldFlags); +} + +void ScMenuFloatingWindow::endSubMenu() +{ + if (maOpenTimer.mpSubMenu) + { + maOpenTimer.mpSubMenu->EndPopupMode(); + maOpenTimer.mpSubMenu = NULL; + highlightMenuItem(maOpenTimer.mnMenuPos, true); + } +} + +void ScMenuFloatingWindow::notify(NotificationType eType) +{ + switch (eType) + { + case SUBMENU_FOCUSED: + // Cancel any request for ending submenu. + maCloseTimer.reset(); + if (mnSelectedMenu != maOpenTimer.mnMenuPos) + { + highlightMenuItem(maOpenTimer.mnMenuPos, true); + mnSelectedMenu = maOpenTimer.mnMenuPos; + } + break; + default: + ; + } +} + +void ScMenuFloatingWindow::resetMenu(bool bSetMenuPos) +{ + mnSelectedMenu = bSetMenuPos ? 0 : MENU_NOT_SELECTED; + resizeToFitMenuItems(); +} + +void ScMenuFloatingWindow::resizeToFitMenuItems() +{ + if (maMenuItems.empty()) + return; + + vector::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end(); + long nTextWidth = 0; + for (; itr != itrEnd; ++itr) + nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth); + + size_t nLastPos = maMenuItems.size()-1; + Point aPos; + Size aSize; + getMenuItemPosSize(aPos, aSize, nLastPos); + aPos.X() += nTextWidth + 15; + aPos.Y() += aSize.Height() + 5; + SetOutputSizePixel(Size(aPos.X(), aPos.Y())); +} + +void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer) +{ + if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED) + { + queueCloseSubMenu(); + return; + } + + if (!maMenuItems[nPos].mbEnabled) + { + queueCloseSubMenu(); + return; + } + + highlightMenuItem(nPos, bSelected); + + if (bSelected) + { + if (mpParentMenu) + mpParentMenu->notify(SUBMENU_FOCUSED); + + if (bSubMenuTimer) + { + if (maMenuItems[nPos].mpSubMenuWin) + { + ScMenuFloatingWindow* pSubMenu = maMenuItems[nPos].mpSubMenuWin.get(); + queueLaunchSubMenu(nPos, pSubMenu); + } + else + queueCloseSubMenu(); + } + } +} + +void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected) +{ + const StyleSettings& rStyle = GetSettings().GetStyleSettings(); + Color aBackColor = rStyle.GetMenuColor(); + SetFillColor(aBackColor); + SetLineColor(aBackColor); + + Point aPos; + Size aSize; + getMenuItemPosSize(aPos, aSize, nPos); + Region aRegion(Rectangle(aPos,aSize)); + + if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL)) + { + Push(PUSH_CLIPREGION); + IntersectClipRegion(Rectangle(aPos, aSize)); + Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel()); + DrawNativeControl( + CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, Region(aCtrlRect), CTRL_STATE_ENABLED, + ImplControlValue(), OUString()); + + Pop(); + } + + bool bNativeDrawn = true; + if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM)) + { + ControlState nState = bSelected ? CTRL_STATE_SELECTED : 0; + if (maMenuItems[nPos].mbEnabled) + nState |= CTRL_STATE_ENABLED; + bNativeDrawn = DrawNativeControl( + CTRL_MENU_POPUP, PART_MENU_ITEM, aRegion, nState, ImplControlValue(), OUString()); + } + else + bNativeDrawn = false; + + if (!bNativeDrawn) + { + if (bSelected) + { + aBackColor = rStyle.GetMenuHighlightColor(); + SetFillColor(aBackColor); + SetLineColor(aBackColor); + } + DrawRect(Rectangle(aPos,aSize)); + } + + Color aTextColor = bSelected ? rStyle.GetMenuHighlightTextColor() : rStyle.GetMenuTextColor(); + SetTextColor(aTextColor); + drawMenuItem(nPos); +} + +void ScMenuFloatingWindow::getMenuItemPosSize(Point& rPos, Size& rSize, size_t nPos) const +{ + const sal_uInt16 nLeftMargin = 5; + const sal_uInt16 nTopMargin = 5; + const sal_uInt16 nMenuItemHeight = maLabelFont.GetHeight()*1.8; + + Size aWndSize = GetSizePixel(); + + Point aPos1(nLeftMargin, nTopMargin); + Size aSize1(aWndSize.Width() - nLeftMargin*2, nMenuItemHeight); + + rPos = aPos1; + rPos.Y() += aSize1.Height()*nPos; + rSize = aSize1; +} + +size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const +{ + size_t n = maMenuItems.size(); + for (size_t i = 0; i < n; ++i) + { + Point aPos; + Size aSize; + getMenuItemPosSize(aPos, aSize, i); + Rectangle aRect(aPos, aSize); + if (aRect.IsInside(rPos)) + return i; + } + return MENU_NOT_SELECTED; +} + +IMPL_LINK( ScMenuFloatingWindow, EndPopupHdl, void*, EMPTYARG ) +{ + if (mbActionFired && mpParentMenu) + mpParentMenu->EndPopupMode(); + + return 0; +} + +// ============================================================================ + +ScDPFieldPopupWindow::Member::Member() : + mbVisible(true) +{ +} + +// ---------------------------------------------------------------------------- + +ScDPFieldPopupWindow::CancelButton::CancelButton(ScDPFieldPopupWindow* pParent) : + ::CancelButton(pParent), mpParent(pParent) {} + +void ScDPFieldPopupWindow::CancelButton::Click() +{ + mpParent->EndPopupMode(); + ::CancelButton::Click(); +} + +// ---------------------------------------------------------------------------- + +ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : + ScMenuFloatingWindow(pParent), + maCheck0(this, 0), + maCheck1(this, 0), + maCheck2(this, 0), + maCheck3(this, 0), + maCheck4(this, 0), + maCheck5(this, 0), + maCheck6(this, 0), + maCheck7(this, 0), + maCheck8(this, 0), + maCheck9(this, 0), + maScrollBar(this, WB_VERT), + maBtnOk(this), + maBtnCancel(this), + mpExtendedData(NULL), + mpOKAction(NULL), + mnScrollPos(0) +{ + Point aPos; + Size aSize; + getSectionPosSize(aPos, aSize, WHOLE); + SetOutputSizePixel(aSize); + Size aOutSize = GetOutputSizePixel(); + + mpCheckPtr.reserve(10); + mpCheckPtr.push_back(&maCheck0); + mpCheckPtr.push_back(&maCheck1); + mpCheckPtr.push_back(&maCheck2); + mpCheckPtr.push_back(&maCheck3); + mpCheckPtr.push_back(&maCheck4); + mpCheckPtr.push_back(&maCheck5); + mpCheckPtr.push_back(&maCheck6); + mpCheckPtr.push_back(&maCheck7); + mpCheckPtr.push_back(&maCheck8); + mpCheckPtr.push_back(&maCheck9); + + getSectionPosSize(aPos, aSize, FIRST_LISTITEM); + for (vector::iterator itr = mpCheckPtr.begin(), itrEnd = mpCheckPtr.end(); + itr != itrEnd; ++itr) + { + CheckBox* p = *itr; + p->SetPosSizePixel(aPos, aSize); + p->SetFont(getLabelFont()); + p->SetClickHdl( LINK(this, ScDPFieldPopupWindow, CheckBoxHdl) ); + aPos.Y() += aSize.Height() + 1; + } + + getSectionPosSize(aPos, aSize, BTN_OK); + maBtnOk.SetPosSizePixel(aPos, aSize); + maBtnOk.SetFont(getLabelFont()); + maBtnOk.SetClickHdl( LINK(this, ScDPFieldPopupWindow, OKButtonHdl) ); + maBtnOk.Show(); + + getSectionPosSize(aPos, aSize, BTN_CANCEL); + maBtnCancel.SetPosSizePixel(aPos, aSize); + maBtnCancel.SetFont(getLabelFont()); + maBtnCancel.Show(); + + getSectionPosSize(aPos, aSize, SCROLL_BAR_V); + maScrollBar.SetPosSizePixel(aPos, aSize); + maScrollBar.SetPageSize(mpCheckPtr.size()); + maScrollBar.SetVisibleSize(mpCheckPtr.size()); + maScrollBar.SetLineSize(1); + maScrollBar.SetScrollHdl( LINK(this, ScDPFieldPopupWindow, ScrollHdl) ); + maScrollBar.EnableDrag(true); +} + +ScDPFieldPopupWindow::~ScDPFieldPopupWindow() +{ +} + +vector& ScDPFieldPopupWindow::getMembers() +{ + return maMembers; +} + +void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const +{ + const sal_uInt16 nListBoxMargin = 5; + const sal_uInt16 nTopMargin = 5; + const sal_uInt16 nMenuHeight = 60; + const sal_uInt16 nBottomBtnAreaHeight = 50; + const sal_uInt16 nInnerItemMargin = 5; + const sal_uInt16 nScrollBarWidth = 17; + const sal_uInt16 nBtnWidth = 60; + const sal_uInt16 nBtnHeight = getLabelFont().GetHeight()*2; + const sal_uInt16 nBottomMargin = 10; + const sal_uInt16 nMenuListMargin = 20; + + Size aWndSize = Size(160, 330); + + switch (eType) + { + case WHOLE: + { + rPos = Point(0, 0); + rSize = aWndSize; + } + break; + case LISTBOX_AREA: + { + rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin); + rSize = Size( + aWndSize.Width() - nListBoxMargin*2, + aWndSize.Height() - nTopMargin - nMenuHeight - nMenuListMargin - nBottomBtnAreaHeight); + } + break; + case FIRST_LISTITEM: + { + rPos = Point(nListBoxMargin + nInnerItemMargin, + nTopMargin + nMenuHeight + nMenuListMargin + nInnerItemMargin); + rSize = Size( + aWndSize.Width() - nListBoxMargin*2 - nInnerItemMargin - nScrollBarWidth - 10, + 17); + } + break; + case BTN_OK: + { + long x = (aWndSize.Width() - nBtnWidth*2)/3; + long y = aWndSize.Height() - nBottomMargin - nBtnHeight; + rPos = Point(x, y); + rSize = Size(nBtnWidth, nBtnHeight); + } + break; + case BTN_CANCEL: + { + long x = (aWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth; + long y = aWndSize.Height() - nBottomMargin - nBtnHeight; + rPos = Point(x, y); + rSize = Size(nBtnWidth, nBtnHeight); + } + break; + case SCROLL_BAR_V: + { + long x = aWndSize.Width() - nListBoxMargin - nInnerItemMargin - nScrollBarWidth; + long y = nTopMargin + nMenuHeight + nMenuListMargin + nInnerItemMargin; + rPos = Point(x, y); + long h = aWndSize.Height() - nTopMargin - nMenuHeight - nMenuListMargin - nBottomBtnAreaHeight - nInnerItemMargin*2; + rSize = Size(nScrollBarWidth, h); + } + break; + default: + ; + } +} + +void ScDPFieldPopupWindow::resetDisplayedItems() +{ + long nScrollPos = maScrollBar.GetThumbPos(); + if (nScrollPos < 0) + return; + + mnScrollPos = static_cast(nScrollPos); + size_t nCheckCount = mpCheckPtr.size(); + for (size_t i = 0; i < nCheckCount; ++i) + { + CheckBox* p = mpCheckPtr[i]; + p->SetText(maMembers[i+mnScrollPos].maName); + TriState nNewState = maMembers[i+mnScrollPos].mbVisible ? STATE_CHECK : STATE_NOCHECK; + p->SetState(nNewState); + } +} + +IMPL_LINK( ScDPFieldPopupWindow, CheckBoxHdl, CheckBox*, pCheck ) +{ + vector::const_iterator itr, itrBeg = mpCheckPtr.begin(), itrEnd = mpCheckPtr.end(); + for (itr = itrBeg; itr != itrEnd; ++itr) + { + if (*itr == pCheck) + { + size_t nIndex = ::std::distance(itrBeg, itr); + maMembers[nIndex+mnScrollPos].mbVisible = !maMembers[nIndex+mnScrollPos].mbVisible; + } + } + return 0; +} + +IMPL_LINK( ScDPFieldPopupWindow, OKButtonHdl, OKButton*, EMPTYARG ) +{ + close(true); + return 0; +} + +IMPL_LINK( ScDPFieldPopupWindow, ScrollHdl, ScrollBar*, EMPTYARG ) +{ + resetDisplayedItems(); + return 0; +} + +void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt) +{ + ScMenuFloatingWindow::MouseMove(rMEvt); + + size_t nSelectedMenu = getSelectedMenuItem(); + if (nSelectedMenu == MENU_NOT_SELECTED) + queueCloseSubMenu(); +} + +void ScDPFieldPopupWindow::Paint(const Rectangle& rRect) +{ + ScMenuFloatingWindow::Paint(rRect); + + const StyleSettings& rStyle = GetSettings().GetStyleSettings(); + Color aMemberBackColor = rStyle.GetFieldColor(); + + // Member list box background + SetFillColor(aMemberBackColor); + Point aPos; + Size aSize; + getSectionPosSize(aPos, aSize, LISTBOX_AREA); + DrawRect(Rectangle(aPos,aSize)); +} + +void ScDPFieldPopupWindow::setMemberSize(size_t n) +{ + maMembers.reserve(n); +} + +void ScDPFieldPopupWindow::addMember(const OUString& rName, bool bVisible) +{ + Member aMember; + aMember.maName = rName; + aMember.mbVisible = bVisible; + maMembers.push_back(aMember); +} + +void ScDPFieldPopupWindow::initMembers() +{ + size_t nMemCount = maMembers.size(); + size_t nCheckCount = mpCheckPtr.size(); + bool bNeedsScroll = false; + if (nMemCount > nCheckCount) + { + nMemCount = nCheckCount; + bNeedsScroll = true; + } + + for (size_t i = 0; i < nMemCount; ++i) + { + CheckBox* p = mpCheckPtr[i]; + p->SetText(maMembers[i].maName); + p->Show(); + p->SetState(maMembers[i].mbVisible ? STATE_CHECK : STATE_NOCHECK); + } + if (bNeedsScroll) + { + maScrollBar.SetRange(Range(0, maMembers.size())); + maScrollBar.Show(); + } +} + +void ScDPFieldPopupWindow::getResult(hash_map& rResult) +{ + typedef hash_map ResultMap; + ResultMap aResult; + vector::const_iterator itr = maMembers.begin(), itrEnd = maMembers.end(); + for (; itr != itrEnd; ++itr) + aResult.insert(ResultMap::value_type(itr->maName, itr->mbVisible)); + rResult.swap(aResult); +} + +void ScDPFieldPopupWindow::close(bool bOK) +{ + if (bOK && mpOKAction.get()) + mpOKAction->execute(); + + EndPopupMode(); +} + +void ScDPFieldPopupWindow::setExtendedData(ExtendedData* p) +{ + mpExtendedData.reset(p); +} + +ScDPFieldPopupWindow::ExtendedData* ScDPFieldPopupWindow::getExtendedData() +{ + return mpExtendedData.get(); +} + +void ScDPFieldPopupWindow::setOKAction(Action* p) +{ + mpOKAction.reset(p); +} + diff --git a/sc/source/ui/cctrl/dpcontrol.src b/sc/source/ui/cctrl/dpcontrol.src new file mode 100644 index 000000000000..5f7ab9a66a9f --- /dev/null +++ b/sc/source/ui/cctrl/dpcontrol.src @@ -0,0 +1,49 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: globstr.src,v $ + * $Revision: 1.74.96.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "dpcontrol.hrc" + +Resource RID_POPUP_FILTER +{ + String STR_MENU_SORT_ASC + { + Text [ en-US ] = "Sort Ascending" ; + }; + + String STR_MENU_SORT_DESC + { + Text [ en-US ] = "Sort Descending" ; + }; + + String STR_MENU_SORT_CUSTOM + { + Text [ en-US ] = "Custom Sort" ; + }; +}; diff --git a/sc/source/ui/cctrl/makefile.mk b/sc/source/ui/cctrl/makefile.mk index e7b96afd7b9a..541a90cc4347 100644 --- a/sc/source/ui/cctrl/makefile.mk +++ b/sc/source/ui/cctrl/makefile.mk @@ -45,22 +45,30 @@ LIBTARGET=NO # --- Files -------------------------------------------------------- EXCEPTIONSFILES= \ - $(SLO)$/tbzoomsliderctrl.obj + $(SLO)$/tbzoomsliderctrl.obj \ + $(SLO)$/dpcontrol.obj SLOFILES = \ $(SLO)$/popmenu.obj \ $(SLO)$/tbinsert.obj \ $(SLO)$/cbuttonw.obj \ + $(SLO)$/dpcontrol.obj \ $(SLO)$/editfield.obj \ $(EXCEPTIONSFILES) +SRS1NAME=$(TARGET) +SRC1FILES = \ + dpcontrol.src + LIB1TARGET=$(SLB)$/$(TARGET).lib LIB1OBJFILES= \ $(SLO)$/popmenu.obj \ $(SLO)$/tbinsert.obj \ $(SLO)$/cbuttonw.obj \ + $(SLO)$/dpcontrol.obj \ $(SLO)$/tbzoomsliderctrl.obj + # --- Tagets ------------------------------------------------------- .INCLUDE : target.mk diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx index c23068b82200..688c0d60f79e 100644 --- a/sc/source/ui/dbgui/pvlaydlg.cxx +++ b/sc/source/ui/dbgui/pvlaydlg.cxx @@ -64,6 +64,7 @@ #include "scabstdlg.hxx" //CHINA001 using namespace com::sun::star; using ::rtl::OUString; +using ::std::vector; //---------------------------------------------------------------------------- @@ -379,24 +380,23 @@ void ScDPLayoutDlg::StateChanged( StateChangedType nStateChange ) //---------------------------------------------------------------------------- -void ScDPLayoutDlg::InitWndSelect( LabelData** ppLabelArr, long nLabels ) +void ScDPLayoutDlg::InitWndSelect( const vector& rLabels ) { - if ( ppLabelArr ) + size_t nLabelCount = rLabels.size(); + if (nLabelCount > MAX_LABELS) + nLabelCount = MAX_LABELS; + size_t nLast = (nLabelCount > PAGE_SIZE) ? (PAGE_SIZE - 1) : (nLabelCount - 1); + + aLabelDataArr.clear(); + aLabelDataArr.reserve( nLabelCount ); + for ( size_t i=0; i < nLabelCount; i++ ) { - size_t nLabelCount = static_cast< size_t >( (nLabels > MAX_LABELS) ? MAX_LABELS : nLabels ); - size_t nLast = (nLabelCount > PAGE_SIZE) ? (PAGE_SIZE - 1) : (nLabelCount - 1); + aLabelDataArr.push_back(*rLabels[i]); - aLabelDataArr.clear(); - aLabelDataArr.reserve( nLabelCount ); - for ( size_t i=0; i < nLabelCount; i++ ) + if ( i <= nLast ) { - aLabelDataArr.push_back( *ppLabelArr[i] ); - - if ( i <= nLast ) - { - aWndSelect.AddField( aLabelDataArr[i].maName, i ); - aSelectArr[i].reset( new ScDPFuncData( aLabelDataArr[i].mnCol, aLabelDataArr[i].mnFuncMask ) ); - } + aWndSelect.AddField( aLabelDataArr[i].maName, i ); + aSelectArr[i].reset( new ScDPFuncData( aLabelDataArr[i].mnCol, aLabelDataArr[i].mnFuncMask ) ); } } } @@ -494,18 +494,19 @@ void ScDPLayoutDlg::InitFocus() void ScDPLayoutDlg::InitFields() { - InitWndSelect( thePivotData.ppLabelArr, static_cast(thePivotData.nLabels) ); + InitWndSelect(thePivotData.maLabelArray); InitWnd( thePivotData.aPageArr, static_cast(thePivotData.nPageCount), TYPE_PAGE ); InitWnd( thePivotData.aColArr, static_cast(thePivotData.nColCount), TYPE_COL ); InitWnd( thePivotData.aRowArr, static_cast(thePivotData.nRowCount), TYPE_ROW ); InitWnd( thePivotData.aDataArr, static_cast(thePivotData.nDataCount), TYPE_DATA ); + size_t nLabels = thePivotData.maLabelArray.size(); aSlider.SetPageSize( PAGE_SIZE ); aSlider.SetVisibleSize( PAGE_SIZE ); aSlider.SetLineSize( LINE_SIZE ); - aSlider.SetRange( Range( 0, static_cast(((thePivotData.nLabels+LINE_SIZE-1)/LINE_SIZE)*LINE_SIZE) ) ); + aSlider.SetRange( Range( 0, static_cast(((nLabels+LINE_SIZE-1)/LINE_SIZE)*LINE_SIZE) ) ); - if ( thePivotData.nLabels > PAGE_SIZE ) + if ( nLabels > PAGE_SIZE ) { aSlider.SetEndScrollHdl( LINK( this, ScDPLayoutDlg, ScrollHdl ) ); aSlider.Show(); diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 1e85f3c01f3e..ebbdd6cfbae4 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -1233,7 +1233,7 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb aRange.aEnd.Col(), aRange.aEnd.Row(), nTab, SC_MF_AUTO ); - pDoc->GetDPCollection()->Free( pOldObj ); // object is deleted here + pDoc->GetDPCollection()->FreeTable( pOldObj ); // object is deleted here rDocShell.PostPaintGridAll(); //! only necessary parts rDocShell.PostPaint( aRange.aStart.Col(), aRange.aStart.Row(), nTab, @@ -1277,7 +1277,7 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb pDestObj = new ScDPObject( *pNewObj ); pDestObj->SetAlive(TRUE); - if ( !pDoc->GetDPCollection()->Insert(pDestObj) ) + if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) ) { DBG_ERROR("cannot insert DPObject"); DELETEZ( pDestObj ); diff --git a/sc/source/ui/inc/dbfunc.hxx b/sc/source/ui/inc/dbfunc.hxx index 82739bfdd274..afeb90df1a79 100644 --- a/sc/source/ui/inc/dbfunc.hxx +++ b/sc/source/ui/inc/dbfunc.hxx @@ -99,6 +99,7 @@ public: void UngroupDataPilot(); void DataPilotInput( const ScAddress& rPos, const String& rString ); + bool DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId = NULL ); BOOL DataPilotMove( const ScRange& rSource, const ScAddress& rDest ); BOOL HasSelectionForDrillDown( USHORT& rOrientation ); diff --git a/sc/source/ui/inc/dpcontrol.hrc b/sc/source/ui/inc/dpcontrol.hrc new file mode 100644 index 000000000000..7ec03c5134ae --- /dev/null +++ b/sc/source/ui/inc/dpcontrol.hrc @@ -0,0 +1,40 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: protectiondlg.hrc,v $ + * $Revision: 1.1.2.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __DPCONTROL_HRC__ +#define __DPCONTROL_HRC__ + +#include + +#define STR_MENU_SORT_ASC 1 +#define STR_MENU_SORT_DESC 2 +#define STR_MENU_SORT_CUSTOM 3 + +#endif diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx new file mode 100644 index 000000000000..5c1e7a59aad2 --- /dev/null +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -0,0 +1,289 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: document.hxx,v $ + * $Revision: 1.115.36.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_DPCONTROL_HXX +#define SC_DPCONTROL_HXX + +#include "rtl/ustring.hxx" +#include "tools/gen.hxx" +#include "vcl/floatwin.hxx" +#include "vcl/button.hxx" +#include "vcl/scrbar.hxx" +#include "vcl/timer.hxx" + +#include +#include +#include + +class OutputDevice; +class Point; +class Size; +class StyleSettings; +class Window; + +/** + * This class takes care of physically drawing field button controls inside + * data pilot tables. + */ +class ScDPFieldButton +{ +public: + ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle); + ~ScDPFieldButton(); + + void setText(const ::rtl::OUString& rText); + void setBoundingBox(const Point& rPos, const Size& rSize); + void setDrawPopupButton(bool b); + void setHasHiddenMember(bool b); + void draw(); + + void getPopupBoundingBox(Point& rPos, Size& rSize) const; + bool isPopupButton() const; + +private: + void drawPopupButton(); + +private: + Point maPos; + Size maSize; + ::rtl::OUString maText; + OutputDevice* mpOutDev; + const StyleSettings* mpStyle; + bool mbPopupButton; + bool mbHasHiddenMember; +}; + +// ============================================================================ + +class ScMenuFloatingWindow : public FloatingWindow +{ +public: + /** + * Action to perform when an event takes place. Create a sub-class of + * this to implement the desired action. + */ + class Action + { + public: + virtual void execute() = 0; + }; + + explicit ScMenuFloatingWindow(Window* pParent); + virtual ~ScMenuFloatingWindow(); + + virtual void MouseMove(const MouseEvent& rMEvt); + virtual void MouseButtonDown(const MouseEvent& rMEvt); + virtual void MouseButtonUp(const MouseEvent& rMEvt); + virtual void KeyInput(const KeyEvent& rKEvt); + virtual void Paint(const Rectangle& rRect); + + void addMenuItem(const ::rtl::OUString& rText, bool bEnabled, Action* pAction); + ScMenuFloatingWindow* addSubMenuItem(const ::rtl::OUString& rText, bool bEnabled); + +protected: + void drawMenuItem(size_t nPos); + void drawAllMenuItems(); + const Font& getLabelFont() const; + + void executeMenu(size_t nPos); + void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer = true); + size_t getSelectedMenuItem() const; + void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu); + void queueCloseSubMenu(); + void launchSubMenu(bool bSetMenuPos); + void endSubMenu(); + +private: + struct SubMenuItem; + void handleMenuTimeout(SubMenuItem* pTimer); + + enum NotificationType { SUBMENU_FOCUSED }; + void notify(NotificationType eType); + + void resetMenu(bool bSetMenuPos); + void resizeToFitMenuItems(); + void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer); + void highlightMenuItem(size_t nPos, bool bSelected); + + void getMenuItemPosSize(Point& rPos, Size& rSize, size_t nPos) const; + size_t getEnclosingMenuItem(const Point& rPos) const; + + DECL_LINK( EndPopupHdl, void* ); + +private: + struct MenuItem + { + ::rtl::OUString maText; + bool mbEnabled; + + ::boost::shared_ptr mpAction; + ::boost::shared_ptr mpSubMenuWin; + + MenuItem(); + }; + + ::std::vector maMenuItems; + + struct SubMenuItem + { + Timer maTimer; + ScMenuFloatingWindow* mpSubMenu; + size_t mnMenuPos; + + DECL_LINK( TimeoutHdl, void* ); + + SubMenuItem(ScMenuFloatingWindow* pParent); + void reset(); + + private: + ScMenuFloatingWindow* mpParent; + }; + SubMenuItem maOpenTimer; + SubMenuItem maCloseTimer; + + Font maLabelFont; + + size_t mnSelectedMenu; + size_t mnClickedMenu; + + ScMenuFloatingWindow* mpParentMenu; + ScMenuFloatingWindow* mpActiveSubMenu; + + bool mbActionFired; +}; + +// ============================================================================ + +/** + * This class implements a popup window for field button, for quick access + * of hide-item list, and possibly more stuff related to field options. + */ +class ScDPFieldPopupWindow : public ScMenuFloatingWindow +{ +public: + /** + * Extended data that the client code may need to store. Create a + * sub-class of this and store data there. + */ + struct ExtendedData {}; + + explicit ScDPFieldPopupWindow(Window* pParent); + virtual ~ScDPFieldPopupWindow(); + + virtual void MouseMove(const MouseEvent& rMEvt); + virtual void Paint(const Rectangle& rRect); + + void setMemberSize(size_t n); + void addMember(const ::rtl::OUString& rName, bool bVisible); + void initMembers(); + + void getResult(::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rResult); + void close(bool bOK); + + /** + * Set auxiliary data that the client code might need. Note that this + * popup window class manages its life time; no explicit deletion of the + * instance is needed in the client code. + */ + void setExtendedData(ExtendedData* p); + + /** + * Get the store auxiliary data, or NULL if no such data is stored. + */ + ExtendedData* getExtendedData(); + + void setOKAction(Action* p); + +private: + struct Member + { + ::rtl::OUString maName; + bool mbVisible; + + Member(); + }; + + class CancelButton : public ::CancelButton + { + public: + CancelButton(ScDPFieldPopupWindow* pParent); + + virtual void Click(); + + private: + ScDPFieldPopupWindow* mpParent; + }; + + ::std::vector& getMembers(); + + enum SectionType { + WHOLE, // entire window + LISTBOX_AREA, // box enclosing the check box items. + FIRST_LISTITEM, // first list item at the top + BTN_OK, // OK button + BTN_CANCEL, // Cancel button + SCROLL_BAR_V, // vertical scroll bar along the right edge of the list box. + }; + void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const; + + void resetDisplayedItems(); + + DECL_LINK( CheckBoxHdl, CheckBox* ); + DECL_LINK( OKButtonHdl, OKButton* ); + DECL_LINK( ScrollHdl, ScrollBar* ); + +private: + + CheckBox maCheck0; + CheckBox maCheck1; + CheckBox maCheck2; + CheckBox maCheck3; + CheckBox maCheck4; + CheckBox maCheck5; + CheckBox maCheck6; + CheckBox maCheck7; + CheckBox maCheck8; + CheckBox maCheck9; + + ScrollBar maScrollBar; + + OKButton maBtnOk; + CancelButton maBtnCancel; + + ::std::vector mpCheckPtr; + + ::std::vector maMembers; + ::std::auto_ptr mpExtendedData; + ::std::auto_ptr mpOKAction; + + size_t mnScrollPos; +}; + +#endif diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index 9b31289d13d0..32ecaf26cc56 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -39,6 +39,7 @@ #include #include +#include // --------------------------------------------------------------------------- @@ -48,6 +49,7 @@ class ScViewSelectionEngine; class ScPivot; #endif class ScDPObject; +class ScDPFieldPopupWindow; class ScOutputData; class ScFilterListBox; class AutoFilterPopup; @@ -159,6 +161,7 @@ private: ScFilterListBox* pFilterBox; FloatingWindow* pFilterFloat; + ::std::auto_ptr mpDPFieldPopup; USHORT nCursorHideCount; @@ -245,6 +248,16 @@ private: void DPMouseButtonUp( const MouseEvent& rMEvt ); void DPTestMouse( const MouseEvent& rMEvt, BOOL bMove ); + /** + * Check if the mouse click is on a field popup button. + * + * @return bool true if the field popup menu has been launched and no + * further mouse event handling is necessary, false otherwise. + */ + bool DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj); + void DPLaunchFieldPopupMenu( + const Point& rSrcPos, const Size& rSrcSize, const ScAddress& rPos, ScDPObject* pDPObj); + void RFMouseMove( const MouseEvent& rMEvt, BOOL bUp ); void PagebreakMove( const MouseEvent& rMEvt, BOOL bUp ); @@ -409,6 +422,8 @@ public: void CheckNeedsRepaint(); + void UpdateDPFromFieldPopupMenu(); + // #114409# void CursorChanged(); void DrawLayerCreated(); diff --git a/sc/source/ui/inc/pvlaydlg.hxx b/sc/source/ui/inc/pvlaydlg.hxx index b7a71aebc1fe..c77364d3761f 100644 --- a/sc/source/ui/inc/pvlaydlg.hxx +++ b/sc/source/ui/inc/pvlaydlg.hxx @@ -193,7 +193,7 @@ private: private: ScDPFieldWindow& GetFieldWindow ( ScDPFieldType eType ); void Init (); - void InitWndSelect ( LabelData** ppLabelArr, long nLabels ); + void InitWndSelect ( const ::std::vector& rLabels ); void InitWnd ( PivotField* pArr, long nCount, ScDPFieldType eType ); void InitFocus (); void InitFields (); diff --git a/sc/source/ui/undo/undodat.cxx b/sc/source/ui/undo/undodat.cxx index f16409b37239..ffc750a7ceb8 100644 --- a/sc/source/ui/undo/undodat.cxx +++ b/sc/source/ui/undo/undodat.cxx @@ -1876,7 +1876,7 @@ void __EXPORT ScUndoDataPilot::Undo() else { // delete inserted object - pDoc->GetDPCollection()->Free(pDocObj); + pDoc->GetDPCollection()->FreeTable(pDocObj); } } } @@ -1886,7 +1886,7 @@ void __EXPORT ScUndoDataPilot::Undo() ScDPObject* pDestObj = new ScDPObject( *pOldDPObject ); pDestObj->SetAlive(TRUE); - if ( !pDoc->GetDPCollection()->Insert(pDestObj) ) + if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) ) { DBG_ERROR("cannot insert DPObject"); DELETEZ( pDestObj ); diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index c71bc31a1150..e0d6693b39ef 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -81,9 +81,13 @@ #include "patattr.hxx" #include "unonames.hxx" #include "cell.hxx" +#include "userlist.hxx" #include +#include #include +#include +#include using namespace com::sun::star; using ::com::sun::star::uno::Any; @@ -94,8 +98,13 @@ using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::container::XNameAccess; using ::com::sun::star::sheet::XDimensionsSupplier; using ::rtl::OUString; +using ::rtl::OUStringHash; using ::rtl::OUStringBuffer; using ::std::auto_ptr; +using ::std::list; +using ::std::vector; +using ::std::hash_map; +using ::std::hash_set; // STATIC DATA ----------------------------------------------------------- @@ -1681,6 +1690,134 @@ void lcl_MoveToEnd( ScDPSaveDimension& rDim, const String& rItemName ) // puts it to the end of the list even if it was in the list before. } +bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId ) +{ + ScDocument* pDoc = GetViewData()->GetDocument(); + ScDPObject* pDPObj = pDoc->GetDPAtCursor(rPos.Col(), rPos.Row(), rPos.Tab()); + if (!pDPObj) + return false; + + // We need to run this to get all members later. + pDPObj->BuildAllDimensionMembers(); + + USHORT nOrientation; + long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation); + if (nDimIndex < 0) + // Invalid dimension index. Bail out. + return false; + + BOOL bDataLayout; + ScDPSaveData* pSaveData = pDPObj->GetSaveData(); + if (!pSaveData) + return false; + + ScDPSaveData aNewSaveData(*pSaveData); + String aDimName = pDPObj->GetDimName(nDimIndex, bDataLayout); + ScDPSaveDimension* pSaveDim = aNewSaveData.GetDimensionByName(aDimName); + if (!pSaveDim) + return false; + + typedef ScDPSaveDimension::MemberList MemList; + const MemList& rDimMembers = pSaveDim->GetMembers(); + list aMembers; + hash_set aMemberSet; + size_t nMemberCount = 0; + for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end(); + itr != itrEnd; ++itr) + { + ScDPSaveMember* pMem = *itr; + aMembers.push_back(pMem->GetName()); + aMemberSet.insert(pMem->GetName()); + ++nMemberCount; + } + + // Sort the member list in ascending order. + aMembers.sort(); + + // Collect and rank those custom sort strings that also exist in the member name list. + + typedef hash_map UserSortMap; + UserSortMap aSubStrs; + sal_uInt16 nSubCount = 0; + if (pUserListId) + { + ScUserList* pUserList = ScGlobal::GetUserList(); + if (!pUserList) + return false; + + { + sal_uInt16 n = pUserList->GetCount(); + if (!n || *pUserListId >= n) + return false; + } + + ScUserListData* pData = static_cast((*pUserList)[*pUserListId]); + if (pData) + { + sal_uInt16 n = pData->GetSubCount(); + for (sal_uInt16 i = 0; i < n; ++i) + { + OUString aSub = pData->GetSubStr(i); + if (!aMemberSet.count(aSub)) + // This string doesn't exist in the member name set. Don't add this. + continue; + + aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++)); + } + } + } + + // Rank all members. + + vector aRankedNames(nMemberCount); + sal_uInt16 nCurStrId = 0; + for (list::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end(); + itr != itrEnd; ++itr) + { + OUString aName = *itr; + sal_uInt16 nRank = 0; + UserSortMap::const_iterator itrSub = aSubStrs.find(aName); + if (itrSub == aSubStrs.end()) + nRank = nSubCount + nCurStrId++; + else + nRank = itrSub->second; + + if (!bAscending) + nRank = nMemberCount - nRank - 1; + + aRankedNames[nRank] = aName; + } + + // Re-order ScDPSaveMember instances with the new ranks. + + for (vector::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end(); + itr != itrEnd; ++itr) + { + const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr); + if (!pOldMem) + // All members are supposed to be present. + continue; + + ScDPSaveMember* pNewMem = new ScDPSaveMember(*pOldMem); + pSaveDim->AddMember(pNewMem); + } + + // Set the sorting mode to manual for now. We may introduce a new sorting + // mode later on. + + sheet::DataPilotFieldSortInfo aSortInfo; + aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL; + pSaveDim->SetSortInfo(&aSortInfo); + + // Update the datapilot with the newly sorted field members. + + auto_ptr pNewObj(new ScDPObject(*pDPObj)); + pNewObj->SetSaveData(aNewSaveData); + ScDBDocFunc aFunc(*GetViewData()->GetDocShell()); + + return aFunc.DataPilotUpdate(pDPObj, pNewObj.get(), true, false); +} + BOOL ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest ) { BOOL bRet = FALSE; diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 5591a2a496be..8949d2bd29a9 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -119,6 +119,7 @@ #include "drwlayer.hxx" #include "attrib.hxx" #include "validat.hxx" +#include "dpcontrol.hxx" // #114409# #include // FRound @@ -370,6 +371,7 @@ ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhic pNoteMarker( NULL ), pFilterBox( NULL ), pFilterFloat( NULL ), + mpDPFieldPopup(NULL), nCursorHideCount( 0 ), bMarking( FALSE ), nButtonDown( 0 ), diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index 92743ef65524..1cfb5bdf71c0 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -55,11 +55,23 @@ #include "dpoutput.hxx" // ScDPPositionData #include "dpshttab.hxx" #include "dbdocfun.hxx" +#include "dpcontrol.hxx" +#include "dpcontrol.hrc" +#include "strload.hxx" +#include "userlist.hxx" #include #include "scabstdlg.hxx" //CHINA001 -using namespace com::sun::star; +#include +#include + +using namespace com::sun::star; +using ::std::vector; +using ::std::auto_ptr; +using ::std::hash_map; +using ::rtl::OUString; +using ::rtl::OUStringHash; // STATIC DATA ----------------------------------------------------------- @@ -199,6 +211,15 @@ void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt bDPMouse = TRUE; nDPField = nField; pDragDPObj = pDPObj; + + if (DPTestFieldPopupArrow(rMEvt, aPos, pDPObj)) + { + // field name pop up menu has been launched. Don't activate + // field move. + bDPMouse = false; + return; + } + DPTestMouse( rMEvt, TRUE ); StartTracking(); } @@ -726,6 +747,185 @@ void ScGridWindow::DPTestMouse( const MouseEvent& rMEvt, BOOL bMove ) pViewData->GetView()->ResetTimer(); } +bool ScGridWindow::DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj) +{ + // Get the geometry of the cell. + Point aSrcPos = pViewData->GetScrPos(rPos.Col(), rPos.Row(), eWhich); + long nSizeX, nSizeY; + pViewData->GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeX, nSizeY); + Size aSrcSize(nSizeX-1, nSizeY-1); + + // Check if the mouse cursor is clicking on the popup arrow box. + ScDPFieldButton aBtn(this, &GetSettings().GetStyleSettings()); + aBtn.setBoundingBox(aSrcPos, aSrcSize); + Point aPopupPos; + Size aPopupSize; + aBtn.getPopupBoundingBox(aPopupPos, aPopupSize); + Rectangle aRec(aPopupPos, aPopupSize); + if (aRec.IsInside(rMEvt.GetPosPixel())) + { + // Mouse cursor inside the popup arrow box. Launch the field menu. + DPLaunchFieldPopupMenu(OutputToScreenPixel(aSrcPos), aSrcSize, rPos, pDPObj); + return true; + } + + return false; +} + +namespace { + +struct DPFieldPopupData : public ScDPFieldPopupWindow::ExtendedData +{ + ScPivotParam maDPParam; + ScDPObject* mpDPObj; + long mnDim; +}; + +class DPFieldPopupOKAction : public ScMenuFloatingWindow::Action +{ +public: + explicit DPFieldPopupOKAction(ScGridWindow* p) : + mpGridWindow(p) {} + + virtual void execute() + { + mpGridWindow->UpdateDPFromFieldPopupMenu(); + } +private: + ScGridWindow* mpGridWindow; +}; + +class PopupSortAction : public ScMenuFloatingWindow::Action +{ +public: + enum SortType { ASCENDING, DESCENDING, CUSTOM }; + + explicit PopupSortAction(const ScAddress& rPos, SortType eType, sal_uInt16 nUserListIndex, ScTabViewShell* pViewShell) : + maPos(rPos), meType(eType), mnUserListIndex(nUserListIndex), mpViewShell(pViewShell) {} + + virtual void execute() + { + switch (meType) + { + case ASCENDING: + mpViewShell->DataPilotSort(maPos, true); + break; + case DESCENDING: + mpViewShell->DataPilotSort(maPos, false); + break; + case CUSTOM: + mpViewShell->DataPilotSort(maPos, true, &mnUserListIndex); + break; + default: + ; + } + } + +private: + ScAddress maPos; + SortType meType; + sal_uInt16 mnUserListIndex; + ScTabViewShell* mpViewShell; +}; + +} + +void ScGridWindow::DPLaunchFieldPopupMenu( + const Point& rSrcPos, const Size& rSrcSize, const ScAddress& rPos, ScDPObject* pDPObj) +{ + // We need to get the list of field members. + auto_ptr pDPData(new DPFieldPopupData); + pDPObj->FillLabelData(pDPData->maDPParam); + pDPData->mpDPObj = pDPObj; + + USHORT nOrient; + pDPData->mnDim = pDPObj->GetHeaderDim(rPos, nOrient); + + if (pDPData->maDPParam.maLabelArray.size() <= static_cast(pDPData->mnDim)) + // out-of-bound dimension ID. This should never happen! + return; + + const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim]; + + mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this)); + mpDPFieldPopup->setExtendedData(pDPData.release()); + mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this)); + { + sal_Int32 n = rLabelData.maMembers.getLength(); + mpDPFieldPopup->setMemberSize(n); + for (sal_Int32 i = 0; i < n; ++i) + mpDPFieldPopup->addMember(rLabelData.maMembers[i], rLabelData.maVisible[i]); + mpDPFieldPopup->initMembers(); + } + + vector aUserSortNames; + ScUserList* pUserList = ScGlobal::GetUserList(); + if (pUserList) + { + sal_uInt16 n = pUserList->GetCount(); + aUserSortNames.reserve(n); + for (sal_uInt16 i = 0; i < n; ++i) + { + ScUserListData* pData = static_cast((*pUserList)[i]); + aUserSortNames.push_back(pData->GetString()); + } + } + + // Populate the menus. + ScTabViewShell* pViewShell = pViewData->GetViewShell(); + mpDPFieldPopup->addMenuItem( + ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_ASC).GetString(), true, + new PopupSortAction(rPos, PopupSortAction::ASCENDING, 0, pViewShell)); + mpDPFieldPopup->addMenuItem( + ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_DESC).GetString(), true, + new PopupSortAction(rPos, PopupSortAction::DESCENDING, 0, pViewShell)); + ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem( + ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_CUSTOM).GetString(), !aUserSortNames.empty()); + + if (pSubMenu && !aUserSortNames.empty()) + { + size_t n = aUserSortNames.size(); + for (size_t i = 0; i < n; ++i) + { + pSubMenu->addMenuItem( + aUserSortNames[i], true, + new PopupSortAction(rPos, PopupSortAction::CUSTOM, i, pViewShell)); + } + } + + mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) ); + Rectangle aCellRect(rSrcPos, rSrcSize); + mpDPFieldPopup->StartPopupMode(aCellRect, (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_GRABFOCUS)); +} + +void ScGridWindow::UpdateDPFromFieldPopupMenu() +{ + if (!mpDPFieldPopup.get()) + return; + + DPFieldPopupData* pDPData = static_cast(mpDPFieldPopup->getExtendedData()); + if (!pDPData) + return; + + ScDPObject* pDPObj = pDPData->mpDPObj; + ScDPObject aNewDPObj(*pDPObj); + aNewDPObj.BuildAllDimensionMembers(); + ScDPSaveData* pSaveData = aNewDPObj.GetSaveData(); + + BOOL bIsDataLayout; + String aDimName = pDPObj->GetDimName(pDPData->mnDim, bIsDataLayout); + ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(aDimName); + if (!pDim) + return; + + hash_map aResult; + mpDPFieldPopup->getResult(aResult); + pDim->UpdateMemberVisibility(aResult); + + ScDBDocFunc aFunc(*pViewData->GetDocShell()); + aFunc.DataPilotUpdate(pDPObj, &aNewDPObj, true, false); +} + void ScGridWindow::DPMouseMove( const MouseEvent& rMEvt ) { DPTestMouse( rMEvt, TRUE ); diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index b90e5d3e802e..e6466e7ba3b1 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -73,6 +73,7 @@ #include "editutil.hxx" #include "inputopt.hxx" #include "fillinfo.hxx" +#include "dpcontrol.hxx" #include "sc.hrc" #include @@ -1203,6 +1204,8 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2 { aComboButton.SetOutputDevice( pContentDev ); + ScDPFieldButton aDPFieldBtn(pContentDev, &GetSettings().GetStyleSettings()); + SCCOL nCol; SCROW nRow; SCSIZE nArrY; @@ -1318,13 +1321,13 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2 nPosX -= nSizeX - 2; } - pContentDev->SetLineColor( GetSettings().GetStyleSettings().GetLightColor() ); - pContentDev->DrawLine( Point(nPosX,nPosY), Point(nPosX,nPosY+nSizeY-1) ); - pContentDev->DrawLine( Point(nPosX,nPosY), Point(nPosX+nSizeX-1,nPosY) ); - pContentDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() ); - pContentDev->DrawLine( Point(nPosX,nPosY+nSizeY-1), Point(nPosX+nSizeX-1,nPosY+nSizeY-1) ); - pContentDev->DrawLine( Point(nPosX+nSizeX-1,nPosY), Point(nPosX+nSizeX-1,nPosY+nSizeY-1) ); - pContentDev->SetLineColor( COL_BLACK ); + String aStr; + pDoc->GetString(nCol, nRow, nTab, aStr); + aDPFieldBtn.setText(aStr); + aDPFieldBtn.setBoundingBox(Point(nPosX,nPosY), Size(nSizeX-1, nSizeY-1)); + aDPFieldBtn.setDrawPopupButton(pInfo->bPopupButton); + aDPFieldBtn.setHasHiddenMember(pInfo->bFilterActive); + aDPFieldBtn.draw(); } } } diff --git a/sc/util/makefile.mk b/sc/util/makefile.mk index fe2bf6bc636d..0a47fee22e1a 100644 --- a/sc/util/makefile.mk +++ b/sc/util/makefile.mk @@ -58,6 +58,7 @@ RESLIB1LIST=\ $(SRS)$/formdlgs.srs \ $(SRS)$/pagedlg.srs \ $(SRS)$/navipi.srs \ + $(SRS)$/cctrl.srs \ $(SOLARCOMMONRESDIR)$/sfx.srs RESLIB1NAME=sc -- cgit From f926cbe9c3ddd0524f10c43978c719bf1e5870e4 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Mon, 13 Jul 2009 14:12:14 +0000 Subject: #i103512# fixed a crasher bug. --- sc/inc/dpoutputgeometry.hxx | 4 +++- sc/source/core/data/dpoutputgeometry.cxx | 39 ++++++++++++++++++-------------- sc/source/filter/excel/xipivot.cxx | 38 +++++++++++++++++++++---------- 3 files changed, 51 insertions(+), 30 deletions(-) (limited to 'sc') diff --git a/sc/inc/dpoutputgeometry.hxx b/sc/inc/dpoutputgeometry.hxx index dcf98f8f4ade..8183d94e2305 100644 --- a/sc/inc/dpoutputgeometry.hxx +++ b/sc/inc/dpoutputgeometry.hxx @@ -57,6 +57,8 @@ public: void getRowFieldPositions(::std::vector& rAddrs) const; void getPageFieldPositions(::std::vector& rAddrs) const; + SCROW getRowFieldHeaderRow() const; + FieldType getFieldButtonType(const ScAddress& rPos) const; private: @@ -64,7 +66,7 @@ private: private: ScRange maOutRange; - sal_uInt32 mnRowFields; + sal_uInt32 mnRowFields; /// number of row fields (data layout field NOT included!) sal_uInt32 mnColumnFields; sal_uInt32 mnPageFields; sal_uInt32 mnDataFields; diff --git a/sc/source/core/data/dpoutputgeometry.cxx b/sc/source/core/data/dpoutputgeometry.cxx index 1b8fc0b8435f..86b7d8f0bd15 100644 --- a/sc/source/core/data/dpoutputgeometry.cxx +++ b/sc/source/core/data/dpoutputgeometry.cxx @@ -117,23 +117,7 @@ void ScDPOutputGeometry::getRowFieldPositions(vector& rAddrs) const return; } - SCROW nCurRow = maOutRange.aStart.Row(); - - if (mnPageFields) - { - SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter; - SCROW nRowEnd = nRowStart + static_cast(mnPageFields-1); - nCurRow = nRowEnd + 2; - } - else if (mbShowFilter) - nCurRow += 2; - - if (mnColumnFields) - nCurRow += static_cast(mnColumnFields); - else - ++nCurRow; - - SCROW nRow = nCurRow; + SCROW nRow = getRowFieldHeaderRow(); SCTAB nTab = maOutRange.aStart.Tab(); SCCOL nColStart = maOutRange.aStart.Col(); SCCOL nColEnd = nColStart + static_cast(mnRowFields-1); @@ -163,6 +147,27 @@ void ScDPOutputGeometry::getPageFieldPositions(vector& rAddrs) const rAddrs.swap(aAddrs); } +SCROW ScDPOutputGeometry::getRowFieldHeaderRow() const +{ + SCROW nCurRow = maOutRange.aStart.Row(); + + if (mnPageFields) + { + SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter; + SCROW nRowEnd = nRowStart + static_cast(mnPageFields-1); + nCurRow = nRowEnd + 2; + } + else if (mbShowFilter) + nCurRow += 2; + + if (mnColumnFields) + nCurRow += static_cast(mnColumnFields); + else if (mnRowFields) + ++nCurRow; + + return nCurRow; +} + ScDPOutputGeometry::FieldType ScDPOutputGeometry::getFieldButtonType(const ScAddress& rPos) const { // We will ignore the table position for now. diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index 7ec0e5d2a694..fdc7246151ca 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -1486,21 +1486,35 @@ void XclImpPivotTable::ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveD vector aRowBtns; aGeometry.getRowFieldPositions(aRowBtns); - itr = aRowBtns.begin(); - itrEnd = aRowBtns.end(); - for (; itr != itrEnd; ++itr) + if (aRowBtns.empty()) { - sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP; - String aName; - rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName); - if (rSaveData.HasInvisibleMember(aName)) - nMFlag |= SC_MF_HIDDEN_MEMBER; - rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag); + if (bDataLayout) + { + // No row fields, but the data layout button exists. + SCROW nRow = aGeometry.getRowFieldHeaderRow(); + SCCOL nCol = rOutRange.aStart.Col(); + SCTAB nTab = rOutRange.aStart.Tab(); + rDoc.ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON); + } } - if (bDataLayout) + else { - --itr; // move back to the last row field position. - rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), SC_MF_BUTTON); + itr = aRowBtns.begin(); + itrEnd = aRowBtns.end(); + for (; itr != itrEnd; ++itr) + { + sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP; + String aName; + rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName); + if (rSaveData.HasInvisibleMember(aName)) + nMFlag |= SC_MF_HIDDEN_MEMBER; + rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag); + } + if (bDataLayout) + { + --itr; // move back to the last row field position. + rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), SC_MF_BUTTON); + } } } -- cgit From 34310d90da930c12be486d88cc3a478fa650ba57 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 30 Jul 2009 00:40:07 +0000 Subject: Draw borders around the list member box. --- sc/source/ui/cctrl/dpcontrol.cxx | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index d6aa21ab79bb..b483f2bde957 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -927,9 +927,11 @@ void ScDPFieldPopupWindow::Paint(const Rectangle& rRect) const StyleSettings& rStyle = GetSettings().GetStyleSettings(); Color aMemberBackColor = rStyle.GetFieldColor(); + Color aBorderColor = rStyle.GetShadowColor(); // Member list box background SetFillColor(aMemberBackColor); + SetLineColor(aBorderColor); Point aPos; Size aSize; getSectionPosSize(aPos, aSize, LISTBOX_AREA); -- cgit From e55664992c9182d89988ca1253693c012c806930 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 30 Jul 2009 03:18:29 +0000 Subject: Ctrl-D to launch the dp field popup window, the same way it launches the page field window. --- sc/source/ui/inc/gridwin.hxx | 8 +++++--- sc/source/ui/view/gridwin.cxx | 18 +++++++++++++++++- sc/source/ui/view/gridwin2.cxx | 37 +++++++++++++++++++++++++++++-------- sc/source/ui/view/tabview.cxx | 30 +++++++++++++++++++++--------- 4 files changed, 72 insertions(+), 21 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index 32ecaf26cc56..c5908d380a45 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -37,7 +37,7 @@ #include "viewdata.hxx" #include "cbutton.hxx" #include - +#include #include #include @@ -380,9 +380,11 @@ public: void DoAutoFilterMenue( SCCOL nCol, SCROW nRow, BOOL bDataSelect ); void DoScenarioMenue( const ScRange& rScenRange ); - void DoPageFieldMenue( SCCOL nCol, SCROW nRow ); - BOOL HasPageFieldData( SCCOL nCol, SCROW nRow ) const; + void LaunchPageFieldMenu( SCCOL nCol, SCROW nRow ); + void LaunchDPFieldMenu( SCCOL nCol, SCROW nRow ); + + ::com::sun::star::sheet::DataPilotFieldOrientation GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const; void DrawButtons( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScTableInfo& rTabInfo, OutputDevice* pContentDev ); diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 8949d2bd29a9..bc175d7b65d0 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -513,7 +513,7 @@ void ScGridWindow::ExecPageFieldSelect( SCCOL nCol, SCROW nRow, BOOL bHasSelecti } } -void ScGridWindow::DoPageFieldMenue( SCCOL nCol, SCROW nRow ) +void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow ) { //! merge position/size handling with DoAutoFilterMenue @@ -664,6 +664,22 @@ void ScGridWindow::DoPageFieldMenue( SCCOL nCol, SCROW nRow ) CaptureMouse(); } +void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow ) +{ + SCTAB nTab = pViewData->GetTabNo(); + ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab); + if (!pDPObj) + return; + + // Get the geometry of the cell. + Point aSrcPos = pViewData->GetScrPos(nCol, nRow, eWhich); + long nSizeX, nSizeY; + pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY); + Size aSrcSize(nSizeX-1, nSizeY-1); + + DPLaunchFieldPopupMenu(OutputToScreenPixel(aSrcPos), aSrcSize, ScAddress(nCol, nRow, nTab), pDPObj); +} + void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange ) { delete pFilterBox; diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index 1cfb5bdf71c0..a0791391e9d3 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -67,6 +67,7 @@ #include using namespace com::sun::star; +using ::com::sun::star::sheet::DataPilotFieldOrientation; using ::std::vector; using ::std::auto_ptr; using ::std::hash_map; @@ -77,33 +78,53 @@ using ::rtl::OUStringHash; // ----------------------------------------------------------------------- -BOOL ScGridWindow::HasPageFieldData( SCCOL nCol, SCROW nRow ) const +DataPilotFieldOrientation ScGridWindow::GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const { + using namespace ::com::sun::star::sheet; + ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab); - if ( pDPObj && nCol > 0 ) + if (!pDPObj) + return DataPilotFieldOrientation_HIDDEN; + + USHORT nOrient = DataPilotFieldOrientation_HIDDEN; + + // Check for page field first. + if (nCol > 0) { // look for the dimension header left of the drop-down arrow - USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN; long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient ); - if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE ) + if ( nField >= 0 && nOrient == DataPilotFieldOrientation_PAGE ) { BOOL bIsDataLayout = FALSE; String aFieldName = pDPObj->GetDimName( nField, bIsDataLayout ); if ( aFieldName.Len() && !bIsDataLayout ) - return TRUE; + return DataPilotFieldOrientation_PAGE; } } - return FALSE; + + nOrient = sheet::DataPilotFieldOrientation_HIDDEN; + + // Now, check for row/column field. + long nField = pDPObj->GetHeaderDim(ScAddress(nCol, nRow, nTab), nOrient); + if (nField >= 0 && (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW) ) + { + BOOL bIsDataLayout = FALSE; + String aFieldName = pDPObj->GetDimName(nField, bIsDataLayout); + if (aFieldName.Len() && !bIsDataLayout) + return static_cast(nOrient); + } + + return DataPilotFieldOrientation_HIDDEN; } // private method for mouse button handling BOOL ScGridWindow::DoPageFieldSelection( SCCOL nCol, SCROW nRow ) { - if ( HasPageFieldData( nCol, nRow ) ) + if (GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE) { - DoPageFieldMenue( nCol, nRow ); + LaunchPageFieldMenu( nCol, nRow ); return TRUE; } return FALSE; diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index c51c81c36dd8..4590f9988d69 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -200,6 +200,8 @@ #include "AccessibilityHints.hxx" #include "appoptio.hxx" +#include + #include #include @@ -212,6 +214,8 @@ // fuer Rad-Maus #define SC_DELTA_ZOOM 10 +using namespace ::com::sun::star; + // STATIC DATA ----------------------------------------------------------- @@ -2477,7 +2481,7 @@ sal_Bool ScTabView::HasPageFieldDataAtCursor() const SCCOL nCol = aViewData.GetCurX(); SCROW nRow = aViewData.GetCurY(); if (pWin) - return pWin->HasPageFieldData( nCol, nRow ); + return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE; return sal_False; } @@ -2487,15 +2491,23 @@ void ScTabView::StartDataSelect() ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()]; SCCOL nCol = aViewData.GetCurX(); SCROW nRow = aViewData.GetCurY(); - if (pWin) - { - // #i36598# If the cursor is on a page field's data cell, - // no meaningful input is possible anyway, so this function - // can be used to select a page field entry. - if ( pWin->HasPageFieldData( nCol, nRow ) ) - pWin->DoPageFieldMenue( nCol, nRow ); - else + if (!pWin) + return; + + switch (pWin->GetDPFieldOrientation(nCol, nRow)) + { + case sheet::DataPilotFieldOrientation_PAGE: + // #i36598# If the cursor is on a page field's data cell, + // no meaningful input is possible anyway, so this function + // can be used to select a page field entry. + pWin->LaunchPageFieldMenu( nCol, nRow ); + break; + case sheet::DataPilotFieldOrientation_COLUMN: + case sheet::DataPilotFieldOrientation_ROW: + pWin->LaunchDPFieldMenu( nCol, nRow ); + break; + default: pWin->DoAutoFilterMenue( nCol, nRow, TRUE ); } } -- cgit From 58a98fbb38dc78eba9768cebfc1e6215fbe97306 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 30 Jul 2009 21:07:52 +0000 Subject: Used SvxCheckListBox to implement the check list box instead of rolling my own. --- sc/source/ui/cctrl/dpcontrol.cxx | 130 +++++++++------------------------------ sc/source/ui/inc/dpcontrol.hxx | 23 ++----- 2 files changed, 32 insertions(+), 121 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index b483f2bde957..185671b3af97 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -724,17 +724,7 @@ void ScDPFieldPopupWindow::CancelButton::Click() ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : ScMenuFloatingWindow(pParent), - maCheck0(this, 0), - maCheck1(this, 0), - maCheck2(this, 0), - maCheck3(this, 0), - maCheck4(this, 0), - maCheck5(this, 0), - maCheck6(this, 0), - maCheck7(this, 0), - maCheck8(this, 0), - maCheck9(this, 0), - maScrollBar(this, WB_VERT), + maChecks(this, 0), maBtnOk(this), maBtnCancel(this), mpExtendedData(NULL), @@ -747,29 +737,6 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : SetOutputSizePixel(aSize); Size aOutSize = GetOutputSizePixel(); - mpCheckPtr.reserve(10); - mpCheckPtr.push_back(&maCheck0); - mpCheckPtr.push_back(&maCheck1); - mpCheckPtr.push_back(&maCheck2); - mpCheckPtr.push_back(&maCheck3); - mpCheckPtr.push_back(&maCheck4); - mpCheckPtr.push_back(&maCheck5); - mpCheckPtr.push_back(&maCheck6); - mpCheckPtr.push_back(&maCheck7); - mpCheckPtr.push_back(&maCheck8); - mpCheckPtr.push_back(&maCheck9); - - getSectionPosSize(aPos, aSize, FIRST_LISTITEM); - for (vector::iterator itr = mpCheckPtr.begin(), itrEnd = mpCheckPtr.end(); - itr != itrEnd; ++itr) - { - CheckBox* p = *itr; - p->SetPosSizePixel(aPos, aSize); - p->SetFont(getLabelFont()); - p->SetClickHdl( LINK(this, ScDPFieldPopupWindow, CheckBoxHdl) ); - aPos.Y() += aSize.Height() + 1; - } - getSectionPosSize(aPos, aSize, BTN_OK); maBtnOk.SetPosSizePixel(aPos, aSize); maBtnOk.SetFont(getLabelFont()); @@ -781,13 +748,10 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : maBtnCancel.SetFont(getLabelFont()); maBtnCancel.Show(); - getSectionPosSize(aPos, aSize, SCROLL_BAR_V); - maScrollBar.SetPosSizePixel(aPos, aSize); - maScrollBar.SetPageSize(mpCheckPtr.size()); - maScrollBar.SetVisibleSize(mpCheckPtr.size()); - maScrollBar.SetLineSize(1); - maScrollBar.SetScrollHdl( LINK(this, ScDPFieldPopupWindow, ScrollHdl) ); - maScrollBar.EnableDrag(true); + getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER); + maChecks.SetPosSizePixel(aPos, aSize); + maChecks.SetFont(getLabelFont()); + maChecks.Show(); } ScDPFieldPopupWindow::~ScDPFieldPopupWindow() @@ -802,6 +766,7 @@ vector& ScDPFieldPopupWindow::getMembers() void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const { const sal_uInt16 nListBoxMargin = 5; + const sal_uInt16 nListBoxInnerPadding = 5; const sal_uInt16 nTopMargin = 5; const sal_uInt16 nMenuHeight = 60; const sal_uInt16 nBottomBtnAreaHeight = 50; @@ -822,7 +787,7 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy rSize = aWndSize; } break; - case LISTBOX_AREA: + case LISTBOX_AREA_OUTER: { rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin); rSize = Size( @@ -830,6 +795,15 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy aWndSize.Height() - nTopMargin - nMenuHeight - nMenuListMargin - nBottomBtnAreaHeight); } break; + case LISTBOX_AREA_INNER: + { + rPos = Point(nListBoxMargin + nListBoxInnerPadding, + nTopMargin + nMenuHeight + nMenuListMargin + nListBoxInnerPadding); + rSize = Size( + aWndSize.Width() - nListBoxMargin*2 - nListBoxInnerPadding*2, + aWndSize.Height() - nTopMargin - nMenuHeight - nMenuListMargin - nBottomBtnAreaHeight - nListBoxInnerPadding*2); + } + break; case FIRST_LISTITEM: { rPos = Point(nListBoxMargin + nInnerItemMargin, @@ -869,49 +843,12 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy } } -void ScDPFieldPopupWindow::resetDisplayedItems() -{ - long nScrollPos = maScrollBar.GetThumbPos(); - if (nScrollPos < 0) - return; - - mnScrollPos = static_cast(nScrollPos); - size_t nCheckCount = mpCheckPtr.size(); - for (size_t i = 0; i < nCheckCount; ++i) - { - CheckBox* p = mpCheckPtr[i]; - p->SetText(maMembers[i+mnScrollPos].maName); - TriState nNewState = maMembers[i+mnScrollPos].mbVisible ? STATE_CHECK : STATE_NOCHECK; - p->SetState(nNewState); - } -} - -IMPL_LINK( ScDPFieldPopupWindow, CheckBoxHdl, CheckBox*, pCheck ) -{ - vector::const_iterator itr, itrBeg = mpCheckPtr.begin(), itrEnd = mpCheckPtr.end(); - for (itr = itrBeg; itr != itrEnd; ++itr) - { - if (*itr == pCheck) - { - size_t nIndex = ::std::distance(itrBeg, itr); - maMembers[nIndex+mnScrollPos].mbVisible = !maMembers[nIndex+mnScrollPos].mbVisible; - } - } - return 0; -} - IMPL_LINK( ScDPFieldPopupWindow, OKButtonHdl, OKButton*, EMPTYARG ) { close(true); return 0; } -IMPL_LINK( ScDPFieldPopupWindow, ScrollHdl, ScrollBar*, EMPTYARG ) -{ - resetDisplayedItems(); - return 0; -} - void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt) { ScMenuFloatingWindow::MouseMove(rMEvt); @@ -929,12 +866,13 @@ void ScDPFieldPopupWindow::Paint(const Rectangle& rRect) Color aMemberBackColor = rStyle.GetFieldColor(); Color aBorderColor = rStyle.GetShadowColor(); + Point aPos; + Size aSize; + getSectionPosSize(aPos, aSize, LISTBOX_AREA_OUTER); + // Member list box background SetFillColor(aMemberBackColor); SetLineColor(aBorderColor); - Point aPos; - Size aSize; - getSectionPosSize(aPos, aSize, LISTBOX_AREA); DrawRect(Rectangle(aPos,aSize)); } @@ -954,25 +892,10 @@ void ScDPFieldPopupWindow::addMember(const OUString& rName, bool bVisible) void ScDPFieldPopupWindow::initMembers() { size_t nMemCount = maMembers.size(); - size_t nCheckCount = mpCheckPtr.size(); - bool bNeedsScroll = false; - if (nMemCount > nCheckCount) - { - nMemCount = nCheckCount; - bNeedsScroll = true; - } - for (size_t i = 0; i < nMemCount; ++i) { - CheckBox* p = mpCheckPtr[i]; - p->SetText(maMembers[i].maName); - p->Show(); - p->SetState(maMembers[i].mbVisible ? STATE_CHECK : STATE_NOCHECK); - } - if (bNeedsScroll) - { - maScrollBar.SetRange(Range(0, maMembers.size())); - maScrollBar.Show(); + maChecks.InsertEntry(maMembers[i].maName); + maChecks.CheckEntryPos(i, maMembers[i].mbVisible); } } @@ -980,9 +903,12 @@ void ScDPFieldPopupWindow::getResult(hash_map& rRe { typedef hash_map ResultMap; ResultMap aResult; - vector::const_iterator itr = maMembers.begin(), itrEnd = maMembers.end(); - for (; itr != itrEnd; ++itr) - aResult.insert(ResultMap::value_type(itr->maName, itr->mbVisible)); + size_t n = maMembers.size(); + for (size_t i = 0; i < n; ++i) + { + bool bState = maChecks.IsChecked(i); + aResult.insert(ResultMap::value_type(maMembers[i].maName, bState)); + } rResult.swap(aResult); } diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 5c1e7a59aad2..e360f4f5acf2 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -37,6 +37,7 @@ #include "vcl/button.hxx" #include "vcl/scrbar.hxx" #include "vcl/timer.hxx" +#include "svx/checklbx.hxx" #include #include @@ -245,7 +246,8 @@ private: enum SectionType { WHOLE, // entire window - LISTBOX_AREA, // box enclosing the check box items. + LISTBOX_AREA_OUTER, // box enclosing the check box items. + LISTBOX_AREA_INNER, // box enclosing the check box items. FIRST_LISTITEM, // first list item at the top BTN_OK, // OK button BTN_CANCEL, // Cancel button @@ -253,32 +255,15 @@ private: }; void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const; - void resetDisplayedItems(); - - DECL_LINK( CheckBoxHdl, CheckBox* ); DECL_LINK( OKButtonHdl, OKButton* ); DECL_LINK( ScrollHdl, ScrollBar* ); private: - - CheckBox maCheck0; - CheckBox maCheck1; - CheckBox maCheck2; - CheckBox maCheck3; - CheckBox maCheck4; - CheckBox maCheck5; - CheckBox maCheck6; - CheckBox maCheck7; - CheckBox maCheck8; - CheckBox maCheck9; - - ScrollBar maScrollBar; + SvxCheckListBox maChecks; OKButton maBtnOk; CancelButton maBtnCancel; - ::std::vector mpCheckPtr; - ::std::vector maMembers; ::std::auto_ptr mpExtendedData; ::std::auto_ptr mpOKAction; -- cgit From 4c1e7fbbd53c669ae6f274a24a7ac73c7107ceaf Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 30 Jul 2009 21:11:57 +0000 Subject: Removed unused code after the switch to SvxCheckListBox. --- sc/source/ui/cctrl/dpcontrol.cxx | 20 -------------------- sc/source/ui/inc/dpcontrol.hxx | 2 -- 2 files changed, 22 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 185671b3af97..945fd0b1e358 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -770,8 +770,6 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy const sal_uInt16 nTopMargin = 5; const sal_uInt16 nMenuHeight = 60; const sal_uInt16 nBottomBtnAreaHeight = 50; - const sal_uInt16 nInnerItemMargin = 5; - const sal_uInt16 nScrollBarWidth = 17; const sal_uInt16 nBtnWidth = 60; const sal_uInt16 nBtnHeight = getLabelFont().GetHeight()*2; const sal_uInt16 nBottomMargin = 10; @@ -804,15 +802,6 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy aWndSize.Height() - nTopMargin - nMenuHeight - nMenuListMargin - nBottomBtnAreaHeight - nListBoxInnerPadding*2); } break; - case FIRST_LISTITEM: - { - rPos = Point(nListBoxMargin + nInnerItemMargin, - nTopMargin + nMenuHeight + nMenuListMargin + nInnerItemMargin); - rSize = Size( - aWndSize.Width() - nListBoxMargin*2 - nInnerItemMargin - nScrollBarWidth - 10, - 17); - } - break; case BTN_OK: { long x = (aWndSize.Width() - nBtnWidth*2)/3; @@ -829,15 +818,6 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy rSize = Size(nBtnWidth, nBtnHeight); } break; - case SCROLL_BAR_V: - { - long x = aWndSize.Width() - nListBoxMargin - nInnerItemMargin - nScrollBarWidth; - long y = nTopMargin + nMenuHeight + nMenuListMargin + nInnerItemMargin; - rPos = Point(x, y); - long h = aWndSize.Height() - nTopMargin - nMenuHeight - nMenuListMargin - nBottomBtnAreaHeight - nInnerItemMargin*2; - rSize = Size(nScrollBarWidth, h); - } - break; default: ; } diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index e360f4f5acf2..a79373579ff1 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -248,10 +248,8 @@ private: WHOLE, // entire window LISTBOX_AREA_OUTER, // box enclosing the check box items. LISTBOX_AREA_INNER, // box enclosing the check box items. - FIRST_LISTITEM, // first list item at the top BTN_OK, // OK button BTN_CANCEL, // Cancel button - SCROLL_BAR_V, // vertical scroll bar along the right edge of the list box. }; void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const; -- cgit From e5fb7fa24c796e7e608e6aa392ef8fb1900a4ee7 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 30 Jul 2009 23:10:58 +0000 Subject: removed unused method. --- sc/source/ui/cctrl/dpcontrol.cxx | 5 ----- sc/source/ui/inc/dpcontrol.hxx | 2 -- 2 files changed, 7 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 945fd0b1e358..9365a923dc44 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -758,11 +758,6 @@ ScDPFieldPopupWindow::~ScDPFieldPopupWindow() { } -vector& ScDPFieldPopupWindow::getMembers() -{ - return maMembers; -} - void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const { const sal_uInt16 nListBoxMargin = 5; diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index a79373579ff1..03064a835d4a 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -242,8 +242,6 @@ private: ScDPFieldPopupWindow* mpParent; }; - ::std::vector& getMembers(); - enum SectionType { WHOLE, // entire window LISTBOX_AREA_OUTER, // box enclosing the check box items. -- cgit From 69e8adefda15685dc09b7af00fd6743c1937c4c7 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 31 Jul 2009 02:57:58 +0000 Subject: Implemented "toggle all" check box per IBM's spec. --- sc/source/ui/cctrl/dpcontrol.cxx | 138 +++++++++++++++++++++++++++++++++++---- sc/source/ui/cctrl/dpcontrol.src | 5 ++ sc/source/ui/inc/dpcontrol.hrc | 1 + sc/source/ui/inc/dpcontrol.hxx | 17 +++-- 4 files changed, 142 insertions(+), 19 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 9365a923dc44..18cc9089e108 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -34,11 +34,13 @@ // INCLUDE --------------------------------------------------------------- #include "dpcontrol.hxx" +#include "dpcontrol.hrc" #include "vcl/outdev.hxx" #include "vcl/settings.hxx" #include "vcl/wintypes.hxx" #include "vcl/decoview.hxx" +#include "strload.hxx" #define MENU_NOT_SELECTED 999 @@ -725,12 +727,15 @@ void ScDPFieldPopupWindow::CancelButton::Click() ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : ScMenuFloatingWindow(pParent), maChecks(this, 0), + maChkToggleAll(this, 0), maBtnOk(this), maBtnCancel(this), mpExtendedData(NULL), mpOKAction(NULL), - mnScrollPos(0) + mePrevToggleAllState(STATE_DONTKNOW) { + const StyleSettings& rStyle = GetSettings().GetStyleSettings(); + Point aPos; Size aSize; getSectionPosSize(aPos, aSize, WHOLE); @@ -751,7 +756,16 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER); maChecks.SetPosSizePixel(aPos, aSize); maChecks.SetFont(getLabelFont()); + maChecks.SetCheckButtonHdl( LINK(this, ScDPFieldPopupWindow, CheckHdl) ); maChecks.Show(); + + getSectionPosSize(aPos, aSize, CHECK_TOGGLE_ALL); + maChkToggleAll.SetPosSizePixel(aPos, aSize); + maChkToggleAll.SetFont(getLabelFont()); + maChkToggleAll.SetText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_TOGGLE_ALL).GetString()); + maChkToggleAll.SetControlBackground(rStyle.GetMenuColor()); + maChkToggleAll.SetClickHdl( LINK(this, ScDPFieldPopupWindow, TriStateHdl) ); + maChkToggleAll.Show(); } ScDPFieldPopupWindow::~ScDPFieldPopupWindow() @@ -760,18 +774,28 @@ ScDPFieldPopupWindow::~ScDPFieldPopupWindow() void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const { - const sal_uInt16 nListBoxMargin = 5; + // constant parameters. + const sal_uInt16 nListBoxMargin = 5; // horizontal distance from the side of the dialog to the listbox border. const sal_uInt16 nListBoxInnerPadding = 5; const sal_uInt16 nTopMargin = 5; const sal_uInt16 nMenuHeight = 60; - const sal_uInt16 nBottomBtnAreaHeight = 50; + const sal_uInt16 nSingleItemBtnAreaHeight = 30; // height of the middle area below the list box where the single-action buttons are. + const sal_uInt16 nBottomBtnAreaHeight = 50; // height of the bottom area where the OK and Cancel buttons are. const sal_uInt16 nBtnWidth = 60; - const sal_uInt16 nBtnHeight = getLabelFont().GetHeight()*2; + const sal_uInt16 nLabelHeight = getLabelFont().GetHeight(); + const sal_uInt16 nBtnHeight = nLabelHeight*2; const sal_uInt16 nBottomMargin = 10; const sal_uInt16 nMenuListMargin = 20; Size aWndSize = Size(160, 330); + // parameters calculated from constants. + const sal_uInt16 nListBoxWidth = aWndSize.Width() - nListBoxMargin*2; + const sal_uInt16 nListBoxHeight = aWndSize.Height() - nTopMargin - nMenuHeight - + nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight; + + const sal_uInt16 nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1; + switch (eType) { case WHOLE: @@ -783,18 +807,33 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy case LISTBOX_AREA_OUTER: { rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin); - rSize = Size( - aWndSize.Width() - nListBoxMargin*2, - aWndSize.Height() - nTopMargin - nMenuHeight - nMenuListMargin - nBottomBtnAreaHeight); + rSize = Size(nListBoxWidth, nListBoxHeight); } break; case LISTBOX_AREA_INNER: { - rPos = Point(nListBoxMargin + nListBoxInnerPadding, - nTopMargin + nMenuHeight + nMenuListMargin + nListBoxInnerPadding); - rSize = Size( - aWndSize.Width() - nListBoxMargin*2 - nListBoxInnerPadding*2, - aWndSize.Height() - nTopMargin - nMenuHeight - nMenuListMargin - nBottomBtnAreaHeight - nListBoxInnerPadding*2); + rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin); + rPos.X() += nListBoxInnerPadding; + rPos.Y() += nListBoxInnerPadding; + + rSize = Size(nListBoxWidth, nListBoxHeight); + rSize.Width() -= nListBoxInnerPadding*2; + rSize.Height() -= nListBoxInnerPadding*2; + } + break; + case SINGLE_BTN_AREA: + { + rPos = Point(nListBoxMargin, nSingleBtnAreaY); + rSize = Size(nListBoxWidth, nSingleItemBtnAreaHeight); + } + break; + case CHECK_TOGGLE_ALL: + { + long h = nLabelHeight*3/2; // check box height is heuristically 150% of the text height. + rPos = Point(nListBoxMargin, nSingleBtnAreaY); + rPos.X() += 5; + rPos.Y() += (nSingleItemBtnAreaHeight - h)/2; + rSize = Size(70, h); } break; case BTN_OK: @@ -818,12 +857,58 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy } } +void ScDPFieldPopupWindow::setAllMemberState(bool bSet) +{ + size_t n = maMembers.size(); + for (size_t i = 0; i < n; ++i) + maChecks.CheckEntryPos(i, bSet); +} + IMPL_LINK( ScDPFieldPopupWindow, OKButtonHdl, OKButton*, EMPTYARG ) { close(true); return 0; } +IMPL_LINK( ScDPFieldPopupWindow, TriStateHdl, TriStateBox*, EMPTYARG ) +{ + switch (mePrevToggleAllState) + { + case STATE_NOCHECK: + maChkToggleAll.SetState(STATE_CHECK); + setAllMemberState(true); + break; + case STATE_CHECK: + maChkToggleAll.SetState(STATE_NOCHECK); + setAllMemberState(false); + break; + case STATE_DONTKNOW: + default: + maChkToggleAll.SetState(STATE_CHECK); + setAllMemberState(true); + break; + } + + mePrevToggleAllState = maChkToggleAll.GetState(); + return 0; +} + +IMPL_LINK( ScDPFieldPopupWindow, CheckHdl, SvTreeListBox*, EMPTYARG ) +{ + size_t nNumChecked = maChecks.GetCheckedEntryCount(); + if (nNumChecked == maMembers.size()) + // all members visible + maChkToggleAll.SetState(STATE_CHECK); + else if (nNumChecked == 0) + // no members visible + maChkToggleAll.SetState(STATE_NOCHECK); + else + maChkToggleAll.SetState(STATE_DONTKNOW); + + mePrevToggleAllState = maChkToggleAll.GetState(); + return 0; +} + void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt) { ScMenuFloatingWindow::MouseMove(rMEvt); @@ -849,6 +934,11 @@ void ScDPFieldPopupWindow::Paint(const Rectangle& rRect) SetFillColor(aMemberBackColor); SetLineColor(aBorderColor); DrawRect(Rectangle(aPos,aSize)); + + // Single-action button box + getSectionPosSize(aPos, aSize, SINGLE_BTN_AREA); + SetFillColor(rStyle.GetMenuColor()); + DrawRect(Rectangle(aPos,aSize)); } void ScDPFieldPopupWindow::setMemberSize(size_t n) @@ -866,11 +956,31 @@ void ScDPFieldPopupWindow::addMember(const OUString& rName, bool bVisible) void ScDPFieldPopupWindow::initMembers() { - size_t nMemCount = maMembers.size(); - for (size_t i = 0; i < nMemCount; ++i) + size_t n = maMembers.size(); + size_t nVisMemCount = 0; + for (size_t i = 0; i < n; ++i) { maChecks.InsertEntry(maMembers[i].maName); maChecks.CheckEntryPos(i, maMembers[i].mbVisible); + if (maMembers[i].mbVisible) + ++nVisMemCount; + } + if (nVisMemCount == n) + { + // all members visible + maChkToggleAll.SetState(STATE_CHECK); + mePrevToggleAllState = STATE_CHECK; + } + else if (nVisMemCount == 0) + { + // no members visible + maChkToggleAll.SetState(STATE_NOCHECK); + mePrevToggleAllState = STATE_NOCHECK; + } + else + { + maChkToggleAll.SetState(STATE_DONTKNOW); + mePrevToggleAllState = STATE_DONTKNOW; } } diff --git a/sc/source/ui/cctrl/dpcontrol.src b/sc/source/ui/cctrl/dpcontrol.src index 5f7ab9a66a9f..4c1bda0b2724 100644 --- a/sc/source/ui/cctrl/dpcontrol.src +++ b/sc/source/ui/cctrl/dpcontrol.src @@ -46,4 +46,9 @@ Resource RID_POPUP_FILTER { Text [ en-US ] = "Custom Sort" ; }; + + String STR_BTN_TOGGLE_ALL + { + Text [ en-US ] = "All" ; + }; }; diff --git a/sc/source/ui/inc/dpcontrol.hrc b/sc/source/ui/inc/dpcontrol.hrc index 7ec03c5134ae..e792dc4a9ace 100644 --- a/sc/source/ui/inc/dpcontrol.hrc +++ b/sc/source/ui/inc/dpcontrol.hrc @@ -36,5 +36,6 @@ #define STR_MENU_SORT_ASC 1 #define STR_MENU_SORT_DESC 2 #define STR_MENU_SORT_CUSTOM 3 +#define STR_BTN_TOGGLE_ALL 4 #endif diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 03064a835d4a..0a97f7e1046a 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -243,20 +243,27 @@ private: }; enum SectionType { - WHOLE, // entire window + WHOLE, // entire window LISTBOX_AREA_OUTER, // box enclosing the check box items. LISTBOX_AREA_INNER, // box enclosing the check box items. - BTN_OK, // OK button - BTN_CANCEL, // Cancel button + SINGLE_BTN_AREA, // box enclosing the single-action buttons. + CHECK_TOGGLE_ALL, // check box for toggling all items. + BTN_OK, // OK button + BTN_CANCEL, // Cancel button }; void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const; + void setAllMemberState(bool bSet); + DECL_LINK( OKButtonHdl, OKButton* ); - DECL_LINK( ScrollHdl, ScrollBar* ); + DECL_LINK( TriStateHdl, TriStateBox* ); + DECL_LINK( CheckHdl, SvTreeListBox* ); private: SvxCheckListBox maChecks; + TriStateBox maChkToggleAll; + OKButton maBtnOk; CancelButton maBtnCancel; @@ -264,7 +271,7 @@ private: ::std::auto_ptr mpExtendedData; ::std::auto_ptr mpOKAction; - size_t mnScrollPos; + TriState mePrevToggleAllState; }; #endif -- cgit From 8dca6ccdde0d337c113217562c3a9f594ddbc155 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 31 Jul 2009 04:56:38 +0000 Subject: Implemented single-select buttons. It's fully functional. --- sc/inc/sc.hrc | 2 ++ sc/source/ui/cctrl/dpcontrol.cxx | 52 ++++++++++++++++++++++++++++++++++++---- sc/source/ui/cctrl/dpcontrol.src | 18 ++++++++++++++ sc/source/ui/inc/dpcontrol.hxx | 7 +++++- 4 files changed, 74 insertions(+), 5 deletions(-) (limited to 'sc') diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index 13d8481fce16..b005f7c61c1d 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -1444,6 +1444,8 @@ #define RID_IMG_H_DROP_URL (BMP_START + 5) #define RID_IMG_H_DROP_LINK (BMP_START + 6) #define RID_IMG_H_DROP_COPY (BMP_START + 7) +#define RID_IMG_SELECT_CURRENT (BMP_START + 8) +#define RID_IMG_UNSELECT_CURRENT (BMP_START + 9) #define RID_SCPTR_PIVOTCOL (BMP_START + 81) #define RID_SCPTR_PIVOTROW (BMP_START + 82) diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 18cc9089e108..848d0c60250c 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -728,6 +728,8 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : ScMenuFloatingWindow(pParent), maChecks(this, 0), maChkToggleAll(this, 0), + maBtnSelectSingle (this, 0), + maBtnUnselectSingle(this, 0), maBtnOk(this), maBtnCancel(this), mpExtendedData(NULL), @@ -745,7 +747,7 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : getSectionPosSize(aPos, aSize, BTN_OK); maBtnOk.SetPosSizePixel(aPos, aSize); maBtnOk.SetFont(getLabelFont()); - maBtnOk.SetClickHdl( LINK(this, ScDPFieldPopupWindow, OKButtonHdl) ); + maBtnOk.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) ); maBtnOk.Show(); getSectionPosSize(aPos, aSize, BTN_CANCEL); @@ -766,6 +768,18 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : maChkToggleAll.SetControlBackground(rStyle.GetMenuColor()); maChkToggleAll.SetClickHdl( LINK(this, ScDPFieldPopupWindow, TriStateHdl) ); maChkToggleAll.Show(); + + getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT); + maBtnSelectSingle.SetPosSizePixel(aPos, aSize); + maBtnSelectSingle.SetModeImage(Image(ScResId(RID_IMG_SELECT_CURRENT)), BMP_COLOR_NORMAL); + maBtnSelectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) ); + maBtnSelectSingle.Show(); + + getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT); + maBtnUnselectSingle.SetPosSizePixel(aPos, aSize); + maBtnUnselectSingle.SetModeImage(Image(ScResId(RID_IMG_UNSELECT_CURRENT)), BMP_COLOR_NORMAL); + maBtnUnselectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) ); + maBtnUnselectSingle.Show(); } ScDPFieldPopupWindow::~ScDPFieldPopupWindow() @@ -779,7 +793,7 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy const sal_uInt16 nListBoxInnerPadding = 5; const sal_uInt16 nTopMargin = 5; const sal_uInt16 nMenuHeight = 60; - const sal_uInt16 nSingleItemBtnAreaHeight = 30; // height of the middle area below the list box where the single-action buttons are. + const sal_uInt16 nSingleItemBtnAreaHeight = 32; // height of the middle area below the list box where the single-action buttons are. const sal_uInt16 nBottomBtnAreaHeight = 50; // height of the bottom area where the OK and Cancel buttons are. const sal_uInt16 nBtnWidth = 60; const sal_uInt16 nLabelHeight = getLabelFont().GetHeight(); @@ -836,6 +850,24 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy rSize = Size(70, h); } break; + case BTN_SINGLE_SELECT: + { + long h = 26; + rPos = Point(nListBoxMargin, nSingleBtnAreaY); + rPos.X() += 75; + rPos.Y() += (nSingleItemBtnAreaHeight - h)/2; + rSize = Size(h, h); + } + break; + case BTN_SINGLE_UNSELECT: + { + long h = 26; + rPos = Point(nListBoxMargin, nSingleBtnAreaY); + rPos.X() += 75 + h + 10; + rPos.Y() += (nSingleItemBtnAreaHeight - h)/2; + rSize = Size(h, h); + } + break; case BTN_OK: { long x = (aWndSize.Width() - nBtnWidth*2)/3; @@ -864,9 +896,21 @@ void ScDPFieldPopupWindow::setAllMemberState(bool bSet) maChecks.CheckEntryPos(i, bSet); } -IMPL_LINK( ScDPFieldPopupWindow, OKButtonHdl, OKButton*, EMPTYARG ) +void ScDPFieldPopupWindow::selectCurrentMemberOnly(bool bSet) +{ + setAllMemberState(!bSet); + sal_uInt16 nSelected = maChecks.GetSelectEntryPos(); + maChecks.CheckEntryPos(nSelected, bSet); +} + +IMPL_LINK( ScDPFieldPopupWindow, ButtonHdl, Button*, pBtn ) { - close(true); + if (pBtn == &maBtnOk) + close(true); + else if (pBtn == &maBtnSelectSingle) + selectCurrentMemberOnly(true); + else if (pBtn == &maBtnUnselectSingle) + selectCurrentMemberOnly(false); return 0; } diff --git a/sc/source/ui/cctrl/dpcontrol.src b/sc/source/ui/cctrl/dpcontrol.src index 4c1bda0b2724..31252a88b281 100644 --- a/sc/source/ui/cctrl/dpcontrol.src +++ b/sc/source/ui/cctrl/dpcontrol.src @@ -52,3 +52,21 @@ Resource RID_POPUP_FILTER Text [ en-US ] = "All" ; }; }; + +Image RID_IMG_SELECT_CURRENT +{ + ImageBitmap = Bitmap + { + File = "popup_select_current.png"; + }; + MaskColor = STD_MASKCOLOR; +}; + +Image RID_IMG_UNSELECT_CURRENT +{ + ImageBitmap = Bitmap + { + File = "popup_unselect_current.png"; + }; + MaskColor = STD_MASKCOLOR; +}; diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 0a97f7e1046a..5f990038a112 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -248,14 +248,17 @@ private: LISTBOX_AREA_INNER, // box enclosing the check box items. SINGLE_BTN_AREA, // box enclosing the single-action buttons. CHECK_TOGGLE_ALL, // check box for toggling all items. + BTN_SINGLE_SELECT, + BTN_SINGLE_UNSELECT, BTN_OK, // OK button BTN_CANCEL, // Cancel button }; void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const; void setAllMemberState(bool bSet); + void selectCurrentMemberOnly(bool bSet); - DECL_LINK( OKButtonHdl, OKButton* ); + DECL_LINK( ButtonHdl, Button* ); DECL_LINK( TriStateHdl, TriStateBox* ); DECL_LINK( CheckHdl, SvTreeListBox* ); @@ -263,6 +266,8 @@ private: SvxCheckListBox maChecks; TriStateBox maChkToggleAll; + ImageButton maBtnSelectSingle; + ImageButton maBtnUnselectSingle; OKButton maBtnOk; CancelButton maBtnCancel; -- cgit From 10607279f3091b644156ed82f651fc9d3ce8372d Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 31 Jul 2009 05:09:14 +0000 Subject: Quick help strings for the single-selection buttons per spec from IBM. --- sc/source/ui/cctrl/dpcontrol.cxx | 2 ++ sc/source/ui/cctrl/dpcontrol.src | 10 ++++++++++ sc/source/ui/inc/dpcontrol.hrc | 10 ++++++---- 3 files changed, 18 insertions(+), 4 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 848d0c60250c..bc36abb7d182 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -771,12 +771,14 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT); maBtnSelectSingle.SetPosSizePixel(aPos, aSize); + maBtnSelectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_SELECT_CURRENT).GetString()); maBtnSelectSingle.SetModeImage(Image(ScResId(RID_IMG_SELECT_CURRENT)), BMP_COLOR_NORMAL); maBtnSelectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) ); maBtnSelectSingle.Show(); getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT); maBtnUnselectSingle.SetPosSizePixel(aPos, aSize); + maBtnUnselectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_UNSELECT_CURRENT).GetString()); maBtnUnselectSingle.SetModeImage(Image(ScResId(RID_IMG_UNSELECT_CURRENT)), BMP_COLOR_NORMAL); maBtnUnselectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) ); maBtnUnselectSingle.Show(); diff --git a/sc/source/ui/cctrl/dpcontrol.src b/sc/source/ui/cctrl/dpcontrol.src index 31252a88b281..31cbb62085e5 100644 --- a/sc/source/ui/cctrl/dpcontrol.src +++ b/sc/source/ui/cctrl/dpcontrol.src @@ -51,6 +51,16 @@ Resource RID_POPUP_FILTER { Text [ en-US ] = "All" ; }; + + String STR_BTN_SELECT_CURRENT + { + Text [ en-US ] = "Show only the current item." ; + }; + + String STR_BTN_UNSELECT_CURRENT + { + Text [ en-US ] = "Hide only the current item." ; + }; }; Image RID_IMG_SELECT_CURRENT diff --git a/sc/source/ui/inc/dpcontrol.hrc b/sc/source/ui/inc/dpcontrol.hrc index e792dc4a9ace..2275b601c17a 100644 --- a/sc/source/ui/inc/dpcontrol.hrc +++ b/sc/source/ui/inc/dpcontrol.hrc @@ -33,9 +33,11 @@ #include -#define STR_MENU_SORT_ASC 1 -#define STR_MENU_SORT_DESC 2 -#define STR_MENU_SORT_CUSTOM 3 -#define STR_BTN_TOGGLE_ALL 4 +#define STR_MENU_SORT_ASC 1 +#define STR_MENU_SORT_DESC 2 +#define STR_MENU_SORT_CUSTOM 3 +#define STR_BTN_TOGGLE_ALL 4 +#define STR_BTN_SELECT_CURRENT 5 +#define STR_BTN_UNSELECT_CURRENT 6 #endif -- cgit From fef2f67ef7f3d49cc5b9bab8b2f21e2004cdfb16 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 31 Jul 2009 05:14:59 +0000 Subject: Don't forget to update the toggle-all check box after each single selection. --- sc/source/ui/cctrl/dpcontrol.cxx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index bc36abb7d182..2edfc2a91e05 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -910,9 +910,15 @@ IMPL_LINK( ScDPFieldPopupWindow, ButtonHdl, Button*, pBtn ) if (pBtn == &maBtnOk) close(true); else if (pBtn == &maBtnSelectSingle) + { selectCurrentMemberOnly(true); + CheckHdl(&maChecks); + } else if (pBtn == &maBtnUnselectSingle) + { selectCurrentMemberOnly(false); + CheckHdl(&maChecks); + } return 0; } @@ -939,8 +945,11 @@ IMPL_LINK( ScDPFieldPopupWindow, TriStateHdl, TriStateBox*, EMPTYARG ) return 0; } -IMPL_LINK( ScDPFieldPopupWindow, CheckHdl, SvTreeListBox*, EMPTYARG ) +IMPL_LINK( ScDPFieldPopupWindow, CheckHdl, SvTreeListBox*, pChecks ) { + if (pChecks != &maChecks) + return 0; + size_t nNumChecked = maChecks.GetCheckedEntryCount(); if (nNumChecked == maMembers.size()) // all members visible -- cgit From 140a7e79d697b679c5c2a3b5ffe00c91f8cb9585 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 31 Jul 2009 15:36:49 +0000 Subject: We append an extra title row only for xls import, not for ods import. --- sc/inc/dpoutputgeometry.hxx | 5 ++++- sc/source/core/data/dpoutputgeometry.cxx | 5 +++-- sc/source/filter/excel/xipivot.cxx | 2 +- sc/source/filter/xml/xmldpimp.cxx | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) (limited to 'sc') diff --git a/sc/inc/dpoutputgeometry.hxx b/sc/inc/dpoutputgeometry.hxx index 8183d94e2305..b665c9cc88b4 100644 --- a/sc/inc/dpoutputgeometry.hxx +++ b/sc/inc/dpoutputgeometry.hxx @@ -40,8 +40,9 @@ class SC_DLLPUBLIC ScDPOutputGeometry { public: enum FieldType { Column, Row, Page, Data, None }; + enum ImportType { ODF, XLS }; - ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter); + ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter, ImportType eImportType); ~ScDPOutputGeometry(); /** @@ -71,6 +72,8 @@ private: sal_uInt32 mnPageFields; sal_uInt32 mnDataFields; + ImportType meImportType; + bool mbShowFilter; }; diff --git a/sc/source/core/data/dpoutputgeometry.cxx b/sc/source/core/data/dpoutputgeometry.cxx index 86b7d8f0bd15..20c071976ebe 100644 --- a/sc/source/core/data/dpoutputgeometry.cxx +++ b/sc/source/core/data/dpoutputgeometry.cxx @@ -42,12 +42,13 @@ using ::std::vector; -ScDPOutputGeometry::ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter) : +ScDPOutputGeometry::ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter, ImportType eImportType) : maOutRange(rOutRange), mnRowFields(0), mnColumnFields(0), mnPageFields(0), mnDataFields(0), + meImportType(eImportType), mbShowFilter(bShowFilter) { } @@ -172,7 +173,7 @@ ScDPOutputGeometry::FieldType ScDPOutputGeometry::getFieldButtonType(const ScAdd { // We will ignore the table position for now. - bool bExtraTitleRow = (mnColumnFields == 0); + bool bExtraTitleRow = (mnColumnFields == 0 && meImportType == ScDPOutputGeometry::XLS); bool bDataLayout = mnDataFields > 1; SCROW nCurRow = maOutRange.aStart.Row(); diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index fdc7246151ca..24ebce414c6a 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -1443,7 +1443,7 @@ void XclImpPivotTable::ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveD { // Apply merge flags for varoius datapilot controls. - ScDPOutputGeometry aGeometry(rOutRange, false); + ScDPOutputGeometry aGeometry(rOutRange, false, ScDPOutputGeometry::XLS); aGeometry.setColumnFieldCount(maPTInfo.mnColFields); aGeometry.setPageFieldCount(maPTInfo.mnPageFields); aGeometry.setDataFieldCount(maPTInfo.mnDataFields); diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index 0a990416006e..572bcbb817e3 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -285,7 +285,7 @@ SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( USHORT nPref void ScXMLDataPilotTableContext::SetButtons() { - ScDPOutputGeometry aGeometry(aTargetRangeAddress, bShowFilter); + ScDPOutputGeometry aGeometry(aTargetRangeAddress, bShowFilter, ScDPOutputGeometry::ODF); aGeometry.setColumnFieldCount(mnColFieldCount); aGeometry.setRowFieldCount(mnRowFieldCount); aGeometry.setPageFieldCount(mnPageFieldCount); -- cgit From e4228cc6472975a438aaa428a3562bd727c4a83f Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 31 Jul 2009 18:40:28 +0000 Subject: Handle optional property values of DataPilotSource more gracefully. We need to allow the data provider to not support those optional properties. --- sc/inc/miscuno.hxx | 14 +++++ sc/source/core/data/dpsave.cxx | 112 +++++++++------------------------------- sc/source/ui/unoobj/miscuno.cxx | 17 ++++++ 3 files changed, 54 insertions(+), 89 deletions(-) (limited to 'sc') diff --git a/sc/inc/miscuno.hxx b/sc/inc/miscuno.hxx index 1486d3ce480b..7f6bd4774faf 100644 --- a/sc/inc/miscuno.hxx +++ b/sc/inc/miscuno.hxx @@ -291,6 +291,20 @@ public: static sal_Int32 GetInt32FromAny( const com::sun::star::uno::Any& aAny ); static sal_Int32 GetEnumFromAny( const com::sun::star::uno::Any& aAny ); static void SetBoolInAny( com::sun::star::uno::Any& rAny, sal_Bool bValue ); + + static void SetOptionalPropertyValue( + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rPropSet, + const sal_Char* pPropName, const ::com::sun::star::uno::Any& rVal ); + + template + static void SetOptionalPropertyValue( + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rPropSet, + const sal_Char* pPropName, const ValueType& rVal ) + { + ::com::sun::star::uno::Any any; + any <<= rVal; + SetOptionalPropertyValue(rPropSet, pPropName, any); + } }; diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx index cc564457761f..7ab7a13c7fc1 100644 --- a/sc/source/core/data/dpsave.cxx +++ b/sc/source/core/data/dpsave.cxx @@ -61,6 +61,8 @@ #include using namespace com::sun::star; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Any; using ::rtl::OUString; using ::rtl::OUStringHash; using ::std::hash_map; @@ -213,28 +215,10 @@ void ScDPSaveMember::WriteToSource( const uno::Reference& xMemb rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS), (BOOL)nShowDetailsMode ); if (mpLayoutName.get()) - { - try - { - uno::Any any; - any <<= rtl::OUString(*mpLayoutName); - xMembProp->setPropertyValue(rtl::OUString::createFromAscii(SC_UNO_LAYOUTNAME), any); - } - catch (uno::Exception&) - { - } - } + ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_LAYOUTNAME, *mpLayoutName); + if ( nPosition >= 0 ) - { - try - { - xMembProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_POSITION), uno::Any(nPosition) ); - } - catch ( uno::Exception& ) - { - // position is optional - exception must be ignored - } - } + ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, DP_PROP_POSITION, nPosition); } } @@ -604,28 +588,15 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference& xD aFilter = uno::Sequence( &aField, 1 ); } // else keep empty sequence - try - { - aAny <<= aFilter; - xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FILTER), aAny ); - if (mpLayoutName.get()) - { - aAny <<= *mpLayoutName; - xDimProp->setPropertyValue(rtl::OUString::createFromAscii(SC_UNO_LAYOUTNAME), aAny); - } - const OUString* pSubTotalName = GetSubtotalName(); - if (pSubTotalName) - { - // Custom subtotal name, with '?' being replaced by the visible field name later. - aAny <<= *pSubTotalName; - xDimProp->setPropertyValue(OUString::createFromAscii(SC_UNO_FIELD_SUBTOTALNAME), aAny); - } - } - catch ( beans::UnknownPropertyException& ) - { - // recent addition - allow source to not handle it (no error) - } + ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, DP_PROP_FILTER, aFilter); + if (mpLayoutName.get()) + ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_LAYOUTNAME, *mpLayoutName); + + const OUString* pSubTotalName = GetSubtotalName(); + if (pSubTotalName) + // Custom subtotal name, with '?' being replaced by the visible field name later. + ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_FIELD_SUBTOTALNAME, *pSubTotalName); } // Level loop outside of maMemberList loop @@ -684,41 +655,13 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference& xD rtl::OUString::createFromAscii(DP_PROP_SHOWEMPTY), (BOOL)nShowEmptyMode ); if ( pSortInfo ) - { - aAny <<= *pSortInfo; - try - { - xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_SORTING), aAny ); - } - catch ( beans::UnknownPropertyException& ) - { - // recent addition - allow source to not handle it (no error) - } - } + ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_SORTING, *pSortInfo); + if ( pAutoShowInfo ) - { - aAny <<= *pAutoShowInfo; - try - { - xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_AUTOSHOW), aAny ); - } - catch ( beans::UnknownPropertyException& ) - { - // recent addition - allow source to not handle it (no error) - } - } + ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_AUTOSHOW, *pAutoShowInfo); + if ( pLayoutInfo ) - { - aAny <<= *pLayoutInfo; - try - { - xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_LAYOUT), aAny ); - } - catch ( beans::UnknownPropertyException& ) - { - // recent addition - allow source to not handle it (no error) - } - } + ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_LAYOUT, *pLayoutInfo); // exceptions are caught at ScDPSaveData::WriteToSource } @@ -759,12 +702,7 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference& xD } if (xDimProp.is()) - { - uno::Any any; - any <<= bHasHiddenMember; - xDimProp->setPropertyValue( - OUString::createFromAscii(SC_UNO_HAS_HIDDEN_MEMBER), any); - } + ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_HAS_HIDDEN_MEMBER, bHasHiddenMember); } void ScDPSaveDimension::UpdateMemberVisibility(const hash_map& rData) @@ -1166,19 +1104,15 @@ void ScDPSaveData::WriteToSource( const uno::ReferencesetPropertyValue(OUString::createFromAscii(SC_UNO_GRANDTOTAL_NAME), any); - } } catch(uno::Exception&) { // no error } + + const OUString* pGrandTotalName = GetGrandTotalName(); + if (pGrandTotalName) + ScUnoHelpFunctions::SetOptionalPropertyValue(xSourceProp, SC_UNO_GRANDTOTAL_NAME, *pGrandTotalName); } // exceptions in the other calls are errors diff --git a/sc/source/ui/unoobj/miscuno.cxx b/sc/source/ui/unoobj/miscuno.cxx index 3d41da907016..090073e259ae 100644 --- a/sc/source/ui/unoobj/miscuno.cxx +++ b/sc/source/ui/unoobj/miscuno.cxx @@ -39,6 +39,9 @@ #include "unoguard.hxx" using namespace com::sun::star; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Any; +using ::rtl::OUString; //------------------------------------------------------------------------ @@ -180,6 +183,20 @@ void ScUnoHelpFunctions::SetBoolInAny( uno::Any& rAny, sal_Bool bValue ) rAny.setValue( &bValue, getBooleanCppuType() ); } +// static +void ScUnoHelpFunctions::SetOptionalPropertyValue( + Reference& rPropSet, const sal_Char* pPropName, const Any& rVal ) +{ + try + { + rPropSet->setPropertyValue(OUString::createFromAscii(pPropName), rVal); + } + catch (const beans::UnknownPropertyException&) + { + // ignored - not supported. + } +} + //------------------------------------------------------------------------ ScIndexEnumeration::ScIndexEnumeration(const uno::Reference& rInd, -- cgit From 05b32c409e8984e3e24ee2a20d4bc21683f0b600 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 31 Jul 2009 19:21:20 +0000 Subject: Draw black border around the popup arrow. It looks better this way. --- sc/source/ui/cctrl/dpcontrol.cxx | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 2edfc2a91e05..726c6dd660bd 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -144,16 +144,21 @@ void ScDPFieldButton::drawPopupButton() Size aSize; getPopupBoundingBox(aPos, aSize); + // outer black border + mpOutDev->SetLineColor(COL_BLACK); + mpOutDev->SetFillColor(); + mpOutDev->DrawRect(Rectangle(aPos, aSize)); + // border lines mpOutDev->SetLineColor(mpStyle->GetLightColor()); - mpOutDev->DrawLine(aPos, Point(aPos.X(), aPos.Y()+aSize.Height()-1)); - mpOutDev->DrawLine(aPos, Point(aPos.X()+aSize.Width()-1, aPos.Y())); + mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+1, aPos.Y()+aSize.Height()-2)); + mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+aSize.Width()-2, aPos.Y()+1)); mpOutDev->SetLineColor(mpStyle->GetShadowColor()); - mpOutDev->DrawLine(Point(aPos.X(), aPos.Y()+aSize.Height()-1), - Point(aPos.X()+aSize.Width()-1, aPos.Y()+aSize.Height()-1)); - mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-1, aPos.Y()), - Point(aPos.X()+aSize.Width()-1, aPos.Y()+aSize.Height()-1)); + mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+aSize.Height()-2), + Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2)); + mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-2, aPos.Y()+1), + Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2)); // the arrowhead Color aArrowColor = mbHasHiddenMember ? mpStyle->GetHighlightLinkColor() : mpStyle->GetButtonTextColor(); -- cgit From ba3f18f4ab3a93264fd67ce956dfad96e74249f5 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 31 Jul 2009 19:47:48 +0000 Subject: Draw the autofilter arrow button the same way as the field popup button. This will temporarily break autofilter's push animation and mouse pointer hit analysis. Also made the popup button a little wider. --- sc/source/ui/cctrl/dpcontrol.cxx | 71 ++++++++++++++++++++++------------------ sc/source/ui/inc/dpcontrol.hxx | 2 ++ sc/source/ui/view/gridwin4.cxx | 24 +++++++------- 3 files changed, 54 insertions(+), 43 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 726c6dd660bd..db05af97b8df 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -52,6 +52,7 @@ using ::std::hash_map; ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle) : mpOutDev(pOutDev), mpStyle(pStyle), + mbBaseButton(true), mbPopupButton(false), mbHasHiddenMember(false) { @@ -72,6 +73,11 @@ void ScDPFieldButton::setBoundingBox(const Point& rPos, const Size& rSize) maSize = rSize; } +void ScDPFieldButton::setDrawBaseButton(bool b) +{ + mbBaseButton = b; +} + void ScDPFieldButton::setDrawPopupButton(bool b) { mbPopupButton = b; @@ -86,33 +92,36 @@ void ScDPFieldButton::draw() { const long nMargin = 2; - // Background - Rectangle aRect(maPos, maSize); - mpOutDev->SetLineColor(mpStyle->GetFaceColor()); - mpOutDev->SetFillColor(mpStyle->GetFaceColor()); - mpOutDev->DrawRect(aRect); - - // Border lines - mpOutDev->SetLineColor(mpStyle->GetLightColor()); - mpOutDev->DrawLine(Point(maPos), Point(maPos.X(), maPos.Y()+maSize.Height()-1)); - mpOutDev->DrawLine(Point(maPos), Point(maPos.X()+maSize.Width()-1, maPos.Y())); - - mpOutDev->SetLineColor(mpStyle->GetShadowColor()); - mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1), - Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1)); - mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()), - Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1)); - - // Field name - Font aTextFont( mpStyle->GetLabelFont() ); - aTextFont.SetHeight(12); - mpOutDev->SetFont(aTextFont); - - Point aTextPos = maPos; - long nTHeight = mpOutDev->GetTextHeight(); - aTextPos.setX(maPos.getX() + nMargin); - aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2); - mpOutDev->DrawText(aTextPos, maText); + if (mbBaseButton) + { + // Background + Rectangle aRect(maPos, maSize); + mpOutDev->SetLineColor(mpStyle->GetFaceColor()); + mpOutDev->SetFillColor(mpStyle->GetFaceColor()); + mpOutDev->DrawRect(aRect); + + // Border lines + mpOutDev->SetLineColor(mpStyle->GetLightColor()); + mpOutDev->DrawLine(Point(maPos), Point(maPos.X(), maPos.Y()+maSize.Height()-1)); + mpOutDev->DrawLine(Point(maPos), Point(maPos.X()+maSize.Width()-1, maPos.Y())); + + mpOutDev->SetLineColor(mpStyle->GetShadowColor()); + mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1), + Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1)); + mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()), + Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1)); + + // Field name + Font aTextFont( mpStyle->GetLabelFont() ); + aTextFont.SetHeight(12); + mpOutDev->SetFont(aTextFont); + + Point aTextPos = maPos; + long nTHeight = mpOutDev->GetTextHeight(); + aTextPos.setX(maPos.getX() + nMargin); + aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2); + mpOutDev->DrawText(aTextPos, maText); + } if (mbPopupButton) drawPopupButton(); @@ -122,8 +131,8 @@ void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const { long nW = maSize.getWidth()*0.5; long nH = maSize.getHeight(); - if (nW > 16) - nW = 16; + if (nW > 18) + nW = 18; if (nH > 18) nH = 18; @@ -144,9 +153,9 @@ void ScDPFieldButton::drawPopupButton() Size aSize; getPopupBoundingBox(aPos, aSize); - // outer black border + // Background & outer black border mpOutDev->SetLineColor(COL_BLACK); - mpOutDev->SetFillColor(); + mpOutDev->SetFillColor(mpStyle->GetFaceColor()); mpOutDev->DrawRect(Rectangle(aPos, aSize)); // border lines diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 5f990038a112..9bd78d8ab598 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -61,6 +61,7 @@ public: void setText(const ::rtl::OUString& rText); void setBoundingBox(const Point& rPos, const Size& rSize); + void setDrawBaseButton(bool b); void setDrawPopupButton(bool b); void setHasHiddenMember(bool b); void draw(); @@ -77,6 +78,7 @@ private: ::rtl::OUString maText; OutputDevice* mpOutDev; const StyleSettings* mpStyle; + bool mbBaseButton; bool mbPopupButton; bool mbHasHiddenMember; }; diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index e6466e7ba3b1..12e93f977945 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -1204,7 +1204,7 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2 { aComboButton.SetOutputDevice( pContentDev ); - ScDPFieldButton aDPFieldBtn(pContentDev, &GetSettings().GetStyleSettings()); + ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings()); SCCOL nCol; SCROW nRow; @@ -1287,14 +1287,13 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2 bool bArrowState = bSimpleQuery && bColumnFound; long nSizeX; long nSizeY; - pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); - aComboButton.SetOptSizePixel(); - DrawComboButton( pViewData->GetScrPos( nCol, nRow, eWhich ), - nSizeX, nSizeY, bArrowState ); + Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich ); - aComboButton.SetPosPixel( aOldPos ); // alten Zustand - aComboButton.SetSizePixel( aOldSize ); // fuer MouseUp/Down + aCellBtn.setBoundingBox(aScrPos, Size(nSizeX-1, nSizeY-1)); + aCellBtn.setDrawBaseButton(false); + aCellBtn.setDrawPopupButton(true); + aCellBtn.draw(); } } } @@ -1323,11 +1322,12 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2 String aStr; pDoc->GetString(nCol, nRow, nTab, aStr); - aDPFieldBtn.setText(aStr); - aDPFieldBtn.setBoundingBox(Point(nPosX,nPosY), Size(nSizeX-1, nSizeY-1)); - aDPFieldBtn.setDrawPopupButton(pInfo->bPopupButton); - aDPFieldBtn.setHasHiddenMember(pInfo->bFilterActive); - aDPFieldBtn.draw(); + aCellBtn.setText(aStr); + aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1)); + aCellBtn.setDrawBaseButton(true); + aCellBtn.setDrawPopupButton(pInfo->bPopupButton); + aCellBtn.setHasHiddenMember(pInfo->bFilterActive); + aCellBtn.draw(); } } } -- cgit From 3989ce308969f2eb5ae0e147518fb2a711868c65 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 31 Jul 2009 23:21:18 +0000 Subject: Extracted the autofilter hit handling code into its own method. --- sc/source/ui/inc/gridwin.hxx | 1 + sc/source/ui/view/gridwin.cxx | 46 +----------------------------------------- sc/source/ui/view/gridwin2.cxx | 39 +++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 45 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index c5908d380a45..e38c2a4f422c 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -236,6 +236,7 @@ private: BOOL TestMouse( const MouseEvent& rMEvt, BOOL bAction ); BOOL DoPageFieldSelection( SCCOL nCol, SCROW nRow ); + bool DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt ); void DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt ); #if OLD_PIVOT_IMPLEMENTATION void PivotMouseMove( const MouseEvent& rMEvt ); diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index bc175d7b65d0..79529194b668 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -1634,52 +1634,8 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt ) pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG ); if (pAttr->HasAutoFilter()) { - Point aScrPos = pViewData->GetScrPos(nPosX,nPosY,eWhich); - long nSizeX; - long nSizeY; - Point aDiffPix = aPos; - - aDiffPix -= aScrPos; - BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab ); - if ( bLayoutRTL ) - aDiffPix.X() = -aDiffPix.X(); - - pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY ); - - // Breite des Buttons ist nicht von der Zellhoehe abhaengig - Size aButSize = aComboButton.GetSizePixel(); - long nButWidth = Min( aButSize.Width(), nSizeX ); - long nButHeight = Min( aButSize.Height(), nSizeY ); - - if ( aDiffPix.X() >= nSizeX - nButWidth && - aDiffPix.Y() >= nSizeY - nButHeight ) - { - if ( DoPageFieldSelection( nPosX, nPosY ) ) - return; - - BOOL bFilterActive = IsAutoFilterActive( nPosX, nPosY, - pViewData->GetTabNo() ); - - aComboButton.SetOptSizePixel(); - DrawComboButton( aScrPos, nSizeX, nSizeY, bFilterActive, TRUE ); - -#if 0 - if ( bWasFilterBox - && (SCsCOL)nOldColFBox == nPosX - && (SCsROW)nOldRowFBox == nPosY ) - { - // Verhindern, dass an gleicher Stelle eine - // FilterBox geoeffnet wird, wenn diese gerade - // geloescht wurde - - nMouseStatus = SC_GM_FILTER; // fuer ButtonDraw im MouseButtonUp(); - return; - } -#endif - DoAutoFilterMenue( nPosX, nPosY, FALSE ); - + if (DoAutoFilterButton(nPosX, nPosY, rMEvt)) return; - } } if (pAttr->HasButton()) { diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index a0791391e9d3..8db035d6df55 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -130,6 +130,45 @@ BOOL ScGridWindow::DoPageFieldSelection( SCCOL nCol, SCROW nRow ) return FALSE; } +bool ScGridWindow::DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt ) +{ + ScDocument* pDoc = pViewData->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich); + Point aDiffPix = rMEvt.GetPosPixel(); + + aDiffPix -= aScrPos; + BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab ); + if ( bLayoutRTL ) + aDiffPix.X() = -aDiffPix.X(); + + long nSizeX, nSizeY; + pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); + + // Breite des Buttons ist nicht von der Zellhoehe abhaengig + Size aButSize = aComboButton.GetSizePixel(); + long nButWidth = Min( aButSize.Width(), nSizeX ); + long nButHeight = Min( aButSize.Height(), nSizeY ); + + if ( aDiffPix.X() >= nSizeX - nButWidth && + aDiffPix.Y() >= nSizeY - nButHeight ) + { + if ( DoPageFieldSelection( nCol, nRow ) ) + return true; + + BOOL bFilterActive = IsAutoFilterActive( nCol, nRow, + pViewData->GetTabNo() ); + + aComboButton.SetOptSizePixel(); + DrawComboButton( aScrPos, nSizeX, nSizeY, bFilterActive, TRUE ); + DoAutoFilterMenue(nCol, nRow, false); + + return true; + } + + return false; +} + void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt ) { ScDocument* pDoc = pViewData->GetDocument(); -- cgit From 41eedbe32033a7d11c1027a5561f46453324d105 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Sat, 1 Aug 2009 01:27:21 +0000 Subject: Button pressing animation for autofilter buttons. --- sc/source/ui/cctrl/dpcontrol.cxx | 46 +++++++++++++++++++++++++++++++--------- sc/source/ui/inc/dpcontrol.hxx | 2 ++ sc/source/ui/inc/gridwin.hxx | 2 ++ sc/source/ui/view/gridwin.cxx | 28 +++++++++++++++++------- sc/source/ui/view/gridwin2.cxx | 42 +++++++++++++++++++----------------- sc/source/ui/view/gridwin4.cxx | 1 + 6 files changed, 84 insertions(+), 37 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index db05af97b8df..2239a4c96a2c 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -54,7 +54,8 @@ ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pSt mpStyle(pStyle), mbBaseButton(true), mbPopupButton(false), - mbHasHiddenMember(false) + mbHasHiddenMember(false), + mbPopupPressed(false) { } @@ -88,9 +89,16 @@ void ScDPFieldButton::setHasHiddenMember(bool b) mbHasHiddenMember = b; } +void ScDPFieldButton::setPopupPressed(bool b) +{ + mbPopupPressed = b; +} + void ScDPFieldButton::draw() { const long nMargin = 2; + bool bOldMapEnablaed = mpOutDev->IsMapModeEnabled(); + mpOutDev->EnableMapMode(false); if (mbBaseButton) { @@ -125,6 +133,8 @@ void ScDPFieldButton::draw() if (mbPopupButton) drawPopupButton(); + + mpOutDev->EnableMapMode(bOldMapEnablaed); } void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const @@ -158,16 +168,19 @@ void ScDPFieldButton::drawPopupButton() mpOutDev->SetFillColor(mpStyle->GetFaceColor()); mpOutDev->DrawRect(Rectangle(aPos, aSize)); - // border lines - mpOutDev->SetLineColor(mpStyle->GetLightColor()); - mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+1, aPos.Y()+aSize.Height()-2)); - mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+aSize.Width()-2, aPos.Y()+1)); + if (!mbPopupPressed) + { + // border lines + mpOutDev->SetLineColor(mpStyle->GetLightColor()); + mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+1, aPos.Y()+aSize.Height()-2)); + mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+aSize.Width()-2, aPos.Y()+1)); - mpOutDev->SetLineColor(mpStyle->GetShadowColor()); - mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+aSize.Height()-2), - Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2)); - mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-2, aPos.Y()+1), - Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2)); + mpOutDev->SetLineColor(mpStyle->GetShadowColor()); + mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+aSize.Height()-2), + Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2)); + mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-2, aPos.Y()+1), + Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2)); + } // the arrowhead Color aArrowColor = mbHasHiddenMember ? mpStyle->GetHighlightLinkColor() : mpStyle->GetButtonTextColor(); @@ -180,6 +193,14 @@ void ScDPFieldButton::drawPopupButton() aPos1.Y() = aCenter.Y() - 3; aPos2.Y() = aCenter.Y() - 3; + if (mbPopupPressed) + { + aPos1.X() += 1; + aPos2.X() += 1; + aPos1.Y() += 1; + aPos2.Y() += 1; + } + do { ++aPos1.X(); @@ -194,6 +215,11 @@ void ScDPFieldButton::drawPopupButton() { // tiny little box to display in presence of hidden member(s). Point aBoxPos(aPos.X() + aSize.Width() - 5, aPos.Y() + aSize.Height() - 5); + if (mbPopupPressed) + { + aBoxPos.X() += 1; + aBoxPos.Y() += 1; + } Size aBoxSize(3, 3); mpOutDev->DrawRect(Rectangle(aBoxPos, aBoxSize)); } diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 9bd78d8ab598..367dfe059600 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -64,6 +64,7 @@ public: void setDrawBaseButton(bool b); void setDrawPopupButton(bool b); void setHasHiddenMember(bool b); + void setPopupPressed(bool b); void draw(); void getPopupBoundingBox(Point& rPos, Size& rSize) const; @@ -81,6 +82,7 @@ private: bool mbBaseButton; bool mbPopupButton; bool mbHasHiddenMember; + bool mbPopupPressed; }; // ============================================================================ diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index e38c2a4f422c..4408c5f9b602 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -50,6 +50,7 @@ class ScPivot; #endif class ScDPObject; class ScDPFieldPopupWindow; +class ScDPFieldButton; class ScOutputData; class ScFilterListBox; class AutoFilterPopup; @@ -162,6 +163,7 @@ private: ScFilterListBox* pFilterBox; FloatingWindow* pFilterFloat; ::std::auto_ptr mpDPFieldPopup; + ::std::auto_ptr mpFilterButton; USHORT nCursorHideCount; diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 79529194b668..8522ab27739b 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -372,6 +372,7 @@ ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhic pFilterBox( NULL ), pFilterFloat( NULL ), mpDPFieldPopup(NULL), + mpFilterButton(NULL), nCursorHideCount( 0 ), bMarking( FALSE ), nButtonDown( 0 ), @@ -1765,11 +1766,17 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt ) { if ( pFilterBox && pFilterBox->GetMode() == SC_FILTERBOX_FILTER ) { - BOOL bFilterActive = IsAutoFilterActive( pFilterBox->GetCol(), pFilterBox->GetRow(), - pViewData->GetTabNo() ); - HideCursor(); - aComboButton.Draw( bFilterActive ); - ShowCursor(); + if (mpFilterButton.get()) + { + bool bFilterActive = IsAutoFilterActive( + pFilterBox->GetCol(), pFilterBox->GetRow(), pViewData->GetTabNo() ); + + mpFilterButton->setHasHiddenMember(bFilterActive); + mpFilterButton->setPopupPressed(false); + HideCursor(); + mpFilterButton->draw(); + ShowCursor(); + } } nMouseStatus = SC_GM_NONE; ReleaseMouse(); @@ -2179,9 +2186,14 @@ void __EXPORT ScGridWindow::MouseMove( const MouseEvent& rMEvt ) nMouseStatus = SC_GM_NONE; if ( pFilterBox->GetMode() == SC_FILTERBOX_FILTER ) { - HideCursor(); - aComboButton.Draw( FALSE ); - ShowCursor(); + if (mpFilterButton.get()) + { + mpFilterButton->setHasHiddenMember(false); + mpFilterButton->setPopupPressed(false); + HideCursor(); + mpFilterButton->draw(); + ShowCursor(); + } } ReleaseMouse(); pFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT ) ); diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index 8db035d6df55..40bb30f7c0e7 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -134,8 +134,8 @@ bool ScGridWindow::DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& { ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); - Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich); - Point aDiffPix = rMEvt.GetPosPixel(); + Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich); + Point aDiffPix = rMEvt.GetPosPixel(); aDiffPix -= aScrPos; BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab ); @@ -144,25 +144,29 @@ bool ScGridWindow::DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& long nSizeX, nSizeY; pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); + Size aScrSize(nSizeX-1, nSizeY-1); - // Breite des Buttons ist nicht von der Zellhoehe abhaengig - Size aButSize = aComboButton.GetSizePixel(); - long nButWidth = Min( aButSize.Width(), nSizeX ); - long nButHeight = Min( aButSize.Height(), nSizeY ); - - if ( aDiffPix.X() >= nSizeX - nButWidth && - aDiffPix.Y() >= nSizeY - nButHeight ) + // Check if the mouse cursor is clicking on the popup arrow box. + mpFilterButton.reset(new ScDPFieldButton(this, &GetSettings().GetStyleSettings())); + mpFilterButton->setBoundingBox(aScrPos, aScrSize); + Point aPopupPos; + Size aPopupSize; + mpFilterButton->getPopupBoundingBox(aPopupPos, aPopupSize); + Rectangle aRec(aPopupPos, aPopupSize); + if (aRec.IsInside(rMEvt.GetPosPixel())) { if ( DoPageFieldSelection( nCol, nRow ) ) return true; - BOOL bFilterActive = IsAutoFilterActive( nCol, nRow, - pViewData->GetTabNo() ); - - aComboButton.SetOptSizePixel(); - DrawComboButton( aScrPos, nSizeX, nSizeY, bFilterActive, TRUE ); + bool bFilterActive = IsAutoFilterActive(nCol, nRow, nTab); + mpFilterButton->setHasHiddenMember(bFilterActive); + mpFilterButton->setDrawBaseButton(false); + mpFilterButton->setDrawPopupButton(true); + mpFilterButton->setPopupPressed(true); + HideCursor(); + mpFilterButton->draw(); + ShowCursor(); DoAutoFilterMenue(nCol, nRow, false); - return true; } @@ -810,14 +814,14 @@ void ScGridWindow::DPTestMouse( const MouseEvent& rMEvt, BOOL bMove ) bool ScGridWindow::DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj) { // Get the geometry of the cell. - Point aSrcPos = pViewData->GetScrPos(rPos.Col(), rPos.Row(), eWhich); + Point aScrPos = pViewData->GetScrPos(rPos.Col(), rPos.Row(), eWhich); long nSizeX, nSizeY; pViewData->GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeX, nSizeY); - Size aSrcSize(nSizeX-1, nSizeY-1); + Size aScrSize(nSizeX-1, nSizeY-1); // Check if the mouse cursor is clicking on the popup arrow box. ScDPFieldButton aBtn(this, &GetSettings().GetStyleSettings()); - aBtn.setBoundingBox(aSrcPos, aSrcSize); + aBtn.setBoundingBox(aScrPos, aScrSize); Point aPopupPos; Size aPopupSize; aBtn.getPopupBoundingBox(aPopupPos, aPopupSize); @@ -825,7 +829,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(aSrcPos), aSrcSize, rPos, pDPObj); + DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, rPos, pDPObj); return true; } diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index 12e93f977945..7c20b7ca35a4 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -1293,6 +1293,7 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2 aCellBtn.setBoundingBox(aScrPos, Size(nSizeX-1, nSizeY-1)); aCellBtn.setDrawBaseButton(false); aCellBtn.setDrawPopupButton(true); + aCellBtn.setHasHiddenMember(bArrowState); aCellBtn.draw(); } } -- cgit From 73cabf9a263d8ca4e8ef9a84ae9cd04d1df1aaab Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Sat, 1 Aug 2009 03:09:27 +0000 Subject: dismiss the popup window when the sheet is scrolled etc. --- sc/source/ui/view/gridwin.cxx | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 8522ab27739b..f12a8c9f8a57 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -452,14 +452,26 @@ void __EXPORT ScGridWindow::Resize( const Size& ) void ScGridWindow::ClickExtern() { - // #i81298# don't delete the filter box when called from its select handler - // (possible through row header size update) - // #i84277# when initializing the filter box, a Basic error can deactivate the view - if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) ) - return; + do + { + // #i81298# don't delete the filter box when called from its select handler + // (possible through row header size update) + // #i84277# when initializing the filter box, a Basic error can deactivate the view + if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) ) + { + break; + } - DELETEZ(pFilterBox); - DELETEZ(pFilterFloat); + DELETEZ(pFilterBox); + DELETEZ(pFilterFloat); + } + while (false); + + if (mpDPFieldPopup.get()) + { + mpDPFieldPopup->close(false); + mpDPFieldPopup.reset(); + } } IMPL_LINK( ScGridWindow, PopupModeEndHdl, FloatingWindow*, EMPTYARG ) -- cgit From a1f35730b44c135dbb0883e2df1ee1a817a815a2 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Mon, 3 Aug 2009 19:44:11 +0000 Subject: Fixed text zooming issue where the text was not scaling properly per current zoom level. --- sc/source/ui/cctrl/dpcontrol.cxx | 20 ++++++++++++++++---- sc/source/ui/inc/dpcontrol.hxx | 5 ++++- sc/source/ui/view/gridwin2.cxx | 2 +- sc/source/ui/view/gridwin4.cxx | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 2239a4c96a2c..ca90e6624caa 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -48,8 +48,9 @@ using ::rtl::OUString; using ::rtl::OUStringHash; using ::std::vector; using ::std::hash_map; +using ::std::auto_ptr; -ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle) : +ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY) : mpOutDev(pOutDev), mpStyle(pStyle), mbBaseButton(true), @@ -57,6 +58,15 @@ ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pSt mbHasHiddenMember(false), mbPopupPressed(false) { + if (pZoomX) + maZoomX = *pZoomX; + else + maZoomX = Fraction(1, 1); + + if (pZoomY) + maZoomY = *pZoomY; + else + maZoomY = Fraction(1, 1); } ScDPFieldButton::~ScDPFieldButton() @@ -119,13 +129,15 @@ void ScDPFieldButton::draw() mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()), Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1)); - // Field name + // Field name. Font aTextFont( mpStyle->GetLabelFont() ); - aTextFont.SetHeight(12); + double fFontHeight = 12.0; + fFontHeight *= static_cast(maZoomY.GetNumerator()) / static_cast(maZoomY.GetDenominator()); + aTextFont.SetHeight(fFontHeight); mpOutDev->SetFont(aTextFont); Point aTextPos = maPos; - long nTHeight = mpOutDev->GetTextHeight(); + long nTHeight = static_cast(fFontHeight); aTextPos.setX(maPos.getX() + nMargin); aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2); mpOutDev->DrawText(aTextPos, maText); diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 367dfe059600..74223e329f32 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -33,6 +33,7 @@ #include "rtl/ustring.hxx" #include "tools/gen.hxx" +#include "tools/fract.hxx" #include "vcl/floatwin.hxx" #include "vcl/button.hxx" #include "vcl/scrbar.hxx" @@ -56,7 +57,7 @@ class Window; class ScDPFieldButton { public: - ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle); + ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX = NULL, const Fraction* pZoomY = NULL); ~ScDPFieldButton(); void setText(const ::rtl::OUString& rText); @@ -77,6 +78,8 @@ private: Point maPos; Size maSize; ::rtl::OUString maText; + Fraction maZoomX; + Fraction maZoomY; OutputDevice* mpOutDev; const StyleSettings* mpStyle; bool mbBaseButton; diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index 40bb30f7c0e7..11d1458359c7 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -147,7 +147,7 @@ bool ScGridWindow::DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& Size aScrSize(nSizeX-1, nSizeY-1); // Check if the mouse cursor is clicking on the popup arrow box. - mpFilterButton.reset(new ScDPFieldButton(this, &GetSettings().GetStyleSettings())); + mpFilterButton.reset(new ScDPFieldButton(this, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY())); mpFilterButton->setBoundingBox(aScrPos, aScrSize); Point aPopupPos; Size aPopupSize; diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index 7c20b7ca35a4..594f97b473f8 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -1204,7 +1204,7 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2 { aComboButton.SetOutputDevice( pContentDev ); - ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings()); + ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY()); SCCOL nCol; SCROW nRow; -- cgit From 78b7cf3e05df965564fdebac18c4f80acd594119 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Mon, 3 Aug 2009 19:56:25 +0000 Subject: Fixed naming inconsistency: Src -> Scr --- sc/source/ui/inc/gridwin.hxx | 2 +- sc/source/ui/view/gridwin.cxx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index 4408c5f9b602..c5b08861333e 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -259,7 +259,7 @@ private: */ bool DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj); void DPLaunchFieldPopupMenu( - const Point& rSrcPos, const Size& rSrcSize, const ScAddress& rPos, ScDPObject* pDPObj); + const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj); void RFMouseMove( const MouseEvent& rMEvt, BOOL bUp ); diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index f12a8c9f8a57..9fbcfbb4fdb0 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -685,12 +685,12 @@ void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow ) return; // Get the geometry of the cell. - Point aSrcPos = pViewData->GetScrPos(nCol, nRow, eWhich); + Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich); long nSizeX, nSizeY; pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY); - Size aSrcSize(nSizeX-1, nSizeY-1); + Size aScrSize(nSizeX-1, nSizeY-1); - DPLaunchFieldPopupMenu(OutputToScreenPixel(aSrcPos), aSrcSize, ScAddress(nCol, nRow, nTab), pDPObj); + DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj); } void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange ) -- cgit From 8802d45ff2523326cef7bf62cee92cd3809ada86 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Mon, 3 Aug 2009 20:27:28 +0000 Subject: Launch the popup window right-aligned with the cell if the cell is wider than the width of the popup. --- sc/source/ui/cctrl/dpcontrol.cxx | 22 +++++++++++++--------- sc/source/ui/inc/dpcontrol.hxx | 3 +++ sc/source/ui/view/gridwin2.cxx | 12 ++++++++++-- 3 files changed, 26 insertions(+), 11 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index ca90e6624caa..0060a9341ec3 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -786,6 +786,7 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : maBtnCancel(this), mpExtendedData(NULL), mpOKAction(NULL), + maWndSize(160, 330), mePrevToggleAllState(STATE_DONTKNOW) { const StyleSettings& rStyle = GetSettings().GetStyleSettings(); @@ -855,11 +856,9 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy const sal_uInt16 nBottomMargin = 10; const sal_uInt16 nMenuListMargin = 20; - Size aWndSize = Size(160, 330); - // parameters calculated from constants. - const sal_uInt16 nListBoxWidth = aWndSize.Width() - nListBoxMargin*2; - const sal_uInt16 nListBoxHeight = aWndSize.Height() - nTopMargin - nMenuHeight - + const sal_uInt16 nListBoxWidth = maWndSize.Width() - nListBoxMargin*2; + const sal_uInt16 nListBoxHeight = maWndSize.Height() - nTopMargin - nMenuHeight - nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight; const sal_uInt16 nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1; @@ -869,7 +868,7 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy case WHOLE: { rPos = Point(0, 0); - rSize = aWndSize; + rSize = maWndSize; } break; case LISTBOX_AREA_OUTER: @@ -924,16 +923,16 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy break; case BTN_OK: { - long x = (aWndSize.Width() - nBtnWidth*2)/3; - long y = aWndSize.Height() - nBottomMargin - nBtnHeight; + long x = (maWndSize.Width() - nBtnWidth*2)/3; + long y = maWndSize.Height() - nBottomMargin - nBtnHeight; rPos = Point(x, y); rSize = Size(nBtnWidth, nBtnHeight); } break; case BTN_CANCEL: { - long x = (aWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth; - long y = aWndSize.Height() - nBottomMargin - nBtnHeight; + long x = (maWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth; + long y = maWndSize.Height() - nBottomMargin - nBtnHeight; rPos = Point(x, y); rSize = Size(nBtnWidth, nBtnHeight); } @@ -1091,6 +1090,11 @@ void ScDPFieldPopupWindow::initMembers() } } +const Size& ScDPFieldPopupWindow::getWindowSize() const +{ + return maWndSize; +} + void ScDPFieldPopupWindow::getResult(hash_map& rResult) { typedef hash_map ResultMap; diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 74223e329f32..0074add2be25 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -212,6 +212,8 @@ public: void addMember(const ::rtl::OUString& rName, bool bVisible); void initMembers(); + const Size& getWindowSize() const; + void getResult(::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rResult); void close(bool bOK); @@ -283,6 +285,7 @@ private: ::std::auto_ptr mpExtendedData; ::std::auto_ptr mpOKAction; + const Size maWndSize; /// hard-coded window size. TriState mePrevToggleAllState; }; diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index 11d1458359c7..8bafb474bff3 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -895,7 +895,7 @@ private: } void ScGridWindow::DPLaunchFieldPopupMenu( - const Point& rSrcPos, const Size& rSrcSize, const ScAddress& rPos, ScDPObject* pDPObj) + const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj) { // We need to get the list of field members. auto_ptr pDPData(new DPFieldPopupData); @@ -957,8 +957,16 @@ void ScGridWindow::DPLaunchFieldPopupMenu( } } + Rectangle aCellRect(rScrPos, rScrSize); + const Size& rPopupSize = mpDPFieldPopup->getWindowSize(); + if (rScrSize.getWidth() > rPopupSize.getWidth()) + { + // If the cell width is larger than the popup window width, launch it + // right-aligned with the cell. + long nXOffset = rScrSize.getWidth() - rPopupSize.getWidth(); + aCellRect.SetPos(Point(rScrPos.X() + nXOffset, rScrPos.Y())); + } mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) ); - Rectangle aCellRect(rSrcPos, rSrcSize); mpDPFieldPopup->StartPopupMode(aCellRect, (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_GRABFOCUS)); } -- cgit From 9c22409f2648758e69a9de4ae49c2ba9bab24a3b Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 20 Aug 2009 04:28:30 +0000 Subject: My first cut on implementing accessibility for the new datapilot field popup window. This is still work-in-progress, with lots of debug statements everywhere. --- sc/inc/AccessibleFilterMenu.hxx | 191 ++++++++ sc/inc/AccessibleFilterMenuItem.hxx | 111 +++++ sc/inc/AccessibleFilterTopWindow.hxx | 80 ++++ .../ui/Accessibility/AccessibleContextBase.cxx | 5 + .../ui/Accessibility/AccessibleFilterMenu.cxx | 532 +++++++++++++++++++++ .../ui/Accessibility/AccessibleFilterMenuItem.cxx | 309 ++++++++++++ .../ui/Accessibility/AccessibleFilterTopWindow.cxx | 98 ++++ sc/source/ui/Accessibility/makefile.mk | 6 + sc/source/ui/cctrl/dpcontrol.cxx | 229 ++++++++- sc/source/ui/inc/AccessibleContextBase.hxx | 2 + sc/source/ui/inc/dpcontrol.hxx | 49 +- sc/source/ui/view/gridwin2.cxx | 3 +- 12 files changed, 1591 insertions(+), 24 deletions(-) create mode 100644 sc/inc/AccessibleFilterMenu.hxx create mode 100644 sc/inc/AccessibleFilterMenuItem.hxx create mode 100644 sc/inc/AccessibleFilterTopWindow.hxx create mode 100644 sc/source/ui/Accessibility/AccessibleFilterMenu.cxx create mode 100644 sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx create mode 100644 sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx (limited to 'sc') diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx new file mode 100644 index 000000000000..1489f3bbdca1 --- /dev/null +++ b/sc/inc/AccessibleFilterMenu.hxx @@ -0,0 +1,191 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_ACCESSIBLEFILTERMENU_HXX +#define SC_ACCESSIBLEFILTERMENU_HXX + +#include "AccessibleContextBase.hxx" +#include "cppuhelper/implbase2.hxx" + +#include +#include +#include +#include +#include + +#include +#include + +namespace com { namespace sun { namespace star { + namespace accessibility { + struct AccessibleEventObject; + } +}}} + +class ScDocument; +class ScMenuFloatingWindow; + +typedef ::cppu::ImplHelper2< + ::com::sun::star::accessibility::XAccessibleStateSet, + ::com::sun::star::accessibility::XAccessibleSelection > ScAccessibleFilterMenu_BASE; + +class ScAccessibleFilterMenu : + public ScAccessibleContextBase, + public ScAccessibleFilterMenu_BASE +{ +public: + struct MenuItem + { + ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible > mxAccessible; + bool mbSelected; + + MenuItem(); + }; + + ScAccessibleFilterMenu( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible>& rxParent, + ScMenuFloatingWindow* pWin, const ::rtl::OUString& rName, ScDocument* pDoc); + virtual ~ScAccessibleFilterMenu(); + + // XAccessibleComponent + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& rPoint ) + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL isVisible() + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL grabFocus() + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getForeground() + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getBackground() + throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleContext + + virtual ::rtl::OUString SAL_CALL getAccessibleName() + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAccessibleChildCount() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL + getAccessibleChild(sal_Int32 nIndex) + throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException); + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL + getAccessibleStateSet() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleEventBroadcaster + + virtual void SAL_CALL + addEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener) + throw (com::sun::star::uno::RuntimeException); + + // Remove an existing event listener. + virtual void SAL_CALL + removeEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener) + throw (com::sun::star::uno::RuntimeException); + + // XAccessibleStateSet + + virtual ::sal_Bool SAL_CALL isEmpty() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL contains(sal_Int16 nState) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL containsAll(const ::com::sun::star::uno::Sequence< ::sal_Int16 >& aStateSet) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence SAL_CALL getStates() throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleSelection + + virtual void SAL_CALL selectAccessibleChild( ::sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isAccessibleChildSelected( ::sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL clearAccessibleSelection( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectAllAccessibleChildren( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL + getSelectedAccessibleChild(sal_Int32 nChildIndex) + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL deselectAccessibleChild( ::sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + // XInterface + + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( + ::com::sun::star::uno::Type const & rType ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); + + // XTypeProvider + + virtual ::com::sun::star::uno::Sequence SAL_CALL getImplementationId() + throw (::com::sun::star::uno::RuntimeException); + + // non-UNO methods + + void selectMenuItem(size_t nIndex, bool bSelect); + void appendMenuItem(const ::rtl::OUString& rName, bool bEnabled, size_t nMenuPos); + + void setEnabled(bool bEnabled); + +private: + bool isFocused(); + bool isSelected(); + + void updateStates(); + +private: + ::std::vector maMenuItems; + ::std::set maStates; + + ScMenuFloatingWindow* mpWindow; + ScDocument* mpDoc; + + bool mbEnabled:1; + bool mbSelected:1; +}; + +#endif diff --git a/sc/inc/AccessibleFilterMenuItem.hxx b/sc/inc/AccessibleFilterMenuItem.hxx new file mode 100644 index 000000000000..740cfd4e30c9 --- /dev/null +++ b/sc/inc/AccessibleFilterMenuItem.hxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_ACCESSIBLEFILTERMENUITEM_HXX +#define SC_ACCESSIBLEFILTERMENUITEM_HXX + +#include "AccessibleContextBase.hxx" +#include "cppuhelper/implbase2.hxx" + +#include +#include + +class ScMenuFloatingWindow; + +typedef ::cppu::ImplHelper2< + ::com::sun::star::accessibility::XAccessibleAction, + ::com::sun::star::accessibility::XAccessibleStateSet > ScAccessibleFilterMenuItem_BASE; + +class ScAccessibleFilterMenuItem : + public ScAccessibleContextBase, + public ScAccessibleFilterMenuItem_BASE +{ +public: + explicit ScAccessibleFilterMenuItem( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const ::rtl::OUString& rName, size_t nMenuPos); + + virtual ~ScAccessibleFilterMenuItem(); + + // XAccessibleContext + + virtual sal_Int32 SAL_CALL getAccessibleChildCount() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL + getAccessibleChild(sal_Int32 nIndex) + throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException); + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL + getAccessibleStateSet() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleStateSet + + virtual ::sal_Bool SAL_CALL isEmpty() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL contains(sal_Int16 nState) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL containsAll(const ::com::sun::star::uno::Sequence< ::sal_Int16 >& aStateSet) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence SAL_CALL getStates() throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleAction + + virtual ::sal_Int32 SAL_CALL getAccessibleActionCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL doAccessibleAction( ::sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleActionDescription( ::sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( ::sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( + ::com::sun::star::uno::Type const & rType ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); + + // Non-UNO Methods + + void select(); + void unselect(); + bool isSelected() const; + + void setEnabled(bool bEnabled); + +private: + ScMenuFloatingWindow* mpWindow; + ::rtl::OUString maName; + size_t mnMenuPos; + bool mbSelected:1; + bool mbEnabled:1; +}; + +#endif diff --git a/sc/inc/AccessibleFilterTopWindow.hxx b/sc/inc/AccessibleFilterTopWindow.hxx new file mode 100644 index 000000000000..7b7ad0c880f0 --- /dev/null +++ b/sc/inc/AccessibleFilterTopWindow.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_ACCESSIBLEFILTERTOPWINDOW_HXX +#define SC_ACCESSIBLEFILTERTOPWINDOW_HXX + +#include "AccessibleContextBase.hxx" +#include "cppuhelper/implbase1.hxx" + +class ScDPFieldPopupWindow; +class ScDocument; + +class ScAccessibleFilterTopWindow : public ScAccessibleContextBase +{ +public: + ScAccessibleFilterTopWindow( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible>& rxParent, + ScDPFieldPopupWindow* pWin, const ::rtl::OUString& rName, ScDocument* pDoc); + virtual ~ScAccessibleFilterTopWindow(); + + // XAccessibleContext + + virtual sal_Int32 SAL_CALL getAccessibleChildCount() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL + getAccessibleChild(sal_Int32 nIndex) + throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException); + + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw (::com::sun::star::uno::RuntimeException); + + // Non-UNO Methods + + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + getAccessibleChildMenu(); + + void setAccessibleChildListBox( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& rAccessible); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + mxAccessibleMenu; + + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + mxAccessibleListBox; + + ScDPFieldPopupWindow* mpWindow; + ScDocument* mpDoc; +}; + +#endif diff --git a/sc/source/ui/Accessibility/AccessibleContextBase.cxx b/sc/source/ui/Accessibility/AccessibleContextBase.cxx index 8774ef74f86d..16d80402abac 100644 --- a/sc/source/ui/Accessibility/AccessibleContextBase.cxx +++ b/sc/source/ui/Accessibility/AccessibleContextBase.cxx @@ -628,3 +628,8 @@ void ScAccessibleContextBase::IsObjectValid() const if (rBHelper.bDisposed || rBHelper.bInDispose) throw lang::DisposedException(); } + +void ScAccessibleContextBase::SetRole(sal_Int16 nRole) +{ + maRole = nRole; +} diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx new file mode 100644 index 000000000000..2ab7722807da --- /dev/null +++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx @@ -0,0 +1,532 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove + +#include "precompiled_sc.hxx" +#include "AccessibleFilterMenu.hxx" +#include "AccessibleFilterMenuItem.hxx" +#include "unoguard.hxx" +#include "global.hxx" +#include "document.hxx" +#include "docpool.hxx" + +#include "tools/gen.hxx" +#include "svx/unoedsrc.hxx" +#include "svx/editdata.hxx" +#include "svx/outliner.hxx" +#include "svtools/itemset.hxx" +#include "vcl/unohelp.hxx" +#include "dpcontrol.hxx" + +#include + +#include +#include +#include +#include +#include + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::accessibility::AccessibleStateType; + +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::lang::IndexOutOfBoundsException; +using ::com::sun::star::lang::IllegalArgumentException; +using ::com::sun::star::uno::RuntimeException; +using ::rtl::OUString; +using ::std::for_each; +using ::std::vector; +using ::std::set; + +#include +#include +#include + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + + void printTime(int line) const + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + +// ============================================================================ + +namespace { + +class SelectMenuItem : public ::std::unary_function +{ +public: + explicit SelectMenuItem(bool bSelect) : mbSelect(bSelect) {} + + void operator() (ScAccessibleFilterMenu::MenuItem& rItem) const + { + rItem.mbSelected = mbSelect; + ScAccessibleFilterMenuItem* p = static_cast(rItem.mxAccessible.get()); + if (mbSelect) + p->select(); + else + p->unselect(); + } +private: + bool mbSelect; +}; + +class AddRemoveEventListener : public ::std::unary_function +{ +public: + explicit AddRemoveEventListener(const Reference& rListener, bool bAdd) : + mxListener(rListener), mbAdd(bAdd) {} + + void operator() (ScAccessibleFilterMenu::MenuItem& rItem) const + { + if (!rItem.mxAccessible.is()) + return; + + Reference xBc(rItem.mxAccessible, UNO_QUERY); + if (xBc.is()) + { + if (mbAdd) + xBc->addEventListener(mxListener); + else + xBc->removeEventListener(mxListener); + } + } +private: + Reference mxListener; + bool mbAdd; +}; + +class CountSelectedMenuItem : public ::std::unary_function +{ +public: + explicit CountSelectedMenuItem() : mnCount(0) {} + + CountSelectedMenuItem(const CountSelectedMenuItem& r) : + mnCount(r.mnCount) {} + + void operator() (ScAccessibleFilterMenu::MenuItem& rItem) + { +// if (rItem.mbSelected) +// ++mnCount; +// + ScAccessibleFilterMenuItem* p = static_cast(rItem.mxAccessible.get()); +// fprintf(stdout, "CountSelectedMenuItem::(): name = '%s' selected = %d\n", +// rtl::OUStringToOString(p->getAccessibleName(), RTL_TEXTENCODING_UTF8).getStr(), p->isSelected()); + if (p->isSelected()) + ++mnCount; + } + + size_t getCount() const { return mnCount; } + +private: + size_t mnCount; +}; + +} + +// ============================================================================ + +ScAccessibleFilterMenu::MenuItem::MenuItem() : + mbSelected(false) +{ +} + +// ============================================================================ + +ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, ScDocument* pDoc) : + ScAccessibleContextBase(rxParent, AccessibleRole::MENU), + mpWindow(pWin), + mpDoc(pDoc), + mbEnabled(true), + mbSelected(false) +{ + fprintf(stdout, "ScAccessibleFilterMenu::ScAccessibleFilterMenu: ctor (%p)\n", this); + SetName(rName); +// SetDescription(OUString::createFromAscii("parent filter menu description")); +} + +ScAccessibleFilterMenu::~ScAccessibleFilterMenu() +{ + fprintf(stdout, "ScAccessibleFilterMenu::~ScAccessibleFilterMenu: dtor (%p)\n", this); +} + +// XAccessibleComponent + +Reference ScAccessibleFilterMenu::getAccessibleAtPoint( const ::com::sun::star::awt::Point& rPoint ) + throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::getAccessibleAtPoint: point = (%ld,%ld)\n", rPoint.X, rPoint.Y); + return this; +} + +sal_Bool ScAccessibleFilterMenu::isVisible() throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::isVisible: called\n"); + return true; +} + +void ScAccessibleFilterMenu::grabFocus() + throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::grabFocus: called\n"); +} + +sal_Int32 ScAccessibleFilterMenu::getForeground() + throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::getForeground: called\n"); + return 0; +} + +sal_Int32 ScAccessibleFilterMenu::getBackground() + throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::getBackground: called\n"); + return 0; +} + +// XAccessibleContext + +OUString ScAccessibleFilterMenu::getAccessibleName() throw (RuntimeException) +{ + return ScAccessibleContextBase::getAccessibleName(); +} + +sal_Int32 ScAccessibleFilterMenu::getAccessibleChildCount() + throw (RuntimeException) +{ + return maMenuItems.size(); +} + +Reference ScAccessibleFilterMenu::getAccessibleChild(sal_Int32 nIndex) + throw (RuntimeException, IndexOutOfBoundsException) +{ + if (maMenuItems.size() <= nIndex) + throw IndexOutOfBoundsException(); + + return maMenuItems[nIndex].mxAccessible; +} + +Reference ScAccessibleFilterMenu::getAccessibleStateSet() + throw (RuntimeException) +{ + updateStates(); + return this; +} + +OUString ScAccessibleFilterMenu::getImplementationName() + throw (RuntimeException) +{ + return OUString::createFromAscii("ScAccessibleFilterMenu - implementation name"); +} + +// XAccessibleEventBroadcaster + +void ScAccessibleFilterMenu::addEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener) + throw (com::sun::star::uno::RuntimeException) +{ + ScAccessibleContextBase::addEventListener(xListener); + for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, true)); +} + +void ScAccessibleFilterMenu::removeEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener) + throw (com::sun::star::uno::RuntimeException) +{ + ScAccessibleContextBase::removeEventListener(xListener); + for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, false)); +} + +// XAccessibleStateSet + +sal_Bool ScAccessibleFilterMenu::isEmpty() throw (RuntimeException) +{ + updateStates(); + return maStates.empty(); +} + +sal_Bool ScAccessibleFilterMenu::contains(sal_Int16 nState) throw (RuntimeException) +{ + updateStates(); + return maStates.count(nState) > 0; +} + +sal_Bool ScAccessibleFilterMenu::containsAll(const Sequence& aStateSet) + throw (RuntimeException) +{ + updateStates(); + sal_Int32 n = aStateSet.getLength(); + for (sal_Int32 i = 0; i < n; ++i) + { + if (!maStates.count(aStateSet[i])) + // This state is not set. + return false; + } + // All specified states are set. + return true; +} + +Sequence ScAccessibleFilterMenu::getStates() throw (RuntimeException) +{ + StackPrinter __stack_printer__("ScAccessibleFilterMenu::getStates"); + updateStates(); + Sequence aSeq(0); + set::const_iterator itr = maStates.begin(), itrEnd = maStates.end(); + for (size_t i = 0; itr != itrEnd; ++itr, ++i) + { + aSeq.realloc(i+1); + aSeq[i] = *itr; + } + if (maStates.count(FOCUSED)) + fprintf(stdout, "ScAccessibleFilterMenu::getStates: focused\n"); + else + fprintf(stdout, "ScAccessibleFilterMenu::getStates: not focused\n"); + return aSeq; +} + +// XAccessibleSelection + +void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex) + throw (IndexOutOfBoundsException, RuntimeException) +{ + StackPrinter __stack_printer__("********** ScAccessibleFilterMenu::selectAccessibleChild **********"); + fprintf(stdout, "ScAccessibleFilterMenu::selectAccessibleChild: index = %ld\n", nChildIndex); + if (nChildIndex >= maMenuItems.size()) + throw IndexOutOfBoundsException(); + + maMenuItems[nChildIndex].mbSelected = true; + mpWindow->setSelectedMenuItem(nChildIndex, false, false); +} + +sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex) + throw (IndexOutOfBoundsException, RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::isAccessibleChildSelected: index = %ld\n", nChildIndex); + if (nChildIndex >= maMenuItems.size()) + throw IndexOutOfBoundsException(); + + return maMenuItems[nChildIndex].mbSelected; +} + +void ScAccessibleFilterMenu::clearAccessibleSelection() throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::clearAccessibleSelection: called\n"); + for_each(maMenuItems.begin(), maMenuItems.end(), SelectMenuItem(false)); + mpWindow->clearSelectedMenuItem(false); +} + +void ScAccessibleFilterMenu::selectAllAccessibleChildren() throw (RuntimeException) +{ + // not suported - this is a menu, you can't select all menu items. + +// fprintf(stdout, "ScAccessibleFilterMenu::selectAllAccessibleChildren: called\n"); +// for_each(maMenuItems.begin(), maMenuItems.end(), SelectMenuItem(true)); +} + +sal_Int32 ScAccessibleFilterMenu::getSelectedAccessibleChildCount() throw (RuntimeException) +{ + sal_Int32 n = for_each(maMenuItems.begin(), maMenuItems.end(), CountSelectedMenuItem()).getCount(); + fprintf(stdout, "ScAccessibleFilterMenu::getSelectedAccessibleChildCount: count = %ld\n", n); + return n; +} + +Reference ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_Int32 nChildIndex) + throw (IndexOutOfBoundsException, RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::getSelectedAccessibleChild: index = %ld\n", nChildIndex); + if (static_cast(nChildIndex) >= maMenuItems.size()) + throw IndexOutOfBoundsException(); + + return maMenuItems[nChildIndex].mxAccessible; +} + +void ScAccessibleFilterMenu::deselectAccessibleChild(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::deselectAccessibleChild: index = %ld\n", nChildIndex); + if (static_cast(nChildIndex) >= maMenuItems.size()) + throw IndexOutOfBoundsException(); + + maMenuItems[nChildIndex].mbSelected = false; + ScAccessibleFilterMenuItem* p = static_cast( + maMenuItems[nChildIndex].mxAccessible.get()); + p->unselect(); + + mpWindow->selectMenuItem(nChildIndex, false, false, false); +} + +// XInterface + +uno::Any SAL_CALL ScAccessibleFilterMenu::queryInterface( uno::Type const & rType ) + throw (RuntimeException) +{ + Any any = ScAccessibleContextBase::queryInterface(rType); + if (any.hasValue()) + return any; + + return ScAccessibleFilterMenu_BASE::queryInterface(rType); +} + +void SAL_CALL ScAccessibleFilterMenu::acquire() throw () +{ + ScAccessibleContextBase::acquire(); +} + +void SAL_CALL ScAccessibleFilterMenu::release() throw () +{ + ScAccessibleContextBase::release(); +} + +// XTypeProvider + +Sequence ScAccessibleFilterMenu::getImplementationId() + throw (RuntimeException) +{ + Sequence aId(16); + return aId; +} + +void ScAccessibleFilterMenu::selectMenuItem(size_t nIndex, bool bSelect) +{ + StackPrinter __stack_printer__("ScAccessibleFilterMenu::selectMenuItem"); + fprintf(stdout, "ScAccessibleFilterMenu::selectMenuItem: index = %d select = %d\n", nIndex, bSelect); + if (maMenuItems.size() <= nIndex) + return; + + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; + CommitChange(aEvent); + + maMenuItems[nIndex].mbSelected = bSelect; + ScAccessibleFilterMenuItem* p = static_cast( + maMenuItems[nIndex].mxAccessible.get()); + if (bSelect) + p->select(); + else + p->unselect(); + + isSelected(); +// aEvent.EventId = AccessibleEventId::STATE_CHANGED; +// CommitChange(aEvent); +} + +void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled, size_t nMenuPos) +{ + // Check weather this menu item is a sub menu or a regular menu item. + ScMenuFloatingWindow* pSubMenu = mpWindow->getSubMenuWindow(nMenuPos); + MenuItem aItem; + if (pSubMenu) + { + aItem.mxAccessible = pSubMenu->CreateAccessible(); + ScAccessibleFilterMenu* p = static_cast( + aItem.mxAccessible.get()); + p->setEnabled(bEnabled); + } + else + { + aItem.mxAccessible.set(new ScAccessibleFilterMenuItem(this, mpWindow, rName, nMenuPos)); + ScAccessibleFilterMenuItem* p = static_cast( + aItem.mxAccessible.get()); + p->setEnabled(bEnabled); + } + maMenuItems.push_back(aItem); +} + +void ScAccessibleFilterMenu::setEnabled(bool bEnabled) +{ + mbEnabled = bEnabled; +} + +bool ScAccessibleFilterMenu::isFocused() +{ + return true; +// return isSelected(); +} + +bool ScAccessibleFilterMenu::isSelected() +{ + // Check to see if any of the child menu items is selected. + size_t nSelectCount = for_each(maMenuItems.begin(), maMenuItems.end(), CountSelectedMenuItem()).getCount(); +// fprintf(stdout, "ScAccessibleFilterMenu::isSelected: selected count = %d\n", nSelectCount); + return nSelectCount == 0; +} + +void ScAccessibleFilterMenu::updateStates() +{ + maStates.clear(); + maStates.insert(ENABLED); + maStates.insert(FOCUSABLE); + maStates.insert(SELECTABLE); + maStates.insert(SENSITIVE); + maStates.insert(OPAQUE); + + if (isFocused()) + maStates.insert(FOCUSED); + if (isSelected()) + maStates.insert(SELECTED); +} diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx new file mode 100644 index 000000000000..2e151b67b600 --- /dev/null +++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx @@ -0,0 +1,309 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove + +#include "precompiled_sc.hxx" +#include "AccessibleFilterMenuItem.hxx" +#include "dpcontrol.hxx" + +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::lang::IndexOutOfBoundsException; +using ::com::sun::star::uno::RuntimeException; +using ::rtl::OUString; +using ::std::vector; + +#include +#include +#include + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + + void printTime(int line) const + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + +ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem( + const Reference& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos) : + ScAccessibleContextBase(rxParent, AccessibleRole::MENU_ITEM), + mpWindow(pWin), + maName(rName), + mnMenuPos(nMenuPos), + mbSelected(false), + mbEnabled(true) +{ + SetName(rName); +} + +ScAccessibleFilterMenuItem::~ScAccessibleFilterMenuItem() +{ +} + +sal_Int32 ScAccessibleFilterMenuItem::getAccessibleChildCount() + throw (RuntimeException) +{ + return 0; +} + +Reference ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 nIndex) + throw (RuntimeException, IndexOutOfBoundsException) +{ + throw IndexOutOfBoundsException(); + return Reference(); +} + +Reference ScAccessibleFilterMenuItem::getAccessibleStateSet() + throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenuItem::getAccessibleStateSet: called\n"); + return this; +} + +OUString ScAccessibleFilterMenuItem::getImplementationName() + throw (RuntimeException) +{ + return OUString::createFromAscii("ScAccessibleFilterMenuItem - implementation name"); +} + +// XAccessibleStateSet + +sal_Bool ScAccessibleFilterMenuItem::isEmpty() throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenuItem::isEmpty: called\n"); + return (mbEnabled || mbSelected); +} + +sal_Bool ScAccessibleFilterMenuItem::contains(sal_Int16 nState) throw (RuntimeException) +{ + using namespace ::com::sun::star::accessibility::AccessibleStateType; + fprintf(stdout, "ScAccessibleFilterMenuItem::contains: state = %d\n", nState); + if (mbEnabled) + { + switch (nState) + { + case ENABLED: + case FOCUSABLE: + case SELECTABLE: + case SENSITIVE: + return true; + } + } + + if (mbSelected) + { + switch (nState) + { + case FOCUSED: + case SELECTED: + return true; + } + } + return false; +} + +sal_Bool ScAccessibleFilterMenuItem::containsAll(const Sequence& aStateSet) + throw (RuntimeException) +{ + using namespace ::com::sun::star::accessibility::AccessibleStateType; + fprintf(stdout, "ScAccessibleFilterMenuItem::containsAll: called\n"); + sal_Int32 n = aStateSet.getLength(); + for (sal_Int32 i = 0; i < n; ++i) + { + sal_Int16 nState = aStateSet[i]; + if (mbEnabled) + { + switch (nState) + { + case ENABLED: + case FOCUSABLE: + case SELECTABLE: + case SENSITIVE: + continue; + } + } + if (mbSelected) + { + switch (nState) + { + case FOCUSED: + case SELECTED: + continue; + } + } + return false; + } + return true; +} + +Sequence ScAccessibleFilterMenuItem::getStates() throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenuItem::getStates: name = '%s' enabled = %d selected = %d\n", + rtl::OUStringToOString(getAccessibleName(), RTL_TEXTENCODING_UTF8).getStr(), + mbEnabled, mbSelected); + using namespace ::com::sun::star::accessibility::AccessibleStateType; + vector aStates; + if (mbEnabled) + { + aStates.push_back(ENABLED); + aStates.push_back(FOCUSABLE); + aStates.push_back(SELECTABLE); + aStates.push_back(SENSITIVE); + } + + if (mbSelected) + { + aStates.push_back(FOCUSED); + aStates.push_back(SELECTED); + } + + size_t n = aStates.size(); + Sequence aSeq(aStates.size()); + for (size_t i = 0; i < n; ++i) + aSeq[i] = aStates[i]; + + return aSeq; +} + +// XAccessibleAction + +sal_Int32 ScAccessibleFilterMenuItem::getAccessibleActionCount() throw (RuntimeException) +{ + return 1; +} + +sal_Bool ScAccessibleFilterMenuItem::doAccessibleAction(sal_Int32 nIndex) + throw (IndexOutOfBoundsException, RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenuItem::doAccessibleAction: called\n"); + return false; +} + +OUString ScAccessibleFilterMenuItem::getAccessibleActionDescription(sal_Int32 nIndex) + throw (IndexOutOfBoundsException, RuntimeException) +{ + return OUString::createFromAscii("Add some action here..."); +} + +Reference ScAccessibleFilterMenuItem::getAccessibleActionKeyBinding( + sal_Int32 nIndex) throw (IndexOutOfBoundsException, RuntimeException) +{ + return Reference(); +} + +Any SAL_CALL ScAccessibleFilterMenuItem::queryInterface( uno::Type const & rType ) + throw (RuntimeException) +{ + Any any = ScAccessibleContextBase::queryInterface(rType); + if (any.hasValue()) + return any; + + return ScAccessibleFilterMenuItem_BASE::queryInterface(rType); +} + +void SAL_CALL ScAccessibleFilterMenuItem::acquire() throw () +{ + ScAccessibleContextBase::acquire(); +} + +void SAL_CALL ScAccessibleFilterMenuItem::release() throw () +{ + ScAccessibleContextBase::release(); +} + +void ScAccessibleFilterMenuItem::select() +{ + mbSelected = true; + CommitFocusGained(); +} + +void ScAccessibleFilterMenuItem::unselect() +{ + mbSelected = false; + CommitFocusLost(); +} + +bool ScAccessibleFilterMenuItem::isSelected() const +{ + return mbSelected; +} + +void ScAccessibleFilterMenuItem::setEnabled(bool bEnabled) +{ + mbEnabled = bEnabled; +} + diff --git a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx new file mode 100644 index 000000000000..f0256b0abe9f --- /dev/null +++ b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove + +#include "precompiled_sc.hxx" +#include "AccessibleFilterTopWindow.hxx" +#include "AccessibleFilterMenu.hxx" +#include "dpcontrol.hxx" + +#include + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using ::com::sun::star::lang::IndexOutOfBoundsException; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::RuntimeException; +using ::rtl::OUString; + +ScAccessibleFilterTopWindow::ScAccessibleFilterTopWindow( + const Reference& rxParent, ScDPFieldPopupWindow* pWin, const OUString& rName, ScDocument* pDoc) : + ScAccessibleContextBase(rxParent, AccessibleRole::PANEL), + mpWindow(pWin), + mpDoc(pDoc) +{ + SetName(rName); +} + +ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow() +{ +} + +// XAccessibleContext + +sal_Int32 ScAccessibleFilterTopWindow::getAccessibleChildCount() throw (RuntimeException) +{ + return 2; +} + +Reference ScAccessibleFilterTopWindow::getAccessibleChild( + sal_Int32 nIndex) throw (RuntimeException, IndexOutOfBoundsException) +{ + if (nIndex >= 2) + throw IndexOutOfBoundsException(); + + if (nIndex == 0) + return getAccessibleChildMenu(); + + if (nIndex == 1) + return mxAccessibleListBox; + + return Reference(); +} + +OUString ScAccessibleFilterTopWindow::getImplementationName() throw (RuntimeException) +{ + return OUString::createFromAscii("ScAccessibleFilterTopWindow"); +} + +Reference ScAccessibleFilterTopWindow::getAccessibleChildMenu() +{ + if (!mxAccessibleMenu.is()) + mxAccessibleMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), mpDoc)); + return mxAccessibleMenu; +} + +void ScAccessibleFilterTopWindow::setAccessibleChildListBox(const Reference& rAccessible) +{ + mxAccessibleListBox = rAccessible; +} + diff --git a/sc/source/ui/Accessibility/makefile.mk b/sc/source/ui/Accessibility/makefile.mk index dfa5ac94b63f..0bde79f1f159 100644 --- a/sc/source/ui/Accessibility/makefile.mk +++ b/sc/source/ui/Accessibility/makefile.mk @@ -53,6 +53,9 @@ SLOFILES = \ $(SLO)$/AccessibleDocumentBase.obj \ $(SLO)$/AccessibleCellBase.obj \ $(SLO)$/AccessibleDocumentPagePreview.obj \ + $(SLO)$/AccessibleFilterMenu.obj \ + $(SLO)$/AccessibleFilterMenuItem.obj \ + $(SLO)$/AccessibleFilterTopWindow.obj \ $(SLO)$/AccessiblePreviewTable.obj \ $(SLO)$/AccessiblePreviewCell.obj \ $(SLO)$/AccessiblePreviewHeaderCell.obj \ @@ -73,6 +76,9 @@ EXCEPTIONSFILES= \ $(SLO)$/AccessibleDocumentBase.obj \ $(SLO)$/AccessibleCellBase.obj \ $(SLO)$/AccessibleDocumentPagePreview.obj \ + $(SLO)$/AccessibleFilterMenu.obj \ + $(SLO)$/AccessibleFilterMenuItem.obj \ + $(SLO)$/AccessibleFilterTopWindow.obj \ $(SLO)$/AccessiblePreviewTable.obj \ $(SLO)$/AccessiblePreviewCell.obj \ $(SLO)$/AccessiblePreviewHeaderCell.obj \ diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 0060a9341ec3..df8658eb1f6b 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -41,14 +41,86 @@ #include "vcl/wintypes.hxx" #include "vcl/decoview.hxx" #include "strload.hxx" +#include "global.hxx" + +#include "AccessibleFilterMenu.hxx" +#include "AccessibleFilterTopWindow.hxx" + +#include #define MENU_NOT_SELECTED 999 +using ::com::sun::star::uno::Reference; +using ::com::sun::star::accessibility::XAccessible; using ::rtl::OUString; using ::rtl::OUStringHash; using ::std::vector; using ::std::hash_map; using ::std::auto_ptr; +//using ::std::for_each; + + +#include +#include +#include + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + + void printTime(int line) const + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + +//namespace { +// +//class AppendAccessibleMenuItems : public ::std::unary_function +//{ +//public: +// explicit AppendAccessibleMenuItems(ScAccessibleFilterMenu* pAccMenu) : +// mnPos(0), mpAccMenu(pAccMenu) {} +// +// void operator() (const ScMenuFloatingWindow::MenuItem& rItem) +// { +// mpAccMenu->appendMenuItem(rItem.maText, rItem.mbEnabled, mnPos++); +// } +// +//private: +// size_t mnPos; +// ScAccessibleFilterMenu* mpAccMenu; +//}; +// +//} ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY) : mpOutDev(pOutDev), @@ -272,16 +344,19 @@ IMPL_LINK( ScMenuFloatingWindow::SubMenuItem, TimeoutHdl, void*, EMPTYARG ) // ---------------------------------------------------------------------------- -ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent) : +ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc) : FloatingWindow(pParent, (WB_SYSTEMFLOATWIN|WB_SYSTEMWINDOW|WB_NOBORDER)), maOpenTimer(this), maCloseTimer(this), + maName(OUString::createFromAscii("ScMenuFloatingWindow")), mnSelectedMenu(MENU_NOT_SELECTED), mnClickedMenu(MENU_NOT_SELECTED), + mpDoc(pDoc), mpParentMenu(dynamic_cast(pParent)), mpActiveSubMenu(NULL), mbActionFired(false) { + fprintf(stdout, "***** ScMenuFloatingWindow::ScMenuFloatingWindow: ctor (%p) parent = %p\n", this, pParent); // TODO: How do we get the right font to use here ? const sal_uInt16 nPopupFontHeight = 12; const StyleSettings& rStyle = GetSettings().GetStyleSettings(); @@ -289,6 +364,7 @@ ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent) : maLabelFont.SetHeight(nPopupFontHeight); SetFont(maLabelFont); + SetText(OUString::createFromAscii("ScMenuFloatingWindow")); SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, EndPopupHdl) ); } @@ -404,6 +480,30 @@ void ScMenuFloatingWindow::Paint(const Rectangle& /*rRect*/) drawAllMenuItems(); } +Reference ScMenuFloatingWindow::CreateAccessible() +{ + if (!mxAccessible.is()) + { + StackPrinter __stack_printer__("ScMenuFloatingWindow::CreateAccessible (create new)"); + Reference xAccParent = mpParentMenu ? + mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible(); + + mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, getDoc())); + ScAccessibleFilterMenu* p = static_cast( + mxAccessible.get()); + +// for_each(maMenuItems.begin(), maMenuItems.end(), AppendAccessibleMenuItems(p)); + vector::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end(); + for (itr = itrBeg; itr != itrEnd; ++itr) + { + size_t nPos = ::std::distance(itrBeg, itr); + p->appendMenuItem(itr->maText, itr->mbEnabled, nPos); + } + } + + return mxAccessible; +} + void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction) { MenuItem aItem; @@ -418,7 +518,8 @@ ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText MenuItem aItem; aItem.maText = rText; aItem.mbEnabled = bEnabled; - aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this)); + aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc)); + aItem.mpSubMenuWin->setName(rText); maMenuItems.push_back(aItem); return aItem.mpSubMenuWin.get(); } @@ -430,7 +531,7 @@ void ScMenuFloatingWindow::drawMenuItem(size_t nPos) Point aPos; Size aSize; - getMenuItemPosSize(aPos, aSize, nPos); + getMenuItemPosSize(nPos, aPos, aSize); DecorationView aDecoView(this); long nXOffset = 5; @@ -476,17 +577,19 @@ void ScMenuFloatingWindow::executeMenu(size_t nPos) EndPopupMode(); } -void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer) +void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bNotifyAccessible) { + StackPrinter __stack_printer__("******************** ScMenuFloatingWindow::setSelectedMenuItem ********************"); + fprintf(stdout, "ScMenuFloatingWindow::setSelectedMenuItem: pos = %d\n", nPos); if (mnSelectedMenu != nPos) { - selectMenuItem(mnSelectedMenu, false, bSubMenuTimer); - selectMenuItem(nPos, true, bSubMenuTimer); + selectMenuItem(mnSelectedMenu, false, bSubMenuTimer, bNotifyAccessible); + selectMenuItem(nPos, true, bSubMenuTimer, bNotifyAccessible); mnSelectedMenu = nPos; } } -size_t ScMenuFloatingWindow::getSelectedMenuItem() const +size_t ScMenuFloatingWindow::getSelectedMenuPos() const { return mnSelectedMenu; } @@ -563,7 +666,7 @@ void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos) { Point aPos; Size aSize; - getMenuItemPosSize(aPos, aSize, maOpenTimer.mnMenuPos); + getMenuItemPosSize(maOpenTimer.mnMenuPos, aPos, aSize); ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu; if (!pSubMenu) @@ -588,6 +691,21 @@ void ScMenuFloatingWindow::endSubMenu() } } +void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const +{ + vector::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end(); + for (itr = itrBeg; itr != itrEnd; ++itr) + { + size_t nPos = ::std::distance(itrBeg, itr); + pAccMenu->appendMenuItem(itr->maText, itr->mbEnabled, nPos); + } +} + +ScDocument* ScMenuFloatingWindow::getDoc() +{ + return mpDoc; +} + void ScMenuFloatingWindow::notify(NotificationType eType) { switch (eType) @@ -608,8 +726,9 @@ void ScMenuFloatingWindow::notify(NotificationType eType) void ScMenuFloatingWindow::resetMenu(bool bSetMenuPos) { - mnSelectedMenu = bSetMenuPos ? 0 : MENU_NOT_SELECTED; resizeToFitMenuItems(); + if (bSetMenuPos) + setSelectedMenuItem(0, false, true); } void ScMenuFloatingWindow::resizeToFitMenuItems() @@ -625,14 +744,15 @@ void ScMenuFloatingWindow::resizeToFitMenuItems() size_t nLastPos = maMenuItems.size()-1; Point aPos; Size aSize; - getMenuItemPosSize(aPos, aSize, nLastPos); + getMenuItemPosSize(nLastPos, aPos, aSize); aPos.X() += nTextWidth + 15; aPos.Y() += aSize.Height() + 5; SetOutputSizePixel(Size(aPos.X(), aPos.Y())); } -void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer) +void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer, bool bNotifyAccessible) { + fprintf(stdout, "ScMenuFloatingWindow::selectMenuItem: pos = %d selected = %d\n", nPos, bSelected); if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED) { queueCloseSubMenu(); @@ -663,6 +783,64 @@ void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSub queueCloseSubMenu(); } } + + if (bNotifyAccessible && mxAccessible.is()) + { + ScAccessibleFilterMenu* p = static_cast(mxAccessible.get()); + p->selectMenuItem(nPos, bSelected); + } +} + +void ScMenuFloatingWindow::clearSelectedMenuItem(bool bNotifyAccessible) +{ + selectMenuItem(mnSelectedMenu, false, false, bNotifyAccessible); + + if (bNotifyAccessible && mxAccessible.is()) + { + ScAccessibleFilterMenu* p = static_cast(mxAccessible.get()); + p->selectMenuItem(mnSelectedMenu, false); + } + + mnSelectedMenu = MENU_NOT_SELECTED; +} + +ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const +{ + if (maMenuItems.size() <= nPos) + return NULL; + + return maMenuItems[nPos].mpSubMenuWin.get(); +} + +size_t ScMenuFloatingWindow::getMenuItemCount() const +{ + return maMenuItems.size(); +} + +OUString ScMenuFloatingWindow::getMenuItemName(size_t nPos) const +{ + if (maMenuItems.size() <= nPos) + return ScGlobal::GetEmptyString(); + + return maMenuItems[nPos].maText; +} + +bool ScMenuFloatingWindow::isMenuItemEnabled(size_t nPos) const +{ + if (maMenuItems.size() <= nPos) + return false; + + return maMenuItems[nPos].mbEnabled; +} + +void ScMenuFloatingWindow::setName(const OUString& rName) +{ + maName = rName; +} + +const OUString& ScMenuFloatingWindow::getName() const +{ + return maName; } void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected) @@ -674,7 +852,7 @@ void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected) Point aPos; Size aSize; - getMenuItemPosSize(aPos, aSize, nPos); + getMenuItemPosSize(nPos, aPos, aSize); Region aRegion(Rectangle(aPos,aSize)); if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL)) @@ -717,7 +895,7 @@ void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected) drawMenuItem(nPos); } -void ScMenuFloatingWindow::getMenuItemPosSize(Point& rPos, Size& rSize, size_t nPos) const +void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const { const sal_uInt16 nLeftMargin = 5; const sal_uInt16 nTopMargin = 5; @@ -740,7 +918,7 @@ size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const { Point aPos; Size aSize; - getMenuItemPosSize(aPos, aSize, i); + getMenuItemPosSize(i, aPos, aSize); Rectangle aRect(aPos, aSize); if (aRect.IsInside(rPos)) return i; @@ -776,8 +954,8 @@ void ScDPFieldPopupWindow::CancelButton::Click() // ---------------------------------------------------------------------------- -ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : - ScMenuFloatingWindow(pParent), +ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc) : + ScMenuFloatingWindow(pParent, pDoc), maChecks(this, 0), maChkToggleAll(this, 0), maBtnSelectSingle (this, 0), @@ -1019,7 +1197,7 @@ void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt) { ScMenuFloatingWindow::MouseMove(rMEvt); - size_t nSelectedMenu = getSelectedMenuItem(); + size_t nSelectedMenu = getSelectedMenuPos(); if (nSelectedMenu == MENU_NOT_SELECTED) queueCloseSubMenu(); } @@ -1047,6 +1225,23 @@ void ScDPFieldPopupWindow::Paint(const Rectangle& rRect) DrawRect(Rectangle(aPos,aSize)); } +Reference ScDPFieldPopupWindow::CreateAccessible() +{ + if (!mxAccessible.is()) + { + mxAccessible.set(new ScAccessibleFilterTopWindow( + GetAccessibleParentWindow()->GetAccessible(), this, getName(), getDoc())); + ScAccessibleFilterTopWindow* pAccTop = static_cast(mxAccessible.get()); + Reference xAccMenu = pAccTop->getAccessibleChildMenu(); + ScAccessibleFilterMenu* pAccMenu = static_cast(xAccMenu.get()); + fillMenuItemsToAccessible(pAccMenu); + + pAccTop->setAccessibleChildListBox(maChecks.CreateAccessible()); + } + + return mxAccessible; +} + void ScDPFieldPopupWindow::setMemberSize(size_t n) { maMembers.reserve(n); diff --git a/sc/source/ui/inc/AccessibleContextBase.hxx b/sc/source/ui/inc/AccessibleContextBase.hxx index 8d312a0d13d9..c1ff5afcf52f 100644 --- a/sc/source/ui/inc/AccessibleContextBase.hxx +++ b/sc/source/ui/inc/AccessibleContextBase.hxx @@ -319,6 +319,8 @@ protected: /// Use this method to set initial Description without notification void SetDescription(const rtl::OUString& rDesc) { msDescription = rDesc; } + void SetRole(sal_Int16 nRole); + /// Reference to the parent object. ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> mxParent; diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 0074add2be25..72a7dc7a6970 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -44,11 +44,21 @@ #include #include +namespace com { namespace sun { namespace star { + + namespace accessibility { + class XAccessible; + } + +}}} + class OutputDevice; class Point; class Size; class StyleSettings; class Window; +class ScDocument; +class ScAccessibleFilterMenu; /** * This class takes care of physically drawing field button controls inside @@ -103,7 +113,7 @@ public: virtual void execute() = 0; }; - explicit ScMenuFloatingWindow(Window* pParent); + explicit ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc); virtual ~ScMenuFloatingWindow(); virtual void MouseMove(const MouseEvent& rMEvt); @@ -111,23 +121,42 @@ public: virtual void MouseButtonUp(const MouseEvent& rMEvt); virtual void KeyInput(const KeyEvent& rKEvt); virtual void Paint(const Rectangle& rRect); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible(); void addMenuItem(const ::rtl::OUString& rText, bool bEnabled, Action* pAction); ScMenuFloatingWindow* addSubMenuItem(const ::rtl::OUString& rText, bool bEnabled); + void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer = true, bool bNotifyAccessible = true); + void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer, bool bNotifyAccessible); + void clearSelectedMenuItem(bool bNotifyAccessible); + ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const; + size_t getMenuItemCount() const; + ::rtl::OUString getMenuItemName(size_t nPos) const; + bool isMenuItemEnabled(size_t nPos) const; + + void setName(const ::rtl::OUString& rName); + const ::rtl::OUString& getName() const; protected: + void drawMenuItem(size_t nPos); void drawAllMenuItems(); const Font& getLabelFont() const; void executeMenu(size_t nPos); - void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer = true); - size_t getSelectedMenuItem() const; + size_t getSelectedMenuPos() const; void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu); void queueCloseSubMenu(); void launchSubMenu(bool bSetMenuPos); void endSubMenu(); + void fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const; + + ScDocument* getDoc(); + +protected: + ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible > mxAccessible; + private: struct SubMenuItem; void handleMenuTimeout(SubMenuItem* pTimer); @@ -137,15 +166,15 @@ private: void resetMenu(bool bSetMenuPos); void resizeToFitMenuItems(); - void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer); void highlightMenuItem(size_t nPos, bool bSelected); - void getMenuItemPosSize(Point& rPos, Size& rSize, size_t nPos) const; + void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const; size_t getEnclosingMenuItem(const Point& rPos) const; DECL_LINK( EndPopupHdl, void* ); private: + struct MenuItem { ::rtl::OUString maText; @@ -178,9 +207,16 @@ private: Font maLabelFont; + // Name of this menu window, taken from the menu item of the parent window + // that launches it (if this is a sub menu). If this is a top-level menu + // window, then this name can be anything. + ::rtl::OUString maName; + size_t mnSelectedMenu; size_t mnClickedMenu; + ScDocument* mpDoc; + ScMenuFloatingWindow* mpParentMenu; ScMenuFloatingWindow* mpActiveSubMenu; @@ -202,11 +238,12 @@ public: */ struct ExtendedData {}; - explicit ScDPFieldPopupWindow(Window* pParent); + explicit ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc); virtual ~ScDPFieldPopupWindow(); virtual void MouseMove(const MouseEvent& rMEvt); virtual void Paint(const Rectangle& rRect); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible(); void setMemberSize(size_t n); void addMember(const ::rtl::OUString& rName, bool bVisible); diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index 8bafb474bff3..5a01a642ac24 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -911,7 +911,8 @@ void ScGridWindow::DPLaunchFieldPopupMenu( const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim]; - mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this)); + mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this, pViewData->GetDocument())); + mpDPFieldPopup->setName(OUString::createFromAscii("DataPilot field member popup")); mpDPFieldPopup->setExtendedData(pDPData.release()); mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this)); { -- cgit From fb89c0d1df93909faeaa080359e77b1f35eed572 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 20 Aug 2009 17:36:00 +0000 Subject: Added accessible objects for the remainder of the standard widgets. --- sc/inc/AccessibleFilterTopWindow.hxx | 30 +++++++++-- .../ui/Accessibility/AccessibleFilterTopWindow.cxx | 59 +++++++++++++++++----- sc/source/ui/cctrl/dpcontrol.cxx | 13 ++++- 3 files changed, 85 insertions(+), 17 deletions(-) (limited to 'sc') diff --git a/sc/inc/AccessibleFilterTopWindow.hxx b/sc/inc/AccessibleFilterTopWindow.hxx index 7b7ad0c880f0..f492c498b29a 100644 --- a/sc/inc/AccessibleFilterTopWindow.hxx +++ b/sc/inc/AccessibleFilterTopWindow.hxx @@ -63,15 +63,37 @@ public: ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChildMenu(); - void setAccessibleChildListBox( - const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& rAccessible); + enum ChildControlType { + LISTBOX, TOGGLE_ALL, SINGLE_ON_BTN, SINGLE_OFF_BTN, OK_BTN, CANCEL_BTN + }; + void setAccessibleChild( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& rAccessible, + ChildControlType eType); private: + /** The top menu part */ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > - mxAccessibleMenu; + mxAccMenu; + /** check list box for field member visibility */ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > - mxAccessibleListBox; + mxAccListBox; + + /** check box for toggling all field member's visibility. */ + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + mxAccToggleAll; + + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + mxAccSingleOnBtn; + + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + mxAccSingleOffBtn; + + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + mxAccOkBtn; + + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + mxAccCancelBtn; ScDPFieldPopupWindow* mpWindow; ScDocument* mpDoc; diff --git a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx index f0256b0abe9f..3e8ab00427b0 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx @@ -61,20 +61,34 @@ ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow() sal_Int32 ScAccessibleFilterTopWindow::getAccessibleChildCount() throw (RuntimeException) { - return 2; + return 7; } Reference ScAccessibleFilterTopWindow::getAccessibleChild( sal_Int32 nIndex) throw (RuntimeException, IndexOutOfBoundsException) { - if (nIndex >= 2) + if (nIndex >= 7) throw IndexOutOfBoundsException(); - if (nIndex == 0) - return getAccessibleChildMenu(); - - if (nIndex == 1) - return mxAccessibleListBox; + switch (nIndex) + { + case 0: + return getAccessibleChildMenu(); + case 1: + return mxAccListBox; + case 2: + return mxAccToggleAll; + case 3: + return mxAccSingleOnBtn; + case 4: + return mxAccSingleOffBtn; + case 5: + return mxAccOkBtn; + case 6: + return mxAccCancelBtn; + default: + ; + } return Reference(); } @@ -86,13 +100,34 @@ OUString ScAccessibleFilterTopWindow::getImplementationName() throw (RuntimeExce Reference ScAccessibleFilterTopWindow::getAccessibleChildMenu() { - if (!mxAccessibleMenu.is()) - mxAccessibleMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), mpDoc)); - return mxAccessibleMenu; + if (!mxAccMenu.is()) + mxAccMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), mpDoc)); + return mxAccMenu; } -void ScAccessibleFilterTopWindow::setAccessibleChildListBox(const Reference& rAccessible) +void ScAccessibleFilterTopWindow::setAccessibleChild( + const Reference& rAccessible, ChildControlType eType) { - mxAccessibleListBox = rAccessible; + switch (eType) + { + case LISTBOX: + mxAccListBox = rAccessible; + break; + case TOGGLE_ALL: + mxAccToggleAll = rAccessible; + break; + case SINGLE_ON_BTN: + mxAccSingleOnBtn = rAccessible; + break; + case SINGLE_OFF_BTN: + mxAccSingleOffBtn = rAccessible; + break; + case OK_BTN: + mxAccOkBtn = rAccessible; + break; + case CANCEL_BTN: + mxAccCancelBtn = rAccessible; + break; + } } diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index df8658eb1f6b..66915b3878e7 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -1236,7 +1236,18 @@ Reference ScDPFieldPopupWindow::CreateAccessible() ScAccessibleFilterMenu* pAccMenu = static_cast(xAccMenu.get()); fillMenuItemsToAccessible(pAccMenu); - pAccTop->setAccessibleChildListBox(maChecks.CreateAccessible()); + pAccTop->setAccessibleChild( + maChecks.CreateAccessible(), ScAccessibleFilterTopWindow::LISTBOX); + pAccTop->setAccessibleChild( + maChkToggleAll.CreateAccessible(), ScAccessibleFilterTopWindow::TOGGLE_ALL); + pAccTop->setAccessibleChild( + maBtnSelectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_ON_BTN); + pAccTop->setAccessibleChild( + maBtnUnselectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_OFF_BTN); + pAccTop->setAccessibleChild( + maBtnOk.CreateAccessible(), ScAccessibleFilterTopWindow::OK_BTN); + pAccTop->setAccessibleChild( + maBtnCancel.CreateAccessible(), ScAccessibleFilterTopWindow::CANCEL_BTN); } return mxAccessible; -- cgit From 4a08bf44d06f9e075ae578b062c01673eb7edf97 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 20 Aug 2009 20:23:05 +0000 Subject: removed all my printf statements. --- sc/inc/AccessibleFilterTopWindow.hxx | 3 +- .../ui/Accessibility/AccessibleFilterMenu.cxx | 80 +--------------------- .../ui/Accessibility/AccessibleFilterMenuItem.cxx | 50 -------------- sc/source/ui/cctrl/dpcontrol.cxx | 76 ++------------------ sc/source/ui/inc/dpcontrol.hxx | 2 +- 5 files changed, 9 insertions(+), 202 deletions(-) (limited to 'sc') diff --git a/sc/inc/AccessibleFilterTopWindow.hxx b/sc/inc/AccessibleFilterTopWindow.hxx index f492c498b29a..801d84d0c5fb 100644 --- a/sc/inc/AccessibleFilterTopWindow.hxx +++ b/sc/inc/AccessibleFilterTopWindow.hxx @@ -67,7 +67,8 @@ public: LISTBOX, TOGGLE_ALL, SINGLE_ON_BTN, SINGLE_OFF_BTN, OK_BTN, CANCEL_BTN }; void setAccessibleChild( - const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& rAccessible, + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible >& rAccessible, ChildControlType eType); private: diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx index 2ab7722807da..bbc3ab91e450 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx @@ -70,48 +70,6 @@ using ::std::for_each; using ::std::vector; using ::std::set; -#include -#include -#include - -namespace { - -class StackPrinter -{ -public: - explicit StackPrinter(const char* msg) : - msMsg(msg) - { - fprintf(stdout, "%s: --begin\n", msMsg.c_str()); - mfStartTime = getTime(); - } - - ~StackPrinter() - { - double fEndTime = getTime(); - fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); - } - - void printTime(int line) const - { - double fEndTime = getTime(); - fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); - } - -private: - double getTime() const - { - timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec + tv.tv_usec / 1000000.0; - } - - ::std::string msMsg; - double mfStartTime; -}; - -} - // ============================================================================ namespace { @@ -169,12 +127,7 @@ public: void operator() (ScAccessibleFilterMenu::MenuItem& rItem) { -// if (rItem.mbSelected) -// ++mnCount; -// ScAccessibleFilterMenuItem* p = static_cast(rItem.mxAccessible.get()); -// fprintf(stdout, "CountSelectedMenuItem::(): name = '%s' selected = %d\n", -// rtl::OUStringToOString(p->getAccessibleName(), RTL_TEXTENCODING_UTF8).getStr(), p->isSelected()); if (p->isSelected()) ++mnCount; } @@ -203,14 +156,11 @@ ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference& rxP mbEnabled(true), mbSelected(false) { - fprintf(stdout, "ScAccessibleFilterMenu::ScAccessibleFilterMenu: ctor (%p)\n", this); SetName(rName); -// SetDescription(OUString::createFromAscii("parent filter menu description")); } ScAccessibleFilterMenu::~ScAccessibleFilterMenu() { - fprintf(stdout, "ScAccessibleFilterMenu::~ScAccessibleFilterMenu: dtor (%p)\n", this); } // XAccessibleComponent @@ -218,33 +168,28 @@ ScAccessibleFilterMenu::~ScAccessibleFilterMenu() Reference ScAccessibleFilterMenu::getAccessibleAtPoint( const ::com::sun::star::awt::Point& rPoint ) throw (RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenu::getAccessibleAtPoint: point = (%ld,%ld)\n", rPoint.X, rPoint.Y); return this; } sal_Bool ScAccessibleFilterMenu::isVisible() throw (RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenu::isVisible: called\n"); return true; } void ScAccessibleFilterMenu::grabFocus() throw (RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenu::grabFocus: called\n"); } sal_Int32 ScAccessibleFilterMenu::getForeground() throw (RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenu::getForeground: called\n"); return 0; } sal_Int32 ScAccessibleFilterMenu::getBackground() throw (RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenu::getBackground: called\n"); return 0; } @@ -280,7 +225,7 @@ Reference ScAccessibleFilterMenu::getAccessibleStateSet() OUString ScAccessibleFilterMenu::getImplementationName() throw (RuntimeException) { - return OUString::createFromAscii("ScAccessibleFilterMenu - implementation name"); + return OUString::createFromAscii("ScAccessibleFilterMenu name"); } // XAccessibleEventBroadcaster @@ -334,7 +279,6 @@ sal_Bool ScAccessibleFilterMenu::containsAll(const Sequence& aStateSe Sequence ScAccessibleFilterMenu::getStates() throw (RuntimeException) { - StackPrinter __stack_printer__("ScAccessibleFilterMenu::getStates"); updateStates(); Sequence aSeq(0); set::const_iterator itr = maStates.begin(), itrEnd = maStates.end(); @@ -343,10 +287,6 @@ Sequence ScAccessibleFilterMenu::getStates() throw (RuntimeException) aSeq.realloc(i+1); aSeq[i] = *itr; } - if (maStates.count(FOCUSED)) - fprintf(stdout, "ScAccessibleFilterMenu::getStates: focused\n"); - else - fprintf(stdout, "ScAccessibleFilterMenu::getStates: not focused\n"); return aSeq; } @@ -355,8 +295,6 @@ Sequence ScAccessibleFilterMenu::getStates() throw (RuntimeException) void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException) { - StackPrinter __stack_printer__("********** ScAccessibleFilterMenu::selectAccessibleChild **********"); - fprintf(stdout, "ScAccessibleFilterMenu::selectAccessibleChild: index = %ld\n", nChildIndex); if (nChildIndex >= maMenuItems.size()) throw IndexOutOfBoundsException(); @@ -367,7 +305,6 @@ void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex) sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenu::isAccessibleChildSelected: index = %ld\n", nChildIndex); if (nChildIndex >= maMenuItems.size()) throw IndexOutOfBoundsException(); @@ -376,7 +313,6 @@ sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex void ScAccessibleFilterMenu::clearAccessibleSelection() throw (RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenu::clearAccessibleSelection: called\n"); for_each(maMenuItems.begin(), maMenuItems.end(), SelectMenuItem(false)); mpWindow->clearSelectedMenuItem(false); } @@ -384,22 +320,17 @@ void ScAccessibleFilterMenu::clearAccessibleSelection() throw (RuntimeException) void ScAccessibleFilterMenu::selectAllAccessibleChildren() throw (RuntimeException) { // not suported - this is a menu, you can't select all menu items. - -// fprintf(stdout, "ScAccessibleFilterMenu::selectAllAccessibleChildren: called\n"); -// for_each(maMenuItems.begin(), maMenuItems.end(), SelectMenuItem(true)); } sal_Int32 ScAccessibleFilterMenu::getSelectedAccessibleChildCount() throw (RuntimeException) { sal_Int32 n = for_each(maMenuItems.begin(), maMenuItems.end(), CountSelectedMenuItem()).getCount(); - fprintf(stdout, "ScAccessibleFilterMenu::getSelectedAccessibleChildCount: count = %ld\n", n); return n; } Reference ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenu::getSelectedAccessibleChild: index = %ld\n", nChildIndex); if (static_cast(nChildIndex) >= maMenuItems.size()) throw IndexOutOfBoundsException(); @@ -408,7 +339,6 @@ Reference ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_In void ScAccessibleFilterMenu::deselectAccessibleChild(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenu::deselectAccessibleChild: index = %ld\n", nChildIndex); if (static_cast(nChildIndex) >= maMenuItems.size()) throw IndexOutOfBoundsException(); @@ -453,8 +383,6 @@ Sequence ScAccessibleFilterMenu::getImplementationId() void ScAccessibleFilterMenu::selectMenuItem(size_t nIndex, bool bSelect) { - StackPrinter __stack_printer__("ScAccessibleFilterMenu::selectMenuItem"); - fprintf(stdout, "ScAccessibleFilterMenu::selectMenuItem: index = %d select = %d\n", nIndex, bSelect); if (maMenuItems.size() <= nIndex) return; @@ -471,8 +399,6 @@ void ScAccessibleFilterMenu::selectMenuItem(size_t nIndex, bool bSelect) p->unselect(); isSelected(); -// aEvent.EventId = AccessibleEventId::STATE_CHANGED; -// CommitChange(aEvent); } void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled, size_t nMenuPos) @@ -504,15 +430,13 @@ void ScAccessibleFilterMenu::setEnabled(bool bEnabled) bool ScAccessibleFilterMenu::isFocused() { - return true; -// return isSelected(); + return isSelected(); } bool ScAccessibleFilterMenu::isSelected() { // Check to see if any of the child menu items is selected. size_t nSelectCount = for_each(maMenuItems.begin(), maMenuItems.end(), CountSelectedMenuItem()).getCount(); -// fprintf(stdout, "ScAccessibleFilterMenu::isSelected: selected count = %d\n", nSelectCount); return nSelectCount == 0; } diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx index 2e151b67b600..45197df153ef 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx @@ -56,48 +56,6 @@ using ::com::sun::star::uno::RuntimeException; using ::rtl::OUString; using ::std::vector; -#include -#include -#include - -namespace { - -class StackPrinter -{ -public: - explicit StackPrinter(const char* msg) : - msMsg(msg) - { - fprintf(stdout, "%s: --begin\n", msMsg.c_str()); - mfStartTime = getTime(); - } - - ~StackPrinter() - { - double fEndTime = getTime(); - fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); - } - - void printTime(int line) const - { - double fEndTime = getTime(); - fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); - } - -private: - double getTime() const - { - timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec + tv.tv_usec / 1000000.0; - } - - ::std::string msMsg; - double mfStartTime; -}; - -} - ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem( const Reference& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos) : ScAccessibleContextBase(rxParent, AccessibleRole::MENU_ITEM), @@ -130,7 +88,6 @@ Reference ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 Reference ScAccessibleFilterMenuItem::getAccessibleStateSet() throw (RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenuItem::getAccessibleStateSet: called\n"); return this; } @@ -144,14 +101,12 @@ OUString ScAccessibleFilterMenuItem::getImplementationName() sal_Bool ScAccessibleFilterMenuItem::isEmpty() throw (RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenuItem::isEmpty: called\n"); return (mbEnabled || mbSelected); } sal_Bool ScAccessibleFilterMenuItem::contains(sal_Int16 nState) throw (RuntimeException) { using namespace ::com::sun::star::accessibility::AccessibleStateType; - fprintf(stdout, "ScAccessibleFilterMenuItem::contains: state = %d\n", nState); if (mbEnabled) { switch (nState) @@ -180,7 +135,6 @@ sal_Bool ScAccessibleFilterMenuItem::containsAll(const Sequence& aSta throw (RuntimeException) { using namespace ::com::sun::star::accessibility::AccessibleStateType; - fprintf(stdout, "ScAccessibleFilterMenuItem::containsAll: called\n"); sal_Int32 n = aStateSet.getLength(); for (sal_Int32 i = 0; i < n; ++i) { @@ -212,9 +166,6 @@ sal_Bool ScAccessibleFilterMenuItem::containsAll(const Sequence& aSta Sequence ScAccessibleFilterMenuItem::getStates() throw (RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenuItem::getStates: name = '%s' enabled = %d selected = %d\n", - rtl::OUStringToOString(getAccessibleName(), RTL_TEXTENCODING_UTF8).getStr(), - mbEnabled, mbSelected); using namespace ::com::sun::star::accessibility::AccessibleStateType; vector aStates; if (mbEnabled) @@ -249,7 +200,6 @@ sal_Int32 ScAccessibleFilterMenuItem::getAccessibleActionCount() throw (RuntimeE sal_Bool ScAccessibleFilterMenuItem::doAccessibleAction(sal_Int32 nIndex) throw (IndexOutOfBoundsException, RuntimeException) { - fprintf(stdout, "ScAccessibleFilterMenuItem::doAccessibleAction: called\n"); return false; } diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 66915b3878e7..685ead25b47e 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -57,70 +57,6 @@ using ::rtl::OUStringHash; using ::std::vector; using ::std::hash_map; using ::std::auto_ptr; -//using ::std::for_each; - - -#include -#include -#include - -namespace { - -class StackPrinter -{ -public: - explicit StackPrinter(const char* msg) : - msMsg(msg) - { - fprintf(stdout, "%s: --begin\n", msMsg.c_str()); - mfStartTime = getTime(); - } - - ~StackPrinter() - { - double fEndTime = getTime(); - fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); - } - - void printTime(int line) const - { - double fEndTime = getTime(); - fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); - } - -private: - double getTime() const - { - timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec + tv.tv_usec / 1000000.0; - } - - ::std::string msMsg; - double mfStartTime; -}; - -} - -//namespace { -// -//class AppendAccessibleMenuItems : public ::std::unary_function -//{ -//public: -// explicit AppendAccessibleMenuItems(ScAccessibleFilterMenu* pAccMenu) : -// mnPos(0), mpAccMenu(pAccMenu) {} -// -// void operator() (const ScMenuFloatingWindow::MenuItem& rItem) -// { -// mpAccMenu->appendMenuItem(rItem.maText, rItem.mbEnabled, mnPos++); -// } -// -//private: -// size_t mnPos; -// ScAccessibleFilterMenu* mpAccMenu; -//}; -// -//} ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY) : mpOutDev(pOutDev), @@ -344,7 +280,7 @@ IMPL_LINK( ScMenuFloatingWindow::SubMenuItem, TimeoutHdl, void*, EMPTYARG ) // ---------------------------------------------------------------------------- -ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc) : +ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel) : FloatingWindow(pParent, (WB_SYSTEMFLOATWIN|WB_SYSTEMWINDOW|WB_NOBORDER)), maOpenTimer(this), maCloseTimer(this), @@ -356,7 +292,8 @@ ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc) : mpActiveSubMenu(NULL), mbActionFired(false) { - fprintf(stdout, "***** ScMenuFloatingWindow::ScMenuFloatingWindow: ctor (%p) parent = %p\n", this, pParent); + SetMenuStackLevel(nMenuStackLevel); + // TODO: How do we get the right font to use here ? const sal_uInt16 nPopupFontHeight = 12; const StyleSettings& rStyle = GetSettings().GetStyleSettings(); @@ -484,7 +421,6 @@ Reference ScMenuFloatingWindow::CreateAccessible() { if (!mxAccessible.is()) { - StackPrinter __stack_printer__("ScMenuFloatingWindow::CreateAccessible (create new)"); Reference xAccParent = mpParentMenu ? mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible(); @@ -492,7 +428,6 @@ Reference ScMenuFloatingWindow::CreateAccessible() ScAccessibleFilterMenu* p = static_cast( mxAccessible.get()); -// for_each(maMenuItems.begin(), maMenuItems.end(), AppendAccessibleMenuItems(p)); vector::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end(); for (itr = itrBeg; itr != itrEnd; ++itr) { @@ -518,7 +453,7 @@ ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText MenuItem aItem; aItem.maText = rText; aItem.mbEnabled = bEnabled; - aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc)); + aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc, GetMenuStackLevel()+1)); aItem.mpSubMenuWin->setName(rText); maMenuItems.push_back(aItem); return aItem.mpSubMenuWin.get(); @@ -579,8 +514,6 @@ void ScMenuFloatingWindow::executeMenu(size_t nPos) void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bNotifyAccessible) { - StackPrinter __stack_printer__("******************** ScMenuFloatingWindow::setSelectedMenuItem ********************"); - fprintf(stdout, "ScMenuFloatingWindow::setSelectedMenuItem: pos = %d\n", nPos); if (mnSelectedMenu != nPos) { selectMenuItem(mnSelectedMenu, false, bSubMenuTimer, bNotifyAccessible); @@ -752,7 +685,6 @@ void ScMenuFloatingWindow::resizeToFitMenuItems() void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer, bool bNotifyAccessible) { - fprintf(stdout, "ScMenuFloatingWindow::selectMenuItem: pos = %d selected = %d\n", nPos, bSelected); if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED) { queueCloseSubMenu(); diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 72a7dc7a6970..0071be51fc9d 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -113,7 +113,7 @@ public: virtual void execute() = 0; }; - explicit ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc); + explicit ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel = 0); virtual ~ScMenuFloatingWindow(); virtual void MouseMove(const MouseEvent& rMEvt); -- cgit From e50abfc572a020718f9460d7f836b2c514b377d0 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 21 Aug 2009 00:12:46 +0000 Subject: Let's not duplicate menu's selected state with the accessible object; we can easily query the Window instance for that. This also fixed a crasher when accessing menus from accerciser. --- sc/inc/AccessibleFilterMenu.hxx | 6 +- sc/inc/AccessibleFilterMenuItem.hxx | 2 - .../ui/Accessibility/AccessibleFilterMenu.cxx | 105 ++++++++++++--------- .../ui/Accessibility/AccessibleFilterMenuItem.cxx | 24 ++--- .../ui/Accessibility/AccessibleFilterTopWindow.cxx | 4 +- sc/source/ui/cctrl/dpcontrol.cxx | 34 +++---- sc/source/ui/inc/dpcontrol.hxx | 7 +- 7 files changed, 88 insertions(+), 94 deletions(-) (limited to 'sc') diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx index 1489f3bbdca1..9579e5213cb0 100644 --- a/sc/inc/AccessibleFilterMenu.hxx +++ b/sc/inc/AccessibleFilterMenu.hxx @@ -73,7 +73,7 @@ public: ScAccessibleFilterMenu( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible>& rxParent, - ScMenuFloatingWindow* pWin, const ::rtl::OUString& rName, ScDocument* pDoc); + ScMenuFloatingWindow* pWin, const ::rtl::OUString& rName, size_t nMenuPos, ScDocument* pDoc); virtual ~ScAccessibleFilterMenu(); // XAccessibleComponent @@ -166,9 +166,8 @@ public: // non-UNO methods - void selectMenuItem(size_t nIndex, bool bSelect); void appendMenuItem(const ::rtl::OUString& rName, bool bEnabled, size_t nMenuPos); - + void setMenuPos(size_t nMenuPos); void setEnabled(bool bEnabled); private: @@ -181,6 +180,7 @@ private: ::std::vector maMenuItems; ::std::set maStates; + size_t mnMenuPos; ScMenuFloatingWindow* mpWindow; ScDocument* mpDoc; diff --git a/sc/inc/AccessibleFilterMenuItem.hxx b/sc/inc/AccessibleFilterMenuItem.hxx index 740cfd4e30c9..2dc6f954114a 100644 --- a/sc/inc/AccessibleFilterMenuItem.hxx +++ b/sc/inc/AccessibleFilterMenuItem.hxx @@ -94,8 +94,6 @@ public: // Non-UNO Methods - void select(); - void unselect(); bool isSelected() const; void setEnabled(bool bEnabled); diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx index bbc3ab91e450..3b2317b89515 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx @@ -70,28 +70,53 @@ using ::std::for_each; using ::std::vector; using ::std::set; -// ============================================================================ + +#include +#include +#include namespace { -class SelectMenuItem : public ::std::unary_function +class StackPrinter { public: - explicit SelectMenuItem(bool bSelect) : mbSelect(bSelect) {} + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } - void operator() (ScAccessibleFilterMenu::MenuItem& rItem) const + ~StackPrinter() { - rItem.mbSelected = mbSelect; - ScAccessibleFilterMenuItem* p = static_cast(rItem.mxAccessible.get()); - if (mbSelect) - p->select(); - else - p->unselect(); + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + + void printTime(int line) const + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); } + private: - bool mbSelect; + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; }; +} + +// ============================================================================ + +namespace { + class AddRemoveEventListener : public ::std::unary_function { public: @@ -143,29 +168,33 @@ private: // ============================================================================ ScAccessibleFilterMenu::MenuItem::MenuItem() : + mxAccessible(NULL), mbSelected(false) { } // ============================================================================ -ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, ScDocument* pDoc) : +ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos, ScDocument* pDoc) : ScAccessibleContextBase(rxParent, AccessibleRole::MENU), + mnMenuPos(nMenuPos), mpWindow(pWin), mpDoc(pDoc), mbEnabled(true), mbSelected(false) { + fprintf(stdout, "ScAccessibleFilterMenu::ScAccessibleFilterMenu: ctor (%p)\n", this); SetName(rName); } ScAccessibleFilterMenu::~ScAccessibleFilterMenu() { + fprintf(stdout, "ScAccessibleFilterMenu::~ScAccessibleFilterMenu: dtor (%p)\n", this); } // XAccessibleComponent -Reference ScAccessibleFilterMenu::getAccessibleAtPoint( const ::com::sun::star::awt::Point& rPoint ) +Reference ScAccessibleFilterMenu::getAccessibleAtPoint( const ::com::sun::star::awt::Point& /*rPoint*/ ) throw (RuntimeException) { return this; @@ -209,7 +238,7 @@ sal_Int32 ScAccessibleFilterMenu::getAccessibleChildCount() Reference ScAccessibleFilterMenu::getAccessibleChild(sal_Int32 nIndex) throw (RuntimeException, IndexOutOfBoundsException) { - if (maMenuItems.size() <= nIndex) + if (maMenuItems.size() <= static_cast(nIndex)) throw IndexOutOfBoundsException(); return maMenuItems[nIndex].mxAccessible; @@ -295,17 +324,17 @@ Sequence ScAccessibleFilterMenu::getStates() throw (RuntimeException) void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException) { - if (nChildIndex >= maMenuItems.size()) + if (static_cast(nChildIndex) >= maMenuItems.size()) throw IndexOutOfBoundsException(); maMenuItems[nChildIndex].mbSelected = true; - mpWindow->setSelectedMenuItem(nChildIndex, false, false); + mpWindow->setSelectedMenuItem(nChildIndex, false); } sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException) { - if (nChildIndex >= maMenuItems.size()) + if (static_cast(nChildIndex) >= maMenuItems.size()) throw IndexOutOfBoundsException(); return maMenuItems[nChildIndex].mbSelected; @@ -313,8 +342,7 @@ sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex void ScAccessibleFilterMenu::clearAccessibleSelection() throw (RuntimeException) { - for_each(maMenuItems.begin(), maMenuItems.end(), SelectMenuItem(false)); - mpWindow->clearSelectedMenuItem(false); + mpWindow->clearSelectedMenuItem(); } void ScAccessibleFilterMenu::selectAllAccessibleChildren() throw (RuntimeException) @@ -342,12 +370,7 @@ void ScAccessibleFilterMenu::deselectAccessibleChild(sal_Int32 nChildIndex) thro if (static_cast(nChildIndex) >= maMenuItems.size()) throw IndexOutOfBoundsException(); - maMenuItems[nChildIndex].mbSelected = false; - ScAccessibleFilterMenuItem* p = static_cast( - maMenuItems[nChildIndex].mxAccessible.get()); - p->unselect(); - - mpWindow->selectMenuItem(nChildIndex, false, false, false); + mpWindow->selectMenuItem(nChildIndex, false, false); } // XInterface @@ -381,28 +404,9 @@ Sequence ScAccessibleFilterMenu::getImplementationId() return aId; } -void ScAccessibleFilterMenu::selectMenuItem(size_t nIndex, bool bSelect) -{ - if (maMenuItems.size() <= nIndex) - return; - - AccessibleEventObject aEvent; - aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; - CommitChange(aEvent); - - maMenuItems[nIndex].mbSelected = bSelect; - ScAccessibleFilterMenuItem* p = static_cast( - maMenuItems[nIndex].mxAccessible.get()); - if (bSelect) - p->select(); - else - p->unselect(); - - isSelected(); -} - void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled, size_t nMenuPos) { +// StackPrinter __stack_printer__("ScAccessibleFilterMenu::appendMenuItem"); // Check weather this menu item is a sub menu or a regular menu item. ScMenuFloatingWindow* pSubMenu = mpWindow->getSubMenuWindow(nMenuPos); MenuItem aItem; @@ -412,6 +416,7 @@ void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled ScAccessibleFilterMenu* p = static_cast( aItem.mxAccessible.get()); p->setEnabled(bEnabled); + p->setMenuPos(nMenuPos); } else { @@ -423,6 +428,11 @@ void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled maMenuItems.push_back(aItem); } +void ScAccessibleFilterMenu::setMenuPos(size_t nMenuPos) +{ + mnMenuPos = nMenuPos; +} + void ScAccessibleFilterMenu::setEnabled(bool bEnabled) { mbEnabled = bEnabled; @@ -436,8 +446,9 @@ bool ScAccessibleFilterMenu::isFocused() bool ScAccessibleFilterMenu::isSelected() { // Check to see if any of the child menu items is selected. - size_t nSelectCount = for_each(maMenuItems.begin(), maMenuItems.end(), CountSelectedMenuItem()).getCount(); - return nSelectCount == 0; +// size_t nSelectCount = for_each(maMenuItems.begin(), maMenuItems.end(), CountSelectedMenuItem()).getCount(); +// return nSelectCount == 0; + return mpWindow->isMenuItemSelected(mnMenuPos); } void ScAccessibleFilterMenu::updateStates() diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx index 45197df153ef..414169854dc6 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx @@ -65,11 +65,13 @@ ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem( mbSelected(false), mbEnabled(true) { + fprintf(stdout, "ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem: ctor (%p)\n", this); SetName(rName); } ScAccessibleFilterMenuItem::~ScAccessibleFilterMenuItem() { + fprintf(stdout, "ScAccessibleFilterMenuItem::~ScAccessibleFilterMenuItem: dtor (%p)\n", this); } sal_Int32 ScAccessibleFilterMenuItem::getAccessibleChildCount() @@ -78,7 +80,7 @@ sal_Int32 ScAccessibleFilterMenuItem::getAccessibleChildCount() return 0; } -Reference ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 nIndex) +Reference ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 /*nIndex*/) throw (RuntimeException, IndexOutOfBoundsException) { throw IndexOutOfBoundsException(); @@ -197,20 +199,20 @@ sal_Int32 ScAccessibleFilterMenuItem::getAccessibleActionCount() throw (RuntimeE return 1; } -sal_Bool ScAccessibleFilterMenuItem::doAccessibleAction(sal_Int32 nIndex) +sal_Bool ScAccessibleFilterMenuItem::doAccessibleAction(sal_Int32 /*nIndex*/) throw (IndexOutOfBoundsException, RuntimeException) { return false; } -OUString ScAccessibleFilterMenuItem::getAccessibleActionDescription(sal_Int32 nIndex) +OUString ScAccessibleFilterMenuItem::getAccessibleActionDescription(sal_Int32 /*nIndex*/) throw (IndexOutOfBoundsException, RuntimeException) { return OUString::createFromAscii("Add some action here..."); } Reference ScAccessibleFilterMenuItem::getAccessibleActionKeyBinding( - sal_Int32 nIndex) throw (IndexOutOfBoundsException, RuntimeException) + sal_Int32 /*nIndex*/) throw (IndexOutOfBoundsException, RuntimeException) { return Reference(); } @@ -235,21 +237,9 @@ void SAL_CALL ScAccessibleFilterMenuItem::release() throw () ScAccessibleContextBase::release(); } -void ScAccessibleFilterMenuItem::select() -{ - mbSelected = true; - CommitFocusGained(); -} - -void ScAccessibleFilterMenuItem::unselect() -{ - mbSelected = false; - CommitFocusLost(); -} - bool ScAccessibleFilterMenuItem::isSelected() const { - return mbSelected; + return mpWindow->isMenuItemSelected(mnMenuPos); } void ScAccessibleFilterMenuItem::setEnabled(bool bEnabled) diff --git a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx index 3e8ab00427b0..02fafd87e138 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx @@ -50,11 +50,13 @@ ScAccessibleFilterTopWindow::ScAccessibleFilterTopWindow( mpWindow(pWin), mpDoc(pDoc) { + fprintf(stdout, "ScAccessibleFilterTopWindow::ScAccessibleFilterTopWindow: ctor (%p)\n", this); SetName(rName); } ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow() { + fprintf(stdout, "ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow: dtor (%p)\n", this); } // XAccessibleContext @@ -101,7 +103,7 @@ OUString ScAccessibleFilterTopWindow::getImplementationName() throw (RuntimeExce Reference ScAccessibleFilterTopWindow::getAccessibleChildMenu() { if (!mxAccMenu.is()) - mxAccMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), mpDoc)); + mxAccMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), 999, mpDoc)); return mxAccMenu; } diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 685ead25b47e..541d573f4e23 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -424,7 +424,7 @@ Reference ScMenuFloatingWindow::CreateAccessible() Reference xAccParent = mpParentMenu ? mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible(); - mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, getDoc())); + mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, 999, getDoc())); ScAccessibleFilterMenu* p = static_cast( mxAccessible.get()); @@ -512,12 +512,12 @@ void ScMenuFloatingWindow::executeMenu(size_t nPos) EndPopupMode(); } -void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bNotifyAccessible) +void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer) { if (mnSelectedMenu != nPos) { - selectMenuItem(mnSelectedMenu, false, bSubMenuTimer, bNotifyAccessible); - selectMenuItem(nPos, true, bSubMenuTimer, bNotifyAccessible); + selectMenuItem(mnSelectedMenu, false, bSubMenuTimer); + selectMenuItem(nPos, true, bSubMenuTimer); mnSelectedMenu = nPos; } } @@ -661,7 +661,7 @@ void ScMenuFloatingWindow::resetMenu(bool bSetMenuPos) { resizeToFitMenuItems(); if (bSetMenuPos) - setSelectedMenuItem(0, false, true); + setSelectedMenuItem(0, false); } void ScMenuFloatingWindow::resizeToFitMenuItems() @@ -683,7 +683,7 @@ void ScMenuFloatingWindow::resizeToFitMenuItems() SetOutputSizePixel(Size(aPos.X(), aPos.Y())); } -void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer, bool bNotifyAccessible) +void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer) { if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED) { @@ -715,24 +715,11 @@ void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSub queueCloseSubMenu(); } } - - if (bNotifyAccessible && mxAccessible.is()) - { - ScAccessibleFilterMenu* p = static_cast(mxAccessible.get()); - p->selectMenuItem(nPos, bSelected); - } } -void ScMenuFloatingWindow::clearSelectedMenuItem(bool bNotifyAccessible) +void ScMenuFloatingWindow::clearSelectedMenuItem() { - selectMenuItem(mnSelectedMenu, false, false, bNotifyAccessible); - - if (bNotifyAccessible && mxAccessible.is()) - { - ScAccessibleFilterMenu* p = static_cast(mxAccessible.get()); - p->selectMenuItem(mnSelectedMenu, false); - } - + selectMenuItem(mnSelectedMenu, false, false); mnSelectedMenu = MENU_NOT_SELECTED; } @@ -765,6 +752,11 @@ bool ScMenuFloatingWindow::isMenuItemEnabled(size_t nPos) const return maMenuItems[nPos].mbEnabled; } +bool ScMenuFloatingWindow::isMenuItemSelected(size_t nPos) const +{ + return nPos == mnSelectedMenu; +} + void ScMenuFloatingWindow::setName(const OUString& rName) { maName = rName; diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 0071be51fc9d..1e980a778434 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -125,13 +125,14 @@ public: void addMenuItem(const ::rtl::OUString& rText, bool bEnabled, Action* pAction); ScMenuFloatingWindow* addSubMenuItem(const ::rtl::OUString& rText, bool bEnabled); - void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer = true, bool bNotifyAccessible = true); - void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer, bool bNotifyAccessible); - void clearSelectedMenuItem(bool bNotifyAccessible); + void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer = true); + void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer); + void clearSelectedMenuItem(); ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const; size_t getMenuItemCount() const; ::rtl::OUString getMenuItemName(size_t nPos) const; bool isMenuItemEnabled(size_t nPos) const; + bool isMenuItemSelected(size_t nPos) const; void setName(const ::rtl::OUString& rName); const ::rtl::OUString& getName() const; -- cgit From 26d3db0ac1f3ba939716388cb881ae65ba4cb9e6 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 21 Aug 2009 00:23:14 +0000 Subject: removed debug statements & more dynamic type checking (this will be replaced later). --- sc/inc/AccessibleFilterMenu.hxx | 2 +- .../ui/Accessibility/AccessibleFilterMenu.cxx | 60 +++++----------------- 2 files changed, 14 insertions(+), 48 deletions(-) (limited to 'sc') diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx index 9579e5213cb0..cec3b1b8b8e9 100644 --- a/sc/inc/AccessibleFilterMenu.hxx +++ b/sc/inc/AccessibleFilterMenu.hxx @@ -169,10 +169,10 @@ public: void appendMenuItem(const ::rtl::OUString& rName, bool bEnabled, size_t nMenuPos); void setMenuPos(size_t nMenuPos); void setEnabled(bool bEnabled); + bool isSelected(); private: bool isFocused(); - bool isSelected(); void updateStates(); diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx index 3b2317b89515..4f4dd494da18 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx @@ -70,49 +70,6 @@ using ::std::for_each; using ::std::vector; using ::std::set; - -#include -#include -#include - -namespace { - -class StackPrinter -{ -public: - explicit StackPrinter(const char* msg) : - msMsg(msg) - { - fprintf(stdout, "%s: --begin\n", msMsg.c_str()); - mfStartTime = getTime(); - } - - ~StackPrinter() - { - double fEndTime = getTime(); - fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); - } - - void printTime(int line) const - { - double fEndTime = getTime(); - fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); - } - -private: - double getTime() const - { - timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec + tv.tv_usec / 1000000.0; - } - - ::std::string msMsg; - double mfStartTime; -}; - -} - // ============================================================================ namespace { @@ -152,9 +109,19 @@ public: void operator() (ScAccessibleFilterMenu::MenuItem& rItem) { - ScAccessibleFilterMenuItem* p = static_cast(rItem.mxAccessible.get()); - if (p->isSelected()) - ++mnCount; + { + ScAccessibleFilterMenuItem* p = dynamic_cast( + rItem.mxAccessible.get()); + if (p && p->isSelected()) + ++mnCount; + } + + { + ScAccessibleFilterMenu* p = dynamic_cast( + rItem.mxAccessible.get()); + if (p && p->isSelected()) + ++mnCount; + } } size_t getCount() const { return mnCount; } @@ -406,7 +373,6 @@ Sequence ScAccessibleFilterMenu::getImplementationId() void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled, size_t nMenuPos) { -// StackPrinter __stack_printer__("ScAccessibleFilterMenu::appendMenuItem"); // Check weather this menu item is a sub menu or a regular menu item. ScMenuFloatingWindow* pSubMenu = mpWindow->getSubMenuWindow(nMenuPos); MenuItem aItem; -- cgit From 656fd381e17fa494a678ce2b1306251d649eab3d Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 21 Aug 2009 00:35:37 +0000 Subject: Broke long method declarations into several lines. --- sc/inc/AccessibleFilterMenu.hxx | 37 ++++++++++++++++++++++++++---------- sc/inc/AccessibleFilterMenuItem.hxx | 38 ++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 19 deletions(-) (limited to 'sc') diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx index cec3b1b8b8e9..12faa7e848e3 100644 --- a/sc/inc/AccessibleFilterMenu.hxx +++ b/sc/inc/AccessibleFilterMenu.hxx @@ -131,24 +131,41 @@ public: // XAccessibleStateSet - virtual ::sal_Bool SAL_CALL isEmpty() throw (::com::sun::star::uno::RuntimeException); - virtual ::sal_Bool SAL_CALL contains(sal_Int16 nState) throw (::com::sun::star::uno::RuntimeException); - virtual ::sal_Bool SAL_CALL containsAll(const ::com::sun::star::uno::Sequence< ::sal_Int16 >& aStateSet) throw (::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Sequence SAL_CALL getStates() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isEmpty() throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL contains(sal_Int16 nState) + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL containsAll( + const ::com::sun::star::uno::Sequence& aStateSet) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence SAL_CALL getStates() + throw (::com::sun::star::uno::RuntimeException); // XAccessibleSelection - virtual void SAL_CALL selectAccessibleChild( ::sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); - virtual ::sal_Bool SAL_CALL isAccessibleChildSelected( ::sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL clearAccessibleSelection( ) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL selectAllAccessibleChildren( ) throw (::com::sun::star::uno::RuntimeException); - virtual ::sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectAccessibleChild(sal_Int32 nChildIndex) + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL isAccessibleChildSelected(sal_Int32 nChildIndex) + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL clearAccessibleSelection() + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL selectAllAccessibleChildren() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Int32 SAL_CALL getSelectedAccessibleChildCount() + throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild(sal_Int32 nChildIndex) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL deselectAccessibleChild( ::sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deselectAccessibleChild(sal_Int32 nChildIndex) + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); // XInterface diff --git a/sc/inc/AccessibleFilterMenuItem.hxx b/sc/inc/AccessibleFilterMenuItem.hxx index 2dc6f954114a..d4434da5f937 100644 --- a/sc/inc/AccessibleFilterMenuItem.hxx +++ b/sc/inc/AccessibleFilterMenuItem.hxx @@ -59,7 +59,8 @@ public: virtual sal_Int32 SAL_CALL getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild(sal_Int32 nIndex) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException); @@ -73,17 +74,36 @@ public: // XAccessibleStateSet - virtual ::sal_Bool SAL_CALL isEmpty() throw (::com::sun::star::uno::RuntimeException); - virtual ::sal_Bool SAL_CALL contains(sal_Int16 nState) throw (::com::sun::star::uno::RuntimeException); - virtual ::sal_Bool SAL_CALL containsAll(const ::com::sun::star::uno::Sequence< ::sal_Int16 >& aStateSet) throw (::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Sequence SAL_CALL getStates() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isEmpty() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Bool SAL_CALL contains(sal_Int16 nState) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Bool SAL_CALL containsAll( + const ::com::sun::star::uno::Sequence& aStateSet) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence SAL_CALL getStates() + throw (::com::sun::star::uno::RuntimeException); // XAccessibleAction - virtual ::sal_Int32 SAL_CALL getAccessibleActionCount( ) throw (::com::sun::star::uno::RuntimeException); - virtual ::sal_Bool SAL_CALL doAccessibleAction( ::sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); - virtual ::rtl::OUString SAL_CALL getAccessibleActionDescription( ::sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( ::sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getAccessibleActionCount() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Bool SAL_CALL doAccessibleAction(sal_Int32 nIndex) + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getAccessibleActionDescription(sal_Int32 nIndex) + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleKeyBinding > SAL_CALL + getAccessibleActionKeyBinding(sal_Int32 nIndex) + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + // XInterface virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( ::com::sun::star::uno::Type const & rType ) -- cgit From 4d56fc68ec3803dc6d009acaacd975f83384d5f8 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 21 Aug 2009 01:19:38 +0000 Subject: renamed structs. --- sc/source/ui/cctrl/dpcontrol.cxx | 24 ++++++++++++------------ sc/source/ui/inc/dpcontrol.hxx | 28 +++++++++++++++++++--------- 2 files changed, 31 insertions(+), 21 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 541d573f4e23..17f75371a306 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -247,7 +247,7 @@ void ScDPFieldButton::drawPopupButton() // ============================================================================ -ScMenuFloatingWindow::MenuItem::MenuItem() : +ScMenuFloatingWindow::MenuItemData::MenuItemData() : mbEnabled(true), mpAction(static_cast(NULL)), mpSubMenuWin(static_cast(NULL)) @@ -256,23 +256,23 @@ ScMenuFloatingWindow::MenuItem::MenuItem() : // ---------------------------------------------------------------------------- -ScMenuFloatingWindow::SubMenuItem::SubMenuItem(ScMenuFloatingWindow* pParent) : +ScMenuFloatingWindow::SubMenuItemData::SubMenuItemData(ScMenuFloatingWindow* pParent) : mpSubMenu(NULL), mnMenuPos(MENU_NOT_SELECTED), mpParent(pParent) { - maTimer.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItem, TimeoutHdl) ); + maTimer.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl) ); maTimer.SetTimeout(mpParent->GetSettings().GetMouseSettings().GetMenuDelay()); } -void ScMenuFloatingWindow::SubMenuItem::reset() +void ScMenuFloatingWindow::SubMenuItemData::reset() { mpSubMenu = NULL; mnMenuPos = MENU_NOT_SELECTED; maTimer.Stop(); } -IMPL_LINK( ScMenuFloatingWindow::SubMenuItem, TimeoutHdl, void*, EMPTYARG ) +IMPL_LINK( ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl, void*, EMPTYARG ) { mpParent->handleMenuTimeout(this); return 0; @@ -364,7 +364,7 @@ void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt) if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED) break; - const MenuItem& rMenu = maMenuItems[mnSelectedMenu]; + const MenuItemData& rMenu = maMenuItems[mnSelectedMenu]; if (!rMenu.mbEnabled || !rMenu.mpSubMenuWin) break; @@ -428,7 +428,7 @@ Reference ScMenuFloatingWindow::CreateAccessible() ScAccessibleFilterMenu* p = static_cast( mxAccessible.get()); - vector::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end(); + vector::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end(); for (itr = itrBeg; itr != itrEnd; ++itr) { size_t nPos = ::std::distance(itrBeg, itr); @@ -441,7 +441,7 @@ Reference ScMenuFloatingWindow::CreateAccessible() void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction) { - MenuItem aItem; + MenuItemData aItem; aItem.maText = rText; aItem.mbEnabled = bEnabled; aItem.mpAction.reset(pAction); @@ -450,7 +450,7 @@ void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Act ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText, bool bEnabled) { - MenuItem aItem; + MenuItemData aItem; aItem.maText = rText; aItem.mbEnabled = bEnabled; aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc, GetMenuStackLevel()+1)); @@ -527,7 +527,7 @@ size_t ScMenuFloatingWindow::getSelectedMenuPos() const return mnSelectedMenu; } -void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItem* pTimer) +void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItemData* pTimer) { if (pTimer == &maOpenTimer) { @@ -626,7 +626,7 @@ void ScMenuFloatingWindow::endSubMenu() void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const { - vector::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end(); + vector::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end(); for (itr = itrBeg; itr != itrEnd; ++itr) { size_t nPos = ::std::distance(itrBeg, itr); @@ -669,7 +669,7 @@ void ScMenuFloatingWindow::resizeToFitMenuItems() if (maMenuItems.empty()) return; - vector::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end(); + vector::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end(); long nTextWidth = 0; for (; itr != itrEnd; ++itr) nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth); diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 1e980a778434..bc131ae1c113 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -113,6 +113,16 @@ public: virtual void execute() = 0; }; + class MenuItem : public Window + { + public: + explicit MenuItem(Window* pParent); + + private: + bool mbSelected:1; + bool mbEnabled:1; + }; + explicit ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel = 0); virtual ~ScMenuFloatingWindow(); @@ -159,8 +169,8 @@ protected: ::com::sun::star::accessibility::XAccessible > mxAccessible; private: - struct SubMenuItem; - void handleMenuTimeout(SubMenuItem* pTimer); + struct SubMenuItemData; + void handleMenuTimeout(SubMenuItemData* pTimer); enum NotificationType { SUBMENU_FOCUSED }; void notify(NotificationType eType); @@ -176,7 +186,7 @@ private: private: - struct MenuItem + struct MenuItemData { ::rtl::OUString maText; bool mbEnabled; @@ -184,12 +194,12 @@ private: ::boost::shared_ptr mpAction; ::boost::shared_ptr mpSubMenuWin; - MenuItem(); + MenuItemData(); }; - ::std::vector maMenuItems; + ::std::vector maMenuItems; - struct SubMenuItem + struct SubMenuItemData { Timer maTimer; ScMenuFloatingWindow* mpSubMenu; @@ -197,14 +207,14 @@ private: DECL_LINK( TimeoutHdl, void* ); - SubMenuItem(ScMenuFloatingWindow* pParent); + SubMenuItemData(ScMenuFloatingWindow* pParent); void reset(); private: ScMenuFloatingWindow* mpParent; }; - SubMenuItem maOpenTimer; - SubMenuItem maCloseTimer; + SubMenuItemData maOpenTimer; + SubMenuItemData maCloseTimer; Font maLabelFont; -- cgit From 703de85908f24676c44a58b27644601edd4e357b Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 21 Aug 2009 04:29:45 +0000 Subject: remove the MenuItem class declaration - it was a wrong idea. --- sc/source/ui/inc/dpcontrol.hxx | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index bc131ae1c113..1c57089bf073 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -113,16 +113,6 @@ public: virtual void execute() = 0; }; - class MenuItem : public Window - { - public: - explicit MenuItem(Window* pParent); - - private: - bool mbSelected:1; - bool mbEnabled:1; - }; - explicit ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel = 0); virtual ~ScMenuFloatingWindow(); -- cgit From 4ac8aba5a707967c29fc19edeaf8aedc70b63097 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 21 Aug 2009 18:34:11 +0000 Subject: Ensure correct menu hierarchy when selecting an arbitrary menu item from the accessible object. --- .../ui/Accessibility/AccessibleFilterMenu.cxx | 2 +- sc/source/ui/cctrl/dpcontrol.cxx | 178 +++++++++++++++++---- sc/source/ui/inc/dpcontrol.hxx | 27 +++- 3 files changed, 166 insertions(+), 41 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx index 4f4dd494da18..c9342c4ec1c1 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx @@ -295,7 +295,7 @@ void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex) throw IndexOutOfBoundsException(); maMenuItems[nChildIndex].mbSelected = true; - mpWindow->setSelectedMenuItem(nChildIndex, false); + mpWindow->setSelectedMenuItem(nChildIndex, false, true); } sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex) diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 17f75371a306..10cec6fff069 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -58,6 +58,49 @@ using ::std::vector; using ::std::hash_map; using ::std::auto_ptr; + +#include +#include +#include + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + + void printTime(int line) const + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY) : mpOutDev(pOutDev), mpStyle(pStyle), @@ -314,7 +357,7 @@ void ScMenuFloatingWindow::MouseMove(const MouseEvent& rMEvt) { const Point& rPos = rMEvt.GetPosPixel(); size_t nSelectedMenu = getEnclosingMenuItem(rPos); - setSelectedMenuItem(nSelectedMenu); + setSelectedMenuItem(nSelectedMenu, true, false); Window::MouseMove(rMEvt); } @@ -346,14 +389,14 @@ void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt) nSelectedMenu = nLastMenuPos; else --nSelectedMenu; - setSelectedMenuItem(nSelectedMenu, false); + setSelectedMenuItem(nSelectedMenu, false, false); break; case KEY_DOWN: if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == nLastMenuPos) nSelectedMenu = 0; else ++nSelectedMenu; - setSelectedMenuItem(nSelectedMenu, false); + setSelectedMenuItem(nSelectedMenu, false, false); break; case KEY_LEFT: if (mpParentMenu) @@ -512,14 +555,35 @@ void ScMenuFloatingWindow::executeMenu(size_t nPos) EndPopupMode(); } -void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer) +void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu) { - if (mnSelectedMenu != nPos) + StackPrinter __stack_printer__("ScMenuFloatingWindow::setSelectedMenuItem"); + if (mnSelectedMenu == nPos) + // nothing to do. + return; + + if (bEnsureSubMenu) { - selectMenuItem(mnSelectedMenu, false, bSubMenuTimer); - selectMenuItem(nPos, true, bSubMenuTimer); - mnSelectedMenu = nPos; + fprintf(stdout, "ScMenuFloatingWindow::setSelectedMenuItem: (ensuring...) selected menu = %d\n", mnSelectedMenu); + // Dismiss any child popup menu windows. + if (mnSelectedMenu < maMenuItems.size() && + maMenuItems[mnSelectedMenu].mpSubMenuWin && + maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible()) + { + maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible(); + } + + // The popup is not visible, yet a menu item is selected. The request + // most likely comes from the accessible object. Make sure this + // window, as well as all its parent windows are visible. + if (!IsVisible() && mpParentMenu) + mpParentMenu->ensureSubMenuVisible(this); } + + selectMenuItem(mnSelectedMenu, false, bSubMenuTimer); + selectMenuItem(nPos, true, bSubMenuTimer); + mnSelectedMenu = nPos; + fprintf(stdout, "ScMenuFloatingWindow::setSelectedMenuItem: selected menu = %d\n", mnSelectedMenu); } size_t ScMenuFloatingWindow::getSelectedMenuPos() const @@ -607,10 +671,12 @@ void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos) sal_uInt32 nOldFlags = GetPopupModeFlags(); SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE); - pSubMenu->resetMenu(bSetMenuPos); + pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly. pSubMenu->StartPopupMode( Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS)); pSubMenu->AddPopupModeWindow(this); + if (bSetMenuPos) + pSubMenu->setSelectedMenuItem(0, false, false); // select menu item after the popup becomes fully visible. SetPopupModeFlags(nOldFlags); } @@ -639,31 +705,6 @@ ScDocument* ScMenuFloatingWindow::getDoc() return mpDoc; } -void ScMenuFloatingWindow::notify(NotificationType eType) -{ - switch (eType) - { - case SUBMENU_FOCUSED: - // Cancel any request for ending submenu. - maCloseTimer.reset(); - if (mnSelectedMenu != maOpenTimer.mnMenuPos) - { - highlightMenuItem(maOpenTimer.mnMenuPos, true); - mnSelectedMenu = maOpenTimer.mnMenuPos; - } - break; - default: - ; - } -} - -void ScMenuFloatingWindow::resetMenu(bool bSetMenuPos) -{ - resizeToFitMenuItems(); - if (bSetMenuPos) - setSelectedMenuItem(0, false); -} - void ScMenuFloatingWindow::resizeToFitMenuItems() { if (maMenuItems.empty()) @@ -702,7 +743,7 @@ void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSub if (bSelected) { if (mpParentMenu) - mpParentMenu->notify(SUBMENU_FOCUSED); + mpParentMenu->setSubMenuFocused(this); if (bSubMenuTimer) { @@ -721,6 +762,7 @@ void ScMenuFloatingWindow::clearSelectedMenuItem() { selectMenuItem(mnSelectedMenu, false, false); mnSelectedMenu = MENU_NOT_SELECTED; + fprintf(stdout, "ScMenuFloatingWindow::clearSelectedMenuItem: here\n"); } ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const @@ -769,6 +811,9 @@ const OUString& ScMenuFloatingWindow::getName() const void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected) { + if (nPos == MENU_NOT_SELECTED) + return; + const StyleSettings& rStyle = GetSettings().GetStyleSettings(); Color aBackColor = rStyle.GetMenuColor(); SetFillColor(aBackColor); @@ -850,6 +895,69 @@ size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const return MENU_NOT_SELECTED; } +size_t ScMenuFloatingWindow::getSubMenuPos(ScMenuFloatingWindow* pSubMenu) +{ + size_t n = maMenuItems.size(); + for (size_t i = 0; i < n; ++i) + { + if (maMenuItems[i].mpSubMenuWin.get() == pSubMenu) + return i; + } + return MENU_NOT_SELECTED; +} + +void ScMenuFloatingWindow::setSubMenuFocused(ScMenuFloatingWindow* pSubMenu) +{ + maCloseTimer.reset(); + size_t nMenuPos = getSubMenuPos(pSubMenu); + if (mnSelectedMenu != nMenuPos) + { + highlightMenuItem(nMenuPos, true); + mnSelectedMenu = nMenuPos; + } +} + +void ScMenuFloatingWindow::ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu) +{ + StackPrinter __stack_printer__("ScMenuFloatingWindow::ensureSubMenuVisible"); + if (mpParentMenu) + mpParentMenu->ensureSubMenuVisible(this); + + if (pSubMenu->IsVisible()) + return; + + // Find the menu position of the submenu. + size_t nMenuPos = getSubMenuPos(pSubMenu); + if (nMenuPos != MENU_NOT_SELECTED) + { + setSelectedMenuItem(nMenuPos, false, false); + + Point aPos; + Size aSize; + getMenuItemPosSize(nMenuPos, aPos, aSize); + + sal_uInt32 nOldFlags = GetPopupModeFlags(); + SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE); + pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly. + pSubMenu->StartPopupMode( + Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS)); + pSubMenu->AddPopupModeWindow(this); + SetPopupModeFlags(nOldFlags); + } +} + +void ScMenuFloatingWindow::ensureSubMenuNotVisible() +{ + if (mnSelectedMenu <= maMenuItems.size() && + maMenuItems[mnSelectedMenu].mpSubMenuWin && + maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible()) + { + maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible(); + } + + EndPopupMode(); +} + IMPL_LINK( ScMenuFloatingWindow, EndPopupHdl, void*, EMPTYARG ) { if (mbActionFired && mpParentMenu) diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 1c57089bf073..29a39547b88c 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -125,7 +125,7 @@ public: void addMenuItem(const ::rtl::OUString& rText, bool bEnabled, Action* pAction); ScMenuFloatingWindow* addSubMenuItem(const ::rtl::OUString& rText, bool bEnabled); - void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer = true); + void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu); void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer); void clearSelectedMenuItem(); ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const; @@ -162,15 +162,32 @@ private: struct SubMenuItemData; void handleMenuTimeout(SubMenuItemData* pTimer); - enum NotificationType { SUBMENU_FOCUSED }; - void notify(NotificationType eType); - - void resetMenu(bool bSetMenuPos); void resizeToFitMenuItems(); void highlightMenuItem(size_t nPos, bool bSelected); void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const; size_t getEnclosingMenuItem(const Point& rPos) const; + size_t getSubMenuPos(ScMenuFloatingWindow* pSubMenu); + + /** + * Make sure that the specified submenu is permanently up, the submenu + * close timer is not active, and the correct menu item associated with + * the submenu is highlighted. + */ + void setSubMenuFocused(ScMenuFloatingWindow* pSubMenu); + + /** + * When a menu item of an invisible submenu is selected, we need to make + * sure that all its parent menu(s) are visible, with the right menu item + * highlighted in each of the parents. Calling this method ensures it. + */ + void ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu); + + /** + * Dismiss any visible child submenus when a menu item of a parent menu is + * selected. + */ + void ensureSubMenuNotVisible(); DECL_LINK( EndPopupHdl, void* ); -- cgit From 2a2abd3243d8c46612970595a6e6836d7e4e7f0a Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 21 Aug 2009 18:35:29 +0000 Subject: forgot to remove debug statements. --- .../ui/Accessibility/AccessibleFilterMenu.cxx | 2 - sc/source/ui/cctrl/dpcontrol.cxx | 48 ---------------------- 2 files changed, 50 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx index c9342c4ec1c1..9df813886dc5 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx @@ -150,13 +150,11 @@ ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference& rxP mbEnabled(true), mbSelected(false) { - fprintf(stdout, "ScAccessibleFilterMenu::ScAccessibleFilterMenu: ctor (%p)\n", this); SetName(rName); } ScAccessibleFilterMenu::~ScAccessibleFilterMenu() { - fprintf(stdout, "ScAccessibleFilterMenu::~ScAccessibleFilterMenu: dtor (%p)\n", this); } // XAccessibleComponent diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 10cec6fff069..3d51baf73a96 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -58,49 +58,6 @@ using ::std::vector; using ::std::hash_map; using ::std::auto_ptr; - -#include -#include -#include - -namespace { - -class StackPrinter -{ -public: - explicit StackPrinter(const char* msg) : - msMsg(msg) - { - fprintf(stdout, "%s: --begin\n", msMsg.c_str()); - mfStartTime = getTime(); - } - - ~StackPrinter() - { - double fEndTime = getTime(); - fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); - } - - void printTime(int line) const - { - double fEndTime = getTime(); - fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); - } - -private: - double getTime() const - { - timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec + tv.tv_usec / 1000000.0; - } - - ::std::string msMsg; - double mfStartTime; -}; - -} - ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY) : mpOutDev(pOutDev), mpStyle(pStyle), @@ -557,14 +514,12 @@ void ScMenuFloatingWindow::executeMenu(size_t nPos) void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu) { - StackPrinter __stack_printer__("ScMenuFloatingWindow::setSelectedMenuItem"); if (mnSelectedMenu == nPos) // nothing to do. return; if (bEnsureSubMenu) { - fprintf(stdout, "ScMenuFloatingWindow::setSelectedMenuItem: (ensuring...) selected menu = %d\n", mnSelectedMenu); // Dismiss any child popup menu windows. if (mnSelectedMenu < maMenuItems.size() && maMenuItems[mnSelectedMenu].mpSubMenuWin && @@ -583,7 +538,6 @@ void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, selectMenuItem(mnSelectedMenu, false, bSubMenuTimer); selectMenuItem(nPos, true, bSubMenuTimer); mnSelectedMenu = nPos; - fprintf(stdout, "ScMenuFloatingWindow::setSelectedMenuItem: selected menu = %d\n", mnSelectedMenu); } size_t ScMenuFloatingWindow::getSelectedMenuPos() const @@ -762,7 +716,6 @@ void ScMenuFloatingWindow::clearSelectedMenuItem() { selectMenuItem(mnSelectedMenu, false, false); mnSelectedMenu = MENU_NOT_SELECTED; - fprintf(stdout, "ScMenuFloatingWindow::clearSelectedMenuItem: here\n"); } ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const @@ -919,7 +872,6 @@ void ScMenuFloatingWindow::setSubMenuFocused(ScMenuFloatingWindow* pSubMenu) void ScMenuFloatingWindow::ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu) { - StackPrinter __stack_printer__("ScMenuFloatingWindow::ensureSubMenuVisible"); if (mpParentMenu) mpParentMenu->ensureSubMenuVisible(this); -- cgit From b6391fb9131b4f345e048cb7c5d7967bd62752a0 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 21 Aug 2009 18:40:05 +0000 Subject: more debug statements removed. --- sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx | 2 -- 1 file changed, 2 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx index 414169854dc6..86bf18551d14 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx @@ -65,13 +65,11 @@ ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem( mbSelected(false), mbEnabled(true) { - fprintf(stdout, "ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem: ctor (%p)\n", this); SetName(rName); } ScAccessibleFilterMenuItem::~ScAccessibleFilterMenuItem() { - fprintf(stdout, "ScAccessibleFilterMenuItem::~ScAccessibleFilterMenuItem: dtor (%p)\n", this); } sal_Int32 ScAccessibleFilterMenuItem::getAccessibleChildCount() -- cgit From ed33032301907f6888b49cacb61ec10f78dee9ae Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 21 Aug 2009 19:03:06 +0000 Subject: Supported execution of menu items from the accessible object. --- sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx | 5 +++-- sc/source/ui/cctrl/dpcontrol.cxx | 6 +++--- sc/source/ui/inc/dpcontrol.hxx | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx index 86bf18551d14..42c16e6154f4 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx @@ -200,13 +200,14 @@ sal_Int32 ScAccessibleFilterMenuItem::getAccessibleActionCount() throw (RuntimeE sal_Bool ScAccessibleFilterMenuItem::doAccessibleAction(sal_Int32 /*nIndex*/) throw (IndexOutOfBoundsException, RuntimeException) { - return false; + mpWindow->executeMenuItem(mnMenuPos); + return true; } OUString ScAccessibleFilterMenuItem::getAccessibleActionDescription(sal_Int32 /*nIndex*/) throw (IndexOutOfBoundsException, RuntimeException) { - return OUString::createFromAscii("Add some action here..."); + return OUString::createFromAscii("click"); } Reference ScAccessibleFilterMenuItem::getAccessibleActionKeyBinding( diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 3d51baf73a96..bcf01317d3de 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -328,7 +328,7 @@ void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent& rMEvt) void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent& rMEvt) { - executeMenu(mnClickedMenu); + executeMenuItem(mnClickedMenu); mnClickedMenu = MENU_NOT_SELECTED; Window::MouseButtonUp(rMEvt); } @@ -375,7 +375,7 @@ void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt) break; case KEY_RETURN: if (nSelectedMenu != MENU_NOT_SELECTED) - executeMenu(nSelectedMenu); + executeMenuItem(nSelectedMenu); break; default: bHandled = false; @@ -498,7 +498,7 @@ const Font& ScMenuFloatingWindow::getLabelFont() const return maLabelFont; } -void ScMenuFloatingWindow::executeMenu(size_t nPos) +void ScMenuFloatingWindow::executeMenuItem(size_t nPos) { if (nPos >= maMenuItems.size()) return; diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 29a39547b88c..e4fe0e6378ca 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -137,13 +137,14 @@ public: void setName(const ::rtl::OUString& rName); const ::rtl::OUString& getName() const; + void executeMenuItem(size_t nPos); + protected: void drawMenuItem(size_t nPos); void drawAllMenuItems(); const Font& getLabelFont() const; - void executeMenu(size_t nPos); size_t getSelectedMenuPos() const; void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu); void queueCloseSubMenu(); -- cgit From 9dffba7f4b3e7bb139993ab7e94b6c20965ef9ab Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 21 Aug 2009 19:17:39 +0000 Subject: When a menu action is fired via accessible object, we need to make sure that all the popup windows get dismissed. --- sc/source/ui/cctrl/dpcontrol.cxx | 15 ++++++--------- sc/source/ui/inc/dpcontrol.hxx | 8 +++++--- 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index bcf01317d3de..cd7aca9acc2f 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -289,8 +289,7 @@ ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, US mnClickedMenu(MENU_NOT_SELECTED), mpDoc(pDoc), mpParentMenu(dynamic_cast(pParent)), - mpActiveSubMenu(NULL), - mbActionFired(false) + mpActiveSubMenu(NULL) { SetMenuStackLevel(nMenuStackLevel); @@ -508,8 +507,7 @@ void ScMenuFloatingWindow::executeMenuItem(size_t nPos) return; maMenuItems[nPos].mpAction->execute(); - mbActionFired = true; - EndPopupMode(); + terminateAllPopupMenus(); } void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu) @@ -910,12 +908,11 @@ void ScMenuFloatingWindow::ensureSubMenuNotVisible() EndPopupMode(); } -IMPL_LINK( ScMenuFloatingWindow, EndPopupHdl, void*, EMPTYARG ) +void ScMenuFloatingWindow::terminateAllPopupMenus() { - if (mbActionFired && mpParentMenu) - mpParentMenu->EndPopupMode(); - - return 0; + EndPopupMode(); + if (mpParentMenu) + mpParentMenu->terminateAllPopupMenus(); } // ============================================================================ diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index e4fe0e6378ca..55afc0470c64 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -190,7 +190,11 @@ private: */ void ensureSubMenuNotVisible(); - DECL_LINK( EndPopupHdl, void* ); + /** + * Dismiss all visible popup menus and set focus back to the application + * window. This method is called e.g. when a menu action is fired. + */ + void terminateAllPopupMenus(); private: @@ -238,8 +242,6 @@ private: ScMenuFloatingWindow* mpParentMenu; ScMenuFloatingWindow* mpActiveSubMenu; - - bool mbActionFired; }; // ============================================================================ -- cgit From 514d004f7422f4103d8574b7339c22345a5e6c7c Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 21 Aug 2009 20:19:55 +0000 Subject: fixed a build breakage. --- sc/source/ui/cctrl/dpcontrol.cxx | 1 - 1 file changed, 1 deletion(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index cd7aca9acc2f..ab3123718d40 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -301,7 +301,6 @@ ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, US SetFont(maLabelFont); SetText(OUString::createFromAscii("ScMenuFloatingWindow")); - SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, EndPopupHdl) ); } ScMenuFloatingWindow::~ScMenuFloatingWindow() -- cgit From aa18040a8e2db3b1c51e6de4ea34f73efa96a447 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Sat, 22 Aug 2009 03:13:19 +0000 Subject: code cleanup. --- sc/inc/AccessibleFilterMenu.hxx | 14 +--- .../ui/Accessibility/AccessibleFilterMenu.cxx | 86 +++++----------------- sc/source/ui/cctrl/dpcontrol.cxx | 10 ++- sc/source/ui/inc/dpcontrol.hxx | 3 +- 4 files changed, 30 insertions(+), 83 deletions(-) (limited to 'sc') diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx index 12faa7e848e3..c5049045d672 100644 --- a/sc/inc/AccessibleFilterMenu.hxx +++ b/sc/inc/AccessibleFilterMenu.hxx @@ -61,16 +61,7 @@ class ScAccessibleFilterMenu : public ScAccessibleFilterMenu_BASE { public: - struct MenuItem - { - ::com::sun::star::uno::Reference< - ::com::sun::star::accessibility::XAccessible > mxAccessible; - bool mbSelected; - - MenuItem(); - }; - - ScAccessibleFilterMenu( + explicit ScAccessibleFilterMenu( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const ::rtl::OUString& rName, size_t nMenuPos, ScDocument* pDoc); @@ -194,7 +185,7 @@ private: void updateStates(); private: - ::std::vector maMenuItems; + ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > > maMenuItems; ::std::set maStates; size_t mnMenuPos; @@ -202,7 +193,6 @@ private: ScDocument* mpDoc; bool mbEnabled:1; - bool mbSelected:1; }; #endif diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx index 9df813886dc5..5a1253181a8f 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx @@ -74,18 +74,18 @@ using ::std::set; namespace { -class AddRemoveEventListener : public ::std::unary_function +class AddRemoveEventListener : public ::std::unary_function > { public: explicit AddRemoveEventListener(const Reference& rListener, bool bAdd) : mxListener(rListener), mbAdd(bAdd) {} - void operator() (ScAccessibleFilterMenu::MenuItem& rItem) const + void operator() (const Reference& xAccessible) const { - if (!rItem.mxAccessible.is()) + if (!xAccessible.is()) return; - Reference xBc(rItem.mxAccessible, UNO_QUERY); + Reference xBc(xAccessible, UNO_QUERY); if (xBc.is()) { if (mbAdd) @@ -99,45 +99,6 @@ private: bool mbAdd; }; -class CountSelectedMenuItem : public ::std::unary_function -{ -public: - explicit CountSelectedMenuItem() : mnCount(0) {} - - CountSelectedMenuItem(const CountSelectedMenuItem& r) : - mnCount(r.mnCount) {} - - void operator() (ScAccessibleFilterMenu::MenuItem& rItem) - { - { - ScAccessibleFilterMenuItem* p = dynamic_cast( - rItem.mxAccessible.get()); - if (p && p->isSelected()) - ++mnCount; - } - - { - ScAccessibleFilterMenu* p = dynamic_cast( - rItem.mxAccessible.get()); - if (p && p->isSelected()) - ++mnCount; - } - } - - size_t getCount() const { return mnCount; } - -private: - size_t mnCount; -}; - -} - -// ============================================================================ - -ScAccessibleFilterMenu::MenuItem::MenuItem() : - mxAccessible(NULL), - mbSelected(false) -{ } // ============================================================================ @@ -147,8 +108,7 @@ ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference& rxP mnMenuPos(nMenuPos), mpWindow(pWin), mpDoc(pDoc), - mbEnabled(true), - mbSelected(false) + mbEnabled(true) { SetName(rName); } @@ -167,7 +127,7 @@ Reference ScAccessibleFilterMenu::getAccessibleAtPoint( const ::com sal_Bool ScAccessibleFilterMenu::isVisible() throw (RuntimeException) { - return true; + return mpWindow->IsVisible(); } void ScAccessibleFilterMenu::grabFocus() @@ -206,7 +166,7 @@ Reference ScAccessibleFilterMenu::getAccessibleChild(sal_Int32 nInd if (maMenuItems.size() <= static_cast(nIndex)) throw IndexOutOfBoundsException(); - return maMenuItems[nIndex].mxAccessible; + return maMenuItems[nIndex]; } Reference ScAccessibleFilterMenu::getAccessibleStateSet() @@ -219,7 +179,7 @@ Reference ScAccessibleFilterMenu::getAccessibleStateSet() OUString ScAccessibleFilterMenu::getImplementationName() throw (RuntimeException) { - return OUString::createFromAscii("ScAccessibleFilterMenu name"); + return OUString::createFromAscii("ScAccessibleFilterMenu"); } // XAccessibleEventBroadcaster @@ -246,20 +206,17 @@ void ScAccessibleFilterMenu::removeEventListener( sal_Bool ScAccessibleFilterMenu::isEmpty() throw (RuntimeException) { - updateStates(); return maStates.empty(); } sal_Bool ScAccessibleFilterMenu::contains(sal_Int16 nState) throw (RuntimeException) { - updateStates(); return maStates.count(nState) > 0; } sal_Bool ScAccessibleFilterMenu::containsAll(const Sequence& aStateSet) throw (RuntimeException) { - updateStates(); sal_Int32 n = aStateSet.getLength(); for (sal_Int32 i = 0; i < n; ++i) { @@ -292,7 +249,6 @@ void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex) if (static_cast(nChildIndex) >= maMenuItems.size()) throw IndexOutOfBoundsException(); - maMenuItems[nChildIndex].mbSelected = true; mpWindow->setSelectedMenuItem(nChildIndex, false, true); } @@ -302,7 +258,7 @@ sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex if (static_cast(nChildIndex) >= maMenuItems.size()) throw IndexOutOfBoundsException(); - return maMenuItems[nChildIndex].mbSelected; + return mpWindow->isMenuItemSelected(static_cast(nChildIndex)); } void ScAccessibleFilterMenu::clearAccessibleSelection() throw (RuntimeException) @@ -317,8 +273,8 @@ void ScAccessibleFilterMenu::selectAllAccessibleChildren() throw (RuntimeExcepti sal_Int32 ScAccessibleFilterMenu::getSelectedAccessibleChildCount() throw (RuntimeException) { - sal_Int32 n = for_each(maMenuItems.begin(), maMenuItems.end(), CountSelectedMenuItem()).getCount(); - return n; + // Since this is a menu, either one menu item is selected, or none at all. + return mpWindow->getSelectedMenuItem() == ScMenuFloatingWindow::MENU_NOT_SELECTED ? 0 : 1; } Reference ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_Int32 nChildIndex) @@ -327,7 +283,7 @@ Reference ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_In if (static_cast(nChildIndex) >= maMenuItems.size()) throw IndexOutOfBoundsException(); - return maMenuItems[nChildIndex].mxAccessible; + return maMenuItems[nChildIndex]; } void ScAccessibleFilterMenu::deselectAccessibleChild(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException) @@ -373,23 +329,23 @@ void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled { // Check weather this menu item is a sub menu or a regular menu item. ScMenuFloatingWindow* pSubMenu = mpWindow->getSubMenuWindow(nMenuPos); - MenuItem aItem; + Reference xAccessible; if (pSubMenu) { - aItem.mxAccessible = pSubMenu->CreateAccessible(); - ScAccessibleFilterMenu* p = static_cast( - aItem.mxAccessible.get()); + xAccessible = pSubMenu->CreateAccessible(); + ScAccessibleFilterMenu* p = + static_cast(xAccessible.get()); p->setEnabled(bEnabled); p->setMenuPos(nMenuPos); } else { - aItem.mxAccessible.set(new ScAccessibleFilterMenuItem(this, mpWindow, rName, nMenuPos)); - ScAccessibleFilterMenuItem* p = static_cast( - aItem.mxAccessible.get()); + xAccessible.set(new ScAccessibleFilterMenuItem(this, mpWindow, rName, nMenuPos)); + ScAccessibleFilterMenuItem* p = + static_cast(xAccessible.get()); p->setEnabled(bEnabled); } - maMenuItems.push_back(aItem); + maMenuItems.push_back(xAccessible); } void ScAccessibleFilterMenu::setMenuPos(size_t nMenuPos) @@ -410,8 +366,6 @@ bool ScAccessibleFilterMenu::isFocused() bool ScAccessibleFilterMenu::isSelected() { // Check to see if any of the child menu items is selected. -// size_t nSelectCount = for_each(maMenuItems.begin(), maMenuItems.end(), CountSelectedMenuItem()).getCount(); -// return nSelectCount == 0; return mpWindow->isMenuItemSelected(mnMenuPos); } diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index ab3123718d40..ce45f0c1b504 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -48,8 +48,6 @@ #include -#define MENU_NOT_SELECTED 999 - using ::com::sun::star::uno::Reference; using ::com::sun::star::accessibility::XAccessible; using ::rtl::OUString; @@ -280,6 +278,8 @@ IMPL_LINK( ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl, void*, EMPTYARG ) // ---------------------------------------------------------------------------- +size_t ScMenuFloatingWindow::MENU_NOT_SELECTED = 999; + ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel) : FloatingWindow(pParent, (WB_SYSTEMFLOATWIN|WB_SYSTEMWINDOW|WB_NOBORDER)), maOpenTimer(this), @@ -537,7 +537,7 @@ void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, mnSelectedMenu = nPos; } -size_t ScMenuFloatingWindow::getSelectedMenuPos() const +size_t ScMenuFloatingWindow::getSelectedMenuItem() const { return mnSelectedMenu; } @@ -1177,7 +1177,7 @@ void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt) { ScMenuFloatingWindow::MouseMove(rMEvt); - size_t nSelectedMenu = getSelectedMenuPos(); + size_t nSelectedMenu = getSelectedMenuItem(); if (nSelectedMenu == MENU_NOT_SELECTED) queueCloseSubMenu(); } @@ -1240,6 +1240,8 @@ void ScDPFieldPopupWindow::setMemberSize(size_t n) void ScDPFieldPopupWindow::addMember(const OUString& rName, bool bVisible) { + fprintf(stdout, "ScDPFieldPopupWindow::addMember: name = '%s' visible = %d\n", + rtl::OUStringToOString(rName, RTL_TEXTENCODING_UTF8).getStr(), bVisible); Member aMember; aMember.maName = rName; aMember.mbVisible = bVisible; diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 55afc0470c64..dbbbcb55ed49 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -103,6 +103,7 @@ private: class ScMenuFloatingWindow : public FloatingWindow { public: + static size_t MENU_NOT_SELECTED; /** * Action to perform when an event takes place. Create a sub-class of * this to implement the desired action. @@ -133,6 +134,7 @@ public: ::rtl::OUString getMenuItemName(size_t nPos) const; bool isMenuItemEnabled(size_t nPos) const; bool isMenuItemSelected(size_t nPos) const; + size_t getSelectedMenuItem() const; void setName(const ::rtl::OUString& rName); const ::rtl::OUString& getName() const; @@ -145,7 +147,6 @@ protected: void drawAllMenuItems(); const Font& getLabelFont() const; - size_t getSelectedMenuPos() const; void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu); void queueCloseSubMenu(); void launchSubMenu(bool bSetMenuPos); -- cgit From 914141b32155e25a2d87ac00908bfb376ac30344 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Sat, 22 Aug 2009 03:40:29 +0000 Subject: More code cleanup & wrote a separate XAccessibleStateSet implementation that can be shared across classes. --- sc/inc/AccessibleFilterMenuItem.hxx | 3 +- sc/inc/AccessibleGlobal.hxx | 69 +++++++++++++++ .../ui/Accessibility/AccessibleFilterMenuItem.cxx | 9 +- sc/source/ui/Accessibility/AccessibleGlobal.cxx | 98 ++++++++++++++++++++++ sc/source/ui/Accessibility/makefile.mk | 2 + 5 files changed, 174 insertions(+), 7 deletions(-) create mode 100644 sc/inc/AccessibleGlobal.hxx create mode 100644 sc/source/ui/Accessibility/AccessibleGlobal.cxx (limited to 'sc') diff --git a/sc/inc/AccessibleFilterMenuItem.hxx b/sc/inc/AccessibleFilterMenuItem.hxx index d4434da5f937..3f7f58d3a818 100644 --- a/sc/inc/AccessibleFilterMenuItem.hxx +++ b/sc/inc/AccessibleFilterMenuItem.hxx @@ -122,8 +122,7 @@ private: ScMenuFloatingWindow* mpWindow; ::rtl::OUString maName; size_t mnMenuPos; - bool mbSelected:1; - bool mbEnabled:1; + bool mbEnabled; }; #endif diff --git a/sc/inc/AccessibleGlobal.hxx b/sc/inc/AccessibleGlobal.hxx new file mode 100644 index 000000000000..83f5e0d2222c --- /dev/null +++ b/sc/inc/AccessibleGlobal.hxx @@ -0,0 +1,69 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_ACCESSIBLEGLOBAL_HXX +#define SC_ACCESSIBLEGLOBAL_HXX + +#include +#include "cppuhelper/implbase1.hxx" + +#include + +class ScAccessibleStateSet : public ::cppu::WeakImplHelper1< ::com::sun::star::accessibility::XAccessibleStateSet > +{ +public: + ScAccessibleStateSet(); + virtual ~ScAccessibleStateSet(); + + // XAccessibleStateSet + + virtual ::sal_Bool SAL_CALL isEmpty() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Bool SAL_CALL contains(sal_Int16 nState) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Bool SAL_CALL containsAll( + const ::com::sun::star::uno::Sequence& aStateSet) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence SAL_CALL getStates() + throw (::com::sun::star::uno::RuntimeException); + + // Non-UNO Methods + + void insert(sal_Int16 nState); + void clear(); + +private: + ::std::set maStates; +}; + +#endif diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx index 42c16e6154f4..662e5303df48 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx @@ -62,7 +62,6 @@ ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem( mpWindow(pWin), maName(rName), mnMenuPos(nMenuPos), - mbSelected(false), mbEnabled(true) { SetName(rName); @@ -101,7 +100,7 @@ OUString ScAccessibleFilterMenuItem::getImplementationName() sal_Bool ScAccessibleFilterMenuItem::isEmpty() throw (RuntimeException) { - return (mbEnabled || mbSelected); + return false; } sal_Bool ScAccessibleFilterMenuItem::contains(sal_Int16 nState) throw (RuntimeException) @@ -119,7 +118,7 @@ sal_Bool ScAccessibleFilterMenuItem::contains(sal_Int16 nState) throw (RuntimeEx } } - if (mbSelected) + if (isSelected()) { switch (nState) { @@ -150,7 +149,7 @@ sal_Bool ScAccessibleFilterMenuItem::containsAll(const Sequence& aSta continue; } } - if (mbSelected) + if (isSelected()) { switch (nState) { @@ -176,7 +175,7 @@ Sequence ScAccessibleFilterMenuItem::getStates() throw (RuntimeExcept aStates.push_back(SENSITIVE); } - if (mbSelected) + if (isSelected()) { aStates.push_back(FOCUSED); aStates.push_back(SELECTED); diff --git a/sc/source/ui/Accessibility/AccessibleGlobal.cxx b/sc/source/ui/Accessibility/AccessibleGlobal.cxx new file mode 100644 index 000000000000..6ac7190a132b --- /dev/null +++ b/sc/source/ui/Accessibility/AccessibleGlobal.cxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove + +#include "precompiled_sc.hxx" +#include "AccessibleGlobal.hxx" + +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::std::set; + +ScAccessibleStateSet::ScAccessibleStateSet() +{ +} + +ScAccessibleStateSet::~ScAccessibleStateSet() +{ +} + +// XAccessibleStateSet + +sal_Bool SAL_CALL ScAccessibleStateSet::isEmpty() throw (RuntimeException) +{ + return maStates.empty(); +} + +sal_Bool SAL_CALL ScAccessibleStateSet::contains(sal_Int16 nState) + throw (RuntimeException) +{ + return maStates.count(nState) != 0; +} + +sal_Bool SAL_CALL ScAccessibleStateSet::containsAll( + const Sequence& aStateSet) throw (RuntimeException) +{ + sal_Int32 n = aStateSet.getLength(); + for (sal_Int32 i = 0; i < n; ++i) + { + if (!maStates.count(aStateSet[i])) + // This state is not set. + return false; + } + // All specified states are set. + return true; +} + +Sequence SAL_CALL ScAccessibleStateSet::getStates() + throw (RuntimeException) +{ + Sequence aSeq(0); + set::const_iterator itr = maStates.begin(), itrEnd = maStates.end(); + for (size_t i = 0; itr != itrEnd; ++itr, ++i) + { + aSeq.realloc(i+1); + aSeq[i] = *itr; + } + return aSeq; +} + +void ScAccessibleStateSet::insert(sal_Int16 nState) +{ + maStates.insert(nState); +} + +void ScAccessibleStateSet::clear() +{ + maStates.clear(); +} + diff --git a/sc/source/ui/Accessibility/makefile.mk b/sc/source/ui/Accessibility/makefile.mk index 0bde79f1f159..1ef6db37e0c1 100644 --- a/sc/source/ui/Accessibility/makefile.mk +++ b/sc/source/ui/Accessibility/makefile.mk @@ -47,6 +47,7 @@ SLOFILES = \ $(SLO)$/AccessibleContextBase.obj \ $(SLO)$/AccessibleTableBase.obj \ $(SLO)$/AccessibleDocument.obj \ + $(SLO)$/AccessibleGlobal.obj \ $(SLO)$/AccessibleSpreadsheet.obj \ $(SLO)$/AccessibleCell.obj \ $(SLO)$/AccessibilityHints.obj \ @@ -71,6 +72,7 @@ EXCEPTIONSFILES= \ $(SLO)$/AccessibleContextBase.obj \ $(SLO)$/AccessibleTableBase.obj \ $(SLO)$/AccessibleDocument.obj \ + $(SLO)$/AccessibleGlobal.obj \ $(SLO)$/AccessibleSpreadsheet.obj \ $(SLO)$/AccessibleCell.obj \ $(SLO)$/AccessibleDocumentBase.obj \ -- cgit From f379d876d1a4894bd9767640c2329ba44f0e4820 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Sat, 22 Aug 2009 04:02:38 +0000 Subject: Use ScAccessibleStateSet to share state set implementation. --- sc/inc/AccessibleFilterMenu.hxx | 26 +---- sc/inc/AccessibleFilterMenuItem.hxx | 31 ++--- sc/inc/AccessibleGlobal.hxx | 3 + .../ui/Accessibility/AccessibleFilterMenu.cxx | 76 ++++--------- .../ui/Accessibility/AccessibleFilterMenuItem.cxx | 126 ++++++--------------- 5 files changed, 73 insertions(+), 189 deletions(-) (limited to 'sc') diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx index c5049045d672..93cfe1a78b21 100644 --- a/sc/inc/AccessibleFilterMenu.hxx +++ b/sc/inc/AccessibleFilterMenu.hxx @@ -32,10 +32,9 @@ #define SC_ACCESSIBLEFILTERMENU_HXX #include "AccessibleContextBase.hxx" -#include "cppuhelper/implbase2.hxx" +#include "cppuhelper/implbase1.hxx" #include -#include #include #include #include @@ -52,8 +51,7 @@ namespace com { namespace sun { namespace star { class ScDocument; class ScMenuFloatingWindow; -typedef ::cppu::ImplHelper2< - ::com::sun::star::accessibility::XAccessibleStateSet, +typedef ::cppu::ImplHelper1< ::com::sun::star::accessibility::XAccessibleSelection > ScAccessibleFilterMenu_BASE; class ScAccessibleFilterMenu : @@ -120,20 +118,6 @@ public: ::com::sun::star::accessibility::XAccessibleEventListener>& xListener) throw (com::sun::star::uno::RuntimeException); - // XAccessibleStateSet - - virtual sal_Bool SAL_CALL isEmpty() throw (::com::sun::star::uno::RuntimeException); - - virtual sal_Bool SAL_CALL contains(sal_Int16 nState) - throw (::com::sun::star::uno::RuntimeException); - - virtual sal_Bool SAL_CALL containsAll( - const ::com::sun::star::uno::Sequence& aStateSet) - throw (::com::sun::star::uno::RuntimeException); - - virtual ::com::sun::star::uno::Sequence SAL_CALL getStates() - throw (::com::sun::star::uno::RuntimeException); - // XAccessibleSelection virtual void SAL_CALL selectAccessibleChild(sal_Int32 nChildIndex) @@ -177,16 +161,16 @@ public: void appendMenuItem(const ::rtl::OUString& rName, bool bEnabled, size_t nMenuPos); void setMenuPos(size_t nMenuPos); void setEnabled(bool bEnabled); - bool isSelected(); private: - bool isFocused(); + bool isSelected() const; + bool isFocused() const; void updateStates(); private: ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > > maMenuItems; - ::std::set maStates; + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > mxStateSet; size_t mnMenuPos; ScMenuFloatingWindow* mpWindow; diff --git a/sc/inc/AccessibleFilterMenuItem.hxx b/sc/inc/AccessibleFilterMenuItem.hxx index 3f7f58d3a818..10d471f4b245 100644 --- a/sc/inc/AccessibleFilterMenuItem.hxx +++ b/sc/inc/AccessibleFilterMenuItem.hxx @@ -32,16 +32,14 @@ #define SC_ACCESSIBLEFILTERMENUITEM_HXX #include "AccessibleContextBase.hxx" -#include "cppuhelper/implbase2.hxx" +#include "cppuhelper/implbase1.hxx" #include -#include class ScMenuFloatingWindow; -typedef ::cppu::ImplHelper2< - ::com::sun::star::accessibility::XAccessibleAction, - ::com::sun::star::accessibility::XAccessibleStateSet > ScAccessibleFilterMenuItem_BASE; +typedef ::cppu::ImplHelper1< + ::com::sun::star::accessibility::XAccessibleAction > ScAccessibleFilterMenuItem_BASE; class ScAccessibleFilterMenuItem : public ScAccessibleContextBase, @@ -72,21 +70,6 @@ public: virtual ::rtl::OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException); - // XAccessibleStateSet - - virtual ::sal_Bool SAL_CALL isEmpty() - throw (::com::sun::star::uno::RuntimeException); - - virtual ::sal_Bool SAL_CALL contains(sal_Int16 nState) - throw (::com::sun::star::uno::RuntimeException); - - virtual ::sal_Bool SAL_CALL containsAll( - const ::com::sun::star::uno::Sequence& aStateSet) - throw (::com::sun::star::uno::RuntimeException); - - virtual ::com::sun::star::uno::Sequence SAL_CALL getStates() - throw (::com::sun::star::uno::RuntimeException); - // XAccessibleAction virtual ::sal_Int32 SAL_CALL getAccessibleActionCount() @@ -114,11 +97,17 @@ public: // Non-UNO Methods - bool isSelected() const; void setEnabled(bool bEnabled); private: + bool isSelected() const; + bool isFocused() const; + void updateStateSet(); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > mxStateSet; + ScMenuFloatingWindow* mpWindow; ::rtl::OUString maName; size_t mnMenuPos; diff --git a/sc/inc/AccessibleGlobal.hxx b/sc/inc/AccessibleGlobal.hxx index 83f5e0d2222c..9f17c2eaacae 100644 --- a/sc/inc/AccessibleGlobal.hxx +++ b/sc/inc/AccessibleGlobal.hxx @@ -36,6 +36,9 @@ #include +/** + * Generic XAccessibleStateSet implementation. + */ class ScAccessibleStateSet : public ::cppu::WeakImplHelper1< ::com::sun::star::accessibility::XAccessibleStateSet > { public: diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx index 5a1253181a8f..ad50425db56e 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx @@ -31,6 +31,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" +#include "AccessibleGlobal.hxx" #include "AccessibleFilterMenu.hxx" #include "AccessibleFilterMenuItem.hxx" #include "unoguard.hxx" @@ -173,7 +174,7 @@ Reference ScAccessibleFilterMenu::getAccessibleStateSet() throw (RuntimeException) { updateStates(); - return this; + return mxStateSet; } OUString ScAccessibleFilterMenu::getImplementationName() @@ -202,45 +203,6 @@ void ScAccessibleFilterMenu::removeEventListener( for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, false)); } -// XAccessibleStateSet - -sal_Bool ScAccessibleFilterMenu::isEmpty() throw (RuntimeException) -{ - return maStates.empty(); -} - -sal_Bool ScAccessibleFilterMenu::contains(sal_Int16 nState) throw (RuntimeException) -{ - return maStates.count(nState) > 0; -} - -sal_Bool ScAccessibleFilterMenu::containsAll(const Sequence& aStateSet) - throw (RuntimeException) -{ - sal_Int32 n = aStateSet.getLength(); - for (sal_Int32 i = 0; i < n; ++i) - { - if (!maStates.count(aStateSet[i])) - // This state is not set. - return false; - } - // All specified states are set. - return true; -} - -Sequence ScAccessibleFilterMenu::getStates() throw (RuntimeException) -{ - updateStates(); - Sequence aSeq(0); - set::const_iterator itr = maStates.begin(), itrEnd = maStates.end(); - for (size_t i = 0; itr != itrEnd; ++itr, ++i) - { - aSeq.realloc(i+1); - aSeq[i] = *itr; - } - return aSeq; -} - // XAccessibleSelection void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex) @@ -358,28 +320,36 @@ void ScAccessibleFilterMenu::setEnabled(bool bEnabled) mbEnabled = bEnabled; } -bool ScAccessibleFilterMenu::isFocused() +bool ScAccessibleFilterMenu::isSelected() const { - return isSelected(); + // Check to see if any of the child menu items is selected. + return mpWindow->isMenuItemSelected(mnMenuPos); } -bool ScAccessibleFilterMenu::isSelected() +bool ScAccessibleFilterMenu::isFocused() const { - // Check to see if any of the child menu items is selected. - return mpWindow->isMenuItemSelected(mnMenuPos); + return isSelected(); } void ScAccessibleFilterMenu::updateStates() { - maStates.clear(); - maStates.insert(ENABLED); - maStates.insert(FOCUSABLE); - maStates.insert(SELECTABLE); - maStates.insert(SENSITIVE); - maStates.insert(OPAQUE); + if (!mxStateSet.is()) + mxStateSet.set(new ScAccessibleStateSet); + + ScAccessibleStateSet* p = static_cast( + mxStateSet.get()); + + p->clear(); + + p->insert(ENABLED); + p->insert(FOCUSABLE); + p->insert(SELECTABLE); + p->insert(SENSITIVE); + p->insert(OPAQUE); if (isFocused()) - maStates.insert(FOCUSED); + p->insert(FOCUSED); + if (isSelected()) - maStates.insert(SELECTED); + p->insert(SELECTED); } diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx index 662e5303df48..76822ccb3820 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx @@ -31,6 +31,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" +#include "AccessibleGlobal.hxx" #include "AccessibleFilterMenuItem.hxx" #include "dpcontrol.hxx" @@ -46,6 +47,7 @@ using namespace ::com::sun::star; using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::accessibility::AccessibleStateType; using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Reference; @@ -87,7 +89,8 @@ Reference ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 Reference ScAccessibleFilterMenuItem::getAccessibleStateSet() throw (RuntimeException) { - return this; + updateStateSet(); + return mxStateSet; } OUString ScAccessibleFilterMenuItem::getImplementationName() @@ -96,99 +99,6 @@ OUString ScAccessibleFilterMenuItem::getImplementationName() return OUString::createFromAscii("ScAccessibleFilterMenuItem - implementation name"); } -// XAccessibleStateSet - -sal_Bool ScAccessibleFilterMenuItem::isEmpty() throw (RuntimeException) -{ - return false; -} - -sal_Bool ScAccessibleFilterMenuItem::contains(sal_Int16 nState) throw (RuntimeException) -{ - using namespace ::com::sun::star::accessibility::AccessibleStateType; - if (mbEnabled) - { - switch (nState) - { - case ENABLED: - case FOCUSABLE: - case SELECTABLE: - case SENSITIVE: - return true; - } - } - - if (isSelected()) - { - switch (nState) - { - case FOCUSED: - case SELECTED: - return true; - } - } - return false; -} - -sal_Bool ScAccessibleFilterMenuItem::containsAll(const Sequence& aStateSet) - throw (RuntimeException) -{ - using namespace ::com::sun::star::accessibility::AccessibleStateType; - sal_Int32 n = aStateSet.getLength(); - for (sal_Int32 i = 0; i < n; ++i) - { - sal_Int16 nState = aStateSet[i]; - if (mbEnabled) - { - switch (nState) - { - case ENABLED: - case FOCUSABLE: - case SELECTABLE: - case SENSITIVE: - continue; - } - } - if (isSelected()) - { - switch (nState) - { - case FOCUSED: - case SELECTED: - continue; - } - } - return false; - } - return true; -} - -Sequence ScAccessibleFilterMenuItem::getStates() throw (RuntimeException) -{ - using namespace ::com::sun::star::accessibility::AccessibleStateType; - vector aStates; - if (mbEnabled) - { - aStates.push_back(ENABLED); - aStates.push_back(FOCUSABLE); - aStates.push_back(SELECTABLE); - aStates.push_back(SENSITIVE); - } - - if (isSelected()) - { - aStates.push_back(FOCUSED); - aStates.push_back(SELECTED); - } - - size_t n = aStates.size(); - Sequence aSeq(aStates.size()); - for (size_t i = 0; i < n; ++i) - aSeq[i] = aStates[i]; - - return aSeq; -} - // XAccessibleAction sal_Int32 ScAccessibleFilterMenuItem::getAccessibleActionCount() throw (RuntimeException) @@ -240,8 +150,36 @@ bool ScAccessibleFilterMenuItem::isSelected() const return mpWindow->isMenuItemSelected(mnMenuPos); } +bool ScAccessibleFilterMenuItem::isFocused() const +{ + return isSelected(); +} + void ScAccessibleFilterMenuItem::setEnabled(bool bEnabled) { mbEnabled = bEnabled; } +void ScAccessibleFilterMenuItem::updateStateSet() +{ + if (!mxStateSet.is()) + mxStateSet.set(new ScAccessibleStateSet); + + ScAccessibleStateSet* p = static_cast( + mxStateSet.get()); + + p->clear(); + + p->insert(ENABLED); + p->insert(FOCUSABLE); + p->insert(SELECTABLE); + p->insert(SENSITIVE); + p->insert(OPAQUE); + + if (isFocused()) + p->insert(FOCUSED); + + if (isSelected()) + p->insert(SELECTED); +} + -- cgit From fd7c4e6b7c51ccb702bb7b383ad14d573ebb3a48 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Sat, 22 Aug 2009 04:04:35 +0000 Subject: forgot to remove debug statement. --- sc/source/ui/cctrl/dpcontrol.cxx | 2 -- 1 file changed, 2 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index ce45f0c1b504..ca3d5d3d93ae 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -1240,8 +1240,6 @@ void ScDPFieldPopupWindow::setMemberSize(size_t n) void ScDPFieldPopupWindow::addMember(const OUString& rName, bool bVisible) { - fprintf(stdout, "ScDPFieldPopupWindow::addMember: name = '%s' visible = %d\n", - rtl::OUStringToOString(rName, RTL_TEXTENCODING_UTF8).getStr(), bVisible); Member aMember; aMember.maName = rName; aMember.mbVisible = bVisible; -- cgit From 6f8305a93490ec9868510b62f522c7545ef73a5b Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Sat, 22 Aug 2009 04:15:31 +0000 Subject: more cleanup --- sc/inc/AccessibleFilterMenu.hxx | 1 - sc/source/ui/Accessibility/AccessibleFilterMenu.cxx | 3 --- sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx | 5 +---- 3 files changed, 1 insertion(+), 8 deletions(-) (limited to 'sc') diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx index 93cfe1a78b21..f295950f1c82 100644 --- a/sc/inc/AccessibleFilterMenu.hxx +++ b/sc/inc/AccessibleFilterMenu.hxx @@ -40,7 +40,6 @@ #include #include -#include namespace com { namespace sun { namespace star { namespace accessibility { diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx index ad50425db56e..5e576128ba87 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx @@ -47,8 +47,6 @@ #include "vcl/unohelp.hxx" #include "dpcontrol.hxx" -#include - #include #include #include @@ -69,7 +67,6 @@ using ::com::sun::star::uno::RuntimeException; using ::rtl::OUString; using ::std::for_each; using ::std::vector; -using ::std::set; // ============================================================================ diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx index 76822ccb3820..1918a1c01e35 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx @@ -43,8 +43,6 @@ #include #include -#include - using namespace ::com::sun::star; using namespace ::com::sun::star::accessibility; using namespace ::com::sun::star::accessibility::AccessibleStateType; @@ -56,7 +54,6 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::lang::IndexOutOfBoundsException; using ::com::sun::star::uno::RuntimeException; using ::rtl::OUString; -using ::std::vector; ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem( const Reference& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos) : @@ -96,7 +93,7 @@ Reference ScAccessibleFilterMenuItem::getAccessibleStateSet OUString ScAccessibleFilterMenuItem::getImplementationName() throw (RuntimeException) { - return OUString::createFromAscii("ScAccessibleFilterMenuItem - implementation name"); + return OUString::createFromAscii("ScAccessibleFilterMenuItem"); } // XAccessibleAction -- cgit From fddbd3634adb04995106aff39334c1ddf55013bc Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Tue, 25 Aug 2009 15:36:57 +0000 Subject: Reorganized accessible menu implementation so that the toplevel window is treated as menu. It's cleaner and less complicated this way. --- sc/inc/AccessibleFilterMenu.hxx | 10 +++++ sc/inc/AccessibleFilterMenuItem.hxx | 9 +++- sc/inc/AccessibleFilterTopWindow.hxx | 5 ++- .../ui/Accessibility/AccessibleFilterMenu.cxx | 52 +++++++++++++++++++++- .../ui/Accessibility/AccessibleFilterMenuItem.cxx | 27 +++++++++++ .../ui/Accessibility/AccessibleFilterTopWindow.cxx | 28 ++++++------ sc/source/ui/cctrl/dpcontrol.cxx | 9 ++-- sc/source/ui/inc/dpcontrol.hxx | 3 +- 8 files changed, 122 insertions(+), 21 deletions(-) (limited to 'sc') diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx index f295950f1c82..54194a2d4acf 100644 --- a/sc/inc/AccessibleFilterMenu.hxx +++ b/sc/inc/AccessibleFilterMenu.hxx @@ -161,6 +161,16 @@ public: void setMenuPos(size_t nMenuPos); void setEnabled(bool bEnabled); +protected: + + sal_Int32 getMenuItemCount() const; + + virtual Rectangle GetBoundingBoxOnScreen() const + throw (::com::sun::star::uno::RuntimeException); + + virtual Rectangle GetBoundingBox() const + throw (::com::sun::star::uno::RuntimeException); + private: bool isSelected() const; bool isFocused() const; diff --git a/sc/inc/AccessibleFilterMenuItem.hxx b/sc/inc/AccessibleFilterMenuItem.hxx index 10d471f4b245..f5ad0fd5d74b 100644 --- a/sc/inc/AccessibleFilterMenuItem.hxx +++ b/sc/inc/AccessibleFilterMenuItem.hxx @@ -97,9 +97,16 @@ public: // Non-UNO Methods - void setEnabled(bool bEnabled); +protected: + + virtual Rectangle GetBoundingBoxOnScreen() const + throw (::com::sun::star::uno::RuntimeException); + + virtual Rectangle GetBoundingBox() const + throw (::com::sun::star::uno::RuntimeException); + private: bool isSelected() const; bool isFocused() const; diff --git a/sc/inc/AccessibleFilterTopWindow.hxx b/sc/inc/AccessibleFilterTopWindow.hxx index 801d84d0c5fb..e901949286a1 100644 --- a/sc/inc/AccessibleFilterTopWindow.hxx +++ b/sc/inc/AccessibleFilterTopWindow.hxx @@ -31,13 +31,14 @@ #ifndef SC_ACCESSIBLEFILTERTOPWINDOW_HXX #define SC_ACCESSIBLEFILTERTOPWINDOW_HXX -#include "AccessibleContextBase.hxx" +//#include "AccessibleContextBase.hxx" +#include "AccessibleFilterMenu.hxx" #include "cppuhelper/implbase1.hxx" class ScDPFieldPopupWindow; class ScDocument; -class ScAccessibleFilterTopWindow : public ScAccessibleContextBase +class ScAccessibleFilterTopWindow : public ScAccessibleFilterMenu { public: ScAccessibleFilterTopWindow( diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx index 5e576128ba87..14824b920c85 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx @@ -155,7 +155,7 @@ OUString ScAccessibleFilterMenu::getAccessibleName() throw (RuntimeException) sal_Int32 ScAccessibleFilterMenu::getAccessibleChildCount() throw (RuntimeException) { - return maMenuItems.size(); + return getMenuItemCount(); } Reference ScAccessibleFilterMenu::getAccessibleChild(sal_Int32 nIndex) @@ -284,6 +284,51 @@ Sequence ScAccessibleFilterMenu::getImplementationId() return aId; } +Rectangle ScAccessibleFilterMenu::GetBoundingBoxOnScreen() const + throw (RuntimeException) +{ + if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED) + return Rectangle(); + + // Menu object's bounding box is the bounding box of the menu item that + // launches the menu, which belongs to the parent window. + ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow(); + if (!pParentWin) + return Rectangle(); + + if (!pParentWin->IsVisible()) + return Rectangle(); + + Point aPos = pParentWin->OutputToAbsoluteScreenPixel(Point(0,0)); + Point aMenuPos; + Size aMenuSize; + pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize); + Rectangle aRect(aPos + aMenuPos, aMenuSize); + return aRect; +} + +Rectangle ScAccessibleFilterMenu::GetBoundingBox() const + throw (RuntimeException) +{ + if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED) + return Rectangle(); + + // Menu object's bounding box is the bounding box of the menu item that + // launches the menu, which belongs to the parent window. + ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow(); + if (!pParentWin) + return Rectangle(); + + if (!pParentWin->IsVisible()) + return Rectangle(); + + Point aMenuPos; + Size aMenuSize; + pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize); + Rectangle aRect(aMenuPos, aMenuSize); + return aRect; +} + void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled, size_t nMenuPos) { // Check weather this menu item is a sub menu or a regular menu item. @@ -317,6 +362,11 @@ void ScAccessibleFilterMenu::setEnabled(bool bEnabled) mbEnabled = bEnabled; } +sal_Int32 ScAccessibleFilterMenu::getMenuItemCount() const +{ + return maMenuItems.size(); +} + bool ScAccessibleFilterMenu::isSelected() const { // Check to see if any of the child menu items is selected. diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx index 1918a1c01e35..0ab5fa270688 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx @@ -157,6 +157,33 @@ void ScAccessibleFilterMenuItem::setEnabled(bool bEnabled) mbEnabled = bEnabled; } +Rectangle ScAccessibleFilterMenuItem::GetBoundingBoxOnScreen() const + throw (RuntimeException) +{ + if (!mpWindow->IsVisible()) + return Rectangle(); + + Point aPos = mpWindow->OutputToAbsoluteScreenPixel(Point(0,0)); + Point aMenuPos; + Size aMenuSize; + mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize); + Rectangle aRect(aPos + aMenuPos, aMenuSize); + return aRect; +} + +Rectangle ScAccessibleFilterMenuItem::GetBoundingBox() const + throw (RuntimeException) +{ + if (!mpWindow->IsVisible()) + return Rectangle(); + + Point aMenuPos; + Size aMenuSize; + mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize); + Rectangle aRect(aMenuPos, aMenuSize); + return aRect; +} + void ScAccessibleFilterMenuItem::updateStateSet() { if (!mxStateSet.is()) diff --git a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx index 02fafd87e138..832cb37dd096 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx @@ -46,47 +46,49 @@ using ::rtl::OUString; ScAccessibleFilterTopWindow::ScAccessibleFilterTopWindow( const Reference& rxParent, ScDPFieldPopupWindow* pWin, const OUString& rName, ScDocument* pDoc) : - ScAccessibleContextBase(rxParent, AccessibleRole::PANEL), + ScAccessibleFilterMenu(rxParent, pWin, rName, ScMenuFloatingWindow::MENU_NOT_SELECTED, pDoc), mpWindow(pWin), mpDoc(pDoc) { - fprintf(stdout, "ScAccessibleFilterTopWindow::ScAccessibleFilterTopWindow: ctor (%p)\n", this); SetName(rName); } ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow() { - fprintf(stdout, "ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow: dtor (%p)\n", this); } // XAccessibleContext sal_Int32 ScAccessibleFilterTopWindow::getAccessibleChildCount() throw (RuntimeException) { - return 7; + sal_Int32 nMenuCount = getMenuItemCount(); + return nMenuCount + 6; } Reference ScAccessibleFilterTopWindow::getAccessibleChild( sal_Int32 nIndex) throw (RuntimeException, IndexOutOfBoundsException) { - if (nIndex >= 7) + if (nIndex >= getAccessibleChildCount()) throw IndexOutOfBoundsException(); + sal_Int32 nMenuCount = getMenuItemCount(); + if (nIndex < nMenuCount) + return ScAccessibleFilterMenu::getAccessibleChild(nIndex); + + nIndex -= nMenuCount; switch (nIndex) { case 0: - return getAccessibleChildMenu(); - case 1: return mxAccListBox; - case 2: + case 1: return mxAccToggleAll; - case 3: + case 2: return mxAccSingleOnBtn; - case 4: + case 3: return mxAccSingleOffBtn; - case 5: + case 4: return mxAccOkBtn; - case 6: + case 5: return mxAccCancelBtn; default: ; @@ -103,7 +105,7 @@ OUString ScAccessibleFilterTopWindow::getImplementationName() throw (RuntimeExce Reference ScAccessibleFilterTopWindow::getAccessibleChildMenu() { if (!mxAccMenu.is()) - mxAccMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), 999, mpDoc)); + mxAccMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), ScMenuFloatingWindow::MENU_NOT_SELECTED, mpDoc)); return mxAccMenu; } diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index ca3d5d3d93ae..c46a83e4f8b8 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -830,6 +830,11 @@ void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rS rSize = aSize1; } +ScMenuFloatingWindow* ScMenuFloatingWindow::getParentMenuWindow() const +{ + return mpParentMenu; +} + size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const { size_t n = maMenuItems.size(); @@ -1212,9 +1217,7 @@ Reference ScDPFieldPopupWindow::CreateAccessible() mxAccessible.set(new ScAccessibleFilterTopWindow( GetAccessibleParentWindow()->GetAccessible(), this, getName(), getDoc())); ScAccessibleFilterTopWindow* pAccTop = static_cast(mxAccessible.get()); - Reference xAccMenu = pAccTop->getAccessibleChildMenu(); - ScAccessibleFilterMenu* pAccMenu = static_cast(xAccMenu.get()); - fillMenuItemsToAccessible(pAccMenu); + fillMenuItemsToAccessible(pAccTop); pAccTop->setAccessibleChild( maChecks.CreateAccessible(), ScAccessibleFilterTopWindow::LISTBOX); diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index dbbbcb55ed49..77fae133ce81 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -140,6 +140,8 @@ public: const ::rtl::OUString& getName() const; void executeMenuItem(size_t nPos); + void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const; + ScMenuFloatingWindow* getParentMenuWindow() const; protected: @@ -167,7 +169,6 @@ private: void resizeToFitMenuItems(); void highlightMenuItem(size_t nPos, bool bSelected); - void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const; size_t getEnclosingMenuItem(const Point& rPos) const; size_t getSubMenuPos(ScMenuFloatingWindow* pSubMenu); -- cgit From 4848dbac7b540e2a0d64521e19765a261f7e7305 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 26 Aug 2009 00:48:56 +0000 Subject: Fire a menu highlight event on menu item selection change, to get the accessibility to work correctly. --- sc/source/ui/cctrl/dpcontrol.cxx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index c46a83e4f8b8..e17ff0cd1dab 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -47,9 +47,11 @@ #include "AccessibleFilterTopWindow.hxx" #include +#include using ::com::sun::star::uno::Reference; using ::com::sun::star::accessibility::XAccessible; +using ::com::sun::star::accessibility::XAccessibleContext; using ::rtl::OUString; using ::rtl::OUStringHash; using ::std::vector; @@ -706,6 +708,26 @@ void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSub else queueCloseSubMenu(); } + + if (mxAccessible.is()) + { + // Fire a menu highlight event since the accessibility framework + // needs this to track focus on menu items. + do + { + Reference xAccCxt = mxAccessible->getAccessibleContext(); + if (!xAccCxt.is()) + break; + + Reference xAccMenu = xAccCxt->getAccessibleChild(nPos); + if (!xAccMenu.is()) + break; + + VclAccessibleEvent aEvent(VCLEVENT_MENU_HIGHLIGHT, xAccMenu); + FireVclEvent(&aEvent); + } + while (false); + } } } -- cgit From 443f0efd5acca6afe87f75d9f9f75844596622ac Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 26 Aug 2009 02:47:23 +0000 Subject: clear selected menu item when the popup ends. --- sc/source/ui/cctrl/dpcontrol.cxx | 49 ++++++++++++++++++++++++---------------- sc/source/ui/inc/dpcontrol.hxx | 8 +++++++ 2 files changed, 37 insertions(+), 20 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index e17ff0cd1dab..8b4c1ba6812e 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -303,6 +303,7 @@ ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, US SetFont(maLabelFont); SetText(OUString::createFromAscii("ScMenuFloatingWindow")); + SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, PopupEndHdl) ); } ScMenuFloatingWindow::~ScMenuFloatingWindow() @@ -537,6 +538,8 @@ void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, selectMenuItem(mnSelectedMenu, false, bSubMenuTimer); selectMenuItem(nPos, true, bSubMenuTimer); mnSelectedMenu = nPos; + + fireMenuHighlightedEvent(); } size_t ScMenuFloatingWindow::getSelectedMenuItem() const @@ -708,26 +711,6 @@ void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSub else queueCloseSubMenu(); } - - if (mxAccessible.is()) - { - // Fire a menu highlight event since the accessibility framework - // needs this to track focus on menu items. - do - { - Reference xAccCxt = mxAccessible->getAccessibleContext(); - if (!xAccCxt.is()) - break; - - Reference xAccMenu = xAccCxt->getAccessibleChild(nPos); - if (!xAccMenu.is()) - break; - - VclAccessibleEvent aEvent(VCLEVENT_MENU_HIGHLIGHT, xAccMenu); - FireVclEvent(&aEvent); - } - while (false); - } } } @@ -883,6 +866,26 @@ size_t ScMenuFloatingWindow::getSubMenuPos(ScMenuFloatingWindow* pSubMenu) return MENU_NOT_SELECTED; } +void ScMenuFloatingWindow::fireMenuHighlightedEvent() +{ + if (mnSelectedMenu == MENU_NOT_SELECTED) + return; + + if (!mxAccessible.is()) + return; + + Reference xAccCxt = mxAccessible->getAccessibleContext(); + if (!xAccCxt.is()) + return; + + Reference xAccMenu = xAccCxt->getAccessibleChild(mnSelectedMenu); + if (!xAccMenu.is()) + return; + + VclAccessibleEvent aEvent(VCLEVENT_MENU_HIGHLIGHT, xAccMenu); + FireVclEvent(&aEvent); +} + void ScMenuFloatingWindow::setSubMenuFocused(ScMenuFloatingWindow* pSubMenu) { maCloseTimer.reset(); @@ -941,6 +944,12 @@ void ScMenuFloatingWindow::terminateAllPopupMenus() mpParentMenu->terminateAllPopupMenus(); } +IMPL_LINK( ScMenuFloatingWindow, PopupEndHdl, void*, EMPTYARG ) +{ + clearSelectedMenuItem(); + return 0; +} + // ============================================================================ ScDPFieldPopupWindow::Member::Member() : diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 77fae133ce81..d8300ad25030 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -172,6 +172,12 @@ private: size_t getEnclosingMenuItem(const Point& rPos) const; size_t getSubMenuPos(ScMenuFloatingWindow* pSubMenu); + /** + * Fire a menu highlight event since the accessibility framework needs + * this to track focus on menu items. + */ + void fireMenuHighlightedEvent(); + /** * Make sure that the specified submenu is permanently up, the submenu * close timer is not active, and the correct menu item associated with @@ -198,6 +204,8 @@ private: */ void terminateAllPopupMenus(); + DECL_LINK( PopupEndHdl, void* ); + private: struct MenuItemData -- cgit From b4049f44bf9bb5c004d238063cf8ef56951553ce Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 26 Aug 2009 03:04:42 +0000 Subject: changed endSubMenu() to not rely on the open timer data to dismiss the sub menu. --- sc/source/ui/cctrl/dpcontrol.cxx | 17 +++++++++++------ sc/source/ui/inc/dpcontrol.hxx | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 8b4c1ba6812e..f4fbd02266fc 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -358,7 +358,7 @@ void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt) break; case KEY_LEFT: if (mpParentMenu) - mpParentMenu->endSubMenu(); + mpParentMenu->endSubMenu(this); break; case KEY_RIGHT: { @@ -636,14 +636,19 @@ void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos) SetPopupModeFlags(nOldFlags); } -void ScMenuFloatingWindow::endSubMenu() +void ScMenuFloatingWindow::endSubMenu(ScMenuFloatingWindow* pSubMenu) { + if (!pSubMenu) + return; + + pSubMenu->EndPopupMode(); + + size_t nMenuPos = getSubMenuPos(pSubMenu); + if (nMenuPos != MENU_NOT_SELECTED) + highlightMenuItem(nMenuPos, true); + if (maOpenTimer.mpSubMenu) - { - maOpenTimer.mpSubMenu->EndPopupMode(); maOpenTimer.mpSubMenu = NULL; - highlightMenuItem(maOpenTimer.mnMenuPos, true); - } } void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index d8300ad25030..4123d75ca4cd 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -152,7 +152,7 @@ protected: void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu); void queueCloseSubMenu(); void launchSubMenu(bool bSetMenuPos); - void endSubMenu(); + void endSubMenu(ScMenuFloatingWindow* pSubMenu); void fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const; -- cgit From b0838ee5af5000192b5784ca1da504be1db0b7cf Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 26 Aug 2009 03:14:06 +0000 Subject: read the highlighted menu of the parent popup when the child popup gets dismissed. --- sc/source/ui/cctrl/dpcontrol.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index f4fbd02266fc..7423ea4278fb 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -642,13 +642,15 @@ void ScMenuFloatingWindow::endSubMenu(ScMenuFloatingWindow* pSubMenu) return; pSubMenu->EndPopupMode(); + maOpenTimer.reset(); size_t nMenuPos = getSubMenuPos(pSubMenu); if (nMenuPos != MENU_NOT_SELECTED) + { highlightMenuItem(nMenuPos, true); - - if (maOpenTimer.mpSubMenu) - maOpenTimer.mpSubMenu = NULL; + mnSelectedMenu = nMenuPos; + fireMenuHighlightedEvent(); + } } void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const -- cgit From 5e8d3e43d3e4689d91d2f94d826146c076f907e6 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 26 Aug 2009 19:07:14 +0000 Subject: TAB key to cycle through controls. --- sc/source/ui/cctrl/dpcontrol.cxx | 57 ++++++++++++++++++++++++++++++++++++++++ sc/source/ui/inc/dpcontrol.hxx | 6 +++++ 2 files changed, 63 insertions(+) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 7423ea4278fb..4c9dee6b4af1 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -985,11 +985,21 @@ ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc) : maBtnUnselectSingle(this, 0), maBtnOk(this), maBtnCancel(this), + mnCurTabStop(0), mpExtendedData(NULL), mpOKAction(NULL), maWndSize(160, 330), mePrevToggleAllState(STATE_DONTKNOW) { + maTabStopCtrls.reserve(7); + maTabStopCtrls.push_back(this); + maTabStopCtrls.push_back(&maChecks); + maTabStopCtrls.push_back(&maChkToggleAll); + maTabStopCtrls.push_back(&maBtnSelectSingle); + maTabStopCtrls.push_back(&maBtnUnselectSingle); + maTabStopCtrls.push_back(&maBtnOk); + maTabStopCtrls.push_back(&maBtnCancel); + const StyleSettings& rStyle = GetSettings().GetStyleSettings(); Point aPos; @@ -1157,6 +1167,28 @@ void ScDPFieldPopupWindow::selectCurrentMemberOnly(bool bSet) maChecks.CheckEntryPos(nSelected, bSet); } +void ScDPFieldPopupWindow::cycleFocus(bool bReverse) +{ + maTabStopCtrls[mnCurTabStop]->LoseFocus(); + if (mnCurTabStop == 0) + clearSelectedMenuItem(); + + if (bReverse) + { + if (mnCurTabStop > 0) + --mnCurTabStop; + else + mnCurTabStop = maTabStopCtrls.size() - 1; + } + else + { + ++mnCurTabStop; + if (mnCurTabStop >= maTabStopCtrls.size()) + mnCurTabStop = 0; + } + maTabStopCtrls[mnCurTabStop]->GetFocus(); +} + IMPL_LINK( ScDPFieldPopupWindow, ButtonHdl, Button*, pBtn ) { if (pBtn == &maBtnOk) @@ -1225,6 +1257,26 @@ void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt) queueCloseSubMenu(); } +long ScDPFieldPopupWindow::Notify(NotifyEvent& rNEvt) +{ + switch (rNEvt.GetType()) + { + case EVENT_KEYUP: + { + const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent(); + const KeyCode& rCode = pKeyEvent->GetKeyCode(); + bool bShift = rCode.IsShift(); + if (rCode.GetCode() == KEY_TAB) + { + cycleFocus(bShift); + return true; + } + } + break; + } + return ScMenuFloatingWindow::Notify(rNEvt); +} + void ScDPFieldPopupWindow::Paint(const Rectangle& rRect) { ScMenuFloatingWindow::Paint(rRect); @@ -1248,6 +1300,11 @@ void ScDPFieldPopupWindow::Paint(const Rectangle& rRect) DrawRect(Rectangle(aPos,aSize)); } +Window* ScDPFieldPopupWindow::GetPreferredKeyInputWindow() +{ + return maTabStopCtrls[mnCurTabStop]; +} + Reference ScDPFieldPopupWindow::CreateAccessible() { if (!mxAccessible.is()) diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 4123d75ca4cd..ffab5f887238 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -273,7 +273,9 @@ public: virtual ~ScDPFieldPopupWindow(); virtual void MouseMove(const MouseEvent& rMEvt); + virtual long Notify(NotifyEvent& rNEvt); virtual void Paint(const Rectangle& rRect); + virtual Window* GetPreferredKeyInputWindow(); virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible(); void setMemberSize(size_t n); @@ -334,6 +336,7 @@ private: void setAllMemberState(bool bSet); void selectCurrentMemberOnly(bool bSet); + void cycleFocus(bool bReverse = false); DECL_LINK( ButtonHdl, Button* ); DECL_LINK( TriStateHdl, TriStateBox* ); @@ -349,6 +352,9 @@ private: OKButton maBtnOk; CancelButton maBtnCancel; + ::std::vector maTabStopCtrls; + size_t mnCurTabStop; + ::std::vector maMembers; ::std::auto_ptr mpExtendedData; ::std::auto_ptr mpOKAction; -- cgit From 984236d8b16fbb1c2728a7f4f2d25146865c6dee Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 26 Aug 2009 22:59:36 +0000 Subject: Use the new "fake focus" flag of Window to simulate focus state, in order to implement tab stops inside floating windows. --- sc/source/ui/cctrl/dpcontrol.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 4c9dee6b4af1..32fd88421a84 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -1169,6 +1169,7 @@ void ScDPFieldPopupWindow::selectCurrentMemberOnly(bool bSet) void ScDPFieldPopupWindow::cycleFocus(bool bReverse) { + maTabStopCtrls[mnCurTabStop]->SetFakeFocus(false); maTabStopCtrls[mnCurTabStop]->LoseFocus(); if (mnCurTabStop == 0) clearSelectedMenuItem(); @@ -1186,7 +1187,8 @@ void ScDPFieldPopupWindow::cycleFocus(bool bReverse) if (mnCurTabStop >= maTabStopCtrls.size()) mnCurTabStop = 0; } - maTabStopCtrls[mnCurTabStop]->GetFocus(); + maTabStopCtrls[mnCurTabStop]->SetFakeFocus(true); + maTabStopCtrls[mnCurTabStop]->GrabFocus(); } IMPL_LINK( ScDPFieldPopupWindow, ButtonHdl, Button*, pBtn ) -- cgit From 2d16f08b453f2b2a4a32f902caae616318a19701 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 27 Aug 2009 02:36:18 +0000 Subject: Use the new PopupMenuFloatingWindow instead of FloatingWindow for popup menu specific stuff. --- sc/source/ui/cctrl/dpcontrol.cxx | 2 +- sc/source/ui/inc/dpcontrol.hxx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 32fd88421a84..ee58c3dca601 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -283,7 +283,7 @@ IMPL_LINK( ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl, void*, EMPTYARG ) size_t ScMenuFloatingWindow::MENU_NOT_SELECTED = 999; ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel) : - FloatingWindow(pParent, (WB_SYSTEMFLOATWIN|WB_SYSTEMWINDOW|WB_NOBORDER)), + PopupMenuFloatingWindow(pParent), maOpenTimer(this), maCloseTimer(this), maName(OUString::createFromAscii("ScMenuFloatingWindow")), diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index ffab5f887238..1b99f6a38842 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -34,7 +34,7 @@ #include "rtl/ustring.hxx" #include "tools/gen.hxx" #include "tools/fract.hxx" -#include "vcl/floatwin.hxx" +#include "vcl/popupmenuwindow.hxx" #include "vcl/button.hxx" #include "vcl/scrbar.hxx" #include "vcl/timer.hxx" @@ -100,7 +100,7 @@ private: // ============================================================================ -class ScMenuFloatingWindow : public FloatingWindow +class ScMenuFloatingWindow : public PopupMenuFloatingWindow { public: static size_t MENU_NOT_SELECTED; -- cgit From 12f0af840124fa0f7acd088eafeb8e6d40c7c860 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 28 Aug 2009 04:13:17 +0000 Subject: fixed a build breakage. --- sc/source/filter/excel/xipivot.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sc') diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index 24ebce414c6a..b77df97a0448 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -1435,7 +1435,7 @@ void XclImpPivotTable::MaybeRefresh() { // 'refresh table on load' flag is set. Refresh the table now. Some // Excel files contain partial table output when this flag is set. - mpDPObj->Output(); + mpDPObj->Output(maOutScRange.aStart); } } -- cgit From 07d2c1eaebb1afc679438b15f0a26dd120e4c18e Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Tue, 1 Sep 2009 00:42:43 +0000 Subject: When assigning a display name to subtotal output, we should allow it only when the subtotal type of 'Automatic'. --- sc/source/ui/view/dbfunc3.cxx | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 307ccfc877bc..141d7e377f4e 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -44,19 +44,17 @@ #include #include #include +#include +#include +#include +#include #include #include -#include - -#include #include +#include #include -#include -#include -#include #include -#include -#include +#include #include "global.hxx" #include "globstr.hrc" @@ -1620,6 +1618,13 @@ void ScDBFunc::DataPilotInput( const ScAddress& rPos, const String& rString ) if (aData.GetDataDimensionCount() > 1) break; + // display name for subtotal is allowed only if the subtotal type is 'Automatic'. + if (pDim->GetSubTotalsCount() != 1) + break; + + if (pDim->GetSubTotalFunc(0) != sheet::GeneralFunction_AUTO) + break; + const OUString* pLayoutName = pMem->GetLayoutName(); String aMemberName; if (pLayoutName) -- cgit From e862adfa2e024d63ad86c6ad043b7d073598bf69 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 2 Sep 2009 03:53:11 +0000 Subject: Initial work toward showing the display names (aka layout names) for field and field members when appropriate. Refactored ScDPLabelData quite a bit. I'm not entirely done with this yet. --- sc/inc/dpobject.hxx | 13 ++--- sc/inc/miscuno.hxx | 3 ++ sc/inc/pivot.hxx | 16 ++++-- sc/source/core/data/dpobject.cxx | 110 ++++++++++++++++++--------------------- sc/source/core/data/pivot2.cxx | 6 +++ sc/source/ui/dbgui/pvfundlg.cxx | 41 +++++++++++---- sc/source/ui/dbgui/pvlaydlg.cxx | 42 +++++++-------- sc/source/ui/unoobj/dapiuno.cxx | 2 +- sc/source/ui/unoobj/miscuno.cxx | 20 +++++++ sc/source/ui/view/dbfunc3.cxx | 2 +- sc/source/ui/view/gridwin2.cxx | 42 +++++++++++++-- 11 files changed, 186 insertions(+), 111 deletions(-) (limited to 'sc') diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index f86cafdf81fd..a2e8c3f9e7e2 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -36,6 +36,7 @@ #include "address.hxx" #include "collect.hxx" #include "dpoutput.hxx" +#include "pivot.hxx" #include #include @@ -212,16 +213,10 @@ public: sal_Int32 GetUsedHierarchy( sal_Int32 nDim ); BOOL GetMembersNA( sal_Int32 nDim, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers ); - BOOL GetMembers( sal_Int32 nDim, - com::sun::star::uno::Sequence< rtl::OUString >& rMembers, - com::sun::star::uno::Sequence< sal_Bool >* pVisible = 0, - com::sun::star::uno::Sequence< sal_Bool >* pShowDet = 0 ); - BOOL GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers ); - BOOL GetMembers( sal_Int32 nDim, sal_Int32 nHier, - com::sun::star::uno::Sequence< rtl::OUString >& rMembers, - com::sun::star::uno::Sequence< sal_Bool >* pVisible = 0, - com::sun::star::uno::Sequence< sal_Bool >* pShowDet = 0 ); + + bool GetMemberNames( sal_Int32 nDim, ::com::sun::star::uno::Sequence< ::rtl::OUString >& rNames ); + bool GetMembers( sal_Int32 nDim, sal_Int32 nHier, ::std::vector& rMembers ); void UpdateReference( UpdateRefMode eUpdateRefMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ); diff --git a/sc/inc/miscuno.hxx b/sc/inc/miscuno.hxx index 7f6bd4774faf..df60b2822cb8 100644 --- a/sc/inc/miscuno.hxx +++ b/sc/inc/miscuno.hxx @@ -285,6 +285,9 @@ public: static sal_Int32 GetEnumProperty( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet>& xProp, const ::rtl::OUString& rName, long nDefault ); + static ::rtl::OUString GetStringProperty( + const com::sun::star::uno::Reference& xProp, + const ::rtl::OUString& rName, const ::rtl::OUString& rDefault ); static sal_Bool GetBoolFromAny( const com::sun::star::uno::Any& aAny ); static sal_Int16 GetInt16FromAny( const com::sun::star::uno::Any& aAny ); diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx index e2b8ef3e01fa..6e3088eeb1e9 100644 --- a/sc/inc/pivot.hxx +++ b/sc/inc/pivot.hxx @@ -368,17 +368,25 @@ public: struct ScDPLabelData { - String maName; /// Visible name of the dimension. + String maName; /// Original name of the dimension. + ::rtl::OUString maLayoutName; /// Layout name (display name) SCsCOL mnCol; USHORT mnFuncMask; /// Page/Column/Row subtotal function. sal_Int32 mnUsedHier; /// Used hierarchy. bool mbShowAll; /// true = Show all (also empty) results. bool mbIsValue; /// true = Sum or count in data field. + struct Member + { + ::rtl::OUString maName; + ::rtl::OUString maLayoutName; + bool mbVisible; + bool mbShowDetails; + + Member(); + }; + ::std::vector maMembers; ::com::sun::star::uno::Sequence< ::rtl::OUString > maHiers; /// Hierarchies. - ::com::sun::star::uno::Sequence< ::rtl::OUString > maMembers; /// Members. - ::com::sun::star::uno::Sequence< sal_Bool > maVisible; /// Visibility of members. - ::com::sun::star::uno::Sequence< sal_Bool > maShowDet; /// Show details of members. ::com::sun::star::sheet::DataPilotFieldSortInfo maSortInfo; /// Sorting info. ::com::sun::star::sheet::DataPilotFieldLayoutInfo maLayoutInfo; /// Layout info. ::com::sun::star::sheet::DataPilotFieldAutoShowInfo maShowInfo; /// AutoShow info. diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index bd11044c80b9..67c8c21d31c7 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -75,6 +75,7 @@ #include // IsNumberFormat #include +#include using namespace com::sun::star; using ::std::vector; @@ -597,6 +598,51 @@ void ScDPObject::BuildAllDimensionMembers() pSaveData->BuildAllDimensionMembers(GetTableData()); } +bool ScDPObject::GetMemberNames( sal_Int32 nDim, Sequence& rNames ) +{ + vector aMembers; + GetMembers(nDim, GetUsedHierarchy(nDim), aMembers); + size_t n = aMembers.size(); + rNames.realloc(n); + for (size_t i = 0; i < n; ++i) + rNames[i] = aMembers[i].maName; +} + +bool ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, vector& rMembers ) +{ + Reference< container::XNameAccess > xMembersNA; + if (!GetMembersNA( nDim, nHier, xMembersNA )) + return false; + + Reference xMembersIA( new ScNameToIndexAccess(xMembersNA) ); + sal_Int32 nCount = xMembersIA->getCount(); + vector aMembers; + aMembers.reserve(nCount); + + for (sal_Int32 i = 0; i < nCount; ++i) + { + Reference xMember(xMembersIA->getByIndex(i), UNO_QUERY); + ScDPLabelData::Member aMem; + + if (xMember.is()) + aMem.maName = xMember->getName(); + + Reference xMemProp(xMember, UNO_QUERY); + if (xMemProp.is()) + { + aMem.mbVisible = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_ISVISIBL)); + aMem.mbShowDetails = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_SHOWDETA)); + + aMem.maLayoutName = ScUnoHelpFunctions::GetStringProperty( + xMemProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString()); + } + + aMembers.push_back(aMem); + } + rMembers.swap(aMembers); + return true; +} + void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode, const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ) { @@ -1867,6 +1913,7 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam) for (long nDim=0; nDim < nDimCount; nDim++) { String aFieldName; + OUString aLayoutName; uno::Reference xIntDim = ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) ); uno::Reference xDimName( xIntDim, uno::UNO_QUERY ); @@ -1888,6 +1935,9 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam) uno::Reference xIntOrig; if ( (aOrigAny >>= xIntOrig) && xIntOrig.is() ) bDuplicated = TRUE; + + aOrigAny = xDimProp->getPropertyValue(OUString::createFromAscii(SC_UNO_LAYOUTNAME)); + aOrigAny >>= aLayoutName; } catch(uno::Exception&) { @@ -1899,8 +1949,9 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam) bool bIsValue = true; //! check ScDPLabelDataRef pNewLabel(new ScDPLabelData(aFieldName, nCol, bIsValue)); + pNewLabel->maLayoutName = aLayoutName; GetHierarchies(nDim, pNewLabel->maHiers); - GetMembers(nDim, pNewLabel->maMembers, &pNewLabel->maVisible, &pNewLabel->maShowDet); + GetMembers(nDim, GetUsedHierarchy(nDim), pNewLabel->maMembers); lcl_FillLabelData(*pNewLabel, xDimProp); rParam.maLabelArray.push_back(pNewLabel); } @@ -1955,14 +2006,6 @@ BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, uno::Reference< container::XNameA return GetMembersNA( nDim, GetUsedHierarchy( nDim ), xMembers ); } -BOOL ScDPObject::GetMembers( sal_Int32 nDim, - uno::Sequence< rtl::OUString >& rMembers, - uno::Sequence< sal_Bool >* pVisible, - uno::Sequence< sal_Bool >* pShowDet ) -{ - return GetMembers( nDim, GetUsedHierarchy( nDim ), rMembers, pVisible, pShowDet ); -} - BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference< container::XNameAccess >& xMembers ) { BOOL bRet = FALSE; @@ -1998,55 +2041,6 @@ BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference< return bRet; } -BOOL ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, - uno::Sequence< rtl::OUString >& rMembers, - uno::Sequence< sal_Bool >* pVisible, - uno::Sequence< sal_Bool >* pShowDet ) -{ - BOOL bRet = FALSE; - uno::Reference< container::XNameAccess > xMembersNA; - if( GetMembersNA( nDim, nHier, xMembersNA ) ) - { - uno::Reference< container::XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) ); - sal_Int32 nCount = xMembersIA->getCount(); - rMembers.realloc( nCount ); - if( pVisible ) - pVisible->realloc( nCount ); - if( pShowDet ) - pShowDet->realloc( nCount ); - - rtl::OUString* pAry = rMembers.getArray(); - for( sal_Int32 nItem = 0; nItem < nCount; ++nItem ) - { - uno::Reference< container::XNamed > xMember( xMembersIA->getByIndex( nItem ), uno::UNO_QUERY ); - if( xMember.is() ) - pAry[ nItem ] = xMember->getName(); - if( pVisible || pShowDet ) - { - uno::Reference< beans::XPropertySet > xMemProp( xMember, uno::UNO_QUERY ); - if( pVisible ) - { - sal_Bool bVis = sal_True; - if( xMemProp.is() ) - bVis = ScUnoHelpFunctions::GetBoolProperty( xMemProp, - rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ISVISIBL ) ) ); - (*pVisible)[ nItem ] = bVis; - } - if( pShowDet ) - { - sal_Bool bShow = sal_True; - if( xMemProp.is() ) - bShow = ScUnoHelpFunctions::GetBoolProperty( xMemProp, - rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWDETA ) ) ); - (*pShowDet)[ nItem ] = bShow; - } - } - } - bRet = TRUE; - } - return bRet; -} - //------------------------------------------------------------------------ // convert old pivot tables into new datapilot tables diff --git a/sc/source/core/data/pivot2.cxx b/sc/source/core/data/pivot2.cxx index e96bb25c011d..e0e517bb0178 100644 --- a/sc/source/core/data/pivot2.cxx +++ b/sc/source/core/data/pivot2.cxx @@ -487,6 +487,12 @@ ScDataObject* ScPivotCollection::Clone() const // ============================================================================ +ScDPLabelData::Member::Member() : + mbVisible(true), + mbShowDetails(true) +{ +} + ScDPLabelData::ScDPLabelData( const String& rName, short nCol, bool bIsValue ) : maName( rName ), mnCol( nCol ), diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx index dac8ee1e5e04..284e7bdf15f6 100644 --- a/sc/source/ui/dbgui/pvfundlg.cxx +++ b/sc/source/ui/dbgui/pvfundlg.cxx @@ -48,12 +48,15 @@ #include "pvfundlg.hrc" #include "globstr.hrc" +#include + // ============================================================================ using namespace ::com::sun::star::sheet; using ::rtl::OUString; using ::com::sun::star::uno::Sequence; +using ::std::vector; // ============================================================================ @@ -86,6 +89,26 @@ bool lclFillListBox( ListBoxType& rLBox, const Sequence< OUString >& rStrings, U return bEmpty; } +template< typename ListBoxType > +bool lclFillListBox( ListBoxType& rLBox, const vector& rMembers, USHORT nEmptyPos = LISTBOX_APPEND ) +{ + bool bEmpty = false; + vector::const_iterator itr = rMembers.begin(), itrEnd = rMembers.end(); + for (; itr != itrEnd; ++itr) + { + if (itr->maLayoutName.getLength()) + rLBox.InsertEntry(itr->maLayoutName); + else if (itr->maName.getLength()) + rLBox.InsertEntry(itr->maName); + else + { + rLBox.InsertEntry(ScGlobal::GetRscString(STR_EMPTYDATA), nEmptyPos); + bEmpty = true; + } + } + return bEmpty; +} + /** Searches for a listbox entry, starts search at specified position. */ USHORT lclFindListBoxEntry( const ListBox& rLBox, const String& rEntry, USHORT nStartPos ) { @@ -253,7 +276,10 @@ void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData& maLbFunc.SetSelection( nFuncMask ); // field name - maFtName.SetText( rLabelData.maName ); + if (rLabelData.maLayoutName.getLength()) + maFtName.SetText(rLabelData.maLayoutName); + else + maFtName.SetText(rLabelData.maName); // "More button" controls maBtnMore.AddWindow( &maFlDisplay ); @@ -414,8 +440,6 @@ void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const rLabelData.mnUsedHier = maLabelData.mnUsedHier; rLabelData.mbShowAll = maCbShowAll.IsChecked(); rLabelData.maMembers = maLabelData.maMembers; - rLabelData.maVisible = maLabelData.maVisible; - rLabelData.maShowDet = maLabelData.maShowDet; rLabelData.maSortInfo = maLabelData.maSortInfo; rLabelData.maLayoutInfo = maLabelData.maLayoutInfo; rLabelData.maShowInfo = maLabelData.maShowInfo; @@ -547,9 +571,8 @@ void ScDPSubtotalOptDlg::FillLabelData( ScDPLabelData& rLabelData ) const rLabelData.maMembers = maLabelData.maMembers; ULONG nVisCount = maLbHide.GetEntryCount(); - rLabelData.maVisible.realloc( nVisCount ); for( USHORT nPos = 0; nPos < nVisCount; ++nPos ) - rLabelData.maVisible[ nPos ] = !maLbHide.IsChecked( nPos ); + rLabelData.maMembers[nPos].mbVisible = !maLbHide.IsChecked(nPos); // *** HIERARCHY *** @@ -656,8 +679,9 @@ void ScDPSubtotalOptDlg::InitHideListBox() { maLbHide.Clear(); lclFillListBox( maLbHide, maLabelData.maMembers ); - for( sal_Int32 nVisIdx = 0, nVisSize = maLabelData.maVisible.getLength(); nVisIdx < nVisSize; ++nVisIdx ) - maLbHide.CheckEntryPos( static_cast< USHORT >( nVisIdx ), !maLabelData.maVisible[ nVisIdx ] ); + size_t n = maLabelData.maMembers.size(); + for (size_t i = 0; i < n; ++i) + maLbHide.CheckEntryPos(static_cast(i), !maLabelData.maMembers[i].mbVisible); bool bEnable = maLbHide.GetEntryCount() > 0; maFlHide.Enable( bEnable ); maLbHide.Enable( bEnable ); @@ -690,8 +714,7 @@ IMPL_LINK( ScDPSubtotalOptDlg, SelectHdl, ListBox*, pLBox ) { if( pLBox == &maLbHierarchy ) { - mrDPObj.GetMembers( maLabelData.mnCol, maLbHierarchy.GetSelectEntryPos(), - maLabelData.maMembers, &maLabelData.maVisible, &maLabelData.maShowDet ); + mrDPObj.GetMembers(maLabelData.mnCol, maLbHierarchy.GetSelectEntryPos(), maLabelData.maMembers); InitHideListBox(); } return 0; diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx index 688c0d60f79e..d1959bbf79d1 100644 --- a/sc/source/ui/dbgui/pvlaydlg.cxx +++ b/sc/source/ui/dbgui/pvlaydlg.cxx @@ -1546,33 +1546,27 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG ) bool bManualSort = ( aIt->maSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL ); // visibility of members - if( const rtl::OUString* pItem = aIt->maMembers.getConstArray() ) + for (vector::const_iterator itr = aIt->maMembers.begin(), itrEnd = aIt->maMembers.end(); + itr != itrEnd; ++itr) { - sal_Int32 nIdx = 0; - sal_Int32 nVisSize = aIt->maVisible.getLength(); - sal_Int32 nShowSize = aIt->maShowDet.getLength(); - for( const rtl::OUString* pEnd = pItem + aIt->maMembers.getLength(); pItem != pEnd; ++pItem, ++nIdx ) + ScDPSaveMember* pMember = pDim->GetMemberByName(itr->maName); + + // #i40054# create/access members only if flags are not default + // (or in manual sorting mode - to keep the order) + if (bManualSort || !itr->mbVisible || !itr->mbShowDetails) + { + pMember->SetIsVisible(itr->mbVisible); + pMember->SetShowDetails(itr->mbShowDetails); + } + if (pOldDim) { - // #i40054# create/access members only if flags are not default - // (or in manual sorting mode - to keep the order) - bool bIsVisible = (nIdx >= nVisSize) || aIt->maVisible[ nIdx ]; - bool bShowDetails = (nIdx >= nShowSize) || aIt->maShowDet[ nIdx ]; - if( bManualSort || !bIsVisible || !bShowDetails ) + // Transfer the existing layout name. + ScDPSaveMember* pOldMember = pOldDim->GetMemberByName(itr->maName); + if (pOldMember) { - ScDPSaveMember* pMember = pDim->GetMemberByName( *pItem ); - pMember->SetIsVisible( bIsVisible ); - pMember->SetShowDetails( bShowDetails ); - if (pOldDim) - { - // Transfer the existing layout name. - ScDPSaveMember* pOldMember = pOldDim->GetMemberByName(*pItem); - if (pOldMember) - { - const OUString* pLayoutName = pOldMember->GetLayoutName(); - if (pLayoutName) - pMember->SetLayoutName(*pLayoutName); - } - } + const OUString* pLayoutName = pOldMember->GetLayoutName(); + if (pLayoutName) + pMember->SetLayoutName(*pLayoutName); } } } diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index c52921f7c5de..efc498517f1b 100644 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -3074,7 +3074,7 @@ Sequence SAL_CALL ScDataPilotItemsObj::getElementNames() ScUnoGuard aGuard; Sequence< OUString > aSeq; if( ScDPObject* pDPObj = GetDPObject() ) - pDPObj->GetMembers( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq ); + pDPObj->GetMemberNames( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq ); return aSeq; } diff --git a/sc/source/ui/unoobj/miscuno.cxx b/sc/source/ui/unoobj/miscuno.cxx index 090073e259ae..ee2a64bd8c78 100644 --- a/sc/source/ui/unoobj/miscuno.cxx +++ b/sc/source/ui/unoobj/miscuno.cxx @@ -140,6 +140,26 @@ sal_Int32 ScUnoHelpFunctions::GetEnumProperty( const uno::Reference& xProp, const OUString& rName, const OUString& rDefault ) +{ + OUString aRet = rDefault; + if (!xProp.is()) + return aRet; + + try + { + Any any = xProp->getPropertyValue(rName); + any >>= aRet; + } + catch (const uno::Exception&) + { + } + + return aRet; +} + // static sal_Bool ScUnoHelpFunctions::GetBoolFromAny( const uno::Any& aAny ) { diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 141d7e377f4e..dcad0cbce885 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -1868,7 +1868,7 @@ BOOL ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest ) // get all member names in source order uno::Sequence aMemberNames; - pDPObj->GetMembers( aDestData.Dimension, aMemberNames ); + pDPObj->GetMemberNames( aDestData.Dimension, aMemberNames ); bool bInserted = false; diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index 5a01a642ac24..dc278f4e3def 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -916,10 +916,17 @@ void ScGridWindow::DPLaunchFieldPopupMenu( mpDPFieldPopup->setExtendedData(pDPData.release()); mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this)); { - sal_Int32 n = rLabelData.maMembers.getLength(); + // Populate field members. + size_t n = rLabelData.maMembers.size(); mpDPFieldPopup->setMemberSize(n); - for (sal_Int32 i = 0; i < n; ++i) - mpDPFieldPopup->addMember(rLabelData.maMembers[i], rLabelData.maVisible[i]); + for (size_t i = 0; i < n; ++i) + { + const ScDPLabelData::Member& rMem = rLabelData.maMembers[i]; + if (rMem.maLayoutName.getLength()) + mpDPFieldPopup->addMember(rMem.maLayoutName, rMem.mbVisible); + else + mpDPFieldPopup->addMember(rMem.maName, rMem.mbVisible); + } mpDPFieldPopup->initMembers(); } @@ -973,6 +980,9 @@ void ScGridWindow::DPLaunchFieldPopupMenu( void ScGridWindow::UpdateDPFromFieldPopupMenu() { + typedef hash_map MemNameMapType; + typedef hash_map MemVisibilityType; + if (!mpDPFieldPopup.get()) return; @@ -991,8 +1001,30 @@ void ScGridWindow::UpdateDPFromFieldPopupMenu() if (!pDim) return; - hash_map aResult; - mpDPFieldPopup->getResult(aResult); + // Build a map of layout names to original names. + const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim]; + MemNameMapType aMemNameMap; + for (vector::const_iterator itr = rLabelData.maMembers.begin(), itrEnd = rLabelData.maMembers.end(); + itr != itrEnd; ++itr) + aMemNameMap.insert(MemNameMapType::value_type(itr->maLayoutName, itr->maName)); + + // The raw result may contain a mixture of layout names and original names. + MemVisibilityType aRawResult; + mpDPFieldPopup->getResult(aRawResult); + + MemVisibilityType aResult; + for (MemVisibilityType::const_iterator itr = aRawResult.begin(), itrEnd = aRawResult.end(); itr != itrEnd; ++itr) + { + MemNameMapType::const_iterator itrNameMap = aMemNameMap.find(itr->first); + if (itrNameMap == aMemNameMap.end()) + // This is an original member name. Use it as-is. + aResult.insert(MemVisibilityType::value_type(itr->first, itr->second)); + else + { + // This is a layout name. Get the original member name and use it. + aResult.insert(MemVisibilityType::value_type(itrNameMap->second, itr->second)); + } + } pDim->UpdateMemberVisibility(aResult); ScDBDocFunc aFunc(*pViewData->GetDocShell()); -- cgit From 9b0c9920d629acbdf8516e13ba045cfea7b1fd97 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 2 Sep 2009 04:17:43 +0000 Subject: Show display names (aka layout names) of fields in the dp layout dialog and its child dialogs. --- sc/inc/pivot.hxx | 2 +- sc/source/ui/dbgui/pvfundlg.cxx | 18 +++++++++++++++--- sc/source/ui/dbgui/pvlaydlg.cxx | 21 +++++++++++++++------ 3 files changed, 31 insertions(+), 10 deletions(-) (limited to 'sc') diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx index 6e3088eeb1e9..b8ca4da7762b 100644 --- a/sc/inc/pivot.hxx +++ b/sc/inc/pivot.hxx @@ -368,7 +368,7 @@ public: struct ScDPLabelData { - String maName; /// Original name of the dimension. + ::rtl::OUString maName; /// Original name of the dimension. ::rtl::OUString maLayoutName; /// Layout name (display name) SCsCOL mnCol; USHORT mnFuncMask; /// Page/Column/Row subtotal function. diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx index 284e7bdf15f6..2b755769517c 100644 --- a/sc/source/ui/dbgui/pvfundlg.cxx +++ b/sc/source/ui/dbgui/pvfundlg.cxx @@ -297,7 +297,12 @@ void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData& // base field list box for( ScDPLabelDataVec::const_iterator aIt = mrLabelVec.begin(), aEnd = mrLabelVec.end(); aIt != aEnd; ++aIt ) - maLbBaseField.InsertEntry( aIt->maName ); + { + if (aIt->maLayoutName.getLength()) + maLbBaseField.InsertEntry( aIt->maLayoutName ); + else + maLbBaseField.InsertEntry( aIt->maName ); + } // base item list box maLbBaseItem.SetSeparatorPos( SC_BASEITEM_USER_POS - 1 ); @@ -448,7 +453,10 @@ void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const void ScDPSubtotalDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData ) { // field name - maFtName.SetText( rLabelData.maName ); + if (rLabelData.maLayoutName.getLength()) + maFtName.SetText( rLabelData.maLayoutName ); + else + maFtName.SetText( rLabelData.maName ); // radio buttons maRbNone.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) ); @@ -586,7 +594,11 @@ void ScDPSubtotalOptDlg::Init( const ScDPNameVec& rDataFields, bool bEnableLayou sal_Int32 nSortMode = maLabelData.maSortInfo.Mode; // sort fields list box - maLbSortBy.InsertEntry( maLabelData.maName ); + if (maLabelData.maLayoutName.getLength()) + maLbSortBy.InsertEntry( maLabelData.maLayoutName ); + else + maLbSortBy.InsertEntry( maLabelData.maName ); + for( ScDPNameVec::const_iterator aIt = rDataFields.begin(), aEnd = rDataFields.end(); aIt != aEnd; ++aIt ) { maLbSortBy.InsertEntry( *aIt ); diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx index d1959bbf79d1..ea70891a8d1d 100644 --- a/sc/source/ui/dbgui/pvlaydlg.cxx +++ b/sc/source/ui/dbgui/pvlaydlg.cxx @@ -395,7 +395,10 @@ void ScDPLayoutDlg::InitWndSelect( const vector& rLabels ) if ( i <= nLast ) { - aWndSelect.AddField( aLabelDataArr[i].maName, i ); + OUString aFieldName = aLabelDataArr[i].maName; + if (aLabelDataArr[i].maLayoutName.getLength()) + aFieldName = aLabelDataArr[i].maLayoutName; + aWndSelect.AddField(aFieldName, i); aSelectArr[i].reset( new ScDPFuncData( aLabelDataArr[i].mnCol, aLabelDataArr[i].mnFuncMask ) ); } } @@ -596,7 +599,7 @@ void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Po if ( !bDataArr ) { - if ( toWnd->AddField( rData.maName, + if ( toWnd->AddField( rData.maLayoutName.getLength() ? rData.maLayoutName : rData.maName, DlgPos2WndPos( rAtPos, *toWnd ), nAddedAt ) ) { @@ -607,9 +610,12 @@ void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Po else { USHORT nMask = fData.mnFuncMask; - String aStr( GetFuncString( nMask, rData.mbIsValue ) ); + OUString aStr = GetFuncString( nMask, rData.mbIsValue ); - aStr += rData.maName; + if (rData.maLayoutName.getLength()) + aStr += rData.maLayoutName; + else + aStr += rData.maName; if ( toWnd->AddField( aStr, DlgPos2WndPos( rAtPos, *toWnd ), @@ -1217,7 +1223,7 @@ String ScDPLayoutDlg::GetLabelString( SCsCOL nCol ) ScDPLabelData* pData = GetLabelData( nCol ); DBG_ASSERT( pData, "LabelData not found" ); if (pData) - return pData->maName; + return pData->maLayoutName.getLength() ? pData->maLayoutName : pData->maName; return String(); } @@ -1756,7 +1762,10 @@ IMPL_LINK( ScDPLayoutDlg, ScrollHdl, ScrollBar *, EMPTYARG ) for ( i=0; i Date: Wed, 2 Sep 2009 19:09:26 +0000 Subject: Fixed a bug where the layout names of field members get lost when updating the table from the layout dialog. --- sc/source/core/data/dpobject.cxx | 13 ++++++++----- sc/source/core/data/dpsave.cxx | 4 ---- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'sc') diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 67c8c21d31c7..b09744747f23 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -601,11 +601,15 @@ void ScDPObject::BuildAllDimensionMembers() bool ScDPObject::GetMemberNames( sal_Int32 nDim, Sequence& rNames ) { vector aMembers; - GetMembers(nDim, GetUsedHierarchy(nDim), aMembers); + if (!GetMembers(nDim, GetUsedHierarchy(nDim), aMembers)) + return false; + size_t n = aMembers.size(); rNames.realloc(n); for (size_t i = 0; i < n; ++i) rNames[i] = aMembers[i].maName; + + return true; } bool ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, vector& rMembers ) @@ -1913,7 +1917,6 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam) for (long nDim=0; nDim < nDimCount; nDim++) { String aFieldName; - OUString aLayoutName; uno::Reference xIntDim = ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) ); uno::Reference xDimName( xIntDim, uno::UNO_QUERY ); @@ -1935,14 +1938,14 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam) uno::Reference xIntOrig; if ( (aOrigAny >>= xIntOrig) && xIntOrig.is() ) bDuplicated = TRUE; - - aOrigAny = xDimProp->getPropertyValue(OUString::createFromAscii(SC_UNO_LAYOUTNAME)); - aOrigAny >>= aLayoutName; } catch(uno::Exception&) { } + OUString aLayoutName = ScUnoHelpFunctions::GetStringProperty( + xDimProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString()); + if ( aFieldName.Len() && !bData && !bDuplicated ) { SCsCOL nCol = static_cast< SCsCOL >( nDim ); //! ??? diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx index 7ab7a13c7fc1..829a948ed5e2 100644 --- a/sc/source/core/data/dpsave.cxx +++ b/sc/source/core/data/dpsave.cxx @@ -196,10 +196,6 @@ void ScDPSaveMember::RemoveLayoutName() void ScDPSaveMember::WriteToSource( const uno::Reference& xMember, sal_Int32 nPosition ) { - // nothing to do? - if ( nVisibleMode == SC_DPSAVEMODE_DONTKNOW && nShowDetailsMode == SC_DPSAVEMODE_DONTKNOW && nPosition < 0 ) - return; - uno::Reference xMembProp( xMember, uno::UNO_QUERY ); DBG_ASSERT( xMembProp.is(), "no properties at member" ); if ( xMembProp.is() ) -- cgit From 8cf3d5f0317095f6a39ec7e0bfccf2b2d2d41aa2 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 2 Sep 2009 20:13:36 +0000 Subject: added getDisplayName() to ScDPLabelData, to keep the client code a little cleaner. --- sc/inc/pivot.hxx | 14 ++++++++++++++ sc/source/core/data/pivot2.cxx | 17 +++++++++++++++++ sc/source/ui/dbgui/pvfundlg.cxx | 14 ++++---------- sc/source/ui/view/gridwin2.cxx | 5 +---- 4 files changed, 36 insertions(+), 14 deletions(-) (limited to 'sc') diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx index b8ca4da7762b..ad5ec926ed97 100644 --- a/sc/inc/pivot.hxx +++ b/sc/inc/pivot.hxx @@ -384,6 +384,13 @@ struct ScDPLabelData bool mbShowDetails; Member(); + + /** + * return the name that should be displayed in the dp dialogs i.e. + * when the layout name is present, use it, or else use the original + * name. + */ + ::rtl::OUString SC_DLLPUBLIC getDisplayName() const; }; ::std::vector maMembers; ::com::sun::star::uno::Sequence< ::rtl::OUString > maHiers; /// Hierarchies. @@ -392,6 +399,13 @@ struct ScDPLabelData ::com::sun::star::sheet::DataPilotFieldAutoShowInfo maShowInfo; /// AutoShow info. explicit ScDPLabelData( const String& rName, short nCol, bool bIsValue ); + + /** + * return the name that should be displayed in the dp dialogs i.e. + * when the layout name is present, use it, or else use the original + * name. + */ + ::rtl::OUString SC_DLLPUBLIC getDisplayName() const; }; // ============================================================================ diff --git a/sc/source/core/data/pivot2.cxx b/sc/source/core/data/pivot2.cxx index e0e517bb0178..1e8eb63e99ec 100644 --- a/sc/source/core/data/pivot2.cxx +++ b/sc/source/core/data/pivot2.cxx @@ -61,6 +61,7 @@ #include "stlsheet.hxx" using ::com::sun::star::sheet::DataPilotFieldReference; +using ::rtl::OUString; // STATIC DATA ----------------------------------------------------------- @@ -493,6 +494,14 @@ ScDPLabelData::Member::Member() : { } +OUString ScDPLabelData::Member::getDisplayName() const +{ + if (maLayoutName.getLength()) + return maLayoutName; + + return maName; +} + ScDPLabelData::ScDPLabelData( const String& rName, short nCol, bool bIsValue ) : maName( rName ), mnCol( nCol ), @@ -503,6 +512,14 @@ ScDPLabelData::ScDPLabelData( const String& rName, short nCol, bool bIsValue ) : { } +OUString ScDPLabelData::getDisplayName() const +{ + if (maLayoutName.getLength()) + return maLayoutName; + + return maName; +} + // ============================================================================ ScDPFuncData::ScDPFuncData( short nCol, USHORT nFuncMask ) : diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx index 2b755769517c..e272be0edb7f 100644 --- a/sc/source/ui/dbgui/pvfundlg.cxx +++ b/sc/source/ui/dbgui/pvfundlg.cxx @@ -96,10 +96,9 @@ bool lclFillListBox( ListBoxType& rLBox, const vector& rM vector::const_iterator itr = rMembers.begin(), itrEnd = rMembers.end(); for (; itr != itrEnd; ++itr) { - if (itr->maLayoutName.getLength()) - rLBox.InsertEntry(itr->maLayoutName); - else if (itr->maName.getLength()) - rLBox.InsertEntry(itr->maName); + OUString aName = itr->getDisplayName(); + if (aName.getLength()) + rLBox.InsertEntry(aName); else { rLBox.InsertEntry(ScGlobal::GetRscString(STR_EMPTYDATA), nEmptyPos); @@ -297,12 +296,7 @@ void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData& // base field list box for( ScDPLabelDataVec::const_iterator aIt = mrLabelVec.begin(), aEnd = mrLabelVec.end(); aIt != aEnd; ++aIt ) - { - if (aIt->maLayoutName.getLength()) - maLbBaseField.InsertEntry( aIt->maLayoutName ); - else - maLbBaseField.InsertEntry( aIt->maName ); - } + maLbBaseField.InsertEntry(aIt->getDisplayName()); // base item list box maLbBaseItem.SetSeparatorPos( SC_BASEITEM_USER_POS - 1 ); diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index dc278f4e3def..19a059bf3af1 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -922,10 +922,7 @@ void ScGridWindow::DPLaunchFieldPopupMenu( for (size_t i = 0; i < n; ++i) { const ScDPLabelData::Member& rMem = rLabelData.maMembers[i]; - if (rMem.maLayoutName.getLength()) - mpDPFieldPopup->addMember(rMem.maLayoutName, rMem.mbVisible); - else - mpDPFieldPopup->addMember(rMem.maName, rMem.mbVisible); + mpDPFieldPopup->addMember(rMem.getDisplayName(), rMem.mbVisible); } mpDPFieldPopup->initMembers(); } -- cgit From fb8e51e2a5dc9d95a3465ca3041b0b27591df0a6 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 2 Sep 2009 20:21:52 +0000 Subject: More use for ScDPLabelData::getDisplayName(). --- sc/source/ui/dbgui/pvfundlg.cxx | 15 +++------------ sc/source/ui/dbgui/pvlaydlg.cxx | 19 +++++-------------- 2 files changed, 8 insertions(+), 26 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx index e272be0edb7f..30ee1a44d384 100644 --- a/sc/source/ui/dbgui/pvfundlg.cxx +++ b/sc/source/ui/dbgui/pvfundlg.cxx @@ -275,10 +275,7 @@ void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData& maLbFunc.SetSelection( nFuncMask ); // field name - if (rLabelData.maLayoutName.getLength()) - maFtName.SetText(rLabelData.maLayoutName); - else - maFtName.SetText(rLabelData.maName); + maFtName.SetText(rLabelData.getDisplayName()); // "More button" controls maBtnMore.AddWindow( &maFlDisplay ); @@ -447,10 +444,7 @@ void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const void ScDPSubtotalDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData ) { // field name - if (rLabelData.maLayoutName.getLength()) - maFtName.SetText( rLabelData.maLayoutName ); - else - maFtName.SetText( rLabelData.maName ); + maFtName.SetText(rLabelData.getDisplayName()); // radio buttons maRbNone.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) ); @@ -588,10 +582,7 @@ void ScDPSubtotalOptDlg::Init( const ScDPNameVec& rDataFields, bool bEnableLayou sal_Int32 nSortMode = maLabelData.maSortInfo.Mode; // sort fields list box - if (maLabelData.maLayoutName.getLength()) - maLbSortBy.InsertEntry( maLabelData.maLayoutName ); - else - maLbSortBy.InsertEntry( maLabelData.maName ); + maLbSortBy.InsertEntry(maLabelData.getDisplayName()); for( ScDPNameVec::const_iterator aIt = rDataFields.begin(), aEnd = rDataFields.end(); aIt != aEnd; ++aIt ) { diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx index ea70891a8d1d..6a9bb63e3ae3 100644 --- a/sc/source/ui/dbgui/pvlaydlg.cxx +++ b/sc/source/ui/dbgui/pvlaydlg.cxx @@ -395,10 +395,7 @@ void ScDPLayoutDlg::InitWndSelect( const vector& rLabels ) if ( i <= nLast ) { - OUString aFieldName = aLabelDataArr[i].maName; - if (aLabelDataArr[i].maLayoutName.getLength()) - aFieldName = aLabelDataArr[i].maLayoutName; - aWndSelect.AddField(aFieldName, i); + aWndSelect.AddField(aLabelDataArr[i].getDisplayName(), i); aSelectArr[i].reset( new ScDPFuncData( aLabelDataArr[i].mnCol, aLabelDataArr[i].mnFuncMask ) ); } } @@ -599,7 +596,7 @@ void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Po if ( !bDataArr ) { - if ( toWnd->AddField( rData.maLayoutName.getLength() ? rData.maLayoutName : rData.maName, + if ( toWnd->AddField( rData.getDisplayName(), DlgPos2WndPos( rAtPos, *toWnd ), nAddedAt ) ) { @@ -612,10 +609,7 @@ void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Po USHORT nMask = fData.mnFuncMask; OUString aStr = GetFuncString( nMask, rData.mbIsValue ); - if (rData.maLayoutName.getLength()) - aStr += rData.maLayoutName; - else - aStr += rData.maName; + aStr += rData.getDisplayName(); if ( toWnd->AddField( aStr, DlgPos2WndPos( rAtPos, *toWnd ), @@ -1223,7 +1217,7 @@ String ScDPLayoutDlg::GetLabelString( SCsCOL nCol ) ScDPLabelData* pData = GetLabelData( nCol ); DBG_ASSERT( pData, "LabelData not found" ); if (pData) - return pData->maLayoutName.getLength() ? pData->maLayoutName : pData->maName; + return pData->getDisplayName(); return String(); } @@ -1762,10 +1756,7 @@ IMPL_LINK( ScDPLayoutDlg, ScrollHdl, ScrollBar *, EMPTYARG ) for ( i=0; i Date: Wed, 2 Sep 2009 20:46:19 +0000 Subject: Fixed a bug where field arrow buttons didn't indicate the presence of hidden members when the name of a field was a layout name. --- sc/source/filter/xml/xmldpimp.cxx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'sc') diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index 572bcbb817e3..da89897269f0 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -357,7 +357,15 @@ void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim, bool bHas } if (bHasHiddenMember) - maHiddenMemberFields.insert(pDim->GetName()); + { + // the layout name takes priority over the original name, + // since this data is used against cell values. + const OUString* pLayoutName = pDim->GetLayoutName(); + if (pLayoutName) + maHiddenMemberFields.insert(*pLayoutName); + else + maHiddenMemberFields.insert(pDim->GetName()); + } } pDPSave->AddDimension(pDim); } -- cgit From 15516a01e3368a07854cabfe9cace1c841ac3795 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 3 Sep 2009 03:05:22 +0000 Subject: slight comment cleaning --- sc/inc/pivot.hxx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sc') diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx index ad5ec926ed97..eb70f50e70f2 100644 --- a/sc/inc/pivot.hxx +++ b/sc/inc/pivot.hxx @@ -401,9 +401,8 @@ struct ScDPLabelData explicit ScDPLabelData( const String& rName, short nCol, bool bIsValue ); /** - * return the name that should be displayed in the dp dialogs i.e. - * when the layout name is present, use it, or else use the original - * name. + * return the name that should be displayed in the dp dialogs i.e. when + * the layout name is present, use it, or else use the original name. */ ::rtl::OUString SC_DLLPUBLIC getDisplayName() const; }; -- cgit From cc67bdb74d77446686dc1dcb78c53e5196ce1326 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 3 Sep 2009 04:37:43 +0000 Subject: #i104742# ported some code from ooo-build to implement shrinking of db data area. --- sc/inc/document.hxx | 2 ++ sc/inc/table.hxx | 1 + sc/source/core/data/document.cxx | 26 ++++++++++++++++++++++++++ sc/source/core/data/table2.cxx | 8 ++++++++ sc/source/ui/inc/dbfunc.hxx | 2 +- sc/source/ui/view/dbfunc.cxx | 18 +++++++++++++++++- 6 files changed, 55 insertions(+), 2 deletions(-) (limited to 'sc') diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index c8d3751a7aaf..ea04d92b9f10 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -874,6 +874,8 @@ public: USHORT GetErrCode( const ScAddress& ) const; + bool ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const; + void GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld ); SC_DLLPUBLIC BOOL GetCellArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const; diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 8b2227d48dbb..0c6233e5fb98 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -291,6 +291,7 @@ public: } ScBaseCell* GetCell( SCCOL nCol, SCROW nRow ) const; + void GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const; void GetLastDataPos(SCCOL& rCol, SCROW& rRow) const; /** Returns the pointer to a cell note object at the passed cell address. */ diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 61cf3ab94b35..9596954cf5a8 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -618,6 +618,32 @@ BOOL ScDocument::GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) cons return FALSE; } +bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return false; + + SCCOL nCol1, nCol2; + SCROW nRow1, nRow2; + pTab[nTab]->GetFirstDataPos(nCol1, nRow1); + pTab[nTab]->GetLastDataPos(nCol2, nRow2); + + if (nCol1 > nCol2 || nRow1 > nRow2) + // invalid range. + return false; + + // Make sure the area only shrinks, and doesn't grow. + if (rStartCol < nCol1) + rStartCol = nCol1; + if (nCol2 < rEndCol) + rEndCol = nCol2; + if (rStartRow < nRow1) + rStartRow = nRow1; + if (nRow2 < rEndRow) + rEndRow = nRow2; + + return true; // success! +} // zusammenhaengender Bereich diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 59858796078c..47b119805e0c 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -962,6 +962,14 @@ ScBaseCell* ScTable::GetCell( SCCOL nCol, SCROW nRow ) const return NULL; } +void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const +{ + rCol = 0; + rRow = 0; + while (aCol[rCol].IsEmptyData() && rCol < MAXCOL) + ++rCol; + rRow = aCol[rCol].GetFirstDataPos(); +} void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const { diff --git a/sc/source/ui/inc/dbfunc.hxx b/sc/source/ui/inc/dbfunc.hxx index afeb90df1a79..875576a22889 100644 --- a/sc/source/ui/inc/dbfunc.hxx +++ b/sc/source/ui/inc/dbfunc.hxx @@ -80,7 +80,7 @@ public: void GotoDBArea( const String& rDBName ); // DB-Bereich vom Cursor - ScDBData* GetDBData( BOOL bMarkArea = TRUE, ScGetDBMode eMode = SC_DB_MAKE ); + ScDBData* GetDBData( BOOL bMarkArea = TRUE, ScGetDBMode eMode = SC_DB_MAKE, bool bShrinkToData = false ); void NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const List& rDelAreaList ); diff --git a/sc/source/ui/view/dbfunc.cxx b/sc/source/ui/view/dbfunc.cxx index 0d44603b64f8..48b6d3ba11f7 100644 --- a/sc/source/ui/view/dbfunc.cxx +++ b/sc/source/ui/view/dbfunc.cxx @@ -107,14 +107,30 @@ void ScDBFunc::GotoDBArea( const String& rDBName ) // aktuellen Datenbereich fuer Sortieren / Filtern suchen -ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode ) +ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode, bool bShrinkToData ) { ScDocShell* pDocSh = GetViewData()->GetDocShell(); ScDBData* pData = NULL; ScRange aRange; ScMarkType eMarkType = GetViewData()->GetSimpleArea(aRange); if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED ) + { + if (bShrinkToData) + { + // Shrink the range to only include data area. + ScDocument* pDoc = pDocSh->GetDocument(); + SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col(); + SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row(); + if (pDoc->ShrinkToDataArea(aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2)) + { + aRange.aStart.SetCol(nCol1); + aRange.aEnd.SetCol(nCol2); + aRange.aStart.SetRow(nRow1); + aRange.aEnd.SetRow(nRow2); + } + } pData = pDocSh->GetDBData( aRange, eMode, FALSE ); + } else if ( eMode != SC_DB_OLD ) pData = pDocSh->GetDBData( ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), -- cgit From 87435fda334e9ac833968193524b9bb0ff276c97 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 3 Sep 2009 05:17:25 +0000 Subject: #i104742# shrink selected soure data to the data area when making datapilot table from cell range. --- sc/source/ui/view/cellsh2.cxx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'sc') diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx index eabf33f3defc..3675cd690916 100644 --- a/sc/source/ui/view/cellsh2.cxx +++ b/sc/source/ui/view/cellsh2.cxx @@ -750,7 +750,7 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq ) { // select database range or data pTabViewShell->GetDBData( TRUE, SC_DB_OLD ); - const ScMarkData& rMark = GetViewData()->GetMarkData(); + ScMarkData& rMark = GetViewData()->GetMarkData(); if ( !rMark.IsMarked() && !rMark.IsMultiMarked() ) pTabViewShell->MarkDataArea( FALSE ); @@ -816,6 +816,19 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq ) ScMarkType eType = GetViewData()->GetSimpleArea(aRange); if ( (eType & SC_MARK_SIMPLE) == SC_MARK_SIMPLE ) { + // Shrink the range to the data area. + SCCOL nStartCol = aRange.aStart.Col(), nEndCol = aRange.aEnd.Col(); + SCROW nStartRow = aRange.aStart.Row(), nEndRow = aRange.aEnd.Row(); + if (pDoc->ShrinkToDataArea(aRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow)) + { + aRange.aStart.SetCol(nStartCol); + aRange.aStart.SetRow(nStartRow); + aRange.aEnd.SetCol(nEndCol); + aRange.aEnd.SetRow(nEndRow); + rMark.SetMarkArea(aRange); + pTabViewShell->MarkRange(aRange); + } + BOOL bOK = TRUE; if ( pDoc->HasSubTotalCells( aRange ) ) { -- cgit From 23f300a0f3b66df0dee0bca7e26d38d60cb8b5a2 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Sat, 5 Sep 2009 02:30:47 +0000 Subject: resurrected one formerly unused method to fix build breakage. --- sc/inc/column.hxx | 2 +- sc/source/core/data/column2.cxx | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'sc') diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 816a8ade4628..80b2394788d1 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -162,7 +162,7 @@ public: SCSIZE GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const; BOOL HasDataAt(SCROW nRow) const; BOOL HasVisibleDataAt(SCROW nRow) const; -//UNUSED2009-05 SCROW GetFirstDataPos() const; + SCROW GetFirstDataPos() const; SCROW GetLastDataPos() const; SCROW GetLastVisDataPos(BOOL bNotes) const; // ohne Broadcaster SCROW GetFirstVisDataPos(BOOL bNotes) const; diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 01c72ab4e0c4..f7a6a3bf83c9 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1376,13 +1376,13 @@ SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirecti return nLines; } -//UNUSED2009-05 SCROW ScColumn::GetFirstDataPos() const -//UNUSED2009-05 { -//UNUSED2009-05 if (nCount) -//UNUSED2009-05 return pItems[0].nRow; -//UNUSED2009-05 else -//UNUSED2009-05 return 0; -//UNUSED2009-05 } +SCROW ScColumn::GetFirstDataPos() const +{ + if (nCount) + return pItems[0].nRow; + else + return 0; +} SCROW ScColumn::GetLastDataPos() const { -- cgit From 27472f118a27c8b5b7e6396c9b219645bb0e3402 Mon Sep 17 00:00:00 2001 From: Daniel Rentz Date: Mon, 12 Oct 2009 13:48:51 +0000 Subject: missing usings --- sc/inc/AccessibleFilterMenu.hxx | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sc') diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx index 54194a2d4acf..76344a65ceda 100644 --- a/sc/inc/AccessibleFilterMenu.hxx +++ b/sc/inc/AccessibleFilterMenu.hxx @@ -104,6 +104,9 @@ public: // XAccessibleEventBroadcaster + using ScAccessibleContextBase::addEventListener; + using ScAccessibleContextBase::removeEventListener; + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< -- cgit From a0cf30a3798291a310c12a9fbcbc06c00d755c0c Mon Sep 17 00:00:00 2001 From: Daniel Rentz Date: Tue, 13 Oct 2009 11:30:10 +0000 Subject: unx warning --- sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx | 1 - 1 file changed, 1 deletion(-) (limited to 'sc') diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx index 0ab5fa270688..9f5524dcb8ce 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx @@ -80,7 +80,6 @@ Reference ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 throw (RuntimeException, IndexOutOfBoundsException) { throw IndexOutOfBoundsException(); - return Reference(); } Reference ScAccessibleFilterMenuItem::getAccessibleStateSet() -- cgit From 8dc2dfea882ac43277bfabbfb3e2e9b011dee40c Mon Sep 17 00:00:00 2001 From: Daniel Rentz Date: Tue, 13 Oct 2009 11:53:13 +0000 Subject: missing exceptions file --- sc/source/ui/dbgui/makefile.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'sc') diff --git a/sc/source/ui/dbgui/makefile.mk b/sc/source/ui/dbgui/makefile.mk index 5d716552ca71..d6e5887c66d2 100644 --- a/sc/source/ui/dbgui/makefile.mk +++ b/sc/source/ui/dbgui/makefile.mk @@ -80,6 +80,7 @@ EXCEPTIONSFILES= \ $(SLO)$/csvsplits.obj \ $(SLO)$/csvtablebox.obj \ $(SLO)$/fieldwnd.obj \ + $(SLO)$/pvfundlg.obj \ $(SLO)$/pvlaydlg.obj \ $(SLO)$/dapidata.obj -- cgit From 620d99d825221ba06276ea3c6144ffd604ee7bc0 Mon Sep 17 00:00:00 2001 From: Daniel Rentz Date: Tue, 13 Oct 2009 12:27:53 +0000 Subject: missing exceptions file --- sc/source/ui/view/makefile.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sc') diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk index 466ab5dc8627..55e9998881bf 100644 --- a/sc/source/ui/view/makefile.mk +++ b/sc/source/ui/view/makefile.mk @@ -157,7 +157,8 @@ EXCEPTIONSFILES= \ $(SLO)$/cellsh1.obj \ $(SLO)$/drawvie4.obj \ $(SLO)$/formatsh.obj \ - $(SLO)$/scextopt.obj \ + $(SLO)$/gridwin2.obj \ + $(SLO)$/scextopt.obj \ $(SLO)$/tabvwshb.obj \ $(SLO)$/viewdata.obj \ $(SLO)$/viewfun5.obj \ -- cgit From 557814474f7c73b386fa25a189c5139ac854f616 Mon Sep 17 00:00:00 2001 From: Daniel Rentz Date: Wed, 14 Oct 2009 08:12:03 +0000 Subject: wntmsci12 warnings --- sc/source/core/data/dpoutputgeometry.cxx | 4 ++-- sc/source/ui/cctrl/dpcontrol.cxx | 20 ++++++++++---------- sc/source/ui/view/makefile.mk | 1 - 3 files changed, 12 insertions(+), 13 deletions(-) (limited to 'sc') diff --git a/sc/source/core/data/dpoutputgeometry.cxx b/sc/source/core/data/dpoutputgeometry.cxx index 20c071976ebe..9eace100c137 100644 --- a/sc/source/core/data/dpoutputgeometry.cxx +++ b/sc/source/core/data/dpoutputgeometry.cxx @@ -101,7 +101,7 @@ void ScDPOutputGeometry::getColumnFieldPositions(vector& rAddrs) cons SCROW nRow = nCurRow; SCTAB nTab = maOutRange.aStart.Tab(); - SCCOL nColStart = maOutRange.aStart.Col() + mnRowFields + bDataLayout; + SCCOL nColStart = static_cast(maOutRange.aStart.Col() + mnRowFields + (bDataLayout ? 1 : 0)); SCCOL nColEnd = nColStart + static_cast(mnColumnFields-1); for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol) @@ -194,7 +194,7 @@ ScDPOutputGeometry::FieldType ScDPOutputGeometry::getFieldButtonType(const ScAdd if (mnColumnFields) { SCROW nRow = nCurRow; - SCCOL nColStart = maOutRange.aStart.Col() + mnRowFields + bDataLayout; + SCCOL nColStart = static_cast(maOutRange.aStart.Col() + mnRowFields + (bDataLayout ? 1 : 0)); SCCOL nColEnd = nColStart + static_cast(mnColumnFields-1); if (rPos.Row() == nRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd) return Column; diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index ee58c3dca601..a938948e1b26 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -141,7 +141,7 @@ void ScDPFieldButton::draw() Font aTextFont( mpStyle->GetLabelFont() ); double fFontHeight = 12.0; fFontHeight *= static_cast(maZoomY.GetNumerator()) / static_cast(maZoomY.GetDenominator()); - aTextFont.SetHeight(fFontHeight); + aTextFont.SetHeight(static_cast(fFontHeight)); mpOutDev->SetFont(aTextFont); Point aTextPos = maPos; @@ -159,7 +159,7 @@ void ScDPFieldButton::draw() void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const { - long nW = maSize.getWidth()*0.5; + long nW = maSize.getWidth() / 2; long nH = maSize.getHeight(); if (nW > 18) nW = 18; @@ -830,7 +830,7 @@ void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rS { const sal_uInt16 nLeftMargin = 5; const sal_uInt16 nTopMargin = 5; - const sal_uInt16 nMenuItemHeight = maLabelFont.GetHeight()*1.8; + const sal_uInt16 nMenuItemHeight = static_cast< sal_uInt16 >( maLabelFont.GetHeight()*1.8 ); Size aWndSize = GetSizePixel(); @@ -1062,15 +1062,15 @@ void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionTy const sal_uInt16 nSingleItemBtnAreaHeight = 32; // height of the middle area below the list box where the single-action buttons are. const sal_uInt16 nBottomBtnAreaHeight = 50; // height of the bottom area where the OK and Cancel buttons are. const sal_uInt16 nBtnWidth = 60; - const sal_uInt16 nLabelHeight = getLabelFont().GetHeight(); + const sal_uInt16 nLabelHeight = static_cast< sal_uInt16 >( getLabelFont().GetHeight() ); const sal_uInt16 nBtnHeight = nLabelHeight*2; const sal_uInt16 nBottomMargin = 10; const sal_uInt16 nMenuListMargin = 20; // parameters calculated from constants. - const sal_uInt16 nListBoxWidth = maWndSize.Width() - nListBoxMargin*2; - const sal_uInt16 nListBoxHeight = maWndSize.Height() - nTopMargin - nMenuHeight - - nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight; + const sal_uInt16 nListBoxWidth = static_cast< sal_uInt16 >( maWndSize.Width() - nListBoxMargin*2 ); + const sal_uInt16 nListBoxHeight = static_cast< sal_uInt16 >( maWndSize.Height() - nTopMargin - nMenuHeight - + nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight ); const sal_uInt16 nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1; @@ -1157,7 +1157,7 @@ void ScDPFieldPopupWindow::setAllMemberState(bool bSet) { size_t n = maMembers.size(); for (size_t i = 0; i < n; ++i) - maChecks.CheckEntryPos(i, bSet); + maChecks.CheckEntryPos(static_cast< USHORT >( i ), bSet); } void ScDPFieldPopupWindow::selectCurrentMemberOnly(bool bSet) @@ -1353,7 +1353,7 @@ void ScDPFieldPopupWindow::initMembers() for (size_t i = 0; i < n; ++i) { maChecks.InsertEntry(maMembers[i].maName); - maChecks.CheckEntryPos(i, maMembers[i].mbVisible); + maChecks.CheckEntryPos(static_cast< USHORT >( i ), maMembers[i].mbVisible); if (maMembers[i].mbVisible) ++nVisMemCount; } @@ -1388,7 +1388,7 @@ void ScDPFieldPopupWindow::getResult(hash_map& rRe size_t n = maMembers.size(); for (size_t i = 0; i < n; ++i) { - bool bState = maChecks.IsChecked(i); + bool bState = maChecks.IsChecked(static_cast< USHORT >( i )); aResult.insert(ResultMap::value_type(maMembers[i].maName, bState)); } rResult.swap(aResult); diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk index 55e9998881bf..aa39b4cc64a0 100644 --- a/sc/source/ui/view/makefile.mk +++ b/sc/source/ui/view/makefile.mk @@ -140,7 +140,6 @@ SLOFILES = \ $(SLO)$/dbfunc2.obj \ $(SLO)$/tabvwsh2.obj .ELSE - NOOPTFILES=\ $(SLO)$/drawview.obj \ $(SLO)$/dbfunc2.obj \ -- cgit From 24046e0b2625c3ed2da1ad5955771a09fe5f2b36 Mon Sep 17 00:00:00 2001 From: Daniel Rentz Date: Thu, 15 Oct 2009 07:58:02 +0000 Subject: wntmsci12 warning --- sc/source/ui/view/dbfunc3.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sc') diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index dcad0cbce885..996625e0491b 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -1788,7 +1788,7 @@ bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16 nRank = itrSub->second; if (!bAscending) - nRank = nMemberCount - nRank - 1; + nRank = static_cast< sal_uInt16 >( nMemberCount - nRank - 1 ); aRankedNames[nRank] = aName; } -- cgit From 2aaa78d388dc0eb5b2de84fc5206e7924b579cca Mon Sep 17 00:00:00 2001 From: Daniel Rentz Date: Thu, 15 Oct 2009 11:25:30 +0000 Subject: wntmsci12 warning --- sc/source/ui/view/gridwin2.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sc') diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index c10fee8d9a5e..e0dd63ff090e 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -514,7 +514,7 @@ void ScGridWindow::DPLaunchFieldPopupMenu( { pSubMenu->addMenuItem( aUserSortNames[i], true, - new PopupSortAction(rPos, PopupSortAction::CUSTOM, i, pViewShell)); + new PopupSortAction(rPos, PopupSortAction::CUSTOM, static_cast(i), pViewShell)); } } -- cgit From 43b559189d10a54409bdab90c92def6b9a341b4f Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Mon, 16 Nov 2009 21:02:12 +0000 Subject: #i106583# Use the up-to-date output range when refreshing datapilot tables. --- sc/source/filter/excel/xipivot.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sc') diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index b77df97a0448..0eedd6bbbd7d 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -1435,7 +1435,8 @@ void XclImpPivotTable::MaybeRefresh() { // 'refresh table on load' flag is set. Refresh the table now. Some // Excel files contain partial table output when this flag is set. - mpDPObj->Output(maOutScRange.aStart); + ScRange aOutRange = mpDPObj->GetOutRange(); + mpDPObj->Output(aOutRange.aStart); } } -- cgit From 276790cd38c56be757b86c3b10d9f3815a30fa62 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Tue, 17 Nov 2009 19:49:18 +0000 Subject: #i106975# Use tableooo namespace when exporting datapilot's display names. --- sc/source/filter/xml/XMLExportDataPilot.cxx | 8 +++---- sc/source/filter/xml/xmldpimp.cxx | 4 ++++ sc/source/filter/xml/xmlimprt.cxx | 36 ++++++++++++++++------------- sc/source/filter/xml/xmlimprt.hxx | 8 +++++-- 4 files changed, 34 insertions(+), 22 deletions(-) (limited to 'sc') diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx index 318606ca3c49..b779f2374569 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.cxx +++ b/sc/source/filter/xml/XMLExportDataPilot.cxx @@ -464,7 +464,7 @@ void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim) ScXMLConverter::GetStringFromFunction( sFunction, nFunc); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction); if (pLayoutName && nFunc == sheet::GeneralFunction_AUTO) - rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pLayoutName); + rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName); SvXMLElementExport aElemST(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, sal_True, sal_True); } } @@ -482,7 +482,7 @@ void ScXMLExportDataPilot::WriteMembers(ScDPSaveDimension* pDim) rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString((*i)->GetName())); const OUString* pLayoutName = (*i)->GetLayoutName(); if (pLayoutName) - rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pLayoutName); + rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName); rtl::OUStringBuffer sBuffer; SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetIsVisible()); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear()); @@ -682,7 +682,7 @@ void ScXMLExportDataPilot::WriteDimension(ScDPSaveDimension* pDim, const ScDPDim rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, rtl::OUString(pDim->GetName())); const OUString* pLayoutName = pDim->GetLayoutName(); if (pLayoutName) - rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pLayoutName); + rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName); if (pDim->IsDataLayout()) rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TRUE); @@ -726,7 +726,7 @@ void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, bVisible ? XML_TRUE : XML_FALSE); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, eOrient); if (pGrandTotal) - rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pGrandTotal); + rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pGrandTotal); SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True); } diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index da89897269f0..6454baf08431 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -771,6 +771,7 @@ ScXMLDataPilotGrandTotalContext::ScXMLDataPilotGrandTotalContext( meOrientation = COLUMN; break; case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME: + case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT: maDisplayName = rAttrValue; break; default: @@ -914,6 +915,7 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport, } break; case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME: + case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT: { aDisplayName = sValue; } @@ -1448,6 +1450,7 @@ ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImpo ScXMLConverter::GetFunctionFromString( sValue ) ) ); } case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME: + case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT: pDataPilotSubTotals->SetDisplayName(sValue); break; } @@ -1547,6 +1550,7 @@ ScXMLDataPilotMemberContext::ScXMLDataPilotMemberContext( ScXMLImport& rImport, } break; case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME: + case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT: { maDisplayName = sValue; } diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx index cfb91dd51856..d7ca2ea75a74 100644 --- a/sc/source/filter/xml/xmlimprt.cxx +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -1387,9 +1387,10 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotGrandTotalAttrTokenMap() { static __FAR_DATA SvXMLTokenMapEntry aDataPilotGrandTotalAttrTokenMap[] = { - { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY }, - { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION }, - { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME }, + { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY }, + { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION }, + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME }, + { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT }, XML_TOKEN_MAP_END }; @@ -1437,13 +1438,14 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotFieldAttrTokenMap() { static __FAR_DATA SvXMLTokenMapEntry aDataPilotFieldAttrTokenMap[] = { - { XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME }, - { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME }, - { XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD }, - { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION }, - { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION }, - { XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE }, - { XML_NAMESPACE_TABLE, XML_USED_HIERARCHY, XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY }, + { XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME }, + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME }, + { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT }, + { XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD }, + { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION }, + { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION }, + { XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE }, + { XML_NAMESPACE_TABLE, XML_USED_HIERARCHY, XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY }, XML_TOKEN_MAP_END }; @@ -1529,8 +1531,9 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotSubTotalAttrTokenMap() { static __FAR_DATA SvXMLTokenMapEntry aDataPilotSubTotalAttrTokenMap[] = { - { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION }, - { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME }, + { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION }, + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME }, + { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT }, XML_TOKEN_MAP_END }; @@ -1562,10 +1565,11 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotMemberAttrTokenMap() { static __FAR_DATA SvXMLTokenMapEntry aDataPilotMemberAttrTokenMap[] = { - { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME }, - { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME }, - { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY }, - { XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS }, + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME }, + { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME }, + { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT }, + { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY }, + { XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS }, XML_TOKEN_MAP_END }; diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx index 0fb9aead0e4f..c110c70f72e2 100644 --- a/sc/source/filter/xml/xmlimprt.hxx +++ b/sc/source/filter/xml/xmlimprt.hxx @@ -509,7 +509,8 @@ enum ScXMLDataPilotGrandTotalAttrTokens { XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION, - XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME + XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME, + XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT }; enum ScXMLDataPilotTableSourceCellRangeElemTokens @@ -526,6 +527,7 @@ enum ScXMLDataPilotFieldAttrTokens { XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME, + XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT, XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD, XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION, XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION, @@ -562,7 +564,8 @@ enum ScXMLDataPilotSubTotalsElemTokens enum ScXMLDataPilotSubTotalAttrTokens { XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION, - XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME + XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME, + XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT }; enum ScXMLDataPilotMembersElemTokens @@ -574,6 +577,7 @@ enum ScXMLDataPilotMemberAttrTokens { XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME, + XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY, XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS }; -- cgit From 39161b01316e9368f51567e7ab4b6e2ffd195b2f Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Tue, 17 Nov 2009 21:01:24 +0000 Subject: #i106975# Don't export tableooo:display-name attributes unless the specified ODF version is 1.2 extended or later. --- sc/source/filter/xml/XMLExportDataPilot.cxx | 36 +++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 9 deletions(-) (limited to 'sc') diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx index b779f2374569..dffb6f4f7080 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.cxx +++ b/sc/source/filter/xml/XMLExportDataPilot.cxx @@ -452,7 +452,11 @@ void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim) using sheet::GeneralFunction; sal_Int32 nSubTotalCount = pDim->GetSubTotalsCount(); - const OUString* pLayoutName = pDim->GetSubtotalName(); + const OUString* pLayoutName = NULL; + if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST) + // Export display names only for 1.2 extended or later. + pLayoutName = pDim->GetSubtotalName(); + if (nSubTotalCount > 0) { SvXMLElementExport aElemSTs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, sal_True, sal_True); @@ -480,9 +484,15 @@ void ScXMLExportDataPilot::WriteMembers(ScDPSaveDimension* pDim) for (ScDPSaveDimension::MemberList::const_iterator i=rMembers.begin(); i != rMembers.end() ; i++) { rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString((*i)->GetName())); - const OUString* pLayoutName = (*i)->GetLayoutName(); - if (pLayoutName) - rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName); + + if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST) + { + // Export display names only for ODF 1.2 extended or later. + const OUString* pLayoutName = (*i)->GetLayoutName(); + if (pLayoutName) + rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName); + } + rtl::OUStringBuffer sBuffer; SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetIsVisible()); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear()); @@ -680,9 +690,13 @@ void ScXMLExportDataPilot::WriteGroupDimElements(ScDPSaveDimension* pDim, const void ScXMLExportDataPilot::WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData) { rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, rtl::OUString(pDim->GetName())); - const OUString* pLayoutName = pDim->GetLayoutName(); - if (pLayoutName) - rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName); + if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST) + { + // Export display names only for ODF 1.2 extended or later. + const OUString* pLayoutName = pDim->GetLayoutName(); + if (pLayoutName) + rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName); + } if (pDim->IsDataLayout()) rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TRUE); @@ -725,8 +739,12 @@ void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient { rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, bVisible ? XML_TRUE : XML_FALSE); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, eOrient); - if (pGrandTotal) - rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pGrandTotal); + if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST) + { + // Export display names only for ODF 1.2 extended or later. + if (pGrandTotal) + rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pGrandTotal); + } SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True); } -- cgit From d803f1b8cfb2b15920fa03b3a64371b4664f4a31 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 18 Nov 2009 18:57:07 +0000 Subject: #i106975# data-pilot-grand-total is also new in ODF 1.2 extended. --- sc/source/filter/xml/XMLExportDataPilot.cxx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'sc') diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx index dffb6f4f7080..d6c800853c6f 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.cxx +++ b/sc/source/filter/xml/XMLExportDataPilot.cxx @@ -737,14 +737,15 @@ void ScXMLExportDataPilot::WriteDimensions(ScDPSaveData* pDPSave) void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const OUString* pGrandTotal) { + if (rExport.getDefaultVersion() != SvtSaveOptions::ODFVER_LATEST) + // Export grand total only for ODF 1.2 extended or later. + return; + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, bVisible ? XML_TRUE : XML_FALSE); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, eOrient); - if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST) - { - // Export display names only for ODF 1.2 extended or later. - if (pGrandTotal) - rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pGrandTotal); - } + if (pGrandTotal) + rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pGrandTotal); + SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True); } -- cgit From e90a5b82b8454c8c77a0bf50285e99cf25c631bd Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 18 Nov 2009 19:35:08 +0000 Subject: #i106975# When custom grand total name is not used, write the xml data the old way. --- sc/source/filter/xml/XMLExportDataPilot.cxx | 31 +++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'sc') diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx index d6c800853c6f..88c710ae9f11 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.cxx +++ b/sc/source/filter/xml/XMLExportDataPilot.cxx @@ -737,10 +737,6 @@ void ScXMLExportDataPilot::WriteDimensions(ScDPSaveData* pDPSave) void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const OUString* pGrandTotal) { - if (rExport.getDefaultVersion() != SvtSaveOptions::ODFVER_LATEST) - // Export grand total only for ODF 1.2 extended or later. - return; - rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, bVisible ? XML_TRUE : XML_FALSE); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, eOrient); if (pGrandTotal) @@ -821,14 +817,33 @@ void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference GetGrandTotalName(); - if (bRowGrand && bColumnGrand) + if (pGrandTotalName && rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST) { - WriteGrandTotal(XML_BOTH, true, pGrandTotalName); + // Use the new data-pilot-grand-total element. + if (bRowGrand && bColumnGrand) + { + WriteGrandTotal(XML_BOTH, true, pGrandTotalName); + } + else + { + WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName); + WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName); + } } else { - WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName); - WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName); + // custom grand total not present, or it's not ODF 1.2 extended. + // Write it the old way. + if (bRowGrand && bColumnGrand) + { + // Don't write anything. Grand totals are displayed for both row and column fields by default. + } + else if (bRowGrand) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_ROW); + else if (bColumnGrand) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_COLUMN); + else + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_NONE); } rExport.CheckAttrList(); -- cgit From 48cee6fff042f05a7cd5a1bc0f8f7f93f361da15 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 18 Nov 2009 20:01:54 +0000 Subject: Actually this is wrong. --- sc/source/filter/xml/XMLExportDataPilot.cxx | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'sc') diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx index 88c710ae9f11..97926ee7113f 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.cxx +++ b/sc/source/filter/xml/XMLExportDataPilot.cxx @@ -830,21 +830,6 @@ void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference IsSheetData()) -- cgit From 9794e714928d3d8336817545d5a1355645ccf7e8 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 18 Nov 2009 20:08:02 +0000 Subject: The default visibility of grand total is actually true, not false. --- sc/source/filter/xml/xmldpimp.cxx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'sc') diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index 6454baf08431..08e8633978b1 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -117,7 +117,7 @@ void ScXMLDataPilotTablesContext::EndElement() } ScXMLDataPilotTableContext::GrandTotalItem::GrandTotalItem() : - mbVisible(false) {} + mbVisible(true) {} ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport, USHORT nPrfx, @@ -177,11 +177,18 @@ ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport, else if (IsXMLToken(sValue, XML_ROW)) { maRowGrandTotal.mbVisible = true; + maColGrandTotal.mbVisible = false; } else if (IsXMLToken(sValue, XML_COLUMN)) { + maRowGrandTotal.mbVisible = false; maColGrandTotal.mbVisible = true; } + else + { + maRowGrandTotal.mbVisible = false; + maColGrandTotal.mbVisible = false; + } } break; case XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS : -- cgit