dd2384f
From 62deebf153661bfb92258b2d474bdfda958e8e29 Mon Sep 17 00:00:00 2001
dd2384f
From: David Tardon <dtardon@redhat.com>
dd2384f
Date: Fri, 12 Dec 2014 17:09:45 +0100
dd2384f
Subject: [PATCH] rhbz#1116534 crash when pasting over a formula
dd2384f
dd2384f
When pasting CSV data into existing document, we cannot use the
dd2384f
ScImportExport optimization for insertion, because the cells can already
dd2384f
have content (a grouped formula in this case). So use appropriate
dd2384f
ScDocument functions, even if that means the import is slower.
dd2384f
dd2384f
This is a regression from commit 93959db4d8846cfdfb87ab647c4d457fb09bb869
dd2384f
"use DocumentImport for csv import, related fdo#69006".
dd2384f
dd2384f
(cherry picked from commit bf97980c8d5d5fbc63a08b8834c10fe903152b75)
dd2384f
dd2384f
Conflicts:
dd2384f
	sc/source/ui/view/viewfun5.cxx
dd2384f
dd2384f
Change-Id: I92f70abca0542d796e3aa674b28a31053fff00d0
dd2384f
---
dd2384f
 sc/source/ui/docshell/impex.cxx | 69 ++++++++++++++++++++++++++++-------------
dd2384f
 sc/source/ui/inc/impex.hxx      |  4 +++
dd2384f
 sc/source/ui/view/viewfun5.cxx  |  6 ++--
dd2384f
 3 files changed, 54 insertions(+), 25 deletions(-)
dd2384f
dd2384f
diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx
dd2384f
index 9882966..feba39c 100644
dd2384f
--- a/sc/source/ui/docshell/impex.cxx
dd2384f
+++ b/sc/source/ui/docshell/impex.cxx
dd2384f
@@ -85,7 +85,8 @@ ScImportExport::ScImportExport( ScDocument* p )
dd2384f
       bFormulas( false ), bIncludeFiltered( true ),
dd2384f
       bAll( true ), bSingle( true ), bUndo( false ),
dd2384f
       bOverflowRow( false ), bOverflowCol( false ), bOverflowCell( false ),
