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