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