dd2384f
-      mbApi( true ), mbImportBroadcast(false), mExportTextOptions()
dd2384f
+      mbApi( true ), mbImportBroadcast(false), mbOverwriting( false ),
dd2384f
+      mExportTextOptions()
dd2384f
 {
dd2384f
     pUndoDoc = NULL;
dd2384f
     pExtOptions = NULL;
dd2384f
@@ -99,7 +100,8 @@ ScImportExport::ScImportExport( ScDocument* p, const ScAddress& rPt )
dd2384f
       bFormulas( false ), bIncludeFiltered( true ),
dd2384f
       bAll( false ), bSingle( true ), bUndo( pDocSh != NULL ),
dd2384f
       bOverflowRow( false ), bOverflowCol( false ), bOverflowCell( false ),
dd2384f
-      mbApi( true ), mbImportBroadcast(false), mExportTextOptions()
dd2384f
+      mbApi( true ), mbImportBroadcast(false), mbOverwriting( false ),
dd2384f
+      mExportTextOptions()
dd2384f
 {
dd2384f
     pUndoDoc = NULL;
dd2384f
     pExtOptions = NULL;
dd2384f
@@ -114,7 +116,8 @@ ScImportExport::ScImportExport( ScDocument* p, const ScRange& r )
dd2384f
       bFormulas( false ), bIncludeFiltered( true ),
dd2384f
       bAll( false ), bSingle( false ), bUndo( pDocSh != NULL ),
dd2384f
       bOverflowRow( false ), bOverflowCol( false ), bOverflowCell( false ),
dd2384f
-      mbApi( true ), mbImportBroadcast(false), mExportTextOptions()
dd2384f
+      mbApi( true ), mbImportBroadcast(false), mbOverwriting( false ),
dd2384f
+      mExportTextOptions()
dd2384f
 {
dd2384f
     pUndoDoc = NULL;
dd2384f
     pExtOptions = NULL;
dd2384f
@@ -130,7 +133,8 @@ ScImportExport::ScImportExport( ScDocument* p, const OUString& rPos )
dd2384f
       bFormulas( false ), bIncludeFiltered( true ),
dd2384f
       bAll( false ), bSingle( true ), bUndo( pDocSh != NULL ),
dd2384f
       bOverflowRow( false ), bOverflowCol( false ), bOverflowCell( false ),
dd2384f
-      mbApi( true ), mbImportBroadcast(false), mExportTextOptions()
dd2384f
+      mbApi( true ), mbImportBroadcast(false), mbOverwriting( false ),
dd2384f
+      mExportTextOptions()
dd2384f
 {
dd2384f
     pUndoDoc = NULL;
dd2384f
     pExtOptions = NULL;
dd2384f
@@ -928,7 +932,8 @@ bool ScImportExport::Text2Doc( SvStream& rStrm )
dd2384f
 //  Extended Ascii-Import
dd2384f
 
dd2384f
 static bool lcl_PutString(
dd2384f
-    ScDocumentImport& rDocImport, SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rStr, sal_uInt8 nColFormat,
dd2384f
+    ScDocumentImport& rDocImport, bool bUseDocImport,
dd2384f
+    SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rStr, sal_uInt8 nColFormat,
dd2384f
     SvNumberFormatter* pFormatter, bool bDetectNumFormat,
dd2384f
     ::utl::TransliterationWrapper& rTransliteration, CalendarWrapper& rCalendar,
dd2384f
     ::utl::TransliterationWrapper* pSecondTransliteration, CalendarWrapper* pSecondCalendar )
dd2384f
@@ -952,17 +957,24 @@ static bool lcl_PutString(
dd2384f
             pDoc->ApplyPattern(nCol, nRow, nTab, aNewAttrs);
dd2384f
 
dd2384f
         }
dd2384f
-        if(ScStringUtil::isMultiline(rStr))
dd2384f
+        if ( bUseDocImport )
dd2384f
         {
dd2384f
-            ScFieldEditEngine& rEngine = pDoc->GetEditEngine();
dd2384f
-            rEngine.SetText(rStr);
dd2384f
-            rDocImport.setEditCell(ScAddress(nCol, nRow, nTab), rEngine.CreateTextObject());
dd2384f
-            return true;
dd2384f
-        }
dd2384f
-        else
dd2384f
+            if(ScStringUtil::isMultiline(rStr))
dd2384f
+            {
dd2384f
+                ScFieldEditEngine& rEngine = pDoc->GetEditEngine();
dd2384f
+                rEngine.SetText(rStr);
dd2384f
+                rDocImport.setEditCell(ScAddress(nCol, nRow, nTab), rEngine.CreateTextObject());
dd2384f
+                return true;
dd2384f
+            }
dd2384f
+            else
dd2384f
+            {
dd2384f
+                rDocImport.setStringCell(ScAddress(nCol, nRow, nTab), rStr);
dd2384f
+                return false;
dd2384f
+            }
dd2384f
+        } else
dd2384f
         {
dd2384f
-            rDocImport.setStringCell(ScAddress(nCol, nRow, nTab), rStr);
dd2384f
-            return false;
dd2384f
+            pDoc->SetTextCell(ScAddress(nCol, nRow, nTab), rStr);
dd2384f
+            return bMultiLine;
dd2384f
         }
dd2384f
     }
dd2384f
 
dd2384f
@@ -976,7 +988,10 @@ static bool lcl_PutString(
dd2384f
         if ( pDocFormatter->IsNumberFormat( rStr, nEnglish, fVal ) )
dd2384f
         {
dd2384f
             // Numberformat will not be set to English
dd2384f
-            rDocImport.setNumericCell( ScAddress( nCol, nRow, nTab ), fVal );
dd2384f
+            if ( bUseDocImport )
dd2384f
+                rDocImport.setNumericCell( ScAddress( nCol, nRow, nTab ), fVal );
dd2384f
+            else
dd2384f
+                pDoc->SetValue( nCol, nRow, nTab, fVal );
dd2384f
             return bMultiLine;
dd2384f
         }
dd2384f
         // else, continue with SetString
dd2384f
@@ -1165,7 +1180,10 @@ static bool lcl_PutString(
dd2384f
                         nFormat = pDocFormatter->GetStandardFormat( fDays, nFormat, nType, eDocLang);
dd2384f
 
dd2384f
                     ScAddress aPos(nCol,nRow,nTab);
dd2384f
-                    rDocImport.setNumericCell(aPos, fDays);
dd2384f
+                    if ( bUseDocImport )
dd2384f
+                        rDocImport.setNumericCell(aPos, fDays);
dd2384f
+                    else
dd2384f
+                        pDoc->SetValue( aPos, fDays );
dd2384f
                     pDoc->SetNumberFormat(aPos, nFormat);
dd2384f
 
dd2384f
                     return bMultiLine;     // success
dd2384f
@@ -1182,14 +1200,20 @@ static bool lcl_PutString(
dd2384f
         aParam.mbDetectNumberFormat = bDetectNumFormat;
dd2384f
         aParam.meSetTextNumFormat = ScSetStringParam::SpecialNumberOnly;
dd2384f
         aParam.mbHandleApostrophe = false;
dd2384f
-        rDocImport.setAutoInput(ScAddress(nCol, nRow, nTab), rStr, &aParam);
dd2384f
+        if ( bUseDocImport )
dd2384f
+            rDocImport.setAutoInput(ScAddress(nCol, nRow, nTab), rStr, &aParam);
dd2384f
+        else
dd2384f
+            pDoc->SetString( nCol, nRow, nTab, rStr, &aParam );
dd2384f
     }
dd2384f
     else
dd2384f
     {
dd2384f
         bMultiLine = true;
dd2384f
         ScFieldEditEngine& rEngine = pDoc->GetEditEngine();
dd2384f
         rEngine.SetText(rStr);
dd2384f
-        rDocImport.setEditCell(ScAddress(nCol, nRow, nTab), rEngine.CreateTextObject());
dd2384f
+        if ( bUseDocImport )
dd2384f
+            rDocImport.setEditCell(ScAddress(nCol, nRow, nTab), rEngine.CreateTextObject());
dd2384f
+        else
dd2384f
+            pDoc->SetEditText( ScAddress( nCol, nRow, nTab ), rEngine.CreateTextObject() );
dd2384f
     }
dd2384f
     return bMultiLine;
dd2384f
 }
dd2384f
@@ -1347,7 +1371,7 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )
dd2384f
                                 nFmt = SC_COL_TEXT;
dd2384f
 
dd2384f
                             bMultiLine |= lcl_PutString(
dd2384f
-                                aDocImport, nCol, nRow, nTab, aCell, nFmt,
dd2384f
+                                aDocImport, !mbOverwriting, nCol, nRow, nTab, aCell, nFmt,
dd2384f
                                 &aNumFormatter, bDetectNumFormat, aTransliteration, aCalendar,
dd2384f
                                 pEnglishTransliteration.get(), pEnglishCalendar.get());
dd2384f
                         }
dd2384f
@@ -1390,7 +1414,7 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )
dd2384f
                                 nFmt = SC_COL_TEXT;
dd2384f
 
dd2384f
                             bMultiLine |= lcl_PutString(
dd2384f
-                                aDocImport, nCol, nRow, nTab, aCell, nFmt,
dd2384f
+                                aDocImport, !mbOverwriting, nCol, nRow, nTab, aCell, nFmt,
dd2384f
                                 &aNumFormatter, bDetectNumFormat, aTransliteration,
dd2384f
                                 aCalendar, pEnglishTransliteration.get(), pEnglishCalendar.get());
dd2384f
                         }
dd2384f
@@ -1448,13 +1472,14 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )
dd2384f
 
dd2384f
         bDetermineRange = !bDetermineRange;     // toggle
dd2384f
     } while (!bDetermineRange);
dd2384f
-    aDocImport.finalize();
dd2384f
+    if ( !mbOverwriting )
dd2384f
+        aDocImport.finalize();
dd2384f
 
dd2384f
     xProgress.reset();    // make room for AdjustRowHeight progress
dd2384f
     if (bRangeIsDetermined)
dd2384f
         EndPaste(false);
dd2384f
 
dd2384f
-    if (mbImportBroadcast)
dd2384f
+    if (mbImportBroadcast && !mbOverwriting)
dd2384f
     {
dd2384f
         pDoc->BroadcastCells(aRange, SC_HINT_DATACHANGED);
dd2384f
         pDocSh->PostDataChanged();
dd2384f
diff --git a/sc/source/ui/inc/impex.hxx b/sc/source/ui/inc/impex.hxx
dd2384f
index 9faa1a6..0db2234 100644
dd2384f
--- a/sc/source/ui/inc/impex.hxx
dd2384f
+++ b/sc/source/ui/inc/impex.hxx
dd2384f
@@ -67,6 +67,9 @@ class ScImportExport
dd2384f
     bool        bOverflowCell;          // too much data for a cell
dd2384f
     bool        mbApi;
dd2384f
     bool        mbImportBroadcast; // whether or not to broadcast after data import.
dd2384f
+    bool        mbOverwriting;  // Whether we could be overwriting existing values (paste).
dd2384f
+                                // In this case we cannot use the insert optimization, but we
dd2384f
+                                // do not need to broadcast after the import.
dd2384f
     ScExportTextOptions mExportTextOptions;
dd2384f
 
dd2384f
     ScAsciiOptions* pExtOptions;        // extended options
dd2384f
@@ -155,6 +158,7 @@ public:
dd2384f
     bool IsApi() const { return mbApi; }
dd2384f
     void SetApi( bool bApi ) { mbApi = bApi; }
dd2384f
     void SetImportBroadcast( bool b ) { mbImportBroadcast = b; }
dd2384f
+    void SetOverwriting( const bool bOverwriting ) { mbOverwriting = bOverwriting; }
dd2384f
     const ScExportTextOptions& GetExportTextOptions() { return mExportTextOptions; }
dd2384f
     void SetExportTextOptions( const ScExportTextOptions& options ) { mExportTextOptions = options; }
dd2384f
 };
dd2384f
diff --git a/sc/source/ui/view/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx
dd2384f
index 9d39811..6803808 100644
dd2384f
--- a/sc/source/ui/view/viewfun5.cxx
dd2384f
+++ b/sc/source/ui/view/viewfun5.cxx
dd2384f
@@ -294,9 +294,9 @@ bool ScViewFunc::PasteDataFormat( sal_uLong nFormatId,
dd2384f
         }
dd2384f
         else
dd2384f
         {
dd2384f
-            ScAddress aCellPos( nPosX, nPosY, GetViewData()->GetTabNo() );
dd2384f
-            ScImportExport aObj( GetViewData()->GetDocument(), aCellPos );
dd2384f
-            aObj.SetImportBroadcast(true);
f403693
+            ScAddress aCellPos( nPosX, nPosY, GetViewData()->GetTabNo() );
f403693
+            ScImportExport aObj( GetViewData()->GetDocument(), aCellPos );
dd2384f
+            aObj.SetOverwriting( true );
dd2384f
 
dd2384f
             OUString aStr;
dd2384f
             SotStorageStreamRef xStream;
dd2384f
-- 
dd2384f
2.1.0
dd2384f