Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
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 gridcell.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 SVXCORE_DLLIMPLEMENTATION -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium/public -D COMPONENT_BUILD -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/svx/inc -I /home/maarten/src/libreoffice/core/svx/source/inc -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/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/svx/sdi -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/svx/source/fmcomp/gridcell.cxx

/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.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
21#include <memory>
22#include <sal/log.hxx>
23#include <fmprop.hxx>
24#include <svx/strings.hrc>
25#include <svx/fmtools.hxx>
26#include <gridcell.hxx>
27#include <gridcols.hxx>
28#include <sdbdatacolumn.hxx>
29
30#include <com/sun/star/awt/LineEndFormat.hpp>
31#include <com/sun/star/awt/MouseWheelBehavior.hpp>
32#include <com/sun/star/awt/VisualEffect.hpp>
33#include <com/sun/star/container/XChild.hpp>
34#include <com/sun/star/container/XIndexAccess.hpp>
35#include <com/sun/star/form/FormComponentType.hpp>
36#include <com/sun/star/form/XBoundComponent.hpp>
37#include <com/sun/star/script/XEventAttacherManager.hpp>
38#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
39#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
40#include <com/sun/star/sdbc/DataType.hpp>
41#include <com/sun/star/sdbc/SQLException.hpp>
42#include <com/sun/star/sdbc/XRowSet.hpp>
43#include <com/sun/star/sdbc/XStatement.hpp>
44#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
45#include <com/sun/star/util/XNumberFormatter.hpp>
46#include <com/sun/star/util/Time.hpp>
47#include <com/sun/star/util/Date.hpp>
48
49#include <comphelper/numbers.hxx>
50#include <comphelper/property.hxx>
51#include <comphelper/servicehelper.hxx>
52#include <comphelper/string.hxx>
53#include <comphelper/types.hxx>
54#include <connectivity/formattedcolumnvalue.hxx>
55#include <i18nlangtag/lang.h>
56
57#include <rtl/math.hxx>
58#include <svl/numuno.hxx>
59#include <svl/zforlist.hxx>
60#include <svx/dialmgr.hxx>
61#include <toolkit/helper/vclunohelper.hxx>
62#include <tools/debug.hxx>
63#include <tools/diagnose_ex.h>
64#include <vcl/settings.hxx>
65#include <vcl/svapp.hxx>
66#include <connectivity/dbtools.hxx>
67#include <connectivity/dbconversion.hxx>
68#include <connectivity/sqlnode.hxx>
69
70using namespace ::connectivity;
71using namespace ::svxform;
72using namespace ::comphelper;
73using namespace ::svt;
74using namespace ::com::sun::star;
75using namespace ::com::sun::star::uno;
76using namespace ::com::sun::star::sdbc;
77using namespace ::com::sun::star::sdbcx;
78using namespace ::com::sun::star::sdb;
79using namespace ::com::sun::star::beans;
80using namespace ::com::sun::star::form;
81using namespace ::dbtools::DBTypeConversion;
82using namespace ::dbtools;
83
84using ::com::sun::star::util::XNumberFormatter;
85
86const char INVALIDTEXT[] = "###";
87const char OBJECTTEXT[] = "<OBJECT>";
88
89
90//= helper
91
92namespace
93{
94 LineEnd getModelLineEndSetting( const Reference< XPropertySet >& _rxModel )
95 {
96 LineEnd eFormat = LINEEND_LF;
97
98 try
99 {
100 sal_Int16 nLineEndFormat = awt::LineEndFormat::LINE_FEED;
101
102 Reference< XPropertySetInfo > xPSI;
103 if ( _rxModel.is() )
104 xPSI = _rxModel->getPropertySetInfo();
105
106 OSL_ENSURE( xPSI.is(), "getModelLineEndSetting: invalid column model!" )do { if (true && (!(xPSI.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "106" ": "), "%s", "getModelLineEndSetting: invalid column model!"
); } } while (false)
;
107 if ( xPSI.is() && xPSI->hasPropertyByName( FM_PROP_LINEENDFORMAT"LineEndFormat" ) )
108 {
109 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_LINEENDFORMAT ) >>= nLineEndFormat )do { if (!(_rxModel->getPropertyValue( "LineEndFormat" ) >>=
nLineEndFormat)) do { if (true && (!(0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "109" ": "), "OSL_ASSERT: %s", "0"); } } while (false); }
while (0)
;
110
111 switch ( nLineEndFormat )
112 {
113 case awt::LineEndFormat::CARRIAGE_RETURN: eFormat = LINEEND_CR; break;
114 case awt::LineEndFormat::LINE_FEED: eFormat = LINEEND_LF; break;
115 case awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED: eFormat = LINEEND_CRLF; break;
116 default:
117 OSL_FAIL( "getModelLineEndSetting: what's this?" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "117" ": "), "%s", "getModelLineEndSetting: what's this?"
); } } while (false)
;
118 }
119 }
120 }
121 catch( const Exception& )
122 {
123 TOOLS_WARN_EXCEPTION( "svx", "getModelLineEndSetting" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "getModelLineEndSetting" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "123" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "getModelLineEndSetting" << " " <<
exceptionToString(tools_warn_exception)), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"getModelLineEndSetting" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "123" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "getModelLineEndSetting" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "123" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "getModelLineEndSetting" << " " <<
exceptionToString(tools_warn_exception)), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"getModelLineEndSetting" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "123" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
124 }
125 return eFormat;
126 }
127}
128
129
130//= DbGridColumn
131
132
133CellControllerRef DbGridColumn::s_xEmptyController;
134
135
136void DbGridColumn::CreateControl(sal_Int32 _nFieldPos, const Reference< css::beans::XPropertySet >& xField, sal_Int32 nTypeId)
137{
138 Clear();
139
140 m_nTypeId = static_cast<sal_Int16>(nTypeId);
141 if (xField != m_xField)
142 {
143 // initial setting
144 m_xField = xField;
145 xField->getPropertyValue(FM_PROP_FORMATKEY"FormatKey") >>= m_nFormatKey;
146 m_nFieldPos = static_cast<sal_Int16>(_nFieldPos);
147 m_bReadOnly = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISREADONLY"IsReadOnly"));
148 m_bAutoValue = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_AUTOINCREMENT"IsAutoIncrement"));
149 m_nFieldType = static_cast<sal_Int16>(::comphelper::getINT32(xField->getPropertyValue(FM_PROP_FIELDTYPE"Type")));
150
151 switch (m_nFieldType)
152 {
153 case DataType::DATE:
154 case DataType::TIME:
155 case DataType::TIMESTAMP:
156 case DataType::BIT:
157 case DataType::BOOLEAN:
158 case DataType::TINYINT:
159 case DataType::SMALLINT:
160 case DataType::INTEGER:
161 case DataType::BIGINT:
162 case DataType::FLOAT:
163 case DataType::REAL:
164 case DataType::DOUBLE:
165 case DataType::NUMERIC:
166 case DataType::DECIMAL:
167 m_nAlign = css::awt::TextAlign::RIGHT;
168 m_bNumeric = true;
169 break;
170 default:
171 m_nAlign = css::awt::TextAlign::LEFT;
172 break;
173 }
174 }
175
176 std::unique_ptr<DbCellControl> pCellControl;
177 if (m_rParent.IsFilterMode())
178 {
179 pCellControl.reset(new DbFilterField(m_rParent.getContext(),*this));
180 }
181 else
182 {
183
184 switch (nTypeId)
185 {
186 case TYPE_CHECKBOX0: pCellControl.reset(new DbCheckBox(*this)); break;
187 case TYPE_COMBOBOX1: pCellControl.reset(new DbComboBox(*this)); break;
188 case TYPE_CURRENCYFIELD2: pCellControl.reset(new DbCurrencyField(*this)); break;
189 case TYPE_DATEFIELD3: pCellControl.reset(new DbDateField(*this)); break;
190 case TYPE_LISTBOX5: pCellControl.reset(new DbListBox(*this)); break;
191 case TYPE_NUMERICFIELD6: pCellControl.reset(new DbNumericField(*this)); break;
192 case TYPE_PATTERNFIELD7: pCellControl.reset(new DbPatternField( *this, m_rParent.getContext() )); break;
193 case TYPE_TEXTFIELD8: pCellControl.reset(new DbTextField(*this)); break;
194 case TYPE_TIMEFIELD9: pCellControl.reset(new DbTimeField(*this)); break;
195 case TYPE_FORMATTEDFIELD4: pCellControl.reset(new DbFormattedField(*this)); break;
196 default:
197 OSL_FAIL("DbGridColumn::CreateControl: Unknown Column")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "197" ": "), "%s", "DbGridColumn::CreateControl: Unknown Column"
); } } while (false)
;
198 return;
199 }
200
201 }
202 Reference< XRowSet > xCur;
203 if (m_rParent.getDataSource())
204 xCur.set(Reference< XInterface >(*m_rParent.getDataSource()), UNO_QUERY);
205 // TODO : the cursor wrapper should use an XRowSet interface, too
206
207 pCellControl->Init( m_rParent.GetDataWindow(), xCur );
208
209 // now create the control wrapper
210 auto pTempCellControl = pCellControl.get();
211 if (m_rParent.IsFilterMode())
212 m_pCell = new FmXFilterCell(this, std::unique_ptr<DbFilterField>(static_cast<DbFilterField*>(pCellControl.release())));
213 else
214 {
215 switch (nTypeId)
216 {
217 case TYPE_CHECKBOX0: m_pCell = new FmXCheckBoxCell( this, std::move(pCellControl) ); break;
218 case TYPE_LISTBOX5: m_pCell = new FmXListBoxCell( this, std::move(pCellControl) ); break;
219 case TYPE_COMBOBOX1: m_pCell = new FmXComboBoxCell( this, std::move(pCellControl) ); break;
220 default:
221 m_pCell = new FmXEditCell( this, std::move(pCellControl) );
222 }
223 }
224 m_pCell->init();
225
226 impl_toggleScriptManager_nothrow( true );
227
228 // only if we use have a bound field, we use a controller for displaying the
229 // window in the grid
230 if (m_xField.is())
231 m_xController = pTempCellControl->CreateController();
232}
233
234
235void DbGridColumn::impl_toggleScriptManager_nothrow( bool _bAttach )
236{
237 try
238 {
239 Reference< container::XChild > xChild( m_xModel, UNO_QUERY_THROW );
240 Reference< script::XEventAttacherManager > xManager( xChild->getParent(), UNO_QUERY_THROW );
241 Reference< container::XIndexAccess > xContainer( xChild->getParent(), UNO_QUERY_THROW );
242
243 sal_Int32 nIndexInParent( getElementPos( xContainer, m_xModel ) );
244
245 Reference< XInterface > xCellInterface( *m_pCell, UNO_QUERY );
246 if ( _bAttach )
247 xManager->attach( nIndexInParent, xCellInterface, makeAny( xCellInterface ) );
248 else
249 xManager->detach( nIndexInParent, xCellInterface );
250 }
251 catch( const Exception& )
252 {
253 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "253" ": ", "svx" );
;
254 }
255}
256
257void DbGridColumn::UpdateFromField(const DbGridRow* pRow, const Reference< XNumberFormatter >& xFormatter)
258{
259 if (FmXFilterCell* pCell = dynamic_cast<FmXFilterCell*>(m_pCell.get()))
260 pCell->Update();
261 else if (pRow && pRow->IsValid() && m_nFieldPos >= 0 && m_pCell.is() && pRow->HasField(m_nFieldPos))
262 {
263 dynamic_cast<FmXDataCell&>(*m_pCell).UpdateFromField( pRow->GetField( m_nFieldPos ).getColumn(), xFormatter );
264 }
265}
266
267bool DbGridColumn::Commit()
268{
269 bool bResult = true;
270 if (!m_bInSave && m_pCell.is())
271 {
272 m_bInSave = true;
273 bResult = m_pCell->Commit();
274
275 // store the data into the model
276 FmXDataCell* pDataCell = dynamic_cast<FmXDataCell*>( m_pCell.get() );
277 if (bResult && pDataCell)
278 {
279 Reference< css::form::XBoundComponent > xComp(m_xModel, UNO_QUERY);
280 if (xComp.is())
281 bResult = xComp->commit();
282 }
283 m_bInSave = false;
284 }
285 return bResult;
286}
287
288DbGridColumn::~DbGridColumn()
289{
290 Clear();
291}
292
293void DbGridColumn::setModel(const css::uno::Reference< css::beans::XPropertySet >& _xModel)
294{
295 if ( m_pCell.is() )
296 impl_toggleScriptManager_nothrow( false );
297
298 m_xModel = _xModel;
299
300 if ( m_pCell.is() )
301 impl_toggleScriptManager_nothrow( true );
302}
303
304
305void DbGridColumn::Clear()
306{
307 if ( m_pCell.is() )
308 {
309 impl_toggleScriptManager_nothrow( false );
310
311 m_pCell->dispose();
312 m_pCell.clear();
313 }
314
315 m_xController = nullptr;
316 m_xField = nullptr;
317
318 m_nFormatKey = 0;
319 m_nFieldPos = -1;
320 m_bReadOnly = true;
321 m_bAutoValue = false;
322 m_nFieldType = DataType::OTHER;
323}
324
325
326sal_Int16 DbGridColumn::SetAlignment(sal_Int16 _nAlign)
327{
328 if (_nAlign == -1)
329 { // 'Standard'
330 if (m_xField.is())
331 {
332 sal_Int32 nType = 0;
333 m_xField->getPropertyValue(FM_PROP_FIELDTYPE"Type") >>= nType;
334
335 switch (nType)
336 {
337 case DataType::NUMERIC:
338 case DataType::DECIMAL:
339 case DataType::DOUBLE:
340 case DataType::REAL:
341 case DataType::BIGINT:
342 case DataType::INTEGER:
343 case DataType::SMALLINT:
344 case DataType::TINYINT:
345 case DataType::DATE:
346 case DataType::TIME:
347 case DataType::TIMESTAMP:
348 _nAlign = css::awt::TextAlign::RIGHT;
349 break;
350 case DataType::BIT:
351 case DataType::BOOLEAN:
352 _nAlign = css::awt::TextAlign::CENTER;
353 break;
354 default:
355 _nAlign = css::awt::TextAlign::LEFT;
356 break;
357 }
358 }
359 else
360 _nAlign = css::awt::TextAlign::LEFT;
361 }
362
363 m_nAlign = _nAlign;
364 if (m_pCell.is() && m_pCell->isAlignedController())
365 m_pCell->AlignControl(m_nAlign);
366
367 return m_nAlign;
368}
369
370
371sal_Int16 DbGridColumn::SetAlignmentFromModel(sal_Int16 nStandardAlign)
372{
373 Any aAlign( m_xModel->getPropertyValue(FM_PROP_ALIGN"Align"));
374 if (aAlign.hasValue())
375 {
376 sal_Int16 nTest = sal_Int16();
377 if (aAlign >>= nTest)
378 nStandardAlign = nTest;
379 }
380 return SetAlignment(nStandardAlign);
381}
382
383
384void DbGridColumn::setLock(bool _bLock)
385{
386 if (m_bLocked == _bLock)
387 return;
388 m_bLocked = _bLock;
389
390 // is the column we represent active ?
391 if (m_bHidden)
392 return; // no, it isn't (or at least it shouldn't be ...)
393
394 if (m_rParent.GetCurColumnId() == m_nId)
395 {
396 m_rParent.DeactivateCell();
397 m_rParent.ActivateCell(m_rParent.GetCurRow(), m_rParent.GetCurColumnId());
398 }
399}
400
401
402OUString DbGridColumn::GetCellText(const DbGridRow* pRow, const Reference< XNumberFormatter >& xFormatter) const
403{
404 OUString aText;
405 if (m_pCell.is() && dynamic_cast<const FmXFilterCell*>( m_pCell.get() ) != nullptr)
406 return aText;
407
408 if (!pRow || !pRow->IsValid())
409 aText = INVALIDTEXT;
410 else if (pRow->HasField(m_nFieldPos))
411 {
412 aText = GetCellText( pRow->GetField( m_nFieldPos ).getColumn(), xFormatter );
413 }
414 return aText;
415}
416
417OUString DbGridColumn::GetCellText(const Reference< css::sdb::XColumn >& xField, const Reference< XNumberFormatter >& xFormatter) const
418{
419 OUString aText;
420 if (xField.is())
421 {
422 FmXTextCell* pTextCell = dynamic_cast<FmXTextCell*>( m_pCell.get() );
423 if (pTextCell)
424 aText = pTextCell->GetText(xField, xFormatter);
425 else if (m_bObject)
426 aText = OBJECTTEXT;
427 }
428 return aText;
429}
430
431Reference< css::sdb::XColumn > DbGridColumn::GetCurrentFieldValue() const
432{
433 Reference< css::sdb::XColumn > xField;
434 const DbGridRowRef xRow = m_rParent.GetCurrentRow();
435 if (xRow.is() && xRow->HasField(m_nFieldPos))
436 {
437 xField = xRow->GetField(m_nFieldPos).getColumn();
438 }
439 return xField;
440}
441
442
443void DbGridColumn::Paint(OutputDevice& rDev,
444 const tools::Rectangle& rRect,
445 const DbGridRow* pRow,
446 const Reference< XNumberFormatter >& xFormatter)
447{
448 bool bEnabled = ( rDev.GetOutDevType() != OUTDEV_WINDOW )
449 || ( static_cast< vcl::Window& >( rDev ).IsEnabled() );
450
451 FmXDataCell* pDataCell = dynamic_cast<FmXDataCell*>( m_pCell.get() );
452 if (pDataCell)
453 {
454 if (!pRow || !pRow->IsValid())
455 {
456 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
457 if ( !bEnabled )
458 nStyle |= DrawTextFlags::Disable;
459
460 rDev.DrawText(rRect, OUString(INVALIDTEXT), nStyle);
461 }
462 else if (m_bAutoValue && pRow->IsNew())
463 {
464 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter;
465 if ( !bEnabled )
466 nStyle |= DrawTextFlags::Disable;
467
468 switch (GetAlignment())
469 {
470 case css::awt::TextAlign::RIGHT:
471 nStyle |= DrawTextFlags::Right;
472 break;
473 case css::awt::TextAlign::CENTER:
474 nStyle |= DrawTextFlags::Center;
475 break;
476 default:
477 nStyle |= DrawTextFlags::Left;
478 }
479
480 rDev.DrawText(rRect, SvxResId(RID_STR_AUTOFIELDreinterpret_cast<char const *>("RID_STR_AUTOFIELD" "\004"
u8"<AutoField>")
), nStyle);
481 }
482 else if (pRow->HasField(m_nFieldPos))
483 {
484 pDataCell->PaintFieldToCell(rDev, rRect, pRow->GetField( m_nFieldPos ).getColumn(), xFormatter);
485 }
486 }
487 else if (!m_pCell.is())
488 {
489 if (!pRow || !pRow->IsValid())
490 {
491 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
492 if ( !bEnabled )
493 nStyle |= DrawTextFlags::Disable;
494
495 rDev.DrawText(rRect, OUString(INVALIDTEXT), nStyle);
496 }
497 else if (pRow->HasField(m_nFieldPos) && m_bObject)
498 {
499 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
500 if ( !bEnabled )
501 nStyle |= DrawTextFlags::Disable;
502 rDev.DrawText(rRect, OUString(OBJECTTEXT), nStyle);
503 }
504 }
505 else if ( dynamic_cast<const FmXFilterCell*>( m_pCell.get() ) != nullptr )
506 static_cast< FmXFilterCell* >( m_pCell.get() )->PaintCell( rDev, rRect );
507}
508
509
510void DbGridColumn::ImplInitWindow( vcl::Window const & rParent, const InitWindowFacet _eInitWhat )
511{
512 if ( m_pCell.is() )
513 m_pCell->ImplInitWindow( rParent, _eInitWhat );
514}
515
516
517//= cell controls
518
519
520DbCellControl::DbCellControl( DbGridColumn& _rColumn )
521 :OPropertyChangeListener(m_aMutex)
522 ,m_bTransparent( false )
523 ,m_bAlignedController( true )
524 ,m_bAccessingValueProperty( false )
525 ,m_rColumn( _rColumn )
526 ,m_pPainter( nullptr )
527 ,m_pWindow( nullptr )
528{
529 Reference< XPropertySet > xColModelProps = _rColumn.getModel();
530 if ( !xColModelProps.is() )
531 return;
532
533 // if our model's format key changes we want to propagate the new value to our windows
534 m_pModelChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, _rColumn.getModel());
535
536 // be listener for some common properties
537 implDoPropertyListening( FM_PROP_READONLY"ReadOnly", false );
538 implDoPropertyListening( FM_PROP_ENABLED"Enabled", false );
539
540 // add as listener for all known "value" properties
541 implDoPropertyListening( FM_PROP_VALUE"Value", false );
542 implDoPropertyListening( FM_PROP_STATE"State", false );
543 implDoPropertyListening( FM_PROP_TEXT"Text", false );
544 implDoPropertyListening( FM_PROP_EFFECTIVE_VALUE"EffectiveValue", false );
545 implDoPropertyListening( FM_PROP_SELECT_SEQ"SelectedItems", false );
546 implDoPropertyListening( FM_PROP_DATE"Date", false );
547 implDoPropertyListening( FM_PROP_TIME"Time", false );
548
549 // be listener at the bound field as well
550 try
551 {
552 Reference< XPropertySetInfo > xPSI( xColModelProps->getPropertySetInfo(), UNO_SET_THROW );
553 if ( xPSI->hasPropertyByName( FM_PROP_BOUNDFIELD"BoundField" ) )
554 {
555 Reference< XPropertySet > xField;
556 xColModelProps->getPropertyValue( FM_PROP_BOUNDFIELD"BoundField" ) >>= xField;
557 if ( xField.is() )
558 {
559 m_pFieldChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, xField);
560 m_pFieldChangeBroadcaster->addProperty( FM_PROP_ISREADONLY"IsReadOnly" );
561 }
562 }
563 }
564 catch( const Exception& )
565 {
566 TOOLS_WARN_EXCEPTION( "svx", "DbCellControl::doPropertyListening" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "DbCellControl::doPropertyListening" << " "
<< exceptionToString(tools_warn_exception)) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "566" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DbCellControl::doPropertyListening" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DbCellControl::doPropertyListening" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "566" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "DbCellControl::doPropertyListening" << " "
<< exceptionToString(tools_warn_exception)) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "566" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DbCellControl::doPropertyListening" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DbCellControl::doPropertyListening" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "566" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
567 }
568}
569
570
571void DbCellControl::implDoPropertyListening(const OUString& _rPropertyName, bool _bWarnIfNotExistent)
572{
573 try
574 {
575 Reference< XPropertySet > xColModelProps = m_rColumn.getModel();
576 Reference< XPropertySetInfo > xPSI;
577 if ( xColModelProps.is() )
578 xPSI = xColModelProps->getPropertySetInfo();
579
580 DBG_ASSERT( !_bWarnIfNotExistent || ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) ),do { if (true && (!(!_bWarnIfNotExistent || ( xPSI.is
() && xPSI->hasPropertyByName( _rPropertyName ) ))
)) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "581" ": "), "%s", "DbCellControl::doPropertyListening: no property set info or non-existent property!"
); } } while (false)
581 "DbCellControl::doPropertyListening: no property set info or non-existent property!" )do { if (true && (!(!_bWarnIfNotExistent || ( xPSI.is
() && xPSI->hasPropertyByName( _rPropertyName ) ))
)) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "581" ": "), "%s", "DbCellControl::doPropertyListening: no property set info or non-existent property!"
); } } while (false)
;
582
583 if ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) )
584 m_pModelChangeBroadcaster->addProperty( _rPropertyName );
585 }
586 catch( const Exception& )
587 {
588 TOOLS_WARN_EXCEPTION( "svx", "DbCellControl::doPropertyListening" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "DbCellControl::doPropertyListening" << " "
<< exceptionToString(tools_warn_exception)) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "588" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DbCellControl::doPropertyListening" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DbCellControl::doPropertyListening" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "588" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "DbCellControl::doPropertyListening" << " "
<< exceptionToString(tools_warn_exception)) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "588" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DbCellControl::doPropertyListening" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DbCellControl::doPropertyListening" << " " <<
exceptionToString(tools_warn_exception); ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_WARN), ("svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "588" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
589 }
590}
591
592
593void DbCellControl::doPropertyListening(const OUString& _rPropertyName)
594{
595 implDoPropertyListening( _rPropertyName, true );
596}
597
598static void lcl_clearBroadCaster(rtl::Reference<::comphelper::OPropertyChangeMultiplexer>& _pBroadcaster)
599{
600 if ( _pBroadcaster.is() )
601 {
602 _pBroadcaster->dispose();
603 _pBroadcaster.clear();
604 // no delete, this is done implicitly
605 }
606}
607
608DbCellControl::~DbCellControl()
609{
610 lcl_clearBroadCaster(m_pModelChangeBroadcaster);
611 lcl_clearBroadCaster(m_pFieldChangeBroadcaster);
612
613 m_pWindow.disposeAndClear();
614 m_pPainter.disposeAndClear();
615}
616
617void DbCellControl::implValuePropertyChanged( )
618{
619 OSL_ENSURE( !isValuePropertyLocked(),do { if (true && (!(!isValuePropertyLocked()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "620" ": "), "%s", "DbCellControl::implValuePropertyChanged: not to be called with the value property locked!"
); } } while (false)
620 "DbCellControl::implValuePropertyChanged: not to be called with the value property locked!" )do { if (true && (!(!isValuePropertyLocked()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "620" ": "), "%s", "DbCellControl::implValuePropertyChanged: not to be called with the value property locked!"
); } } while (false)
;
621
622 if ( m_pWindow )
623 {
624 if ( m_rColumn.getModel().is() )
625 updateFromModel( m_rColumn.getModel() );
626 }
627}
628
629
630void DbCellControl::implAdjustGenericFieldSetting( const Reference< XPropertySet >& /*_rxModel*/ )
631{
632 // nothing to do here
633}
634
635
636void DbCellControl::_propertyChanged(const PropertyChangeEvent& _rEvent)
637{
638 SolarMutexGuard aGuard;
639
640 Reference< XPropertySet > xSourceProps( _rEvent.Source, UNO_QUERY );
641
642 if ( _rEvent.PropertyName == FM_PROP_VALUE"Value"
643 || _rEvent.PropertyName == FM_PROP_STATE"State"
644 || _rEvent.PropertyName == FM_PROP_TEXT"Text"
645 || _rEvent.PropertyName == FM_PROP_EFFECTIVE_VALUE"EffectiveValue"
646 || _rEvent.PropertyName == FM_PROP_SELECT_SEQ"SelectedItems"
647 || _rEvent.PropertyName == FM_PROP_DATE"Date"
648 || _rEvent.PropertyName == FM_PROP_TIME"Time"
649 )
650 { // it was one of the known "value" properties
651 if ( !isValuePropertyLocked() )
652 {
653 implValuePropertyChanged( );
654 }
655 }
656 else if ( _rEvent.PropertyName == FM_PROP_READONLY"ReadOnly" )
657 {
658 implAdjustReadOnly( xSourceProps, true);
659 }
660 else if ( _rEvent.PropertyName == FM_PROP_ISREADONLY"IsReadOnly" )
661 {
662 bool bReadOnly = true;
663 _rEvent.NewValue >>= bReadOnly;
664 m_rColumn.SetReadOnly(bReadOnly);
665 implAdjustReadOnly( xSourceProps, false);
666 }
667 else if ( _rEvent.PropertyName == FM_PROP_ENABLED"Enabled" )
668 {
669 implAdjustEnabled( xSourceProps );
670 }
671 else
672 implAdjustGenericFieldSetting( xSourceProps );
673}
674
675bool DbCellControl::Commit()
676{
677 // lock the listening for value property changes
678 lockValueProperty();
679 // commit the content of the control into the model's value property
680 bool bReturn = false;
681 try
682 {
683 bReturn = commitControl();
684 }
685 catch( const Exception& )
686 {
687 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "687" ": ", "svx" );
;
688 }
689 // unlock the listening for value property changes
690 unlockValueProperty();
691 // outta here
692 return bReturn;
693}
694
695void DbCellControl::ImplInitWindow( vcl::Window const & rParent, const InitWindowFacet _eInitWhat )
696{
697 vcl::Window* pWindows[] = { m_pPainter, m_pWindow };
698
699 if (_eInitWhat & InitWindowFacet::WritingMode)
700 {
701 for (vcl::Window* pWindow : pWindows)
702 {
703 if (pWindow)
704 pWindow->EnableRTL(rParent.IsRTLEnabled());
705 }
706 }
707
708 if (_eInitWhat & InitWindowFacet::Font)
709 {
710 for (vcl::Window* pWindow : pWindows)
711 {
712 if (!pWindow)
713 continue;
714
715 pWindow->SetZoom(rParent.GetZoom());
716
717 const StyleSettings& rStyleSettings = pWindow->GetSettings().GetStyleSettings();
718 vcl::Font aFont = rStyleSettings.GetFieldFont();
719 aFont.SetTransparent(isTransparent());
720
721 if (rParent.IsControlFont())
722 {
723 pWindow->SetControlFont(rParent.GetControlFont());
724 aFont.Merge(rParent.GetControlFont());
725 }
726 else
727 pWindow->SetControlFont();
728
729 pWindow->SetZoomedPointFont(*pWindow, aFont); // FIXME RenderContext
730 }
731 }
732
733 if ((_eInitWhat & InitWindowFacet::Font) || (_eInitWhat & InitWindowFacet::Foreground))
734 {
735 Color aTextColor(rParent.IsControlForeground() ? rParent.GetControlForeground() : rParent.GetTextColor());
736
737 bool bTextLineColor = rParent.IsTextLineColor();
738 Color aTextLineColor(rParent.GetTextLineColor());
739
740 for (vcl::Window* pWindow : pWindows)
741 {
742 if (pWindow)
743 {
744 pWindow->SetTextColor(aTextColor);
745 if (rParent.IsControlForeground())
746 pWindow->SetControlForeground(aTextColor);
747
748 if (bTextLineColor)
749 pWindow->SetTextLineColor();
750 else
751 pWindow->SetTextLineColor(aTextLineColor);
752 }
753 }
754 }
755
756 if (!(_eInitWhat & InitWindowFacet::Background))
757 return;
758
759 if (rParent.IsControlBackground())
760 {
761 Color aColor(rParent.GetControlBackground());
762 for (vcl::Window* pWindow : pWindows)
763 {
764 if (pWindow)
765 {
766 if (isTransparent())
767 pWindow->SetBackground();
768 else
769 {
770 pWindow->SetBackground(aColor);
771 pWindow->SetControlBackground(aColor);
772 }
773 pWindow->SetFillColor(aColor);
774 }
775 }
776 }
777 else
778 {
779 if (m_pPainter)
780 {
781 if (isTransparent())
782 m_pPainter->SetBackground();
783 else
784 m_pPainter->SetBackground(rParent.GetBackground());
785 m_pPainter->SetFillColor(rParent.GetFillColor());
786 }
787
788 if (m_pWindow)
789 {
790 if (isTransparent())
791 m_pWindow->SetBackground(rParent.GetBackground());
792 else
793 m_pWindow->SetFillColor(rParent.GetFillColor());
794 }
795 }
796}
797
798void DbCellControl::implAdjustReadOnly( const Reference< XPropertySet >& _rxModel,bool i_bReadOnly )
799{
800 DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustReadOnly: not to be called without window!" )do { if (true && (!(m_pWindow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "800" ": "), "%s", "DbCellControl::implAdjustReadOnly: not to be called without window!"
); } } while (false)
;
801 DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustReadOnly: invalid model!" )do { if (true && (!(_rxModel.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "801" ": "), "%s", "DbCellControl::implAdjustReadOnly: invalid model!"
); } } while (false)
;
802 if ( !(m_pWindow && _rxModel.is()) )
803 return;
804
805 ControlBase* pEditWindow = dynamic_cast<ControlBase*>(m_pWindow.get());
806 if ( pEditWindow )
807 {
808 bool bReadOnly = m_rColumn.IsReadOnly();
809 if ( !bReadOnly )
810 {
811 _rxModel->getPropertyValue( i_bReadOnly ? OUString(FM_PROP_READONLY"ReadOnly") : OUString(FM_PROP_ISREADONLY"IsReadOnly")) >>= bReadOnly;
812 }
813 pEditWindow->SetEditableReadOnly(bReadOnly);
814 }
815}
816
817void DbCellControl::implAdjustEnabled( const Reference< XPropertySet >& _rxModel )
818{
819 DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustEnabled: not to be called without window!" )do { if (true && (!(m_pWindow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "819" ": "), "%s", "DbCellControl::implAdjustEnabled: not to be called without window!"
); } } while (false)
;
820 DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustEnabled: invalid model!" )do { if (true && (!(_rxModel.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "820" ": "), "%s", "DbCellControl::implAdjustEnabled: invalid model!"
); } } while (false)
;
821 if ( m_pWindow && _rxModel.is() )
822 {
823 bool bEnable = true;
824 _rxModel->getPropertyValue( FM_PROP_ENABLED"Enabled" ) >>= bEnable;
825 m_pWindow->Enable( bEnable );
826 }
827}
828
829void DbCellControl::Init(BrowserDataWin& rParent, const Reference< XRowSet >& _rxCursor)
830{
831 ImplInitWindow( rParent, InitWindowFacet::All );
832
833 if ( m_pWindow )
834 {
835 // align the control
836 if ( isAlignedController() )
837 AlignControl( m_rColumn.GetAlignment() );
838
839 try
840 {
841 // some other common properties
842 Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW );
843 Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW );
844
845 if ( xModelPSI->hasPropertyByName( FM_PROP_READONLY"ReadOnly" ) )
846 {
847 implAdjustReadOnly( xModel,true );
848 }
849
850 if ( xModelPSI->hasPropertyByName( FM_PROP_ENABLED"Enabled" ) )
851 {
852 implAdjustEnabled( xModel );
853 }
854
855 if ( xModelPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR"MouseWheelBehavior" ) )
856 {
857 sal_Int16 nWheelBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY;
858 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) >>= nWheelBehavior )do { if (!(xModel->getPropertyValue( "MouseWheelBehavior" )
>>= nWheelBehavior)) do { if (true && (!(0))) {
sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "858" ": "), "OSL_ASSERT: %s", "0"); } } while (false); }
while (0)
;
859 MouseWheelBehaviour nVclSetting = MouseWheelBehaviour::FocusOnly;
860 switch ( nWheelBehavior )
861 {
862 case css::awt::MouseWheelBehavior::SCROLL_DISABLED: nVclSetting = MouseWheelBehaviour::Disable; break;
863 case css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclSetting = MouseWheelBehaviour::FocusOnly; break;
864 case css::awt::MouseWheelBehavior::SCROLL_ALWAYS: nVclSetting = MouseWheelBehaviour::ALWAYS; break;
865 default:
866 OSL_FAIL( "DbCellControl::Init: invalid MouseWheelBehavior!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "866" ": "), "%s", "DbCellControl::Init: invalid MouseWheelBehavior!"
); } } while (false)
;
867 break;
868 }
869
870 AllSettings aSettings = m_pWindow->GetSettings();
871 MouseSettings aMouseSettings = aSettings.GetMouseSettings();
872 aMouseSettings.SetWheelBehavior( nVclSetting );
873 aSettings.SetMouseSettings( aMouseSettings );
874 m_pWindow->SetSettings( aSettings, true );
875 }
876 }
877 catch( const Exception& )
878 {
879 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "879" ": ", "svx" );
;
880 }
881 }
882 m_xCursor = _rxCursor;
883 if ( m_rColumn.getModel().is() )
884 updateFromModel( m_rColumn.getModel() );
885}
886
887
888void DbCellControl::SetTextLineColor()
889{
890 if (m_pWindow)
891 m_pWindow->SetTextLineColor();
892 if (m_pPainter)
893 m_pPainter->SetTextLineColor();
894}
895
896
897void DbCellControl::SetTextLineColor(const Color& _rColor)
898{
899 if (m_pWindow)
900 m_pWindow->SetTextLineColor(_rColor);
901 if (m_pPainter)
902 m_pPainter->SetTextLineColor(_rColor);
903}
904
905namespace
906{
907 void lcl_implAlign( vcl::Window* _pWindow, WinBits _nAlignmentBit )
908 {
909 if (EditControlBase* pControl = dynamic_cast<EditControlBase*>(_pWindow))
910 {
911 switch (_nAlignmentBit)
912 {
913 case WB_LEFT:
914 pControl->get_widget().set_alignment(TxtAlign::Left);
915 break;
916 case WB_CENTER:
917 pControl->get_widget().set_alignment(TxtAlign::Center);
918 break;
919 case WB_RIGHT:
920 pControl->get_widget().set_alignment(TxtAlign::Right);
921 break;
922 }
923 return;
924 }
925
926 WinBits nStyle = _pWindow->GetStyle();
927 nStyle &= ~(WB_LEFT | WB_RIGHT | WB_CENTER);
928 _pWindow->SetStyle( nStyle | _nAlignmentBit );
929 }
930}
931
932void DbCellControl::AlignControl(sal_Int16 nAlignment)
933{
934 WinBits nAlignmentBit = 0;
935 switch (nAlignment)
936 {
937 case css::awt::TextAlign::RIGHT:
938 nAlignmentBit = WB_RIGHT;
939 break;
940 case css::awt::TextAlign::CENTER:
941 nAlignmentBit = WB_CENTER;
942 break;
943 default:
944 nAlignmentBit = WB_LEFT;
945 break;
946 }
947 lcl_implAlign( m_pWindow, nAlignmentBit );
948 if ( m_pPainter )
949 lcl_implAlign( m_pPainter, nAlignmentBit );
950}
951
952void DbCellControl::PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect)
953{
954 m_pPainter->SetSizePixel(rRect.GetSize());
955 m_pPainter->Draw(&rDev, rRect.TopLeft(), DrawFlags::NONE);
956}
957
958void DbCellControl::PaintFieldToCell( OutputDevice& _rDev, const tools::Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
959{
960 m_pPainter->SetText( GetFormatText( _rxField, _rxFormatter ) );
961 PaintCell( _rDev, _rRect );
962}
963
964double DbCellControl::GetValue(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter) const
965{
966 double fValue = 0;
967 if (m_rColumn.IsNumeric())
968 {
969 try
970 {
971 fValue = _rxField->getDouble();
972 }
973 catch(const Exception&) { }
974 }
975 else
976 {
977 bool bSuccess = false;
978 try
979 {
980 fValue = _rxField->getDouble();
981 bSuccess = true;
982 }
983 catch(const Exception&) { }
984 if (!bSuccess)
985 {
986 try
987 {
988 fValue = xFormatter->convertStringToNumber(m_rColumn.GetKey(), _rxField->getString());
989 }
990 catch(const Exception&) { }
991 }
992 }
993 return fValue;
994}
995
996void DbCellControl::invalidatedController()
997{
998 m_rColumn.GetParent().refreshController(m_rColumn.GetId(), DbGridControl::GrantControlAccess());
999}
1000
1001// CellModels
1002
1003DbLimitedLengthField::DbLimitedLengthField( DbGridColumn& _rColumn )
1004 :DbCellControl( _rColumn )
1005{
1006 doPropertyListening( FM_PROP_MAXTEXTLEN"MaxTextLen" );
1007}
1008
1009
1010void DbLimitedLengthField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1011{
1012 DBG_ASSERT( m_pWindow, "DbLimitedLengthField::implAdjustGenericFieldSetting: not to be called without window!" )do { if (true && (!(m_pWindow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1012" ": "), "%s", "DbLimitedLengthField::implAdjustGenericFieldSetting: not to be called without window!"
); } } while (false)
;
1013 DBG_ASSERT( _rxModel.is(), "DbLimitedLengthField::implAdjustGenericFieldSetting: invalid model!" )do { if (true && (!(_rxModel.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1013" ": "), "%s", "DbLimitedLengthField::implAdjustGenericFieldSetting: invalid model!"
); } } while (false)
;
1014 if ( m_pWindow && _rxModel.is() )
1015 {
1016 sal_Int16 nMaxLen = 0;
1017 _rxModel->getPropertyValue( FM_PROP_MAXTEXTLEN"MaxTextLen" ) >>= nMaxLen;
1018 implSetMaxTextLen( nMaxLen );
1019 }
1020}
1021
1022void DbLimitedLengthField::implSetEffectiveMaxTextLen(sal_Int32 nMaxLen)
1023{
1024 dynamic_cast<EditControlBase&>(*m_pWindow).get_widget().set_max_length(nMaxLen);
1025 if (m_pPainter)
1026 dynamic_cast<EditControlBase&>(*m_pPainter).get_widget().set_max_length(nMaxLen);
1027}
1028
1029DbTextField::DbTextField(DbGridColumn& _rColumn)
1030 :DbLimitedLengthField(_rColumn)
1031 ,m_bIsSimpleEdit( true )
1032{
1033}
1034
1035DbTextField::~DbTextField( )
1036{
1037 m_pPainterImplementation.reset();
1038 m_pEdit.reset();
1039}
1040
1041void DbTextField::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
1042{
1043 sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1044
1045 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1046
1047 bool bLeftAlign = true;
1048
1049 // is this a multi-line field?
1050 bool bIsMultiLine = false;
1051 try
1052 {
1053 if ( xModel.is() )
1054 {
1055 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MULTILINE ) >>= bIsMultiLine )do { if (!(xModel->getPropertyValue( "MultiLine" ) >>=
bIsMultiLine)) do { if (true && (!(0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1055" ": "), "OSL_ASSERT: %s", "0"); } } while (false);
} while (0)
;
1056 }
1057 }
1058 catch( const Exception& )
1059 {
1060 TOOLS_WARN_EXCEPTION("svx",do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1061" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx")
, ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1061" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1061" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx")
, ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1061" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
1061 "caught an exception while determining the multi-line capabilities!")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1061" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx")
, ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1061" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"svx"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1061" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "caught an exception while determining the multi-line capabilities!"
<< " " << exceptionToString(tools_warn_exception
); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx")
, ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1061" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1062 }
1063
1064 m_bIsSimpleEdit = !bIsMultiLine;
1065 if ( bIsMultiLine )
1066 {
1067 auto xEditControl = VclPtr<MultiLineTextCell>::Create(&rParent);
1068 auto xEditPainter = VclPtr<MultiLineTextCell>::Create(&rParent);
1069
1070 switch (nAlignment)
1071 {
1072 case awt::TextAlign::RIGHT:
1073 xEditControl->get_widget().set_alignment(TxtAlign::Right);
1074 xEditPainter->get_widget().set_alignment(TxtAlign::Right);
1075 bLeftAlign = false;
1076 break;
1077 case awt::TextAlign::CENTER:
1078 xEditControl->get_widget().set_alignment(TxtAlign::Center);
1079 xEditPainter->get_widget().set_alignment(TxtAlign::Center);
1080 bLeftAlign = false;
1081 break;
1082 }
1083
1084 m_pWindow = xEditControl;
1085 m_pEdit.reset(new MultiLineEditImplementation(*xEditControl));
1086
1087 m_pPainter = xEditPainter;
1088 m_pPainterImplementation.reset(new MultiLineEditImplementation(*xEditPainter));
1089 }
1090 else
1091 {
1092 auto xEditControl = VclPtr<EditControl>::Create(&rParent);
1093 auto xEditPainter = VclPtr<EditControl>::Create(&rParent);
1094
1095 switch (nAlignment)
1096 {
1097 case awt::TextAlign::RIGHT:
1098 xEditControl->get_widget().set_alignment(TxtAlign::Right);
1099 xEditPainter->get_widget().set_alignment(TxtAlign::Right);
1100 bLeftAlign = false;
1101 break;
1102 case awt::TextAlign::CENTER:
1103 xEditControl->get_widget().set_alignment(TxtAlign::Center);
1104 xEditPainter->get_widget().set_alignment(TxtAlign::Center);
1105 bLeftAlign = false;
1106 break;
1107 }
1108
1109 m_pWindow = xEditControl;
1110 m_pEdit.reset(new EntryImplementation(*xEditControl));
1111
1112 m_pPainter = xEditPainter;
1113 m_pPainterImplementation.reset(new EntryImplementation(*xEditPainter));
1114 }
1115
1116 if (bLeftAlign)
1117 {
1118 // this is so that when getting the focus, the selection is oriented left-to-right
1119 AllSettings aSettings = m_pWindow->GetSettings();
1120 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1121 aStyleSettings.SetSelectionOptions(
1122 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
1123 aSettings.SetStyleSettings(aStyleSettings);
1124 m_pWindow->SetSettings(aSettings);
1125 }
1126
1127 implAdjustGenericFieldSetting( xModel );
1128
1129 DbLimitedLengthField::Init( rParent, xCursor );
1130}
1131
1132CellControllerRef DbTextField::CreateController() const
1133{
1134 return new EditCellController( m_pEdit.get() );
1135}
1136
1137void DbTextField::PaintFieldToCell( OutputDevice& _rDev, const tools::Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1138{
1139 if ( m_pPainterImplementation )
1140 m_pPainterImplementation->SetText( GetFormatText( _rxField, _rxFormatter ) );
1141
1142 DbLimitedLengthField::PaintFieldToCell( _rDev, _rRect, _rxField, _rxFormatter );
1143}
1144
1145OUString DbTextField::GetFormatText(const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, const Color** /*ppColor*/)
1146{
1147 if (!_rxField.is())
1148 return OUString();
1149
1150 const css::uno::Reference<css::beans::XPropertySet> xPS(_rxField, UNO_QUERY);
1151 FormattedColumnValue fmter( xFormatter, xPS );
1152
1153 try
1154 {
1155 return fmter.getFormattedValue();
1156 }
1157 catch( const Exception& )
1158 {
1159 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1159" ": ", "svx" );
;
1160 }
1161 return OUString();
1162
1163}
1164
1165void DbTextField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
1166{
1167 m_pEdit->SetText( GetFormatText( _rxField, xFormatter ) );
1168 m_pEdit->SetSelection( Selection( SELECTION_MAX9223372036854775807L, SELECTION_MIN(-9223372036854775807L -1L) ) );
1169}
1170
1171void DbTextField::updateFromModel( Reference< XPropertySet > _rxModel )
1172{
1173 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTextField::updateFromModel: invalid call!" )do { if (true && (!(_rxModel.is() && m_pWindow
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1173" ": "), "%s", "DbTextField::updateFromModel: invalid call!"
); } } while (false)
;
1174
1175 OUString sText;
1176 _rxModel->getPropertyValue( FM_PROP_TEXT"Text" ) >>= sText;
1177
1178 sal_Int32 nMaxTextLen = m_pEdit->GetMaxTextLen();
1179 if (nMaxTextLen != 0 && sText.getLength() > nMaxTextLen)
1180 {
1181 sal_Int32 nDiff = sText.getLength() - nMaxTextLen;
1182 sText = sText.replaceAt(sText.getLength() - nDiff,nDiff, OUString());
1183 }
1184
1185
1186 m_pEdit->SetText( sText );
1187 m_pEdit->SetSelection( Selection( SELECTION_MAX9223372036854775807L, SELECTION_MIN(-9223372036854775807L -1L) ) );
1188}
1189
1190bool DbTextField::commitControl()
1191{
1192 OUString aText( m_pEdit->GetText( getModelLineEndSetting( m_rColumn.getModel() ) ) );
1193 // we have to check if the length before we can decide if the value was modified
1194 sal_Int32 nMaxTextLen = m_pEdit->GetMaxTextLen();
1195 if (nMaxTextLen != 0)
1196 {
1197 OUString sOldValue;
1198 m_rColumn.getModel()->getPropertyValue( FM_PROP_TEXT"Text" ) >>= sOldValue;
1199 // if the new value didn't change we must set the old long value again
1200 if ( sOldValue.getLength() > nMaxTextLen && sOldValue.compareTo(aText,nMaxTextLen) == 0 )
1201 aText = sOldValue;
1202 }
1203 m_rColumn.getModel()->setPropertyValue( FM_PROP_TEXT"Text", makeAny( aText ) );
1204 return true;
1205}
1206
1207void DbTextField::implSetEffectiveMaxTextLen( sal_Int32 _nMaxLen )
1208{
1209 if ( m_pEdit )
1210 m_pEdit->SetMaxTextLen( _nMaxLen );
1211 if ( m_pPainterImplementation )
1212 m_pPainterImplementation->SetMaxTextLen( _nMaxLen );
1213}
1214
1215DbFormattedField::DbFormattedField(DbGridColumn& _rColumn)
1216 :DbLimitedLengthField(_rColumn)
1217{
1218 // if our model's format key changes we want to propagate the new value to our windows
1219 doPropertyListening( FM_PROP_FORMATKEY"FormatKey" );
1220}
1221
1222DbFormattedField::~DbFormattedField()
1223{
1224}
1225
1226void DbFormattedField::Init( BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
1227{
1228 sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1229
1230 Reference< css::beans::XPropertySet > xUnoModel = m_rColumn.getModel();
1231
1232 auto xEditControl = VclPtr<FormattedControl>::Create(&rParent, false);
1233 auto xEditPainter = VclPtr<FormattedControl>::Create(&rParent, false);
1234
1235 weld::EntryFormatter& rControlFormatter = xEditControl->get_formatter();
1236 weld::EntryFormatter& rPainterFormatter = xEditPainter->get_formatter();
1237
1238 m_pWindow = xEditControl.get();
1239 m_pPainter = xEditPainter.get();
1240
1241 switch (nAlignment)
1242 {
1243 case awt::TextAlign::RIGHT:
1244 xEditControl->get_widget().set_alignment(TxtAlign::Right);
1245 xEditPainter->get_widget().set_alignment(TxtAlign::Right);
1246 break;
1247 case awt::TextAlign::CENTER:
1248 xEditControl->get_widget().set_alignment(TxtAlign::Center);
1249 xEditPainter->get_widget().set_alignment(TxtAlign::Center);
1250 break;
1251 default:
1252 {
1253 // Everything just so that the selection goes from right to left when getting focus
1254 SelectionOptions eOptions = rControlFormatter.GetEntrySelectionOptions();
1255 rControlFormatter.SetEntrySelectionOptions(eOptions | SelectionOptions::ShowFirst);
1256 break;
1257 }
1258 }
1259
1260 implAdjustGenericFieldSetting( xUnoModel );
1261
1262 rControlFormatter.SetStrictFormat(false);
1263 rPainterFormatter.SetStrictFormat(false);
1264 // if one allows any formatting, one cannot make an entry check anyway
1265 // (the FormattedField does not support that anyway, only derived classes)
1266
1267 // get the formatter from the uno model
1268 // (I could theoretically also go via the css::util::NumberFormatter, which the cursor would
1269 // surely give me. The problem is that I can not really rely on the fact that the two
1270 // formatters are the same. Clean is the whole thing if I go via the UNO model.)
1271 sal_Int32 nFormatKey = -1;
1272
1273 // let's see if the model has one ...
1274 DBG_ASSERT(::comphelper::hasProperty(FM_PROP_FORMATSSUPPLIER, xUnoModel), "DbFormattedField::Init : invalid UNO model !")do { if (true && (!(::comphelper::hasProperty("FormatsSupplier"
, xUnoModel)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1274" ": "), "%s", "DbFormattedField::Init : invalid UNO model !"
); } } while (false)
;
1275 Any aSupplier( xUnoModel->getPropertyValue(FM_PROP_FORMATSSUPPLIER"FormatsSupplier"));
1276 if (aSupplier.hasValue())
1277 {
1278 m_xSupplier.set(aSupplier, css::uno::UNO_QUERY);
1279 if (m_xSupplier.is())
1280 {
1281 // if we take the supplier from the model, then also the key
1282 Any aFmtKey( xUnoModel->getPropertyValue(FM_PROP_FORMATKEY"FormatKey"));
1283 if (aFmtKey.hasValue())
1284 {
1285 DBG_ASSERT(aFmtKey.getValueType().getTypeClass() == TypeClass_LONG, "DbFormattedField::Init : invalid format key property (no sal_Int32) !")do { if (true && (!(aFmtKey.getValueType().getTypeClass
() == TypeClass_LONG))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1285" ": "), "%s", "DbFormattedField::Init : invalid format key property (no sal_Int32) !"
); } } while (false)
;
1286 nFormatKey = ::comphelper::getINT32(aFmtKey);
1287 }
1288 else
1289 {
1290 SAL_INFO("svx.fmcomp", "DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "svx.fmcomp")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.fmcomp"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1290" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.fmcomp"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1290" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.fmcomp"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1290" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.fmcomp"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1290" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1291 // the OFormattedModel which we usually are working with ensures that the model has a format key
1292 // as soon as the form is loaded. Unfortunally this method here is called from within loaded, too.
1293 // So if our LoadListener is called before the LoadListener of the model, this "else case" is
1294 // allowed.
1295 // Of course our property listener for the FormatKey property will notify us if the prop is changed,
1296 // so this here isn't really bad...
1297 nFormatKey = 0;
1298 }
1299 }
1300 }
1301
1302 // No? Maybe the css::form::component::Form behind the cursor?
1303 if (!m_xSupplier.is())
1304 {
1305 if (xCursor.is())
1306 { // If we take the formatter from the cursor, then also the key from the field to which we are bound
1307 m_xSupplier = getNumberFormats(getConnection(xCursor));
1308
1309 if (m_rColumn.GetField().is())
1310 nFormatKey = ::comphelper::getINT32(m_rColumn.GetField()->getPropertyValue(FM_PROP_FORMATKEY"FormatKey"));
1311 }
1312 }
1313
1314 SvNumberFormatter* pFormatterUsed = nullptr;
1315 if (m_xSupplier.is())
1316 {
1317 SvNumberFormatsSupplierObj* pImplementation = comphelper::getUnoTunnelImplementation<SvNumberFormatsSupplierObj>(m_xSupplier);
1318 if (pImplementation)
1319 pFormatterUsed = pImplementation->GetNumberFormatter();
1320 else
1321 // Everything is invalid: the supplier is of the wrong type, then we can not
1322 // rely on a standard formatter to know the (possibly non-standard) key.
1323 nFormatKey = -1;
1324 }
1325
1326 // a standard formatter ...
1327 if (pFormatterUsed == nullptr)
1328 {
1329 pFormatterUsed = rControlFormatter.StandardFormatter();
1330 DBG_ASSERT(pFormatterUsed != nullptr, "DbFormattedField::Init : no standard formatter given by the numeric field !")do { if (true && (!(pFormatterUsed != nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1330" ": "), "%s", "DbFormattedField::Init : no standard formatter given by the numeric field !"
); } } while (false)
;
1331 }
1332 // ... and a standard key
1333 if (nFormatKey == -1)
1334 nFormatKey = 0;
1335
1336 rControlFormatter.SetFormatter(pFormatterUsed);
1337 rPainterFormatter.SetFormatter(pFormatterUsed);
1338
1339 rControlFormatter.SetFormatKey(nFormatKey);
1340 rPainterFormatter.SetFormatKey(nFormatKey);
1341
1342 rControlFormatter.TreatAsNumber(m_rColumn.IsNumeric());
1343 rPainterFormatter.TreatAsNumber(m_rColumn.IsNumeric());
1344
1345 // min and max values
1346 if (m_rColumn.IsNumeric())
1347 {
1348 bool bClearMin = true;
1349 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MIN"EffectiveMin", xUnoModel))
1350 {
1351 Any aMin( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MIN"EffectiveMin"));
1352 if (aMin.getValueType().getTypeClass() != TypeClass_VOID)
1353 {
1354 DBG_ASSERT(aMin.getValueType().getTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid min value !")do { if (true && (!(aMin.getValueType().getTypeClass(
) == TypeClass_DOUBLE))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1354" ": "), "%s", "DbFormattedField::Init : the model has an invalid min value !"
); } } while (false)
;
1355 double dMin = ::comphelper::getDouble(aMin);
1356 rControlFormatter.SetMinValue(dMin);
1357 rPainterFormatter.SetMinValue(dMin);
1358 bClearMin = false;
1359 }
1360 }
1361 if (bClearMin)
1362 {
1363 rControlFormatter.ClearMinValue();
1364 rPainterFormatter.ClearMinValue();
1365 }
1366 bool bClearMax = true;
1367 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MAX"EffectiveMax", xUnoModel))
1368 {
1369 Any aMax(xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MAX"EffectiveMax"));
1370 if (aMax.getValueType().getTypeClass() != TypeClass_VOID)
1371 {
1372 DBG_ASSERT(aMax.getValueType().getTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid max value !")do { if (true && (!(aMax.getValueType().getTypeClass(
) == TypeClass_DOUBLE))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1372" ": "), "%s", "DbFormattedField::Init : the model has an invalid max value !"
); } } while (false)
;
1373 double dMax = ::comphelper::getDouble(aMax);
1374 rControlFormatter.SetMaxValue(dMax);
1375 rPainterFormatter.SetMaxValue(dMax);
1376 bClearMax = false;
1377 }
1378 }
1379 if (bClearMax)
1380 {
1381 rControlFormatter.ClearMaxValue();
1382 rPainterFormatter.ClearMaxValue();
1383 }
1384 }
1385
1386 // the default value
1387 Any aDefault( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_DEFAULT"EffectiveDefault"));
1388 if (aDefault.hasValue())
1389 { // the thing can be a double or a string
1390 switch (aDefault.getValueType().getTypeClass())
1391 {
1392 case TypeClass_DOUBLE:
1393 if (m_rColumn.IsNumeric())
1394 {
1395 rControlFormatter.SetDefaultValue(::comphelper::getDouble(aDefault));
1396 rPainterFormatter.SetDefaultValue(::comphelper::getDouble(aDefault));
1397 }
1398 else
1399 {
1400 OUString sConverted;
1401 const Color* pDummy;
1402 pFormatterUsed->GetOutputString(::comphelper::getDouble(aDefault), 0, sConverted, &pDummy);
1403 rControlFormatter.SetDefaultText(sConverted);
1404 rPainterFormatter.SetDefaultText(sConverted);
1405 }
1406 break;
1407 case TypeClass_STRING:
1408 {
1409 OUString sDefault( ::comphelper::getString(aDefault) );
1410 if (m_rColumn.IsNumeric())
1411 {
1412 double dVal;
1413 sal_uInt32 nTestFormat(0);
1414 if (pFormatterUsed->IsNumberFormat(sDefault, nTestFormat, dVal))
1415 {
1416 rControlFormatter.SetDefaultValue(dVal);
1417 rPainterFormatter.SetDefaultValue(dVal);
1418 }
1419 }
1420 else
1421 {
1422 rControlFormatter.SetDefaultText(sDefault);
1423 rPainterFormatter.SetDefaultText(sDefault);
1424 }
1425 }
1426 break;
1427 default:
1428 OSL_FAIL( "DbFormattedField::Init: unexpected value type!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1428" ": "), "%s", "DbFormattedField::Init: unexpected value type!"
); } } while (false)
;
1429 break;
1430 }
1431 }
1432 DbLimitedLengthField::Init( rParent, xCursor );
1433}
1434
1435CellControllerRef DbFormattedField::CreateController() const
1436{
1437 return new ::svt::FormattedFieldCellController(static_cast<FormattedControlBase*>(m_pWindow.get()));
1438}
1439
1440void DbFormattedField::_propertyChanged( const PropertyChangeEvent& _rEvent )
1441{
1442 if (_rEvent.PropertyName == FM_PROP_FORMATKEY"FormatKey" )
1443 {
1444 sal_Int32 nNewKey = _rEvent.NewValue.hasValue() ? ::comphelper::getINT32(_rEvent.NewValue) : 0;
1445
1446 DBG_ASSERT(m_pWindow && m_pPainter, "DbFormattedField::_propertyChanged : where are my windows ?")do { if (true && (!(m_pWindow && m_pPainter))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1446" ": "), "%s", "DbFormattedField::_propertyChanged : where are my windows ?"
); } } while (false)
;
1447 if (m_pWindow)
1448 static_cast<FormattedControlBase*>(m_pWindow.get())->get_formatter().SetFormatKey(nNewKey);
1449 if (m_pPainter)
1450 static_cast<FormattedControlBase*>(m_pPainter.get())->get_formatter().SetFormatKey(nNewKey);
1451 }
1452 else
1453 {
1454 DbLimitedLengthField::_propertyChanged( _rEvent );
1455 }
1456}
1457
1458OUString DbFormattedField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** ppColor)
1459{
1460 // no color specification by default
1461 if (ppColor != nullptr)
1462 *ppColor = nullptr;
1463
1464 // NULL value -> empty text
1465 if (!_rxField.is())
1466 return OUString();
1467
1468 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pPainter.get());
1469 weld::EntryFormatter& rPainterFormatter = pControl->get_formatter();
1470
1471 OUString aText;
1472 try
1473 {
1474 if (m_rColumn.IsNumeric())
1475 {
1476 // The IsNumeric at the column says nothing about the class of the used format, but
1477 // about the class of the field bound to the column. So when you bind a FormattedField
1478 // column to a double field and format it as text, m_rColumn.IsNumeric() returns
1479 // sal_True. So that simply means that I can query the contents of the variant using
1480 // getDouble, and then I can leave the rest (the formatting) to the FormattedField.
1481 double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1482 if (_rxField->wasNull())
1483 return aText;
1484 rPainterFormatter.SetValue(dValue);
1485 }
1486 else
1487 {
1488 // Here I can not work with a double, since the field can not provide it to me.
1489 // So simply bind the text from the css::util::NumberFormatter to the correct css::form::component::Form.
1490 aText = _rxField->getString();
1491 if (_rxField->wasNull())
1492 return aText;
1493 rPainterFormatter.SetTextFormatted(aText);
1494 }
1495 }
1496 catch( const Exception& )
1497 {
1498 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1498" ": ", "svx" );
;
1499 }
1500
1501 aText = pControl->get_widget().get_text();
1502 if (ppColor != nullptr)
1503 *ppColor = rPainterFormatter.GetLastOutputColor();
1504
1505 return aText;
1506}
1507
1508void DbFormattedField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1509{
1510 try
1511 {
1512 FormattedControlBase* pEditControl = static_cast<FormattedControlBase*>(m_pWindow.get());
1513 weld::Entry& rEntry = pEditControl->get_widget();
1514 weld::EntryFormatter& rEditFormatter = pEditControl->get_formatter();
1515
1516 if (!_rxField.is())
1517 {
1518 // NULL value -> empty text
1519 rEntry.set_text(OUString());
1520 }
1521 else if (m_rColumn.IsNumeric())
1522 {
1523 // The IsNumeric at the column says nothing about the class of the used format, but
1524 // about the class of the field bound to the column. So when you bind a FormattedField
1525 // column to a double field and format it as text, m_rColumn.IsNumeric() returns
1526 // sal_True. So that simply means that I can query the contents of the variant using
1527 // getDouble, and then I can leave the rest (the formatting) to the FormattedField.
1528 double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1529 if (_rxField->wasNull())
1530 rEntry.set_text(OUString());
1531 else
1532 rEditFormatter.SetValue(dValue);
1533 }
1534 else
1535 {
1536 // Here I can not work with a double, since the field can not provide it to me.
1537 // So simply bind the text from the css::util::NumberFormatter to the correct css::form::component::Form.
1538 OUString sText( _rxField->getString());
1539
1540 rEditFormatter.SetTextFormatted( sText );
1541 rEntry.select_region(0, -1);
1542 }
1543 }
1544 catch( const Exception& )
1545 {
1546 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1546" ": ", "svx" );
;
1547 }
1548}
1549
1550void DbFormattedField::updateFromModel( Reference< XPropertySet > _rxModel )
1551{
1552 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFormattedField::updateFromModel: invalid call!" )do { if (true && (!(_rxModel.is() && m_pWindow
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1552" ": "), "%s", "DbFormattedField::updateFromModel: invalid call!"
); } } while (false)
;
1553
1554 FormattedControlBase* pEditControl = static_cast<FormattedControlBase*>(m_pWindow.get());
1555 weld::Entry& rEntry = pEditControl->get_widget();
1556 weld::EntryFormatter& rEditFormatter = pEditControl->get_formatter();
1557
1558 OUString sText;
1559 Any aValue = _rxModel->getPropertyValue( FM_PROP_EFFECTIVE_VALUE"EffectiveValue" );
1560 if ( !aValue.hasValue() || (aValue >>= sText) )
1561 {
1562 // our effective value is transferred as string
1563 rEditFormatter.SetTextFormatted( sText );
1564 rEntry.select_region(0, -1);
1565 }
1566 else
1567 {
1568 double dValue = 0;
1569 aValue >>= dValue;
1570 rEditFormatter.SetValue(dValue);
1571 }
1572}
1573
1574bool DbFormattedField::commitControl()
1575{
1576 Any aNewVal;
1577
1578 FormattedControlBase* pEditControl = static_cast<FormattedControlBase*>(m_pWindow.get());
1579 weld::Entry& rEntry = pEditControl->get_widget();
1580 weld::EntryFormatter& rEditFormatter = pEditControl->get_formatter();
1581
1582 if (m_rColumn.IsNumeric())
1583 {
1584 if (!rEntry.get_text().isEmpty())
1585 aNewVal <<= rEditFormatter.GetValue();
1586 // an empty string is passed on as void by default, to start with
1587 }
1588 else
1589 aNewVal <<= rEditFormatter.GetTextValue();
1590
1591 m_rColumn.getModel()->setPropertyValue(FM_PROP_EFFECTIVE_VALUE"EffectiveValue", aNewVal);
1592 return true;
1593}
1594
1595DbCheckBox::DbCheckBox( DbGridColumn& _rColumn )
1596 :DbCellControl( _rColumn )
1597{
1598 setAlignedController( false );
1599}
1600
1601namespace
1602{
1603 void setCheckBoxStyle( vcl::Window* _pWindow, bool bMono )
1604 {
1605 AllSettings aSettings = _pWindow->GetSettings();
1606 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1607 if( bMono )
1608 aStyleSettings.SetOptions( aStyleSettings.GetOptions() | StyleSettingsOptions::Mono );
1609 else
1610 aStyleSettings.SetOptions( aStyleSettings.GetOptions() & (~StyleSettingsOptions::Mono) );
1611 aSettings.SetStyleSettings( aStyleSettings );
1612 _pWindow->SetSettings( aSettings );
1613 }
1614}
1615
1616void DbCheckBox::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
1617{
1618 setTransparent( true );
1619
1620 m_pWindow = VclPtr<CheckBoxControl>::Create( &rParent );
1621 m_pPainter = VclPtr<CheckBoxControl>::Create( &rParent );
1622
1623 m_pWindow->SetPaintTransparent( true );
1624 m_pPainter->SetPaintTransparent( true );
1625
1626 m_pPainter->SetBackground();
1627
1628 try
1629 {
1630 Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW );
1631
1632 sal_Int16 nStyle = awt::VisualEffect::LOOK3D;
1633 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_VISUALEFFECT ) >>= nStyle )do { if (!(xModel->getPropertyValue( "VisualEffect" ) >>=
nStyle)) do { if (true && (!(0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1633" ": "), "OSL_ASSERT: %s", "0"); } } while (false);
} while (0)
;
1634
1635 setCheckBoxStyle( m_pWindow, nStyle == awt::VisualEffect::FLAT );
1636 setCheckBoxStyle( m_pPainter, nStyle == awt::VisualEffect::FLAT );
1637
1638 bool bTristate = true;
1639 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_TRISTATE ) >>= bTristate )do { if (!(xModel->getPropertyValue( "TriState" ) >>=
bTristate)) do { if (true && (!(0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1639" ": "), "OSL_ASSERT: %s", "0"); } } while (false);
} while (0)
;
1640 static_cast< CheckBoxControl* >( m_pWindow.get() )->EnableTriState( bTristate );
1641 static_cast< CheckBoxControl* >( m_pPainter.get() )->EnableTriState( bTristate );
1642 }
1643 catch( const Exception& )
1644 {
1645 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1645" ": ", "svx" );
;
1646 }
1647
1648 DbCellControl::Init( rParent, xCursor );
1649}
1650
1651CellControllerRef DbCheckBox::CreateController() const
1652{
1653 return new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
1654}
1655
1656static void lcl_setCheckBoxState( const Reference< css::sdb::XColumn >& _rxField,
1657 CheckBoxControl* _pCheckBoxControl )
1658{
1659 TriState eState = TRISTATE_INDET;
1660 if (_rxField.is())
1661 {
1662 try
1663 {
1664 bool bValue = _rxField->getBoolean();
1665 if (!_rxField->wasNull())
1666 eState = bValue ? TRISTATE_TRUE : TRISTATE_FALSE;
1667 }
1668 catch( const Exception& )
1669 {
1670 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1670" ": ", "svx" );
;
1671 }
1672 }
1673 _pCheckBoxControl->SetState(eState);
1674}
1675
1676void DbCheckBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1677{
1678 lcl_setCheckBoxState( _rxField, static_cast<CheckBoxControl*>(m_pWindow.get()) );
1679}
1680
1681void DbCheckBox::PaintFieldToCell(OutputDevice& rDev, const tools::Rectangle& rRect,
1682 const Reference< css::sdb::XColumn >& _rxField,
1683 const Reference< XNumberFormatter >& xFormatter)
1684{
1685 CheckBoxControl* pControl = static_cast<CheckBoxControl*>(m_pPainter.get());
1686 lcl_setCheckBoxState( _rxField, pControl );
1687
1688 Size aBoxSize = pControl->GetBox().get_preferred_size();
1689 tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
1690 rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
1691 aBoxSize);
1692
1693 DbCellControl::PaintFieldToCell(rDev, aRect, _rxField, xFormatter);
1694}
1695
1696void DbCheckBox::updateFromModel( Reference< XPropertySet > _rxModel )
1697{
1698 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCheckBox::updateFromModel: invalid call!" )do { if (true && (!(_rxModel.is() && m_pWindow
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1698" ": "), "%s", "DbCheckBox::updateFromModel: invalid call!"
); } } while (false)
;
1699
1700 sal_Int16 nState = TRISTATE_INDET;
1701 _rxModel->getPropertyValue( FM_PROP_STATE"State" ) >>= nState;
1702 static_cast< CheckBoxControl* >( m_pWindow.get() )->SetState( static_cast< TriState >( nState ) );
1703}
1704
1705bool DbCheckBox::commitControl()
1706{
1707 m_rColumn.getModel()->setPropertyValue( FM_PROP_STATE"State",
1708 makeAny( static_cast<sal_Int16>( static_cast< CheckBoxControl* >( m_pWindow.get() )->GetState() ) ) );
1709 return true;
1710}
1711
1712OUString DbCheckBox::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
1713{
1714 return OUString();
1715}
1716
1717DbPatternField::DbPatternField( DbGridColumn& _rColumn, const Reference<XComponentContext>& _rContext )
1718 :DbCellControl( _rColumn )
1719 ,m_xContext( _rContext )
1720{
1721 doPropertyListening( FM_PROP_LITERALMASK"LiteralMask" );
1722 doPropertyListening( FM_PROP_EDITMASK"EditMask" );
1723 doPropertyListening( FM_PROP_STRICTFORMAT"StrictFormat" );
1724}
1725
1726void DbPatternField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1727{
1728 DBG_ASSERT( m_pWindow, "DbPatternField::implAdjustGenericFieldSetting: not to be called without window!" )do { if (true && (!(m_pWindow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1728" ": "), "%s", "DbPatternField::implAdjustGenericFieldSetting: not to be called without window!"
); } } while (false)
;
1729 DBG_ASSERT( _rxModel.is(), "DbPatternField::implAdjustGenericFieldSetting: invalid model!" )do { if (true && (!(_rxModel.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1729" ": "), "%s", "DbPatternField::implAdjustGenericFieldSetting: invalid model!"
); } } while (false)
;
1730 if ( !m_pWindow || !_rxModel.is() )
1731 return;
1732
1733 OUString aLitMask;
1734 OUString aEditMask;
1735 bool bStrict = false;
1736
1737 _rxModel->getPropertyValue( FM_PROP_LITERALMASK"LiteralMask" ) >>= aLitMask;
1738 _rxModel->getPropertyValue( FM_PROP_EDITMASK"EditMask" ) >>= aEditMask;
1739 _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT"StrictFormat" ) >>= bStrict;
1740
1741 OString aAsciiEditMask(OUStringToOString(aEditMask, RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11))));
1742
1743 weld::PatternFormatter& rEditFormatter = static_cast<PatternControl*>(m_pWindow.get())->get_formatter();
1744 rEditFormatter.SetMask(aAsciiEditMask, aLitMask);
1745 rEditFormatter.SetStrictFormat(bStrict);
1746
1747 weld::PatternFormatter& rPaintFormatter = static_cast<PatternControl*>(m_pPainter.get())->get_formatter();
1748 rPaintFormatter.SetMask(aAsciiEditMask, aLitMask);
1749 rPaintFormatter.SetStrictFormat(bStrict);
1750}
1751
1752void DbPatternField::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
1753{
1754 m_rColumn.SetAlignmentFromModel(-1);
1755
1756 m_pWindow = VclPtr<PatternControl>::Create(&rParent);
1757 m_pPainter= VclPtr<PatternControl>::Create(&rParent);
1758
1759 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1760 implAdjustGenericFieldSetting( xModel );
1761
1762 DbCellControl::Init( rParent, xCursor );
1763}
1764
1765CellControllerRef DbPatternField::CreateController() const
1766{
1767 return new EditCellController(static_cast<PatternControl*>(m_pWindow.get()));
1768}
1769
1770OUString DbPatternField::impl_formatText( const OUString& _rText )
1771{
1772 weld::PatternFormatter& rPaintFormatter = static_cast<PatternControl*>(m_pPainter.get())->get_formatter();
1773 rPaintFormatter.get_widget().set_text(_rText);
1774 rPaintFormatter.ReformatAll();
1775 return rPaintFormatter.get_widget().get_text();
1776}
1777
1778OUString DbPatternField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
1779{
1780 bool bIsForPaint = _rxField != m_rColumn.GetField();
1781 ::std::unique_ptr< FormattedColumnValue >& rpFormatter = bIsForPaint ? m_pPaintFormatter : m_pValueFormatter;
1782
1783 if (!rpFormatter)
1784 {
1785 rpFormatter = std::make_unique< FormattedColumnValue> (
1786 m_xContext, getCursor(), Reference< XPropertySet >( _rxField, UNO_QUERY ) );
1787 OSL_ENSURE(rpFormatter, "DbPatternField::Init: no value formatter!")do { if (true && (!(rpFormatter))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1787" ": "), "%s", "DbPatternField::Init: no value formatter!"
); } } while (false)
;
1788 }
1789 else
1790 OSL_ENSURE( rpFormatter->getColumn() == _rxField, "DbPatternField::GetFormatText: my value formatter is working for another field ...!" )do { if (true && (!(rpFormatter->getColumn() == _rxField
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1790" ": "), "%s", "DbPatternField::GetFormatText: my value formatter is working for another field ...!"
); } } while (false)
;
1791 // re-creating the value formatter here every time would be quite expensive ...
1792
1793 OUString sText;
1794 if (rpFormatter)
1795 sText = rpFormatter->getFormattedValue();
1796
1797 return impl_formatText( sText );
1798}
1799
1800void DbPatternField::UpdateFromField( const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1801{
1802 weld::Entry& rEntry = static_cast<PatternControl*>(m_pWindow.get())->get_widget();
1803 rEntry.set_text(GetFormatText(_rxField, _rxFormatter));
1804 rEntry.select_region(-1, 0);
1805}
1806
1807void DbPatternField::updateFromModel( Reference< XPropertySet > _rxModel )
1808{
1809 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbPatternField::updateFromModel: invalid call!" )do { if (true && (!(_rxModel.is() && m_pWindow
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1809" ": "), "%s", "DbPatternField::updateFromModel: invalid call!"
); } } while (false)
;
1810
1811 OUString sText;
1812 _rxModel->getPropertyValue( FM_PROP_TEXT"Text" ) >>= sText;
1813
1814 weld::Entry& rEntry = static_cast<PatternControl*>(m_pWindow.get())->get_widget();
1815 rEntry.set_text(impl_formatText(sText));
1816 rEntry.select_region(-1, 0);
1817}
1818
1819bool DbPatternField::commitControl()
1820{
1821 weld::Entry& rEntry = static_cast<PatternControl*>(m_pWindow.get())->get_widget();
1822 m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT"Text", makeAny(rEntry.get_text()));
1823 return true;
1824}
1825
1826DbSpinField::DbSpinField( DbGridColumn& _rColumn, sal_Int16 _nStandardAlign )
1827 :DbCellControl( _rColumn )
1828 ,m_nStandardAlign( _nStandardAlign )
1829{
1830}
1831
1832void DbSpinField::Init(BrowserDataWin& _rParent, const Reference< XRowSet >& _rxCursor)
1833{
1834 m_rColumn.SetAlignmentFromModel( m_nStandardAlign );
1835
1836 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1837
1838 // determine if we need a spinbutton version
1839 bool bSpinButton(false);
1840 if ( ::comphelper::getBOOL( xModel->getPropertyValue( FM_PROP_SPIN"Spin" ) ) )
1841 bSpinButton = true;
1842 // create the fields
1843 m_pWindow = createField( &_rParent, bSpinButton, xModel );
1844 m_pPainter = createField( &_rParent, bSpinButton, xModel );
1845
1846 // adjust all other settings which depend on the property values
1847 implAdjustGenericFieldSetting( xModel );
1848
1849 // call the base class
1850 DbCellControl::Init( _rParent, _rxCursor );
1851}
1852
1853CellControllerRef DbSpinField::CreateController() const
1854{
1855 return new ::svt::FormattedFieldCellController(static_cast<FormattedControlBase*>(m_pWindow.get()));
1856}
1857
1858DbNumericField::DbNumericField( DbGridColumn& _rColumn )
1859 :DbSpinField( _rColumn )
1860{
1861 doPropertyListening( FM_PROP_DECIMAL_ACCURACY"DecimalAccuracy" );
1862 doPropertyListening( FM_PROP_VALUEMIN"ValueMin" );
1863 doPropertyListening( FM_PROP_VALUEMAX"ValueMax" );
1864 doPropertyListening( FM_PROP_VALUESTEP"ValueStep" );
1865 doPropertyListening( FM_PROP_STRICTFORMAT"StrictFormat" );
1866 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP"ShowThousandsSeparator" );
1867}
1868
1869void DbNumericField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1870{
1871 DBG_ASSERT( m_pWindow, "DbNumericField::implAdjustGenericFieldSetting: not to be called without window!" )do { if (true && (!(m_pWindow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1871" ": "), "%s", "DbNumericField::implAdjustGenericFieldSetting: not to be called without window!"
); } } while (false)
;
1872 DBG_ASSERT( _rxModel.is(), "DbNumericField::implAdjustGenericFieldSetting: invalid model!" )do { if (true && (!(_rxModel.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1872" ": "), "%s", "DbNumericField::implAdjustGenericFieldSetting: invalid model!"
); } } while (false)
;
1873 if ( !m_pWindow || !_rxModel.is() )
1874 return;
1875
1876 sal_Int32 nMin = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN"ValueMin" ) ));
1877 sal_Int32 nMax = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX"ValueMax" ) ));
1878 sal_Int32 nStep = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP"ValueStep" ) ));
1879 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT"StrictFormat" ) );
1880 sal_Int16 nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY"DecimalAccuracy" ) );
1881 bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP"ShowThousandsSeparator" ) );
1882
1883 Formatter& rEditFormatter = static_cast<FormattedControlBase*>(m_pWindow.get())->get_formatter();
1884 rEditFormatter.SetMinValue(nMin);
1885 rEditFormatter.SetMaxValue(nMax);
1886 rEditFormatter.SetSpinSize(nStep);
1887 rEditFormatter.SetStrictFormat(bStrict);
1888
1889 Formatter& rPaintFormatter = static_cast<FormattedControlBase*>(m_pPainter.get())->get_formatter();
1890 rPaintFormatter.SetMinValue(nMin);
1891 rPaintFormatter.SetMaxValue(nMax);
1892 rPaintFormatter.SetStrictFormat(bStrict);
1893
1894 // give a formatter to the field and the painter;
1895 // test first if I can get from the service behind a connection
1896 Reference< css::util::XNumberFormatsSupplier > xSupplier;
1897 Reference< XRowSet > xForm;
1898 if ( m_rColumn.GetParent().getDataSource() )
1899 xForm.set( Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY );
1900 if ( xForm.is() )
1901 xSupplier = getNumberFormats( getConnection( xForm ), true );
1902 SvNumberFormatter* pFormatterUsed = nullptr;
1903 if ( xSupplier.is() )
1904 {
1905 SvNumberFormatsSupplierObj* pImplementation = comphelper::getUnoTunnelImplementation<SvNumberFormatsSupplierObj>( xSupplier );
1906 pFormatterUsed = pImplementation ? pImplementation->GetNumberFormatter() : nullptr;
1907 }
1908 if ( nullptr == pFormatterUsed )
1909 { // the cursor didn't lead to success -> standard
1910 pFormatterUsed = rEditFormatter.StandardFormatter();
1911 DBG_ASSERT( pFormatterUsed != nullptr, "DbNumericField::implAdjustGenericFieldSetting: no standard formatter given by the numeric field !" )do { if (true && (!(pFormatterUsed != nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1911" ": "), "%s", "DbNumericField::implAdjustGenericFieldSetting: no standard formatter given by the numeric field !"
); } } while (false)
;
1912 }
1913 rEditFormatter.SetFormatter( pFormatterUsed );
1914 rPaintFormatter.SetFormatter( pFormatterUsed );
1915
1916 // and then generate a format which has the desired length after the decimal point, etc.
1917 LanguageType aAppLanguage = Application::GetSettings().GetUILanguageTag().getLanguageType();
1918 OUString sFormatString = pFormatterUsed->GenerateFormat(0, aAppLanguage, bThousand, false, nScale);
1919
1920 rEditFormatter.SetFormat( sFormatString, aAppLanguage );
1921 rPaintFormatter.SetFormat( sFormatString, aAppLanguage );
1922}
1923
1924VclPtr<Control> DbNumericField::createField(BrowserDataWin* pParent, bool bSpinButton, const Reference<XPropertySet>& /*rxModel*/)
1925{
1926 return VclPtr<DoubleNumericControl>::Create(pParent, bSpinButton);
1927}
1928
1929namespace
1930{
1931 OUString lcl_setFormattedNumeric_nothrow( FormattedControlBase& _rField, const DbCellControl& _rControl,
1932 const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1933 {
1934 OUString sValue;
1935 if ( _rxField.is() )
1936 {
1937 try
1938 {
1939 double fValue = _rControl.GetValue( _rxField, _rxFormatter );
1940 if ( !_rxField->wasNull() )
1941 {
1942 _rField.get_formatter().SetValue(fValue);
1943 sValue = _rField.get_widget().get_text();
1944 }
1945 }
1946 catch( const Exception& )
1947 {
1948 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1948" ": ", "svx" );
;
1949 }
1950 }
1951 return sValue;
1952 }
1953}
1954
1955OUString DbNumericField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter, const Color** /*ppColor*/)
1956{
1957 return lcl_setFormattedNumeric_nothrow(dynamic_cast<FormattedControlBase&>(*m_pPainter), *this, _rxField, _rxFormatter);
1958}
1959
1960void DbNumericField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter)
1961{
1962 lcl_setFormattedNumeric_nothrow(dynamic_cast<FormattedControlBase&>(*m_pWindow), *this, _rxField, _rxFormatter);
1963}
1964
1965void DbNumericField::updateFromModel( Reference< XPropertySet > _rxModel )
1966{
1967 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbNumericField::updateFromModel: invalid call!" )do { if (true && (!(_rxModel.is() && m_pWindow
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "1967" ": "), "%s", "DbNumericField::updateFromModel: invalid call!"
); } } while (false)
;
1968
1969 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
1970
1971 double dValue = 0;
1972 if ( _rxModel->getPropertyValue( FM_PROP_VALUE"Value" ) >>= dValue )
1973 {
1974 Formatter& rFormatter = pControl->get_formatter();
1975 rFormatter.SetValue(dValue);
1976 }
1977 else
1978 pControl->get_widget().set_text(OUString());
1979}
1980
1981bool DbNumericField::commitControl()
1982{
1983 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
1984 OUString aText(pControl->get_widget().get_text());
1985 Any aVal;
1986
1987 if (!aText.isEmpty()) // not empty
1988 {
1989 Formatter& rFormatter = pControl->get_formatter();
1990 double fValue = rFormatter.GetValue();
1991 aVal <<= fValue;
1992 }
1993 m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE"Value", aVal);
1994 return true;
1995}
1996
1997DbCurrencyField::DbCurrencyField(DbGridColumn& _rColumn)
1998 :DbSpinField( _rColumn )
1999{
2000 doPropertyListening( FM_PROP_DECIMAL_ACCURACY"DecimalAccuracy" );
2001 doPropertyListening( FM_PROP_VALUEMIN"ValueMin" );
2002 doPropertyListening( FM_PROP_VALUEMAX"ValueMax" );
2003 doPropertyListening( FM_PROP_VALUESTEP"ValueStep" );
2004 doPropertyListening( FM_PROP_STRICTFORMAT"StrictFormat" );
2005 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP"ShowThousandsSeparator" );
2006 doPropertyListening( FM_PROP_CURRENCYSYMBOL"CurrencySymbol" );
2007}
2008
2009void DbCurrencyField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2010{
2011 DBG_ASSERT( m_pWindow, "DbCurrencyField::implAdjustGenericFieldSetting: not to be called without window!" )do { if (true && (!(m_pWindow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2011" ": "), "%s", "DbCurrencyField::implAdjustGenericFieldSetting: not to be called without window!"
); } } while (false)
;
2012 DBG_ASSERT( _rxModel.is(), "DbCurrencyField::implAdjustGenericFieldSetting: invalid model!" )do { if (true && (!(_rxModel.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2012" ": "), "%s", "DbCurrencyField::implAdjustGenericFieldSetting: invalid model!"
); } } while (false)
;
2013 if ( !m_pWindow || !_rxModel.is() )
2014 return;
2015
2016 sal_Int16 nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY"DecimalAccuracy" ) );
2017 double nMin = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN"ValueMin" ) );
2018 double nMax = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX"ValueMax" ) );
2019 double nStep = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP"ValueStep" ) );
2020 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT"StrictFormat" ) );
2021 bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP"ShowThousandsSeparator" ) );
2022 OUString aStr( getString( _rxModel->getPropertyValue(FM_PROP_CURRENCYSYMBOL"CurrencySymbol" ) ) );
2023
2024 Formatter& rEditFormatter = static_cast<FormattedControlBase*>(m_pWindow.get())->get_formatter();
2025 rEditFormatter.SetDecimalDigits(nScale);
2026 rEditFormatter.SetMinValue(nMin);
2027 rEditFormatter.SetMaxValue(nMax);
2028 rEditFormatter.SetSpinSize(nStep);
2029 rEditFormatter.SetStrictFormat(bStrict);
2030 weld::LongCurrencyFormatter& rCurrencyEditFormatter = static_cast<weld::LongCurrencyFormatter&>(rEditFormatter);
2031 rCurrencyEditFormatter.SetUseThousandSep(bThousand);
2032 rCurrencyEditFormatter.SetCurrencySymbol(aStr);
2033
2034 Formatter& rPaintFormatter = static_cast<FormattedControlBase*>(m_pPainter.get())->get_formatter();
2035 rPaintFormatter.SetDecimalDigits(nScale);
2036 rPaintFormatter.SetMinValue(nMin);
2037 rPaintFormatter.SetMaxValue(nMax);
2038 rPaintFormatter.SetStrictFormat(bStrict);
2039 weld::LongCurrencyFormatter& rPaintCurrencyFormatter = static_cast<weld::LongCurrencyFormatter&>(rPaintFormatter);
2040 rPaintCurrencyFormatter.SetUseThousandSep(bThousand);
2041 rPaintCurrencyFormatter.SetCurrencySymbol(aStr);
2042}
2043
2044VclPtr<Control> DbCurrencyField::createField(BrowserDataWin* pParent, bool bSpinButton, const Reference< XPropertySet >& /*rxModel*/)
2045{
2046 return VclPtr<LongCurrencyControl>::Create(pParent, bSpinButton);
2047}
2048
2049namespace
2050{
2051 OUString lcl_setFormattedCurrency_nothrow( FormattedControlBase& _rField, const DbCurrencyField& _rControl,
2052 const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
2053 {
2054 OUString sValue;
2055 if ( _rxField.is() )
2056 {
2057 try
2058 {
2059 double fValue = _rControl.GetValue( _rxField, _rxFormatter );
2060 if ( !_rxField->wasNull() )
2061 {
2062 _rField.get_formatter().SetValue(fValue);
2063 sValue = _rField.get_widget().get_text();
2064 }
2065 }
2066 catch( const Exception& )
2067 {
2068 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2068" ": ", "svx" );
;
2069 }
2070 }
2071 return sValue;
2072 }
2073}
2074
2075OUString DbCurrencyField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter, const Color** /*ppColor*/)
2076{
2077 return lcl_setFormattedCurrency_nothrow(dynamic_cast<FormattedControlBase&>(*m_pPainter), *this, _rxField, _rxFormatter);
2078}
2079
2080void DbCurrencyField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter)
2081{
2082 lcl_setFormattedCurrency_nothrow(dynamic_cast<FormattedControlBase&>(*m_pWindow), *this, _rxField, _rxFormatter);
2083}
2084
2085void DbCurrencyField::updateFromModel( Reference< XPropertySet > _rxModel )
2086{
2087 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCurrencyField::updateFromModel: invalid call!" )do { if (true && (!(_rxModel.is() && m_pWindow
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2087" ": "), "%s", "DbCurrencyField::updateFromModel: invalid call!"
); } } while (false)
;
2088
2089 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2090
2091 double dValue = 0;
2092 if ( _rxModel->getPropertyValue( FM_PROP_VALUE"Value" ) >>= dValue )
2093 {
2094 Formatter& rFormatter = pControl->get_formatter();
2095 rFormatter.SetValue(dValue);
2096 }
2097 else
2098 pControl->get_widget().set_text(OUString());
2099}
2100
2101bool DbCurrencyField::commitControl()
2102{
2103 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2104 OUString aText(pControl->get_widget().get_text());
2105 Any aVal;
2106
2107 if (!aText.isEmpty()) // not empty
2108 {
2109 Formatter& rFormatter = pControl->get_formatter();
2110 double fValue = rFormatter.GetValue();
2111 aVal <<= fValue;
2112 }
2113 m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE"Value", aVal);
2114 return true;
2115}
2116
2117DbDateField::DbDateField( DbGridColumn& _rColumn )
2118 :DbSpinField( _rColumn )
2119{
2120 doPropertyListening( FM_PROP_DATEFORMAT"DateFormat" );
2121 doPropertyListening( FM_PROP_DATEMIN"DateMin" );
2122 doPropertyListening( FM_PROP_DATEMAX"DateMax" );
2123 doPropertyListening( FM_PROP_STRICTFORMAT"StrictFormat" );
2124 doPropertyListening( FM_PROP_DATE_SHOW_CENTURY"DateShowCentury" );
2125}
2126
2127VclPtr<Control> DbDateField::createField(BrowserDataWin* pParent, bool bSpinButton, const Reference< XPropertySet >& rxModel)
2128{
2129 // check if there is a DropDown property set to TRUE
2130 bool bDropDown = !hasProperty( FM_PROP_DROPDOWN"Dropdown", rxModel )
2131 || getBOOL( rxModel->getPropertyValue( FM_PROP_DROPDOWN"Dropdown" ) );
2132 // given the apparent inability to set a custom up/down action for a gtk
2133 // spinbutton to have different up/down dates depending on the zone the
2134 // mouse is in, show the dropdown calendar for both the spin or dropdown case
2135 return VclPtr<DateControl>::Create(pParent, bSpinButton || bDropDown);
2136}
2137
2138void DbDateField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2139{
2140 DBG_ASSERT( m_pWindow, "DbDateField::implAdjustGenericFieldSetting: not to be called without window!" )do { if (true && (!(m_pWindow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2140" ": "), "%s", "DbDateField::implAdjustGenericFieldSetting: not to be called without window!"
); } } while (false)
;
2141 DBG_ASSERT( _rxModel.is(), "DbDateField::implAdjustGenericFieldSetting: invalid model!" )do { if (true && (!(_rxModel.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2141" ": "), "%s", "DbDateField::implAdjustGenericFieldSetting: invalid model!"
); } } while (false)
;
2142 if ( !m_pWindow || !_rxModel.is() )
2143 return;
2144
2145 sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_DATEFORMAT"DateFormat" ) );
2146 util::Date aMin;
2147 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMIN ) >>= aMin )do { if (!(_rxModel->getPropertyValue( "DateMin" ) >>=
aMin)) do { if (true && (!(0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2147" ": "), "OSL_ASSERT: %s", "0"); } } while (false);
} while (0)
;
2148 util::Date aMax;
2149 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMAX ) >>= aMax )do { if (!(_rxModel->getPropertyValue( "DateMax" ) >>=
aMax)) do { if (true && (!(0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2149" ": "), "OSL_ASSERT: %s", "0"); } } while (false);
} while (0)
;
2150 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT"StrictFormat" ) );
2151
2152 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2153 weld::DateFormatter& rControlFormatter = static_cast<weld::DateFormatter&>(pControl->get_formatter());
2154
2155 FormattedControlBase* pPainter = static_cast<FormattedControlBase*>(m_pPainter.get());
2156 weld::DateFormatter& rPainterFormatter = static_cast<weld::DateFormatter&>(pPainter->get_formatter());
2157
2158 Any aCentury = _rxModel->getPropertyValue( FM_PROP_DATE_SHOW_CENTURY"DateShowCentury" );
2159 if ( aCentury.getValueType().getTypeClass() != TypeClass_VOID )
2160 {
2161 bool bShowDateCentury = getBOOL( aCentury );
2162
2163 rControlFormatter.SetShowDateCentury(bShowDateCentury);
2164 rPainterFormatter.SetShowDateCentury(bShowDateCentury);
2165 }
2166
2167 rControlFormatter.SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) );
2168 rControlFormatter.SetMin( aMin );
2169 rControlFormatter.SetMax( aMax );
2170 rControlFormatter.SetStrictFormat( bStrict );
2171 rControlFormatter.EnableEmptyField( true );
2172
2173 rPainterFormatter.SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) );
2174 rPainterFormatter.SetMin( aMin );
2175 rPainterFormatter.SetMax( aMax );
2176 rPainterFormatter.SetStrictFormat( bStrict );
2177 rPainterFormatter.EnableEmptyField( true );
2178}
2179
2180namespace
2181{
2182 OUString lcl_setFormattedDate_nothrow(DateControl& _rField, const Reference<XColumn>& _rxField)
2183 {
2184 OUString sDate;
2185 if ( _rxField.is() )
2186 {
2187 try
2188 {
2189 css::util::Date aValue = _rxField->getDate();
2190 if (!_rxField->wasNull())
2191 {
2192 _rField.SetDate(::Date(aValue.Day, aValue.Month, aValue.Year));
2193 sDate = _rField.get_widget().get_text();
2194 }
2195 }
2196 catch( const Exception& )
2197 {
2198 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2198" ": ", "svx" );
;
2199 }
2200 }
2201 return sDate;
2202 }
2203}
2204
2205OUString DbDateField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
2206{
2207 return lcl_setFormattedDate_nothrow(*static_cast<DateControl*>(m_pPainter.get()), _rxField);
2208}
2209
2210void DbDateField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2211{
2212 lcl_setFormattedDate_nothrow(*static_cast<DateControl*>(m_pWindow.get()), _rxField);
2213}
2214
2215void DbDateField::updateFromModel( Reference< XPropertySet > _rxModel )
2216{
2217 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbDateField::updateFromModel: invalid call!" )do { if (true && (!(_rxModel.is() && m_pWindow
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2217" ": "), "%s", "DbDateField::updateFromModel: invalid call!"
); } } while (false)
;
2218
2219 DateControl* pControl = static_cast<DateControl*>(m_pWindow.get());
2220
2221 util::Date aDate;
2222 if ( _rxModel->getPropertyValue( FM_PROP_DATE"Date" ) >>= aDate )
2223 pControl->SetDate(::Date(aDate));
2224 else
2225 pControl->get_widget().set_text(OUString());
2226}
2227
2228bool DbDateField::commitControl()
2229{
2230 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2231 OUString aText(pControl->get_widget().get_text());
2232 Any aVal;
2233
2234 if (!aText.isEmpty()) // not empty
2235 {
2236 weld::DateFormatter& rControlFormatter = static_cast<weld::DateFormatter&>(pControl->get_formatter());
2237 aVal <<= rControlFormatter.GetDate().GetUNODate();
2238 }
2239
2240 m_rColumn.getModel()->setPropertyValue(FM_PROP_DATE"Date", aVal);
2241 return true;
2242}
2243
2244DbTimeField::DbTimeField( DbGridColumn& _rColumn )
2245 :DbSpinField( _rColumn, css::awt::TextAlign::LEFT )
2246{
2247 doPropertyListening( FM_PROP_TIMEFORMAT"TimeFormat" );
2248 doPropertyListening( FM_PROP_TIMEMIN"TimeMin" );
2249 doPropertyListening( FM_PROP_TIMEMAX"TimeMax" );
2250 doPropertyListening( FM_PROP_STRICTFORMAT"StrictFormat" );
2251}
2252
2253VclPtr<Control> DbTimeField::createField(BrowserDataWin* pParent, bool bSpinButton, const Reference< XPropertySet >& /*rxModel*/ )
2254{
2255 return VclPtr<TimeControl>::Create(pParent, bSpinButton);
2256}
2257
2258void DbTimeField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2259{
2260 DBG_ASSERT( m_pWindow, "DbTimeField::implAdjustGenericFieldSetting: not to be called without window!" )do { if (true && (!(m_pWindow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2260" ": "), "%s", "DbTimeField::implAdjustGenericFieldSetting: not to be called without window!"
); } } while (false)
;
2261 DBG_ASSERT( _rxModel.is(), "DbTimeField::implAdjustGenericFieldSetting: invalid model!" )do { if (true && (!(_rxModel.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2261" ": "), "%s", "DbTimeField::implAdjustGenericFieldSetting: invalid model!"
); } } while (false)
;
2262 if ( !m_pWindow || !_rxModel.is() )
2263 return;
2264
2265 sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_TIMEFORMAT"TimeFormat" ) );
2266 util::Time aMin;
2267 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMIN ) >>= aMin )do { if (!(_rxModel->getPropertyValue( "TimeMin" ) >>=
aMin)) do { if (true && (!(0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2267" ": "), "OSL_ASSERT: %s", "0"); } } while (false);
} while (0)
;
2268 util::Time aMax;
2269 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMAX ) >>= aMax )do { if (!(_rxModel->getPropertyValue( "TimeMax" ) >>=
aMax)) do { if (true && (!(0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2269" ": "), "OSL_ASSERT: %s", "0"); } } while (false);
} while (0)
;
2270 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT"StrictFormat" ) );
2271
2272 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2273 weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
2274
2275 rControlFormatter.SetExtFormat(static_cast<ExtTimeFieldFormat>(nFormat));
2276 rControlFormatter.SetMin(aMin);
2277 rControlFormatter.SetMax(aMax);
2278 rControlFormatter.SetStrictFormat(bStrict);
2279 rControlFormatter.EnableEmptyField(true);
2280
2281 FormattedControlBase* pPainter = static_cast<FormattedControlBase*>(m_pPainter.get());
2282 weld::TimeFormatter& rPainterFormatter = static_cast<weld::TimeFormatter&>(pPainter->get_formatter());
2283
2284 rPainterFormatter.SetExtFormat(static_cast<ExtTimeFieldFormat>(nFormat));
2285 rPainterFormatter.SetMin(aMin);
2286 rPainterFormatter.SetMax(aMax);
2287 rPainterFormatter.SetStrictFormat(bStrict);
2288 rPainterFormatter.EnableEmptyField(true);
2289}
2290
2291namespace
2292{
2293 OUString lcl_setFormattedTime_nothrow(TimeControl& _rField, const Reference<XColumn>& _rxField)
2294 {
2295 OUString sTime;
2296 if ( _rxField.is() )
2297 {
2298 try
2299 {
2300 css::util::Time aValue = _rxField->getTime();
2301 if (!_rxField->wasNull())
2302 {
2303 static_cast<weld::TimeFormatter&>(_rField.get_formatter()).SetTime( ::tools::Time( aValue ) );
2304 sTime = _rField.get_widget().get_text();
2305 }
2306 }
2307 catch( const Exception& )
2308 {
2309 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2309" ": ", "svx" );
;
2310 }
2311 }
2312 return sTime;
2313 }
2314}
2315
2316OUString DbTimeField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
2317{
2318 return lcl_setFormattedTime_nothrow(*static_cast<TimeControl*>(m_pPainter.get()), _rxField);
2319}
2320
2321void DbTimeField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2322{
2323 lcl_setFormattedTime_nothrow(*static_cast<TimeControl*>(m_pWindow.get()), _rxField);
2324}
2325
2326void DbTimeField::updateFromModel( Reference< XPropertySet > _rxModel )
2327{
2328 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTimeField::updateFromModel: invalid call!" )do { if (true && (!(_rxModel.is() && m_pWindow
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2328" ": "), "%s", "DbTimeField::updateFromModel: invalid call!"
); } } while (false)
;
2329
2330 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2331 weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
2332
2333 util::Time aTime;
2334 if ( _rxModel->getPropertyValue( FM_PROP_TIME"Time" ) >>= aTime )
2335 rControlFormatter.SetTime(::tools::Time(aTime));
2336 else
2337 pControl->get_widget().set_text(OUString());
2338}
2339
2340bool DbTimeField::commitControl()
2341{
2342 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2343 OUString aText(pControl->get_widget().get_text());
2344 Any aVal;
2345
2346 if (!aText.isEmpty()) // not empty
2347 {
2348 weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
2349 aVal <<= rControlFormatter.GetTime().GetUNOTime();
2350 }
2351
2352 m_rColumn.getModel()->setPropertyValue(FM_PROP_TIME"Time", aVal);
2353 return true;
2354}
2355
2356DbComboBox::DbComboBox(DbGridColumn& _rColumn)
2357 :DbCellControl(_rColumn)
2358{
2359 setAlignedController( false );
2360
2361 doPropertyListening( FM_PROP_STRINGITEMLIST"StringItemList" );
2362 doPropertyListening( FM_PROP_LINECOUNT"LineCount" );
2363}
2364
2365void DbComboBox::_propertyChanged( const PropertyChangeEvent& _rEvent )
2366{
2367 if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST"StringItemList" )
2368 {
2369 SetList(_rEvent.NewValue);
2370 }
2371 else
2372 {
2373 DbCellControl::_propertyChanged( _rEvent ) ;
2374 }
2375}
2376
2377void DbComboBox::SetList(const Any& rItems)
2378{
2379 ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
2380 weld::ComboBox& rComboBox = pField->get_widget();
2381 rComboBox.clear();
2382
2383 css::uno::Sequence<OUString> aTest;
2384 if (rItems >>= aTest)
2385 {
2386 for (const OUString& rString : std::as_const(aTest))
2387 rComboBox.append_text(rString);
2388
2389 // tell the grid control that this controller is invalid and has to be re-initialized
2390 invalidatedController();
2391 }
2392}
2393
2394void DbComboBox::implAdjustGenericFieldSetting(const Reference<XPropertySet>&)
2395{
2396 // we no longer pay attention to FM_PROP_LINECOUNT
2397}
2398
2399void DbComboBox::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
2400{
2401 m_rColumn.SetAlignmentFromModel(css::awt::TextAlign::LEFT);
2402
2403 m_pWindow = VclPtr<ComboBoxControl>::Create( &rParent );
1
Calling 'VclPtr::Create'
3
Returned allocated memory
4
Calling implicit destructor for 'VclPtr<svt::ComboBoxControl>'
5
Calling '~Reference'
12
Returning from '~Reference'
13
Returning from destructor for 'VclPtr<svt::ComboBoxControl>'
2404
2405 // selection from right to left
2406 AllSettings aSettings = m_pWindow->GetSettings();
14
Calling 'VclPtr::operator->'
2407 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2408 aStyleSettings.SetSelectionOptions(
2409 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2410 aSettings.SetStyleSettings(aStyleSettings);
2411 m_pWindow->SetSettings(aSettings, true);
2412
2413 // some initial properties
2414 Reference< XPropertySet > xModel(m_rColumn.getModel());
2415 SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST"StringItemList" ) );
2416 implAdjustGenericFieldSetting( xModel );
2417
2418 DbCellControl::Init( rParent, xCursor );
2419}
2420
2421CellControllerRef DbComboBox::CreateController() const
2422{
2423 return new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2424}
2425
2426OUString DbComboBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, const Color** /*ppColor*/)
2427{
2428 const css::uno::Reference<css::beans::XPropertySet> xPS(_rxField, UNO_QUERY);
2429 ::dbtools::FormattedColumnValue fmter( xFormatter, xPS );
2430
2431 return fmter.getFormattedValue();
2432}
2433
2434void DbComboBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2435{
2436 ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2437 pControl->get_widget().set_entry_text(GetFormatText(_rxField, xFormatter));
2438}
2439
2440void DbComboBox::updateFromModel( Reference< XPropertySet > _rxModel )
2441{
2442 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbComboBox::updateFromModel: invalid call!" )do { if (true && (!(_rxModel.is() && m_pWindow
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2442" ": "), "%s", "DbComboBox::updateFromModel: invalid call!"
); } } while (false)
;
2443
2444 OUString sText;
2445 _rxModel->getPropertyValue( FM_PROP_TEXT"Text" ) >>= sText;
2446
2447 ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2448 weld::ComboBox& rComboBox = pControl->get_widget();
2449 rComboBox.set_entry_text(sText);
2450 rComboBox.select_entry_region(0, -1);
2451}
2452
2453bool DbComboBox::commitControl()
2454{
2455 ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2456 weld::ComboBox& rComboBox = pControl->get_widget();
2457 OUString aText(rComboBox.get_active_text());
2458 m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT"Text", makeAny(aText));
2459 return true;
2460}
2461
2462
2463DbListBox::DbListBox(DbGridColumn& _rColumn)
2464 :DbCellControl(_rColumn)
2465 ,m_bBound(false)
2466{
2467 setAlignedController( false );
2468
2469 doPropertyListening( FM_PROP_STRINGITEMLIST"StringItemList" );
2470 doPropertyListening( FM_PROP_LINECOUNT"LineCount" );
2471}
2472
2473void DbListBox::_propertyChanged( const css::beans::PropertyChangeEvent& _rEvent )
2474{
2475 if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST"StringItemList" )
2476 {
2477 SetList(_rEvent.NewValue);
2478 }
2479 else
2480 {
2481 DbCellControl::_propertyChanged( _rEvent ) ;
2482 }
2483}
2484
2485void DbListBox::SetList(const Any& rItems)
2486{
2487 ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2488
2489 weld::ComboBox& rFieldList = pField->get_widget();
2490
2491 rFieldList.clear();
2492 m_bBound = false;
2493
2494 css::uno::Sequence<OUString> aTest;
2495 if (!(rItems >>= aTest))
2496 return;
2497
2498 if (aTest.hasElements())
2499 {
2500 for (const OUString& rString : std::as_const(aTest))
2501 rFieldList.append_text(rString);
2502
2503 m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ"ValueItemList") >>= m_aValueList;
2504 m_bBound = m_aValueList.hasElements();
2505
2506 // tell the grid control that this controller is invalid and has to be re-initialized
2507 invalidatedController();
2508 }
2509}
2510
2511void DbListBox::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
2512{
2513 m_rColumn.SetAlignment(css::awt::TextAlign::LEFT);
2514
2515 m_pWindow = VclPtr<ListBoxControl>::Create( &rParent );
2516
2517 // some initial properties
2518 Reference< XPropertySet > xModel( m_rColumn.getModel() );
2519 SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST"StringItemList" ) );
2520 implAdjustGenericFieldSetting( xModel );
2521
2522 DbCellControl::Init( rParent, xCursor );
2523}
2524
2525void DbListBox::implAdjustGenericFieldSetting( const Reference< XPropertySet >& /*rxModel*/ )
2526{
2527 // ignore FM_PROP_LINECOUNT
2528}
2529
2530CellControllerRef DbListBox::CreateController() const
2531{
2532 return new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2533}
2534
2535OUString DbListBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
2536{
2537 OUString sText;
2538 if ( _rxField.is() )
2539 {
2540 try
2541 {
2542 sText = _rxField->getString();
2543 if ( m_bBound )
2544 {
2545 sal_Int32 nPos = ::comphelper::findValue( m_aValueList, sText );
2546 if ( nPos != -1 )
2547 sText = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget().get_text(nPos);
2548 else
2549 sText.clear();
2550 }
2551 }
2552 catch( const Exception& )
2553 {
2554 DBG_UNHANDLED_EXCEPTION("svx")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2554" ": ", "svx" );
;
2555 }
2556 }
2557 return sText;
2558}
2559
2560void DbListBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2561{
2562 OUString sFormattedText( GetFormatText( _rxField, xFormatter ) );
2563 weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2564 if (!sFormattedText.isEmpty())
2565 rComboBox.set_active_text(sFormattedText);
2566 else
2567 rComboBox.set_active(-1);
2568}
2569
2570void DbListBox::updateFromModel( Reference< XPropertySet > _rxModel )
2571{
2572 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbListBox::updateFromModel: invalid call!" )do { if (true && (!(_rxModel.is() && m_pWindow
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2572" ": "), "%s", "DbListBox::updateFromModel: invalid call!"
); } } while (false)
;
2573
2574 Sequence< sal_Int16 > aSelection;
2575 _rxModel->getPropertyValue( FM_PROP_SELECT_SEQ"SelectedItems" ) >>= aSelection;
2576
2577 sal_Int16 nSelection = -1;
2578 if ( aSelection.hasElements() )
2579 nSelection = aSelection[ 0 ];
2580
2581 weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2582
2583 if (nSelection >= 0 && nSelection < rComboBox.get_count())
2584 rComboBox.set_active(nSelection);
2585 else
2586 rComboBox.set_active(-1);
2587}
2588
2589bool DbListBox::commitControl()
2590{
2591 Any aVal;
2592 Sequence<sal_Int16> aSelectSeq;
2593 weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2594 auto nActive = rComboBox.get_active();
2595 if (nActive != -1)
2596 {
2597 aSelectSeq.realloc(1);
2598 *aSelectSeq.getArray() = static_cast<sal_Int16>(nActive);
2599 }
2600 aVal <<= aSelectSeq;
2601 m_rColumn.getModel()->setPropertyValue(FM_PROP_SELECT_SEQ"SelectedItems", aVal);
2602 return true;
2603}
2604
2605DbFilterField::DbFilterField(const Reference< XComponentContext >& rxContext,DbGridColumn& _rColumn)
2606 :DbCellControl(_rColumn)
2607 ,OSQLParserClient(rxContext)
2608 ,m_nControlClass(css::form::FormComponentType::TEXTFIELD)
2609 ,m_bFilterList(false)
2610 ,m_bFilterListFilled(false)
2611{
2612
2613 setAlignedController( false );
2614}
2615
2616DbFilterField::~DbFilterField()
2617{
2618 if (m_nControlClass == css::form::FormComponentType::CHECKBOX)
2619 static_cast<CheckBoxControl*>(m_pWindow.get())->SetClickHdl( Link<weld::Button&,void>() );
2620
2621}
2622
2623void DbFilterField::PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect)
2624{
2625 static const DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter | DrawTextFlags::Left;
2626 switch (m_nControlClass)
2627 {
2628 case FormComponentType::CHECKBOX:
2629 {
2630 // center the checkbox within the space available
2631 CheckBoxControl* pControl = static_cast<CheckBoxControl*>(m_pPainter.get());
2632 Size aBoxSize = pControl->GetBox().get_preferred_size();
2633 tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
2634 rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
2635 aBoxSize);
2636
2637 DbCellControl::PaintCell(rDev, aRect);
2638 break;
2639 }
2640 case FormComponentType::LISTBOX:
2641 rDev.DrawText(rRect, static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().get_active_text(), nStyle);
2642 break;
2643 default:
2644 rDev.DrawText(rRect, m_aText, nStyle);
2645 }
2646}
2647
2648void DbFilterField::SetList(const Any& rItems, bool bComboBox)
2649{
2650 css::uno::Sequence<OUString> aTest;
2651 rItems >>= aTest;
2652 if (!aTest.hasElements())
2653 return;
2654
2655 if (bComboBox)
2656 {
2657 ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
2658 weld::ComboBox& rComboBox = pField->get_widget();
2659 for (const OUString& rString : std::as_const(aTest))
2660 rComboBox.append_text(rString);
2661 }
2662 else
2663 {
2664 ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2665 weld::ComboBox& rFieldBox = pField->get_widget();
2666 for (const OUString& rString : std::as_const(aTest))
2667 rFieldBox.append_text(rString);
2668
2669 m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ"ValueItemList") >>= m_aValueList;
2670 }
2671}
2672
2673void DbFilterField::CreateControl(BrowserDataWin* pParent, const Reference< css::beans::XPropertySet >& xModel)
2674{
2675 switch (m_nControlClass)
2676 {
2677 case css::form::FormComponentType::CHECKBOX:
2678 m_pWindow = VclPtr<CheckBoxControl>::Create(pParent);
2679 m_pWindow->SetPaintTransparent( true );
2680 static_cast<CheckBoxControl*>(m_pWindow.get())->SetClickHdl( LINK( this, DbFilterField, OnClick )::tools::detail::makeLink( ::tools::detail::castTo<DbFilterField
*>(this), &DbFilterField::LinkStubOnClick)
);
2681
2682 m_pPainter = VclPtr<CheckBoxControl>::Create(pParent);
2683 m_pPainter->SetPaintTransparent( true );
2684 m_pPainter->SetBackground();
2685 break;
2686 case css::form::FormComponentType::LISTBOX:
2687 {
2688 m_pWindow = VclPtr<ListBoxControl>::Create(pParent);
2689 Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST"StringItemList");
2690 SetList(aItems, false);
2691 } break;
2692 case css::form::FormComponentType::COMBOBOX:
2693 {
2694 m_pWindow = VclPtr<ComboBoxControl>::Create(pParent);
2695
2696 AllSettings aSettings = m_pWindow->GetSettings();
2697 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2698 aStyleSettings.SetSelectionOptions(
2699 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2700 aSettings.SetStyleSettings(aStyleSettings);
2701 m_pWindow->SetSettings(aSettings, true);
2702
2703 if (!m_bFilterList)
2704 {
2705 Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST"StringItemList");
2706 SetList(aItems, true);
2707 }
2708
2709 } break;
2710 default:
2711 {
2712 m_pWindow = VclPtr<EditControl>::Create(pParent);
2713 AllSettings aSettings = m_pWindow->GetSettings();
2714 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2715 aStyleSettings.SetSelectionOptions(
2716 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2717 aSettings.SetStyleSettings(aStyleSettings);
2718 m_pWindow->SetSettings(aSettings, true);
2719 }
2720 }
2721}
2722
2723void DbFilterField::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
2724{
2725 Reference< css::beans::XPropertySet > xModel(m_rColumn.getModel());
2726 m_rColumn.SetAlignment(css::awt::TextAlign::LEFT);
2727
2728 if (xModel.is())
2729 {
2730 m_bFilterList = ::comphelper::hasProperty(FM_PROP_FILTERPROPOSAL"UseFilterValueProposal", xModel) && ::comphelper::getBOOL(xModel->getPropertyValue(FM_PROP_FILTERPROPOSAL"UseFilterValueProposal"));
2731 if (m_bFilterList)
2732 m_nControlClass = css::form::FormComponentType::COMBOBOX;
2733 else
2734 {
2735 sal_Int16 nClassId = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_CLASSID"ClassId"));
2736 switch (nClassId)
2737 {
2738 case FormComponentType::CHECKBOX:
2739 case FormComponentType::LISTBOX:
2740 case FormComponentType::COMBOBOX:
2741 m_nControlClass = nClassId;
2742 break;
2743 default:
2744 if (m_bFilterList)
2745 m_nControlClass = FormComponentType::COMBOBOX;
2746 else
2747 m_nControlClass = FormComponentType::TEXTFIELD;
2748 }
2749 }
2750 }
2751
2752 CreateControl( &rParent, xModel );
2753 DbCellControl::Init( rParent, xCursor );
2754
2755 // filter cells are never readonly
2756 ControlBase* pAsEdit = dynamic_cast<ControlBase*>(m_pWindow.get());
2757 if (pAsEdit)
2758 pAsEdit->SetEditableReadOnly(false);
2759}
2760
2761CellControllerRef DbFilterField::CreateController() const
2762{
2763 CellControllerRef xController;
2764 switch (m_nControlClass)
2765 {
2766 case css::form::FormComponentType::CHECKBOX:
2767 xController = new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
2768 break;
2769 case css::form::FormComponentType::LISTBOX:
2770 xController = new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2771 break;
2772 case css::form::FormComponentType::COMBOBOX:
2773 xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2774 break;
2775 default:
2776 if (m_bFilterList)
2777 xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2778 else
2779 xController = new EditCellController(static_cast<EditControlBase*>(m_pWindow.get()));
2780 }
2781 return xController;
2782}
2783
2784void DbFilterField::updateFromModel( Reference< XPropertySet > _rxModel )
2785{
2786 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFilterField::updateFromModel: invalid call!" )do { if (true && (!(_rxModel.is() && m_pWindow
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2786" ": "), "%s", "DbFilterField::updateFromModel: invalid call!"
); } } while (false)
;
2787
2788 OSL_FAIL( "DbListBox::updateFromModel: not implemented yet (how the hell did you reach this?)!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "2788" ": "), "%s", "DbListBox::updateFromModel: not implemented yet (how the hell did you reach this?)!"
); } } while (false)
;
2789 // TODO: implement this.
2790 // remember: updateFromModel should be some kind of opposite of commitControl
2791}
2792
2793bool DbFilterField::commitControl()
2794{
2795 OUString aText(m_aText);
2796 switch (m_nControlClass)
2797 {
2798 case css::form::FormComponentType::CHECKBOX:
2799 return true;
2800 case css::form::FormComponentType::LISTBOX:
2801 {
2802 aText.clear();
2803 weld::ComboBox& rComboBox = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget();
2804 auto nActive = rComboBox.get_active();
2805 if (nActive != -1)
2806 {
2807 sal_Int16 nPos = static_cast<sal_Int16>(nActive);
2808 if ( ( nPos >= 0 ) && ( nPos < m_aValueList.getLength() ) )
2809 aText = m_aValueList.getConstArray()[nPos];
2810 }
2811
2812 if (m_aText != aText)
2813 {
2814 m_aText = aText;
2815 m_aCommitLink.Call(*this);
2816 }
2817 return true;
2818 }
2819 case css::form::FormComponentType::COMBOBOX:
2820 {
2821 aText = static_cast<ComboBoxControl*>(m_pWindow.get())->get_widget().get_active_text();
2822 break;
2823 }
2824 default:
2825 {
2826 aText = static_cast<EditControlBase*>(m_pWindow.get())->get_widget().get_text();
2827 break;
2828 }
2829 }
2830
2831 if (m_aText != aText)
2832 {
2833 // check the text with the SQL-Parser
2834 OUString aNewText(comphelper::string::stripEnd(aText, ' '));
2835 if (!aNewText.isEmpty())
2836 {
2837 OUString aErrorMsg;
2838 Reference< XNumberFormatter > xNumberFormatter(m_rColumn.GetParent().getNumberFormatter());
2839
2840 std::unique_ptr< OSQLParseNode > pParseNode = predicateTree(aErrorMsg, aNewText,xNumberFormatter, m_rColumn.GetField());
2841 if (pParseNode != nullptr)
2842 {
2843 OUString aPreparedText;
2844
2845 css::lang::Locale aAppLocale = Application::GetSettings().GetUILanguageTag().getLocale();
2846
2847 Reference< XRowSet > xDataSourceRowSet(
2848 Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY);
2849 Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
2850
2851 pParseNode->parseNodeToPredicateStr(aPreparedText,
2852 xConnection,
2853 xNumberFormatter,
2854 m_rColumn.GetField(),
2855 OUString(),
2856 aAppLocale,
2857 OUString("."),
2858 getParseContext());
2859 m_aText = aPreparedText;
2860 }
2861 else
2862 {
2863
2864 SQLException aError;
2865 aError.Message = aErrorMsg;
2866 displayException(aError, m_pWindow->GetParent());
2867 // TODO: transport the title
2868
2869 return false;
2870 }
2871 }
2872 else
2873 m_aText = aText;
2874
2875 m_pWindow->SetText(m_aText);
2876 m_aCommitLink.Call(*this);
2877 }
2878 return true;
2879}
2880
2881
2882void DbFilterField::SetText(const OUString& rText)
2883{
2884 m_aText = rText;
2885 switch (m_nControlClass)
2886 {
2887 case css::form::FormComponentType::CHECKBOX:
2888 {
2889 TriState eState;
2890 if (rText == "1")
2891 eState = TRISTATE_TRUE;
2892 else if (rText == "0")
2893 eState = TRISTATE_FALSE;
2894 else
2895 eState = TRISTATE_INDET;
2896
2897 static_cast<CheckBoxControl*>(m_pWindow.get())->SetState(eState);
2898 static_cast<CheckBoxControl*>(m_pPainter.get())->SetState(eState);
2899 } break;
2900 case css::form::FormComponentType::LISTBOX:
2901 {
2902 sal_Int32 nPos = ::comphelper::findValue(m_aValueList, m_aText);
2903 static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().set_active(nPos);
2904 } break;
2905 case css::form::FormComponentType::COMBOBOX:
2906 {
2907 static_cast<ComboBoxControl*>(m_pWindow.get())->get_widget().set_entry_text(m_aText);
2908 break;
2909 }
2910 default:
2911 {
2912 static_cast<EditControlBase*>(m_pWindow.get())->get_widget().set_text(m_aText);
2913 break;
2914 }
2915 }
2916
2917 // now force a repaint on the window
2918 m_rColumn.GetParent().RowModified(0);
2919}
2920
2921
2922void DbFilterField::Update()
2923{
2924 // should we fill the combobox with a filter proposal?
2925 if (!m_bFilterList || m_bFilterListFilled)
2926 return;
2927
2928 m_bFilterListFilled = true;
2929 Reference< css::beans::XPropertySet > xField = m_rColumn.GetField();
2930 if (!xField.is())
2931 return;
2932
2933 OUString aName;
2934 xField->getPropertyValue(FM_PROP_NAME"Name") >>= aName;
2935
2936 // the columnmodel
2937 Reference< css::container::XChild > xModelAsChild(m_rColumn.getModel(), UNO_QUERY);
2938 // the grid model
2939 xModelAsChild.set(xModelAsChild->getParent(),UNO_QUERY);
2940 Reference< XRowSet > xForm(xModelAsChild->getParent(), UNO_QUERY);
2941 if (!xForm.is())
2942 return;
2943
2944 Reference<XPropertySet> xFormProp(xForm,UNO_QUERY);
2945 Reference< XTablesSupplier > xSupTab;
2946 xFormProp->getPropertyValue("SingleSelectQueryComposer") >>= xSupTab;
2947
2948 Reference< XConnection > xConnection(getConnection(xForm));
2949 if (!xSupTab.is())
2950 return;
2951
2952 // search the field
2953 Reference< XColumnsSupplier > xSupCol(xSupTab,UNO_QUERY);
2954 Reference< css::container::XNameAccess > xFieldNames = xSupCol->getColumns();
2955 if (!xFieldNames->hasByName(aName))
2956 return;
2957
2958 Reference< css::container::XNameAccess > xTablesNames = xSupTab->getTables();
2959 Reference< css::beans::XPropertySet > xComposerFieldAsSet(xFieldNames->getByName(aName),UNO_QUERY);
2960
2961 if (!xComposerFieldAsSet.is() ||
2962 !::comphelper::hasProperty(FM_PROP_TABLENAME"TableName", xComposerFieldAsSet) ||
2963 !::comphelper::hasProperty(FM_PROP_FIELDSOURCE"FieldSource", xComposerFieldAsSet))
2964 return;
2965
2966 OUString aFieldName;
2967 OUString aTableName;
2968 xComposerFieldAsSet->getPropertyValue(FM_PROP_FIELDSOURCE"FieldSource") >>= aFieldName;
2969 xComposerFieldAsSet->getPropertyValue(FM_PROP_TABLENAME"TableName") >>= aTableName;
2970
2971 // no possibility to create a select statement
2972 // looking for the complete table name
2973 if (!xTablesNames->hasByName(aTableName))
2974 return;
2975
2976 // build a statement and send as query;
2977 // Access to the connection
2978 Reference< XStatement > xStatement;
2979 Reference< XResultSet > xListCursor;
2980 Reference< css::sdb::XColumn > xDataField;
2981
2982 try
2983 {
2984 Reference< XDatabaseMetaData > xMeta = xConnection->getMetaData();
2985
2986 OUString aQuote(xMeta->getIdentifierQuoteString());
2987 OUStringBuffer aStatement("SELECT DISTINCT ");
2988 aStatement.append(quoteName(aQuote, aName));
2989 if (!aFieldName.isEmpty() && aName != aFieldName)
2990 {
2991 aStatement.append(" AS ");
2992 aStatement.append(quoteName(aQuote, aFieldName));
2993 }
2994
2995 aStatement.append(" FROM ");
2996
2997 Reference< XPropertySet > xTableNameAccess(xTablesNames->getByName(aTableName), UNO_QUERY_THROW);
2998 aStatement.append(composeTableNameForSelect(xConnection, xTableNameAccess));
2999
3000 xStatement = xConnection->createStatement();
3001 Reference< css::beans::XPropertySet > xStatementProps(xStatement, UNO_QUERY);
3002 xStatementProps->setPropertyValue(FM_PROP_ESCAPE_PROCESSING"EscapeProcessing", makeAny(true));
3003
3004 xListCursor = xStatement->executeQuery(aStatement.makeStringAndClear());
3005
3006 Reference< css::sdbcx::XColumnsSupplier > xSupplyCols(xListCursor, UNO_QUERY);
3007 Reference< css::container::XIndexAccess > xFields(xSupplyCols->getColumns(), UNO_QUERY);
3008 xDataField.set(xFields->getByIndex(0), css::uno::UNO_QUERY);
3009 if (!xDataField.is())
3010 return;
3011 }
3012 catch(const Exception&)
3013 {
3014 ::comphelper::disposeComponent(xStatement);
3015 return;
3016 }
3017
3018 sal_Int16 i = 0;
3019 ::std::vector< OUString > aStringList;
3020 aStringList.reserve(16);
3021 OUString aStr;
3022 css::util::Date aNullDate = m_rColumn.GetParent().getNullDate();
3023 sal_Int32 nFormatKey = m_rColumn.GetKey();
3024 Reference< XNumberFormatter > xFormatter = m_rColumn.GetParent().getNumberFormatter();
3025 sal_Int16 nKeyType = ::comphelper::getNumberFormatType(xFormatter->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey);
3026
3027 while (!xListCursor->isAfterLast() && i++ < SHRT_MAX32767) // max number of entries
3028 {
3029 aStr = getFormattedValue(xDataField, xFormatter, aNullDate, nFormatKey, nKeyType);
3030 aStringList.push_back(aStr);
3031 (void)xListCursor->next();
3032 }
3033
3034 ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
3035 weld::ComboBox& rComboBox = pField->get_widget();
3036 // filling the entries for the combobox
3037 for (const auto& rString : aStringList)
3038 rComboBox.append_text(rString);
3039}
3040
3041OUString DbFilterField::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
3042{
3043 return OUString();
3044}
3045
3046void DbFilterField::UpdateFromField(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/)
3047{
3048 OSL_FAIL( "DbFilterField::UpdateFromField: cannot update a filter control from a field!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3048" ": "), "%s", "DbFilterField::UpdateFromField: cannot update a filter control from a field!"
); } } while (false)
;
3049}
3050
3051IMPL_LINK_NOARG(DbFilterField, OnClick, weld::Button&, void)void DbFilterField::LinkStubOnClick(void * instance, weld::Button
& data) { return static_cast<DbFilterField *>(instance
)->OnClick(data); } void DbFilterField::OnClick(__attribute__
((unused)) weld::Button&)
3052{
3053 TriState eState = static_cast<CheckBoxControl*>(m_pWindow.get())->GetState();
3054 OUStringBuffer aTextBuf;
3055
3056 Reference< XRowSet > xDataSourceRowSet(
3057 Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY);
3058 Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
3059 const sal_Int32 nBooleanComparisonMode = ::dbtools::DatabaseMetaData( xConnection ).getBooleanComparisonMode();
3060
3061 switch (eState)
3062 {
3063 case TRISTATE_TRUE:
3064 ::dbtools::getBooleanComparisonPredicate("", true, nBooleanComparisonMode, aTextBuf);
3065 break;
3066 case TRISTATE_FALSE:
3067 ::dbtools::getBooleanComparisonPredicate("", false, nBooleanComparisonMode, aTextBuf);
3068 break;
3069 case TRISTATE_INDET:
3070 break;
3071 }
3072
3073 const OUString aText(aTextBuf.makeStringAndClear());
3074
3075 if (m_aText != aText)
3076 {
3077 m_aText = aText;
3078 m_aCommitLink.Call(*this);
3079 }
3080}
3081
3082
3083FmXGridCell::FmXGridCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> _pControl )
3084 :OComponentHelper(m_aMutex)
3085 ,m_pColumn(pColumn)
3086 ,m_pCellControl( std::move(_pControl) )
3087 ,m_aWindowListeners( m_aMutex )
3088 ,m_aFocusListeners( m_aMutex )
3089 ,m_aKeyListeners( m_aMutex )
3090 ,m_aMouseListeners( m_aMutex )
3091 ,m_aMouseMotionListeners( m_aMutex )
3092{
3093}
3094
3095
3096void FmXGridCell::init()
3097{
3098 vcl::Window* pEventWindow( getEventWindow() );
3099 if ( pEventWindow )
3100 pEventWindow->AddEventListener( LINK( this, FmXGridCell, OnWindowEvent )::tools::detail::makeLink( ::tools::detail::castTo<FmXGridCell
*>(this), &FmXGridCell::LinkStubOnWindowEvent)
);
3101}
3102
3103
3104vcl::Window* FmXGridCell::getEventWindow() const
3105{
3106 if ( m_pCellControl )
3107 return &m_pCellControl->GetWindow();
3108 return nullptr;
3109}
3110
3111
3112FmXGridCell::~FmXGridCell()
3113{
3114 if (!OComponentHelper::rBHelper.bDisposed)
3115 {
3116 acquire();
3117 dispose();
3118 }
3119
3120}
3121
3122
3123void FmXGridCell::SetTextLineColor()
3124{
3125 if (m_pCellControl)
3126 m_pCellControl->SetTextLineColor();
3127}
3128
3129
3130void FmXGridCell::SetTextLineColor(const Color& _rColor)
3131{
3132 if (m_pCellControl)
3133 m_pCellControl->SetTextLineColor(_rColor);
3134}
3135
3136// XTypeProvider
3137
3138Sequence< Type > SAL_CALL FmXGridCell::getTypes( )
3139{
3140 Sequence< uno::Type > aTypes = ::comphelper::concatSequences(
3141 ::cppu::OComponentHelper::getTypes(),
3142 FmXGridCell_Base::getTypes()
3143 );
3144 if ( m_pCellControl )
3145 aTypes = ::comphelper::concatSequences(
3146 aTypes,
3147 FmXGridCell_WindowBase::getTypes()
3148 );
3149 return aTypes;
3150}
3151
3152
3153IMPLEMENT_GET_IMPLEMENTATION_ID( FmXGridCell )css::uno::Sequence< sal_Int8 > FmXGridCell::getImplementationId
( ) { return css::uno::Sequence<sal_Int8>(); }
3154
3155// OComponentHelper
3156
3157void FmXGridCell::disposing()
3158{
3159 lang::EventObject aEvent( *this );
3160 m_aWindowListeners.disposeAndClear( aEvent );
3161 m_aFocusListeners.disposeAndClear( aEvent );
3162 m_aKeyListeners.disposeAndClear( aEvent );
3163 m_aMouseListeners.disposeAndClear( aEvent );
3164 m_aMouseMotionListeners.disposeAndClear( aEvent );
3165
3166 OComponentHelper::disposing();
3167 m_pColumn = nullptr;
3168 m_pCellControl.reset();
3169}
3170
3171
3172Any SAL_CALL FmXGridCell::queryAggregation( const css::uno::Type& _rType )
3173{
3174 Any aReturn = OComponentHelper::queryAggregation( _rType );
3175
3176 if ( !aReturn.hasValue() )
3177 aReturn = FmXGridCell_Base::queryInterface( _rType );
3178
3179 if ( !aReturn.hasValue() && ( m_pCellControl != nullptr ) )
3180 aReturn = FmXGridCell_WindowBase::queryInterface( _rType );
3181
3182 return aReturn;
3183}
3184
3185// css::awt::XControl
3186
3187Reference< XInterface > FmXGridCell::getContext()
3188{
3189 return Reference< XInterface > ();
3190}
3191
3192
3193Reference< css::awt::XControlModel > FmXGridCell::getModel()
3194{
3195 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3196 return Reference< css::awt::XControlModel > (m_pColumn->getModel(), UNO_QUERY);
3197}
3198
3199// css::form::XBoundControl
3200
3201sal_Bool FmXGridCell::getLock()
3202{
3203 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3204 return m_pColumn->isLocked();
3205}
3206
3207
3208void FmXGridCell::setLock(sal_Bool _bLock)
3209{
3210 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3211 if (getLock() == _bLock)
3212 return;
3213 else
3214 {
3215 ::osl::MutexGuard aGuard(m_aMutex);
3216 m_pColumn->setLock(_bLock);
3217 }
3218}
3219
3220
3221void SAL_CALL FmXGridCell::setPosSize( ::sal_Int32, ::sal_Int32, ::sal_Int32, ::sal_Int32, ::sal_Int16 )
3222{
3223 OSL_FAIL( "FmXGridCell::setPosSize: not implemented" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3223" ": "), "%s", "FmXGridCell::setPosSize: not implemented"
); } } while (false)
;
3224 // not allowed to tamper with this for a grid cell
3225}
3226
3227
3228awt::Rectangle SAL_CALL FmXGridCell::getPosSize( )
3229{
3230 OSL_FAIL( "FmXGridCell::getPosSize: not implemented" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3230" ": "), "%s", "FmXGridCell::getPosSize: not implemented"
); } } while (false)
;
3231 return awt::Rectangle();
3232}
3233
3234
3235void SAL_CALL FmXGridCell::setVisible( sal_Bool )
3236{
3237 OSL_FAIL( "FmXGridCell::setVisible: not implemented" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3237" ": "), "%s", "FmXGridCell::setVisible: not implemented"
); } } while (false)
;
3238 // not allowed to tamper with this for a grid cell
3239}
3240
3241
3242void SAL_CALL FmXGridCell::setEnable( sal_Bool )
3243{
3244 OSL_FAIL( "FmXGridCell::setEnable: not implemented" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3244" ": "), "%s", "FmXGridCell::setEnable: not implemented"
); } } while (false)
;
3245 // not allowed to tamper with this for a grid cell
3246}
3247
3248
3249void SAL_CALL FmXGridCell::setFocus( )
3250{
3251 OSL_FAIL( "FmXGridCell::setFocus: not implemented" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3251" ": "), "%s", "FmXGridCell::setFocus: not implemented"
); } } while (false)
;
3252 // not allowed to tamper with this for a grid cell
3253}
3254
3255
3256void SAL_CALL FmXGridCell::addWindowListener( const Reference< awt::XWindowListener >& _rxListener )
3257{
3258 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3259 m_aWindowListeners.addInterface( _rxListener );
3260}
3261
3262
3263void SAL_CALL FmXGridCell::removeWindowListener( const Reference< awt::XWindowListener >& _rxListener )
3264{
3265 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3266 m_aWindowListeners.removeInterface( _rxListener );
3267}
3268
3269
3270void SAL_CALL FmXGridCell::addFocusListener( const Reference< awt::XFocusListener >& _rxListener )
3271{
3272 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3273 m_aFocusListeners.addInterface( _rxListener );
3274}
3275
3276
3277void SAL_CALL FmXGridCell::removeFocusListener( const Reference< awt::XFocusListener >& _rxListener )
3278{
3279 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3280 m_aFocusListeners.removeInterface( _rxListener );
3281}
3282
3283
3284void SAL_CALL FmXGridCell::addKeyListener( const Reference< awt::XKeyListener >& _rxListener )
3285{
3286 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3287 m_aKeyListeners.addInterface( _rxListener );
3288}
3289
3290
3291void SAL_CALL FmXGridCell::removeKeyListener( const Reference< awt::XKeyListener >& _rxListener )
3292{
3293 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3294 m_aKeyListeners.removeInterface( _rxListener );
3295}
3296
3297
3298void SAL_CALL FmXGridCell::addMouseListener( const Reference< awt::XMouseListener >& _rxListener )
3299{
3300 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3301 m_aMouseListeners.addInterface( _rxListener );
3302}
3303
3304
3305void SAL_CALL FmXGridCell::removeMouseListener( const Reference< awt::XMouseListener >& _rxListener )
3306{
3307 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3308 m_aMouseListeners.removeInterface( _rxListener );
3309}
3310
3311
3312void SAL_CALL FmXGridCell::addMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener )
3313{
3314 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3315 m_aMouseMotionListeners.addInterface( _rxListener );
3316}
3317
3318
3319void SAL_CALL FmXGridCell::removeMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener )
3320{
3321 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3322 m_aMouseMotionListeners.removeInterface( _rxListener );
3323}
3324
3325
3326void SAL_CALL FmXGridCell::addPaintListener( const Reference< awt::XPaintListener >& )
3327{
3328 OSL_FAIL( "FmXGridCell::addPaintListener: not implemented" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3328" ": "), "%s", "FmXGridCell::addPaintListener: not implemented"
); } } while (false)
;
3329}
3330
3331
3332void SAL_CALL FmXGridCell::removePaintListener( const Reference< awt::XPaintListener >& )
3333{
3334 OSL_FAIL( "FmXGridCell::removePaintListener: not implemented" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3334" ": "), "%s", "FmXGridCell::removePaintListener: not implemented"
); } } while (false)
;
3335}
3336
3337
3338IMPL_LINK( FmXGridCell, OnWindowEvent, VclWindowEvent&, _rEvent, void )void FmXGridCell::LinkStubOnWindowEvent(void * instance, VclWindowEvent
& data) { return static_cast<FmXGridCell *>(instance
)->OnWindowEvent(data); } void FmXGridCell::OnWindowEvent(
VclWindowEvent& _rEvent)
3339{
3340 ENSURE_OR_THROW( _rEvent.GetWindow(), "illegal window" )if( !(_rEvent.GetWindow()) ){ do { if (true && (!(_rEvent
.GetWindow()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3340" ": "), "%s", "illegal window"); } } while (false)
; throw css::uno::RuntimeException( __func__ + OUStringLiteral
(u",\n" "illegal window"), css::uno::Reference< css::uno::
XInterface >() ); }
;
3341 onWindowEvent( _rEvent.GetId(), *_rEvent.GetWindow(), _rEvent.GetData() );
3342}
3343
3344
3345void FmXGridCell::onFocusGained( const awt::FocusEvent& _rEvent )
3346{
3347 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3348 m_aFocusListeners.notifyEach( &awt::XFocusListener::focusGained, _rEvent );
3349}
3350
3351
3352void FmXGridCell::onFocusLost( const awt::FocusEvent& _rEvent )
3353{
3354 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3355 m_aFocusListeners.notifyEach( &awt::XFocusListener::focusLost, _rEvent );
3356}
3357
3358
3359void FmXGridCell::onWindowEvent( const VclEventId _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
3360{
3361 switch ( _nEventId )
3362 {
3363 case VclEventId::ControlGetFocus:
3364 case VclEventId::WindowGetFocus:
3365 case VclEventId::ControlLoseFocus:
3366 case VclEventId::WindowLoseFocus:
3367 {
3368 if ( ( _rWindow.IsCompoundControl()
3369 && ( _nEventId == VclEventId::ControlGetFocus
3370 || _nEventId == VclEventId::ControlLoseFocus
3371 )
3372 )
3373 || ( !_rWindow.IsCompoundControl()
3374 && ( _nEventId == VclEventId::WindowGetFocus
3375 || _nEventId == VclEventId::WindowLoseFocus
3376 )
3377 )
3378 )
3379 {
3380 if ( !m_aFocusListeners.getLength() )
3381 break;
3382
3383 bool bFocusGained = ( _nEventId == VclEventId::ControlGetFocus ) || ( _nEventId == VclEventId::WindowGetFocus );
3384
3385 awt::FocusEvent aEvent;
3386 aEvent.Source = *this;
3387 aEvent.FocusFlags = static_cast<sal_Int16>(_rWindow.GetGetFocusFlags());
3388 aEvent.Temporary = false;
3389
3390 if ( bFocusGained )
3391 onFocusGained( aEvent );
3392 else
3393 onFocusLost( aEvent );
3394 }
3395 }
3396 break;
3397 case VclEventId::WindowMouseButtonDown:
3398 case VclEventId::WindowMouseButtonUp:
3399 {
3400 if ( !m_aMouseListeners.getLength() )
3401 break;
3402
3403 const bool bButtonDown = ( _nEventId == VclEventId::WindowMouseButtonDown );
3404
3405 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast< const ::MouseEvent* >( _pEventData ), *this ) );
3406 m_aMouseListeners.notifyEach( bButtonDown ? &awt::XMouseListener::mousePressed : &awt::XMouseListener::mouseReleased, aEvent );
3407 }
3408 break;
3409 case VclEventId::WindowMouseMove:
3410 {
3411 const MouseEvent& rMouseEvent = *static_cast< const ::MouseEvent* >( _pEventData );
3412 if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
3413 {
3414 if ( m_aMouseListeners.getLength() != 0 )
3415 {
3416 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3417 m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? &awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
3418 }
3419 }
3420 else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() )
3421 {
3422 if ( m_aMouseMotionListeners.getLength() != 0 )
3423 {
3424 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3425 aEvent.ClickCount = 0;
3426 const bool bSimpleMove = bool( rMouseEvent.GetMode() & MouseEventModifiers::SIMPLEMOVE );
3427 m_aMouseMotionListeners.notifyEach( bSimpleMove ? &awt::XMouseMotionListener::mouseMoved: &awt::XMouseMotionListener::mouseDragged, aEvent );
3428 }
3429 }
3430 }
3431 break;
3432 case VclEventId::WindowKeyInput:
3433 case VclEventId::WindowKeyUp:
3434 {
3435 if ( !m_aKeyListeners.getLength() )
3436 break;
3437
3438 const bool bKeyPressed = ( _nEventId == VclEventId::WindowKeyInput );
3439 awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent( *static_cast< const ::KeyEvent* >( _pEventData ), *this ) );
3440 m_aKeyListeners.notifyEach( bKeyPressed ? &awt::XKeyListener::keyPressed: &awt::XKeyListener::keyReleased, aEvent );
3441 }
3442 break;
3443 default: break;
3444 }
3445}
3446
3447
3448void FmXDataCell::PaintFieldToCell(OutputDevice& rDev, const tools::Rectangle& rRect,
3449 const Reference< css::sdb::XColumn >& _rxField,
3450 const Reference< XNumberFormatter >& xFormatter)
3451{
3452 m_pCellControl->PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3453}
3454
3455
3456void FmXDataCell::UpdateFromColumn()
3457{
3458 Reference< css::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3459 if (xField.is())
3460 m_pCellControl->UpdateFromField(xField, m_pColumn->GetParent().getNumberFormatter());
3461}
3462
3463
3464FmXTextCell::FmXTextCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3465 :FmXDataCell( pColumn, std::move(pControl) )
3466 ,m_bFastPaint( true )
3467{
3468}
3469
3470
3471void FmXTextCell::PaintFieldToCell(OutputDevice& rDev,
3472 const tools::Rectangle& rRect,
3473 const Reference< css::sdb::XColumn >& _rxField,
3474 const Reference< XNumberFormatter >& xFormatter)
3475{
3476 if ( !m_bFastPaint )
3477 {
3478 FmXDataCell::PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3479 return;
3480 }
3481
3482 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter;
3483 if ( ( rDev.GetOutDevType() == OUTDEV_WINDOW ) && !static_cast< vcl::Window& >( rDev ).IsEnabled() )
3484 nStyle |= DrawTextFlags::Disable;
3485
3486 switch (m_pColumn->GetAlignment())
3487 {
3488 case css::awt::TextAlign::RIGHT:
3489 nStyle |= DrawTextFlags::Right;
3490 break;
3491 case css::awt::TextAlign::CENTER:
3492 nStyle |= DrawTextFlags::Center;
3493 break;
3494 default:
3495 nStyle |= DrawTextFlags::Left;
3496 }
3497
3498 try
3499 {
3500 const Color* pColor = nullptr;
3501 OUString aText = GetText(_rxField, xFormatter, &pColor);
3502 if (pColor != nullptr)
3503 {
3504 Color aOldTextColor( rDev.GetTextColor() );
3505 rDev.SetTextColor( *pColor );
3506 rDev.DrawText(rRect, aText, nStyle);
3507 rDev.SetTextColor( aOldTextColor );
3508 }
3509 else
3510 rDev.DrawText(rRect, aText, nStyle);
3511 }
3512 catch (const Exception&)
3513 {
3514 TOOLS_WARN_EXCEPTION("svx.fmcomp", "PaintFieldToCell")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svx.fmcomp")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "PaintFieldToCell" <<
" " << exceptionToString(tools_warn_exception)) == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.fmcomp"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3514" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "PaintFieldToCell" << " " <<
exceptionToString(tools_warn_exception)), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"PaintFieldToCell" << " " << exceptionToString(tools_warn_exception
); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.fmcomp"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3514" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "PaintFieldToCell" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("svx.fmcomp"), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3514" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "PaintFieldToCell" << " " <<
exceptionToString(tools_warn_exception)), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"PaintFieldToCell" << " " << exceptionToString(tools_warn_exception
); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svx.fmcomp"
), ("/home/maarten/src/libreoffice/core/svx/source/fmcomp/gridcell.cxx"
":" "3514" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
3515 }
3516}
3517
3518FmXEditCell::FmXEditCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3519 :FmXTextCell( pColumn, std::move(pControl) )
3520 ,m_aTextListeners(m_aMutex)
3521 ,m_aChangeListeners( m_aMutex )
3522 ,m_pEditImplementation( nullptr )
3523 ,m_bOwnEditImplementation( false )
3524{
3525
3526 DbTextField* pTextField = dynamic_cast<DbTextField*>( m_pCellControl.get() );
3527 if ( pTextField )
3528 {
3529
3530 m_pEditImplementation = pTextField->GetEditImplementation();
3531 if ( !pTextField->IsSimpleEdit() )
3532 m_bFastPaint = false;
3533 }
3534 else
3535 {
3536 m_pEditImplementation = new EntryImplementation(static_cast<EditControlBase&>(m_pCellControl->GetWindow()));
3537 m_bOwnEditImplementation = true;
3538 }
3539 m_pEditImplementation->SetAuxModifyHdl(LINK(this, FmXEditCell, ModifyHdl)::tools::detail::makeLink( ::tools::detail::castTo<FmXEditCell
*>(this), &FmXEditCell::LinkStubModifyHdl)
);
3540}
3541
3542FmXEditCell::~FmXEditCell()
3543{
3544 if (!OComponentHelper::rBHelper.bDisposed)
3545 {
3546 acquire();
3547 dispose();
3548 }
3549}
3550
3551// OComponentHelper
3552void FmXEditCell::disposing()
3553{
3554 css::lang::EventObject aEvt(*this);
3555 m_aTextListeners.disposeAndClear(aEvt);
3556 m_aChangeListeners.disposeAndClear(aEvt);
3557
3558 if ( m_bOwnEditImplementation )
3559 delete m_pEditImplementation;
3560 m_pEditImplementation = nullptr;
3561
3562 FmXDataCell::disposing();
3563}
3564
3565Any SAL_CALL FmXEditCell::queryAggregation( const css::uno::Type& _rType )
3566{
3567 Any aReturn = FmXTextCell::queryAggregation( _rType );
3568
3569 if ( !aReturn.hasValue() )
3570 aReturn = FmXEditCell_Base::queryInterface( _rType );
3571
3572 return aReturn;
3573}
3574
3575Sequence< css::uno::Type > SAL_CALL FmXEditCell::getTypes( )
3576{
3577 return ::comphelper::concatSequences(
3578 FmXTextCell::getTypes(),
3579 FmXEditCell_Base::getTypes()
3580 );
3581}
3582
3583IMPLEMENT_GET_IMPLEMENTATION_ID( FmXEditCell )css::uno::Sequence< sal_Int8 > FmXEditCell::getImplementationId
( ) { return css::uno::Sequence<sal_Int8>(); }
3584
3585// css::awt::XTextComponent
3586void SAL_CALL FmXEditCell::addTextListener(const Reference< css::awt::XTextListener >& l)
3587{
3588 m_aTextListeners.addInterface( l );
3589}
3590
3591
3592void SAL_CALL FmXEditCell::removeTextListener(const Reference< css::awt::XTextListener >& l)
3593{
3594 m_aTextListeners.removeInterface( l );
3595}
3596
3597void SAL_CALL FmXEditCell::setText( const OUString& aText )
3598{
3599 ::osl::MutexGuard aGuard( m_aMutex );
3600
3601 if ( m_pEditImplementation )
3602 {
3603 m_pEditImplementation->SetText( aText );
3604
3605 // In Java, a textChanged is fired as well; not in VCL.
3606 // css::awt::Toolkit must be Java-compliant...
3607 onTextChanged();
3608 }
3609}
3610
3611void SAL_CALL FmXEditCell::insertText(const css::awt::Selection& rSel, const OUString& aText)
3612{
3613 ::osl::MutexGuard aGuard( m_aMutex );
3614
3615 if ( m_pEditImplementation )
3616 {
3617 m_pEditImplementation->SetSelection( Selection( rSel.Min, rSel.Max ) );
3618 m_pEditImplementation->ReplaceSelected( aText );
3619 }
3620}
3621
3622OUString SAL_CALL FmXEditCell::getText()
3623{
3624 ::osl::MutexGuard aGuard( m_aMutex );
3625
3626 OUString aText;
3627 if ( m_pEditImplementation )
3628 {
3629 if ( m_pEditImplementation->GetControl().IsVisible() && m_pColumn->GetParent().getDisplaySynchron())
3630 {
3631 // if the display isn't sync with the cursor we can't ask the edit field
3632 LineEnd eLineEndFormat = getModelLineEndSetting( m_pColumn->getModel() );
3633 aText = m_pEditImplementation->GetText( eLineEndFormat );
3634 }
3635 else
3636 {
3637 Reference< css::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3638 if (xField.is())
3639 aText = GetText(xField, m_pColumn->GetParent().getNumberFormatter());
3640 }
3641 }
3642 return aText;
3643}
3644
3645OUString SAL_CALL FmXEditCell::getSelectedText()
3646{
3647 ::osl::MutexGuard aGuard( m_aMutex );
3648
3649 OUString aText;
3650 if ( m_pEditImplementation )
3651 {
3652 LineEnd eLineEndFormat = m_pColumn ? getModelLineEndSetting( m_pColumn->getModel() ) : LINEEND_LF;
3653 aText = m_pEditImplementation->GetSelected( eLineEndFormat );
3654 }
3655 return aText;
3656}
3657
3658void SAL_CALL FmXEditCell::setSelection( const css::awt::Selection& aSelection )
3659{
3660 ::osl::MutexGuard aGuard( m_aMutex );
3661
3662 if ( m_pEditImplementation )
3663 m_pEditImplementation->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
3664}
3665
3666css::awt::Selection SAL_CALL FmXEditCell::getSelection()
3667{
3668 ::osl::MutexGuard aGuard( m_aMutex );
3669
3670 Selection aSel;
3671 if ( m_pEditImplementation )
3672 aSel = m_pEditImplementation->GetSelection();
3673
3674 return css::awt::Selection(aSel.Min(), aSel.Max());
3675}
3676
3677sal_Bool SAL_CALL FmXEditCell::isEditable()
3678{
3679 ::osl::MutexGuard aGuard( m_aMutex );
3680
3681 return m_pEditImplementation && !m_pEditImplementation->IsReadOnly() && m_pEditImplementation->GetControl().IsEnabled();
3682}
3683
3684void SAL_CALL FmXEditCell::setEditable( sal_Bool bEditable )
3685{
3686 ::osl::MutexGuard aGuard( m_aMutex );
3687
3688 if ( m_pEditImplementation )
3689 m_pEditImplementation->SetReadOnly( !bEditable );
3690}
3691
3692sal_Int16 SAL_CALL FmXEditCell::getMaxTextLen()
3693{
3694 ::osl::MutexGuard aGuard( m_aMutex );
3695
3696 return m_pEditImplementation ? m_pEditImplementation->GetMaxTextLen() : 0;
3697}
3698
3699void SAL_CALL FmXEditCell::setMaxTextLen( sal_Int16 nLen )
3700{
3701 ::osl::MutexGuard aGuard( m_aMutex );
3702
3703 if ( m_pEditImplementation )
3704 m_pEditImplementation->SetMaxTextLen( nLen );
3705}
3706
3707void SAL_CALL FmXEditCell::addChangeListener( const Reference< form::XChangeListener >& Listener )
3708{
3709 m_aChangeListeners.addInterface( Listener );
3710}
3711
3712void SAL_CALL FmXEditCell::removeChangeListener( const Reference< form::XChangeListener >& Listener )
3713{
3714 m_aChangeListeners.removeInterface( Listener );
3715}
3716
3717void FmXEditCell::onTextChanged()
3718{
3719 css::awt::TextEvent aEvent;
3720 aEvent.Source = *this;
3721 m_aTextListeners.notifyEach( &awt::XTextListener::textChanged, aEvent );
3722}
3723
3724void FmXEditCell::onFocusGained( const awt::FocusEvent& _rEvent )
3725{
3726 FmXTextCell::onFocusGained( _rEvent );
3727 m_sValueOnEnter = getText();
3728}
3729
3730void FmXEditCell::onFocusLost( const awt::FocusEvent& _rEvent )
3731{
3732 FmXTextCell::onFocusLost( _rEvent );
3733
3734 if ( getText() != m_sValueOnEnter )
3735 {
3736 lang::EventObject aEvent( *this );
3737 m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvent );
3738 }
3739}
3740
3741IMPL_LINK_NOARG(FmXEditCell, ModifyHdl, LinkParamNone*, void)void FmXEditCell::LinkStubModifyHdl(void * instance, LinkParamNone
* data) { return static_cast<FmXEditCell *>(instance)->
ModifyHdl(data); } void FmXEditCell::ModifyHdl(__attribute__ (
(unused)) LinkParamNone*)
3742{
3743 if (m_aTextListeners.getLength())
3744 onTextChanged();
3745}
3746
3747FmXCheckBoxCell::FmXCheckBoxCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3748 :FmXDataCell( pColumn, std::move(pControl) )
3749 ,m_aItemListeners(m_aMutex)
3750 ,m_aActionListeners( m_aMutex )
3751 ,m_pBox( & static_cast< CheckBoxControl& >( m_pCellControl->GetWindow() ) )
3752{
3753 m_pBox->SetAuxModifyHdl(LINK(this, FmXCheckBoxCell, ModifyHdl)::tools::detail::makeLink( ::tools::detail::castTo<FmXCheckBoxCell
*>(this), &FmXCheckBoxCell::LinkStubModifyHdl)
);
3754}
3755
3756FmXCheckBoxCell::~FmXCheckBoxCell()
3757{
3758 if (!OComponentHelper::rBHelper.bDisposed)
3759 {
3760 acquire();
3761 dispose();
3762 }
3763}
3764
3765// OComponentHelper
3766void FmXCheckBoxCell::disposing()
3767{
3768 css::lang::EventObject aEvt(*this);
3769 m_aItemListeners.disposeAndClear(aEvt);
3770 m_aActionListeners.disposeAndClear(aEvt);
3771
3772 m_pBox->SetClickHdl(Link<weld::Button&,void>());
3773 m_pBox = nullptr;
3774
3775 FmXDataCell::disposing();
3776}
3777
3778
3779Any SAL_CALL FmXCheckBoxCell::queryAggregation( const css::uno::Type& _rType )
3780{
3781 Any aReturn = FmXDataCell::queryAggregation( _rType );
3782
3783 if ( !aReturn.hasValue() )
3784 aReturn = FmXCheckBoxCell_Base::queryInterface( _rType );
3785
3786 return aReturn;
3787}
3788
3789
3790Sequence< css::uno::Type > SAL_CALL FmXCheckBoxCell::getTypes( )
3791{
3792 return ::comphelper::concatSequences(
3793 FmXDataCell::getTypes(),
3794 FmXCheckBoxCell_Base::getTypes()
3795 );
3796}
3797
3798
3799IMPLEMENT_GET_IMPLEMENTATION_ID( FmXCheckBoxCell )css::uno::Sequence< sal_Int8 > FmXCheckBoxCell::getImplementationId
( ) { return css::uno::Sequence<sal_Int8>(); }
3800
3801void SAL_CALL FmXCheckBoxCell::addItemListener( const Reference< css::awt::XItemListener >& l )
3802{
3803 m_aItemListeners.addInterface( l );
3804}
3805
3806void SAL_CALL FmXCheckBoxCell::removeItemListener( const Reference< css::awt::XItemListener >& l )
3807{
3808 m_aItemListeners.removeInterface( l );
3809}
3810
3811void SAL_CALL FmXCheckBoxCell::setState( sal_Int16 n )
3812{
3813 ::osl::MutexGuard aGuard( m_aMutex );
3814
3815 if (m_pBox)
3816 {
3817 UpdateFromColumn();
3818 m_pBox->SetState( static_cast<TriState>(n) );
3819 }
3820}
3821
3822sal_Int16 SAL_CALL FmXCheckBoxCell::getState()
3823{
3824 ::osl::MutexGuard aGuard( m_aMutex );
3825
3826 if (m_pBox)
3827 {
3828 UpdateFromColumn();
3829 return static_cast<sal_Int16>(m_pBox->GetState());
3830 }
3831 return TRISTATE_INDET;
3832}
3833
3834void SAL_CALL FmXCheckBoxCell::enableTriState(sal_Bool b)
3835{
3836 ::osl::MutexGuard aGuard( m_aMutex );
3837
3838 if (m_pBox)
3839 m_pBox->EnableTriState( b );
3840}
3841
3842void SAL_CALL FmXCheckBoxCell::addActionListener( const Reference< awt::XActionListener >& Listener )
3843{
3844 m_aActionListeners.addInterface( Listener );
3845}
3846
3847
3848void SAL_CALL FmXCheckBoxCell::removeActionListener( const Reference< awt::XActionListener >& Listener )
3849{
3850 m_aActionListeners.removeInterface( Listener );
3851}
3852
3853void SAL_CALL FmXCheckBoxCell::setLabel( const OUString& Label )
3854{
3855 SolarMutexGuard aGuard;
3856 if ( m_pColumn )
3857 {
3858 DbGridControl& rGrid( m_pColumn->GetParent() );
3859 rGrid.SetColumnTitle( rGrid.GetColumnId( m_pColumn->GetFieldPos() ), Label );
3860 }
3861}
3862
3863void SAL_CALL FmXCheckBoxCell::setActionCommand( const OUString& Command )
3864{
3865 m_aActionCommand = Command;
3866}
3867
3868IMPL_LINK_NOARG(FmXCheckBoxCell, ModifyHdl, LinkParamNone*, void)void FmXCheckBoxCell::LinkStubModifyHdl(void * instance, LinkParamNone
* data) { return static_cast<FmXCheckBoxCell *>(instance
)->ModifyHdl(data); } void FmXCheckBoxCell::ModifyHdl(__attribute__
((unused)) LinkParamNone*)
3869{
3870 // check boxes are to be committed immediately (this holds for ordinary check box controls in
3871 // documents, and this must hold for check boxes in grid columns, too
3872 // 91210 - 22.08.2001 - frank.schoenheit@sun.com
3873 m_pCellControl->Commit();
3874
3875 Reference< XWindow > xKeepAlive( this );
3876 if ( m_aItemListeners.getLength() && m_pBox )
3877 {
3878 awt::ItemEvent aEvent;
3879 aEvent.Source = *this;
3880 aEvent.Highlighted = 0;
3881 aEvent.Selected = m_pBox->GetState();
3882 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
3883 }
3884 if ( m_aActionListeners.getLength() )
3885 {
3886 awt::ActionEvent aEvent;
3887 aEvent.Source = *this;
3888 aEvent.ActionCommand = m_aActionCommand;
3889 m_aActionListeners.notifyEach( &awt::XActionListener::actionPerformed, aEvent );
3890 }
3891}
3892
3893FmXListBoxCell::FmXListBoxCell(DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl)
3894 : FmXTextCell(pColumn, std::move(pControl))
3895 , m_aItemListeners(m_aMutex)
3896 , m_aActionListeners(m_aMutex)
3897 , m_pBox(&static_cast<svt::ListBoxControl&>(m_pCellControl->GetWindow()))
3898 , m_nLines(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())
3899 , m_bMulti(false)
3900{
3901 m_pBox->SetAuxModifyHdl(LINK(this, FmXListBoxCell, ChangedHdl)::tools::detail::makeLink( ::tools::detail::castTo<FmXListBoxCell
*>(this), &FmXListBoxCell::LinkStubChangedHdl)
);
3902}
3903
3904FmXListBoxCell::~FmXListBoxCell()
3905{
3906 if (!OComponentHelper::rBHelper.bDisposed)
3907 {
3908 acquire();
3909 dispose();
3910 }
3911}
3912
3913// OComponentHelper
3914void FmXListBoxCell::disposing()
3915{
3916 css::lang::EventObject aEvt(*this);
3917 m_aItemListeners.disposeAndClear(aEvt);
3918 m_aActionListeners.disposeAndClear(aEvt);
3919
3920 m_pBox->SetAuxModifyHdl(Link<LinkParamNone*,void>());
3921 m_pBox = nullptr;
3922
3923 FmXTextCell::disposing();
3924}
3925
3926Any SAL_CALL FmXListBoxCell::queryAggregation( const css::uno::Type& _rType )
3927{
3928 Any aReturn = FmXTextCell::queryAggregation(_rType);
3929
3930 if ( !aReturn.hasValue() )
3931 aReturn = FmXListBoxCell_Base::queryInterface( _rType );
3932
3933 return aReturn;
3934}
3935
3936Sequence< css::uno::Type > SAL_CALL FmXListBoxCell::getTypes( )
3937{
3938 return ::comphelper::concatSequences(
3939 FmXTextCell::getTypes(),
3940 FmXListBoxCell_Base::getTypes()
3941 );
3942}
3943
3944IMPLEMENT_GET_IMPLEMENTATION_ID( FmXListBoxCell )css::uno::Sequence< sal_Int8 > FmXListBoxCell::getImplementationId
( ) { return css::uno::Sequence<sal_Int8>(); }
3945
3946void SAL_CALL FmXListBoxCell::addItemListener(const Reference< css::awt::XItemListener >& l)
3947{
3948 m_aItemListeners.addInterface( l );
3949}
3950
3951void SAL_CALL FmXListBoxCell::removeItemListener(const Reference< css::awt::XItemListener >& l)
3952{
3953 m_aItemListeners.removeInterface( l );
3954}
3955
3956void SAL_CALL FmXListBoxCell::addActionListener(const Reference< css::awt::XActionListener >& l)
3957{
3958 m_aActionListeners.addInterface( l );
3959}
3960
3961void SAL_CALL FmXListBoxCell::removeActionListener(const Reference< css::awt::XActionListener >& l)
3962{
3963 m_aActionListeners.removeInterface( l );
3964}
3965
3966void SAL_CALL FmXListBoxCell::addItem(const OUString& aItem, sal_Int16 nPos)
3967{
3968 ::osl::MutexGuard aGuard( m_aMutex );
3969 if (m_pBox)
3970 {
3971 weld::ComboBox& rBox = m_pBox->get_widget();
3972 rBox.insert_text(nPos, aItem);
3973 }
3974}
3975
3976void SAL_CALL FmXListBoxCell::addItems(const css::uno::Sequence<OUString>& aItems, sal_Int16 nPos)
3977{
3978 ::osl::MutexGuard aGuard( m_aMutex );
3979 if (m_pBox)
3980 {
3981 weld::ComboBox& rBox = m_pBox->get_widget();
3982 sal_uInt16 nP = nPos;
3983 for ( const auto& rItem : aItems )
3984 {
3985 rBox.insert_text(nP, rItem);
3986 if ( nPos != -1 ) // Not if 0xFFFF, because LIST_APPEND
3987 nP++;
3988 }
3989 }
3990}
3991
3992void SAL_CALL FmXListBoxCell::removeItems(sal_Int16 nPos, sal_Int16 nCount)
3993{
3994 ::osl::MutexGuard aGuard( m_aMutex );
3995 if ( m_pBox )
3996 {
3997 weld::ComboBox& rBox = m_pBox->get_widget();
3998 for ( sal_uInt16 n = nCount; n; )
3999 rBox.remove( nPos + (--n) );
4000 }
4001}
4002
4003sal_Int16 SAL_CALL FmXListBoxCell::getItemCount()
4004{
4005 ::osl::MutexGuard aGuard( m_aMutex );
4006 if (!m_pBox)
4007 return 0;
4008 weld::ComboBox& rBox = m_pBox->get_widget();
4009 return rBox.get_count();
4010}
4011
4012OUString SAL_CALL FmXListBoxCell::getItem(sal_Int16 nPos)
4013{
4014 ::osl::MutexGuard aGuard( m_aMutex );
4015 if (!m_pBox)
4016 return OUString();
4017 weld::ComboBox& rBox = m_pBox->get_widget();
4018 return rBox.get_text(nPos);
4019}
4020
4021css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getItems()
4022{
4023 ::osl::MutexGuard aGuard( m_aMutex );
4024
4025 css::uno::Sequence<OUString> aSeq;
4026 if (m_pBox)
4027 {
4028 weld::ComboBox& rBox = m_pBox->get_widget();
4029 const sal_Int32 nEntries = rBox.get_count();
4030 aSeq = css::uno::Sequence<OUString>( nEntries );
4031 for ( sal_Int32 n = nEntries; n; )
4032 {
4033 --n;
4034 aSeq.getArray()[n] = rBox.get_text( n );
4035 }
4036 }
4037 return aSeq;
4038}
4039
4040sal_Int16 SAL_CALL FmXListBoxCell::getSelectedItemPos()
4041{
4042 ::osl::MutexGuard aGuard( m_aMutex );
4043 if (m_pBox)
4044 {
4045 UpdateFromColumn();
4046 weld::ComboBox& rBox = m_pBox->get_widget();
4047 sal_Int32 nPos = rBox.get_active();
4048 if (nPos > SHRT_MAX32767 || nPos < SHRT_MIN(-32767 -1))
4049 throw std::out_of_range("awt::XListBox::getSelectedItemPos can only return a short");
4050 return nPos;
4051 }
4052 return 0;
4053}
4054
4055Sequence< sal_Int16 > SAL_CALL FmXListBoxCell::getSelectedItemsPos()
4056{
4057 ::osl::MutexGuard aGuard( m_aMutex );
4058 Sequence<sal_Int16> aSeq;
4059
4060 if (m_pBox)
4061 {
4062 UpdateFromColumn();
4063 weld::ComboBox& rBox = m_pBox->get_widget();
4064 auto nActive = rBox.get_active();
4065 if (nActive != -1)
4066 {
4067 aSeq = Sequence<sal_Int16>(1);
4068 aSeq.getArray()[0] = nActive;
4069 }
4070 }
4071 return aSeq;
4072}
4073
4074OUString SAL_CALL FmXListBoxCell::getSelectedItem()
4075{
4076 ::osl::MutexGuard aGuard( m_aMutex );
4077
4078 OUString aItem;
4079
4080 if (m_pBox)
4081 {
4082 UpdateFromColumn();
4083 weld::ComboBox& rBox = m_pBox->get_widget();
4084 aItem = rBox.get_active_text();
4085 }
4086
4087 return aItem;
4088}
4089
4090css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getSelectedItems()
4091{
4092 ::osl::MutexGuard aGuard( m_aMutex );
4093
4094 css::uno::Sequence<OUString> aSeq;
4095
4096 if (m_pBox)
4097 {
4098 UpdateFromColumn();
4099 weld::ComboBox& rBox = m_pBox->get_widget();
4100 auto nActive = rBox.get_active();
4101 if (nActive != -1)
4102 {
4103 aSeq = css::uno::Sequence<OUString>(1);
4104 aSeq.getArray()[0] = rBox.get_text(nActive);
4105 }
4106 }
4107 return aSeq;
4108}
4109
4110void SAL_CALL FmXListBoxCell::selectItemPos(sal_Int16 nPos, sal_Bool bSelect)
4111{
4112 ::osl::MutexGuard aGuard( m_aMutex );
4113
4114 if (m_pBox)
4115 {
4116 weld::ComboBox& rBox = m_pBox->get_widget();
4117 if (bSelect)
4118 rBox.set_active(nPos);
4119 else if (nPos == rBox.get_active())
4120 rBox.set_active(-1);
4121 }
4122}
4123
4124void SAL_CALL FmXListBoxCell::selectItemsPos(const Sequence< sal_Int16 >& aPositions, sal_Bool bSelect)
4125{
4126 ::osl::MutexGuard aGuard( m_aMutex );
4127
4128 if (m_pBox)
4129 {
4130 weld::ComboBox& rBox = m_pBox->get_widget();
4131 for ( sal_uInt16 n = static_cast<sal_uInt16>(aPositions.getLength()); n; )
4132 {
4133 auto nPos = static_cast<sal_uInt16>(aPositions.getConstArray()[--n]);
4134 if (bSelect)
4135 rBox.set_active(nPos);
4136 else if (nPos == rBox.get_active())
4137 rBox.set_active(-1);
4138 }
4139 }
4140}
4141
4142void SAL_CALL FmXListBoxCell::selectItem(const OUString& aItem, sal_Bool bSelect)
4143{
4144 ::osl::MutexGuard aGuard( m_aMutex );
4145
4146 if (m_pBox)
4147 {
4148 weld::ComboBox& rBox = m_pBox->get_widget();
4149 auto nPos = rBox.find_text(aItem);
4150 if (bSelect)
4151 rBox.set_active(nPos);
4152 else if (nPos == rBox.get_active())
4153 rBox.set_active(-1);
4154 }
4155}
4156
4157sal_Bool SAL_CALL FmXListBoxCell::isMutipleMode()
4158{
4159 ::osl::MutexGuard aGuard( m_aMutex );
4160
4161 return m_bMulti;
4162}
4163
4164void SAL_CALL FmXListBoxCell::setMultipleMode(sal_Bool bMulti)
4165{
4166 ::osl::MutexGuard aGuard( m_aMutex );
4167
4168 m_bMulti = bMulti;
4169}
4170
4171sal_Int16 SAL_CALL FmXListBoxCell::getDropDownLineCount()
4172{
4173 ::osl::MutexGuard aGuard( m_aMutex );
4174 return m_nLines;
4175}
4176
4177void SAL_CALL FmXListBoxCell::setDropDownLineCount(sal_Int16 nLines)
4178{
4179 ::osl::MutexGuard aGuard( m_aMutex );
4180
4181 m_nLines = nLines; // just store it to return it
4182}
4183
4184void SAL_CALL FmXListBoxCell::makeVisible(sal_Int16 /*nEntry*/)
4185{
4186}
4187
4188IMPL_LINK_NOARG(FmXListBoxCell, ChangedHdl, LinkParamNone*, void)void FmXListBoxCell::LinkStubChangedHdl(void * instance, LinkParamNone
* data) { return static_cast<FmXListBoxCell *>(instance
)->ChangedHdl(data); } void FmXListBoxCell::ChangedHdl(__attribute__
((unused)) LinkParamNone*)
4189{
4190 if (!m_pBox)
4191 return;
4192
4193 weld::ComboBox& rBox = m_pBox->get_widget();
4194
4195 if (!rBox.changed_by_direct_pick())
4196 return;
4197
4198 OnDoubleClick();
4199
4200 css::awt::ItemEvent aEvent;
4201 aEvent.Source = *this;
4202 aEvent.Highlighted = 0;
4203
4204 // with multiple selection 0xFFFF, otherwise the ID
4205 aEvent.Selected = (rBox.get_active() != -1 )
4206 ? rBox.get_active() : 0xFFFF;
4207
4208 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4209}
4210
4211void FmXListBoxCell::OnDoubleClick()
4212{
4213 ::comphelper::OInterfaceIteratorHelper2 aIt( m_aActionListeners );
4214
4215 css::awt::ActionEvent aEvent;
4216 aEvent.Source = *this;
4217 weld::ComboBox& rBox = m_pBox->get_widget();
4218 aEvent.ActionCommand = rBox.get_active_text();
4219
4220 while( aIt.hasMoreElements() )
4221 static_cast< css::awt::XActionListener *>(aIt.next())->actionPerformed( aEvent );
4222}
4223
4224FmXComboBoxCell::FmXComboBoxCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
4225 :FmXTextCell( pColumn, std::move(pControl) )
4226 ,m_aItemListeners( m_aMutex )
4227 ,m_aActionListeners( m_aMutex )
4228 ,m_pComboBox(&static_cast<ComboBoxControl&>(m_pCellControl->GetWindow()))
4229 ,m_nLines(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())
4230{
4231 m_pComboBox->SetAuxModifyHdl(LINK(this, FmXComboBoxCell, ChangedHdl)::tools::detail::makeLink( ::tools::detail::castTo<FmXComboBoxCell
*>(this), &FmXComboBoxCell::LinkStubChangedHdl)
);
4232}
4233
4234FmXComboBoxCell::~FmXComboBoxCell()
4235{
4236 if ( !OComponentHelper::rBHelper.bDisposed )
4237 {
4238 acquire();
4239 dispose();
4240 }
4241
4242}
4243
4244void FmXComboBoxCell::disposing()
4245{
4246 css::lang::EventObject aEvt(*this);
4247 m_aItemListeners.disposeAndClear(aEvt);
4248 m_aActionListeners.disposeAndClear(aEvt);
4249
4250 m_pComboBox->SetAuxModifyHdl(Link<LinkParamNone*,void>());
4251 m_pComboBox = nullptr;
4252
4253 FmXTextCell::disposing();
4254}
4255
4256Any SAL_CALL FmXComboBoxCell::queryAggregation( const css::uno::Type& _rType )
4257{
4258 Any aReturn = FmXTextCell::queryAggregation(_rType);
4259
4260 if ( !aReturn.hasValue() )
4261 aReturn = FmXComboBoxCell_Base::queryInterface( _rType );
4262
4263 return aReturn;
4264}
4265
4266Sequence< Type > SAL_CALL FmXComboBoxCell::getTypes( )
4267{
4268 return ::comphelper::concatSequences(
4269 FmXTextCell::getTypes(),
4270 FmXComboBoxCell_Base::getTypes()
4271 );
4272}
4273
4274IMPLEMENT_GET_IMPLEMENTATION_ID( FmXComboBoxCell )css::uno::Sequence< sal_Int8 > FmXComboBoxCell::getImplementationId
( ) { return css::uno::Sequence<sal_Int8>(); }
4275
4276void SAL_CALL FmXComboBoxCell::addItemListener(const Reference< awt::XItemListener >& l)
4277{
4278 m_aItemListeners.addInterface( l );
4279}
4280
4281void SAL_CALL FmXComboBoxCell::removeItemListener(const Reference< awt::XItemListener >& l)
4282{
4283 m_aItemListeners.removeInterface( l );
4284}
4285
4286void SAL_CALL FmXComboBoxCell::addActionListener(const Reference< awt::XActionListener >& l)
4287{
4288 m_aActionListeners.addInterface( l );
4289}
4290
4291
4292void SAL_CALL FmXComboBoxCell::removeActionListener(const Reference< awt::XActionListener >& l)
4293{
4294 m_aActionListeners.removeInterface( l );
4295}
4296
4297void SAL_CALL FmXComboBoxCell::addItem( const OUString& Item, sal_Int16 Pos )
4298{
4299 ::osl::MutexGuard aGuard( m_aMutex );
4300 if (!m_pComboBox)
4301 return;
4302 weld::ComboBox& rBox = m_pComboBox->get_widget();
4303 rBox.insert_text(Pos, Item);
4304}
4305
4306void SAL_CALL FmXComboBoxCell::addItems( const Sequence< OUString >& Items, sal_Int16 Pos )
4307{
4308 ::osl::MutexGuard aGuard( m_aMutex );
4309 if (!m_pComboBox)
4310 return;
4311 weld::ComboBox& rBox = m_pComboBox->get_widget();
4312 sal_uInt16 nP = Pos;
4313 for ( const auto& rItem : Items )
4314 {
4315 rBox.insert_text(nP, rItem);
4316 if ( Pos != -1 )
4317 nP++;
4318 }
4319}
4320
4321void SAL_CALL FmXComboBoxCell::removeItems( sal_Int16 Pos, sal_Int16 Count )
4322{
4323 ::osl::MutexGuard aGuard( m_aMutex );
4324 if (!m_pComboBox)
4325 return;
4326 weld::ComboBox& rBox = m_pComboBox->get_widget();
4327 for ( sal_uInt16 n = Count; n; )
4328 rBox.remove( Pos + (--n) );
4329}
4330
4331sal_Int16 SAL_CALL FmXComboBoxCell::getItemCount()
4332{
4333 ::osl::MutexGuard aGuard( m_aMutex );
4334 if (!m_pComboBox)
4335 return 0;
4336 weld::ComboBox& rBox = m_pComboBox->get_widget();
4337 return rBox.get_count();
4338}
4339
4340OUString SAL_CALL FmXComboBoxCell::getItem( sal_Int16 Pos )
4341{
4342 ::osl::MutexGuard aGuard( m_aMutex );
4343 if (!m_pComboBox)
4344 return OUString();
4345 weld::ComboBox& rBox = m_pComboBox->get_widget();
4346 return rBox.get_text(Pos);
4347}
4348
4349Sequence< OUString > SAL_CALL FmXComboBoxCell::getItems()
4350{
4351 ::osl::MutexGuard aGuard( m_aMutex );
4352
4353 Sequence< OUString > aItems;
4354 if (m_pComboBox)
4355 {
4356 weld::ComboBox& rBox = m_pComboBox->get_widget();
4357 const sal_Int32 nEntries = rBox.get_count();
4358 aItems.realloc( nEntries );
4359 OUString* pItem = aItems.getArray();
4360 for ( sal_Int32 n=0; n<nEntries; ++n, ++pItem )
4361 *pItem = rBox.get_text(n);
4362 }
4363 return aItems;
4364}
4365
4366sal_Int16 SAL_CALL FmXComboBoxCell::getDropDownLineCount()
4367{
4368 ::osl::MutexGuard aGuard( m_aMutex );
4369 return m_nLines;
4370}
4371
4372void SAL_CALL FmXComboBoxCell::setDropDownLineCount(sal_Int16 nLines)
4373{
4374 ::osl::MutexGuard aGuard( m_aMutex );
4375 m_nLines = nLines; // just store it to return it
4376}
4377
4378IMPL_LINK_NOARG(FmXComboBoxCell, ChangedHdl, LinkParamNone*, void)void FmXComboBoxCell::LinkStubChangedHdl(void * instance, LinkParamNone
* data) { return static_cast<FmXComboBoxCell *>(instance
)->ChangedHdl(data); } void FmXComboBoxCell::ChangedHdl(__attribute__
((unused)) LinkParamNone*)
4379{
4380 if (!m_pComboBox)
4381 return;
4382
4383 weld::ComboBox& rComboBox = m_pComboBox->get_widget();
4384
4385 if (!rComboBox.changed_by_direct_pick())
4386 return;
4387
4388 awt::ItemEvent aEvent;
4389 aEvent.Source = *this;
4390 aEvent.Highlighted = 0;
4391
4392 // with invalid selection 0xFFFF, otherwise the position
4393 aEvent.Selected = ( rComboBox.get_active() != -1 )
4394 ? rComboBox.get_active()
4395 : 0xFFFF;
4396 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4397}
4398
4399FmXFilterCell::FmXFilterCell(DbGridColumn* pColumn, std::unique_ptr<DbFilterField> pControl )
4400 :FmXGridCell( pColumn, std::move(pControl) )
4401 ,m_aTextListeners(m_aMutex)
4402{
4403 static_cast<DbFilterField*>(m_pCellControl.get())->SetCommitHdl( LINK( this, FmXFilterCell, OnCommit )::tools::detail::makeLink( ::tools::detail::castTo<FmXFilterCell
*>(this), &FmXFilterCell::LinkStubOnCommit)
);
4404}
4405
4406FmXFilterCell::~FmXFilterCell()
4407{
4408 if (!OComponentHelper::rBHelper.bDisposed)
4409 {
4410 acquire();
4411 dispose();
4412 }
4413
4414}
4415
4416// XUnoTunnel
4417sal_Int64 SAL_CALL FmXFilterCell::getSomething( const Sequence< sal_Int8 >& _rIdentifier )
4418{
4419 sal_Int64 nReturn(0);
4420
4421 if ( isUnoTunnelId<FmXFilterCell>(_rIdentifier) )
4422 {
4423 nReturn = reinterpret_cast<sal_Int64>(this);
4424 }
4425
4426 return nReturn;
4427}
4428
4429namespace
4430{
4431 class theFmXFilterCellUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theFmXFilterCellUnoTunnelId > {};
4432}
4433
4434const Sequence<sal_Int8>& FmXFilterCell::getUnoTunnelId()
4435{
4436 return theFmXFilterCellUnoTunnelId::get().getSeq();
4437}
4438
4439
4440void FmXFilterCell::PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect )
4441{
4442 static_cast< DbFilterField* >( m_pCellControl.get() )->PaintCell( rDev, rRect );
4443}
4444
4445// OComponentHelper
4446
4447void FmXFilterCell::disposing()
4448{
4449 css::lang::EventObject aEvt(*this);
4450 m_aTextListeners.disposeAndClear(aEvt);
4451
4452 static_cast<DbFilterField*>(m_pCellControl.get())->SetCommitHdl(Link<DbFilterField&,void>());
4453
4454 FmXGridCell::disposing();
4455}
4456
4457
4458Any SAL_CALL FmXFilterCell::queryAggregation( const css::uno::Type& _rType )
4459{
4460 Any aReturn = FmXGridCell::queryAggregation(_rType);
4461
4462 if ( !aReturn.hasValue() )
4463 aReturn = FmXFilterCell_Base::queryInterface( _rType );
4464
4465 return aReturn;
4466}
4467
4468
4469Sequence< css::uno::Type > SAL_CALL FmXFilterCell::getTypes( )
4470{
4471 return ::comphelper::concatSequences(
4472 FmXGridCell::getTypes(),
4473 FmXFilterCell_Base::getTypes()
4474 );
4475}
4476
4477
4478IMPLEMENT_GET_IMPLEMENTATION_ID( FmXFilterCell )css::uno::Sequence< sal_Int8 > FmXFilterCell::getImplementationId
( ) { return css::uno::Sequence<sal_Int8>(); }
4479
4480// css::awt::XTextComponent
4481
4482void SAL_CALL FmXFilterCell::addTextListener(const Reference< css::awt::XTextListener >& l)
4483{
4484 m_aTextListeners.addInterface( l );
4485}
4486
4487
4488void SAL_CALL FmXFilterCell::removeTextListener(const Reference< css::awt::XTextListener >& l)
4489{
4490 m_aTextListeners.removeInterface( l );
4491}
4492
4493void SAL_CALL FmXFilterCell::setText( const OUString& aText )
4494{
4495 ::osl::MutexGuard aGuard( m_aMutex );
4496 static_cast<DbFilterField*>(m_pCellControl.get())->SetText(aText);
4497}
4498
4499void SAL_CALL FmXFilterCell::insertText( const css::awt::Selection& /*rSel*/, const OUString& /*aText*/ )
4500{
4501}
4502
4503OUString SAL_CALL FmXFilterCell::getText()
4504{
4505 ::osl::MutexGuard aGuard( m_aMutex );
4506 return static_cast<DbFilterField*>(m_pCellControl.get())->GetText();
4507}
4508
4509OUString SAL_CALL FmXFilterCell::getSelectedText()
4510{
4511 return getText();
4512}
4513
4514void SAL_CALL FmXFilterCell::setSelection( const css::awt::Selection& /*aSelection*/ )
4515{
4516}
4517
4518css::awt::Selection SAL_CALL FmXFilterCell::getSelection()
4519{
4520 return css::awt::Selection();
4521}
4522
4523sal_Bool SAL_CALL FmXFilterCell::isEditable()
4524{
4525 return true;
4526}
4527
4528void SAL_CALL FmXFilterCell::setEditable( sal_Bool /*bEditable*/ )
4529{
4530}
4531
4532sal_Int16 SAL_CALL FmXFilterCell::getMaxTextLen()
4533{
4534 return 0;
4535}
4536
4537void SAL_CALL FmXFilterCell::setMaxTextLen( sal_Int16 /*nLen*/ )
4538{
4539}
4540
4541IMPL_LINK_NOARG(FmXFilterCell, OnCommit, DbFilterField&, void)void FmXFilterCell::LinkStubOnCommit(void * instance, DbFilterField
& data) { return static_cast<FmXFilterCell *>(instance
)->OnCommit(data); } void FmXFilterCell::OnCommit(__attribute__
((unused)) DbFilterField&)
4542{
4543 ::comphelper::OInterfaceIteratorHelper2 aIt( m_aTextListeners );
4544 css::awt::TextEvent aEvt;
4545 aEvt.Source = *this;
4546 while( aIt.hasMoreElements() )
4547 static_cast< css::awt::XTextListener *>(aIt.next())->textChanged( aEvt );
4548}
4549
4550/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
2
Memory is allocated
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
15
Calling 'Reference::get'
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
205 if (aTmp.get()) {
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody
5.1
Field 'm_pBody' is non-null
5.1
Field 'm_pBody' is non-null
5.1
Field 'm_pBody' is non-null
5.1
Field 'm_pBody' is non-null
)
6
Taking true branch
113 m_pBody->release();
7
Calling 'VclReferenceBase::release'
11
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
16
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
8
Assuming the condition is true
9
Taking true branch
40 delete this;
10
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif