xref: /AOO41X/main/sc/source/ui/docshell/dbdocimp.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8) !
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 
28 
29 // INCLUDE ---------------------------------------------------------
30 
31 #include <comphelper/processfactory.hxx>
32 #include <comphelper/types.hxx>
33 #include <vcl/msgbox.hxx>
34 #include <tools/debug.hxx>
35 #include <svx/dataaccessdescriptor.hxx>
36 #include <sfx2/viewfrm.hxx>
37 
38 #include <com/sun/star/sdb/CommandType.hpp>
39 #include <com/sun/star/sdb/XCompletedExecution.hpp>
40 #include <com/sun/star/sdbc/XRow.hpp>
41 #include <com/sun/star/sdbc/XRowSet.hpp>
42 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
43 #include <com/sun/star/sdbcx/XRowLocate.hpp>
44 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <com/sun/star/frame/XDispatchProvider.hpp>
47 #include <com/sun/star/frame/FrameSearchFlag.hpp>
48 #include <com/sun/star/view/XSelectionSupplier.hpp>
49 
50 
51 #include "dbdocfun.hxx"
52 #include "docsh.hxx"
53 #include "globstr.hrc"
54 #include "scerrors.hxx"
55 #include "dbcolect.hxx"
56 #include "markdata.hxx"
57 #include "undodat.hxx"
58 #include "progress.hxx"
59 #include "patattr.hxx"
60 #include "docpool.hxx"
61 #include "attrib.hxx"
62 #include "dbdocutl.hxx"
63 #include "editable.hxx"
64 #include "hints.hxx"
65 #include "miscuno.hxx"
66 
67 using namespace com::sun::star;
68 
69 #define SC_SERVICE_ROWSET           "com.sun.star.sdb.RowSet"
70 #define SC_SERVICE_INTHANDLER       "com.sun.star.task.InteractionHandler"
71 
72 //! move to a header file?
73 #define SC_DBPROP_DATASOURCENAME    "DataSourceName"
74 #define SC_DBPROP_COMMAND           "Command"
75 #define SC_DBPROP_COMMANDTYPE       "CommandType"
76 #define SC_DBPROP_SELECTION         "Selection"
77 #define SC_DBPROP_CURSOR            "Cursor"
78 
79 // static
ShowInBeamer(const ScImportParam & rParam,SfxViewFrame * pFrame)80 void ScDBDocFunc::ShowInBeamer( const ScImportParam& rParam, SfxViewFrame* pFrame )
81 {
82     //  called after opening the database beamer
83 
84     if ( !pFrame || !rParam.bImport )
85         return;
86 
87     uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame().GetFrameInterface();
88     uno::Reference<frame::XDispatchProvider> xDP(xFrame, uno::UNO_QUERY);
89 
90     uno::Reference<frame::XFrame> xBeamerFrame = xFrame->findFrame(
91                                         rtl::OUString::createFromAscii("_beamer"),
92                                         frame::FrameSearchFlag::CHILDREN);
93     if (xBeamerFrame.is())
94     {
95         uno::Reference<frame::XController> xController = xBeamerFrame->getController();
96         uno::Reference<view::XSelectionSupplier> xControllerSelection(xController, uno::UNO_QUERY);
97         if (xControllerSelection.is())
98         {
99             sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
100                         ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
101                                                         sdb::CommandType::TABLE );
102 
103             ::svx::ODataAccessDescriptor aSelection;
104             aSelection.setDataSource(rtl::OUString( rParam.aDBName ));
105             aSelection[svx::daCommand]      <<= rtl::OUString( rParam.aStatement );
106             aSelection[svx::daCommandType]  <<= nType;
107 
108             xControllerSelection->select(uno::makeAny(aSelection.createPropertyValueSequence()));
109         }
110         else
111         {
112             DBG_ERROR("no selection supplier in the beamer!");
113         }
114     }
115 }
116 
117 // -----------------------------------------------------------------
118 
DoImportUno(const ScAddress & rPos,const uno::Sequence<beans::PropertyValue> & aArgs)119 sal_Bool ScDBDocFunc::DoImportUno( const ScAddress& rPos,
120                                 const uno::Sequence<beans::PropertyValue>& aArgs )
121 {
122     svx::ODataAccessDescriptor aDesc( aArgs );      // includes selection and result set
123 
124     //  create database range
125     ScDBData* pDBData = rDocShell.GetDBData( ScRange(rPos), SC_DB_IMPORT, SC_DBSEL_KEEP );
126     DBG_ASSERT(pDBData, "can't create DB data");
127     String sTarget = pDBData->GetName();
128 
129     UpdateImport( sTarget, aDesc );
130 
131     return sal_True;
132 }
133 
134 // -----------------------------------------------------------------
135 
DoImport(SCTAB nTab,const ScImportParam & rParam,const svx::ODataAccessDescriptor * pDescriptor,sal_Bool bRecord,sal_Bool bAddrInsert)136 sal_Bool ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam,
137         const svx::ODataAccessDescriptor* pDescriptor, sal_Bool bRecord, sal_Bool bAddrInsert )
138 {
139     ScDocument* pDoc = rDocShell.GetDocument();
140 
141     if (bRecord && !pDoc->IsUndoEnabled())
142         bRecord = sal_False;
143 
144     ScDBData* pDBData = 0;
145     if ( !bAddrInsert )
146     {
147         pDBData = pDoc->GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1,
148                                             rParam.nCol2, rParam.nRow2 );
149         if (!pDBData)
150         {
151             DBG_ERROR( "DoImport: no DBData" );
152             return sal_False;
153         }
154     }
155 
156     Window* pWaitWin = rDocShell.GetActiveDialogParent();
157     if (pWaitWin)
158         pWaitWin->EnterWait();
159     ScDocShellModificator aModificator( rDocShell );
160 
161     sal_Bool bSuccess = sal_False;
162     sal_Bool bApi = sal_False;                      //! pass as argument
163     sal_Bool bTruncated = sal_False;                // for warning
164     sal_uInt16 nErrStringId = 0;
165     String aErrorMessage;
166 
167     SCCOL nCol = rParam.nCol1;
168     SCROW nRow = rParam.nRow1;
169     SCCOL nEndCol = nCol;                   // end of resulting database area
170     SCROW nEndRow = nRow;
171     long i;
172 
173     sal_Bool bDoSelection = sal_False;
174     sal_Bool bRealSelection = sal_False;            // sal_True if not everything is selected
175     sal_Bool bBookmarkSelection = sal_False;
176     sal_Int32 nListPos = 0;
177     sal_Int32 nRowsRead = 0;
178     sal_Int32 nListCount = 0;
179 
180     uno::Sequence<uno::Any> aSelection;
181     if ( pDescriptor && pDescriptor->has(svx::daSelection) )
182     {
183         (*pDescriptor)[svx::daSelection] >>= aSelection;
184         nListCount = aSelection.getLength();
185         if ( nListCount > 0 )
186         {
187             bDoSelection = sal_True;
188             if ( pDescriptor->has(svx::daBookmarkSelection) )
189                 bBookmarkSelection = ScUnoHelpFunctions::GetBoolFromAny( (*pDescriptor)[svx::daBookmarkSelection] );
190             if ( bBookmarkSelection )
191             {
192                 // From bookmarks, there's no way to detect if all records are selected.
193                 // Rely on base to pass no selection in that case.
194                 bRealSelection = sal_True;
195             }
196         }
197     }
198 
199     uno::Reference<sdbc::XResultSet> xResultSet;
200     if ( pDescriptor && pDescriptor->has(svx::daCursor) )
201         xResultSet.set((*pDescriptor)[svx::daCursor], uno::UNO_QUERY);
202 
203     // ImportDoc - also used for Redo
204     ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO );
205     pImportDoc->InitUndo( pDoc, nTab, nTab );
206     ScColumn::bDoubleAlloc = sal_True;
207 
208     //
209     //  get data from database into import document
210     //
211 
212     try
213     {
214         //  progress bar
215         //  only text (title is still needed, for the cancel button)
216         ScProgress aProgress( &rDocShell, ScGlobal::GetRscString(STR_UNDO_IMPORTDATA), 0 );
217         sal_uInt16 nInserted = 0;
218 
219         uno::Reference<sdbc::XRowSet> xRowSet = uno::Reference<sdbc::XRowSet>(
220                 xResultSet, uno::UNO_QUERY );
221         sal_Bool bDispose = sal_False;
222         if ( !xRowSet.is() )
223         {
224             bDispose = sal_True;
225             xRowSet = uno::Reference<sdbc::XRowSet>(
226                     comphelper::getProcessServiceFactory()->createInstance(
227                         rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
228                     uno::UNO_QUERY);
229             uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
230             DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
231             if ( xRowProp.is() )
232             {
233                 //
234                 //  set source parameters
235                 //
236 
237                 sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
238                             ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
239                                                             sdb::CommandType::TABLE );
240                 uno::Any aAny;
241 
242                 aAny <<= rtl::OUString( rParam.aDBName );
243                 xRowProp->setPropertyValue(
244                             rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny );
245 
246                 aAny <<= rtl::OUString( rParam.aStatement );
247                 xRowProp->setPropertyValue(
248                             rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );
249 
250                 aAny <<= nType;
251                 xRowProp->setPropertyValue(
252                             rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );
253 
254                 uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY );
255                 if ( xExecute.is() )
256                 {
257                     uno::Reference<task::XInteractionHandler> xHandler(
258                             comphelper::getProcessServiceFactory()->createInstance(
259                                 rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ),
260                             uno::UNO_QUERY);
261                     xExecute->executeWithCompletion( xHandler );
262                 }
263                 else
264                     xRowSet->execute();
265             }
266         }
267         if ( xRowSet.is() )
268         {
269             //
270             //  get column descriptions
271             //
272 
273             long nColCount = 0;
274             uno::Reference<sdbc::XResultSetMetaData> xMeta;
275             uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY );
276             if ( xMetaSupp.is() )
277                 xMeta = xMetaSupp->getMetaData();
278             if ( xMeta.is() )
279                 nColCount = xMeta->getColumnCount();    // this is the number of real columns
280 
281             if ( rParam.nCol1 + nColCount - 1 > MAXCOL )
282             {
283                 nColCount = 0;
284                 //! error message
285             }
286 
287             uno::Reference<sdbcx::XRowLocate> xLocate;
288             if ( bBookmarkSelection )
289             {
290                 xLocate.set( xRowSet, uno::UNO_QUERY );
291                 if ( !xLocate.is() )
292                 {
293                     DBG_ERRORFILE("can't get XRowLocate");
294                     bDoSelection = bRealSelection = bBookmarkSelection = sal_False;
295                 }
296             }
297 
298             uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY );
299             if ( nColCount > 0 && xRow.is() )
300             {
301                 nEndCol = (SCCOL)( rParam.nCol1 + nColCount - 1 );
302 
303                 uno::Sequence<sal_Int32> aColTypes( nColCount );    // column types
304                 uno::Sequence<sal_Bool> aColCurr( nColCount );      // currency flag is not in types
305                 sal_Int32* pTypeArr = aColTypes.getArray();
306                 sal_Bool* pCurrArr = aColCurr.getArray();
307                 for (i=0; i<nColCount; i++)
308                 {
309                     pTypeArr[i] = xMeta->getColumnType( i+1 );
310                     pCurrArr[i] = xMeta->isCurrency( i+1 );
311                 }
312 
313                 if ( !bAddrInsert )                 // read column names
314                 {
315                     nCol = rParam.nCol1;
316                     for (i=0; i<nColCount; i++)
317                     {
318                         pImportDoc->SetString( nCol, nRow, nTab,
319                                                 xMeta->getColumnLabel( i+1 ) );
320                         ++nCol;
321                     }
322                     ++nRow;
323                 }
324 
325                 sal_Bool bEnd = sal_False;
326                 if ( !bDoSelection )
327                     xRowSet->beforeFirst();
328                 while ( !bEnd )
329                 {
330                     //  skip rows that are not selected
331                     if ( !bDoSelection )
332                     {
333                         if ( (bEnd = !xRowSet->next()) == sal_False )
334                             ++nRowsRead;
335                     }
336                     else
337                     {
338                         if (nListPos < nListCount)
339                         {
340                             if ( bBookmarkSelection )
341                             {
342                                 bEnd = !xLocate->moveToBookmark(aSelection[nListPos]);
343                             }
344                             else    // use record numbers
345                             {
346                                 sal_Int32 nNextRow = 0;
347                                 aSelection[nListPos] >>= nNextRow;
348                                 if ( nRowsRead+1 < nNextRow )
349                                     bRealSelection = sal_True;
350                                 bEnd = !xRowSet->absolute(nRowsRead = nNextRow);
351                             }
352                             ++nListPos;
353                         }
354                         else
355                         {
356                             if ( !bBookmarkSelection && xRowSet->next() )
357                                 bRealSelection = sal_True;                      // more data available but not used
358                             bEnd = sal_True;
359                         }
360                     }
361 
362                     if ( !bEnd )
363                     {
364                         if ( ValidRow(nRow) )
365                         {
366                             nCol = rParam.nCol1;
367                             for (i=0; i<nColCount; i++)
368                             {
369                                 ScDatabaseDocUtil::PutData( pImportDoc, nCol, nRow, nTab,
370                                                 xRow, i+1, pTypeArr[i], pCurrArr[i] );
371                                 ++nCol;
372                             }
373                             nEndRow = nRow;
374                             ++nRow;
375 
376                             //  progress bar
377 
378                             ++nInserted;
379                             if (!(nInserted & 15))
380                             {
381                                 String aPict = ScGlobal::GetRscString( STR_PROGRESS_IMPORT );
382                                 String aText = aPict.GetToken(0,'#');
383                                 aText += String::CreateFromInt32( nInserted );
384                                 aText += aPict.GetToken(1,'#');
385 
386                                 if (!aProgress.SetStateText( 0, aText ))    // stopped by user?
387                                 {
388                                     bEnd = sal_True;
389                                     bSuccess = sal_False;
390                                     nErrStringId = STR_DATABASE_ABORTED;
391                                 }
392                             }
393                         }
394                         else        // past the end of the spreadsheet
395                         {
396                             bEnd = sal_True;            // don't continue
397                             bTruncated = sal_True;      // warning flag
398                         }
399                     }
400                 }
401 
402                 bSuccess = sal_True;
403             }
404 
405             if ( bDispose )
406                 ::comphelper::disposeComponent( xRowSet );
407         }
408     }
409     catch ( sdbc::SQLException& rError )
410     {
411         aErrorMessage = rError.Message;
412     }
413     catch ( uno::Exception& )
414     {
415         DBG_ERROR("Unexpected exception in database");
416     }
417 
418     ScColumn::bDoubleAlloc = sal_False;
419     pImportDoc->DoColResize( nTab, rParam.nCol1,nEndCol, 0 );
420 
421     //
422     //  test for cell protection
423     //
424 
425     sal_Bool bKeepFormat = !bAddrInsert && pDBData->IsKeepFmt();
426     sal_Bool bMoveCells = !bAddrInsert && pDBData->IsDoSize();
427     SCCOL nFormulaCols = 0; // columns to be filled with formulas
428     if (bMoveCells && nEndCol == rParam.nCol2)
429     {
430         //  if column count changes, formulas would become invalid anyway
431         //  -> only set nFormulaCols for unchanged column count
432 
433         SCCOL nTestCol = rParam.nCol2 + 1;      // right of the data
434         SCROW nTestRow = rParam.nRow1 + 1;      // below the title row
435         while ( nTestCol <= MAXCOL &&
436                 pDoc->GetCellType(ScAddress( nTestCol, nTestRow, nTab )) == CELLTYPE_FORMULA )
437             ++nTestCol, ++nFormulaCols;
438     }
439 
440     if (bSuccess)
441     {
442         //  old and new range editable?
443         ScEditableTester aTester;
444         aTester.TestBlock( pDoc, nTab, rParam.nCol1,rParam.nRow1,rParam.nCol2,rParam.nRow2 );
445         aTester.TestBlock( pDoc, nTab, rParam.nCol1,rParam.nRow1,nEndCol,nEndRow );
446         if ( !aTester.IsEditable() )
447         {
448             nErrStringId = aTester.GetMessageId();
449             bSuccess = sal_False;
450         }
451         else if ( pDoc->GetChangeTrack() != NULL )
452         {
453             nErrStringId = STR_PROTECTIONERR;
454             bSuccess = sal_False;
455         }
456     }
457 
458     if ( bSuccess && bMoveCells )
459     {
460         ScRange aOld( rParam.nCol1, rParam.nRow1, nTab,
461                         rParam.nCol2+nFormulaCols, rParam.nRow2, nTab );
462         ScRange aNew( rParam.nCol1, rParam.nRow1, nTab,
463                         nEndCol+nFormulaCols, nEndRow, nTab );
464         if (!pDoc->CanFitBlock( aOld, aNew ))
465         {
466             nErrStringId = STR_MSSG_DOSUBTOTALS_2;      // can't insert cells
467             bSuccess = sal_False;
468         }
469     }
470 
471     //
472     //  copy data from import doc into real document
473     //
474 
475     if ( bSuccess )
476     {
477         if (bKeepFormat)
478         {
479             //  keep formatting of title and first data row from the document
480             //  CopyToDocument also copies styles, Apply... needs separate calls
481 
482             SCCOL nMinEndCol = Min( rParam.nCol2, nEndCol );    // not too much
483             nMinEndCol = sal::static_int_cast<SCCOL>( nMinEndCol + nFormulaCols );  // only if column count unchanged
484             pImportDoc->DeleteAreaTab( 0,0, MAXCOL,MAXROW, nTab, IDF_ATTRIB );
485             pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab,
486                                     nMinEndCol, rParam.nRow1, nTab,
487                                     IDF_ATTRIB, sal_False, pImportDoc );
488 
489             SCROW nDataStartRow = rParam.nRow1+1;
490             for (SCCOL nCopyCol=rParam.nCol1; nCopyCol<=nMinEndCol; nCopyCol++)
491             {
492                 const ScPatternAttr* pSrcPattern = pDoc->GetPattern(
493                                                     nCopyCol, nDataStartRow, nTab );
494                 pImportDoc->ApplyPatternAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow,
495                                                     nTab, *pSrcPattern );
496                 const ScStyleSheet* pStyle = pSrcPattern->GetStyleSheet();
497                 if (pStyle)
498                     pImportDoc->ApplyStyleAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow,
499                                                     nTab, *pStyle );
500             }
501         }
502 
503         //  don't set cell protection attribute if table is protected
504         if (pDoc->IsTabProtected(nTab))
505         {
506             ScPatternAttr aPattern(pImportDoc->GetPool());
507             aPattern.GetItemSet().Put( ScProtectionAttr( sal_False,sal_False,sal_False,sal_False ) );
508             pImportDoc->ApplyPatternAreaTab( 0,0,MAXCOL,MAXROW, nTab, aPattern );
509         }
510 
511         //
512         //  copy old data for undo
513         //
514 
515         SCCOL nUndoEndCol = Max( nEndCol, rParam.nCol2 );       // rParam = old end
516         SCROW nUndoEndRow = Max( nEndRow, rParam.nRow2 );
517 
518         ScDocument* pUndoDoc = NULL;
519         ScDBData* pUndoDBData = NULL;
520         if ( bRecord )
521         {
522             pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
523             pUndoDoc->InitUndo( pDoc, nTab, nTab );
524 
525             if ( !bAddrInsert )
526                 pUndoDBData = new ScDBData( *pDBData );
527         }
528 
529         ScMarkData aNewMark;
530         aNewMark.SelectOneTable( nTab );
531 
532         if (bRecord)
533         {
534             // do not touch notes (ScUndoImportData does not support drawing undo)
535             sal_uInt16 nCopyFlags = IDF_ALL & ~IDF_NOTE;
536 
537             //  nFormulaCols is set only if column count is unchanged
538             pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab,
539                                     nEndCol+nFormulaCols, nEndRow, nTab,
540                                     nCopyFlags, sal_False, pUndoDoc );
541             if ( rParam.nCol2 > nEndCol )
542                 pDoc->CopyToDocument( nEndCol+1, rParam.nRow1, nTab,
543                                         nUndoEndCol, nUndoEndRow, nTab,
544                                         nCopyFlags, sal_False, pUndoDoc );
545             if ( rParam.nRow2 > nEndRow )
546                 pDoc->CopyToDocument( rParam.nCol1, nEndRow+1, nTab,
547                                         nUndoEndCol+nFormulaCols, nUndoEndRow, nTab,
548                                         nCopyFlags, sal_False, pUndoDoc );
549         }
550 
551         //
552         //  move new data
553         //
554 
555         if (bMoveCells)
556         {
557             //  clear only the range without the formulas,
558             //  so the formula title and first row are preserved
559 
560             ScRange aDelRange( rParam.nCol1, rParam.nRow1, nTab,
561                                 rParam.nCol2, rParam.nRow2, nTab );
562             pDoc->DeleteAreaTab( aDelRange, IDF_ALL & ~IDF_NOTE );  // ohne die Formeln
563 
564             ScRange aOld( rParam.nCol1, rParam.nRow1, nTab,
565                             rParam.nCol2+nFormulaCols, rParam.nRow2, nTab );
566             ScRange aNew( rParam.nCol1, rParam.nRow1, nTab,
567                             nEndCol+nFormulaCols, nEndRow, nTab );
568             pDoc->FitBlock( aOld, aNew, sal_False );        // Formeln nicht loeschen
569         }
570         else if ( nEndCol < rParam.nCol2 )      // DeleteArea calls PutInOrder
571             pDoc->DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2,
572                                 aNewMark, IDF_CONTENTS & ~IDF_NOTE );
573 
574         //  CopyToDocument doesn't remove contents
575         pDoc->DeleteAreaTab( rParam.nCol1, rParam.nRow1, nEndCol, nEndRow, nTab, IDF_CONTENTS & ~IDF_NOTE );
576 
577         //  #41216# remove each column from ImportDoc after copying to reduce memory usage
578         sal_Bool bOldAutoCalc = pDoc->GetAutoCalc();
579         pDoc->SetAutoCalc( sal_False );             // outside of the loop
580         for (SCCOL nCopyCol = rParam.nCol1; nCopyCol <= nEndCol; nCopyCol++)
581         {
582             pImportDoc->CopyToDocument( nCopyCol, rParam.nRow1, nTab, nCopyCol, nEndRow, nTab,
583                                         IDF_ALL, sal_False, pDoc );
584             pImportDoc->DeleteAreaTab( nCopyCol, rParam.nRow1, nCopyCol, nEndRow, nTab, IDF_CONTENTS );
585             pImportDoc->DoColResize( nTab, nCopyCol, nCopyCol, 0 );
586         }
587         pDoc->SetAutoCalc( bOldAutoCalc );
588 
589         if (nFormulaCols > 0)               // copy formulas
590         {
591             if (bKeepFormat)            // formats for formulas
592                 pImportDoc->CopyToDocument( nEndCol+1, rParam.nRow1, nTab,
593                                             nEndCol+nFormulaCols, nEndRow, nTab,
594                                             IDF_ATTRIB, sal_False, pDoc );
595             // fill formulas
596             ScMarkData aMark;
597             aMark.SelectOneTable(nTab);
598             pDoc->Fill( nEndCol+1, rParam.nRow1+1, nEndCol+nFormulaCols, rParam.nRow1+1,
599                             aMark, nEndRow-rParam.nRow1-1, FILL_TO_BOTTOM, FILL_SIMPLE );
600         }
601 
602         //  if new range is smaller, clear old contents
603 
604         if (!bMoveCells)        // move has happened above
605         {
606             if ( rParam.nCol2 > nEndCol )
607                 pDoc->DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2,
608                                     aNewMark, IDF_CONTENTS );
609             if ( rParam.nRow2 > nEndRow )
610                 pDoc->DeleteArea( rParam.nCol1, nEndRow+1, rParam.nCol2, rParam.nRow2,
611                                     aNewMark, IDF_CONTENTS );
612         }
613 
614         if( !bAddrInsert )      // update database range
615         {
616             pDBData->SetImportParam( rParam );
617             pDBData->SetHeader( sal_True );
618             pDBData->SetByRow( sal_True );
619             pDBData->SetArea( nTab, rParam.nCol1,rParam.nRow1, nEndCol,nEndRow );
620             pDBData->SetImportSelection( bRealSelection );
621             pDoc->CompileDBFormula();
622         }
623 
624         if (bRecord)
625         {
626             ScDocument* pRedoDoc = pImportDoc;
627             pImportDoc = NULL;
628 
629             if (nFormulaCols > 0)                   // include filled formulas for redo
630                 pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab,
631                                         nEndCol+nFormulaCols, nEndRow, nTab,
632                                         IDF_ALL & ~IDF_NOTE, sal_False, pRedoDoc );
633 
634             ScDBData* pRedoDBData = pDBData ? new ScDBData( *pDBData ) : NULL;
635 
636             rDocShell.GetUndoManager()->AddUndoAction(
637                 new ScUndoImportData( &rDocShell, nTab,
638                                         rParam, nUndoEndCol, nUndoEndRow,
639                                         nFormulaCols,
640                                         pUndoDoc, pRedoDoc, pUndoDBData, pRedoDBData ) );
641         }
642 
643         pDoc->SetDirty();
644         rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
645         aModificator.SetDocumentModified();
646 
647         ScDBRangeRefreshedHint aHint( rParam );
648         pDoc->BroadcastUno( aHint );
649 
650         if (pWaitWin)
651             pWaitWin->LeaveWait();
652 
653         if ( bTruncated && !bApi )          // show warning
654             ErrorHandler::HandleError(SCWARN_IMPORT_RANGE_OVERFLOW);
655     }
656     else if ( !bApi )
657     {
658         if (pWaitWin)
659             pWaitWin->LeaveWait();
660 
661         if (!aErrorMessage.Len())
662         {
663             if (!nErrStringId)
664                 nErrStringId = STR_MSSG_IMPORTDATA_0;
665             aErrorMessage = ScGlobal::GetRscString( nErrStringId );
666         }
667         InfoBox aInfoBox( rDocShell.GetActiveDialogParent(), aErrorMessage );
668         aInfoBox.Execute();
669     }
670 
671     delete pImportDoc;
672 
673     return bSuccess;
674 }
675 
676 
677 
678 
679