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