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