tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / docshell / dbdocimp.cxx
blob70616d9382b5ad1d31abd352121155edeb36ba01
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/errinf.hxx>
21 #include <comphelper/processfactory.hxx>
22 #include <comphelper/types.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/weld.hxx>
25 #include <svx/dataaccessdescriptor.hxx>
26 #include <sfx2/viewfrm.hxx>
27 #include <sal/log.hxx>
28 #include <osl/diagnose.h>
29 #include <comphelper/diagnose_ex.hxx>
31 #include <com/sun/star/sdb/CommandType.hpp>
32 #include <com/sun/star/sdb/XCompletedExecution.hpp>
33 #include <com/sun/star/sdbc/SQLException.hpp>
34 #include <com/sun/star/sdbc/XRow.hpp>
35 #include <com/sun/star/sdbc/XRowSet.hpp>
36 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
37 #include <com/sun/star/sdbcx/XRowLocate.hpp>
38 #include <com/sun/star/task/InteractionHandler.hpp>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/frame/FrameSearchFlag.hpp>
42 #include <com/sun/star/view/XSelectionSupplier.hpp>
44 #include <dbdocfun.hxx>
45 #include <docsh.hxx>
46 #include <globstr.hrc>
47 #include <scresid.hxx>
48 #include <scerrors.hxx>
49 #include <dbdata.hxx>
50 #include <markdata.hxx>
51 #include <undodat.hxx>
52 #include <progress.hxx>
53 #include <patattr.hxx>
54 #include <docpool.hxx>
55 #include <attrib.hxx>
56 #include <dbdocutl.hxx>
57 #include <editable.hxx>
58 #include <hints.hxx>
59 #include <miscuno.hxx>
60 #include <chgtrack.hxx>
61 #include <refupdatecontext.hxx>
63 using namespace com::sun::star;
65 constexpr OUStringLiteral SC_SERVICE_ROWSET = u"com.sun.star.sdb.RowSet";
67 //! move to a header file?
68 constexpr OUStringLiteral SC_DBPROP_DATASOURCENAME = u"DataSourceName";
69 constexpr OUStringLiteral SC_DBPROP_COMMAND = u"Command";
70 constexpr OUStringLiteral SC_DBPROP_COMMANDTYPE = u"CommandType";
72 void ScDBDocFunc::ShowInBeamer( const ScImportParam& rParam, const SfxViewFrame* pFrame )
74 // called after opening the database beamer
76 if ( !pFrame || !rParam.bImport )
77 return;
79 uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame().GetFrameInterface();
81 uno::Reference<frame::XFrame> xBeamerFrame = xFrame->findFrame(
82 u"_beamer"_ustr,
83 frame::FrameSearchFlag::CHILDREN);
84 if (!xBeamerFrame.is())
85 return;
87 uno::Reference<frame::XController> xController = xBeamerFrame->getController();
88 uno::Reference<view::XSelectionSupplier> xControllerSelection(xController, uno::UNO_QUERY);
89 if (xControllerSelection.is())
91 sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
92 ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
93 sdb::CommandType::TABLE );
95 svx::ODataAccessDescriptor aSelection;
96 aSelection.setDataSource(rParam.aDBName);
97 aSelection[svx::DataAccessDescriptorProperty::Command] <<= rParam.aStatement;
98 aSelection[svx::DataAccessDescriptorProperty::CommandType] <<= nType;
100 xControllerSelection->select(uno::Any(aSelection.createPropertyValueSequence()));
102 else
104 OSL_FAIL("no selection supplier in the beamer!");
108 void ScDBDocFunc::DoImportUno( const ScAddress& rPos,
109 const uno::Sequence<beans::PropertyValue>& aArgs )
111 svx::ODataAccessDescriptor aDesc( aArgs ); // includes selection and result set
113 // create database range
114 ScDBData* pDBData = rDocShell.GetDBData( ScRange(rPos), SC_DB_IMPORT, ScGetDBSelection::Keep );
115 assert(pDBData && "can't create DB data");
116 OUString sTarget = pDBData->GetName();
118 UpdateImport( sTarget, aDesc );
121 bool ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam,
122 const svx::ODataAccessDescriptor* pDescriptor )
124 ScDocument& rDoc = rDocShell.GetDocument();
125 ScChangeTrack *pChangeTrack = nullptr;
126 ScRange aChangedRange;
128 bool bRecord = true;
129 if (!rDoc.IsUndoEnabled())
130 bRecord = false;
132 ScDBData* pDBData = rDoc.GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1,
133 rParam.nCol2, rParam.nRow2 );
134 if (!pDBData)
136 OSL_FAIL( "DoImport: no DBData" );
137 return false;
140 std::unique_ptr<weld::WaitObject> xWaitWin(new weld::WaitObject(ScDocShell::GetActiveDialogParent()));
141 ScDocShellModificator aModificator( rDocShell );
143 bool bSuccess = false;
144 bool bTruncated = false; // for warning
145 TranslateId pErrStringId;
146 OUString aErrorMessage;
148 SCCOL nCol = rParam.nCol1;
149 SCROW nRow = rParam.nRow1;
150 SCCOL nEndCol = nCol; // end of resulting database area
151 SCROW nEndRow = nRow;
153 bool bDoSelection = false;
154 bool bRealSelection = false; // sal_True if not everything is selected
155 bool bBookmarkSelection = false;
156 sal_Int32 nListPos = 0;
157 sal_Int32 nRowsRead = 0;
158 sal_Int32 nListCount = 0;
160 uno::Sequence<uno::Any> aSelection;
161 if ( pDescriptor && pDescriptor->has(svx::DataAccessDescriptorProperty::Selection) )
163 (*pDescriptor)[svx::DataAccessDescriptorProperty::Selection] >>= aSelection;
164 nListCount = aSelection.getLength();
165 if ( nListCount > 0 )
167 bDoSelection = true;
168 if ( pDescriptor->has(svx::DataAccessDescriptorProperty::BookmarkSelection) )
169 bBookmarkSelection = ScUnoHelpFunctions::GetBoolFromAny( (*pDescriptor)[svx::DataAccessDescriptorProperty::BookmarkSelection] );
170 if ( bBookmarkSelection )
172 // From bookmarks, there's no way to detect if all records are selected.
173 // Rely on base to pass no selection in that case.
174 bRealSelection = true;
179 uno::Reference<sdbc::XResultSet> xResultSet;
180 if ( pDescriptor && pDescriptor->has(svx::DataAccessDescriptorProperty::Cursor) )
181 xResultSet.set((*pDescriptor)[svx::DataAccessDescriptorProperty::Cursor], uno::UNO_QUERY);
183 // ImportDoc - also used for Redo
184 ScDocumentUniquePtr pImportDoc(new ScDocument( SCDOCMODE_UNDO ));
185 pImportDoc->InitUndo( rDoc, nTab, nTab );
187 // get data from database into import document
191 // progress bar
192 // only text (title is still needed, for the cancel button)
193 ScProgress aProgress( &rDocShell, ScResId(STR_UNDO_IMPORTDATA), 0, true );
195 uno::Reference<sdbc::XRowSet> xRowSet( xResultSet, uno::UNO_QUERY );
196 bool bDispose = false;
197 if ( !xRowSet.is() )
199 bDispose = true;
200 xRowSet.set(comphelper::getProcessServiceFactory()->createInstance(
201 SC_SERVICE_ROWSET ),
202 uno::UNO_QUERY);
203 uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
204 OSL_ENSURE( xRowProp.is(), "can't get RowSet" );
205 if ( xRowProp.is() )
208 // set source parameters
210 sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
211 ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
212 sdb::CommandType::TABLE );
214 xRowProp->setPropertyValue( SC_DBPROP_DATASOURCENAME, uno::Any(rParam.aDBName) );
216 xRowProp->setPropertyValue( SC_DBPROP_COMMAND, uno::Any(rParam.aStatement) );
218 xRowProp->setPropertyValue( SC_DBPROP_COMMANDTYPE, uno::Any(nType) );
220 uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY );
221 if ( xExecute.is() )
223 uno::Reference<task::XInteractionHandler> xHandler(
224 task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), nullptr),
225 uno::UNO_QUERY_THROW);
226 xExecute->executeWithCompletion( xHandler );
228 else
229 xRowSet->execute();
232 if ( xRowSet.is() )
235 // get column descriptions
237 sal_Int32 nColCount = 0;
238 uno::Reference<sdbc::XResultSetMetaData> xMeta;
239 uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY );
240 if ( xMetaSupp.is() )
241 xMeta = xMetaSupp->getMetaData();
242 if ( xMeta.is() )
243 nColCount = xMeta->getColumnCount(); // this is the number of real columns
245 if ( rParam.nCol1 + nColCount - 1 > rDoc.MaxCol() )
247 nColCount = 0;
248 //! error message
251 uno::Reference<sdbcx::XRowLocate> xLocate;
252 if ( bBookmarkSelection )
254 xLocate.set( xRowSet, uno::UNO_QUERY );
255 if ( !xLocate.is() )
257 SAL_WARN( "sc.ui","can't get XRowLocate");
258 bDoSelection = bRealSelection = bBookmarkSelection = false;
262 uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY );
263 if ( nColCount > 0 && xRow.is() )
265 nEndCol = static_cast<SCCOL>( rParam.nCol1 + nColCount - 1 );
267 uno::Sequence<sal_Int32> aColTypes( nColCount ); // column types
268 uno::Sequence<sal_Bool> aColCurr( nColCount ); // currency flag is not in types
269 sal_Int32* pTypeArr = aColTypes.getArray();
270 sal_Bool* pCurrArr = aColCurr.getArray();
271 for (tools::Long i=0; i<nColCount; i++)
273 pTypeArr[i] = xMeta->getColumnType( i+1 );
274 pCurrArr[i] = xMeta->isCurrency( i+1 );
277 // read column names
278 nCol = rParam.nCol1;
279 for (tools::Long i=0; i<nColCount; i++)
281 pImportDoc->SetString( nCol, nRow, nTab,
282 xMeta->getColumnLabel( i+1 ) );
283 ++nCol;
285 ++nRow;
287 bool bEnd = false;
288 if ( !bDoSelection )
289 xRowSet->beforeFirst();
290 sal_uInt16 nInserted = 0;
291 while ( !bEnd )
293 // skip rows that are not selected
294 if ( !bDoSelection )
296 bEnd = !xRowSet->next();
297 if ( !bEnd )
298 ++nRowsRead;
300 else
302 if (nListPos < nListCount)
304 if ( bBookmarkSelection )
306 bEnd = !xLocate->moveToBookmark(aSelection[nListPos]);
308 else // use record numbers
310 sal_Int32 nNextRow = 0;
311 aSelection[nListPos] >>= nNextRow;
312 if ( nRowsRead+1 < nNextRow )
313 bRealSelection = true;
314 nRowsRead = nNextRow;
315 bEnd = !xRowSet->absolute(nRowsRead);
317 ++nListPos;
319 else
321 if ( !bBookmarkSelection && xRowSet->next() )
322 bRealSelection = true; // more data available but not used
323 bEnd = true;
327 if ( !bEnd )
329 if ( rDoc.ValidRow(nRow) )
331 nCol = rParam.nCol1;
332 for (tools::Long i=0; i<nColCount; i++)
334 ScDatabaseDocUtil::PutData( *pImportDoc, nCol, nRow, nTab,
335 xRow, i+1, pTypeArr[i], pCurrArr[i] );
336 ++nCol;
338 nEndRow = nRow;
339 ++nRow;
341 // progress bar
343 ++nInserted;
344 if (!(nInserted & 15))
346 aProgress.SetState( 0 );
349 else // past the end of the spreadsheet
351 bEnd = true; // don't continue
352 bTruncated = true; // warning flag
357 bSuccess = true;
360 if ( bDispose )
361 ::comphelper::disposeComponent( xRowSet );
364 catch ( const sdbc::SQLException& rError )
366 aErrorMessage = rError.Message;
368 catch ( uno::Exception& )
370 TOOLS_WARN_EXCEPTION( "sc", "Unexpected exception in database");
373 // test for cell protection
375 bool bKeepFormat = pDBData->IsKeepFmt();
376 bool bMoveCells = pDBData->IsDoSize();
377 SCCOL nFormulaCols = 0; // columns to be filled with formulas
378 if (bMoveCells && nEndCol == rParam.nCol2)
380 // if column count changes, formulas would become invalid anyway
381 // -> only set nFormulaCols for unchanged column count
383 SCCOL nTestCol = rParam.nCol2 + 1; // right of the data
384 SCROW nTestRow = rParam.nRow1 + 1; // below the title row
385 while ( nTestCol <= rDoc.MaxCol() &&
386 rDoc.GetCellType(ScAddress( nTestCol, nTestRow, nTab )) == CELLTYPE_FORMULA )
388 ++nTestCol;
389 ++nFormulaCols;
393 if (bSuccess)
395 // old and new range editable?
396 ScEditableTester aTester;
397 aTester.TestBlock( rDoc, nTab, rParam.nCol1,rParam.nRow1,rParam.nCol2,rParam.nRow2 );
398 aTester.TestBlock( rDoc, nTab, rParam.nCol1,rParam.nRow1,nEndCol,nEndRow );
399 if ( !aTester.IsEditable() )
401 pErrStringId = aTester.GetMessageId();
402 bSuccess = false;
404 else if ( (pChangeTrack = rDoc.GetChangeTrack()) != nullptr )
405 aChangedRange = ScRange(rParam.nCol1, rParam.nRow1, nTab,
406 nEndCol+nFormulaCols, nEndRow, nTab );
409 if ( bSuccess && bMoveCells )
411 ScRange aOld( rParam.nCol1, rParam.nRow1, nTab,
412 rParam.nCol2+nFormulaCols, rParam.nRow2, nTab );
413 ScRange aNew( rParam.nCol1, rParam.nRow1, nTab,
414 nEndCol+nFormulaCols, nEndRow, nTab );
415 if (!rDoc.CanFitBlock( aOld, aNew ))
417 pErrStringId = STR_MSSG_DOSUBTOTALS_2; // can't insert cells
418 bSuccess = false;
422 // copy data from import doc into real document
424 if ( bSuccess )
426 if (bKeepFormat)
428 // keep formatting of title and first data row from the document
429 // CopyToDocument also copies styles, Apply... needs separate calls
431 SCCOL nMinEndCol = std::min( rParam.nCol2, nEndCol ); // not too much
432 nMinEndCol = sal::static_int_cast<SCCOL>( nMinEndCol + nFormulaCols ); // only if column count unchanged
433 pImportDoc->DeleteAreaTab( 0,0, rDoc.MaxCol(),rDoc.MaxRow(), nTab, InsertDeleteFlags::ATTRIB );
434 rDoc.CopyToDocument(rParam.nCol1, rParam.nRow1, nTab,
435 nMinEndCol, rParam.nRow1, nTab,
436 InsertDeleteFlags::ATTRIB, false, *pImportDoc);
438 SCROW nDataStartRow = rParam.nRow1+1;
439 for (SCCOL nCopyCol=rParam.nCol1; nCopyCol<=nMinEndCol; nCopyCol++)
441 const ScPatternAttr* pSrcPattern = rDoc.GetPattern(
442 nCopyCol, nDataStartRow, nTab );
443 pImportDoc->ApplyPatternAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow,
444 nTab, *pSrcPattern );
445 const ScStyleSheet* pStyle = pSrcPattern->GetStyleSheet();
446 if (pStyle)
447 pImportDoc->ApplyStyleAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow,
448 nTab, *pStyle );
452 // don't set cell protection attribute if table is protected
453 if (rDoc.IsTabProtected(nTab))
455 ScPatternAttr aPattern(pImportDoc->getCellAttributeHelper());
456 aPattern.GetItemSet().Put( ScProtectionAttr( false,false,false,false ) );
457 pImportDoc->ApplyPatternAreaTab( 0,0,rDoc.MaxCol(),rDoc.MaxRow(), nTab, aPattern );
460 // copy old data for undo
462 SCCOL nUndoEndCol = std::max( nEndCol, rParam.nCol2 ); // rParam = old end
463 SCROW nUndoEndRow = std::max( nEndRow, rParam.nRow2 );
465 ScDocumentUniquePtr pUndoDoc;
466 std::unique_ptr<ScDBData> pUndoDBData;
467 if ( bRecord )
469 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
470 pUndoDoc->InitUndo( rDoc, nTab, nTab );
472 pUndoDBData.reset(new ScDBData( *pDBData ));
475 ScMarkData aNewMark(rDoc.GetSheetLimits());
476 aNewMark.SelectOneTable( nTab );
478 if (bRecord)
480 // do not touch notes (ScUndoImportData does not support drawing undo)
481 InsertDeleteFlags nCopyFlags = InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE;
483 // nFormulaCols is set only if column count is unchanged
484 rDoc.CopyToDocument(rParam.nCol1, rParam.nRow1, nTab,
485 nEndCol+nFormulaCols, nEndRow, nTab,
486 nCopyFlags, false, *pUndoDoc);
487 if ( rParam.nCol2 > nEndCol )
488 rDoc.CopyToDocument(nEndCol+1, rParam.nRow1, nTab,
489 nUndoEndCol, nUndoEndRow, nTab,
490 nCopyFlags, false, *pUndoDoc);
491 if ( rParam.nRow2 > nEndRow )
492 rDoc.CopyToDocument(rParam.nCol1, nEndRow+1, nTab,
493 nUndoEndCol+nFormulaCols, nUndoEndRow, nTab,
494 nCopyFlags, false, *pUndoDoc);
497 // move new data
499 if (bMoveCells)
501 // clear only the range without the formulas,
502 // so the formula title and first row are preserved
504 ScRange aDelRange( rParam.nCol1, rParam.nRow1, nTab,
505 rParam.nCol2, rParam.nRow2, nTab );
506 rDoc.DeleteAreaTab( aDelRange, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE ); // without the formulas
508 ScRange aOld( rParam.nCol1, rParam.nRow1, nTab,
509 rParam.nCol2+nFormulaCols, rParam.nRow2, nTab );
510 ScRange aNew( rParam.nCol1, rParam.nRow1, nTab,
511 nEndCol+nFormulaCols, nEndRow, nTab );
512 rDoc.FitBlock( aOld, aNew, false ); // Do not delete formulas
514 else if ( nEndCol < rParam.nCol2 ) // DeleteArea calls PutInOrder
515 rDoc.DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2,
516 aNewMark, InsertDeleteFlags::CONTENTS & ~InsertDeleteFlags::NOTE );
518 // CopyToDocument doesn't remove contents
519 rDoc.DeleteAreaTab( rParam.nCol1, rParam.nRow1, nEndCol, nEndRow, nTab, InsertDeleteFlags::CONTENTS & ~InsertDeleteFlags::NOTE );
521 // remove each column from ImportDoc after copying to reduce memory usage
522 bool bOldAutoCalc = rDoc.GetAutoCalc();
523 rDoc.SetAutoCalc( false ); // outside of the loop
524 for (SCCOL nCopyCol = rParam.nCol1; nCopyCol <= nEndCol; nCopyCol++)
526 pImportDoc->CopyToDocument(nCopyCol, rParam.nRow1, nTab, nCopyCol, nEndRow, nTab,
527 InsertDeleteFlags::ALL, false, rDoc);
528 pImportDoc->DeleteAreaTab( nCopyCol, rParam.nRow1, nCopyCol, nEndRow, nTab, InsertDeleteFlags::CONTENTS );
530 rDoc.SetAutoCalc( bOldAutoCalc );
532 if (nFormulaCols > 0) // copy formulas
534 if (bKeepFormat) // formats for formulas
535 pImportDoc->CopyToDocument(nEndCol+1, rParam.nRow1, nTab,
536 nEndCol+nFormulaCols, nEndRow, nTab,
537 InsertDeleteFlags::ATTRIB, false, rDoc);
538 // fill formulas
539 ScMarkData aMark(rDoc.GetSheetLimits());
540 aMark.SelectOneTable(nTab);
542 sal_uLong nProgCount = nFormulaCols;
543 nProgCount *= nEndRow-rParam.nRow1-1;
544 ScProgress aProgress( rDoc.GetDocumentShell(),
545 ScResId(STR_FILL_SERIES_PROGRESS), nProgCount, true );
547 rDoc.Fill( nEndCol+1, rParam.nRow1+1, nEndCol+nFormulaCols, rParam.nRow1+1,
548 &aProgress, aMark, nEndRow-rParam.nRow1-1, FILL_TO_BOTTOM, FILL_SIMPLE );
551 // if new range is smaller, clear old contents
553 if (!bMoveCells) // move has happened above
555 if ( rParam.nCol2 > nEndCol )
556 rDoc.DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2,
557 aNewMark, InsertDeleteFlags::CONTENTS );
558 if ( rParam.nRow2 > nEndRow )
559 rDoc.DeleteArea( rParam.nCol1, nEndRow+1, rParam.nCol2, rParam.nRow2,
560 aNewMark, InsertDeleteFlags::CONTENTS );
563 // update database range
564 pDBData->SetImportParam( rParam );
565 pDBData->SetHeader( true );
566 pDBData->SetByRow( true );
567 pDBData->SetArea( nTab, rParam.nCol1,rParam.nRow1, nEndCol,nEndRow );
568 pDBData->SetImportSelection( bRealSelection );
569 rDoc.CompileDBFormula();
571 if (bRecord)
573 ScDocumentUniquePtr pRedoDoc = std::move(pImportDoc);
575 if (nFormulaCols > 0) // include filled formulas for redo
576 rDoc.CopyToDocument(rParam.nCol1, rParam.nRow1, nTab,
577 nEndCol+nFormulaCols, nEndRow, nTab,
578 InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE, false, *pRedoDoc);
580 std::unique_ptr<ScDBData> pRedoDBData(new ScDBData(*pDBData));
582 rDocShell.GetUndoManager()->AddUndoAction(
583 std::make_unique<ScUndoImportData>( &rDocShell, nTab,
584 rParam, nUndoEndCol, nUndoEndRow,
585 nFormulaCols,
586 std::move(pUndoDoc), std::move(pRedoDoc),
587 std::move(pUndoDBData), std::move(pRedoDBData) ) );
590 sc::SetFormulaDirtyContext aCxt;
591 rDoc.SetAllFormulasDirty(aCxt);
592 rDocShell.PostPaint(ScRange(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab), PaintPartFlags::Grid);
593 aModificator.SetDocumentModified();
595 ScDBRangeRefreshedHint aHint( rParam );
596 rDoc.BroadcastUno( aHint );
598 xWaitWin.reset();
600 if ( bTruncated ) // show warning
601 ErrorHandler::HandleError(SCWARN_IMPORT_RANGE_OVERFLOW);
603 else
605 xWaitWin.reset();
607 if (aErrorMessage.isEmpty())
609 if (!pErrStringId)
610 pErrStringId = STR_MSSG_IMPORTDATA_0;
611 aErrorMessage = ScResId(pErrStringId);
614 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
615 VclMessageType::Info, VclButtonsType::Ok,
616 aErrorMessage));
617 xInfoBox->run();
620 pImportDoc.reset();
622 if (bSuccess && pChangeTrack)
623 pChangeTrack->AppendInsert ( aChangedRange );
625 return bSuccess;
628 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */