diff options
author | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-06-08 08:36:06 +0200 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-06-08 08:36:06 +0200 |
commit | 3cb55341e41d9dc0b85d097ce8500e8b49d4ec67 (patch) | |
tree | d6378728ec14676d2dc9e465a5754f35fd64740a /sc/source/ui/view | |
parent | 7c54ab539e0b8d52df758cec4cafab675ce313c7 (diff) | |
parent | 028f64e7499338566665b4c6f6979e11fca21c76 (diff) |
Automated merge with http://x42-so4:8009/ooo
Diffstat (limited to 'sc/source/ui/view')
-rwxr-xr-x | sc/source/ui/view/dbfunc3.cxx | 171 | ||||
-rw-r--r-- | sc/source/ui/view/drawview.cxx | 8 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin.cxx | 13 | ||||
-rw-r--r-- | sc/source/ui/view/output2.cxx | 481 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun2.cxx | 17 |
5 files changed, 457 insertions, 233 deletions
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 406fdab9c824..35befa8f7a36 100755 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -1739,6 +1739,18 @@ void lcl_MoveToEnd( ScDPSaveDimension& rDim, const String& rItemName ) // puts it to the end of the list even if it was in the list before. } +struct ScOUStringCollate +{ + CollatorWrapper* mpCollator; + + ScOUStringCollate(CollatorWrapper* pColl) : mpCollator(pColl) {} + + bool operator()(const rtl::OUString& rStr1, const rtl::OUString& rStr2) const + { + return ( mpCollator->compareString(rStr1, rStr2) < 0 ); + } +}; + bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId ) { ScDocument* pDoc = GetViewData()->GetDocument(); @@ -1747,7 +1759,8 @@ bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16 return false; // We need to run this to get all members later. - pDPObj->BuildAllDimensionMembers(); + if ( pUserListId ) + pDPObj->BuildAllDimensionMembers(); USHORT nOrientation; long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation); @@ -1766,97 +1779,111 @@ bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16 if (!pSaveDim) return false; - typedef ScDPSaveDimension::MemberList MemList; - const MemList& rDimMembers = pSaveDim->GetMembers(); - list<OUString> aMembers; - hash_set<OUString, ::rtl::OUStringHash> aMemberSet; - size_t nMemberCount = 0; - for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end(); - itr != itrEnd; ++itr) + // manual evaluation of sort order is only needed if a user list id is given + if ( pUserListId ) { - ScDPSaveMember* pMem = *itr; - aMembers.push_back(pMem->GetName()); - aMemberSet.insert(pMem->GetName()); - ++nMemberCount; - } - - // Sort the member list in ascending order. - aMembers.sort(); + typedef ScDPSaveDimension::MemberList MemList; + const MemList& rDimMembers = pSaveDim->GetMembers(); + list<OUString> aMembers; + hash_set<OUString, ::rtl::OUStringHash> aMemberSet; + size_t nMemberCount = 0; + for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end(); + itr != itrEnd; ++itr) + { + ScDPSaveMember* pMem = *itr; + aMembers.push_back(pMem->GetName()); + aMemberSet.insert(pMem->GetName()); + ++nMemberCount; + } - // Collect and rank those custom sort strings that also exist in the member name list. + // Sort the member list in ascending order. + ScOUStringCollate aCollate( ScGlobal::GetCollator() ); + aMembers.sort(aCollate); - typedef hash_map<OUString, sal_uInt16, OUStringHash> UserSortMap; - UserSortMap aSubStrs; - sal_uInt16 nSubCount = 0; - if (pUserListId) - { - ScUserList* pUserList = ScGlobal::GetUserList(); - if (!pUserList) - return false; + // Collect and rank those custom sort strings that also exist in the member name list. + typedef hash_map<OUString, sal_uInt16, OUStringHash> UserSortMap; + UserSortMap aSubStrs; + sal_uInt16 nSubCount = 0; + if (pUserListId) { - sal_uInt16 n = pUserList->GetCount(); - if (!n || *pUserListId >= n) + ScUserList* pUserList = ScGlobal::GetUserList(); + if (!pUserList) return false; - } - ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[*pUserListId]); - if (pData) - { - sal_uInt16 n = pData->GetSubCount(); - for (sal_uInt16 i = 0; i < n; ++i) { - OUString aSub = pData->GetSubStr(i); - if (!aMemberSet.count(aSub)) - // This string doesn't exist in the member name set. Don't add this. - continue; + sal_uInt16 n = pUserList->GetCount(); + if (!n || *pUserListId >= n) + return false; + } + + ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[*pUserListId]); + if (pData) + { + sal_uInt16 n = pData->GetSubCount(); + for (sal_uInt16 i = 0; i < n; ++i) + { + OUString aSub = pData->GetSubStr(i); + if (!aMemberSet.count(aSub)) + // This string doesn't exist in the member name set. Don't add this. + continue; - aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++)); + aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++)); + } } } - } - // Rank all members. + // Rank all members. - vector<OUString> aRankedNames(nMemberCount); - sal_uInt16 nCurStrId = 0; - for (list<OUString>::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end(); - itr != itrEnd; ++itr) - { - OUString aName = *itr; - sal_uInt16 nRank = 0; - UserSortMap::const_iterator itrSub = aSubStrs.find(aName); - if (itrSub == aSubStrs.end()) - nRank = nSubCount + nCurStrId++; - else - nRank = itrSub->second; + vector<OUString> aRankedNames(nMemberCount); + sal_uInt16 nCurStrId = 0; + for (list<OUString>::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end(); + itr != itrEnd; ++itr) + { + OUString aName = *itr; + sal_uInt16 nRank = 0; + UserSortMap::const_iterator itrSub = aSubStrs.find(aName); + if (itrSub == aSubStrs.end()) + nRank = nSubCount + nCurStrId++; + else + nRank = itrSub->second; - if (!bAscending) - nRank = static_cast< sal_uInt16 >( nMemberCount - nRank - 1 ); + if (!bAscending) + nRank = static_cast< sal_uInt16 >( nMemberCount - nRank - 1 ); - aRankedNames[nRank] = aName; - } + aRankedNames[nRank] = aName; + } - // Re-order ScDPSaveMember instances with the new ranks. + // Re-order ScDPSaveMember instances with the new ranks. - for (vector<OUString>::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end(); - itr != itrEnd; ++itr) - { - const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr); - if (!pOldMem) - // All members are supposed to be present. - continue; + for (vector<OUString>::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end(); + itr != itrEnd; ++itr) + { + const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr); + if (!pOldMem) + // All members are supposed to be present. + continue; - ScDPSaveMember* pNewMem = new ScDPSaveMember(*pOldMem); - pSaveDim->AddMember(pNewMem); - } + 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. + // 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); + sheet::DataPilotFieldSortInfo aSortInfo; + aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL; + pSaveDim->SetSortInfo(&aSortInfo); + } + else + { + // without user list id, just apply sorting mode + + sheet::DataPilotFieldSortInfo aSortInfo; + aSortInfo.Mode = sheet::DataPilotFieldSortMode::NAME; + aSortInfo.IsAscending = bAscending; + pSaveDim->SetSortInfo(&aSortInfo); + } // Update the datapilot with the newly sorted field members. diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index 311bcf8c24b2..cc09722530ad 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -397,13 +397,13 @@ void ScDrawView::MarkListHasChanged() ScTabViewShell* pViewSh = pViewData->GetViewShell(); - if (!bInConstruct) // nicht wenn die View gerade angelegt wird + // #i110829# remove the cell selection only if drawing objects are selected + if ( !bInConstruct && GetMarkedObjectList().GetMarkCount() ) { - pViewSh->Unmark(); // Selektion auff'm Doc entfernen + pViewSh->Unmark(); // remove cell selection // #65379# end cell edit mode if drawing objects are selected - if ( GetMarkedObjectList().GetMarkCount() ) - SC_MOD()->InputEnterHandler(); + SC_MOD()->InputEnterHandler(); } // IP deaktivieren diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index b8eeb868809e..87740a88e4df 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -165,6 +165,7 @@ private: BOOL bInit; BOOL bCancelled; BOOL bInSelect; + bool mbListHasDates; ULONG nSel; ScFilterBoxMode eMode; @@ -188,6 +189,8 @@ public: BOOL IsInInit() const { return bInit; } void SetCancelled() { bCancelled = TRUE; } BOOL IsInSelect() const { return bInSelect; } + void SetListHasDates(bool b) { mbListHasDates = b; } + bool HasDates() const { return mbListHasDates; } }; //------------------------------------------------------------------- @@ -203,6 +206,7 @@ ScFilterListBox::ScFilterListBox( Window* pParent, ScGridWindow* pGrid, bInit( TRUE ), bCancelled( FALSE ), bInSelect( FALSE ), + mbListHasDates(false), nSel( 0 ), eMode( eNewMode ) { @@ -907,7 +911,9 @@ void ScGridWindow::DoAutoFilterMenue( SCCOL nCol, SCROW nRow, BOOL bDataSelect ) pFilterBox->SetSeparatorPos( nDefCount - 1 ); // get list entries - pDoc->GetFilterEntries( nCol, nRow, nTab, aStrings, true ); + bool bHasDates = false; + pDoc->GetFilterEntries( nCol, nRow, nTab, true, aStrings, bHasDates); + pFilterBox->SetListHasDates(bHasDates); // check widths of numerical entries (string entries are not included) // so all numbers are completely visible @@ -1117,7 +1123,7 @@ void ScGridWindow::FilterSelect( ULONG nSel ) ExecDataSelect( nCol, nRow, aString ); break; case SC_FILTERBOX_FILTER: - ExecFilter( nSel, nCol, nRow, aString ); + ExecFilter( nSel, nCol, nRow, aString, pFilterBox->HasDates() ); break; case SC_FILTERBOX_SCENARIO: pViewData->GetView()->UseScenario( aString ); @@ -1150,7 +1156,7 @@ void ScGridWindow::ExecDataSelect( SCCOL nCol, SCROW nRow, const String& rStr ) void ScGridWindow::ExecFilter( ULONG nSel, SCCOL nCol, SCROW nRow, - const String& aValue ) + const String& aValue, bool bCheckForDates ) { SCTAB nTab = pViewData->GetTabNo(); ScDocument* pDoc = pViewData->GetDocument(); @@ -1222,6 +1228,7 @@ void ScGridWindow::ExecFilter( ULONG nSel, rNewEntry.bDoQuery = TRUE; rNewEntry.bQueryByString = TRUE; rNewEntry.nField = nCol; + rNewEntry.bQueryByDate = bCheckForDates; if ( nSel == SC_AUTOFILTER_TOP10 ) { rNewEntry.eOp = SC_TOPVAL; diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index 53851f0e3cf0..5a48d0d310d5 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -53,6 +53,7 @@ #include <editeng/udlnitem.hxx> #include <editeng/unolingu.hxx> #include <svl/zforlist.hxx> +#include <svl/zformat.hxx> #include <vcl/svapp.hxx> #include <vcl/metric.hxx> #include <vcl/outdev.hxx> @@ -74,6 +75,8 @@ #include "scmod.hxx" #include "fillinfo.hxx" +#include <boost/ptr_container/ptr_vector.hpp> + #include <math.h> //! Autofilter-Breite mit column.cxx zusammenfassen @@ -108,6 +111,9 @@ class ScDrawStringsVars String aString; // Inhalte Size aTextSize; long nOriginalWidth; + long nMaxDigitWidth; + long nSignWidth; + long nDotWidth; ScBaseCell* pLastCell; ULONG nValueFormat; @@ -132,7 +138,7 @@ public: void SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet ); BOOL SetText( ScBaseCell* pCell ); // TRUE -> pOldPattern vergessen - void SetHashText(); + void SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth ); void SetAutoText( const String& rAutoText ); const ScPatternAttr* GetPattern() const { return pPattern; } @@ -161,6 +167,14 @@ public: pCondSet->GetItemState( ATTR_FONT_HEIGHT, TRUE ); } BOOL HasEditCharacters() const; + +private: + void SetHashText(); + long GetMaxDigitWidth(); + long GetSignWidth(); + long GetDotWidth(); + void TextChanged(); + long ConvertWidthLogicToPixel( long nWidth ) const; }; //================================================================== @@ -176,6 +190,9 @@ ScDrawStringsVars::ScDrawStringsVars(ScOutputData* pData, BOOL bPTL) : nIndent ( 0 ), bRotated ( FALSE ), nOriginalWidth( 0 ), + nMaxDigitWidth( 0 ), + nSignWidth( 0 ), + nDotWidth( 0 ), pLastCell ( NULL ), nValueFormat( 0 ), bLineBreak ( FALSE ), @@ -242,6 +259,10 @@ void ScDrawStringsVars::SetShrinkScale( long nScale, BYTE nScript ) void ScDrawStringsVars::SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet, ScBaseCell* pCell, BYTE nScript ) { + nMaxDigitWidth = 0; + nSignWidth = 0; + nDotWidth = 0; + pPattern = pNew; pCondSet = pSet; @@ -393,6 +414,9 @@ void ScDrawStringsVars::SetPattern( const ScPatternAttr* pNew, const SfxItemSet* void ScDrawStringsVars::SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet ) { + nMaxDigitWidth = 0; + nSignWidth = 0; + nDotWidth = 0; // wird gerufen, wenn sich die Font-Variablen nicht aendern (!StringDiffer) pPattern = pNew; @@ -467,28 +491,7 @@ BOOL ScDrawStringsVars::SetText( ScBaseCell* pCell ) pLastCell = NULL; // naechstes Mal wieder hierherkommen } - OutputDevice* pRefDevice = pOutput->pRefDevice; - OutputDevice* pFmtDevice = pOutput->pFmtDevice; - aTextSize.Width() = pFmtDevice->GetTextWidth( aString ); - aTextSize.Height() = pFmtDevice->GetTextHeight(); - - if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER ) - { - double fMul = pOutput->GetStretch(); - aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5); - } - - aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent(); - if ( GetOrient() != SVX_ORIENTATION_STANDARD ) - { - long nTemp = aTextSize.Height(); - aTextSize.Height() = aTextSize.Width(); - aTextSize.Width() = nTemp; - } - - nOriginalWidth = aTextSize.Width(); - if ( bPixelToLogic ) - aTextSize = pRefDevice->LogicToPixel( aTextSize ); + TextChanged(); } // sonst String/Groesse behalten } @@ -508,6 +511,82 @@ void ScDrawStringsVars::SetHashText() SetAutoText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) ); } +void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth ) +{ + if (!pCell) + return; + + CellType eType = pCell->GetCellType(); + if (eType != CELLTYPE_VALUE && eType != CELLTYPE_FORMULA) + // must be a value or formula cell. + return; + + if (eType == CELLTYPE_FORMULA && !static_cast<ScFormulaCell*>(pCell)->IsValue()) + // If it's formula, the result must be a value. + return; + + ULONG nFormat = GetValueFormat(); + if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0) + { + // Not 'General' number format. Set hash text and bail out. + SetHashText(); + return; + } + + double fVal = (eType == CELLTYPE_VALUE) ? + static_cast<ScValueCell*>(pCell)->GetValue() : static_cast<ScFormulaCell*>(pCell)->GetValue(); + + const SvNumberformat* pNumFormat = pOutput->pDoc->GetFormatTable()->GetEntry(nFormat); + if (!pNumFormat) + return; + + long nMaxDigit = GetMaxDigitWidth(); + sal_uInt16 nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit); + + if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString)) + // Failed to get output string. Bail out. + return; + + sal_uInt8 nSignCount = 0, nDecimalCount = 0; + xub_StrLen nLen = aString.Len(); + sal_Unicode cDecSep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator.getStr()[0]; + for (xub_StrLen i = 0; i < nLen; ++i) + { + sal_Unicode c = aString.GetChar(i); + if (c == sal_Unicode('-')) + ++nSignCount; + else if (c == cDecSep) + ++nDecimalCount; + } + if (nDecimalCount) + nWidth += (nMaxDigit - GetDotWidth()) * nDecimalCount; + if (nSignCount) + nWidth += (nMaxDigit - GetSignWidth()) * nSignCount; + + if (nDecimalCount || nSignCount) + { + // Re-calculate. + nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit); + if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString)) + // Failed to get output string. Bail out. + return; + } + + long nActualTextWidth = pOutput->pFmtDevice->GetTextWidth(aString); + + if (bPixelToLogic) + nActualTextWidth = ConvertWidthLogicToPixel(nActualTextWidth); + + if (nActualTextWidth > nWidth) + { + // Even after the decimal adjustment the text doesn't fit. Give up. + SetHashText(); + return; + } + + TextChanged(); +} + void ScDrawStringsVars::SetAutoText( const String& rAutoText ) { aString = rAutoText; @@ -538,6 +617,80 @@ void ScDrawStringsVars::SetAutoText( const String& rAutoText ) pLastCell = NULL; // derselbe Text kann in der naechsten Zelle wieder passen } +long ScDrawStringsVars::GetMaxDigitWidth() +{ + if (nMaxDigitWidth > 0) + return nMaxDigitWidth; + + sal_Char cZero = '0'; + for (int i = 0; i < 10; ++i) + { + sal_Char cDigit = cZero + i; + long n = pOutput->pFmtDevice->GetTextWidth(String(cDigit)); + nMaxDigitWidth = ::std::max(nMaxDigitWidth, n); + } + + if (bPixelToLogic) + nMaxDigitWidth = ConvertWidthLogicToPixel(nMaxDigitWidth); + return nMaxDigitWidth; +} + +long ScDrawStringsVars::GetSignWidth() +{ + if (nSignWidth > 0) + return nSignWidth; + + nSignWidth = pOutput->pFmtDevice->GetTextWidth(String('-')); + if (bPixelToLogic) + nSignWidth = ConvertWidthLogicToPixel(nSignWidth); + return nSignWidth; +} + +long ScDrawStringsVars::GetDotWidth() +{ + if (nDotWidth > 0) + return nDotWidth; + + const ::rtl::OUString& sep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator; + nDotWidth = pOutput->pFmtDevice->GetTextWidth(sep); + if (bPixelToLogic) + nDotWidth = ConvertWidthLogicToPixel(nDotWidth); + return nDotWidth; +} + +void ScDrawStringsVars::TextChanged() +{ + OutputDevice* pRefDevice = pOutput->pRefDevice; + OutputDevice* pFmtDevice = pOutput->pFmtDevice; + aTextSize.Width() = pFmtDevice->GetTextWidth( aString ); + aTextSize.Height() = pFmtDevice->GetTextHeight(); + + if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER ) + { + double fMul = pOutput->GetStretch(); + aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5); + } + + aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent(); + if ( GetOrient() != SVX_ORIENTATION_STANDARD ) + { + long nTemp = aTextSize.Height(); + aTextSize.Height() = aTextSize.Width(); + aTextSize.Width() = nTemp; + } + + nOriginalWidth = aTextSize.Width(); + if ( bPixelToLogic ) + aTextSize = pRefDevice->LogicToPixel( aTextSize ); +} + +long ScDrawStringsVars::ConvertWidthLogicToPixel( long nWidth ) const +{ + Size aSize(nWidth, pOutput->pFmtDevice->GetTextHeight()); + aSize = pOutput->pRefDevice->LogicToPixel(aSize); + return aSize.Width(); +} + BOOL ScDrawStringsVars::HasEditCharacters() const { static const sal_Unicode pChars[] = @@ -919,18 +1072,14 @@ BOOL ScOutputData::IsAvailable( SCCOL nX, SCROW nY ) // bCellIsValue: if set, don't extend into empty cells // bBreak: if set, don't extend, and don't set clip marks (but rLeftClip/rRightClip is set) // bOverwrite: if set, also extend into non-empty cells (for rotated text) -// rAlignRect: output: single or merged cell, used for alignment (visual rectangle) -// rClipRect: output: total output area, for clipping (visual) -// rLeftClip: output: need to clip at rClipRect left (visual) edge -// rRightClip: output: same for right +// rParam output: various area parameters. void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY, - SCCOL nCellX, SCROW nCellY, long nNeeded, - const ScPatternAttr& rPattern, - USHORT nHorJustify, BOOL bCellIsValue, - BOOL bBreak, BOOL bOverwrite, - Rectangle& rAlignRect, Rectangle& rClipRect, - BOOL& rLeftClip, BOOL& rRightClip ) + SCCOL nCellX, SCROW nCellY, long nNeeded, + const ScPatternAttr& rPattern, + USHORT nHorJustify, bool bCellIsValue, + bool bBreak, bool bOverwrite, + OutputAreaParam& rParam ) { // rThisRowInfo may be for a different row than nCellY, is still used for clip marks RowInfo& rThisRowInfo = pRowInfo[nArrY]; @@ -1009,21 +1158,23 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY --nMergeSizeX; // leave out the grid horizontally, also for alignment (align between grid lines) + rParam.mnColWidth = nMergeSizeX; // store the actual column width. + // // construct the rectangles using logical left/right values (justify is called at the end) // // rAlignRect is the single cell or merged area, used for alignment. - rAlignRect.Left() = nCellPosX; - rAlignRect.Right() = nCellPosX + ( nMergeSizeX - 1 ) * nLayoutSign; - rAlignRect.Top() = nCellPosY; - rAlignRect.Bottom() = nCellPosY + nMergeSizeY - 1; + rParam.maAlignRect.Left() = nCellPosX; + rParam.maAlignRect.Right() = nCellPosX + ( nMergeSizeX - 1 ) * nLayoutSign; + rParam.maAlignRect.Top() = nCellPosY; + rParam.maAlignRect.Bottom() = nCellPosY + nMergeSizeY - 1; // rClipRect is all cells that are used for output. // For merged cells this is the same as rAlignRect, otherwise neighboring cells can also be used. - rClipRect = rAlignRect; + rParam.maClipRect = rParam.maAlignRect; if ( nNeeded > nMergeSizeX ) { SvxCellHorJustify eHorJust = (SvxCellHorJustify)nHorJustify; @@ -1064,7 +1215,7 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY ++nRightX; long nAdd = (long) ( pDoc->GetColWidth( nRightX, nTab ) * nPPTX ); nRightMissing -= nAdd; - rClipRect.Right() += nAdd * nLayoutSign; + rParam.maClipRect.Right() += nAdd * nLayoutSign; if ( rThisRowInfo.nRowNo == nCellY && nRightX >= nX1 && nRightX <= nX2 ) rThisRowInfo.pCellInfo[nRightX].bHideGrid = TRUE; @@ -1078,7 +1229,7 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY --nLeftX; long nAdd = (long) ( pDoc->GetColWidth( nLeftX, nTab ) * nPPTX ); nLeftMissing -= nAdd; - rClipRect.Left() -= nAdd * nLayoutSign; + rParam.maClipRect.Left() -= nAdd * nLayoutSign; } } @@ -1089,22 +1240,22 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY rThisRowInfo.pCellInfo[nRightX+1].nClipMark |= SC_CLIPMARK_RIGHT; bAnyClipped = TRUE; long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX ); - rClipRect.Right() -= nMarkPixel * nLayoutSign; + rParam.maClipRect.Right() -= nMarkPixel * nLayoutSign; } if ( nLeftMissing > 0 && bMarkClipped && nLeftX >= nX1 && nLeftX <= nX2 && !bBreak && !bCellIsValue ) { rThisRowInfo.pCellInfo[nLeftX+1].nClipMark |= SC_CLIPMARK_LEFT; bAnyClipped = TRUE; long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX ); - rClipRect.Left() += nMarkPixel * nLayoutSign; + rParam.maClipRect.Left() += nMarkPixel * nLayoutSign; } - rLeftClip = ( nLeftMissing > 0 ); - rRightClip = ( nRightMissing > 0 ); + rParam.mbLeftClip = ( nLeftMissing > 0 ); + rParam.mbRightClip = ( nRightMissing > 0 ); } else { - rLeftClip = rRightClip = FALSE; + rParam.mbLeftClip = rParam.mbRightClip = FALSE; // leave space for AutoFilter on screen // (for automatic line break: only if not formatting for printer, as in ScColumn::GetNeededSize) @@ -1120,30 +1271,30 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY // content fits even in the remaining area without the filter button // -> align within that remaining area - rAlignRect.Right() -= nFilter * nLayoutSign; - rClipRect.Right() -= nFilter * nLayoutSign; + rParam.maAlignRect.Right() -= nFilter * nLayoutSign; + rParam.maClipRect.Right() -= nFilter * nLayoutSign; // if a number doesn't fit, don't hide part of the number behind the button // -> set clip flags, so "###" replacement is used (but also within the smaller area) if ( !bFit ) - rLeftClip = rRightClip = TRUE; + rParam.mbLeftClip = rParam.mbRightClip = TRUE; } } } // justify both rectangles for alignment calculation, use with DrawText etc. - rAlignRect.Justify(); - rClipRect.Justify(); + rParam.maAlignRect.Justify(); + rParam.maClipRect.Justify(); #if 0 //! Test !!! pDev->Push(); pDev->SetLineColor(); pDev->SetFillColor( COL_LIGHTGREEN ); - pDev->DrawRect( pDev->PixelToLogic(rClipRect) ); - pDev->DrawRect( rClipRect ); // print preview + pDev->DrawRect( pDev->PixelToLogic(rParam.maClipRect) ); + pDev->DrawRect( rParam.maClipRect ); // print preview pDev->Pop(); //! Test !!! #endif @@ -1164,10 +1315,6 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) ScDrawStringsVars aVars( this, bPixelToLogic ); - const ScPatternAttr* pOldPattern = NULL; - const SfxItemSet* pOldCondSet = NULL; - BYTE nOldScript = 0; - BOOL bProgress = FALSE; long nInitPosX = nScrX; @@ -1184,15 +1331,19 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) --nLoopStartX; // start before nX1 for rest of long text to the left // variables for GetOutputArea + OutputAreaParam aAreaParam; BOOL bCellIsValue = FALSE; - BOOL bLeftClip = FALSE; - BOOL bRightClip = FALSE; long nNeededWidth = 0; - Rectangle aAlignRect; - Rectangle aClipRect; SvxCellHorJustify eOutHorJust = SVX_HOR_JUSTIFY_STANDARD; const ScPatternAttr* pPattern = NULL; const SfxItemSet* pCondSet = NULL; + const ScPatternAttr* pOldPattern = NULL; + const SfxItemSet* pOldCondSet = NULL; + BYTE nOldScript = 0; + + // alternative pattern instances in case we need to modify the pattern + // before processing the cell value. + ::boost::ptr_vector<ScPatternAttr> aAltPatterns; long nPosY = nScrY; for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++) @@ -1330,6 +1481,18 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab ); } + if (pCell->HasValueData() && + static_cast<const SfxBoolItem&>( + pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue()) + { + // Disable line break when the cell content is numeric. + aAltPatterns.push_back(new ScPatternAttr(*pPattern)); + ScPatternAttr* pAltPattern = &aAltPatterns.back(); + SfxBoolItem aLineBreak(ATTR_LINEBREAK, false); + pAltPattern->GetItemSet().Put(aLineBreak); + pPattern = pAltPattern; + } + BYTE nScript = GetScriptType( pDoc, pCell, pPattern, pCondSet ); if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType(); if ( pPattern != pOldPattern || pCondSet != pOldCondSet || @@ -1360,6 +1523,7 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) bNeedEdit = aVars.HasEditCharacters() || (bFormulaCell && ((ScFormulaCell*)pCell)->IsMultilineResult()); } + long nTotalMargin = 0; if (bDoCell && !bNeedEdit) { CellType eCellType = pCell->GetCellType(); @@ -1381,14 +1545,17 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) BOOL bRepeat = aVars.IsRepeat() && !bBreak; BOOL bShrink = aVars.IsShrink() && !bBreak && !bRepeat; - long nTotalMargin = (long) ( aVars.GetLeftTotal() * nPPTX ) + - (long) ( aVars.GetMargin()->GetRightMargin() * nPPTX ); + nTotalMargin = + static_cast<long>(aVars.GetLeftTotal() * nPPTX) + + static_cast<long>(aVars.GetMargin()->GetRightMargin() * nPPTX); + nNeededWidth = aVars.GetTextSize().Width() + nTotalMargin; + // GetOutputArea gives justfied rectangles GetOutputArea( nX, nArrY, nPosX, nPosY, nCellX, nCellY, nNeededWidth, - *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), - bCellIsValue || bRepeat || bShrink, bBreak, FALSE, - aAlignRect, aClipRect, bLeftClip, bRightClip ); + *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), + bCellIsValue || bRepeat || bShrink, bBreak, FALSE, + aAreaParam ); if ( bShrink ) { @@ -1398,9 +1565,9 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) // DrawEdit is used to vertically scale 90 deg rotated text. bNeedEdit = TRUE; } - else if ( bLeftClip || bRightClip ) // horizontal + else if ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) // horizontal { - long nAvailable = aAlignRect.GetWidth() - nTotalMargin; + long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin; long nScaleSize = aVars.GetTextSize().Width(); // without margin if ( nScaleSize > 0 ) // 0 if the text is empty (formulas, number formats) @@ -1424,16 +1591,16 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) // If even at half the size the font still isn't rendered smaller, // fall back to normal clipping (showing ### for numbers). if ( nNewSize <= nAvailable ) - bLeftClip = bRightClip = FALSE; + aAreaParam.mbLeftClip = aAreaParam.mbRightClip = FALSE; pOldPattern = NULL; } } } - if ( bRepeat && !bLeftClip && !bRightClip ) + if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip ) { - long nAvailable = aAlignRect.GetWidth() - nTotalMargin; + long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin; long nRepeatSize = aVars.GetTextSize().Width(); // without margin // When formatting for the printer, the text sizes don't always add up. // Round down (too few repetitions) rather than exceeding the cell size then: @@ -1457,13 +1624,13 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) if ( bBreak ) { if ( aVars.GetOrient() == SVX_ORIENTATION_STANDARD ) - bNeedEdit = ( bLeftClip || bRightClip ); + bNeedEdit = ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ); else { long nHeight = aVars.GetTextSize().Height() + (long)(aVars.GetMargin()->GetTopMargin()*nPPTY) + (long)(aVars.GetMargin()->GetBottomMargin()*nPPTY); - bNeedEdit = ( nHeight > aClipRect.GetHeight() ); + bNeedEdit = ( nHeight > aAreaParam.maClipRect.GetHeight() ); } } } @@ -1479,48 +1646,49 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) } if ( bDoCell ) { - if ( bCellIsValue && ( bLeftClip || bRightClip ) ) + if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) ) { - aVars.SetHashText(); + // Adjust the decimals to fit the available column width. + aVars.SetTextToWidthOrHash(pCell, aAreaParam.mnColWidth - nTotalMargin); nNeededWidth = aVars.GetTextSize().Width() + (long) ( aVars.GetLeftTotal() * nPPTX ) + (long) ( aVars.GetMargin()->GetRightMargin() * nPPTX ); - if ( nNeededWidth <= aClipRect.GetWidth() ) - bLeftClip = bRightClip = FALSE; + if ( nNeededWidth <= aAreaParam.maClipRect.GetWidth() ) + aAreaParam.mbLeftClip = aAreaParam.mbRightClip = FALSE; // If the "###" replacement doesn't fit into the cells, no clip marks // are shown, as the "###" already denotes too little space. // The rectangles from the first GetOutputArea call remain valid. } - long nJustPosX = aAlignRect.Left(); // "justified" - effect of alignment will be added - long nJustPosY = aAlignRect.Top(); - long nAvailWidth = aAlignRect.GetWidth(); - long nOutHeight = aAlignRect.GetHeight(); + long nJustPosX = aAreaParam.maAlignRect.Left(); // "justified" - effect of alignment will be added + long nJustPosY = aAreaParam.maAlignRect.Top(); + long nAvailWidth = aAreaParam.maAlignRect.GetWidth(); + long nOutHeight = aAreaParam.maAlignRect.GetHeight(); - BOOL bOutside = ( aClipRect.Right() < nScrX || aClipRect.Left() >= nScrX + nScrW ); - if ( aClipRect.Left() < nScrX ) + BOOL bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW ); + if ( aAreaParam.maClipRect.Left() < nScrX ) { - aClipRect.Left() = nScrX; - bLeftClip = TRUE; + aAreaParam.maClipRect.Left() = nScrX; + aAreaParam.mbLeftClip = TRUE; } - if ( aClipRect.Right() > nScrX + nScrW ) + if ( aAreaParam.maClipRect.Right() > nScrX + nScrW ) { - aClipRect.Right() = nScrX + nScrW; //! minus one? - bRightClip = TRUE; + aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one? + aAreaParam.mbRightClip = TRUE; } - BOOL bHClip = bLeftClip || bRightClip; + BOOL bHClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip; BOOL bVClip = FALSE; - if ( aClipRect.Top() < nScrY ) + if ( aAreaParam.maClipRect.Top() < nScrY ) { - aClipRect.Top() = nScrY; + aAreaParam.maClipRect.Top() = nScrY; bVClip = TRUE; } - if ( aClipRect.Bottom() > nScrY + nScrH ) + if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH ) { - aClipRect.Bottom() = nScrY + nScrH; //! minus one? + aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one? bVClip = TRUE; } @@ -1603,27 +1771,27 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) if (!bHClip) { - aClipRect.Left() = nScrX; - aClipRect.Right() = nScrX+nScrW; + aAreaParam.maClipRect.Left() = nScrX; + aAreaParam.maClipRect.Right() = nScrX+nScrW; } if (!bVClip) { - aClipRect.Top() = nScrY; - aClipRect.Bottom() = nScrY+nScrH; + aAreaParam.maClipRect.Top() = nScrY; + aAreaParam.maClipRect.Bottom() = nScrY+nScrH; } // aClipRect is not used after SetClipRegion/IntersectClipRegion, // so it can be modified here if (bPixelToLogic) - aClipRect = pRefDevice->PixelToLogic( aClipRect ); + aAreaParam.maClipRect = pRefDevice->PixelToLogic( aAreaParam.maClipRect ); if (bMetaFile) { pDev->Push(); - pDev->IntersectClipRegion( aClipRect ); + pDev->IntersectClipRegion( aAreaParam.maClipRect ); } else - pDev->SetClipRegion( Region( aClipRect ) ); + pDev->SetClipRegion( Region( aAreaParam.maClipRect ) ); } Point aURLStart( nJustPosX, nJustPosY ); // copy before modifying for orientation @@ -1827,7 +1995,7 @@ long lcl_GetEditSize( EditEngine& rEngine, BOOL bWidth, BOOL bSwap, long nAttrRo void ScOutputData::ShrinkEditEngine( EditEngine& rEngine, const Rectangle& rAlignRect, long nLeftM, long nTopM, long nRightM, long nBottomM, BOOL bWidth, USHORT nOrient, long nAttrRotate, BOOL bPixelToLogic, - long& rEngineWidth, long& rEngineHeight, long& rNeededPixel, BOOL& rLeftClip, BOOL& rRightClip ) + long& rEngineWidth, long& rEngineHeight, long& rNeededPixel, bool& rLeftClip, bool& rRightClip ) { if ( !bWidth ) { @@ -2149,10 +2317,7 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) nPosY = nScrY; } - Rectangle aAlignRect; - Rectangle aClipRect; - BOOL bLeftClip = FALSE; - BOOL bRightClip = FALSE; + OutputAreaParam aAreaParam; // // Initial page size - large for normal text, cell size for automatic line breaks @@ -2167,27 +2332,39 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) //! handle nArrY == 0 GetOutputArea( nXForPos, nArrYForPos, nPosX, nPosY, nCellX, nCellY, 0, - *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), - bCellIsValue, TRUE, FALSE, - aAlignRect, aClipRect, bLeftClip, bRightClip ); + *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), + bCellIsValue, true, false, aAreaParam ); //! special ScEditUtil handling if formatting for printer if ( eOrient == SVX_ORIENTATION_TOPBOTTOM || eOrient == SVX_ORIENTATION_BOTTOMTOP ) - aPaperSize.Width() = aAlignRect.GetHeight() - nTopM - nBottomM; + aPaperSize.Width() = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM; else - aPaperSize.Width() = aAlignRect.GetWidth() - nLeftM - nRightM; + aPaperSize.Width() = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM; if (bAsianVertical && bBreak) { // add some extra height (default margin value) for safety // as long as GetEditArea isn't used below long nExtraHeight = (long)( 20 * nPPTY ); - aPaperSize.Height() = aAlignRect.GetHeight() - nTopM - nBottomM + nExtraHeight; + aPaperSize.Height() = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM + nExtraHeight; } } if (bPixelToLogic) - pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize)); + { + Size aLogicSize = pRefDevice->PixelToLogic(aPaperSize); + if ( bBreak && !bAsianVertical && pRefDevice != pFmtDevice ) + { + // #i85342# screen display and formatting for printer, + // use same GetEditArea call as in ScViewData::SetEditEngine + + Fraction aFract(1,1); + Rectangle aUtilRect = ScEditUtil( pDoc, nCellX, nCellY, nTab, Point(0,0), pFmtDevice, + HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( pPattern, FALSE ); + aLogicSize.Width() = aUtilRect.GetWidth(); + } + pEngine->SetPaperSize(aLogicSize); + } else pEngine->SetPaperSize(aPaperSize); @@ -2372,26 +2549,26 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) { // for break, the first GetOutputArea call is sufficient GetOutputArea( nXForPos, nArrYForPos, nPosX, nPosY, nCellX, nCellY, nNeededPixel, - *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), - bCellIsValue || bRepeat || bShrink, FALSE, FALSE, - aAlignRect, aClipRect, bLeftClip, bRightClip ); + *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), + bCellIsValue || bRepeat || bShrink, false, false, aAreaParam ); if ( bShrink ) { BOOL bWidth = ( eOrient == SVX_ORIENTATION_STANDARD && !bAsianVertical ); - ShrinkEditEngine( *pEngine, aAlignRect, + ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM, bWidth, sal::static_int_cast<USHORT>(eOrient), 0, bPixelToLogic, - nEngineWidth, nEngineHeight, nNeededPixel, bLeftClip, bRightClip ); + nEngineWidth, nEngineHeight, nNeededPixel, + aAreaParam.mbLeftClip, aAreaParam.mbRightClip ); } - if ( bRepeat && !bLeftClip && !bRightClip && pEngine->GetParagraphCount() == 1 ) + if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && pEngine->GetParagraphCount() == 1 ) { // First check if twice the space for the formatted text is available // (otherwise just keep it unchanged). long nFormatted = nNeededPixel - nLeftM - nRightM; // without margin - long nAvailable = aAlignRect.GetWidth() - nLeftM - nRightM; + long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM; if ( nAvailable >= 2 * nFormatted ) { // "repeat" is handled with unformatted text (for performance reasons) @@ -2425,7 +2602,7 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) } } - if ( bCellIsValue && ( bLeftClip || bRightClip ) ) + if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) ) { pEngine->SetText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) ); nEngineWidth = (long) pEngine->CalcTextWidth(); @@ -2448,11 +2625,11 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) } } - long nStartX = aAlignRect.Left(); - long nStartY = aAlignRect.Top(); - long nCellWidth = aAlignRect.GetWidth(); + long nStartX = aAreaParam.maAlignRect.Left(); + long nStartY = aAreaParam.maAlignRect.Top(); + long nCellWidth = aAreaParam.maAlignRect.GetWidth(); long nOutWidth = nCellWidth - 1 - nLeftM - nRightM; - long nOutHeight = aAlignRect.GetHeight() - nTopM - nBottomM; + long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM; if ( bBreak || eOrient != SVX_ORIENTATION_STANDARD || bAsianVertical ) { @@ -2472,21 +2649,21 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) nStartX += nLeftM; } - BOOL bOutside = ( aClipRect.Right() < nScrX || aClipRect.Left() >= nScrX + nScrW ); - if ( aClipRect.Left() < nScrX ) + BOOL bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW ); + if ( aAreaParam.maClipRect.Left() < nScrX ) { - aClipRect.Left() = nScrX; - bLeftClip = TRUE; + aAreaParam.maClipRect.Left() = nScrX; + aAreaParam.mbLeftClip = true; } - if ( aClipRect.Right() > nScrX + nScrW ) + if ( aAreaParam.maClipRect.Right() > nScrX + nScrW ) { - aClipRect.Right() = nScrX + nScrW; //! minus one? - bRightClip = TRUE; + aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one? + aAreaParam.mbRightClip = true; } if ( !bHidden && !bOutside ) { - BOOL bClip = bLeftClip || bRightClip; + bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip; BOOL bSimClip = FALSE; if ( bWrapFields ) @@ -2495,14 +2672,14 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) bClip = TRUE; } - if ( aClipRect.Top() < nScrY ) + if ( aAreaParam.maClipRect.Top() < nScrY ) { - aClipRect.Top() = nScrY; + aAreaParam.maClipRect.Top() = nScrY; bClip = TRUE; } - if ( aClipRect.Bottom() > nScrY + nScrH ) + if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH ) { - aClipRect.Bottom() = nScrY + nScrH; //! minus one? + aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one? bClip = TRUE; } @@ -2554,8 +2731,8 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) bAnyClipped = TRUE; long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX ); - if ( aClipRect.Right() - nMarkPixel > aClipRect.Left() ) - aClipRect.Right() -= nMarkPixel; + if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() ) + aAreaParam.maClipRect.Right() -= nMarkPixel; } } @@ -2579,9 +2756,9 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) // Clip marks are already handled in GetOutputArea if (bPixelToLogic) - aLogicClip = pRefDevice->PixelToLogic( aClipRect ); + aLogicClip = pRefDevice->PixelToLogic( aAreaParam.maClipRect ); else - aLogicClip = aClipRect; + aLogicClip = aAreaParam.maClipRect; if (bClip) // bei bSimClip nur aClipRect initialisieren { @@ -3215,10 +3392,7 @@ void ScOutputData::DrawRotated(BOOL bPixelToLogic) // use GetOutputArea to hide the grid // (clip region is done manually below) - BOOL bLeftClip = FALSE; - BOOL bRightClip = FALSE; - Rectangle aAlignRect; - Rectangle aClipRect; + OutputAreaParam aAreaParam; SCCOL nCellX = nX; SCROW nCellY = nY; @@ -3231,8 +3405,7 @@ void ScOutputData::DrawRotated(BOOL bPixelToLogic) GetOutputArea( nX, nArrY, nCellStartX, nPosY, nCellX, nCellY, nNeededWidth, *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), - FALSE, FALSE, TRUE, - aAlignRect, aClipRect, bLeftClip, bRightClip ); + FALSE, FALSE, TRUE, aAreaParam ); if ( bShrink ) { @@ -3240,19 +3413,19 @@ void ScOutputData::DrawRotated(BOOL bPixelToLogic) pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width() : nEngineWidth; long nNeededPixel = nPixelWidth + nLeftM + nRightM; - bLeftClip = bRightClip = TRUE; + aAreaParam.mbLeftClip = aAreaParam.mbRightClip = TRUE; // always do height - ShrinkEditEngine( *pEngine, aAlignRect, nLeftM, nTopM, nRightM, nBottomM, + ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM, FALSE, sal::static_int_cast<USHORT>(eOrient), nAttrRotate, bPixelToLogic, - nEngineWidth, nEngineHeight, nNeededPixel, bLeftClip, bRightClip ); + nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip ); if ( eRotMode == SVX_ROTATE_MODE_STANDARD ) { // do width only if rotating within the cell (standard mode) - ShrinkEditEngine( *pEngine, aAlignRect, nLeftM, nTopM, nRightM, nBottomM, + ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM, TRUE, sal::static_int_cast<USHORT>(eOrient), nAttrRotate, bPixelToLogic, - nEngineWidth, nEngineHeight, nNeededPixel, bLeftClip, bRightClip ); + nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip ); } // nEngineWidth/nEngineHeight is updated in ShrinkEditEngine @@ -3306,19 +3479,19 @@ void ScOutputData::DrawRotated(BOOL bPixelToLogic) } if (bPixelToLogic) - aClipRect = pRefDevice->PixelToLogic( Rectangle( + aAreaParam.maClipRect = pRefDevice->PixelToLogic( Rectangle( Point(nClipStartX,nClipStartY), aClipSize ) ); else - aClipRect = Rectangle(Point(nClipStartX, nClipStartY), + aAreaParam.maClipRect = Rectangle(Point(nClipStartX, nClipStartY), aClipSize ); // Scale = 1 if (bMetaFile) { pDev->Push(); - pDev->IntersectClipRegion( aClipRect ); + pDev->IntersectClipRegion( aAreaParam.maClipRect ); } else - pDev->SetClipRegion( Region( aClipRect ) ); + pDev->SetClipRegion( Region( aAreaParam.maClipRect ) ); } Point aLogicStart; diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 5fcd094acffc..11ecfa5aae8c 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -87,6 +87,13 @@ #include "docuno.hxx" #include "charthelper.hxx" +#include <basic/sbstar.hxx> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/script/XLibraryContainer.hpp> +using namespace com::sun::star; + +// helper func defined in docfunc.cxx +void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName ); // STATIC DATA --------------------------------------------------------------- @@ -2141,6 +2148,7 @@ BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord ) { ScDocShell* pDocSh = GetViewData()->GetDocShell(); ScDocument* pDoc = pDocSh->GetDocument(); + BOOL bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : FALSE; SCTAB nNewTab = TheTabs[0]; int i; WaitObject aWait( GetFrameWin() ); @@ -2212,9 +2220,18 @@ BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord ) for(i=TheTabs.Count()-1;i>=0;i--) { + String sCodeName; + BOOL bHasCodeName = pDoc->GetCodeName( TheTabs[sal::static_int_cast<USHORT>(i)], sCodeName ); if (pDoc->DeleteTab( TheTabs[sal::static_int_cast<USHORT>(i)], pUndoDoc )) { bDelDone = TRUE; + if( bVbaEnabled ) + { + if( bHasCodeName ) + { + VBA_DeleteModule( *pDocSh, sCodeName ); + } + } pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[sal::static_int_cast<USHORT>(i)] ) ); } } |