LibreOffice Module sc (master) 1
docsh8.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <config_features.h>
21
22#include <vcl/errinf.hxx>
23#include <tools/urlobj.hxx>
24#include <svl/converter.hxx>
25#include <svl/numformat.hxx>
28#include <comphelper/types.hxx>
29#include <ucbhelper/content.hxx>
30#include <svx/txenctab.hxx>
33#include <rtl/character.hxx>
34#include <rtl/tencinfo.h>
35#include <sal/log.hxx>
36#include <osl/diagnose.h>
38#include <o3tl/string_view.hxx>
39
40#include <com/sun/star/sdb/CommandType.hpp>
41#include <com/sun/star/sdbc/DataType.hpp>
42#include <com/sun/star/sdbc/SQLException.hpp>
43#include <com/sun/star/sdbc/XConnection.hpp>
44#include <com/sun/star/sdbc/DriverManager.hpp>
45#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
46#include <com/sun/star/sdbc/XRow.hpp>
47#include <com/sun/star/sdbc/XRowSet.hpp>
48#include <com/sun/star/sdbc/XRowUpdate.hpp>
49#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
50#include <com/sun/star/sdbcx/XAppend.hpp>
51#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
52#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
53#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
54#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
55#include <com/sun/star/lang/XMultiServiceFactory.hpp>
56#include <com/sun/star/beans/XPropertySet.hpp>
57#include <com/sun/star/ucb/NameClash.hpp>
58#include <com/sun/star/ucb/TransferInfo.hpp>
59#include <com/sun/star/ucb/XCommandInfo.hpp>
60
61#include <scerrors.hxx>
62#include <docsh.hxx>
63#include <progress.hxx>
64#include <editutil.hxx>
65#include <cellform.hxx>
66#include <dbdocutl.hxx>
67#include <dociter.hxx>
68#include <globstr.hrc>
69#include <scresid.hxx>
70#include <svl/zformat.hxx>
71#include <svl/intitem.hxx>
72#include <patattr.hxx>
73#include <scitems.hxx>
74#include <docpool.hxx>
75#include <segmenttree.hxx>
76#include <docparam.hxx>
77#include <cellvalue.hxx>
78
79#include <unordered_set>
80#include <vector>
81
82using namespace com::sun::star;
83using ::std::vector;
84
85#if HAVE_FEATURE_DBCONNECTIVITY
86
87constexpr OUStringLiteral SC_SERVICE_ROWSET = u"com.sun.star.sdb.RowSet";
88
90constexpr OUStringLiteral SC_DBPROP_ACTIVECONNECTION = u"ActiveConnection";
91constexpr OUStringLiteral SC_DBPROP_COMMAND = u"Command";
92constexpr OUStringLiteral SC_DBPROP_COMMANDTYPE = u"CommandType";
93constexpr OUStringLiteral SC_DBPROP_PROPCHANGE_NOTIFY = u"PropertyChangeNotificationEnabled";
94
95constexpr OUStringLiteral SC_DBPROP_NAME = u"Name";
96constexpr OUStringLiteral SC_DBPROP_TYPE = u"Type";
97constexpr OUStringLiteral SC_DBPROP_PRECISION = u"Precision";
98constexpr OUStringLiteral SC_DBPROP_SCALE = u"Scale";
99
100constexpr OUStringLiteral SC_DBPROP_EXTENSION = u"Extension";
101constexpr OUStringLiteral SC_DBPROP_CHARSET = u"CharSet";
102
103namespace
104{
105 ErrCode lcl_getDBaseConnection(uno::Reference<sdbc::XDriverManager2>& _rDrvMgr, uno::Reference<sdbc::XConnection>& _rConnection, OUString& _rTabName, std::u16string_view rFullFileName, rtl_TextEncoding eCharSet)
106 {
108 aURL.SetSmartProtocol( INetProtocol::File );
109 aURL.SetSmartURL( rFullFileName );
110 _rTabName = aURL.getBase( INetURLObject::LAST_SEGMENT, true,
112 OUString aExtension = aURL.getExtension();
113 aURL.removeSegment();
114 aURL.removeFinalSlash();
115 OUString aPath = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
116 uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
117
118 _rDrvMgr.set( sdbc::DriverManager::create( xContext ) );
119
120 // get connection
121
122 const OUString aConnUrl{"sdbc:dbase:" + aPath};
123
124 // sdbc:dbase is based on the css.sdbc.FILEConnectionProperties UNOIDL service, so we can
125 // transport the raw rtl_TextEncoding value instead of having to translate it into an IANA
126 // character set name string (which might not exist for certain eCharSet values, like
127 // RTL_TEXTENCODING_MS_950):
128 uno::Sequence<beans::PropertyValue> aProps( comphelper::InitPropertySequence({
129 { SC_DBPROP_EXTENSION, uno::Any(aExtension) },
130 { SC_DBPROP_CHARSET, uno::Any(eCharSet) }
131 }));
132
133 _rConnection = _rDrvMgr->getConnectionWithInfo( aConnUrl, aProps );
134 return ERRCODE_NONE;
135 }
136}
137
138#endif // HAVE_FEATURE_DBCONNECTIVITY
139
140// MoveFile/KillFile/IsDocument: similar to SfxContentHelper
141
142bool ScDocShell::MoveFile( const INetURLObject& rSourceObj, const INetURLObject& rDestObj )
143{
144 bool bMoveData = true;
145 bool bRet = true, bKillSource = false;
146 if ( rSourceObj.GetProtocol() != rDestObj.GetProtocol() )
147 {
148 bMoveData = false;
149 bKillSource = true;
150 }
151 OUString aName = rDestObj.getName();
152 INetURLObject aDestPathObj = rDestObj;
153 aDestPathObj.removeSegment();
154 aDestPathObj.setFinalSlash();
155
156 try
157 {
159 uno::Reference< css::ucb::XCommandEnvironment >(),
161 uno::Reference< css::ucb::XCommandInfo > xInfo = aDestPath.getCommands();
162 OUString aTransferName = "transfer";
163 if ( xInfo->hasCommandByName( aTransferName ) )
164 {
165 aDestPath.executeCommand( aTransferName, uno::Any(
166 css::ucb::TransferInfo( bMoveData, rSourceObj.GetMainURL(INetURLObject::DecodeMechanism::NONE), aName,
167 css::ucb::NameClash::ERROR ) ) );
168 }
169 else
170 {
171 OSL_FAIL( "transfer command not available" );
172 }
173 }
174 catch( uno::Exception& )
175 {
176 // ucb may throw different exceptions on failure now
177 bRet = false;
178 }
179
180 if ( bKillSource )
181 KillFile( rSourceObj );
182
183 return bRet;
184}
185
187{
188 bool bRet = true;
189 try
190 {
192 uno::Reference< css::ucb::XCommandEnvironment >(),
194 aCnt.executeCommand( "delete", css::uno::Any( true ) );
195 }
196 catch( uno::Exception& )
197 {
198 // ucb may throw different exceptions on failure now
199 bRet = false;
200 }
201
202 return bRet;
203}
204
206{
207 bool bRet = false;
208 try
209 {
211 uno::Reference< css::ucb::XCommandEnvironment >(),
213 bRet = aCnt.isDocument();
214 }
215 catch( uno::Exception& )
216 {
217 // ucb may throw different exceptions on failure now - warning only
218 TOOLS_WARN_EXCEPTION( "sc", "Any other exception" );
219 }
220
221 return bRet;
222}
223
224#if HAVE_FEATURE_DBCONNECTIVITY
225
226static void lcl_setScalesToColumns(ScDocument& rDoc, const vector<tools::Long>& rScales)
227{
228 SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
229 if (!pFormatter)
230 return;
231
232 SCCOL nColCount = static_cast<SCCOL>(rScales.size());
233 for (SCCOL i = 0; i < nColCount; ++i)
234 {
235 if (rScales[i] < 0)
236 continue;
237
238 sal_uInt32 nOldFormat = rDoc.GetNumberFormat(i, 0, 0);
239 const SvNumberformat* pOldEntry = pFormatter->GetEntry(nOldFormat);
240 if (!pOldEntry)
241 continue;
242
243 LanguageType eLang = pOldEntry->GetLanguage();
244 bool bThousand, bNegRed;
245 sal_uInt16 nPrecision, nLeading;
246 pOldEntry->GetFormatSpecialInfo(bThousand, bNegRed, nPrecision, nLeading);
247
248 nPrecision = static_cast<sal_uInt16>(rScales[i]);
249 OUString aNewPicture = pFormatter->GenerateFormat(nOldFormat, eLang,
250 bThousand, bNegRed, nPrecision, nLeading);
251
252 sal_uInt32 nNewFormat = pFormatter->GetEntryKey(aNewPicture, eLang);
253 if (nNewFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
254 {
255 sal_Int32 nErrPos = 0;
256 SvNumFormatType nNewType = SvNumFormatType::ALL;
257 bool bOk = pFormatter->PutEntry(
258 aNewPicture, nErrPos, nNewType, nNewFormat, eLang);
259
260 if (!bOk)
261 continue;
262 }
263
264 ScPatternAttr aNewAttrs( rDoc.GetPool() );
265 SfxItemSet& rSet = aNewAttrs.GetItemSet();
266 rSet.Put( SfxUInt32Item(ATTR_VALUE_FORMAT, nNewFormat) );
267 rDoc.ApplyPatternAreaTab(i, 0, i, rDoc.MaxRow(), 0, aNewAttrs);
268 }
269}
270
271#endif // HAVE_FEATURE_DBCONNECTIVITY
272
273ErrCode ScDocShell::DBaseImport( const OUString& rFullFileName, rtl_TextEncoding eCharSet,
274 std::map<SCCOL, ScColWidthParam>& aColWidthParam, ScFlatBoolRowSegments& rRowHeightsRecalc )
275{
276#if !HAVE_FEATURE_DBCONNECTIVITY
277 (void) rFullFileName;
278 (void) eCharSet;
279 (void) aColWidthParam;
280 (void) rRowHeightsRecalc;
281
282 return ERRCODE_IO_GENERAL;
283#else
284
285 ErrCode nErr = ERRCODE_NONE;
286
287 try
288 {
290 sal_Int32 nColCount = 0;
291 OUString aTabName;
292 uno::Reference<sdbc::XDriverManager2> xDrvMan;
293 uno::Reference<sdbc::XConnection> xConnection;
294 ErrCode nRet = lcl_getDBaseConnection(xDrvMan,xConnection,aTabName,rFullFileName,eCharSet);
295 if ( !xConnection.is() || !xDrvMan.is() )
296 return nRet;
297 ::utl::DisposableComponent aConnectionHelper(xConnection);
298
299 ScProgress aProgress( this, ScResId( STR_LOAD_DOC ), 0, true );
300 uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory();
301 uno::Reference<sdbc::XRowSet> xRowSet( xFactory->createInstance(SC_SERVICE_ROWSET),
302 uno::UNO_QUERY);
303 ::utl::DisposableComponent aRowSetHelper(xRowSet);
304 uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
305 OSL_ENSURE( xRowProp.is(), "can't get RowSet" );
306 if (!xRowProp.is()) return SCERR_IMPORT_CONNECT;
307
308 xRowProp->setPropertyValue( SC_DBPROP_ACTIVECONNECTION, uno::Any(xConnection) );
309
310 xRowProp->setPropertyValue( SC_DBPROP_COMMANDTYPE, uno::Any(sdb::CommandType::TABLE) );
311
312 xRowProp->setPropertyValue( SC_DBPROP_COMMAND, uno::Any(aTabName) );
313
314 xRowProp->setPropertyValue( SC_DBPROP_PROPCHANGE_NOTIFY, uno::Any(false) );
315
316 xRowSet->execute();
317
318 uno::Reference<sdbc::XResultSetMetaData> xMeta;
319 uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY );
320 if ( xMetaSupp.is() )
321 xMeta = xMetaSupp->getMetaData();
322 if ( xMeta.is() )
323 nColCount = xMeta->getColumnCount(); // this is the number of real columns
324
325 if ( nColCount > m_pDocument->MaxCol()+1 )
326 {
327 nColCount = m_pDocument->MaxCol()+1;
328 nErr = SCWARN_IMPORT_COLUMN_OVERFLOW; // warning
329 }
330
331 uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY );
332 OSL_ENSURE( xRow.is(), "can't get Row" );
333 if (!xRow.is()) return SCERR_IMPORT_CONNECT;
334
335 // currency flag is not needed for dBase
336 uno::Sequence<sal_Int32> aColTypes( nColCount ); // column types
337 sal_Int32* pTypeArr = aColTypes.getArray();
338 for (i=0; i<nColCount; i++)
339 pTypeArr[i] = xMeta->getColumnType( i+1 );
340
341 // read column names
343
344 aProgress.SetState( 0 );
345
346 vector<tools::Long> aScales(nColCount, -1);
347 for (i=0; i<nColCount; i++)
348 {
349 OUString aHeader = xMeta->getColumnLabel( i+1 );
350
351 switch ( pTypeArr[i] )
352 {
353 case sdbc::DataType::BIT:
354 aHeader += ",L";
355 break;
357 aHeader += ",D";
358 break;
359 case sdbc::DataType::LONGVARCHAR:
360 aHeader += ",M";
361 break;
362 case sdbc::DataType::VARCHAR:
363 aHeader += ",C," + OUString::number( xMeta->getColumnDisplaySize( i+1 ) );
364 break;
365 case sdbc::DataType::DECIMAL:
366 {
367 tools::Long nPrec = xMeta->getPrecision( i+1 );
368 tools::Long nScale = xMeta->getScale( i+1 );
369 aHeader += ",N," +
370 OUString::number(
372 nPrec, nScale ) ) +
373 "," +
374 OUString::number( nScale );
375 aScales[i] = nScale;
376 }
377 break;
378 }
379
380 m_pDocument->SetString( static_cast<SCCOL>(i), 0, 0, aHeader );
381 }
382
383 lcl_setScalesToColumns(*m_pDocument, aScales);
384
385 SCROW nRow = 1; // 0 is column titles
386 bool bEnd = false;
387 while ( !bEnd && xRowSet->next() )
388 {
389 if ( nRow <= m_pDocument->MaxRow() )
390 {
391 bool bSimpleRow = true;
392 SCCOL nCol = 0;
393 for (i=0; i<nColCount; i++)
394 {
397 xRow, i+1, pTypeArr[i], false,
398 &aStrData );
399
400 if (aStrData.mnStrLength > aColWidthParam[nCol].mnMaxTextLen)
401 {
402 aColWidthParam[nCol].mnMaxTextLen = aStrData.mnStrLength;
403 aColWidthParam[nCol].mnMaxTextRow = nRow;
404 }
405
406 if (!aStrData.mbSimpleText)
407 {
408 bSimpleRow = false;
409 aColWidthParam[nCol].mbSimpleText = false;
410 }
411
412 ++nCol;
413 }
414 if (!bSimpleRow)
415 rRowHeightsRecalc.setTrue(nRow, nRow);
416 ++nRow;
417 }
418 else // past the end of the spreadsheet
419 {
420 bEnd = true; // don't continue
421 nErr = SCWARN_IMPORT_RANGE_OVERFLOW; // warning message
422 }
423 }
424 }
425 catch ( sdbc::SQLException& )
426 {
428 }
429 catch ( uno::Exception& )
430 {
431 TOOLS_WARN_EXCEPTION( "sc", "Unexpected exception in database");
432 nErr = ERRCODE_IO_GENERAL;
433 }
434
435 return nErr;
436#endif // HAVE_FEATURE_DBCONNECTIVITY
437}
438
439#if HAVE_FEATURE_DBCONNECTIVITY
440
441namespace {
442
443void lcl_GetColumnTypes(
444 ScDocShell& rDocShell, const ScRange& rDataRange, bool bHasFieldNames,
445 OUString* pColNames, sal_Int32* pColTypes, sal_Int32* pColLengths,
446 sal_Int32* pColScales, bool& bHasMemo, rtl_TextEncoding eCharSet )
447{
448 ScDocument& rDoc = rDocShell.GetDocument();
449 SvNumberFormatter* pNumFmt = rDoc.GetFormatTable();
450
451 SCTAB nTab = rDataRange.aStart.Tab();
452 SCCOL nFirstCol = rDataRange.aStart.Col();
453 SCROW nFirstRow = rDataRange.aStart.Row();
454 SCCOL nLastCol = rDataRange.aEnd.Col();
455 SCROW nLastRow = rDataRange.aEnd.Row();
456
457 typedef std::unordered_set<OUString> StrSetType;
458 StrSetType aFieldNames;
459
460 tools::Long nField = 0;
461 SCROW nFirstDataRow = ( bHasFieldNames ? nFirstRow + 1 : nFirstRow );
462 for ( SCCOL nCol = nFirstCol; nCol <= nLastCol; nCol++ )
463 {
464 bool bTypeDefined = false;
465 bool bPrecDefined = false;
466 sal_Int32 nFieldLen = 0;
467 sal_Int32 nPrecision = 0;
468 sal_Int32 nDbType = sdbc::DataType::SQLNULL;
469 OUString aFieldName;
470
471 // Fieldname[,Type[,Width[,Prec]]]
472 // Type etc.: L; D; C[,W]; N[,W[,P]]
473 if ( bHasFieldNames )
474 {
475 OUString aString {rDoc.GetString(nCol, nFirstRow, nTab).toAsciiUpperCase()};
476 sal_Int32 nIdx {0};
477 aFieldName = aString.getToken( 0, ',', nIdx);
478 if ( nIdx>0 )
479 {
480 aString = aString.replaceAll(" ", "");
481 switch ( o3tl::getToken(aString, 0, ',', nIdx )[0] )
482 {
483 case 'L' :
484 nDbType = sdbc::DataType::BIT;
485 nFieldLen = 1;
486 bTypeDefined = true;
487 bPrecDefined = true;
488 break;
489 case 'D' :
490 nDbType = sdbc::DataType::DATE;
491 nFieldLen = 8;
492 bTypeDefined = true;
493 bPrecDefined = true;
494 break;
495 case 'M' :
496 nDbType = sdbc::DataType::LONGVARCHAR;
497 nFieldLen = 10;
498 bTypeDefined = true;
499 bPrecDefined = true;
500 bHasMemo = true;
501 break;
502 case 'C' :
503 nDbType = sdbc::DataType::VARCHAR;
504 bTypeDefined = true;
505 bPrecDefined = true;
506 break;
507 case 'N' :
508 nDbType = sdbc::DataType::DECIMAL;
509 bTypeDefined = true;
510 break;
511 }
512 if ( bTypeDefined && !nFieldLen && nIdx>0 )
513 {
514 nFieldLen = o3tl::toInt32(o3tl::getToken(aString, 0, ',', nIdx ));
515 if ( !bPrecDefined && nIdx>0 )
516 {
517 OUString aTmp( aString.getToken( 0, ',', nIdx ) );
518 if ( CharClass::isAsciiNumeric(aTmp) )
519 {
520 nPrecision = aTmp.toInt32();
521 if (nPrecision && nFieldLen < nPrecision+1)
522 nFieldLen = nPrecision + 1; // include decimal separator
523 bPrecDefined = true;
524 }
525 }
526 }
527 }
528
529 // Check field name and generate valid field name if necessary.
530 // First character has to be alphabetical, subsequent characters
531 // have to be alphanumerical or underscore.
532 // "_DBASELOCK" is reserved (obsolete because first character is
533 // not alphabetical).
534 // No duplicated names.
535 if ( !rtl::isAsciiAlpha(aFieldName[0]) )
536 aFieldName = "N" + aFieldName;
537 OUStringBuffer aTmpStr;
538 sal_Unicode c;
539 for ( const sal_Unicode* p = aFieldName.getStr(); ( c = *p ) != 0; p++ )
540 {
541 if ( rtl::isAsciiAlpha(c) || rtl::isAsciiDigit(c) || c == '_' )
542 aTmpStr.append(c);
543 else
544 aTmpStr.append("_");
545 }
546 aFieldName = aTmpStr.makeStringAndClear();
547 if ( aFieldName.getLength() > 10 )
548 aFieldName = aFieldName.copy(0, 10);
549
550 if (!aFieldNames.insert(aFieldName).second)
551 { // Duplicated field name, append numeric suffix.
552 sal_uInt16 nSub = 1;
553 OUString aFixPart( aFieldName );
554 do
555 {
556 ++nSub;
557 OUString aVarPart = OUString::number( nSub );
558 if ( aFixPart.getLength() + aVarPart.getLength() > 10 )
559 aFixPart = aFixPart.copy( 0, 10 - aVarPart.getLength() );
560 aFieldName = aFixPart + aVarPart;
561 } while (!aFieldNames.insert(aFieldName).second);
562 }
563 }
564 else
565 {
566 aFieldName = "N" + OUString::number(nCol+1);
567 }
568
569 if ( !bTypeDefined )
570 { // Field type.
571 ScRefCellValue aCell(rDoc, ScAddress(nCol, nFirstDataRow, nTab));
572 if (aCell.isEmpty() || aCell.hasString())
573 nDbType = sdbc::DataType::VARCHAR;
574 else
575 {
576 sal_uInt32 nFormat = rDoc.GetNumberFormat( nCol, nFirstDataRow, nTab );
577 switch ( pNumFmt->GetType( nFormat ) )
578 {
579 case SvNumFormatType::LOGICAL :
580 nDbType = sdbc::DataType::BIT;
581 nFieldLen = 1;
582 break;
583 case SvNumFormatType::DATE :
584 nDbType = sdbc::DataType::DATE;
585 nFieldLen = 8;
586 break;
587 case SvNumFormatType::TIME :
588 case SvNumFormatType::DATETIME :
589 nDbType = sdbc::DataType::VARCHAR;
590 break;
591 default:
592 nDbType = sdbc::DataType::DECIMAL;
593 }
594 }
595 }
596 // Field length.
597 if ( nDbType == sdbc::DataType::VARCHAR && !nFieldLen )
598 { // Determine maximum field width.
599 nFieldLen = rDoc.GetMaxStringLen( nTab, nCol, nFirstDataRow,
600 nLastRow, eCharSet );
601 if ( nFieldLen == 0 )
602 nFieldLen = 1;
603 }
604 else if ( nDbType == sdbc::DataType::DECIMAL )
605 { // Determine maximum field width and precision.
606 sal_Int32 nLen;
607 sal_uInt16 nPrec;
608 nLen = rDoc.GetMaxNumberStringLen( nPrec, nTab, nCol,
609 nFirstDataRow, nLastRow );
610 // dBaseIII precision limit: 15
611 if ( nPrecision > 15 )
612 nPrecision = 15;
613 if ( nPrec > 15 )
614 nPrec = 15;
615 if ( bPrecDefined && nPrecision != nPrec )
616 {
617 if (nPrecision < nPrec)
618 {
619 // This is a hairy case. User defined nPrecision but a
620 // number format has more precision. Modifying a dBase
621 // field may as well render the resulting file useless for
622 // an application that relies on its defined structure,
623 // especially if we are resaving an already existing file.
624 // So who's right, the user who (or the loaded file that)
625 // defined the field, or the user who applied the format?
626 // Commit f59e350d1733125055f1144f8b3b1b0a46f6d1ca gave the
627 // format a higher priority, which is debatable.
628 SAL_WARN( "sc", "lcl_GetColumnTypes: conflicting dBase field precision for "
629 << aFieldName << " (" << nPrecision << "<" << nPrec << ")");
630
631 // Adjust length to larger predefined integer part. There
632 // may be a reason that the field was prepared for larger
633 // numbers.
634 if (nFieldLen - nPrecision > nLen - nPrec)
635 nLen = nFieldLen - (nPrecision ? nPrecision+1 : 0) + 1 + nPrec;
636 // And override precision.
637 nPrecision = nPrec;
638 }
639 else
640 {
641#if 1
642 // Adjust length to predefined precision.
643 nLen = nLen + ( nPrecision - nPrec );
644#else
645 /* If the above override for (nPrecision < nPrec) was not in place then
646 * nPrecision could be 0 and this would be the code path to correctly
647 * calculate nLen. But as is, nPrecision is never 0 here, see CID#982304 */
648
649 // Adjust length to predefined precision.
650 if ( nPrecision )
651 nLen = nLen + ( nPrecision - nPrec );
652 else
653 nLen -= nPrec+1; // also remove the decimal separator
654#endif
655 }
656 }
657 if (nFieldLen < nLen)
658 {
659 if (!bTypeDefined)
660 nFieldLen = nLen;
661 else
662 {
663 // Again a hairy case and conflict. Furthermore, the
664 // larger overall length may be a result of only a higher
665 // precision obtained from formats.
666 SAL_WARN( "sc", "lcl_GetColumnTypes: conflicting dBase field length for "
667 << aFieldName << " (" << nFieldLen << "<" << nLen << ")");
668 nFieldLen = nLen;
669 }
670 }
671 if ( !bPrecDefined )
672 nPrecision = nPrec;
673 if ( nFieldLen == 0 )
674 nFieldLen = 1;
675 else if ( nFieldLen > 19 )
676 nFieldLen = 19; // dBaseIII numeric field length limit: 19
677 if ( nPrecision && nFieldLen < nPrecision + 2 )
678 nFieldLen = nPrecision + 2; // 0. must fit into
679 // 538 MUST: Sdb internal representation adds 2 to the field length!
680 // To give the user what he wants we must subtract it here.
683 nFieldLen = SvDbaseConverter::ConvertPrecisionToOdbc( nFieldLen, nPrecision );
684 }
685 if ( nFieldLen > 254 )
686 {
687 if ( nDbType == sdbc::DataType::VARCHAR )
688 { // Too long for a normal text field => memo field.
689 nDbType = sdbc::DataType::LONGVARCHAR;
690 nFieldLen = 10;
691 bHasMemo = true;
692 }
693 else
694 nFieldLen = 254; // bad luck...
695 }
696
697 pColNames[nField] = aFieldName;
698 pColTypes[nField] = nDbType;
699 pColLengths[nField] = nFieldLen;
700 pColScales[nField] = nPrecision;
701
702 ++nField;
703 }
704}
705
706void lcl_getLongVarCharEditString( OUString& rString,
707 const ScRefCellValue& rCell, ScFieldEditEngine& rEditEngine )
708{
709 if (!rCell.getEditText())
710 return;
711
712 rEditEngine.SetTextCurrentDefaults(*rCell.getEditText());
713 rString = rEditEngine.GetText( LINEEND_CRLF );
714}
715
716void lcl_getLongVarCharString(
717 OUString& rString, ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, SvNumberFormatter& rNumFmt )
718{
719 const Color* pColor;
720 ScAddress aPos(nCol, nRow, nTab);
721 sal_uInt32 nFormat = rDoc.GetNumberFormat(aPos);
722 rString = ScCellFormat::GetString(rDoc, aPos, nFormat, &pColor, rNumFmt);
723}
724
725}
726
727#endif // HAVE_FEATURE_DBCONNECTIVITY
728
729ErrCode ScDocShell::DBaseExport( const OUString& rFullFileName, rtl_TextEncoding eCharSet, bool& bHasMemo )
730{
731#if !HAVE_FEATURE_DBCONNECTIVITY
732 (void) rFullFileName;
733 (void) eCharSet;
734 (void) bHasMemo;
735
736 return ERRCODE_IO_GENERAL;
737#else
738 // remove the file so the dBase driver doesn't find an invalid file
739 INetURLObject aDeleteObj( rFullFileName, INetProtocol::File );
740 KillFile( aDeleteObj );
741
742 ErrCode nErr = ERRCODE_NONE;
743
744 SCCOL nFirstCol, nLastCol;
745 SCROW nFirstRow, nLastRow;
746 SCTAB nTab = GetSaveTab();
747 m_pDocument->GetDataStart( nTab, nFirstCol, nFirstRow );
748 m_pDocument->GetCellArea( nTab, nLastCol, nLastRow );
749 if ( nFirstCol > nLastCol )
750 nFirstCol = nLastCol;
751 if ( nFirstRow > nLastRow )
752 nFirstRow = nLastRow;
753 ScProgress aProgress( this, ScResId( STR_SAVE_DOC ),
754 nLastRow - nFirstRow, true );
755 SvNumberFormatter* pNumFmt = m_pDocument->GetFormatTable();
756
757 bool bHasFieldNames = true;
758 for ( SCCOL nDocCol = nFirstCol; nDocCol <= nLastCol && bHasFieldNames; nDocCol++ )
759 { // only Strings in first row => are field names
760 if ( !m_pDocument->HasStringData( nDocCol, nFirstRow, nTab ) )
761 bHasFieldNames = false;
762 }
763
764 sal_Int32 nColCount = nLastCol - nFirstCol + 1;
765 uno::Sequence<OUString> aColNames( nColCount );
766 uno::Sequence<sal_Int32> aColTypes( nColCount );
767 uno::Sequence<sal_Int32> aColLengths( nColCount );
768 uno::Sequence<sal_Int32> aColScales( nColCount );
769
770 ScRange aDataRange( nFirstCol, nFirstRow, nTab, nLastCol, nLastRow, nTab );
771 lcl_GetColumnTypes( *this, aDataRange, bHasFieldNames,
772 aColNames.getArray(), aColTypes.getArray(),
773 aColLengths.getArray(), aColScales.getArray(),
774 bHasMemo, eCharSet );
775 // also needed for exception catch
776 SCROW nDocRow = 0;
777 ScFieldEditEngine aEditEngine(m_pDocument.get(), m_pDocument->GetEditPool());
778 OUString aString;
779
780 try
781 {
782 uno::Reference<sdbc::XDriverManager2> xDrvMan;
783 uno::Reference<sdbc::XConnection> xConnection;
784 OUString aTabName;
785 ErrCode nRet = lcl_getDBaseConnection(xDrvMan,xConnection,aTabName,rFullFileName,eCharSet);
786 if ( !xConnection.is() || !xDrvMan.is() )
787 return nRet;
788 ::utl::DisposableComponent aConnectionHelper(xConnection);
789
790 // get dBase driver
791 uno::Reference< sdbcx::XDataDefinitionSupplier > xDDSup( xDrvMan->getDriverByURL( xConnection->getMetaData()->getURL() ), uno::UNO_QUERY );
792 if ( !xDDSup.is() )
794
795 // create table
796 uno::Reference<sdbcx::XTablesSupplier> xTablesSupp =xDDSup->getDataDefinitionByConnection( xConnection );
797 OSL_ENSURE( xTablesSupp.is(), "can't get Data Definition" );
798 if (!xTablesSupp.is()) return SCERR_EXPORT_CONNECT;
799
800 uno::Reference<container::XNameAccess> xTables = xTablesSupp->getTables();
801 OSL_ENSURE( xTables.is(), "can't get Tables" );
802 if (!xTables.is()) return SCERR_EXPORT_CONNECT;
803
804 uno::Reference<sdbcx::XDataDescriptorFactory> xTablesFact( xTables, uno::UNO_QUERY );
805 OSL_ENSURE( xTablesFact.is(), "can't get tables factory" );
806 if (!xTablesFact.is()) return SCERR_EXPORT_CONNECT;
807
808 uno::Reference<sdbcx::XAppend> xTablesAppend( xTables, uno::UNO_QUERY );
809 OSL_ENSURE( xTablesAppend.is(), "can't get tables XAppend" );
810 if (!xTablesAppend.is()) return SCERR_EXPORT_CONNECT;
811
812 uno::Reference<beans::XPropertySet> xTableDesc = xTablesFact->createDataDescriptor();
813 OSL_ENSURE( xTableDesc.is(), "can't get table descriptor" );
814 if (!xTableDesc.is()) return SCERR_EXPORT_CONNECT;
815
816 xTableDesc->setPropertyValue( SC_DBPROP_NAME, uno::Any(aTabName) );
817
818 // create columns
819
820 uno::Reference<sdbcx::XColumnsSupplier> xColumnsSupp( xTableDesc, uno::UNO_QUERY );
821 OSL_ENSURE( xColumnsSupp.is(), "can't get columns supplier" );
822 if (!xColumnsSupp.is()) return SCERR_EXPORT_CONNECT;
823
824 uno::Reference<container::XNameAccess> xColumns = xColumnsSupp->getColumns();
825 OSL_ENSURE( xColumns.is(), "can't get columns" );
826 if (!xColumns.is()) return SCERR_EXPORT_CONNECT;
827
828 uno::Reference<sdbcx::XDataDescriptorFactory> xColumnsFact( xColumns, uno::UNO_QUERY );
829 OSL_ENSURE( xColumnsFact.is(), "can't get columns factory" );
830 if (!xColumnsFact.is()) return SCERR_EXPORT_CONNECT;
831
832 uno::Reference<sdbcx::XAppend> xColumnsAppend( xColumns, uno::UNO_QUERY );
833 OSL_ENSURE( xColumnsAppend.is(), "can't get columns XAppend" );
834 if (!xColumnsAppend.is()) return SCERR_EXPORT_CONNECT;
835
836 const OUString* pColNames = aColNames.getConstArray();
837 const sal_Int32* pColTypes = aColTypes.getConstArray();
838 const sal_Int32* pColLengths = aColLengths.getConstArray();
839 const sal_Int32* pColScales = aColScales.getConstArray();
840 sal_Int32 nCol;
841
842 for (nCol=0; nCol<nColCount; nCol++)
843 {
844 uno::Reference<beans::XPropertySet> xColumnDesc = xColumnsFact->createDataDescriptor();
845 OSL_ENSURE( xColumnDesc.is(), "can't get column descriptor" );
846 if (!xColumnDesc.is()) return SCERR_EXPORT_CONNECT;
847
848 xColumnDesc->setPropertyValue( SC_DBPROP_NAME, uno::Any(pColNames[nCol]) );
849
850 xColumnDesc->setPropertyValue( SC_DBPROP_TYPE, uno::Any(pColTypes[nCol]) );
851
852 xColumnDesc->setPropertyValue( SC_DBPROP_PRECISION, uno::Any(pColLengths[nCol]) );
853
854 xColumnDesc->setPropertyValue( SC_DBPROP_SCALE, uno::Any(pColScales[nCol]) );
855
856 xColumnsAppend->appendByDescriptor( xColumnDesc );
857 }
858
859 xTablesAppend->appendByDescriptor( xTableDesc );
860
861 // get row set for writing
862 uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory();
863 uno::Reference<sdbc::XRowSet> xRowSet( xFactory->createInstance(SC_SERVICE_ROWSET),
864 uno::UNO_QUERY);
865 ::utl::DisposableComponent aRowSetHelper(xRowSet);
866 uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
867 OSL_ENSURE( xRowProp.is(), "can't get RowSet" );
868 if (!xRowProp.is()) return SCERR_EXPORT_CONNECT;
869
870 xRowProp->setPropertyValue( SC_DBPROP_ACTIVECONNECTION, uno::Any(xConnection) );
871
872 xRowProp->setPropertyValue( SC_DBPROP_COMMANDTYPE, uno::Any(sal_Int32(sdb::CommandType::TABLE)) );
873
874 xRowProp->setPropertyValue( SC_DBPROP_COMMAND, uno::Any(aTabName) );
875
876 xRowSet->execute();
877
878 // write data rows
879
880 uno::Reference<sdbc::XResultSetUpdate> xResultUpdate( xRowSet, uno::UNO_QUERY );
881 OSL_ENSURE( xResultUpdate.is(), "can't get XResultSetUpdate" );
882 if (!xResultUpdate.is()) return SCERR_EXPORT_CONNECT;
883
884 uno::Reference<sdbc::XRowUpdate> xRowUpdate( xRowSet, uno::UNO_QUERY );
885 OSL_ENSURE( xRowUpdate.is(), "can't get XRowUpdate" );
886 if (!xRowUpdate.is()) return SCERR_EXPORT_CONNECT;
887
888 SCROW nFirstDataRow = ( bHasFieldNames ? nFirstRow + 1 : nFirstRow );
889 double fVal;
890
891 for ( nDocRow = nFirstDataRow; nDocRow <= nLastRow; nDocRow++ )
892 {
893 xResultUpdate->moveToInsertRow();
894
895 for (nCol=0; nCol<nColCount; nCol++)
896 {
897 SCCOL nDocCol = sal::static_int_cast<SCCOL>( nFirstCol + nCol );
898
899 switch (pColTypes[nCol])
900 {
901 case sdbc::DataType::LONGVARCHAR:
902 {
903 ScRefCellValue aCell(*m_pDocument, ScAddress(nDocCol, nDocRow, nTab));
904 if (!aCell.isEmpty())
905 {
906 if (aCell.getType() == CELLTYPE_EDIT)
907 { // preserve paragraphs
908 lcl_getLongVarCharEditString(aString, aCell, aEditEngine);
909 }
910 else
911 {
912 lcl_getLongVarCharString(
913 aString, *m_pDocument, nDocCol, nDocRow, nTab, *pNumFmt);
914 }
915 xRowUpdate->updateString( nCol+1, aString );
916 }
917 else
918 xRowUpdate->updateNull( nCol+1 );
919 }
920 break;
921
922 case sdbc::DataType::VARCHAR:
923 aString = m_pDocument->GetString(nDocCol, nDocRow, nTab);
924 xRowUpdate->updateString( nCol+1, aString );
925 if ( nErr == ERRCODE_NONE && pColLengths[nCol] < aString.getLength() )
927 break;
928
930 {
931 fVal = m_pDocument->GetValue( nDocCol, nDocRow, nTab );
932 // differentiate between 0 with value and 0 no-value
933 bool bIsNull = (fVal == 0.0);
934 if ( bIsNull )
935 bIsNull = !m_pDocument->HasValueData( nDocCol, nDocRow, nTab );
936 if ( bIsNull )
937 {
938 xRowUpdate->updateNull( nCol+1 );
939 if ( nErr == ERRCODE_NONE &&
940 m_pDocument->HasStringData( nDocCol, nDocRow, nTab ) )
942 }
943 else
944 {
945 Date aDate = pNumFmt->GetNullDate(); // tools date
946 aDate.AddDays(fVal);
947 xRowUpdate->updateDate( nCol+1, aDate.GetUNODate() );
948 }
949 }
950 break;
951
952 case sdbc::DataType::DECIMAL:
953 case sdbc::DataType::BIT:
954 fVal = m_pDocument->GetValue( nDocCol, nDocRow, nTab );
955 if ( fVal == 0.0 && nErr == ERRCODE_NONE &&
956 m_pDocument->HasStringData( nDocCol, nDocRow, nTab ) )
958 if ( pColTypes[nCol] == sdbc::DataType::BIT )
959 xRowUpdate->updateBoolean( nCol+1, ( fVal != 0.0 ) );
960 else
961 xRowUpdate->updateDouble( nCol+1, fVal );
962 break;
963
964 default:
965 OSL_FAIL( "ScDocShell::DBaseExport: unknown FieldType" );
966 if ( nErr == ERRCODE_NONE )
968 fVal = m_pDocument->GetValue( nDocCol, nDocRow, nTab );
969 xRowUpdate->updateDouble( nCol+1, fVal );
970 }
971 }
972
973 xResultUpdate->insertRow();
974
977
978 aProgress.SetStateOnPercent( nDocRow - nFirstRow );
979 }
980
982 comphelper::disposeComponent( xConnection );
983 }
984 catch ( const sdbc::SQLException& aException )
985 {
986 sal_Int32 nError = aException.ErrorCode;
987 TOOLS_WARN_EXCEPTION("sc", "ScDocShell::DBaseExport");
988
989 if (nError == 22018 || nError == 22001)
990 {
991 // SQL error 22018: Character not in target encoding.
992 // SQL error 22001: String length exceeds field width (after encoding).
993 bool bEncErr = (nError == 22018);
994 bool bIsOctetTextEncoding = rtl_isOctetTextEncoding( eCharSet);
995 OSL_ENSURE( !bEncErr || bIsOctetTextEncoding, "ScDocShell::DBaseExport: encoding error and not an octet textencoding");
996 SCCOL nDocCol = nFirstCol;
997 const sal_Int32* pColTypes = aColTypes.getConstArray();
998 const sal_Int32* pColLengths = aColLengths.getConstArray();
999 ScHorizontalCellIterator aIter( *m_pDocument, nTab, nFirstCol,
1000 nDocRow, nLastCol, nDocRow);
1001 bool bTest = true;
1002 while (bTest)
1003 {
1004 ScRefCellValue* pCell = aIter.GetNext( nDocCol, nDocRow);
1005 if (!pCell)
1006 break;
1007 SCCOL nCol = nDocCol - nFirstCol;
1008 switch (pColTypes[nCol])
1009 {
1010 case sdbc::DataType::LONGVARCHAR:
1011 {
1012 if (pCell->getType() == CELLTYPE_EDIT)
1013 lcl_getLongVarCharEditString(aString, *pCell, aEditEngine);
1014 else
1015 lcl_getLongVarCharString(
1016 aString, *m_pDocument, nDocCol, nDocRow, nTab, *pNumFmt);
1017 }
1018 break;
1019
1020 case sdbc::DataType::VARCHAR:
1021 aString = m_pDocument->GetString(nDocCol, nDocRow, nTab);
1022 break;
1023
1024 // NOTE: length of DECIMAL fields doesn't need to be
1025 // checked here, the database driver adjusts the field
1026 // width accordingly.
1027
1028 default:
1029 bTest = false;
1030 }
1031 if (bTest)
1032 {
1033 sal_Int32 nLen;
1034 if (bIsOctetTextEncoding)
1035 {
1036 OString aOString;
1037 if (!aString.convertToString( &aOString, eCharSet,
1038 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1039 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
1040 {
1041 bTest = false;
1042 bEncErr = true;
1043 }
1044 nLen = aOString.getLength();
1045 if (!bTest)
1046 SAL_WARN("sc", "ScDocShell::DBaseExport encoding error, string with default replacements: ``" << aString << "''");
1047 }
1048 else
1049 nLen = aString.getLength() * sizeof(sal_Unicode);
1050 if (!bEncErr &&
1051 pColTypes[nCol] != sdbc::DataType::LONGVARCHAR &&
1052 pColLengths[nCol] < nLen)
1053 {
1054 bTest = false;
1055 SAL_INFO("sc", "ScDocShell::DBaseExport: field width: " << pColLengths[nCol] << ", encoded length: " << nLen);
1056 }
1057 }
1058 else
1059 bTest = true;
1060 }
1061 OUString sPosition(ScAddress(nDocCol, nDocRow, nTab).GetColRowString());
1062 OUString sEncoding(SvxTextEncodingTable::GetTextString(eCharSet));
1063 nErr = *new TwoStringErrorInfo( (bEncErr ? SCERR_EXPORT_ENCODING :
1064 SCERR_EXPORT_FIELDWIDTH), sPosition, sEncoding,
1065 DialogMask::ButtonsOk | DialogMask::MessageError);
1066 }
1067 else if ( !aException.Message.isEmpty() )
1068 nErr = *new StringErrorInfo( SCERR_EXPORT_SQLEXCEPTION, aException.Message, DialogMask::ButtonsOk | DialogMask::MessageError);
1069 else
1070 nErr = SCERR_EXPORT_DATA;
1071 }
1072 catch ( uno::Exception& )
1073 {
1074 TOOLS_WARN_EXCEPTION( "sc", "Unexpected exception in database");
1075 nErr = ERRCODE_IO_GENERAL;
1076 }
1077
1078 return nErr;
1079#endif // HAVE_FEATURE_DBCONNECTIVITY
1080}
1081
1082/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const char *const aFieldNames[]
static bool isAsciiNumeric(std::u16string_view rStr)
css::util::Date GetUNODate() const
void AddDays(sal_Int32 nAddDays)
OUString GetText(LineEnd eEnd=LINEEND_LF) const
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool removeSegment(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true)
bool setFinalSlash()
INetProtocol GetProtocol() const
SCTAB Tab() const
Definition: address.hxx:283
SCROW Row() const
Definition: address.hxx:274
SCCOL Col() const
Definition: address.hxx:279
static OUString GetString(const ScRefCellValue &rCell, sal_uInt32 nFormat, const Color **ppColor, SvNumberFormatter &rFormatter, const ScDocument &rDoc, bool bNullVals=true, bool bFormula=false, bool bUseStarFormat=false)
Definition: cellform.cxx:31
static void PutData(ScDocument &rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const css::uno::Reference< css::sdbc::XRow > &xRow, sal_Int32 nRowPos, tools::Long nType, bool bCurrency, StrData *pStrData=nullptr)
Definition: dbdocutl.cxx:38
static SAL_DLLPRIVATE bool KillFile(const INetURLObject &rURL)
Definition: docsh8.cxx:186
SAL_DLLPRIVATE SCTAB GetSaveTab()
Definition: docsh.cxx:254
const ScDocument & GetDocument() const
Definition: docsh.hxx:219
std::shared_ptr< ScDocument > m_pDocument
Definition: docsh.hxx:82
static SAL_DLLPRIVATE bool MoveFile(const INetURLObject &rSource, const INetURLObject &rDest)
Definition: docsh8.cxx:142
SAL_DLLPRIVATE ErrCode DBaseExport(const OUString &rFullFileName, rtl_TextEncoding eCharSet, bool &bHasMemo)
Definition: docsh8.cxx:729
SAL_DLLPRIVATE ErrCode DBaseImport(const OUString &rFullFileName, rtl_TextEncoding eCharSet, std::map< SCCOL, ScColWidthParam > &aColWidthParam, ScFlatBoolRowSegments &rRowHeightsRecalc)
Definition: docsh8.cxx:273
static SAL_DLLPRIVATE bool IsDocument(const INetURLObject &rURL)
Definition: docsh8.cxx:205
sal_Int32 GetMaxNumberStringLen(sal_uInt16 &nPrecision, SCTAB nTab, SCCOL nCol, SCROW nRowStart, SCROW nRowEnd) const
Maximum string length of numerical cells of a column, e.g.
Definition: documen4.cxx:594
SC_DLLPUBLIC sal_uInt32 GetNumberFormat(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3640
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6050
SC_DLLPUBLIC void ApplyPatternAreaTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScPatternAttr &rAttr)
Definition: document.cxx:4770
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
sal_Int32 GetMaxStringLen(SCTAB nTab, SCCOL nCol, SCROW nRowStart, SCROW nRowEnd, rtl_TextEncoding eCharSet) const
Maximum string length of a column, e.g.
Definition: documen4.cxx:586
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:467
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
Definition: document.cxx:3505
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:619
bool setTrue(SCROW nRow1, SCROW nRow2)
ScRefCellValue * GetNext(SCCOL &rCol, SCROW &rRow)
Definition: dociter.cxx:1096
void SetState(sal_uInt64 nVal, sal_uInt64 nNewRange=0)
Definition: progress.hxx:78
void SetStateOnPercent(sal_uInt64 nVal)
Definition: progress.hxx:96
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
static SVL_DLLPUBLIC sal_Int32 ConvertPrecisionToOdbc(sal_Int32 _nLen, sal_Int32 _nScale)
static SVL_DLLPUBLIC sal_Int32 ConvertPrecisionToDbase(sal_Int32 _nLen, sal_Int32 _nScale)
bool PutEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge=LANGUAGE_DONTKNOW, bool bReplaceBooleanEquivalent=true)
OUString GenerateFormat(sal_uInt32 nIndex, LanguageType eLnge=LANGUAGE_DONTKNOW, bool bThousand=false, bool IsRed=false, sal_uInt16 nPrecision=0, sal_uInt16 nLeadingCnt=1)
sal_uInt32 GetEntryKey(std::u16string_view sStr, LanguageType eLnge=LANGUAGE_DONTKNOW)
const Date & GetNullDate() const
SvNumFormatType GetType(sal_uInt32 nFIndex) const
const SvNumberformat * GetEntry(sal_uInt32 nKey) const
LanguageType GetLanguage() const
void GetFormatSpecialInfo(bool &bThousand, bool &IsRed, sal_uInt16 &nPrecision, sal_uInt16 &nLeadingCnt) const
static OUString GetTextString(const rtl_TextEncoding nEnc)
css::uno::Any executeCommand(const OUString &rCommandName, const css::uno::Any &rCommandArgument)
css::uno::Reference< css::ucb::XCommandInfo > getCommands()
#define TOOLS_WARN_EXCEPTION(area, stream)
URL aURL
constexpr OUStringLiteral SC_DBPROP_COMMAND
Definition: dpobject.cxx:101
constexpr OUStringLiteral SC_SERVICE_ROWSET
Definition: dpobject.cxx:98
constexpr OUStringLiteral SC_DBPROP_COMMANDTYPE
Definition: dpobject.cxx:102
float u
#define ERRCODE_IO_GENERAL
#define ERRCODE_NONE
Reference< XSingleServiceFactory > xFactory
@ CELLTYPE_EDIT
Definition: global.hxx:277
OUString aName
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
void disposeComponent(css::uno::Reference< TYPE > &_rxComp)
Reference< XMultiServiceFactory > getProcessServiceFactory()
Reference< XComponentContext > getProcessComponentContext()
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
int i
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
long Long
const Color aColNames[SC_RANGECOLORS]
Definition: rfindlst.cxx:26
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
#define SCERR_EXPORT_FIELDWIDTH
Definition: scerrors.hxx:55
#define SCERR_EXPORT_ENCODING
Definition: scerrors.hxx:54
#define SCWARN_IMPORT_RANGE_OVERFLOW
Definition: scerrors.hxx:61
#define SCWARN_EXPORT_DATALOST
Definition: scerrors.hxx:75
#define SCERR_EXPORT_DATA
Definition: scerrors.hxx:53
#define SCWARN_IMPORT_COLUMN_OVERFLOW
Definition: scerrors.hxx:63
#define SCERR_IMPORT_CONNECT
Definition: scerrors.hxx:25
#define SCERR_EXPORT_SQLEXCEPTION
Definition: scerrors.hxx:56
#define SCERR_EXPORT_CONNECT
Definition: scerrors.hxx:52
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALUE_FORMAT(146)
static SfxItemSet & rSet
Detailed information on single string value.
Definition: dbdocutl.hxx:37
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:108
const EditTextObject * getEditText() const
Definition: cellvalue.hxx:136
bool isEmpty() const
Definition: cellvalue.cxx:667
CellType getType() const
Definition: cellvalue.hxx:133
sal_uInt16 sal_Unicode
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
@ TABLE
Definition: xmldpimp.hxx:43
SvNumFormatType