Update ooo320-m1
[ooovba.git] / sc / source / ui / docshell / dbdocimp.cxx
blob112e35b2ab6ab8d3f15959e784e034b3815baf8e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dbdocimp.cxx,v $
10 * $Revision: 1.24 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------
38 #include <comphelper/processfactory.hxx>
39 #include <comphelper/types.hxx>
40 #include <vcl/msgbox.hxx>
41 #include <tools/debug.hxx>
42 #include <svx/dataaccessdescriptor.hxx>
43 #include <sfx2/viewfrm.hxx>
45 #include <com/sun/star/sdb/CommandType.hpp>
46 #include <com/sun/star/sdb/XCompletedExecution.hpp>
47 #include <com/sun/star/sdbc/XRow.hpp>
48 #include <com/sun/star/sdbc/XRowSet.hpp>
49 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
50 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
51 #include <com/sun/star/beans/XPropertySet.hpp>
52 #include <com/sun/star/frame/XDispatchProvider.hpp>
53 #include <com/sun/star/frame/FrameSearchFlag.hpp>
54 #include <com/sun/star/view/XSelectionSupplier.hpp>
57 #include "dbdocfun.hxx"
58 #include "docsh.hxx"
59 #include "globstr.hrc"
60 #include "scerrors.hxx"
61 #include "dbcolect.hxx"
62 #include "markdata.hxx"
63 #include "undodat.hxx"
64 #include "progress.hxx"
65 #include "patattr.hxx"
66 #include "docpool.hxx"
67 #include "attrib.hxx"
68 #include "dbdocutl.hxx"
69 #include "editable.hxx"
70 #include "hints.hxx"
71 #include "chgtrack.hxx"
73 using namespace com::sun::star;
75 #define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet"
76 #define SC_SERVICE_INTHANDLER "com.sun.star.sdb.InteractionHandler"
78 //! move to a header file?
79 #define SC_DBPROP_DATASOURCENAME "DataSourceName"
80 #define SC_DBPROP_COMMAND "Command"
81 #define SC_DBPROP_COMMANDTYPE "CommandType"
82 #define SC_DBPROP_SELECTION "Selection"
83 #define SC_DBPROP_CURSOR "Cursor"
85 // static
86 void ScDBDocFunc::ShowInBeamer( const ScImportParam& rParam, SfxViewFrame* pFrame )
88 // called after opening the database beamer
90 if ( !pFrame || !rParam.bImport )
91 return;
93 uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame()->GetFrameInterface();
94 uno::Reference<frame::XDispatchProvider> xDP(xFrame, uno::UNO_QUERY);
96 uno::Reference<frame::XFrame> xBeamerFrame = xFrame->findFrame(
97 rtl::OUString::createFromAscii("_beamer"),
98 frame::FrameSearchFlag::CHILDREN);
99 if (xBeamerFrame.is())
101 uno::Reference<frame::XController> xController = xBeamerFrame->getController();
102 uno::Reference<view::XSelectionSupplier> xControllerSelection(xController, uno::UNO_QUERY);
103 if (xControllerSelection.is())
105 sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
106 ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
107 sdb::CommandType::TABLE );
109 ::svx::ODataAccessDescriptor aSelection;
110 aSelection.setDataSource(rtl::OUString( rParam.aDBName ));
111 aSelection[svx::daCommand] <<= rtl::OUString( rParam.aStatement );
112 aSelection[svx::daCommandType] <<= nType;
114 xControllerSelection->select(uno::makeAny(aSelection.createPropertyValueSequence()));
116 else
118 DBG_ERROR("no selection supplier in the beamer!");
123 // -----------------------------------------------------------------
125 BOOL ScDBDocFunc::DoImportUno( const ScAddress& rPos,
126 const uno::Sequence<beans::PropertyValue>& aArgs )
128 BOOL bDone = FALSE;
130 ScImportParam aImParam;
131 aImParam.nCol1 = aImParam.nCol2 = rPos.Col();
132 aImParam.nRow1 = aImParam.nRow2 = rPos.Row();
133 aImParam.bImport = TRUE;
135 uno::Reference<sdbc::XResultSet> xResSet;
136 uno::Sequence<uno::Any> aSelection;
138 rtl::OUString aStrVal;
139 const beans::PropertyValue* pPropArray = aArgs.getConstArray();
140 long nPropCount = aArgs.getLength();
141 long i;
142 for (i = 0; i < nPropCount; i++)
144 const beans::PropertyValue& rProp = pPropArray[i];
145 String aPropName = rProp.Name;
147 if ( aPropName.EqualsAscii( SC_DBPROP_DATASOURCENAME ))
149 if ( rProp.Value >>= aStrVal )
150 aImParam.aDBName = aStrVal;
152 else if ( aPropName.EqualsAscii( SC_DBPROP_COMMAND ))
154 if ( rProp.Value >>= aStrVal )
155 aImParam.aStatement = aStrVal;
157 else if ( aPropName.EqualsAscii( SC_DBPROP_COMMANDTYPE ))
159 sal_Int32 nType = 0;
160 if ( rProp.Value >>= nType )
162 aImParam.bSql = ( nType == sdb::CommandType::COMMAND );
163 aImParam.nType = sal::static_int_cast<BYTE>( ( nType == sdb::CommandType::QUERY ) ? ScDbQuery : ScDbTable );
164 // nType is ignored if bSql is set
167 else if ( aPropName.EqualsAscii( SC_DBPROP_SELECTION ))
169 rProp.Value >>= aSelection;
171 else if ( aPropName.EqualsAscii( SC_DBPROP_CURSOR ))
173 rProp.Value >>= xResSet;
177 SbaSelectionList aList;
178 long nSelLen = aSelection.getLength();
179 for (i = 0; i < nSelLen; i++)
181 sal_Int32 nEntry = 0;
182 if ( aSelection[i] >>= nEntry )
183 aList.Insert( (void*)nEntry, LIST_APPEND );
186 BOOL bAddrInsert = FALSE; //!???
187 if ( bAddrInsert )
189 bDone = DoImport( rPos.Tab(), aImParam, xResSet, &aList, TRUE, bAddrInsert );
191 else
193 // create database range
194 //! merge this with SID_SBA_IMPORT execute in docsh4.cxx
196 ScDBData* pDBData = rDocShell.GetDBData( ScRange(rPos), SC_DB_IMPORT, FALSE );
197 DBG_ASSERT(pDBData, "can't create DB data");
198 String sTarget = pDBData->GetName();
200 //! change UpdateImport to use only one of rTableName, rStatement
202 String aTableName, aStatement;
203 if ( aImParam.bSql )
204 aStatement = aImParam.aStatement;
205 else
206 aTableName = aImParam.aStatement;
208 UpdateImport( sTarget, aImParam.aDBName, aTableName, aStatement,
209 aImParam.bNative, aImParam.nType, xResSet, &aList );
210 bDone = TRUE;
213 return bDone;
216 // -----------------------------------------------------------------
218 BOOL ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam,
219 const uno::Reference< sdbc::XResultSet >& xResultSet,
220 const SbaSelectionList* pSelection, BOOL bRecord, BOOL bAddrInsert )
222 ScDocument* pDoc = rDocShell.GetDocument();
223 ScChangeTrack *pChangeTrack = NULL;
224 ScRange aChangedRange;
226 if (bRecord && !pDoc->IsUndoEnabled())
227 bRecord = FALSE;
229 ScDBData* pDBData = 0;
230 if ( !bAddrInsert )
232 pDBData = pDoc->GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1,
233 rParam.nCol2, rParam.nRow2 );
234 if (!pDBData)
236 DBG_ERROR( "DoImport: no DBData" );
237 return FALSE;
241 Window* pWaitWin = rDocShell.GetActiveDialogParent();
242 if (pWaitWin)
243 pWaitWin->EnterWait();
244 ScDocShellModificator aModificator( rDocShell );
246 BOOL bSuccess = FALSE;
247 BOOL bApi = FALSE; //! pass as argument
248 BOOL bTruncated = FALSE; // for warning
249 USHORT nErrStringId = 0;
250 String aErrorMessage;
252 SCCOL nCol = rParam.nCol1;
253 SCROW nRow = rParam.nRow1;
254 SCCOL nEndCol = nCol; // end of resulting database area
255 SCROW nEndRow = nRow;
256 long i;
258 BOOL bDoSelection = FALSE;
259 BOOL bRealSelection = FALSE; // TRUE if not everything is selected
260 ULONG nListPos = 0;
261 ULONG nRowsRead = 0;
262 ULONG nListCount = 0;
264 // -1 is special
265 if ( pSelection && pSelection->Count() && (long)pSelection->GetObject(0) != -1L )
267 bDoSelection = TRUE;
268 nListCount = pSelection->Count();
271 // ImportDoc - also used for Redo
272 ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO );
273 pImportDoc->InitUndo( pDoc, nTab, nTab );
274 ScColumn::bDoubleAlloc = TRUE;
277 // get data from database into import document
282 // progress bar
283 // only text (title is still needed, for the cancel button)
284 ScProgress aProgress( &rDocShell, ScGlobal::GetRscString(STR_UNDO_IMPORTDATA), 0 );
285 USHORT nInserted = 0;
287 uno::Reference<sdbc::XRowSet> xRowSet = uno::Reference<sdbc::XRowSet>(
288 xResultSet, uno::UNO_QUERY );
289 sal_Bool bDispose = sal_False;
290 if ( !xRowSet.is() )
292 bDispose = sal_True;
293 xRowSet = uno::Reference<sdbc::XRowSet>(
294 comphelper::getProcessServiceFactory()->createInstance(
295 rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
296 uno::UNO_QUERY);
297 uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
298 DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
299 if ( xRowProp.is() )
302 // set source parameters
305 sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
306 ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
307 sdb::CommandType::TABLE );
308 uno::Any aAny;
310 aAny <<= rtl::OUString( rParam.aDBName );
311 xRowProp->setPropertyValue(
312 rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny );
314 aAny <<= rtl::OUString( rParam.aStatement );
315 xRowProp->setPropertyValue(
316 rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );
318 aAny <<= nType;
319 xRowProp->setPropertyValue(
320 rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );
322 uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY );
323 if ( xExecute.is() )
325 uno::Reference<task::XInteractionHandler> xHandler(
326 comphelper::getProcessServiceFactory()->createInstance(
327 rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ),
328 uno::UNO_QUERY);
329 xExecute->executeWithCompletion( xHandler );
331 else
332 xRowSet->execute();
335 if ( xRowSet.is() )
338 // get column descriptions
341 long nColCount = 0;
342 uno::Reference<sdbc::XResultSetMetaData> xMeta;
343 uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY );
344 if ( xMetaSupp.is() )
345 xMeta = xMetaSupp->getMetaData();
346 if ( xMeta.is() )
347 nColCount = xMeta->getColumnCount(); // this is the number of real columns
349 if ( rParam.nCol1 + nColCount - 1 > MAXCOL )
351 nColCount = 0;
352 //! error message
355 uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY );
356 if ( nColCount > 0 && xRow.is() )
358 nEndCol = (SCCOL)( rParam.nCol1 + nColCount - 1 );
360 uno::Sequence<sal_Int32> aColTypes( nColCount ); // column types
361 uno::Sequence<sal_Bool> aColCurr( nColCount ); // currency flag is not in types
362 sal_Int32* pTypeArr = aColTypes.getArray();
363 sal_Bool* pCurrArr = aColCurr.getArray();
364 for (i=0; i<nColCount; i++)
366 pTypeArr[i] = xMeta->getColumnType( i+1 );
367 pCurrArr[i] = xMeta->isCurrency( i+1 );
370 if ( !bAddrInsert ) // read column names
372 nCol = rParam.nCol1;
373 for (i=0; i<nColCount; i++)
375 pImportDoc->SetString( nCol, nRow, nTab,
376 xMeta->getColumnLabel( i+1 ) );
377 ++nCol;
379 ++nRow;
382 BOOL bEnd = FALSE;
383 if ( !bDoSelection )
384 xRowSet->beforeFirst();
385 while ( !bEnd )
387 // skip rows that are not selected
388 if ( !bDoSelection )
390 if ( (bEnd = !xRowSet->next()) == FALSE )
391 ++nRowsRead;
393 else
395 if (nListPos < nListCount)
397 ULONG nNextRow = (ULONG) pSelection->GetObject(nListPos);
398 if ( nRowsRead+1 < nNextRow )
399 bRealSelection = TRUE;
400 bEnd = !xRowSet->absolute(nRowsRead = nNextRow);
401 ++nListPos;
403 else
405 bRealSelection = xRowSet->next();
406 bEnd = TRUE; // more data available but not used
410 if ( !bEnd )
412 if ( ValidRow(nRow) )
414 nCol = rParam.nCol1;
415 for (i=0; i<nColCount; i++)
417 ScDatabaseDocUtil::PutData( pImportDoc, nCol, nRow, nTab,
418 xRow, i+1, pTypeArr[i], pCurrArr[i] );
419 ++nCol;
421 nEndRow = nRow;
422 ++nRow;
424 // progress bar
426 ++nInserted;
427 if (!(nInserted & 15))
429 String aPict = ScGlobal::GetRscString( STR_PROGRESS_IMPORT );
430 String aText = aPict.GetToken(0,'#');
431 aText += String::CreateFromInt32( nInserted );
432 aText += aPict.GetToken(1,'#');
434 if (!aProgress.SetStateText( 0, aText )) // stopped by user?
436 bEnd = TRUE;
437 bSuccess = FALSE;
438 nErrStringId = STR_DATABASE_ABORTED;
442 else // past the end of the spreadsheet
444 bEnd = TRUE; // don't continue
445 bTruncated = TRUE; // warning flag
450 bSuccess = TRUE;
453 if ( bDispose )
454 ::comphelper::disposeComponent( xRowSet );
457 catch ( sdbc::SQLException& rError )
459 aErrorMessage = rError.Message;
461 catch ( uno::Exception& )
463 DBG_ERROR("Unexpected exception in database");
466 ScColumn::bDoubleAlloc = FALSE;
467 pImportDoc->DoColResize( nTab, rParam.nCol1,nEndCol, 0 );
470 // test for cell protection
473 BOOL bKeepFormat = !bAddrInsert && pDBData->IsKeepFmt();
474 BOOL bMoveCells = !bAddrInsert && pDBData->IsDoSize();
475 SCCOL nFormulaCols = 0; // columns to be filled with formulas
476 if (bMoveCells && nEndCol == rParam.nCol2)
478 // if column count changes, formulas would become invalid anyway
479 // -> only set nFormulaCols for unchanged column count
481 SCCOL nTestCol = rParam.nCol2 + 1; // right of the data
482 SCROW nTestRow = rParam.nRow1 + 1; // below the title row
483 while ( nTestCol <= MAXCOL &&
484 pDoc->GetCellType(ScAddress( nTestCol, nTestRow, nTab )) == CELLTYPE_FORMULA )
485 ++nTestCol, ++nFormulaCols;
488 if (bSuccess)
490 // old and new range editable?
491 ScEditableTester aTester;
492 aTester.TestBlock( pDoc, nTab, rParam.nCol1,rParam.nRow1,rParam.nCol2,rParam.nRow2 );
493 aTester.TestBlock( pDoc, nTab, rParam.nCol1,rParam.nRow1,nEndCol,nEndRow );
494 if ( !aTester.IsEditable() )
496 nErrStringId = aTester.GetMessageId();
497 bSuccess = FALSE;
499 else if ( (pChangeTrack = pDoc->GetChangeTrack()) != NULL )
500 aChangedRange = ScRange(rParam.nCol1, rParam.nRow1, nTab,
501 nEndCol+nFormulaCols, nEndRow, nTab );
504 if ( bSuccess && bMoveCells )
506 ScRange aOld( rParam.nCol1, rParam.nRow1, nTab,
507 rParam.nCol2+nFormulaCols, rParam.nRow2, nTab );
508 ScRange aNew( rParam.nCol1, rParam.nRow1, nTab,
509 nEndCol+nFormulaCols, nEndRow, nTab );
510 if (!pDoc->CanFitBlock( aOld, aNew ))
512 nErrStringId = STR_MSSG_DOSUBTOTALS_2; // can't insert cells
513 bSuccess = FALSE;
518 // copy data from import doc into real document
521 if ( bSuccess )
523 if (bKeepFormat)
525 // keep formatting of title and first data row from the document
526 // CopyToDocument also copies styles, Apply... needs separate calls
528 SCCOL nMinEndCol = Min( rParam.nCol2, nEndCol ); // not too much
529 nMinEndCol = sal::static_int_cast<SCCOL>( nMinEndCol + nFormulaCols ); // only if column count unchanged
530 pImportDoc->DeleteAreaTab( 0,0, MAXCOL,MAXROW, nTab, IDF_ATTRIB );
531 pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab,
532 nMinEndCol, rParam.nRow1, nTab,
533 IDF_ATTRIB, FALSE, pImportDoc );
535 SCROW nDataStartRow = rParam.nRow1+1;
536 for (SCCOL nCopyCol=rParam.nCol1; nCopyCol<=nMinEndCol; nCopyCol++)
538 const ScPatternAttr* pSrcPattern = pDoc->GetPattern(
539 nCopyCol, nDataStartRow, nTab );
540 pImportDoc->ApplyPatternAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow,
541 nTab, *pSrcPattern );
542 const ScStyleSheet* pStyle = pSrcPattern->GetStyleSheet();
543 if (pStyle)
544 pImportDoc->ApplyStyleAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow,
545 nTab, *pStyle );
549 // don't set cell protection attribute if table is protected
550 if (pDoc->IsTabProtected(nTab))
552 ScPatternAttr aPattern(pImportDoc->GetPool());
553 aPattern.GetItemSet().Put( ScProtectionAttr( FALSE,FALSE,FALSE,FALSE ) );
554 pImportDoc->ApplyPatternAreaTab( 0,0,MAXCOL,MAXROW, nTab, aPattern );
558 // copy old data for undo
561 SCCOL nUndoEndCol = Max( nEndCol, rParam.nCol2 ); // rParam = old end
562 SCROW nUndoEndRow = Max( nEndRow, rParam.nRow2 );
564 ScDocument* pUndoDoc = NULL;
565 ScDBData* pUndoDBData = NULL;
566 if ( bRecord )
568 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
569 pUndoDoc->InitUndo( pDoc, nTab, nTab );
571 if ( !bAddrInsert )
572 pUndoDBData = new ScDBData( *pDBData );
575 ScMarkData aNewMark;
576 aNewMark.SelectOneTable( nTab );
578 if (bRecord)
580 // do not touch notes (ScUndoImportData does not support drawing undo)
581 sal_uInt16 nCopyFlags = IDF_ALL & ~IDF_NOTE;
583 // nFormulaCols is set only if column count is unchanged
584 pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab,
585 nEndCol+nFormulaCols, nEndRow, nTab,
586 nCopyFlags, FALSE, pUndoDoc );
587 if ( rParam.nCol2 > nEndCol )
588 pDoc->CopyToDocument( nEndCol+1, rParam.nRow1, nTab,
589 nUndoEndCol, nUndoEndRow, nTab,
590 nCopyFlags, FALSE, pUndoDoc );
591 if ( rParam.nRow2 > nEndRow )
592 pDoc->CopyToDocument( rParam.nCol1, nEndRow+1, nTab,
593 nUndoEndCol+nFormulaCols, nUndoEndRow, nTab,
594 nCopyFlags, FALSE, pUndoDoc );
598 // move new data
601 if (bMoveCells)
603 // clear only the range without the formulas,
604 // so the formula title and first row are preserved
606 ScRange aDelRange( rParam.nCol1, rParam.nRow1, nTab,
607 rParam.nCol2, rParam.nRow2, nTab );
608 pDoc->DeleteAreaTab( aDelRange, IDF_ALL & ~IDF_NOTE ); // ohne die Formeln
610 ScRange aOld( rParam.nCol1, rParam.nRow1, nTab,
611 rParam.nCol2+nFormulaCols, rParam.nRow2, nTab );
612 ScRange aNew( rParam.nCol1, rParam.nRow1, nTab,
613 nEndCol+nFormulaCols, nEndRow, nTab );
614 pDoc->FitBlock( aOld, aNew, FALSE ); // Formeln nicht loeschen
616 else if ( nEndCol < rParam.nCol2 ) // DeleteArea calls PutInOrder
617 pDoc->DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2,
618 aNewMark, IDF_CONTENTS & ~IDF_NOTE );
620 // CopyToDocument doesn't remove contents
621 pDoc->DeleteAreaTab( rParam.nCol1, rParam.nRow1, nEndCol, nEndRow, nTab, IDF_CONTENTS & ~IDF_NOTE );
623 // #41216# remove each column from ImportDoc after copying to reduce memory usage
624 BOOL bOldAutoCalc = pDoc->GetAutoCalc();
625 pDoc->SetAutoCalc( FALSE ); // outside of the loop
626 for (SCCOL nCopyCol = rParam.nCol1; nCopyCol <= nEndCol; nCopyCol++)
628 pImportDoc->CopyToDocument( nCopyCol, rParam.nRow1, nTab, nCopyCol, nEndRow, nTab,
629 IDF_ALL, FALSE, pDoc );
630 pImportDoc->DeleteAreaTab( nCopyCol, rParam.nRow1, nCopyCol, nEndRow, nTab, IDF_CONTENTS );
631 pImportDoc->DoColResize( nTab, nCopyCol, nCopyCol, 0 );
633 pDoc->SetAutoCalc( bOldAutoCalc );
635 if (nFormulaCols > 0) // copy formulas
637 if (bKeepFormat) // formats for formulas
638 pImportDoc->CopyToDocument( nEndCol+1, rParam.nRow1, nTab,
639 nEndCol+nFormulaCols, nEndRow, nTab,
640 IDF_ATTRIB, FALSE, pDoc );
641 // fill formulas
642 ScMarkData aMark;
643 aMark.SelectOneTable(nTab);
644 pDoc->Fill( nEndCol+1, rParam.nRow1+1, nEndCol+nFormulaCols, rParam.nRow1+1,
645 aMark, nEndRow-rParam.nRow1-1, FILL_TO_BOTTOM, FILL_SIMPLE );
648 // if new range is smaller, clear old contents
650 if (!bMoveCells) // move has happened above
652 if ( rParam.nCol2 > nEndCol )
653 pDoc->DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2,
654 aNewMark, IDF_CONTENTS );
655 if ( rParam.nRow2 > nEndRow )
656 pDoc->DeleteArea( rParam.nCol1, nEndRow+1, rParam.nCol2, rParam.nRow2,
657 aNewMark, IDF_CONTENTS );
660 if( !bAddrInsert ) // update database range
662 pDBData->SetImportParam( rParam );
663 pDBData->SetHeader( TRUE );
664 pDBData->SetByRow( TRUE );
665 pDBData->SetArea( nTab, rParam.nCol1,rParam.nRow1, nEndCol,nEndRow );
666 pDBData->SetImportSelection( bRealSelection );
667 pDoc->CompileDBFormula();
670 if (bRecord)
672 ScDocument* pRedoDoc = pImportDoc;
673 pImportDoc = NULL;
675 if (nFormulaCols > 0) // include filled formulas for redo
676 pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab,
677 nEndCol+nFormulaCols, nEndRow, nTab,
678 IDF_ALL & ~IDF_NOTE, FALSE, pRedoDoc );
680 ScDBData* pRedoDBData = pDBData ? new ScDBData( *pDBData ) : NULL;
682 rDocShell.GetUndoManager()->AddUndoAction(
683 new ScUndoImportData( &rDocShell, nTab,
684 rParam, nUndoEndCol, nUndoEndRow,
685 nFormulaCols,
686 pUndoDoc, pRedoDoc, pUndoDBData, pRedoDBData ) );
689 pDoc->SetDirty();
690 rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
691 aModificator.SetDocumentModified();
693 ScDBRangeRefreshedHint aHint( rParam );
694 pDoc->BroadcastUno( aHint );
696 if (pWaitWin)
697 pWaitWin->LeaveWait();
699 if ( bTruncated && !bApi ) // show warning
700 ErrorHandler::HandleError(SCWARN_IMPORT_RANGE_OVERFLOW);
702 else if ( !bApi )
704 if (pWaitWin)
705 pWaitWin->LeaveWait();
707 if (!aErrorMessage.Len())
709 if (!nErrStringId)
710 nErrStringId = STR_MSSG_IMPORTDATA_0;
711 aErrorMessage = ScGlobal::GetRscString( nErrStringId );
713 InfoBox aInfoBox( rDocShell.GetActiveDialogParent(), aErrorMessage );
714 aInfoBox.Execute();
717 delete pImportDoc;
719 if (bSuccess && pChangeTrack)
720 pChangeTrack->AppendInsert ( aChangedRange );
722 return bSuccess;