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 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 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 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