1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
46 #include <globstr.hrc>
47 #include <scresid.hxx>
48 #include <scerrors.hxx>
50 #include <markdata.hxx>
51 #include <undodat.hxx>
52 #include <progress.hxx>
53 #include <patattr.hxx>
54 #include <docpool.hxx>
56 #include <dbdocutl.hxx>
57 #include <editable.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
)
79 uno::Reference
<frame::XFrame
> xFrame
= pFrame
->GetFrame().GetFrameInterface();
81 uno::Reference
<frame::XFrame
> xBeamerFrame
= xFrame
->findFrame(
83 frame::FrameSearchFlag::CHILDREN
);
84 if (!xBeamerFrame
.is())
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()));
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
;
129 if (!rDoc
.IsUndoEnabled())
132 ScDBData
* pDBData
= rDoc
.GetDBAtArea( nTab
, rParam
.nCol1
, rParam
.nRow1
,
133 rParam
.nCol2
, rParam
.nRow2
);
136 OSL_FAIL( "DoImport: no DBData" );
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 )
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
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;
200 xRowSet
.set(comphelper::getProcessServiceFactory()->createInstance(
203 uno::Reference
<beans::XPropertySet
> xRowProp( xRowSet
, uno::UNO_QUERY
);
204 OSL_ENSURE( xRowProp
.is(), "can't get RowSet" );
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
);
223 uno::Reference
<task::XInteractionHandler
> xHandler(
224 task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), nullptr),
225 uno::UNO_QUERY_THROW
);
226 xExecute
->executeWithCompletion( xHandler
);
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();
243 nColCount
= xMeta
->getColumnCount(); // this is the number of real columns
245 if ( rParam
.nCol1
+ nColCount
- 1 > rDoc
.MaxCol() )
251 uno::Reference
<sdbcx::XRowLocate
> xLocate
;
252 if ( bBookmarkSelection
)
254 xLocate
.set( xRowSet
, uno::UNO_QUERY
);
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 );
279 for (tools::Long i
=0; i
<nColCount
; i
++)
281 pImportDoc
->SetString( nCol
, nRow
, nTab
,
282 xMeta
->getColumnLabel( i
+1 ) );
289 xRowSet
->beforeFirst();
290 sal_uInt16 nInserted
= 0;
293 // skip rows that are not selected
296 bEnd
= !xRowSet
->next();
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
);
321 if ( !bBookmarkSelection
&& xRowSet
->next() )
322 bRealSelection
= true; // more data available but not used
329 if ( rDoc
.ValidRow(nRow
) )
332 for (tools::Long i
=0; i
<nColCount
; i
++)
334 ScDatabaseDocUtil::PutData( *pImportDoc
, nCol
, nRow
, nTab
,
335 xRow
, i
+1, pTypeArr
[i
], pCurrArr
[i
] );
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
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
)
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();
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
422 // copy data from import doc into real document
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();
447 pImportDoc
->ApplyStyleAreaTab( nCopyCol
, nDataStartRow
, nCopyCol
, nEndRow
,
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
;
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
);
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
);
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
);
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();
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
,
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
);
600 if ( bTruncated
) // show warning
601 ErrorHandler::HandleError(SCWARN_IMPORT_RANGE_OVERFLOW
);
607 if (aErrorMessage
.isEmpty())
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
,
622 if (bSuccess
&& pChangeTrack
)
623 pChangeTrack
->AppendInsert ( aChangedRange
);
628 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */