diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2009-06-15 10:46:14 +0000 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2009-06-15 10:46:14 +0000 |
commit | 7ba284b835c6969c651232f97082fe58c2f11c83 (patch) | |
tree | 53ec4dd7467f833a5839670ee97704c4538006fb /sc | |
parent | 0ad5ec8be0fc7edf6785a3831f1c67d060847a04 (diff) |
CWS-TOOLING: integrate CWS calc50
2009-05-28 12:32:46 +0200 nn r272399 : gcc warning
2009-05-28 10:56:48 +0200 nn r272382 : CWS-TOOLING: rebase CWS calc50 to trunk@272291 (milestone: DEV300:m49)
2009-05-27 14:24:52 +0200 nn r272343 : #i50825# DataPilotUpdate: prevent overwriting source data above the table
2009-05-26 18:29:21 +0200 nn r272316 : #i50019# allow borders for multiple cell ranges
2009-05-26 13:43:36 +0200 nn r272300 : #i101960# UpdateExternalRefLinks: set document modified
2009-05-25 18:01:23 +0200 nn r272267 : #i102056# copied from CWS calc311fixes
2009-05-20 12:24:22 +0200 nn r272114 : #i59672# ExecFilter/SC_AUTOFILTER_CUSTOM: select database range (patch from gaozm)
2009-05-15 18:24:44 +0200 nn r271961 : #i100544# correct ScTokenConversion::ConvertToTokenArray
2009-05-13 17:45:02 +0200 nn r271866 : #i101869# DeleteRange: before broadcasting, check if EndListening removed the note cells
2009-05-13 12:43:31 +0200 nn r271856 : #i101806# correct reference undo for inserting/deleting columns/rows across sheets
2009-05-11 18:44:46 +0200 nn r271783 : #i101725# don't copy hash_set with pointers from the other collection
2009-05-11 17:54:21 +0200 nn r271780 : #i101690# correct merge error in frmdlg integration
2009-05-07 15:28:55 +0200 nn r271674 : #i96940# check for negative count in fillAuto
2009-05-07 13:47:58 +0200 nn r271661 : #i101512# SetCompileForFAP is in formula::FormulaCompiler
2009-05-07 13:47:27 +0200 nn r271660 : #i101512# use SetCompileForFAP for CompileTokenArray
2009-05-05 18:47:03 +0200 nn r271551 : #i73074# RepeatDB: re-evaluate advanced filter source range
2009-05-05 18:23:21 +0200 nn r271546 : #i97857# use GetInputString for direct reference as validity range source
2009-05-05 17:38:23 +0200 nn r271538 : #i95834# better enable/disable handling of next/previous buttons (patch by cmc)
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/cell.hxx | 3 | ||||
-rw-r--r-- | sc/inc/compiler.hxx | 3 | ||||
-rw-r--r-- | sc/inc/document.hxx | 12 | ||||
-rw-r--r-- | sc/inc/dpobject.hxx | 3 | ||||
-rw-r--r-- | sc/inc/global.hxx | 1 | ||||
-rw-r--r-- | sc/inc/globstr.hrc | 1 | ||||
-rw-r--r-- | sc/source/core/data/cell2.cxx | 17 | ||||
-rw-r--r-- | sc/source/core/data/column.cxx | 5 | ||||
-rw-r--r-- | sc/source/core/data/column3.cxx | 47 | ||||
-rw-r--r-- | sc/source/core/data/documen8.cxx | 13 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 253 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 9 | ||||
-rw-r--r-- | sc/source/core/data/validat.cxx | 44 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 3 | ||||
-rw-r--r-- | sc/source/ui/docshell/dbdocfun.cxx | 21 | ||||
-rw-r--r-- | sc/source/ui/docshell/docfunc.cxx | 133 | ||||
-rw-r--r-- | sc/source/ui/src/globstr.src | 4 | ||||
-rw-r--r-- | sc/source/ui/unoobj/cellsuno.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/unoobj/tokenuno.cxx | 2 | ||||
-rw-r--r-- | sc/source/ui/view/dbfunc3.cxx | 6 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin.cxx | 7 | ||||
-rw-r--r-- | sc/source/ui/view/viewfunc.cxx | 132 |
22 files changed, 444 insertions, 279 deletions
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx index 2d4bba295547..431284537a13 100644 --- a/sc/inc/cell.hxx +++ b/sc/inc/cell.hxx @@ -393,7 +393,8 @@ public: void UpdateReference(UpdateRefMode eUpdateRefMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz, - ScDocument* pUndoDoc = NULL ); + ScDocument* pUndoDoc = NULL, + const ScAddress* pUndoCellPos = NULL ); void TransposeReference(); void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest, diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index c026e0cb5cf9..1c27041599ad 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -358,8 +358,7 @@ public: bool IsEnglishSymbol( const String& rName ); //! _either_ CompileForFAP _or_ AutoCorrection, _not_ both - void SetCompileForFAP( BOOL bVal ) - { bCompileForFAP = bVal; bIgnoreErrors = bVal; } + // #i101512# SetCompileForFAP is in formula::FormulaCompiler void SetAutoCorrection( BOOL bVal ) { bAutoCorrect = bVal; bIgnoreErrors = bVal; } void SetCloseBrackets( bool bVal ) { mbCloseBrackets = bVal; } diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 66f52fa5c2a8..246a60a4b9d9 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -889,22 +889,26 @@ public: BOOL InsertRow( SCCOL nStartCol, SCTAB nStartTab, SCCOL nEndCol, SCTAB nEndTab, - SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc = NULL ); + SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc = NULL, + const ScMarkData* pTabMark = NULL ); SC_DLLPUBLIC BOOL InsertRow( const ScRange& rRange, ScDocument* pRefUndoDoc = NULL ); void DeleteRow( SCCOL nStartCol, SCTAB nStartTab, SCCOL nEndCol, SCTAB nEndTab, SCROW nStartRow, SCSIZE nSize, - ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL ); + ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL, + const ScMarkData* pTabMark = NULL ); void DeleteRow( const ScRange& rRange, ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL ); BOOL InsertCol( SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab, - SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc = NULL ); + SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc = NULL, + const ScMarkData* pTabMark = NULL ); SC_DLLPUBLIC BOOL InsertCol( const ScRange& rRange, ScDocument* pRefUndoDoc = NULL ); void DeleteCol( SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab, SCCOL nStartCol, SCSIZE nSize, - ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL ); + ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL, + const ScMarkData* pTabMark = NULL ); void DeleteCol( const ScRange& rRange, ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL ); diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 5f3dfe9eb489..cffe735f287a 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -126,7 +126,8 @@ public: void InvalidateData(); void InvalidateSource(); - void Output(); + + void Output( const ScAddress& rPos ); ScRange GetNewOutputRange( BOOL& rOverflow ); const ScRange GetOutputRangeByType( sal_Int32 nType ); diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index 45df07deaf6c..76f5fd665033 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -238,6 +238,7 @@ const USHORT IDF_ATTRIB = IDF_HARDATTR | IDF_STYLES; const USHORT IDF_CONTENTS = IDF_VALUE | IDF_DATETIME | IDF_STRING | IDF_NOTE | IDF_FORMULA; const USHORT IDF_ALL = IDF_CONTENTS | IDF_ATTRIB | IDF_OBJECTS; const USHORT IDF_NOCAPTIONS = 0x0200; /// Internal use only (undo etc.): do not copy/delete caption objects of cell notes. +const USHORT IDF_ADDNOTES = 0x0400; /// Internal use only (copy from clip): do not delete existing cell contents when pasting notes. /// Copy flags for auto/series fill functions: do not touch notes and drawing objects. const USHORT IDF_AUTOFILL = IDF_ALL & ~(IDF_NOTE | IDF_OBJECTS); diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc index db35cb50969e..97d77dc06fc5 100644 --- a/sc/inc/globstr.hrc +++ b/sc/inc/globstr.hrc @@ -84,7 +84,6 @@ #define STR_MSSG_PASTEFROMCLIP_0 48 #define STR_MSSG_PASTEFROMCLIP_1 49 #define STR_MSSG_MOVEBLOCKTO_0 50 -#define STR_MSSG_APPLYPATTLINES_0 51 #define STR_MSSG_INSERTCELLS_0 52 #define STR_MSSG_DELETECELLS_0 53 #define STR_MSSG_MERGECELLS_0 54 diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx index 86c87c0445d8..7ef182660656 100644 --- a/sc/source/core/data/cell2.cxx +++ b/sc/source/core/data/cell2.cxx @@ -472,7 +472,7 @@ BOOL ScFormulaCell::HasColRowName() const void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz, - ScDocument* pUndoDoc ) + ScDocument* pUndoDoc, const ScAddress* pUndoCellPos ) { SCCOL nCol1 = r.aStart.Col(); SCROW nRow1 = r.aStart.Row(); @@ -484,6 +484,8 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode, SCROW nRow = aPos.Row(); SCTAB nTab = aPos.Tab(); ScAddress aUndoPos( aPos ); // position for undo cell in pUndoDoc + if ( pUndoCellPos ) + aUndoPos = *pUndoCellPos; ScAddress aOldPos( aPos ); // BOOL bPosChanged = FALSE; // ob diese Zelle bewegt wurde BOOL bIsInsert = FALSE; @@ -706,10 +708,15 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode, // (InsertCells/DeleteCells - aPos is changed above) as well as when UpdateReference // is called after moving the cells (MoveBlock/PasteFromClip - aOldPos is changed). - ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aUndoPos, - pOld, eTempGrammar, cMatrixFlag ); - pFCell->aResult.SetToken( NULL); // to recognize it as changed later (Cut/Paste!) - pUndoDoc->PutCell( aUndoPos, pFCell ); + // If there is already a formula cell in the undo document, don't overwrite it, + // the first (oldest) is the important cell. + if ( pUndoDoc->GetCellType( aUndoPos ) != CELLTYPE_FORMULA ) + { + ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aUndoPos, + pOld, eTempGrammar, cMatrixFlag ); + pFCell->aResult.SetToken( NULL); // to recognize it as changed later (Cut/Paste!) + pUndoDoc->PutCell( aUndoPos, pFCell ); + } } bValChanged = FALSE; if ( pRangeData ) diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 4c3c86c51971..7bb72225f16f 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -1673,7 +1673,10 @@ void ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW if( pCell->GetCellType() == CELLTYPE_FORMULA) { SCROW nRow = pItems[i].nRow; - ((ScFormulaCell*)pCell)->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc ); + // When deleting rows on several sheets, the formula's position may be updated with the first call, + // so the undo position must be passed from here. + ScAddress aUndoPos( nCol, nRow, nTab ); + ((ScFormulaCell*)pCell)->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc, &aUndoPos ); if ( nRow != pItems[i].nRow ) Search( nRow, i ); // Listener removed/inserted? } diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index bfb1890d70b0..65602f3d5bbc 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -521,6 +521,15 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, USHORT nDelFla for ( FormulaCellVector::iterator aIt = aDelCells.begin(), aEnd = aDelCells.end(); aIt != aEnd; ++aIt ) (*aIt)->EndListeningTo( pDocument ); + // #i101869# if the note cell with the broadcaster was deleted in EndListening, + // forget the pointer to the broadcaster + for ( FormulaCellVector::iterator aIt = aDelCells.begin(), aEnd = aDelCells.end(); aIt != aEnd; ++aIt ) + { + SCSIZE nIndex; + if ( !Search( (*aIt)->aPos.Row(), nIndex ) ) + (*aIt)->ReleaseBroadcaster(); + } + // broadcast SC_HINT_DYING for all cells and delete them for ( FormulaCellVector::iterator aIt = aDelCells.begin(), aEnd = aDelCells.end(); aIt != aEnd; ++aIt ) { @@ -739,6 +748,9 @@ void ScColumn::CopyFromClip(SCROW nRow1, SCROW nRow2, long nDy, Resize( nNew ); } + // IDF_ADDNOTES must be passed without other content flags than IDF_NOTE + bool bAddNotes = (nInsFlag & (IDF_CONTENTS | IDF_ADDNOTES)) == (IDF_NOTE | IDF_ADDNOTES); + BOOL bAtEnd = FALSE; for (SCSIZE i = 0; i < nColCount && !bAtEnd; i++) { @@ -751,12 +763,37 @@ void ScColumn::CopyFromClip(SCROW nRow1, SCROW nRow2, long nDy, // nDestRow may be negative then ScAddress aDestPos( nCol, (SCROW)nDestRow, nTab ); - ScBaseCell* pNew = bAsLink ? - rColumn.CreateRefCell( pDocument, aDestPos, i, nInsFlag ) : - rColumn.CloneCell( i, nInsFlag, *pDocument, aDestPos ); - if (pNew) - Insert((SCROW)nDestRow, pNew); + /* #i102056# Paste from clipboard needs to paste the cell notes in + a second pass. This must not overwrite the existing cells + already copied to the destination position in the first pass. + To indicate this special case, the modifier IDF_ADDNOTES is + passed together with IDF_NOTE in nInsFlag. Of course, there is + still the need to create a new cell, if there is no cell at the + destination position at all. */ + ScBaseCell* pAddNoteCell = bAddNotes ? GetCell( aDestPos.Row() ) : 0; + if (pAddNoteCell) + { + // do nothing if source cell does not contain a note + const ScBaseCell* pSourceCell = rColumn.pItems[i].pCell; + const ScPostIt* pSourceNote = pSourceCell ? pSourceCell->GetNote() : 0; + if (pSourceNote) + { + DBG_ASSERT( !pAddNoteCell->HasNote(), "ScColumn::CopyFromClip - unexpected note at destination cell" ); + bool bCloneCaption = (nInsFlag & IDF_NOCAPTIONS) == 0; + // #i52342# if caption is cloned, the note must be constructed with the destination document + ScPostIt* pNewNote = ScNoteUtil::CloneNote( *pDocument, aDestPos, *pSourceNote, bCloneCaption ); + pAddNoteCell->TakeNote( pNewNote ); + } + } + else + { + ScBaseCell* pNewCell = bAsLink ? + rColumn.CreateRefCell( pDocument, aDestPos, i, nInsFlag ) : + rColumn.CloneCell( i, nInsFlag, *pDocument, aDestPos ); + if (pNewCell) + Insert( aDestPos.Row(), pNewCell ); + } } } } diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx index 0d12c82dec87..c34e93f10d66 100644 --- a/sc/source/core/data/documen8.cxx +++ b/sc/source/core/data/documen8.cxx @@ -44,6 +44,7 @@ #include <svx/linkmgr.hxx> #include <svx/scripttypeitem.hxx> #include <svx/unolingu.hxx> +#include <sfx2/bindings.hxx> #include <sfx2/objsh.hxx> #include <sfx2/printer.hxx> #include <sfx2/viewfrm.hxx> @@ -1046,6 +1047,18 @@ void ScDocument::UpdateExternalRefLinks() TrackFormulas(); pShell->Broadcast( SfxSimpleHint(FID_DATACHANGED) ); ResetChanged( ScRange(0, 0, 0, MAXCOL, MAXROW, MAXTAB) ); + + // #i101960# set document modified, as in TrackTimeHdl for DDE links + if (!pShell->IsModified()) + { + pShell->SetModified( TRUE ); + SfxBindings* pBindings = GetViewBindings(); + if (pBindings) + { + pBindings->Invalidate( SID_SAVEDOC ); + pBindings->Invalidate( SID_DOC_MODIFIED ); + } + } } } diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index bdca03b861c1..0dd6a5db10e2 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -657,6 +657,43 @@ void ScDocument::LimitChartIfAll( ScRangeListRef& rRangeList ) } +void lcl_GetFirstTabRange( SCTAB& rTabRangeStart, SCTAB& rTabRangeEnd, const ScMarkData* pTabMark ) +{ + // without ScMarkData, leave start/end unchanged + if ( pTabMark ) + { + for (SCTAB nTab=0; nTab<=MAXTAB; ++nTab) + if (pTabMark->GetTableSelect(nTab)) + { + // find first range of consecutive selected sheets + rTabRangeStart = nTab; + while ( nTab+1 <= MAXTAB && pTabMark->GetTableSelect(nTab+1) ) + ++nTab; + rTabRangeEnd = nTab; + return; + } + } +} + +bool lcl_GetNextTabRange( SCTAB& rTabRangeStart, SCTAB& rTabRangeEnd, const ScMarkData* pTabMark ) +{ + if ( pTabMark ) + { + // find next range of consecutive selected sheets after rTabRangeEnd + for (SCTAB nTab=rTabRangeEnd+1; nTab<=MAXTAB; ++nTab) + if (pTabMark->GetTableSelect(nTab)) + { + rTabRangeStart = nTab; + while ( nTab+1 <= MAXTAB && pTabMark->GetTableSelect(nTab+1) ) + ++nTab; + rTabRangeEnd = nTab; + return true; + } + } + return false; +} + + BOOL ScDocument::CanInsertRow( const ScRange& rRange ) const { SCCOL nStartCol = rRange.aStart.Col(); @@ -681,39 +718,60 @@ BOOL ScDocument::CanInsertRow( const ScRange& rRange ) const BOOL ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab, SCCOL nEndCol, SCTAB nEndTab, - SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc ) + SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc, + const ScMarkData* pTabMark ) { SCTAB i; PutInOrder( nStartCol, nEndCol ); PutInOrder( nStartTab, nEndTab ); + if ( pTabMark ) + { + nStartTab = 0; + nEndTab = MAXTAB; + } BOOL bTest = TRUE; BOOL bRet = FALSE; BOOL bOldAutoCalc = GetAutoCalc(); SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden for ( i = nStartTab; i <= nEndTab && bTest; i++) - if (pTab[i]) + if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i))) bTest &= pTab[i]->TestInsertRow( nStartCol, nEndCol, nSize ); if (bTest) { // UpdateBroadcastAreas muss vor UpdateReference gerufen werden, damit nicht // Eintraege verschoben werden, die erst bei UpdateReference neu erzeugt werden - UpdateBroadcastAreas( URM_INSDEL, ScRange( - ScAddress( nStartCol, nStartRow, nStartTab ), - ScAddress( nEndCol, MAXROW, nEndTab )), 0, static_cast<SCsROW>(nSize), 0 ); - UpdateReference( URM_INSDEL, nStartCol, nStartRow, nStartTab, - nEndCol, MAXROW, nEndTab, - 0, static_cast<SCsROW>(nSize), 0, pRefUndoDoc, FALSE ); // without drawing objects + // handle chunks of consecutive selected sheets together + SCTAB nTabRangeStart = nStartTab; + SCTAB nTabRangeEnd = nEndTab; + lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ); + do + { + UpdateBroadcastAreas( URM_INSDEL, ScRange( + ScAddress( nStartCol, nStartRow, nTabRangeStart ), + ScAddress( nEndCol, MAXROW, nTabRangeEnd )), 0, static_cast<SCsROW>(nSize), 0 ); + } + while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) ); + + lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ); + do + { + UpdateReference( URM_INSDEL, nStartCol, nStartRow, nTabRangeStart, + nEndCol, MAXROW, nTabRangeEnd, + 0, static_cast<SCsROW>(nSize), 0, pRefUndoDoc, FALSE ); // without drawing objects + } + while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) ); + for (i=nStartTab; i<=nEndTab; i++) - if (pTab[i]) + if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i))) pTab[i]->InsertRow( nStartCol, nEndCol, nStartRow, nSize ); // #82991# UpdateRef for drawing layer must be after inserting, // when the new row heights are known. for (i=nStartTab; i<=nEndTab; i++) - if (pTab[i]) + if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i))) pTab[i]->UpdateDrawRef( URM_INSDEL, nStartCol, nStartRow, nStartTab, nEndCol, MAXROW, nEndTab, 0, static_cast<SCsROW>(nSize), 0 ); @@ -756,42 +814,61 @@ BOOL ScDocument::InsertRow( const ScRange& rRange, ScDocument* pRefUndoDoc ) void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab, SCCOL nEndCol, SCTAB nEndTab, SCROW nStartRow, SCSIZE nSize, - ScDocument* pRefUndoDoc, BOOL* pUndoOutline ) + ScDocument* pRefUndoDoc, BOOL* pUndoOutline, + const ScMarkData* pTabMark ) { SCTAB i; PutInOrder( nStartCol, nEndCol ); PutInOrder( nStartTab, nEndTab ); + if ( pTabMark ) + { + nStartTab = 0; + nEndTab = MAXTAB; + } BOOL bOldAutoCalc = GetAutoCalc(); SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden - if ( ValidRow(nStartRow+nSize) ) + // handle chunks of consecutive selected sheets together + SCTAB nTabRangeStart = nStartTab; + SCTAB nTabRangeEnd = nEndTab; + lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ); + do { - DelBroadcastAreasInRange( ScRange( - ScAddress( nStartCol, nStartRow, nStartTab ), - ScAddress( nEndCol, nStartRow+nSize-1, nEndTab ) ) ); - UpdateBroadcastAreas( URM_INSDEL, ScRange( - ScAddress( nStartCol, nStartRow+nSize, nStartTab ), - ScAddress( nEndCol, MAXROW, nEndTab )), 0, -(static_cast<SCsROW>(nSize)), 0 ); + if ( ValidRow(nStartRow+nSize) ) + { + DelBroadcastAreasInRange( ScRange( + ScAddress( nStartCol, nStartRow, nTabRangeStart ), + ScAddress( nEndCol, nStartRow+nSize-1, nTabRangeEnd ) ) ); + UpdateBroadcastAreas( URM_INSDEL, ScRange( + ScAddress( nStartCol, nStartRow+nSize, nTabRangeStart ), + ScAddress( nEndCol, MAXROW, nTabRangeEnd )), 0, -(static_cast<SCsROW>(nSize)), 0 ); + } + else + DelBroadcastAreasInRange( ScRange( + ScAddress( nStartCol, nStartRow, nTabRangeStart ), + ScAddress( nEndCol, MAXROW, nTabRangeEnd ) ) ); } - else - DelBroadcastAreasInRange( ScRange( - ScAddress( nStartCol, nStartRow, nStartTab ), - ScAddress( nEndCol, MAXROW, nEndTab ) ) ); + while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) ); if ( ValidRow(nStartRow+nSize) ) { - UpdateReference( URM_INSDEL, nStartCol, nStartRow+nSize, nStartTab, - nEndCol, MAXROW, nEndTab, - 0, -(static_cast<SCsROW>(nSize)), 0, pRefUndoDoc ); + lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ); + do + { + UpdateReference( URM_INSDEL, nStartCol, nStartRow+nSize, nTabRangeStart, + nEndCol, MAXROW, nTabRangeEnd, + 0, -(static_cast<SCsROW>(nSize)), 0, pRefUndoDoc ); + } + while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) ); } if (pUndoOutline) *pUndoOutline = FALSE; for ( i = nStartTab; i <= nEndTab; i++) - if (pTab[i]) + if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i))) pTab[i]->DeleteRow( nStartCol, nEndCol, nStartRow, nSize, pUndoOutline ); if ( ValidRow(nStartRow+nSize) ) @@ -844,30 +921,51 @@ BOOL ScDocument::CanInsertCol( const ScRange& rRange ) const BOOL ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab, - SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc ) + SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc, + const ScMarkData* pTabMark ) { SCTAB i; PutInOrder( nStartRow, nEndRow ); PutInOrder( nStartTab, nEndTab ); + if ( pTabMark ) + { + nStartTab = 0; + nEndTab = MAXTAB; + } BOOL bTest = TRUE; BOOL bRet = FALSE; BOOL bOldAutoCalc = GetAutoCalc(); SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden for ( i = nStartTab; i <= nEndTab && bTest; i++) - if (pTab[i]) + if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i))) bTest &= pTab[i]->TestInsertCol( nStartRow, nEndRow, nSize ); if (bTest) { - UpdateBroadcastAreas( URM_INSDEL, ScRange( - ScAddress( nStartCol, nStartRow, nStartTab ), - ScAddress( MAXCOL, nEndRow, nEndTab )), static_cast<SCsCOL>(nSize), 0, 0 ); - UpdateReference( URM_INSDEL, nStartCol, nStartRow, nStartTab, - MAXCOL, nEndRow, nEndTab, - static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc ); + // handle chunks of consecutive selected sheets together + SCTAB nTabRangeStart = nStartTab; + SCTAB nTabRangeEnd = nEndTab; + lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ); + do + { + UpdateBroadcastAreas( URM_INSDEL, ScRange( + ScAddress( nStartCol, nStartRow, nTabRangeStart ), + ScAddress( MAXCOL, nEndRow, nTabRangeEnd )), static_cast<SCsCOL>(nSize), 0, 0 ); + } + while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) ); + + lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ); + do + { + UpdateReference( URM_INSDEL, nStartCol, nStartRow, nTabRangeStart, + MAXCOL, nEndRow, nTabRangeEnd, + static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc ); + } + while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) ); + for (i=nStartTab; i<=nEndTab; i++) - if (pTab[i]) + if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i))) pTab[i]->InsertCol( nStartCol, nStartRow, nEndRow, nSize ); if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() ) @@ -907,42 +1005,60 @@ BOOL ScDocument::InsertCol( const ScRange& rRange, ScDocument* pRefUndoDoc ) void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab, SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc, - BOOL* pUndoOutline ) + BOOL* pUndoOutline, const ScMarkData* pTabMark ) { SCTAB i; PutInOrder( nStartRow, nEndRow ); PutInOrder( nStartTab, nEndTab ); + if ( pTabMark ) + { + nStartTab = 0; + nEndTab = MAXTAB; + } BOOL bOldAutoCalc = GetAutoCalc(); SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden - if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) ) + // handle chunks of consecutive selected sheets together + SCTAB nTabRangeStart = nStartTab; + SCTAB nTabRangeEnd = nEndTab; + lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ); + do { - DelBroadcastAreasInRange( ScRange( - ScAddress( nStartCol, nStartRow, nStartTab ), - ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize-1), nEndRow, nEndTab ) ) ); - UpdateBroadcastAreas( URM_INSDEL, ScRange( - ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nStartTab ), - ScAddress( MAXCOL, nEndRow, nEndTab )), -static_cast<SCsCOL>(nSize), 0, 0 ); + if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) ) + { + DelBroadcastAreasInRange( ScRange( + ScAddress( nStartCol, nStartRow, nTabRangeStart ), + ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize-1), nEndRow, nTabRangeEnd ) ) ); + UpdateBroadcastAreas( URM_INSDEL, ScRange( + ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart ), + ScAddress( MAXCOL, nEndRow, nTabRangeEnd )), -static_cast<SCsCOL>(nSize), 0, 0 ); + } + else + DelBroadcastAreasInRange( ScRange( + ScAddress( nStartCol, nStartRow, nTabRangeStart ), + ScAddress( MAXCOL, nEndRow, nTabRangeEnd ) ) ); } - else - DelBroadcastAreasInRange( ScRange( - ScAddress( nStartCol, nStartRow, nStartTab ), - ScAddress( MAXCOL, nEndRow, nEndTab ) ) ); + while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) ); if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) ) { - UpdateReference( URM_INSDEL, sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nStartTab, - MAXCOL, nEndRow, nEndTab, - -static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc ); + lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ); + do + { + UpdateReference( URM_INSDEL, sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart, + MAXCOL, nEndRow, nTabRangeEnd, + -static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc ); + } + while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) ); } if (pUndoOutline) *pUndoOutline = FALSE; for ( i = nStartTab; i <= nEndTab; i++) - if (pTab[i]) + if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i))) pTab[i]->DeleteCol( nStartCol, nStartRow, nEndRow, nSize, pUndoOutline ); if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) ) @@ -1781,9 +1897,17 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar nXw = sal::static_int_cast<SCCOL>( nXw + nDestAddX ); nYw = sal::static_int_cast<SCROW>( nYw + nDestAddY ); // ClipArea, plus ExtendMerge value - // Inhalte entweder komplett oder gar nicht loeschen: + /* Decide which contents to delete before copying. Delete all + contents if nInsFlag contains any real content flag. + #i102056# Notes are pasted from clipboard in a second pass, + together with the special flag IDF_ADDNOTES that states to not + overwrite/delete existing cells but to insert the notes into + these cells. In this case, just delete old notes from the + destination area. */ USHORT nDelFlag = IDF_NONE; - if ( nInsFlag & IDF_CONTENTS ) + if ( (nInsFlag & (IDF_CONTENTS | IDF_ADDNOTES)) == (IDF_NOTE | IDF_ADDNOTES) ) + nDelFlag |= IDF_NOTE; + else if ( nInsFlag & IDF_CONTENTS ) nDelFlag |= IDF_CONTENTS; // With bSkipAttrForEmpty, don't remove attributes, copy // on top of existing attributes instead. @@ -4030,16 +4154,21 @@ void ScDocument::ApplySelectionFrame( const ScMarkData& rMark, const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner ) { - if (rMark.IsMarked()) + ScRangeList aRangeList; + rMark.FillRangeListWithMarks( &aRangeList, FALSE ); + ULONG nRangeCount = aRangeList.Count(); + for (SCTAB i=0; i<=MAXTAB; i++) { - ScRange aRange; - rMark.GetMarkArea(aRange); - for (SCTAB i=0; i<=MAXTAB; i++) - if (pTab[i]) - if (rMark.GetTableSelect(i)) - pTab[i]->ApplyBlockFrame( pLineOuter, pLineInner, - aRange.aStart.Col(), aRange.aStart.Row(), - aRange.aEnd.Col(), aRange.aEnd.Row() ); + if (pTab[i] && rMark.GetTableSelect(i)) + { + for (ULONG j=0; j<nRangeCount; j++) + { + ScRange aRange = *aRangeList.GetObject(j); + pTab[i]->ApplyBlockFrame( pLineOuter, pLineInner, + aRange.aStart.Col(), aRange.aStart.Row(), + aRange.aEnd.Col(), aRange.aEnd.Row() ); + } + } } } diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 12af06a773ed..813a3381c901 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -466,7 +466,7 @@ ScRange ScDPObject::GetNewOutputRange( BOOL& rOverflow ) } } -void ScDPObject::Output() +void ScDPObject::Output( const ScAddress& rPos ) { // clear old output area pDoc->DeleteAreaTab( aOutRange.aStart.Col(), aOutRange.aStart.Row(), @@ -478,6 +478,8 @@ void ScDPObject::Output() CreateOutput(); // create xSource and pOutput if not already done + pOutput->SetPosition( rPos ); + pOutput->Output(); // aOutRange is always the range that was last output to the document @@ -2337,7 +2339,7 @@ ScDPCollection::ScDPCollection(const ScDPCollection& r) : ScCollection(r), pDoc(r.pDoc), maSharedString(r.maSharedString), - maCacheCellPool(r.maCacheCellPool) + maCacheCellPool() // #i101725# don't copy hash_set with pointers from the other collection { } @@ -2499,8 +2501,9 @@ void ScDPCollection::clearCacheCellPool() vector<ScDPCacheCell*> ps; ps.reserve(maCacheCellPool.size()); copy(maCacheCellPool.begin(), maCacheCellPool.end(), back_inserter(ps)); - for_each(ps.begin(), ps.end(), DeleteCacheCells()); maCacheCellPool.clear(); + // for correctness' sake, delete the elements after clearing the hash_set + for_each(ps.begin(), ps.end(), DeleteCacheCells()); } //------------------------------------------------------------------------ diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx index 09c1db07c464..0a33ab111f50 100644 --- a/sc/source/core/data/validat.cxx +++ b/sc/source/core/data/validat.cxx @@ -695,6 +695,40 @@ bool ScValidationData::GetSelectionFromFormula( TypedScStrCollection* pStrings, SCSIZE nCol, nRow, nCols, nRows, n = 0; pValues->GetDimensions( nCols, nRows ); + BOOL bRef = FALSE; + ScRange aRange; + + ScTokenArray* pArr = (ScTokenArray*) &rTokArr; + pArr->Reset(); + ScToken* t = NULL; + if (pArr->GetLen() == 1 && (t = static_cast<ScToken*>(pArr->GetNextReferenceOrName())) != NULL) + { + if (t->GetOpCode() == ocDBArea) + { + if( ScDBData* pDBData = pDocument->GetDBCollection()->FindIndex( t->GetIndex() ) ) + { + pDBData->GetArea(aRange); + bRef = TRUE; + } + } + else if (t->GetOpCode() == ocName) + { + ScRangeData* pName = pDocument->GetRangeName()->FindIndex( t->GetIndex() ); + if (pName && pName->IsReference(aRange)) + { + bRef = TRUE; + } + } + else if (t->GetType() != svIndex) + { + t->CalcAbsIfRel(rPos); + if (pArr->IsValidReference(aRange)) + { + bRef = TRUE; + } + } + } + /* XL artificially limits things to a single col or row in the UI but does * not list the constraint in MOOXml. If a defined name or INDIRECT * resulting in 1D is entered in the UI and the definition later modified @@ -735,7 +769,15 @@ bool ScValidationData::GetSelectionFromFormula( TypedScStrCollection* pStrings, { // FIXME FIXME FIXME // Feature regression. Date formats are lost passing through the matrix - pFormatter->GetInputLineString( pMatVal->fVal, 0, aValStr ); + //pFormatter->GetInputLineString( pMatVal->fVal, 0, aValStr ); + //For external reference and a formula that results in an area or array, date formats are still lost. + if ( bRef ) + { + pDocument->GetInputString((SCCOL)(nCol+aRange.aStart.Col()), + (SCROW)(nRow+aRange.aStart.Row()), aRange.aStart.Tab() , aValStr); + } + else + pFormatter->GetInputLineString( pMatVal->fVal, 0, aValStr ); } if( pCell && rMatch < 0 ) diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index e8a1dd90a403..0f03d31d3fc8 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -1821,8 +1821,11 @@ void ScTokenArray::ReadjustRelative3DReferences( const ScAddress& rOldPos, case svSingleRef : { ScSingleRefData& rRef1 = static_cast<ScToken*>(pCode[j])->GetSingleRef(); + if ( rRef1.IsFlag3D() ) + { rRef1.CalcAbsIfRel( rOldPos ); rRef1.CalcRelFromAbs( rNewPos ); + } } break; default: diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 1e85f3c01f3e..33caccaed815 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -58,6 +58,7 @@ #include "editable.hxx" #include "attrib.hxx" #include "drwlayer.hxx" +#include "dpshttab.hxx" // ----------------------------------------------------------------- @@ -1299,6 +1300,22 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb BOOL bOverflow = FALSE; ScRange aNewOut = pDestObj->GetNewOutputRange( bOverflow ); + + //! test for overlap with other data pilot tables + if( pOldObj ) + { + const ScSheetSourceDesc* pSheetDesc = pOldObj->GetSheetDesc(); + if( pSheetDesc && pSheetDesc->aSourceRange.Intersects( aNewOut ) ) + { + ScRange aOldRange = pOldObj->GetOutRange(); + SCsROW nDiff = aOldRange.aStart.Row()-aNewOut.aStart.Row(); + aNewOut.aStart.SetRow( aOldRange.aStart.Row() ); + aNewOut.aEnd.SetRow( aNewOut.aEnd.Row()+nDiff ); + if( !ValidRow( aNewOut.aStart.Row() ) || !ValidRow( aNewOut.aEnd.Row() ) ) + bOverflow = TRUE; + } + } + if ( bOverflow ) { // like with STR_PROTECTIONERR, use undo to reverse everything @@ -1354,9 +1371,7 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb pDoc->CopyToDocument( aNewOut, IDF_ALL, FALSE, pNewUndoDoc ); } - //! test for overlap with other data pilot tables - - pDestObj->Output(); + pDestObj->Output( aNewOut.aStart ); rDocShell.PostPaintGridAll(); //! only necessary parts bDone = TRUE; diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 0383d6758767..84b2330a533b 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -1340,6 +1340,14 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark, } } + ScMarkData aFullMark( aMark ); // including scenario sheets + for( i=0; i<nTabCount; i++ ) + if( aMark.GetTableSelect( i ) ) + { + for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ ) + aFullMark.SelectTable( j, TRUE ); + } + SCTAB nSelCount = aMark.GetSelectCount(); // zugehoerige Szenarien auch anpassen @@ -1543,66 +1551,22 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark, switch (eCmd) { case INS_CELLSDOWN: - bSuccess = TRUE; - for( i=0; i<nTabCount; i++ ) - { - if( aMark.GetTableSelect( i ) ) - { - SCTAB nScenarioCount = 0; - for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ ) - nScenarioCount ++; - - bSuccess &= pDoc->InsertRow( nStartCol, i, nEndCol, i+nScenarioCount, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc ); - } - } + bSuccess = pDoc->InsertRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark ); nPaintEndY = MAXROW; break; case INS_INSROWS: - bSuccess = TRUE; - for( i=0; i<nTabCount; i++ ) - { - if( aMark.GetTableSelect( i ) ) - { - SCTAB nScenarioCount = 0; - for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ ) - nScenarioCount ++; - - bSuccess &= pDoc->InsertRow( 0, i, MAXCOL, i+nScenarioCount, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc ); - } - } + bSuccess = pDoc->InsertRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark ); nPaintStartX = 0; nPaintEndX = MAXCOL; nPaintEndY = MAXROW; nPaintFlags |= PAINT_LEFT; break; case INS_CELLSRIGHT: - bSuccess = TRUE; - for( i=0; i<nTabCount; i++ ) - { - if( aMark.GetTableSelect( i ) ) - { - SCTAB nScenarioCount = 0; - for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ ) - nScenarioCount ++; - - bSuccess &= pDoc->InsertCol( nStartRow, i, nEndRow, i+nScenarioCount, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc ); - } - } + bSuccess = pDoc->InsertCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark ); nPaintEndX = MAXCOL; break; case INS_INSCOLS: - bSuccess = TRUE; - for( i=0; i<nTabCount; i++ ) - { - if( aMark.GetTableSelect( i ) ) - { - SCTAB nScenarioCount = 0; - for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ ) - nScenarioCount ++; - - bSuccess &= pDoc->InsertCol( 0, i, MAXROW, i+nScenarioCount, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc ); - } - } + bSuccess = pDoc->InsertCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark ); nPaintStartY = 0; nPaintEndY = MAXROW; nPaintEndX = MAXCOL; @@ -1795,6 +1759,14 @@ BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark, } } + ScMarkData aFullMark( aMark ); // including scenario sheets + for( i=0; i<nTabCount; i++ ) + if( aMark.GetTableSelect( i ) ) + { + for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ ) + aFullMark.SelectTable( j, TRUE ); + } + SCTAB nSelCount = aMark.GetSelectCount(); SCCOL nUndoStartX = nStartCol; @@ -2035,66 +2007,22 @@ BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark, switch (eCmd) { case DEL_CELLSUP: - for( i=0; i<nTabCount; i++ ) - { - if( aMark.GetTableSelect( i ) ) - { - SCTAB nScenarioCount = 0; - - for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ ) - nScenarioCount ++; - - pDoc->DeleteRow( nStartCol, i, nEndCol, i+nScenarioCount, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc ); - } - } + pDoc->DeleteRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, NULL, &aFullMark ); nPaintEndY = MAXROW; break; case DEL_DELROWS: - for( i=0; i<nTabCount; i++ ) - { - if( aMark.GetTableSelect( i ) ) - { - SCTAB nScenarioCount = 0; - - for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ ) - nScenarioCount ++; - - pDoc->DeleteRow( 0, i, MAXCOL, i+nScenarioCount, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &bUndoOutline ); - } - } + pDoc->DeleteRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &bUndoOutline, &aFullMark ); nPaintStartX = 0; nPaintEndX = MAXCOL; nPaintEndY = MAXROW; nPaintFlags |= PAINT_LEFT; break; case DEL_CELLSLEFT: - for( i=0; i<nTabCount; i++ ) - { - if( aMark.GetTableSelect( i ) ) - { - SCTAB nScenarioCount = 0; - - for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ ) - nScenarioCount ++; - - pDoc->DeleteCol( nStartRow, i, nEndRow, i+nScenarioCount, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc ); - } - } + pDoc->DeleteCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, NULL, &aFullMark ); nPaintEndX = MAXCOL; break; case DEL_DELCOLS: - for( i=0; i<nTabCount; i++ ) - { - if( aMark.GetTableSelect( i ) ) - { - SCTAB nScenarioCount = 0; - - for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ ) - nScenarioCount ++; - - pDoc->DeleteCol( 0, i, MAXROW, i+nScenarioCount, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &bUndoOutline ); - } - } + pDoc->DeleteCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &bUndoOutline, &aFullMark ); nPaintStartY = 0; nPaintEndY = MAXROW; nPaintEndX = MAXCOL; @@ -2109,8 +2037,9 @@ BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark, if ( bRecord ) { - for ( i=nStartTab; i<=nTabCount; i++) - pRefUndoDoc->DeleteAreaTab(nUndoStartX,nUndoStartY,nUndoEndX,nUndoEndY, i, IDF_ALL); + for( i=0; i<nTabCount; i++ ) + if( aFullMark.GetTableSelect( i ) ) + pRefUndoDoc->DeleteAreaTab(nUndoStartX,nUndoStartY,nUndoEndX,nUndoEndY, i, IDF_ALL); // alle Tabellen anlegen, damit Formeln kopiert werden koennen: pUndoDoc->AddUndoTab( 0, nTabCount-1, FALSE, FALSE ); @@ -2492,9 +2421,13 @@ BOOL ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos, /* Paste cell notes and drawing objects after adjusting formula references and row heights. There are no cell notes or drawing objects, if the - clipdoc does not contain a drawing layer. */ + clipdoc does not contain a drawing layer. + #i102056# Passing IDF_NOTE only would overwrite cell contents with + empty note cells, therefore the special modifier IDF_ADDNOTES is passed + here too which changes the behaviour of ScColumn::CopyFromClip() to not + touch existing cells. */ if ( pClipDoc->GetDrawLayer() ) - pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_NOTE | IDF_OBJECTS, + pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_NOTE | IDF_ADDNOTES | IDF_OBJECTS, pRefUndoDoc, pClipDoc, TRUE, FALSE, bIncludeFiltered ); if (bRecord) diff --git a/sc/source/ui/src/globstr.src b/sc/source/ui/src/globstr.src index 5166340b189e..c5b8cfd1a9e8 100644 --- a/sc/source/ui/src/globstr.src +++ b/sc/source/ui/src/globstr.src @@ -438,10 +438,6 @@ Resource RID_GLOBSTR { Text [ en-US ] = "Cell merge not possible if cells already merged!" ; }; - String STR_MSSG_APPLYPATTLINES_0 - { - Text [ en-US ] = "Cannot apply borders to multiple selection" ; - }; String STR_MSSG_INSERTCELLS_0 { Text [ en-US ] = "Inserting into merged ranges not possible" ; diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index c73f56dc55a4..7bdb9c7718d2 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -5439,7 +5439,7 @@ void SAL_CALL ScCellRangeObj::fillAuto( sheet::FillDirection nFillDirection, if ( pDocSh && nSourceCount ) { ScRange aSourceRange(aRange); - SCCOLROW nCount = 0; // "Dest-Count" + SCsCOLROW nCount = 0; // "Dest-Count" FillDir eDir = FILL_TO_BOTTOM; BOOL bError = FALSE; switch (nFillDirection) @@ -5467,7 +5467,7 @@ void SAL_CALL ScCellRangeObj::fillAuto( sheet::FillDirection nFillDirection, default: bError = TRUE; } - if (nCount > MAXROW) // Ueberlauf + if (nCount < 0 || nCount > MAXROW) // overflow bError = TRUE; if (!bError) diff --git a/sc/source/ui/unoobj/tokenuno.cxx b/sc/source/ui/unoobj/tokenuno.cxx index dfb0f42702a8..c543b5880fe7 100644 --- a/sc/source/ui/unoobj/tokenuno.cxx +++ b/sc/source/ui/unoobj/tokenuno.cxx @@ -345,7 +345,7 @@ void lcl_SingleRefToApi( sheet::SingleReference& rAPI, const ScSingleRefData& rR bool ScTokenConversion::ConvertToTokenArray( ScDocument& rDoc, ScTokenArray& rTokenArray, const uno::Sequence<sheet::FormulaToken>& rSequence ) { - return rTokenArray.Fill(rSequence,rDoc.GetExternalRefManager()); + return !rTokenArray.Fill(rSequence,rDoc.GetExternalRefManager()); } // static diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 8dcb47c927a2..36667ee43c0f 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -1898,7 +1898,13 @@ void ScDBFunc::RepeatDB( BOOL bRecord ) pDBData->GetQueryParam( aQueryParam ); // Bereich kann sich geaendert haben ScRange aAdvSource; if (pDBData->GetAdvancedQuerySource(aAdvSource)) + { + pDoc->CreateQueryParam( + aAdvSource.aStart.Col(), aAdvSource.aStart.Row(), + aAdvSource.aEnd.Col(), aAdvSource.aEnd.Row(), + aAdvSource.aStart.Tab(), aQueryParam ); Query( aQueryParam, &aAdvSource, FALSE ); + } else Query( aQueryParam, NULL, FALSE ); diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 5591a2a496be..dda608037012 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -1139,6 +1139,13 @@ void ScGridWindow::ExecFilter( ULONG nSel, if (SC_AUTOFILTER_CUSTOM == nSel) { + SCTAB nAreaTab; + SCCOL nStartCol; + SCROW nStartRow; + SCCOL nEndCol; + SCROW nEndRow; + pDBData->GetArea( nAreaTab, nStartCol,nStartRow,nEndCol,nEndRow ); + pViewData->GetView()->MarkRange( ScRange( nStartCol,nStartRow,nAreaTab,nEndCol,nEndRow,nAreaTab)); pViewData->GetView()->SetCursor(nCol,nRow); //! auch ueber Slot ?? pViewData->GetDispatcher().Execute( SID_FILTER, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD ); } diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index 9df9dc5f5246..015c5fd2c083 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -1179,103 +1179,69 @@ void ScViewFunc::ApplyPatternLines( const ScPatternAttr& rAttr, const SvxBoxItem const SvxBoxInfoItem* pNewInner, BOOL bRecord ) { ScDocument* pDoc = GetViewData()->GetDocument(); - ScMarkData& rMark = GetViewData()->GetMarkData(); + ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered + ScViewUtil::UnmarkFiltered( aFuncMark, pDoc ); if (bRecord && !pDoc->IsUndoEnabled()) bRecord = FALSE; - SCCOL nStartCol; - SCROW nStartRow; - SCTAB nStartTab; - SCCOL nEndCol; - SCROW nEndRow; - SCTAB nEndTab; - - ScMarkType eMarkType = GetViewData()->GetSimpleArea( nStartCol, nStartRow, - nStartTab, nEndCol, nEndRow, nEndTab); - if (eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED) + ScRange aMarkRange; + aFuncMark.MarkToSimple(); + BOOL bMulti = aFuncMark.IsMultiMarked(); + if (bMulti) + aFuncMark.GetMultiMarkArea( aMarkRange ); + else if (aFuncMark.IsMarked()) + aFuncMark.GetMarkArea( aMarkRange ); + else { - bool bChangeSelection = false; - ScRange aMarkRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ); - if ( eMarkType == SC_MARK_SIMPLE_FILTERED ) - { - ScMarkData aVisibleMark( rMark ); - ScViewUtil::UnmarkFiltered( aVisibleMark, pDoc ); - ScRangeList aRangeList; - aVisibleMark.FillRangeListWithMarks( &aRangeList, FALSE ); - if ( aRangeList.Count() > 0 ) - { - // use the first range of visible cells - // (might also show an error message instead, or, later, allow multiple ranges) - - aMarkRange = *aRangeList.GetObject(0); - } - else // all hidden -> cursor position - { - aMarkRange.aStart.SetCol(GetViewData()->GetCurX()); - aMarkRange.aStart.SetRow(GetViewData()->GetCurY()); - aMarkRange.aStart.SetTab(GetViewData()->GetTabNo()); - aMarkRange.aEnd = aMarkRange.aStart; - } - aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ); - bChangeSelection = true; // change the selection to only the affected cells - } - - rMark.MarkToSimple(); // not done by GetSimpleArea anymore + aMarkRange = ScRange( GetViewData()->GetCurX(), + GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); + DoneBlockMode(); + InitOwnBlockMode(); + aFuncMark.SetMarkArea(aMarkRange); + MarkDataChanged(); + } - ScDocShell* pDocSh = GetViewData()->GetDocShell(); + ScDocShell* pDocSh = GetViewData()->GetDocShell(); - ScDocShellModificator aModificator( *pDocSh ); + ScDocShellModificator aModificator( *pDocSh ); - if (!rMark.IsMarked() || bChangeSelection) - { - DoneBlockMode(); - InitOwnBlockMode(); - rMark.SetMarkArea( ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ) ); - MarkDataChanged(); - } + if (bRecord) + { + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + SCTAB nStartTab = aMarkRange.aStart.Tab(); + SCTAB nTabCount = pDoc->GetTableCount(); + pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab ); + for (SCTAB i=0; i<nTabCount; i++) + if (i != nStartTab && aFuncMark.GetTableSelect(i)) + pUndoDoc->AddUndoTab( i, i ); - if (bRecord) - { - SCTAB nTabCount = pDoc->GetTableCount(); - ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); - pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab ); - for (SCTAB i=0; i<nTabCount; i++) - if (i != nStartTab && rMark.GetTableSelect(i)) - pUndoDoc->AddUndoTab( i, i ); - pDoc->CopyToDocument( nStartCol, nStartRow, 0, nEndCol, nEndRow, nTabCount-1, - IDF_ATTRIB, FALSE, pUndoDoc ); + ScRange aCopyRange = aMarkRange; + aCopyRange.aStart.SetTab(0); + aCopyRange.aEnd.SetTab(nTabCount-1); + pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pUndoDoc, &aFuncMark ); - pDocSh->GetUndoManager()->AddUndoAction( - new ScUndoSelectionAttr( pDocSh, rMark, - nStartCol, nStartRow, nStartTab, - nEndCol, nEndRow, nEndTab, - pUndoDoc, FALSE, &rAttr, pNewOuter, pNewInner ) ); - } + pDocSh->GetUndoManager()->AddUndoAction( + new ScUndoSelectionAttr( + pDocSh, aFuncMark, + aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), aMarkRange.aStart.Tab(), + aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), aMarkRange.aEnd.Tab(), + pUndoDoc, bMulti, &rAttr, pNewOuter, pNewInner ) ); + } - USHORT nExt = SC_PF_TESTMERGE; - pDocSh->UpdatePaintExt( nExt, nStartCol, nStartRow, nStartTab, - nEndCol, nEndRow, nEndTab ); // content before the change + USHORT nExt = SC_PF_TESTMERGE; + pDocSh->UpdatePaintExt( nExt, aMarkRange ); // content before the change - pDoc->ApplySelectionFrame( rMark, pNewOuter, pNewInner ); + pDoc->ApplySelectionFrame( aFuncMark, pNewOuter, pNewInner ); - pDocSh->UpdatePaintExt( nExt, nStartCol, nStartRow, nStartTab, - nEndCol, nEndRow, nEndTab ); // content after the change + pDocSh->UpdatePaintExt( nExt, aMarkRange ); // content after the change - rMark.MarkToMulti(); - pDoc->ApplySelectionPattern( rAttr, rMark ); + aFuncMark.MarkToMulti(); + pDoc->ApplySelectionPattern( rAttr, aFuncMark ); - pDocSh->PostPaint( nStartCol, nStartRow, nStartTab, - nEndCol, nEndRow, nEndTab, - PAINT_GRID, nExt ); - pDocSh->UpdateOle(GetViewData()); - aModificator.SetDocumentModified(); - CellContentChanged(); - rMark.MarkToSimple(); - } - else - { // "Rahmen nicht auf Mehrfachselektion" - ErrorMessage(STR_MSSG_APPLYPATTLINES_0); - } + pDocSh->PostPaint( aMarkRange, PAINT_GRID, nExt ); + pDocSh->UpdateOle(GetViewData()); + aModificator.SetDocumentModified(); + CellContentChanged(); StartFormatArea(); } |