diff --git sc/inc/column.hxx sc/inc/column.hxx index 5a1a771..f274736 100644 --- sc/inc/column.hxx +++ sc/inc/column.hxx @@ -296,6 +296,7 @@ public: const ScPatternAttr* GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const; ULONG GetNumberFormat( SCROW nRow ) const; + sal_uInt32 GetNumberFormat( SCROW nStartRow, SCROW nEndRow ) const; void MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, BOOL bDeep ) const; void MergePatternArea( ScMergePatternState& rState, SCROW nRow1, SCROW nRow2, BOOL bDeep ) const; diff --git sc/inc/document.hxx sc/inc/document.hxx index 905244d..35fd858 100644 --- sc/inc/document.hxx +++ sc/inc/document.hxx @@ -751,6 +751,7 @@ SC_DLLPUBLIC ScDBCollection* GetDBCollection() const; double RoundValueAsShown( double fVal, ULONG nFormat ); void GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt32& rFormat ); + sal_uInt32 GetNumberFormat( const ScRange& rRange ) const; sal_uInt32 GetNumberFormat( const ScAddress& ) const; /** If no number format attribute is set and the cell pointer passed is of type formula cell, the calculated diff --git sc/inc/table.hxx sc/inc/table.hxx index 932de72..924e3ef 100644 --- sc/inc/table.hxx +++ sc/inc/table.hxx @@ -435,6 +435,7 @@ public: ULONG GetNumberFormat( const ScAddress& rPos ) const { return aCol[rPos.Col()].GetNumberFormat( rPos.Row() ); } ULONG GetNumberFormat( SCCOL nCol, SCROW nRow ) const; + sal_uInt32 GetNumberFormat( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const; void MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, BOOL bDeep ) const; void MergePatternArea( ScMergePatternState& rState, SCCOL nCol1, SCROW nRow1, diff --git sc/sdi/formatsh.sdi sc/sdi/formatsh.sdi index 9bac9d3..71f78f7 100644 --- sc/sdi/formatsh.sdi +++ sc/sdi/formatsh.sdi @@ -119,11 +119,11 @@ interface FormatForSelection SID_ATTR_NUMBERFORMAT_VALUE [ ExecMethod = ExecuteNumFormat; StateMethod = GetNumFormatState;] SID_NUMBER_FORMAT [ ExecMethod = ExecuteNumFormat; StateMethod = GetNumFormatState;] SID_NUMBER_TWODEC [ ExecMethod = ExecuteNumFormat;] - SID_NUMBER_SCIENTIFIC [ ExecMethod = ExecuteNumFormat;] - SID_NUMBER_DATE [ ExecMethod = ExecuteNumFormat;] - SID_NUMBER_CURRENCY [ ExecMethod = ExecuteNumFormat;] - SID_NUMBER_PERCENT [ ExecMethod = ExecuteNumFormat;] - SID_NUMBER_TIME [ ExecMethod = ExecuteNumFormat;] + SID_NUMBER_SCIENTIFIC [ ExecMethod = ExecuteNumFormat; StateMethod = GetNumFormatState; ] + SID_NUMBER_DATE [ ExecMethod = ExecuteNumFormat; StateMethod = GetNumFormatState; ] + SID_NUMBER_CURRENCY [ ExecMethod = ExecuteNumFormat; StateMethod = GetNumFormatState; ] + SID_NUMBER_PERCENT [ ExecMethod = ExecuteNumFormat; StateMethod = GetNumFormatState; ] + SID_NUMBER_TIME [ ExecMethod = ExecuteNumFormat; StateMethod = GetNumFormatState; ] SID_NUMBER_STANDARD [ ExecMethod = ExecuteNumFormat;] SID_NUMBER_INCDEC [ ExecMethod = ExecuteNumFormat;] SID_NUMBER_DECDEC [ ExecMethod = ExecuteNumFormat;] diff --git sc/source/core/data/column.cxx sc/source/core/data/column.cxx index fbc613b..96c7377 100644 --- sc/source/core/data/column.cxx +++ sc/source/core/data/column.cxx @@ -361,6 +361,22 @@ ULONG ScColumn::GetNumberFormat( SCROW nRow ) const return pAttrArray->GetPattern( nRow )->GetNumberFormat( pDocument->GetFormatTable() ); } +sal_uInt32 ScColumn::GetNumberFormat( SCROW nStartRow, SCROW nEndRow ) const +{ + SCROW nPatStartRow, nPatEndRow; + const ScPatternAttr* pPattern = pAttrArray->GetPatternRange(nPatStartRow, nPatEndRow, nStartRow); + sal_uInt32 nFormat = pPattern->GetNumberFormat(pDocument->GetFormatTable()); + while (nEndRow > nPatEndRow) + { + nStartRow = nPatEndRow + 1; + pPattern = pAttrArray->GetPatternRange(nPatStartRow, nPatEndRow, nStartRow); + sal_uInt32 nTmpFormat = pPattern->GetNumberFormat(pDocument->GetFormatTable()); + if (nFormat != nTmpFormat) + return 0; + } + return nFormat; +} + SCsROW ScColumn::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray ) { diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx index 8d182c4..a94a264 100644 --- sc/source/core/data/document.cxx +++ sc/source/core/data/document.cxx @@ -2306,6 +2306,32 @@ void ScDocument::GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab, rFormat = 0; } +sal_uInt32 ScDocument::GetNumberFormat( const ScRange& rRange ) const +{ + SCTAB nTab1 = rRange.aStart.Tab(), nTab2 = rRange.aEnd.Tab(); + SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col(); + SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row(); + + if (!ValidTab(nTab1) || !ValidTab(nTab2) || !pTab[nTab1] || !pTab[nTab2]) + return 0; + + sal_uInt32 nFormat = 0; + bool bFirstItem = true; + for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab) + for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) + { + sal_uInt32 nThisFormat = pTab[nTab]->GetNumberFormat(nCol, nRow1, nRow2); + if (bFirstItem) + { + nFormat = nThisFormat; + bFirstItem = false; + } + else if (nThisFormat != nFormat) + return 0; + } + + return nFormat; +} sal_uInt32 ScDocument::GetNumberFormat( const ScAddress& rPos ) const { diff --git sc/source/core/data/table2.cxx sc/source/core/data/table2.cxx index 26a6d8b..9bcc2b7 100644 --- sc/source/core/data/table2.cxx +++ sc/source/core/data/table2.cxx @@ -1096,6 +1096,14 @@ ULONG ScTable::GetNumberFormat( SCCOL nCol, SCROW nRow ) const return 0; } +sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const +{ + if (!ValidCol(nCol) || !ValidRow(nStartRow) || !ValidRow(nEndRow)) + return 0; + + return aCol[nCol].GetNumberFormat(nStartRow, nEndRow); +} + const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const { diff --git sc/source/ui/inc/formatsh.hxx sc/source/ui/inc/formatsh.hxx index ac7d7ea..94feaba 100644 --- sc/source/ui/inc/formatsh.hxx +++ sc/source/ui/inc/formatsh.hxx @@ -76,6 +76,9 @@ public: void ExecFormatPaintbrush( SfxRequest& rReq ); void StateFormatPaintbrush( SfxItemSet& rSet ); + +private: + short GetCurrentNumberFormatType(); }; #endif diff --git sc/source/ui/view/formatsh.cxx sc/source/ui/view/formatsh.cxx index bcb1304..037620b 100644 --- sc/source/ui/view/formatsh.cxx +++ sc/source/ui/view/formatsh.cxx @@ -58,6 +58,7 @@ #include #include +#include #include #include #include @@ -919,6 +920,7 @@ void ScFormatShell::ExecuteNumFormat( SfxRequest& rReq ) ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell(); const SfxItemSet* pReqArgs = rReq.GetArgs(); USHORT nSlot = rReq.GetSlot(); + SfxBindings& rBindings = pTabViewShell->GetViewFrame()->GetBindings(); pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox @@ -951,6 +953,8 @@ void ScFormatShell::ExecuteNumFormat( SfxRequest& rReq ) } } + short nType = GetCurrentNumberFormatType(); + SfxItemSet aSet( GetPool(), nSlot, nSlot ); switch ( nSlot ) { case SID_NUMBER_TWODEC: @@ -958,23 +962,48 @@ void ScFormatShell::ExecuteNumFormat( SfxRequest& rReq ) rReq.Done(); break; case SID_NUMBER_SCIENTIFIC: - pTabViewShell->SetNumberFormat( NUMBERFORMAT_SCIENTIFIC ); + if ((nType & NUMBERFORMAT_SCIENTIFIC)) + pTabViewShell->SetNumberFormat( NUMBERFORMAT_NUMBER ); + else + pTabViewShell->SetNumberFormat( NUMBERFORMAT_SCIENTIFIC ); + aSet.Put( SfxBoolItem(nSlot, !(nType & NUMBERFORMAT_SCIENTIFIC)) ); + rBindings.Invalidate( nSlot ); rReq.Done(); break; case SID_NUMBER_DATE: - pTabViewShell->SetNumberFormat( NUMBERFORMAT_DATE ); + if ((nType & NUMBERFORMAT_DATE)) + pTabViewShell->SetNumberFormat( NUMBERFORMAT_NUMBER ); + else + pTabViewShell->SetNumberFormat( NUMBERFORMAT_DATE ); + aSet.Put( SfxBoolItem(nSlot, !(nType & NUMBERFORMAT_DATE)) ); + rBindings.Invalidate( nSlot ); rReq.Done(); break; case SID_NUMBER_TIME: - pTabViewShell->SetNumberFormat( NUMBERFORMAT_TIME ); + if ((nType & NUMBERFORMAT_TIME)) + pTabViewShell->SetNumberFormat( NUMBERFORMAT_NUMBER ); + else + pTabViewShell->SetNumberFormat( NUMBERFORMAT_TIME ); + aSet.Put( SfxBoolItem(nSlot, !(nType & NUMBERFORMAT_TIME)) ); + rBindings.Invalidate( nSlot ); rReq.Done(); break; case SID_NUMBER_CURRENCY: - pTabViewShell->SetNumberFormat( NUMBERFORMAT_CURRENCY ); + if ((nType & NUMBERFORMAT_CURRENCY)) + pTabViewShell->SetNumberFormat( NUMBERFORMAT_NUMBER ); + else + pTabViewShell->SetNumberFormat( NUMBERFORMAT_CURRENCY ); + aSet.Put( SfxBoolItem(nSlot, !(nType & NUMBERFORMAT_CURRENCY)) ); + rBindings.Invalidate( nSlot ); rReq.Done(); break; case SID_NUMBER_PERCENT: - pTabViewShell->SetNumberFormat( NUMBERFORMAT_PERCENT ); + if ((nType & NUMBERFORMAT_PERCENT)) + pTabViewShell->SetNumberFormat( NUMBERFORMAT_NUMBER ); + else + pTabViewShell->SetNumberFormat( NUMBERFORMAT_PERCENT ); + aSet.Put( SfxBoolItem(nSlot, !(nType & NUMBERFORMAT_PERCENT)) ); + rBindings.Invalidate( nSlot ); rReq.Done(); break; case SID_NUMBER_STANDARD: @@ -1974,9 +2003,8 @@ void ScFormatShell::GetAlignState( SfxItemSet& rSet ) void ScFormatShell::GetNumFormatState( SfxItemSet& rSet ) { ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell(); - - // ScViewData* pViewData = GetViewData(); - ScDocument* pDoc = pViewData->GetDocument(); + ScDocument* pDoc = pViewData->GetDocument(); + short nType = GetCurrentNumberFormatType(); SfxWhichIter aIter(rSet); USHORT nWhich = aIter.FirstWhich(); @@ -2003,7 +2031,21 @@ void ScFormatShell::GetNumFormatState( SfxItemSet& rSet ) rSet.Put( SfxStringItem( nWhich, aFormatCode ) ); } break; - + case SID_NUMBER_SCIENTIFIC: + rSet.Put( SfxBoolItem(nWhich, (nType & NUMBERFORMAT_SCIENTIFIC)) ); + break; + case SID_NUMBER_DATE: + rSet.Put( SfxBoolItem(nWhich, (nType & NUMBERFORMAT_DATE)) ); + break; + case SID_NUMBER_CURRENCY: + rSet.Put( SfxBoolItem(nWhich, (nType & NUMBERFORMAT_CURRENCY)) ); + break; + case SID_NUMBER_PERCENT: + rSet.Put( SfxBoolItem(nWhich, (nType & NUMBERFORMAT_PERCENT)) ); + break; + case SID_NUMBER_TIME: + rSet.Put( SfxBoolItem(nWhich, (nType & NUMBERFORMAT_TIME)) ); + break; } nWhich = aIter.NextWhich(); } @@ -2154,3 +2196,68 @@ void ScFormatShell::StateFormatPaintbrush( SfxItemSet& rSet ) rSet.Put( SfxBoolItem( SID_FORMATPAINTBRUSH, pViewData->GetView()->HasPaintBrush() ) ); } +short ScFormatShell::GetCurrentNumberFormatType() +{ + short nType = NUMBERFORMAT_ALL; + ScDocument* pDoc = GetViewData()->GetDocument(); + ScMarkData aMark(GetViewData()->GetMarkData()); + const SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + if (!pFormatter) + return nType; + + // TODO: Find out how to get a selected table range in case multiple tables + // are selected. Currently we only check for the current active table. + + if ( aMark.IsMarked() || aMark.IsMultiMarked() ) + { + aMark.MarkToMulti(); + ScRange aRange; + aMark.GetMultiMarkArea(aRange); + + const ScMarkArray* pArray = aMark.GetArray(); + if (!pArray) + return nType; + + short nComboType = NUMBERFORMAT_ALL; + bool bFirstItem = true; + for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol) + { + const ScMarkArray& rColArray = pArray[nCol]; + if (!rColArray.HasMarks()) + continue; + + SCROW nRow1, nRow2; + ScMarkArrayIter aMarkIter(&rColArray); + while (aMarkIter.Next(nRow1, nRow2)) + { + ScRange aColRange(nCol, nRow1, aRange.aStart.Tab()); + aColRange.aEnd.SetRow(nRow2); + sal_uInt32 nNumFmt = pDoc->GetNumberFormat(aColRange); + const SvNumberformat* pEntry = pFormatter->GetEntry(nNumFmt); + if (!pEntry) + return 0; + + short nThisType = pEntry->GetType(); + if (bFirstItem) + { + bFirstItem = false; + nComboType = nThisType; + } + else if (nComboType != nThisType) + // mixed number format type. + return NUMBERFORMAT_ALL; + } + } + nType = nComboType; + } + else + { + sal_uInt32 nNumFmt; + pDoc->GetNumberFormat( pViewData->GetCurX(), pViewData->GetCurY(), + pViewData->GetTabNo(), nNumFmt ); + const SvNumberformat* pEntry = pFormatter->GetEntry( nNumFmt ); + nType = pEntry ? pEntry->GetType() : 0; + } + return nType; +} + diff --git sc/source/ui/view/tabview3.cxx sc/source/ui/view/tabview3.cxx index 674f310..25bba3a 100644 --- sc/source/ui/view/tabview3.cxx +++ sc/source/ui/view/tabview3.cxx @@ -269,6 +269,13 @@ void ScTabView::InvalidateAttribs() rBindings.Invalidate( SID_ALIGN_ANY_VCENTER ); rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM ); + rBindings.Invalidate( SID_NUMBER_CURRENCY ); + rBindings.Invalidate( SID_NUMBER_SCIENTIFIC ); + rBindings.Invalidate( SID_NUMBER_DATE ); + rBindings.Invalidate( SID_NUMBER_CURRENCY ); + rBindings.Invalidate( SID_NUMBER_PERCENT ); + rBindings.Invalidate( SID_NUMBER_TIME ); + // rBindings.Invalidate( SID_RANGE_VALUE ); // rBindings.Invalidate( SID_RANGE_FORMULA ); } diff --git sc/uiconfig/scalc/toolbar/formatobjectbar.xml sc/uiconfig/scalc/toolbar/formatobjectbar.xml index 22f023d..773befc 100644 --- sc/uiconfig/scalc/toolbar/formatobjectbar.xml +++ sc/uiconfig/scalc/toolbar/formatobjectbar.xml @@ -33,7 +33,7 @@ - +