Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/fields/dbfld.cxx
Warning:line 254, column 5
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name dbfld.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/core/fields/dbfld.cxx
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 <float.h>
21#include <o3tl/any.hxx>
22#include <osl/diagnose.h>
23#include <svl/zforlist.hxx>
24#include <com/sun/star/sdbc/DataType.hpp>
25#include <fmtfld.hxx>
26#include <txtfld.hxx>
27#include <calc.hxx>
28#include <doc.hxx>
29#include <IDocumentFieldsAccess.hxx>
30#include <docary.hxx>
31#include <fldbas.hxx>
32#include <ndtxt.hxx>
33#include <dbfld.hxx>
34#include <dbmgr.hxx>
35#include <unofldmid.h>
36#include <calbck.hxx>
37
38using namespace ::com::sun::star::sdbc;
39using namespace ::com::sun::star;
40
41/// replace database separator by dots for display
42static OUString lcl_DBSeparatorConvert(const OUString& aContent)
43{
44 return aContent.replaceAll(OUStringChar(DB_DELIMu'\x00ff'), ".");
45}
46
47// database field type
48
49SwDBFieldType::SwDBFieldType(SwDoc* pDocPtr, const OUString& rNam, const SwDBData& rDBData ) :
50 SwValueFieldType( pDocPtr, SwFieldIds::Database ),
51 m_aDBData(rDBData),
52 m_sName(rNam),
53 m_sColumn(rNam),
54 m_nRefCnt(0)
55{
56 if(!m_aDBData.sDataSource.isEmpty() || !m_aDBData.sCommand.isEmpty())
57 {
58 m_sName = m_aDBData.sDataSource
59 + OUStringChar(DB_DELIMu'\x00ff')
60 + m_aDBData.sCommand
61 + OUStringChar(DB_DELIMu'\x00ff')
62 + m_sName;
63 }
64}
65
66SwDBFieldType::~SwDBFieldType()
67{
68}
69
70std::unique_ptr<SwFieldType> SwDBFieldType::Copy() const
71{
72 return std::make_unique<SwDBFieldType>(GetDoc(), m_sColumn, m_aDBData);
73}
74
75OUString SwDBFieldType::GetName() const
76{
77 return m_sName;
78}
79
80void SwDBFieldType::ReleaseRef()
81{
82 OSL_ENSURE(m_nRefCnt > 0, "RefCount < 0!")do { if (true && (!(m_nRefCnt > 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/fields/dbfld.cxx"
":" "82" ": "), "%s", "RefCount < 0!"); } } while (false)
;
2
Assuming field 'm_nRefCnt' is > 0
3
Taking false branch
4
Loop condition is false. Exiting loop
83
84 if (--m_nRefCnt > 0)
5
Assuming the condition is false
6
Taking false branch
85 return;
86
87 size_t nPos = 0;
88 for (auto const & pFieldType : *GetDoc()->getIDocumentFieldsAccess().GetFieldTypes())
89 {
90 if (pFieldType.get() == this)
91 break;
92 ++nPos;
93 }
94 if (nPos < GetDoc()->getIDocumentFieldsAccess().GetFieldTypes()->size())
7
Assuming the condition is true
8
Taking true branch
95 {
96 GetDoc()->getIDocumentFieldsAccess().RemoveFieldType(nPos);
97 delete this;
9
Memory is released
98 }
99}
100
101void SwDBFieldType::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
102{
103 switch( nWhichId )
104 {
105 case FIELD_PROP_PAR110:
106 rAny <<= m_aDBData.sDataSource;
107 break;
108 case FIELD_PROP_PAR211:
109 rAny <<= m_aDBData.sCommand;
110 break;
111 case FIELD_PROP_PAR312:
112 rAny <<= m_sColumn;
113 break;
114 case FIELD_PROP_SHORT124:
115 rAny <<= m_aDBData.nCommandType;
116 break;
117 default:
118 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/sw/source/core/fields/dbfld.cxx"
, 118, __extension__ __PRETTY_FUNCTION__))
;
119 }
120}
121
122void SwDBFieldType::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
123{
124 switch( nWhichId )
125 {
126 case FIELD_PROP_PAR110:
127 rAny >>= m_aDBData.sDataSource;
128 break;
129 case FIELD_PROP_PAR211:
130 rAny >>= m_aDBData.sCommand;
131 break;
132 case FIELD_PROP_PAR312:
133 {
134 OUString sTmp;
135 rAny >>= sTmp;
136 if( sTmp != m_sColumn )
137 {
138 m_sColumn = sTmp;
139 std::vector<SwFormatField*> vFields;
140 GatherFields(vFields);
141 for(auto pFormatField: vFields)
142 {
143 SwDBField* pDBField = static_cast<SwDBField*>(pFormatField->GetField());
144 pDBField->ClearInitialized();
145 pDBField->InitContent();
146 }
147 }
148 }
149 break;
150 case FIELD_PROP_SHORT124:
151 rAny >>= m_aDBData.nCommandType;
152 break;
153 default:
154 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/sw/source/core/fields/dbfld.cxx"
, 154, __extension__ __PRETTY_FUNCTION__))
;
155 }
156}
157
158// database field
159
160SwDBField::SwDBField(SwDBFieldType* pTyp, sal_uInt32 nFormat)
161 : SwValueField(pTyp, nFormat),
162 m_nSubType(0),
163 m_bIsInBodyText(true),
164 m_bValidValue(false),
165 m_bInitialized(false)
166{
167 if (GetTyp())
168 static_cast<SwDBFieldType*>(GetTyp())->AddRef();
169 InitContent();
170}
171
172SwDBField::~SwDBField()
173{
174 if (GetTyp())
175 static_cast<SwDBFieldType*>(GetTyp())->ReleaseRef();
176}
177
178void SwDBField::InitContent()
179{
180 if (!IsInitialized())
181 {
182 m_aContent = "<" + static_cast<const SwDBFieldType*>(GetTyp())->GetColumnName() + ">";
183 }
184}
185
186void SwDBField::InitContent(const OUString& rExpansion)
187{
188 if (rExpansion.startsWith("<") && rExpansion.endsWith(">"))
189 {
190 const OUString sColumn( rExpansion.copy( 1, rExpansion.getLength() - 2 ) );
191 if( ::GetAppCmpStrIgnore().isEqual( sColumn,
192 static_cast<SwDBFieldType *>(GetTyp())->GetColumnName() ))
193 {
194 InitContent();
195 return;
196 }
197 }
198 SetExpansion( rExpansion );
199}
200
201OUString SwDBField::ExpandImpl(SwRootFrame const*const) const
202{
203 if(0 ==(GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE))
204 return lcl_DBSeparatorConvert(m_aContent);
205 return OUString();
206}
207
208std::unique_ptr<SwField> SwDBField::Copy() const
209{
210 std::unique_ptr<SwDBField> pTmp(new SwDBField(static_cast<SwDBFieldType*>(GetTyp()), GetFormat()));
211 pTmp->m_aContent = m_aContent;
212 pTmp->m_bIsInBodyText = m_bIsInBodyText;
213 pTmp->m_bValidValue = m_bValidValue;
214 pTmp->m_bInitialized = m_bInitialized;
215 pTmp->m_nSubType = m_nSubType;
216 pTmp->SetValue(GetValue());
217 pTmp->m_sFieldCode = m_sFieldCode;
218
219 return std::unique_ptr<SwField>(pTmp.release());
220}
221
222OUString SwDBField::GetFieldName() const
223{
224 const OUString rDBName = static_cast<SwDBFieldType*>(GetTyp())->GetName();
225
226 OUString sContent( rDBName.getToken(0, DB_DELIMu'\x00ff') );
227
228 if (sContent.getLength() > 1)
229 {
230 sContent += OUStringChar(DB_DELIMu'\x00ff')
231 + rDBName.getToken(1, DB_DELIMu'\x00ff')
232 + OUStringChar(DB_DELIMu'\x00ff')
233 + rDBName.getToken(2, DB_DELIMu'\x00ff');
234 }
235 return lcl_DBSeparatorConvert(sContent);
236}
237
238void SwDBField::ChgValue( double d, bool bVal )
239{
240 m_bValidValue = bVal;
241 SetValue(d);
242
243 if( m_bValidValue )
244 m_aContent = static_cast<SwValueFieldType*>(GetTyp())->ExpandValue(d, GetFormat(), GetLanguage());
245}
246
247SwFieldType* SwDBField::ChgTyp( SwFieldType* pNewType )
248{
249 SwFieldType* pOld = SwValueField::ChgTyp( pNewType );
250
251 static_cast<SwDBFieldType*>(pNewType)->AddRef();
252 static_cast<SwDBFieldType*>(pOld)->ReleaseRef();
1
Calling 'SwDBFieldType::ReleaseRef'
10
Returning; memory was released
253
254 return pOld;
11
Use of memory after it is freed
255}
256
257bool SwDBField::FormatValue( SvNumberFormatter const * pDocFormatter, OUString const &aString, sal_uInt32 nFormat,
258 double &aNumber, sal_Int32 nColumnType, SwDBField *pField )
259{
260 bool bValidValue = false;
261
262 if( DBL_MAX1.7976931348623157e+308 != aNumber )
263 {
264 if( DataType::DATE == nColumnType || DataType::TIME == nColumnType ||
265 DataType::TIMESTAMP == nColumnType )
266 {
267 Date aStandard( 1, 1, 1900 );
268 if( pDocFormatter->GetNullDate() != aStandard )
269 aNumber += (aStandard - pDocFormatter->GetNullDate());
270 }
271 bValidValue = true;
272 if( pField )
273 pField->SetValue( aNumber );
274 }
275 else
276 {
277 SwSbxValue aVal;
278 aVal.PutString( aString );
279
280 if (aVal.IsNumeric())
281 {
282 if( pField )
283 pField->SetValue(aVal.GetDouble());
284 else
285 aNumber = aVal.GetDouble();
286
287 if (nFormat && nFormat != SAL_MAX_UINT32((sal_uInt32) 0xFFFFFFFF) && !pDocFormatter->IsTextFormat(nFormat))
288 bValidValue = true; // because of bug #60339 not for all strings
289 }
290 else
291 {
292 // if string length > 0 then true, else false
293 if( pField )
294 pField->SetValue(aString.isEmpty() ? 0 : 1);
295 else
296 aNumber = aString.isEmpty() ? 0 : 1;
297 }
298 }
299
300 return bValidValue;
301}
302
303/// get current field value and cache it
304void SwDBField::Evaluate()
305{
306 SwDBManager* pMgr = GetDoc()->GetDBManager();
307
308 // first delete
309 m_bValidValue = false;
310 double nValue = DBL_MAX1.7976931348623157e+308;
311 const SwDBData& aTmpData = GetDBData();
312
313 if(!pMgr || !pMgr->IsDataSourceOpen(aTmpData.sDataSource, aTmpData.sCommand, true))
314 return ;
315
316 sal_uInt32 nFormat = 0;
317
318 // search corresponding column name
319 OUString aColNm( static_cast<SwDBFieldType*>(GetTyp())->GetColumnName() );
320
321 SvNumberFormatter* pDocFormatter = GetDoc()->GetNumberFormatter();
322 pMgr->GetMergeColumnCnt(aColNm, GetLanguage(), m_aContent, &nValue);
323 if( !( m_nSubType & nsSwExtendedSubType::SUB_OWN_FMT ) )
324 {
325 nFormat = pMgr->GetColumnFormat( aTmpData.sDataSource, aTmpData.sCommand,
326 aColNm, pDocFormatter, GetLanguage() );
327 SetFormat( nFormat );
328 }
329
330 sal_Int32 nColumnType = nValue == DBL_MAX1.7976931348623157e+308
331 ? 0
332 : pMgr->GetColumnType(aTmpData.sDataSource, aTmpData.sCommand, aColNm);
333
334 m_bValidValue = FormatValue( pDocFormatter, m_aContent, nFormat, nValue, nColumnType, this );
335
336 if( DBL_MAX1.7976931348623157e+308 != nValue )
337 m_aContent = static_cast<SwValueFieldType*>(GetTyp())->ExpandValue(nValue, GetFormat(), GetLanguage());
338
339 m_bInitialized = true;
340}
341
342/// get name
343OUString SwDBField::GetPar1() const
344{
345 return static_cast<const SwDBFieldType*>(GetTyp())->GetName();
346}
347
348sal_uInt16 SwDBField::GetSubType() const
349{
350 return m_nSubType;
351}
352
353void SwDBField::SetSubType(sal_uInt16 nType)
354{
355 m_nSubType = nType;
356}
357
358bool SwDBField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
359{
360 switch( nWhichId )
361 {
362 case FIELD_PROP_BOOL115:
363 rAny <<= 0 == (GetSubType()&nsSwExtendedSubType::SUB_OWN_FMT);
364 break;
365 case FIELD_PROP_BOOL216:
366 rAny <<= 0 == (GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE);
367 break;
368 case FIELD_PROP_FORMAT13:
369 rAny <<= static_cast<sal_Int32>(GetFormat());
370 break;
371 case FIELD_PROP_PAR110:
372 rAny <<= m_aContent;
373 break;
374 case FIELD_PROP_PAR211:
375 rAny <<= m_sFieldCode;
376 break;
377 default:
378 OSL_FAIL("illegal property")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/fields/dbfld.cxx"
":" "378" ": "), "%s", "illegal property"); } } while (false
)
;
379 }
380 return true;
381}
382
383bool SwDBField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
384{
385 switch( nWhichId )
386 {
387 case FIELD_PROP_BOOL115:
388 if( *o3tl::doAccess<bool>(rAny) )
389 SetSubType(GetSubType()&~nsSwExtendedSubType::SUB_OWN_FMT);
390 else
391 SetSubType(GetSubType()|nsSwExtendedSubType::SUB_OWN_FMT);
392 break;
393 case FIELD_PROP_BOOL216:
394 {
395 sal_uInt16 nSubTyp = GetSubType();
396 bool bVisible = false;
397 if(!(rAny >>= bVisible))
398 return false;
399 if(bVisible)
400 nSubTyp &= ~nsSwExtendedSubType::SUB_INVISIBLE;
401 else
402 nSubTyp |= nsSwExtendedSubType::SUB_INVISIBLE;
403 SetSubType(nSubTyp);
404 //invalidate text node
405 auto pType = GetTyp();
406 if(!pType)
407 break;
408 std::vector<SwFormatField*> vFields;
409 pType->GatherFields(vFields, false);
410 for(auto pFormatField: vFields)
411 {
412 SwTextField* pTextField = pFormatField->GetTextField();
413 if(pTextField && static_cast<SwDBField*>(pFormatField->GetField()) == this)
414 {
415 //notify the change
416 pTextField->NotifyContentChange(*pFormatField);
417 break;
418 }
419 }
420 }
421 break;
422 case FIELD_PROP_FORMAT13:
423 {
424 sal_Int32 nTemp = 0;
425 rAny >>= nTemp;
426 SetFormat(nTemp);
427 }
428 break;
429 case FIELD_PROP_PAR110:
430 rAny >>= m_aContent;
431 break;
432 case FIELD_PROP_PAR211:
433 rAny >>= m_sFieldCode;
434 break;
435 default:
436 OSL_FAIL("illegal property")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/fields/dbfld.cxx"
":" "436" ": "), "%s", "illegal property"); } } while (false
)
;
437 }
438 return true;
439}
440
441// base class for all further database fields
442
443SwDBNameInfField::SwDBNameInfField(SwFieldType* pTyp, const SwDBData& rDBData, sal_uInt32 nFormat) :
444 SwField(pTyp, nFormat),
445 m_aDBData(rDBData),
446 m_nSubType(0)
447{
448}
449
450SwDBData SwDBNameInfField::GetDBData(SwDoc* pDoc)
451{
452 SwDBData aRet;
453 if(!m_aDBData.sDataSource.isEmpty())
454 aRet = m_aDBData;
455 else
456 aRet = pDoc->GetDBData();
457 return aRet;
458}
459
460void SwDBNameInfField::SetDBData(const SwDBData & rDBData)
461{
462 m_aDBData = rDBData;
463}
464
465OUString SwDBNameInfField::GetFieldName() const
466{
467 OUString sStr( SwField::GetFieldName() );
468 if (!m_aDBData.sDataSource.isEmpty())
469 {
470 sStr += ":"
471 + m_aDBData.sDataSource
472 + OUStringChar(DB_DELIMu'\x00ff')
473 + m_aDBData.sCommand;
474 }
475 return lcl_DBSeparatorConvert(sStr);
476}
477
478bool SwDBNameInfField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
479{
480 switch( nWhichId )
481 {
482 case FIELD_PROP_PAR110:
483 rAny <<= m_aDBData.sDataSource;
484 break;
485 case FIELD_PROP_PAR211:
486 rAny <<= m_aDBData.sCommand;
487 break;
488 case FIELD_PROP_SHORT124:
489 rAny <<= m_aDBData.nCommandType;
490 break;
491 case FIELD_PROP_BOOL216:
492 rAny <<= 0 == (GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE);
493 break;
494 default:
495 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/sw/source/core/fields/dbfld.cxx"
, 495, __extension__ __PRETTY_FUNCTION__))
;
496 }
497 return true;
498}
499
500bool SwDBNameInfField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
501{
502 switch( nWhichId )
503 {
504 case FIELD_PROP_PAR110:
505 rAny >>= m_aDBData.sDataSource;
506 break;
507 case FIELD_PROP_PAR211:
508 rAny >>= m_aDBData.sCommand;
509 break;
510 case FIELD_PROP_SHORT124:
511 rAny >>= m_aDBData.nCommandType;
512 break;
513 case FIELD_PROP_BOOL216:
514 {
515 sal_uInt16 nSubTyp = GetSubType();
516 bool bVisible = false;
517 if(!(rAny >>= bVisible))
518 return false;
519 if(bVisible)
520 nSubTyp &= ~nsSwExtendedSubType::SUB_INVISIBLE;
521 else
522 nSubTyp |= nsSwExtendedSubType::SUB_INVISIBLE;
523 SetSubType(nSubTyp);
524 }
525 break;
526 default:
527 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/sw/source/core/fields/dbfld.cxx"
, 527, __extension__ __PRETTY_FUNCTION__))
;
528 }
529 return true;
530}
531
532sal_uInt16 SwDBNameInfField::GetSubType() const
533{
534 return m_nSubType;
535}
536
537void SwDBNameInfField::SetSubType(sal_uInt16 nType)
538{
539 m_nSubType = nType;
540}
541
542// next dataset
543
544SwDBNextSetFieldType::SwDBNextSetFieldType()
545 : SwFieldType( SwFieldIds::DbNextSet )
546{
547}
548
549std::unique_ptr<SwFieldType> SwDBNextSetFieldType::Copy() const
550{
551 return std::make_unique<SwDBNextSetFieldType>();
552}
553
554// SwDBSetField
555
556SwDBNextSetField::SwDBNextSetField(SwDBNextSetFieldType* pTyp,
557 const OUString& rCond,
558 const SwDBData& rDBData) :
559 SwDBNameInfField(pTyp, rDBData), m_aCond(rCond), m_bCondValid(true)
560{}
561
562OUString SwDBNextSetField::ExpandImpl(SwRootFrame const*const) const
563{
564 return OUString();
565}
566
567std::unique_ptr<SwField> SwDBNextSetField::Copy() const
568{
569 std::unique_ptr<SwDBNextSetField> pTmp(new SwDBNextSetField(static_cast<SwDBNextSetFieldType*>(GetTyp()),
570 m_aCond, GetDBData()));
571 pTmp->SetSubType(GetSubType());
572 pTmp->m_bCondValid = m_bCondValid;
573 return std::unique_ptr<SwField>(pTmp.release());
574}
575
576void SwDBNextSetField::Evaluate(const SwDoc& rDoc)
577{
578 SwDBManager* pMgr = rDoc.GetDBManager();
579 const SwDBData& rData = GetDBData();
580 if( !m_bCondValid ||
581 !pMgr || !pMgr->IsDataSourceOpen(rData.sDataSource, rData.sCommand, false))
582 return ;
583 pMgr->ToNextRecord(rData.sDataSource, rData.sCommand);
584}
585
586/// get condition
587OUString SwDBNextSetField::GetPar1() const
588{
589 return m_aCond;
590}
591
592/// set condition
593void SwDBNextSetField::SetPar1(const OUString& rStr)
594{
595 m_aCond = rStr;
596}
597
598bool SwDBNextSetField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
599{
600 bool bRet = true;
601 switch( nWhichId )
602 {
603 case FIELD_PROP_PAR312:
604 rAny <<= m_aCond;
605 break;
606 default:
607 bRet = SwDBNameInfField::QueryValue( rAny, nWhichId );
608 }
609 return bRet;
610}
611
612bool SwDBNextSetField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
613{
614 bool bRet = true;
615 switch( nWhichId )
616 {
617 case FIELD_PROP_PAR312:
618 rAny >>= m_aCond;
619 break;
620 default:
621 bRet = SwDBNameInfField::PutValue( rAny, nWhichId );
622 }
623 return bRet;
624}
625
626// dataset with certain ID
627
628SwDBNumSetFieldType::SwDBNumSetFieldType() :
629 SwFieldType( SwFieldIds::DbNumSet )
630{
631}
632
633std::unique_ptr<SwFieldType> SwDBNumSetFieldType::Copy() const
634{
635 return std::make_unique<SwDBNumSetFieldType>();
636}
637
638SwDBNumSetField::SwDBNumSetField(SwDBNumSetFieldType* pTyp,
639 const OUString& rCond,
640 const OUString& rDBNum,
641 const SwDBData& rDBData) :
642 SwDBNameInfField(pTyp, rDBData),
643 m_aCond(rCond),
644 m_aPar2(rDBNum),
645 m_bCondValid(true)
646{}
647
648OUString SwDBNumSetField::ExpandImpl(SwRootFrame const*const) const
649{
650 return OUString();
651}
652
653std::unique_ptr<SwField> SwDBNumSetField::Copy() const
654{
655 std::unique_ptr<SwDBNumSetField> pTmp(new SwDBNumSetField(static_cast<SwDBNumSetFieldType*>(GetTyp()),
656 m_aCond, m_aPar2, GetDBData()));
657 pTmp->m_bCondValid = m_bCondValid;
658 pTmp->SetSubType(GetSubType());
659 return std::unique_ptr<SwField>(pTmp.release());
660}
661
662void SwDBNumSetField::Evaluate(const SwDoc& rDoc)
663{
664 SwDBManager* pMgr = rDoc.GetDBManager();
665 const SwDBData& aTmpData = GetDBData();
666
667 if( m_bCondValid && pMgr && pMgr->IsInMerge() &&
668 pMgr->IsDataSourceOpen(aTmpData.sDataSource, aTmpData.sCommand, true))
669 { // condition OK -> adjust current Set
670 pMgr->ToRecordId(std::max(static_cast<sal_uInt16>(m_aPar2.toInt32()), sal_uInt16(1))-1);
671 }
672}
673
674/// get LogDBName
675OUString SwDBNumSetField::GetPar1() const
676{
677 return m_aCond;
678}
679
680/// set LogDBName
681void SwDBNumSetField::SetPar1(const OUString& rStr)
682{
683 m_aCond = rStr;
684}
685
686/// get condition
687OUString SwDBNumSetField::GetPar2() const
688{
689 return m_aPar2;
690}
691
692/// set condition
693void SwDBNumSetField::SetPar2(const OUString& rStr)
694{
695 m_aPar2 = rStr;
696}
697
698bool SwDBNumSetField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
699{
700 bool bRet = true;
701 switch( nWhichId )
702 {
703 case FIELD_PROP_PAR312:
704 rAny <<= m_aCond;
705 break;
706 case FIELD_PROP_FORMAT13:
707 rAny <<= m_aPar2.toInt32();
708 break;
709 default:
710 bRet = SwDBNameInfField::QueryValue(rAny, nWhichId );
711 }
712 return bRet;
713}
714
715bool SwDBNumSetField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
716{
717 bool bRet = true;
718 switch( nWhichId )
719 {
720 case FIELD_PROP_PAR312:
721 rAny >>= m_aCond;
722 break;
723 case FIELD_PROP_FORMAT13:
724 {
725 sal_Int32 nVal = 0;
726 rAny >>= nVal;
727 m_aPar2 = OUString::number(nVal);
728 }
729 break;
730 default:
731 bRet = SwDBNameInfField::PutValue(rAny, nWhichId );
732 }
733 return bRet;
734}
735
736SwDBNameFieldType::SwDBNameFieldType(SwDoc* pDocument)
737 : SwFieldType( SwFieldIds::DatabaseName )
738{
739 m_pDoc = pDocument;
740}
741
742OUString SwDBNameFieldType::Expand() const
743{
744 const SwDBData aData = m_pDoc->GetDBData();
745 return aData.sDataSource + "." + aData.sCommand;
746}
747
748std::unique_ptr<SwFieldType> SwDBNameFieldType::Copy() const
749{
750 return std::make_unique<SwDBNameFieldType>(m_pDoc);
751}
752
753// name of the connected database
754
755SwDBNameField::SwDBNameField(SwDBNameFieldType* pTyp, const SwDBData& rDBData)
756 : SwDBNameInfField(pTyp, rDBData, 0)
757{}
758
759OUString SwDBNameField::ExpandImpl(SwRootFrame const*const) const
760{
761 if(0 ==(GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE))
762 return static_cast<SwDBNameFieldType*>(GetTyp())->Expand();
763 return OUString();
764}
765
766std::unique_ptr<SwField> SwDBNameField::Copy() const
767{
768 std::unique_ptr<SwDBNameField> pTmp(new SwDBNameField(static_cast<SwDBNameFieldType*>(GetTyp()), GetDBData()));
769 pTmp->ChangeFormat(GetFormat());
770 pTmp->SetLanguage(GetLanguage());
771 pTmp->SetSubType(GetSubType());
772 return std::unique_ptr<SwField>(pTmp.release());
773}
774
775bool SwDBNameField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
776{
777 return SwDBNameInfField::QueryValue(rAny, nWhichId );
778}
779
780bool SwDBNameField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
781{
782 return SwDBNameInfField::PutValue(rAny, nWhichId );
783}
784
785SwDBSetNumberFieldType::SwDBSetNumberFieldType()
786 : SwFieldType( SwFieldIds::DbSetNumber )
787{
788}
789
790std::unique_ptr<SwFieldType> SwDBSetNumberFieldType::Copy() const
791{
792 return std::make_unique<SwDBSetNumberFieldType>();
793}
794
795// set-number of the connected database
796
797SwDBSetNumberField::SwDBSetNumberField(SwDBSetNumberFieldType* pTyp,
798 const SwDBData& rDBData,
799 sal_uInt32 nFormat)
800 : SwDBNameInfField(pTyp, rDBData, nFormat), m_nNumber(0)
801{}
802
803OUString SwDBSetNumberField::ExpandImpl(SwRootFrame const*const) const
804{
805 if(0 !=(GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE) || m_nNumber == 0)
806 return OUString();
807 return FormatNumber(m_nNumber, static_cast<SvxNumType>(GetFormat()));
808}
809
810void SwDBSetNumberField::Evaluate(const SwDoc& rDoc)
811{
812 SwDBManager* pMgr = rDoc.GetDBManager();
813
814 const SwDBData& aTmpData = GetDBData();
815 if (!pMgr || !pMgr->IsInMerge() ||
816 !pMgr->IsDataSourceOpen(aTmpData.sDataSource, aTmpData.sCommand, false))
817 return;
818 m_nNumber = pMgr->GetSelectedRecordId();
819}
820
821std::unique_ptr<SwField> SwDBSetNumberField::Copy() const
822{
823 std::unique_ptr<SwDBSetNumberField> pTmp(
824 new SwDBSetNumberField(static_cast<SwDBSetNumberFieldType*>(GetTyp()), GetDBData(), GetFormat()));
825 pTmp->SetLanguage(GetLanguage());
826 pTmp->SetSetNumber(m_nNumber);
827 pTmp->SetSubType(GetSubType());
828 return std::unique_ptr<SwField>(pTmp.release());
829}
830
831bool SwDBSetNumberField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
832{
833 bool bRet = true;
834 switch( nWhichId )
835 {
836 case FIELD_PROP_USHORT118:
837 rAny <<= static_cast<sal_Int16>(GetFormat());
838 break;
839 case FIELD_PROP_FORMAT13:
840 rAny <<= m_nNumber;
841 break;
842 default:
843 bRet = SwDBNameInfField::QueryValue( rAny, nWhichId );
844 }
845 return bRet;
846}
847
848bool SwDBSetNumberField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
849{
850 bool bRet = true;
851 switch( nWhichId )
852 {
853 case FIELD_PROP_USHORT118:
854 {
855 sal_Int16 nSet = 0;
856 rAny >>= nSet;
857 if(nSet < css::style::NumberingType::NUMBER_NONE )
858 SetFormat(nSet);
859 }
860 break;
861 case FIELD_PROP_FORMAT13:
862 rAny >>= m_nNumber;
863 break;
864 default:
865 bRet = SwDBNameInfField::PutValue( rAny, nWhichId );
866 }
867 return bRet;
868}
869
870/* vim:set shiftwidth=4 softtabstop=4 expandtab: */