LibreOffice Module svx (master)  1
gridcell.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
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>
52 #include <comphelper/string.hxx>
53 #include <comphelper/types.hxx>
55 #include <i18nlangtag/lang.h>
56 #include <o3tl/safeint.hxx>
57 #include <svl/numformat.hxx>
58 #include <svl/numuno.hxx>
59 #include <svl/zforlist.hxx>
60 #include <svx/dialmgr.hxx>
62 #include <tools/debug.hxx>
63 #include <tools/fract.hxx>
64 #include <tools/diagnose_ex.h>
65 #include <vcl/settings.hxx>
66 #include <vcl/svapp.hxx>
67 #include <connectivity/dbtools.hxx>
69 #include <connectivity/sqlnode.hxx>
70 
71 using namespace ::connectivity;
72 using namespace ::svxform;
73 using namespace ::comphelper;
74 using namespace ::svt;
75 using namespace ::com::sun::star;
76 using namespace ::com::sun::star::uno;
77 using namespace ::com::sun::star::sdbc;
78 using namespace ::com::sun::star::sdbcx;
79 using namespace ::com::sun::star::sdb;
80 using namespace ::com::sun::star::beans;
81 using namespace ::com::sun::star::form;
82 using namespace ::dbtools::DBTypeConversion;
83 using namespace ::dbtools;
84 
85 using ::com::sun::star::util::XNumberFormatter;
86 
87 constexpr OUStringLiteral INVALIDTEXT = u"###";
88 constexpr OUStringLiteral OBJECTTEXT = u"<OBJECT>";
89 
90 
91 //= helper
92 
93 namespace
94 {
95  LineEnd getModelLineEndSetting( const Reference< XPropertySet >& _rxModel )
96  {
97  LineEnd eFormat = LINEEND_LF;
98 
99  try
100  {
101  sal_Int16 nLineEndFormat = awt::LineEndFormat::LINE_FEED;
102 
103  Reference< XPropertySetInfo > xPSI;
104  if ( _rxModel.is() )
105  xPSI = _rxModel->getPropertySetInfo();
106 
107  OSL_ENSURE( xPSI.is(), "getModelLineEndSetting: invalid column model!" );
108  if ( xPSI.is() && xPSI->hasPropertyByName( FM_PROP_LINEENDFORMAT ) )
109  {
110  OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_LINEENDFORMAT ) >>= nLineEndFormat );
111 
112  switch ( nLineEndFormat )
113  {
114  case awt::LineEndFormat::CARRIAGE_RETURN: eFormat = LINEEND_CR; break;
115  case awt::LineEndFormat::LINE_FEED: eFormat = LINEEND_LF; break;
116  case awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED: eFormat = LINEEND_CRLF; break;
117  default:
118  OSL_FAIL( "getModelLineEndSetting: what's this?" );
119  }
120  }
121  }
122  catch( const Exception& )
123  {
124  TOOLS_WARN_EXCEPTION( "svx", "getModelLineEndSetting" );
125  }
126  return eFormat;
127  }
128 }
129 
130 
131 //= DbGridColumn
132 
133 
135 
136 
137 void DbGridColumn::CreateControl(sal_Int32 _nFieldPos, const Reference< css::beans::XPropertySet >& xField, sal_Int32 nTypeId)
138 {
139  Clear();
140 
141  m_nTypeId = static_cast<sal_Int16>(nTypeId);
142  if (xField != m_xField)
143  {
144  // initial setting
145  m_xField = xField;
146  xField->getPropertyValue(FM_PROP_FORMATKEY) >>= m_nFormatKey;
147  m_nFieldPos = static_cast<sal_Int16>(_nFieldPos);
148  m_bReadOnly = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISREADONLY));
149  m_bAutoValue = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_AUTOINCREMENT));
150  m_nFieldType = static_cast<sal_Int16>(::comphelper::getINT32(xField->getPropertyValue(FM_PROP_FIELDTYPE)));
151 
152  switch (m_nFieldType)
153  {
154  case DataType::DATE:
155  case DataType::TIME:
156  case DataType::TIMESTAMP:
157  case DataType::BIT:
158  case DataType::BOOLEAN:
159  case DataType::TINYINT:
160  case DataType::SMALLINT:
161  case DataType::INTEGER:
162  case DataType::BIGINT:
163  case DataType::FLOAT:
164  case DataType::REAL:
165  case DataType::DOUBLE:
166  case DataType::NUMERIC:
167  case DataType::DECIMAL:
168  m_nAlign = css::awt::TextAlign::RIGHT;
169  m_bNumeric = true;
170  break;
171  default:
172  m_nAlign = css::awt::TextAlign::LEFT;
173  break;
174  }
175  }
176 
177  std::unique_ptr<DbCellControl> pCellControl;
178  if (m_rParent.IsFilterMode())
179  {
180  pCellControl.reset(new DbFilterField(m_rParent.getContext(),*this));
181  }
182  else
183  {
184 
185  switch (nTypeId)
186  {
187  case TYPE_CHECKBOX: pCellControl.reset(new DbCheckBox(*this)); break;
188  case TYPE_COMBOBOX: pCellControl.reset(new DbComboBox(*this)); break;
189  case TYPE_CURRENCYFIELD: pCellControl.reset(new DbCurrencyField(*this)); break;
190  case TYPE_DATEFIELD: pCellControl.reset(new DbDateField(*this)); break;
191  case TYPE_LISTBOX: pCellControl.reset(new DbListBox(*this)); break;
192  case TYPE_NUMERICFIELD: pCellControl.reset(new DbNumericField(*this)); break;
193  case TYPE_PATTERNFIELD: pCellControl.reset(new DbPatternField( *this, m_rParent.getContext() )); break;
194  case TYPE_TEXTFIELD: pCellControl.reset(new DbTextField(*this)); break;
195  case TYPE_TIMEFIELD: pCellControl.reset(new DbTimeField(*this)); break;
196  case TYPE_FORMATTEDFIELD: pCellControl.reset(new DbFormattedField(*this)); break;
197  default:
198  OSL_FAIL("DbGridColumn::CreateControl: Unknown Column");
199  return;
200  }
201 
202  }
203  Reference< XRowSet > xCur;
204  if (m_rParent.getDataSource())
205  xCur.set(Reference< XInterface >(*m_rParent.getDataSource()), UNO_QUERY);
206  // TODO : the cursor wrapper should use an XRowSet interface, too
207 
208  pCellControl->Init( m_rParent.GetDataWindow(), xCur );
209 
210  // now create the control wrapper
211  auto pTempCellControl = pCellControl.get();
212  if (m_rParent.IsFilterMode())
213  m_pCell = new FmXFilterCell(this, std::unique_ptr<DbFilterField>(static_cast<DbFilterField*>(pCellControl.release())));
214  else
215  {
216  switch (nTypeId)
217  {
218  case TYPE_CHECKBOX: m_pCell = new FmXCheckBoxCell( this, std::move(pCellControl) ); break;
219  case TYPE_LISTBOX: m_pCell = new FmXListBoxCell( this, std::move(pCellControl) ); break;
220  case TYPE_COMBOBOX: m_pCell = new FmXComboBoxCell( this, std::move(pCellControl) ); break;
221  default:
222  m_pCell = new FmXEditCell( this, std::move(pCellControl) );
223  }
224  }
225  m_pCell->init();
226 
228 
229  // only if we use have a bound field, we use a controller for displaying the
230  // window in the grid
231  if (m_xField.is())
232  m_xController = pTempCellControl->CreateController();
233 }
234 
235 
237 {
238  try
239  {
240  Reference< container::XChild > xChild( m_xModel, UNO_QUERY_THROW );
241  Reference< script::XEventAttacherManager > xManager( xChild->getParent(), UNO_QUERY_THROW );
242  Reference< container::XIndexAccess > xContainer( xChild->getParent(), UNO_QUERY_THROW );
243 
244  sal_Int32 nIndexInParent( getElementPos( xContainer, m_xModel ) );
245 
246  Reference< XInterface > xCellInterface( *m_pCell, UNO_QUERY );
247  if ( _bAttach )
248  xManager->attach( nIndexInParent, xCellInterface, makeAny( xCellInterface ) );
249  else
250  xManager->detach( nIndexInParent, xCellInterface );
251  }
252  catch( const Exception& )
253  {
255  }
256 }
257 
259 {
260  if (FmXFilterCell* pCell = dynamic_cast<FmXFilterCell*>(m_pCell.get()))
261  pCell->Update();
262  else if (pRow && pRow->IsValid() && m_nFieldPos >= 0 && m_pCell.is() && pRow->HasField(m_nFieldPos))
263  {
264  dynamic_cast<FmXDataCell&>(*m_pCell).UpdateFromField( pRow->GetField( m_nFieldPos ).getColumn(), xFormatter );
265  }
266 }
267 
269 {
270  bool bResult = true;
271  if (!m_bInSave && m_pCell.is())
272  {
273  m_bInSave = true;
274  bResult = m_pCell->Commit();
275 
276  // store the data into the model
277  FmXDataCell* pDataCell = dynamic_cast<FmXDataCell*>( m_pCell.get() );
278  if (bResult && pDataCell)
279  {
280  Reference< css::form::XBoundComponent > xComp(m_xModel, UNO_QUERY);
281  if (xComp.is())
282  bResult = xComp->commit();
283  }
284  m_bInSave = false;
285  }
286  return bResult;
287 }
288 
290 {
291  Clear();
292 }
293 
294 void DbGridColumn::setModel(const css::uno::Reference< css::beans::XPropertySet >& _xModel)
295 {
296  if ( m_pCell.is() )
298 
299  m_xModel = _xModel;
300 
301  if ( m_pCell.is() )
303 }
304 
305 
307 {
308  if ( m_pCell.is() )
309  {
311 
312  m_pCell->dispose();
313  m_pCell.clear();
314  }
315 
316  m_xController = nullptr;
317  m_xField = nullptr;
318 
319  m_nFormatKey = 0;
320  m_nFieldPos = -1;
321  m_bReadOnly = true;
322  m_bAutoValue = false;
323  m_nFieldType = DataType::OTHER;
324 }
325 
326 
327 sal_Int16 DbGridColumn::SetAlignment(sal_Int16 _nAlign)
328 {
329  if (_nAlign == -1)
330  { // 'Standard'
331  if (m_xField.is())
332  {
333  sal_Int32 nType = 0;
334  m_xField->getPropertyValue(FM_PROP_FIELDTYPE) >>= nType;
335 
336  switch (nType)
337  {
338  case DataType::NUMERIC:
339  case DataType::DECIMAL:
340  case DataType::DOUBLE:
341  case DataType::REAL:
342  case DataType::BIGINT:
343  case DataType::INTEGER:
344  case DataType::SMALLINT:
345  case DataType::TINYINT:
346  case DataType::DATE:
347  case DataType::TIME:
348  case DataType::TIMESTAMP:
349  _nAlign = css::awt::TextAlign::RIGHT;
350  break;
351  case DataType::BIT:
352  case DataType::BOOLEAN:
353  _nAlign = css::awt::TextAlign::CENTER;
354  break;
355  default:
356  _nAlign = css::awt::TextAlign::LEFT;
357  break;
358  }
359  }
360  else
361  _nAlign = css::awt::TextAlign::LEFT;
362  }
363 
364  m_nAlign = _nAlign;
365  if (m_pCell.is() && m_pCell->isAlignedController())
366  m_pCell->AlignControl(m_nAlign);
367 
368  return m_nAlign;
369 }
370 
371 
372 sal_Int16 DbGridColumn::SetAlignmentFromModel(sal_Int16 nStandardAlign)
373 {
374  Any aAlign( m_xModel->getPropertyValue(FM_PROP_ALIGN));
375  if (aAlign.hasValue())
376  {
377  sal_Int16 nTest = sal_Int16();
378  if (aAlign >>= nTest)
379  nStandardAlign = nTest;
380  }
381  return SetAlignment(nStandardAlign);
382 }
383 
384 
385 void DbGridColumn::setLock(bool _bLock)
386 {
387  if (m_bLocked == _bLock)
388  return;
389  m_bLocked = _bLock;
390 
391  // is the column we represent active ?
392  if (m_bHidden)
393  return; // no, it isn't (or at least it shouldn't be ...)
394 
395  if (m_rParent.GetCurColumnId() == m_nId)
396  {
399  }
400 }
401 
402 
403 OUString DbGridColumn::GetCellText(const DbGridRow* pRow, const Reference< XNumberFormatter >& xFormatter) const
404 {
405  OUString aText;
406  if (m_pCell.is() && dynamic_cast<const FmXFilterCell*>( m_pCell.get() ) != nullptr)
407  return aText;
408 
409  if (!pRow || !pRow->IsValid())
410  aText = INVALIDTEXT;
411  else if (pRow->HasField(m_nFieldPos))
412  {
413  aText = GetCellText( pRow->GetField( m_nFieldPos ).getColumn(), xFormatter );
414  }
415  return aText;
416 }
417 
418 OUString DbGridColumn::GetCellText(const Reference< css::sdb::XColumn >& xField, const Reference< XNumberFormatter >& xFormatter) const
419 {
420  OUString aText;
421  if (xField.is())
422  {
423  FmXTextCell* pTextCell = dynamic_cast<FmXTextCell*>( m_pCell.get() );
424  if (pTextCell)
425  aText = pTextCell->GetText(xField, xFormatter);
426  else if (m_bObject)
427  aText = OBJECTTEXT;
428  }
429  return aText;
430 }
431 
432 Reference< css::sdb::XColumn > DbGridColumn::GetCurrentFieldValue() const
433 {
434  Reference< css::sdb::XColumn > xField;
436  if (xRow.is() && xRow->HasField(m_nFieldPos))
437  {
438  xField = xRow->GetField(m_nFieldPos).getColumn();
439  }
440  return xField;
441 }
442 
443 
445  const tools::Rectangle& rRect,
446  const DbGridRow* pRow,
447  const Reference< XNumberFormatter >& xFormatter)
448 {
449  bool bEnabled = ( rDev.GetOutDevType() != OUTDEV_WINDOW )
450  || ( rDev.GetOwnerWindow()->IsEnabled() );
451 
452  FmXDataCell* pDataCell = dynamic_cast<FmXDataCell*>( m_pCell.get() );
453  if (pDataCell)
454  {
455  if (!pRow || !pRow->IsValid())
456  {
457  DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
458  if ( !bEnabled )
459  nStyle |= DrawTextFlags::Disable;
460 
461  rDev.DrawText(rRect, OUString(INVALIDTEXT), nStyle);
462  }
463  else if (m_bAutoValue && pRow->IsNew())
464  {
465  DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter;
466  if ( !bEnabled )
467  nStyle |= DrawTextFlags::Disable;
468 
469  switch (GetAlignment())
470  {
471  case css::awt::TextAlign::RIGHT:
472  nStyle |= DrawTextFlags::Right;
473  break;
474  case css::awt::TextAlign::CENTER:
475  nStyle |= DrawTextFlags::Center;
476  break;
477  default:
478  nStyle |= DrawTextFlags::Left;
479  }
480 
481  rDev.DrawText(rRect, SvxResId(RID_STR_AUTOFIELD), nStyle);
482  }
483  else if (pRow->HasField(m_nFieldPos))
484  {
485  pDataCell->PaintFieldToCell(rDev, rRect, pRow->GetField( m_nFieldPos ).getColumn(), xFormatter);
486  }
487  }
488  else if (!m_pCell.is())
489  {
490  if (!pRow || !pRow->IsValid())
491  {
492  DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
493  if ( !bEnabled )
494  nStyle |= DrawTextFlags::Disable;
495 
496  rDev.DrawText(rRect, OUString(INVALIDTEXT), nStyle);
497  }
498  else if (pRow->HasField(m_nFieldPos) && m_bObject)
499  {
500  DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
501  if ( !bEnabled )
502  nStyle |= DrawTextFlags::Disable;
503  rDev.DrawText(rRect, OUString(OBJECTTEXT), nStyle);
504  }
505  }
506  else if ( auto pFilterCell = dynamic_cast<FmXFilterCell*>( m_pCell.get() ) )
507  pFilterCell->PaintCell( rDev, rRect );
508 }
509 
510 
511 void DbGridColumn::ImplInitWindow( vcl::Window const & rParent, const InitWindowFacet _eInitWhat )
512 {
513  if ( m_pCell.is() )
514  m_pCell->ImplInitWindow( rParent, _eInitWhat );
515 }
516 
517 
518 //= cell controls
519 
520 
522  :OPropertyChangeListener(m_aMutex)
523  ,m_bTransparent( false )
524  ,m_bAlignedController( true )
525  ,m_bAccessingValueProperty( false )
526  ,m_rColumn( _rColumn )
527  ,m_pPainter( nullptr )
528  ,m_pWindow( nullptr )
529 {
530  Reference< XPropertySet > xColModelProps = _rColumn.getModel();
531  if ( !xColModelProps.is() )
532  return;
533 
534  // if our model's format key changes we want to propagate the new value to our windows
535  m_pModelChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, _rColumn.getModel());
536 
537  // be listener for some common properties
540 
541  // add as listener for all known "value" properties
549 
550  // be listener at the bound field as well
551  try
552  {
553  Reference< XPropertySetInfo > xPSI( xColModelProps->getPropertySetInfo(), UNO_SET_THROW );
554  if ( xPSI->hasPropertyByName( FM_PROP_BOUNDFIELD ) )
555  {
557  xColModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ) >>= xField;
558  if ( xField.is() )
559  {
560  m_pFieldChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, xField);
562  }
563  }
564  }
565  catch( const Exception& )
566  {
567  TOOLS_WARN_EXCEPTION( "svx", "DbCellControl::doPropertyListening" );
568  }
569 }
570 
571 
572 void DbCellControl::implDoPropertyListening(const OUString& _rPropertyName, bool _bWarnIfNotExistent)
573 {
574  try
575  {
576  Reference< XPropertySet > xColModelProps = m_rColumn.getModel();
577  Reference< XPropertySetInfo > xPSI;
578  if ( xColModelProps.is() )
579  xPSI = xColModelProps->getPropertySetInfo();
580 
581  DBG_ASSERT( !_bWarnIfNotExistent || ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) ),
582  "DbCellControl::doPropertyListening: no property set info or non-existent property!" );
583 
584  if ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) )
585  m_pModelChangeBroadcaster->addProperty( _rPropertyName );
586  }
587  catch( const Exception& )
588  {
589  TOOLS_WARN_EXCEPTION( "svx", "DbCellControl::doPropertyListening" );
590  }
591 }
592 
593 
594 void DbCellControl::doPropertyListening(const OUString& _rPropertyName)
595 {
596  implDoPropertyListening( _rPropertyName, true );
597 }
598 
600 {
601  if ( _pBroadcaster.is() )
602  {
603  _pBroadcaster->dispose();
604  _pBroadcaster.clear();
605  // no delete, this is done implicitly
606  }
607 }
608 
610 {
613 
616 }
617 
619 {
620  OSL_ENSURE( !isValuePropertyLocked(),
621  "DbCellControl::implValuePropertyChanged: not to be called with the value property locked!" );
622 
623  if ( m_pWindow )
624  {
625  if ( m_rColumn.getModel().is() )
627  }
628 }
629 
630 
632 {
633  // nothing to do here
634 }
635 
636 
637 void DbCellControl::_propertyChanged(const PropertyChangeEvent& _rEvent)
638 {
639  SolarMutexGuard aGuard;
640 
641  Reference< XPropertySet > xSourceProps( _rEvent.Source, UNO_QUERY );
642 
643  if ( _rEvent.PropertyName == FM_PROP_VALUE
644  || _rEvent.PropertyName == FM_PROP_STATE
645  || _rEvent.PropertyName == FM_PROP_TEXT
646  || _rEvent.PropertyName == FM_PROP_EFFECTIVE_VALUE
647  || _rEvent.PropertyName == FM_PROP_SELECT_SEQ
648  || _rEvent.PropertyName == FM_PROP_DATE
649  || _rEvent.PropertyName == FM_PROP_TIME
650  )
651  { // it was one of the known "value" properties
652  if ( !isValuePropertyLocked() )
653  {
655  }
656  }
657  else if ( _rEvent.PropertyName == FM_PROP_READONLY )
658  {
659  implAdjustReadOnly( xSourceProps, true);
660  }
661  else if ( _rEvent.PropertyName == FM_PROP_ISREADONLY )
662  {
663  bool bReadOnly = true;
664  _rEvent.NewValue >>= bReadOnly;
665  m_rColumn.SetReadOnly(bReadOnly);
666  implAdjustReadOnly( xSourceProps, false);
667  }
668  else if ( _rEvent.PropertyName == FM_PROP_ENABLED )
669  {
670  implAdjustEnabled( xSourceProps );
671  }
672  else
673  implAdjustGenericFieldSetting( xSourceProps );
674 }
675 
677 {
678  // lock the listening for value property changes
680  // commit the content of the control into the model's value property
681  bool bReturn = false;
682  try
683  {
684  bReturn = commitControl();
685  }
686  catch( const Exception& )
687  {
689  }
690  // unlock the listening for value property changes
692  // outta here
693  return bReturn;
694 }
695 
696 void DbCellControl::ImplInitWindow( vcl::Window const & rParent, const InitWindowFacet _eInitWhat )
697 {
698  svt::ControlBase* pWindows[] = { m_pPainter, m_pWindow };
699 
700  if (_eInitWhat & InitWindowFacet::WritingMode)
701  {
702  for (svt::ControlBase* pWindow : pWindows)
703  {
704  if (pWindow)
705  pWindow->EnableRTL(rParent.IsRTLEnabled());
706  }
707  }
708 
709  if (_eInitWhat & InitWindowFacet::Font)
710  {
711  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
712  const Fraction& rZoom = rParent.GetZoom();
713 
714  for (svt::ControlBase* pWindow : pWindows)
715  {
716  if (!pWindow)
717  continue;
718 
719  vcl::Font aFont = rStyleSettings.GetFieldFont();
720  aFont.SetTransparent(isTransparent());
721 
722  if (rParent.IsControlFont())
723  aFont.Merge(rParent.GetControlFont());
724 
725  if (rZoom.GetNumerator() != rZoom.GetDenominator())
726  {
727  Size aSize = aFont.GetFontSize();
728  aSize.setWidth(std::round(double(aSize.Width() * rZoom)));
729  aSize.setHeight(std::round(double(aSize.Height() * rZoom)));
730  aFont.SetFontSize(aSize);
731  }
732 
733  pWindow->SetPointFont(aFont);
734  }
735  }
736 
737  if ((_eInitWhat & InitWindowFacet::Font) || (_eInitWhat & InitWindowFacet::Foreground))
738  {
739  Color aTextColor(rParent.IsControlForeground() ? rParent.GetControlForeground() : rParent.GetTextColor());
740 
741  bool bTextLineColor = rParent.IsTextLineColor();
742  Color aTextLineColor(rParent.GetTextLineColor());
743 
744  for (svt::ControlBase* pWindow : pWindows)
745  {
746  if (pWindow)
747  {
748  pWindow->SetTextColor(aTextColor);
749  if (rParent.IsControlForeground())
750  pWindow->SetControlForeground(aTextColor);
751 
752  if (bTextLineColor)
753  pWindow->SetTextLineColor();
754  else
755  pWindow->SetTextLineColor(aTextLineColor);
756  }
757  }
758  }
759 
760  if (!(_eInitWhat & InitWindowFacet::Background))
761  return;
762 
763  if (rParent.IsControlBackground())
764  {
765  Color aColor(rParent.GetControlBackground());
766  for (svt::ControlBase* pWindow : pWindows)
767  {
768  if (pWindow)
769  {
770  if (isTransparent())
771  pWindow->SetBackground();
772  else
773  {
774  pWindow->SetBackground(aColor);
775  pWindow->SetControlBackground(aColor);
776  }
777  pWindow->GetOutDev()->SetFillColor(aColor);
778  }
779  }
780  }
781  else
782  {
783  if (m_pPainter)
784  {
785  if (isTransparent())
786  m_pPainter->SetBackground();
787  else
788  m_pPainter->SetBackground(rParent.GetBackground());
789  m_pPainter->GetOutDev()->SetFillColor(rParent.GetOutDev()->GetFillColor());
790  }
791 
792  if (m_pWindow)
793  {
794  if (isTransparent())
795  m_pWindow->SetBackground(rParent.GetBackground());
796  else
797  m_pWindow->GetOutDev()->SetFillColor(rParent.GetOutDev()->GetFillColor());
798  }
799  }
800 }
801 
802 void DbCellControl::implAdjustReadOnly( const Reference< XPropertySet >& _rxModel,bool i_bReadOnly )
803 {
804  DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustReadOnly: not to be called without window!" );
805  DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustReadOnly: invalid model!" );
806  if ( !(m_pWindow && _rxModel.is()) )
807  return;
808 
809  bool bReadOnly = m_rColumn.IsReadOnly();
810  if ( !bReadOnly )
811  {
812  _rxModel->getPropertyValue( i_bReadOnly ? OUString(FM_PROP_READONLY) : OUString(FM_PROP_ISREADONLY)) >>= bReadOnly;
813  }
814  m_pWindow->SetEditableReadOnly(bReadOnly);
815 }
816 
818 {
819  DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustEnabled: not to be called without window!" );
820  DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustEnabled: invalid model!" );
821  if ( m_pWindow && _rxModel.is() )
822  {
823  bool bEnable = true;
824  _rxModel->getPropertyValue( FM_PROP_ENABLED ) >>= bEnable;
825  m_pWindow->Enable( bEnable );
826  }
827 }
828 
829 void DbCellControl::Init(BrowserDataWin& rParent, const Reference< XRowSet >& _rxCursor)
830 {
832 
833  if ( m_pWindow )
834  {
835  // align the control
836  if ( isAlignedController() )
838 
839  try
840  {
841  // some other common properties
843  Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW );
844 
845  if ( xModelPSI->hasPropertyByName( FM_PROP_READONLY ) )
846  {
847  implAdjustReadOnly( xModel,true );
848  }
849 
850  if ( xModelPSI->hasPropertyByName( FM_PROP_ENABLED ) )
851  {
853  }
854 
855  if ( xModelPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
856  {
857  sal_Int16 nWheelBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY;
858  OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) >>= nWheelBehavior );
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!" );
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  {
880  }
881  }
882  m_xCursor = _rxCursor;
883  if ( m_rColumn.getModel().is() )
885 }
886 
887 
889 {
890  if (m_pWindow)
891  m_pWindow->SetTextLineColor();
892  if (m_pPainter)
893  m_pPainter->SetTextLineColor();
894 }
895 
896 
898 {
899  if (m_pWindow)
900  m_pWindow->SetTextLineColor(_rColor);
901  if (m_pPainter)
902  m_pPainter->SetTextLineColor(_rColor);
903 }
904 
905 namespace
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 
932 void 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 
953 {
954  m_pPainter->SetSizePixel(rRect.GetSize());
955  m_pPainter->Draw(&rDev, rRect.TopLeft(), SystemTextColorFlags::NONE);
956 }
957 
958 void 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 
964 double 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 
997 {
999 }
1000 
1001 // CellModels
1002 
1004  :DbCellControl( _rColumn )
1005 {
1007 }
1008 
1009 
1011 {
1012  DBG_ASSERT( m_pWindow, "DbLimitedLengthField::implAdjustGenericFieldSetting: not to be called without window!" );
1013  DBG_ASSERT( _rxModel.is(), "DbLimitedLengthField::implAdjustGenericFieldSetting: invalid model!" );
1014  if ( m_pWindow && _rxModel.is() )
1015  {
1016  sal_Int16 nMaxLen = 0;
1017  _rxModel->getPropertyValue( FM_PROP_MAXTEXTLEN ) >>= nMaxLen;
1018  implSetMaxTextLen( nMaxLen );
1019  }
1020 }
1021 
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 
1030  :DbLimitedLengthField(_rColumn)
1031  ,m_bIsMultiLineEdit(false)
1032 {
1033 }
1034 
1036 {
1037  m_pPainterImplementation.reset();
1038  m_pEdit.reset();
1039 }
1040 
1041 void DbTextField::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
1042 {
1043  sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1044 
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 );
1056  }
1057  }
1058  catch( const Exception& )
1059  {
1060  TOOLS_WARN_EXCEPTION("svx",
1061  "caught an exception while determining the multi-line capabilities!");
1062  }
1063 
1064  m_bIsMultiLineEdit = 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 
1128 
1129  DbLimitedLengthField::Init( rParent, xCursor );
1130 }
1131 
1133 {
1134  return new EditCellController( m_pEdit.get() );
1135 }
1136 
1137 void DbTextField::PaintFieldToCell( OutputDevice& _rDev, const tools::Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1138 {
1140  m_pPainterImplementation->SetText( GetFormatText( _rxField, _rxFormatter ) );
1141 
1142  DbLimitedLengthField::PaintFieldToCell( _rDev, _rRect, _rxField, _rxFormatter );
1143 }
1144 
1145 OUString 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");
1160  }
1161  return OUString();
1162 
1163 }
1164 
1165 void 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_MAX, SELECTION_MIN ) );
1169 }
1170 
1172 {
1173  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTextField::updateFromModel: invalid call!" );
1174 
1175  OUString sText;
1176  _rxModel->getPropertyValue( FM_PROP_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_MAX, SELECTION_MIN ) );
1188 }
1189 
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 ) >>= 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, makeAny( aText ) );
1204  return true;
1205 }
1206 
1208 {
1209  if ( m_pEdit )
1210  m_pEdit->SetMaxTextLen( _nMaxLen );
1212  m_pPainterImplementation->SetMaxTextLen( _nMaxLen );
1213 }
1214 
1216  :DbLimitedLengthField(_rColumn)
1217 {
1218  // if our model's format key changes we want to propagate the new value to our windows
1220 }
1221 
1223 {
1224 }
1225 
1226 void 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 !");
1275  Any aSupplier( xUnoModel->getPropertyValue(FM_PROP_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));
1283  if (aFmtKey.hasValue())
1284  {
1285  DBG_ASSERT(aFmtKey.getValueType().getTypeClass() == TypeClass_LONG, "DbFormattedField::Init : invalid format key property (no sal_Int32) !");
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 !");
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
1308 
1309  if (m_rColumn.GetField().is())
1310  nFormatKey = ::comphelper::getINT32(m_rColumn.GetField()->getPropertyValue(FM_PROP_FORMATKEY));
1311  }
1312  }
1313 
1314  SvNumberFormatter* pFormatterUsed = nullptr;
1315  if (m_xSupplier.is())
1316  {
1317  SvNumberFormatsSupplierObj* pImplementation = comphelper::getFromUnoTunnel<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 !");
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;
1350  {
1351  Any aMin( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MIN));
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 !");
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;
1368  {
1369  Any aMax(xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MAX));
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 !");
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));
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!" );
1429  break;
1430  }
1431  }
1432  DbLimitedLengthField::Init( rParent, xCursor );
1433 }
1434 
1436 {
1437  return new ::svt::FormattedFieldCellController(static_cast<FormattedControlBase*>(m_pWindow.get()));
1438 }
1439 
1440 void DbFormattedField::_propertyChanged( const PropertyChangeEvent& _rEvent )
1441 {
1442  if (_rEvent.PropertyName == FM_PROP_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 ?");
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  {
1455  }
1456 }
1457 
1458 OUString 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");
1499  }
1500 
1501  aText = pControl->get_widget().get_text();
1502  if (ppColor != nullptr)
1503  *ppColor = rPainterFormatter.GetLastOutputColor();
1504 
1505  return aText;
1506 }
1507 
1508 void 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");
1547  }
1548 }
1549 
1551 {
1552  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFormattedField::updateFromModel: invalid call!" );
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 );
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 
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, aNewVal);
1592  return true;
1593 }
1594 
1596  :DbCellControl( _rColumn )
1597 {
1598  setAlignedController( false );
1599 }
1600 
1601 namespace
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 
1616 void DbCheckBox::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
1617 {
1618  setTransparent( true );
1619 
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 );
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 );
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");
1646  }
1647 
1648  DbCellControl::Init( rParent, xCursor );
1649 }
1650 
1652 {
1653  return new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
1654 }
1655 
1656 static 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");
1671  }
1672  }
1673  _pCheckBoxControl->SetState(eState);
1674 }
1675 
1676 void 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 
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;
1689 
1690  switch (rDev.GetOutDevType())
1691  {
1692  case OUTDEV_WINDOW:
1693  case OUTDEV_VIRDEV:
1694  aBoxSize = pControl->GetBox().get_preferred_size();
1695  break;
1696  case OUTDEV_PRINTER:
1697  case OUTDEV_PDF:
1698  {
1699  auto nSize = std::min(rRect.GetWidth(), rRect.GetHeight());
1700  aBoxSize = Size(nSize, nSize);
1701  break;
1702  }
1703  }
1704 
1705  tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
1706  rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
1707  aBoxSize);
1708 
1709  DbCellControl::PaintFieldToCell(rDev, aRect, _rxField, xFormatter);
1710 }
1711 
1713 {
1714  switch (rDev.GetOutDevType())
1715  {
1716  case OUTDEV_WINDOW:
1717  case OUTDEV_VIRDEV:
1718  DbCellControl::PaintCell(rDev, rRect);
1719  break;
1720  case OUTDEV_PRINTER:
1721  case OUTDEV_PDF:
1722  {
1723  TriState eState = static_cast<CheckBoxControl*>(m_pWindow.get())->GetState();
1724 
1725  MapMode aResMapMode(MapUnit::Map100thMM);
1726  Size aImageSize = rDev.LogicToPixel(Size(300, 300), aResMapMode);
1727  Size aBrd1Size = rDev.LogicToPixel(Size(20, 20), aResMapMode);
1728  Size aBrd2Size = rDev.LogicToPixel(Size(30, 30), aResMapMode);
1729  int nCheckWidth = rDev.LogicToPixel(Size(20, 20), aResMapMode).Width();
1730 
1731  tools::Rectangle aStateRect;
1732  aStateRect.SetLeft(rRect.Left() + ((rRect.GetWidth() - aImageSize.Width()) / 2));
1733  aStateRect.SetTop(rRect.Top() + ((rRect.GetHeight() - aImageSize.Height()) / 2));
1734  aStateRect.SetRight(aStateRect.Left() + aImageSize.Width() - 1);
1735  aStateRect.SetBottom(aStateRect.Top() + aImageSize.Height() - 1);
1736 
1737  rDev.Push();
1738  rDev.SetMapMode();
1739 
1740  rDev.SetLineColor();
1741  rDev.SetFillColor(COL_BLACK);
1742  rDev.DrawRect(aStateRect);
1743  aStateRect.AdjustLeft(aBrd1Size.Width());
1744  aStateRect.AdjustTop(aBrd1Size.Height());
1745  aStateRect.AdjustRight(-aBrd1Size.Width());
1746  aStateRect.AdjustBottom(-aBrd1Size.Height());
1747  if (eState == TRISTATE_INDET)
1749  else
1750  rDev.SetFillColor(COL_WHITE);
1751  rDev.DrawRect(aStateRect);
1752 
1753  if (eState == TRISTATE_TRUE)
1754  {
1755  aStateRect.AdjustLeft(aBrd2Size.Width());
1756  aStateRect.AdjustTop(aBrd2Size.Height());
1757  aStateRect.AdjustRight(-aBrd2Size.Width());
1758  aStateRect.AdjustBottom(-aBrd2Size.Height());
1759  Point aPos11(aStateRect.TopLeft());
1760  Point aPos12(aStateRect.BottomRight());
1761  Point aPos21(aStateRect.TopRight());
1762  Point aPos22(aStateRect.BottomLeft());
1763  Point aTempPos11(aPos11);
1764  Point aTempPos12(aPos12);
1765  Point aTempPos21(aPos21);
1766  Point aTempPos22(aPos22);
1767  rDev.SetLineColor(COL_BLACK);
1768  int nDX = 0;
1769  for (int i = 0; i < nCheckWidth; i++)
1770  {
1771  if ( !(i % 2) )
1772  {
1773  aTempPos11.setX(aPos11.X() + nDX);
1774  aTempPos12.setX(aPos12.X() + nDX);
1775  aTempPos21.setX(aPos21.X() + nDX);
1776  aTempPos22.setX(aPos22.X() + nDX);
1777  }
1778  else
1779  {
1780  nDX++;
1781  aTempPos11.setX(aPos11.X() - nDX);
1782  aTempPos12.setX(aPos12.X() - nDX);
1783  aTempPos21.setX(aPos21.X() - nDX);
1784  aTempPos22.setX(aPos22.X() - nDX);
1785  }
1786  rDev.DrawLine(aTempPos11, aTempPos12);
1787  rDev.DrawLine(aTempPos21, aTempPos22);
1788  }
1789  }
1790 
1791  rDev.Pop();
1792  break;
1793  }
1794  }
1795 }
1796 
1798 {
1799  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCheckBox::updateFromModel: invalid call!" );
1800 
1801  sal_Int16 nState = TRISTATE_INDET;
1802  _rxModel->getPropertyValue( FM_PROP_STATE ) >>= nState;
1803  static_cast< CheckBoxControl* >( m_pWindow.get() )->SetState( static_cast< TriState >( nState ) );
1804 }
1805 
1807 {
1808  m_rColumn.getModel()->setPropertyValue( FM_PROP_STATE,
1809  makeAny( static_cast<sal_Int16>( static_cast< CheckBoxControl* >( m_pWindow.get() )->GetState() ) ) );
1810  return true;
1811 }
1812 
1813 OUString DbCheckBox::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
1814 {
1815  return OUString();
1816 }
1817 
1819  :DbCellControl( _rColumn )
1820  ,m_xContext( _rContext )
1821 {
1825 }
1826 
1828 {
1829  DBG_ASSERT( m_pWindow, "DbPatternField::implAdjustGenericFieldSetting: not to be called without window!" );
1830  DBG_ASSERT( _rxModel.is(), "DbPatternField::implAdjustGenericFieldSetting: invalid model!" );
1831  if ( !m_pWindow || !_rxModel.is() )
1832  return;
1833 
1834  OUString aLitMask;
1835  OUString aEditMask;
1836  bool bStrict = false;
1837 
1838  _rxModel->getPropertyValue( FM_PROP_LITERALMASK ) >>= aLitMask;
1839  _rxModel->getPropertyValue( FM_PROP_EDITMASK ) >>= aEditMask;
1840  _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) >>= bStrict;
1841 
1842  OString aAsciiEditMask(OUStringToOString(aEditMask, RTL_TEXTENCODING_ASCII_US));
1843 
1844  weld::PatternFormatter& rEditFormatter = static_cast<PatternControl*>(m_pWindow.get())->get_formatter();
1845  rEditFormatter.SetMask(aAsciiEditMask, aLitMask);
1846  rEditFormatter.SetStrictFormat(bStrict);
1847 
1848  weld::PatternFormatter& rPaintFormatter = static_cast<PatternControl*>(m_pPainter.get())->get_formatter();
1849  rPaintFormatter.SetMask(aAsciiEditMask, aLitMask);
1850  rPaintFormatter.SetStrictFormat(bStrict);
1851 }
1852 
1853 void DbPatternField::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
1854 {
1856 
1859 
1862 
1863  DbCellControl::Init( rParent, xCursor );
1864 }
1865 
1867 {
1868  return new EditCellController(static_cast<PatternControl*>(m_pWindow.get()));
1869 }
1870 
1871 OUString DbPatternField::impl_formatText( const OUString& _rText )
1872 {
1873  weld::PatternFormatter& rPaintFormatter = static_cast<PatternControl*>(m_pPainter.get())->get_formatter();
1874  rPaintFormatter.get_widget().set_text(_rText);
1875  rPaintFormatter.ReformatAll();
1876  return rPaintFormatter.get_widget().get_text();
1877 }
1878 
1879 OUString DbPatternField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
1880 {
1881  bool bIsForPaint = _rxField != m_rColumn.GetField();
1882  ::std::unique_ptr< FormattedColumnValue >& rpFormatter = bIsForPaint ? m_pPaintFormatter : m_pValueFormatter;
1883 
1884  if (!rpFormatter)
1885  {
1886  rpFormatter = std::make_unique< FormattedColumnValue> (
1887  m_xContext, getCursor(), Reference< XPropertySet >( _rxField, UNO_QUERY ) );
1888  OSL_ENSURE(rpFormatter, "DbPatternField::Init: no value formatter!");
1889  }
1890  else
1891  OSL_ENSURE( rpFormatter->getColumn() == _rxField, "DbPatternField::GetFormatText: my value formatter is working for another field ...!" );
1892  // re-creating the value formatter here every time would be quite expensive ...
1893 
1894  OUString sText;
1895  if (rpFormatter)
1896  sText = rpFormatter->getFormattedValue();
1897 
1898  return impl_formatText( sText );
1899 }
1900 
1901 void DbPatternField::UpdateFromField( const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1902 {
1903  weld::Entry& rEntry = static_cast<PatternControl*>(m_pWindow.get())->get_widget();
1904  rEntry.set_text(GetFormatText(_rxField, _rxFormatter));
1905  rEntry.select_region(-1, 0);
1906 }
1907 
1909 {
1910  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbPatternField::updateFromModel: invalid call!" );
1911 
1912  OUString sText;
1913  _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
1914 
1915  weld::Entry& rEntry = static_cast<PatternControl*>(m_pWindow.get())->get_widget();
1916  rEntry.set_text(impl_formatText(sText));
1917  rEntry.select_region(-1, 0);
1918 }
1919 
1921 {
1922  weld::Entry& rEntry = static_cast<PatternControl*>(m_pWindow.get())->get_widget();
1923  m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, makeAny(rEntry.get_text()));
1924  return true;
1925 }
1926 
1927 DbSpinField::DbSpinField( DbGridColumn& _rColumn, sal_Int16 _nStandardAlign )
1928  :DbCellControl( _rColumn )
1929  ,m_nStandardAlign( _nStandardAlign )
1930 {
1931 }
1932 
1933 void DbSpinField::Init(BrowserDataWin& _rParent, const Reference< XRowSet >& _rxCursor)
1934 {
1936 
1938 
1939  // determine if we need a spinbutton version
1940  bool bSpinButton(false);
1941  if ( ::comphelper::getBOOL( xModel->getPropertyValue( FM_PROP_SPIN ) ) )
1942  bSpinButton = true;
1943  // create the fields
1944  m_pWindow = createField( &_rParent, bSpinButton, xModel );
1945  m_pPainter = createField( &_rParent, bSpinButton, xModel );
1946 
1947  // adjust all other settings which depend on the property values
1949 
1950  // call the base class
1951  DbCellControl::Init( _rParent, _rxCursor );
1952 }
1953 
1955 {
1956  return new ::svt::FormattedFieldCellController(static_cast<FormattedControlBase*>(m_pWindow.get()));
1957 }
1958 
1960  :DbSpinField( _rColumn )
1961 {
1968 }
1969 
1971 {
1972  DBG_ASSERT( m_pWindow, "DbNumericField::implAdjustGenericFieldSetting: not to be called without window!" );
1973  DBG_ASSERT( _rxModel.is(), "DbNumericField::implAdjustGenericFieldSetting: invalid model!" );
1974  if ( !m_pWindow || !_rxModel.is() )
1975  return;
1976 
1977  sal_Int32 nMin = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) ));
1978  sal_Int32 nMax = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) ));
1979  sal_Int32 nStep = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) ));
1980  bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
1981  sal_Int16 nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
1982  bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
1983 
1984  Formatter& rEditFormatter = static_cast<FormattedControlBase*>(m_pWindow.get())->get_formatter();
1985  rEditFormatter.SetMinValue(nMin);
1986  rEditFormatter.SetMaxValue(nMax);
1987  rEditFormatter.SetSpinSize(nStep);
1988  rEditFormatter.SetStrictFormat(bStrict);
1989 
1990  Formatter& rPaintFormatter = static_cast<FormattedControlBase*>(m_pPainter.get())->get_formatter();
1991  rPaintFormatter.SetMinValue(nMin);
1992  rPaintFormatter.SetMaxValue(nMax);
1993  rPaintFormatter.SetStrictFormat(bStrict);
1994 
1995  // give a formatter to the field and the painter;
1996  // test first if I can get from the service behind a connection
1997  Reference< css::util::XNumberFormatsSupplier > xSupplier;
1998  Reference< XRowSet > xForm;
1999  if ( m_rColumn.GetParent().getDataSource() )
2000  xForm.set( Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY );
2001  if ( xForm.is() )
2002  xSupplier = getNumberFormats( getConnection( xForm ), true );
2003  SvNumberFormatter* pFormatterUsed = nullptr;
2004  if ( xSupplier.is() )
2005  {
2006  SvNumberFormatsSupplierObj* pImplementation = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>( xSupplier );
2007  pFormatterUsed = pImplementation ? pImplementation->GetNumberFormatter() : nullptr;
2008  }
2009  if ( nullptr == pFormatterUsed )
2010  { // the cursor didn't lead to success -> standard
2011  pFormatterUsed = rEditFormatter.StandardFormatter();
2012  DBG_ASSERT( pFormatterUsed != nullptr, "DbNumericField::implAdjustGenericFieldSetting: no standard formatter given by the numeric field !" );
2013  }
2014  rEditFormatter.SetFormatter( pFormatterUsed );
2015  rPaintFormatter.SetFormatter( pFormatterUsed );
2016 
2017  // and then generate a format which has the desired length after the decimal point, etc.
2019  OUString sFormatString = pFormatterUsed->GenerateFormat(0, aAppLanguage, bThousand, false, nScale);
2020 
2021  rEditFormatter.SetFormat( sFormatString, aAppLanguage );
2022  rPaintFormatter.SetFormat( sFormatString, aAppLanguage );
2023 }
2024 
2026 {
2027  return VclPtr<DoubleNumericControl>::Create(pParent, bSpinButton);
2028 }
2029 
2030 namespace
2031 {
2032  OUString lcl_setFormattedNumeric_nothrow( FormattedControlBase& _rField, const DbCellControl& _rControl,
2033  const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
2034  {
2035  OUString sValue;
2036  if ( _rxField.is() )
2037  {
2038  try
2039  {
2040  double fValue = _rControl.GetValue( _rxField, _rxFormatter );
2041  if ( !_rxField->wasNull() )
2042  {
2043  _rField.get_formatter().SetValue(fValue);
2044  sValue = _rField.get_widget().get_text();
2045  }
2046  }
2047  catch( const Exception& )
2048  {
2049  DBG_UNHANDLED_EXCEPTION("svx");
2050  }
2051  }
2052  return sValue;
2053  }
2054 }
2055 
2056 OUString DbNumericField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter, const Color** /*ppColor*/)
2057 {
2058  return lcl_setFormattedNumeric_nothrow(dynamic_cast<FormattedControlBase&>(*m_pPainter), *this, _rxField, _rxFormatter);
2059 }
2060 
2061 void DbNumericField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter)
2062 {
2063  lcl_setFormattedNumeric_nothrow(dynamic_cast<FormattedControlBase&>(*m_pWindow), *this, _rxField, _rxFormatter);
2064 }
2065 
2067 {
2068  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbNumericField::updateFromModel: invalid call!" );
2069 
2070  FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2071 
2072  double dValue = 0;
2073  if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
2074  {
2075  Formatter& rFormatter = pControl->get_formatter();
2076  rFormatter.SetValue(dValue);
2077  }
2078  else
2079  pControl->get_widget().set_text(OUString());
2080 }
2081 
2083 {
2084  FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2085  OUString aText(pControl->get_widget().get_text());
2086  Any aVal;
2087 
2088  if (!aText.isEmpty()) // not empty
2089  {
2090  Formatter& rFormatter = pControl->get_formatter();
2091  double fValue = rFormatter.GetValue();
2092  aVal <<= fValue;
2093  }
2094  m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2095  return true;
2096 }
2097 
2099  :DbSpinField( _rColumn )
2100 {
2108 }
2109 
2111 {
2112  DBG_ASSERT( m_pWindow, "DbCurrencyField::implAdjustGenericFieldSetting: not to be called without window!" );
2113  DBG_ASSERT( _rxModel.is(), "DbCurrencyField::implAdjustGenericFieldSetting: invalid model!" );
2114  if ( !m_pWindow || !_rxModel.is() )
2115  return;
2116 
2117  sal_Int16 nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
2118  double nMin = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) );
2119  double nMax = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) );
2120  double nStep = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) );
2121  bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2122  bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
2123  OUString aStr( getString( _rxModel->getPropertyValue(FM_PROP_CURRENCYSYMBOL ) ) );
2124 
2125  Formatter& rEditFormatter = static_cast<FormattedControlBase*>(m_pWindow.get())->get_formatter();
2126  rEditFormatter.SetDecimalDigits(nScale);
2127  rEditFormatter.SetMinValue(nMin);
2128  rEditFormatter.SetMaxValue(nMax);
2129  rEditFormatter.SetSpinSize(nStep);
2130  rEditFormatter.SetStrictFormat(bStrict);
2131  weld::LongCurrencyFormatter& rCurrencyEditFormatter = static_cast<weld::LongCurrencyFormatter&>(rEditFormatter);
2132  rCurrencyEditFormatter.SetUseThousandSep(bThousand);
2133  rCurrencyEditFormatter.SetCurrencySymbol(aStr);
2134 
2135  Formatter& rPaintFormatter = static_cast<FormattedControlBase*>(m_pPainter.get())->get_formatter();
2136  rPaintFormatter.SetDecimalDigits(nScale);
2137  rPaintFormatter.SetMinValue(nMin);
2138  rPaintFormatter.SetMaxValue(nMax);
2139  rPaintFormatter.SetStrictFormat(bStrict);
2140  weld::LongCurrencyFormatter& rPaintCurrencyFormatter = static_cast<weld::LongCurrencyFormatter&>(rPaintFormatter);
2141  rPaintCurrencyFormatter.SetUseThousandSep(bThousand);
2142  rPaintCurrencyFormatter.SetCurrencySymbol(aStr);
2143 }
2144 
2146 {
2147  return VclPtr<LongCurrencyControl>::Create(pParent, bSpinButton);
2148 }
2149 
2150 namespace
2151 {
2152  OUString lcl_setFormattedCurrency_nothrow( FormattedControlBase& _rField, const DbCurrencyField& _rControl,
2153  const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
2154  {
2155  OUString sValue;
2156  if ( _rxField.is() )
2157  {
2158  try
2159  {
2160  double fValue = _rControl.GetValue( _rxField, _rxFormatter );
2161  if ( !_rxField->wasNull() )
2162  {
2163  _rField.get_formatter().SetValue(fValue);
2164  sValue = _rField.get_widget().get_text();
2165  }
2166  }
2167  catch( const Exception& )
2168  {
2169  DBG_UNHANDLED_EXCEPTION("svx");
2170  }
2171  }
2172  return sValue;
2173  }
2174 }
2175 
2176 OUString DbCurrencyField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter, const Color** /*ppColor*/)
2177 {
2178  return lcl_setFormattedCurrency_nothrow(dynamic_cast<FormattedControlBase&>(*m_pPainter), *this, _rxField, _rxFormatter);
2179 }
2180 
2181 void DbCurrencyField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter)
2182 {
2183  lcl_setFormattedCurrency_nothrow(dynamic_cast<FormattedControlBase&>(*m_pWindow), *this, _rxField, _rxFormatter);
2184 }
2185 
2187 {
2188  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCurrencyField::updateFromModel: invalid call!" );
2189 
2190  FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2191 
2192  double dValue = 0;
2193  if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
2194  {
2195  Formatter& rFormatter = pControl->get_formatter();
2196  rFormatter.SetValue(dValue);
2197  }
2198  else
2199  pControl->get_widget().set_text(OUString());
2200 }
2201 
2203 {
2204  FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2205  OUString aText(pControl->get_widget().get_text());
2206  Any aVal;
2207 
2208  if (!aText.isEmpty()) // not empty
2209  {
2210  Formatter& rFormatter = pControl->get_formatter();
2211  double fValue = rFormatter.GetValue();
2212  aVal <<= fValue;
2213  }
2214  m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2215  return true;
2216 }
2217 
2219  :DbSpinField( _rColumn )
2220 {
2226 }
2227 
2229 {
2230  // check if there is a DropDown property set to TRUE
2231  bool bDropDown = !hasProperty( FM_PROP_DROPDOWN, rxModel )
2232  || getBOOL( rxModel->getPropertyValue( FM_PROP_DROPDOWN ) );
2233  // given the apparent inability to set a custom up/down action for a gtk
2234  // spinbutton to have different up/down dates depending on the zone the
2235  // mouse is in, show the dropdown calendar for both the spin or dropdown case
2236  return VclPtr<DateControl>::Create(pParent, bSpinButton || bDropDown);
2237 }
2238 
2240 {
2241  DBG_ASSERT( m_pWindow, "DbDateField::implAdjustGenericFieldSetting: not to be called without window!" );
2242  DBG_ASSERT( _rxModel.is(), "DbDateField::implAdjustGenericFieldSetting: invalid model!" );
2243  if ( !m_pWindow || !_rxModel.is() )
2244  return;
2245 
2246  sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_DATEFORMAT ) );
2247  util::Date aMin;
2248  OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMIN ) >>= aMin );
2249  util::Date aMax;
2250  OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMAX ) >>= aMax );
2251  bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2252 
2253  FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2254  weld::DateFormatter& rControlFormatter = static_cast<weld::DateFormatter&>(pControl->get_formatter());
2255 
2256  FormattedControlBase* pPainter = static_cast<FormattedControlBase*>(m_pPainter.get());
2257  weld::DateFormatter& rPainterFormatter = static_cast<weld::DateFormatter&>(pPainter->get_formatter());
2258 
2259  Any aCentury = _rxModel->getPropertyValue( FM_PROP_DATE_SHOW_CENTURY );
2260  if ( aCentury.getValueType().getTypeClass() != TypeClass_VOID )
2261  {
2262  bool bShowDateCentury = getBOOL( aCentury );
2263 
2264  rControlFormatter.SetShowDateCentury(bShowDateCentury);
2265  rPainterFormatter.SetShowDateCentury(bShowDateCentury);
2266  }
2267 
2268  rControlFormatter.SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) );
2269  rControlFormatter.SetMin( aMin );
2270  rControlFormatter.SetMax( aMax );
2271  rControlFormatter.SetStrictFormat( bStrict );
2272  rControlFormatter.EnableEmptyField( true );
2273 
2274  rPainterFormatter.SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) );
2275  rPainterFormatter.SetMin( aMin );
2276  rPainterFormatter.SetMax( aMax );
2277  rPainterFormatter.SetStrictFormat( bStrict );
2278  rPainterFormatter.EnableEmptyField( true );
2279 }
2280 
2281 namespace
2282 {
2283  OUString lcl_setFormattedDate_nothrow(DateControl& _rField, const Reference<XColumn>& _rxField)
2284  {
2285  OUString sDate;
2286  if ( _rxField.is() )
2287  {
2288  try
2289  {
2290  css::util::Date aValue = _rxField->getDate();
2291  if (!_rxField->wasNull())
2292  {
2293  _rField.SetDate(::Date(aValue.Day, aValue.Month, aValue.Year));
2294  sDate = _rField.get_widget().get_text();
2295  }
2296  }
2297  catch( const Exception& )
2298  {
2299  DBG_UNHANDLED_EXCEPTION("svx");
2300  }
2301  }
2302  return sDate;
2303  }
2304 }
2305 
2306 OUString DbDateField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
2307 {
2308  return lcl_setFormattedDate_nothrow(*static_cast<DateControl*>(m_pPainter.get()), _rxField);
2309 }
2310 
2311 void DbDateField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2312 {
2313  lcl_setFormattedDate_nothrow(*static_cast<DateControl*>(m_pWindow.get()), _rxField);
2314 }
2315 
2317 {
2318  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbDateField::updateFromModel: invalid call!" );
2319 
2320  DateControl* pControl = static_cast<DateControl*>(m_pWindow.get());
2321 
2322  util::Date aDate;
2323  if ( _rxModel->getPropertyValue( FM_PROP_DATE ) >>= aDate )
2324  pControl->SetDate(::Date(aDate));
2325  else
2326  pControl->get_widget().set_text(OUString());
2327 }
2328 
2330 {
2331  FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2332  OUString aText(pControl->get_widget().get_text());
2333  Any aVal;
2334 
2335  if (!aText.isEmpty()) // not empty
2336  {
2337  weld::DateFormatter& rControlFormatter = static_cast<weld::DateFormatter&>(pControl->get_formatter());
2338  aVal <<= rControlFormatter.GetDate().GetUNODate();
2339  }
2340 
2341  m_rColumn.getModel()->setPropertyValue(FM_PROP_DATE, aVal);
2342  return true;
2343 }
2344 
2346  :DbSpinField( _rColumn, css::awt::TextAlign::LEFT )
2347 {
2352 }
2353 
2355 {
2356  return VclPtr<TimeControl>::Create(pParent, bSpinButton);
2357 }
2358 
2360 {
2361  DBG_ASSERT( m_pWindow, "DbTimeField::implAdjustGenericFieldSetting: not to be called without window!" );
2362  DBG_ASSERT( _rxModel.is(), "DbTimeField::implAdjustGenericFieldSetting: invalid model!" );
2363  if ( !m_pWindow || !_rxModel.is() )
2364  return;
2365 
2366  sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_TIMEFORMAT ) );
2367  util::Time aMin;
2368  OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMIN ) >>= aMin );
2369  util::Time aMax;
2370  OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMAX ) >>= aMax );
2371  bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2372 
2373  FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2374  weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
2375 
2376  rControlFormatter.SetExtFormat(static_cast<ExtTimeFieldFormat>(nFormat));
2377  rControlFormatter.SetMin(aMin);
2378  rControlFormatter.SetMax(aMax);
2379  rControlFormatter.SetStrictFormat(bStrict);
2380  rControlFormatter.EnableEmptyField(true);
2381 
2382  FormattedControlBase* pPainter = static_cast<FormattedControlBase*>(m_pPainter.get());
2383  weld::TimeFormatter& rPainterFormatter = static_cast<weld::TimeFormatter&>(pPainter->get_formatter());
2384 
2385  rPainterFormatter.SetExtFormat(static_cast<ExtTimeFieldFormat>(nFormat));
2386  rPainterFormatter.SetMin(aMin);
2387  rPainterFormatter.SetMax(aMax);
2388  rPainterFormatter.SetStrictFormat(bStrict);
2389  rPainterFormatter.EnableEmptyField(true);
2390 }
2391 
2392 namespace
2393 {
2394  OUString lcl_setFormattedTime_nothrow(TimeControl& _rField, const Reference<XColumn>& _rxField)
2395  {
2396  OUString sTime;
2397  if ( _rxField.is() )
2398  {
2399  try
2400  {
2401  css::util::Time aValue = _rxField->getTime();
2402  if (!_rxField->wasNull())
2403  {
2404  static_cast<weld::TimeFormatter&>(_rField.get_formatter()).SetTime( ::tools::Time( aValue ) );
2405  sTime = _rField.get_widget().get_text();
2406  }
2407  }
2408  catch( const Exception& )
2409  {
2410  DBG_UNHANDLED_EXCEPTION("svx");
2411  }
2412  }
2413  return sTime;
2414  }
2415 }
2416 
2417 OUString DbTimeField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
2418 {
2419  return lcl_setFormattedTime_nothrow(*static_cast<TimeControl*>(m_pPainter.get()), _rxField);
2420 }
2421 
2422 void DbTimeField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2423 {
2424  lcl_setFormattedTime_nothrow(*static_cast<TimeControl*>(m_pWindow.get()), _rxField);
2425 }
2426 
2428 {
2429  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTimeField::updateFromModel: invalid call!" );
2430 
2431  FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2432  weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
2433 
2434  util::Time aTime;
2435  if ( _rxModel->getPropertyValue( FM_PROP_TIME ) >>= aTime )
2436  rControlFormatter.SetTime(::tools::Time(aTime));
2437  else
2438  pControl->get_widget().set_text(OUString());
2439 }
2440 
2442 {
2443  FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2444  OUString aText(pControl->get_widget().get_text());
2445  Any aVal;
2446 
2447  if (!aText.isEmpty()) // not empty
2448  {
2449  weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
2450  aVal <<= rControlFormatter.GetTime().GetUNOTime();
2451  }
2452 
2453  m_rColumn.getModel()->setPropertyValue(FM_PROP_TIME, aVal);
2454  return true;
2455 }
2456 
2458  :DbCellControl(_rColumn)
2459 {
2460  setAlignedController( false );
2461 
2464 }
2465 
2466 void DbComboBox::_propertyChanged( const PropertyChangeEvent& _rEvent )
2467 {
2468  if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
2469  {
2470  SetList(_rEvent.NewValue);
2471  }
2472  else
2473  {
2474  DbCellControl::_propertyChanged( _rEvent ) ;
2475  }
2476 }
2477 
2478 void DbComboBox::SetList(const Any& rItems)
2479 {
2480  ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
2481  weld::ComboBox& rComboBox = pField->get_widget();
2482  rComboBox.clear();
2483 
2484  css::uno::Sequence<OUString> aTest;
2485  if (rItems >>= aTest)
2486  {
2487  for (const OUString& rString : std::as_const(aTest))
2488  rComboBox.append_text(rString);
2489 
2490  // tell the grid control that this controller is invalid and has to be re-initialized
2492  }
2493 }
2494 
2496 {
2497  // we no longer pay attention to FM_PROP_LINECOUNT
2498 }
2499 
2500 void DbComboBox::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
2501 {
2502  m_rColumn.SetAlignmentFromModel(css::awt::TextAlign::LEFT);
2503 
2505 
2506  // selection from right to left
2507  AllSettings aSettings = m_pWindow->GetSettings();
2508  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2509  aStyleSettings.SetSelectionOptions(
2510  aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2511  aSettings.SetStyleSettings(aStyleSettings);
2512  m_pWindow->SetSettings(aSettings, true);
2513 
2514  // some initial properties
2516  SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2518 
2519  DbCellControl::Init( rParent, xCursor );
2520 }
2521 
2523 {
2524  return new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2525 }
2526 
2527 OUString DbComboBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, const Color** /*ppColor*/)
2528 {
2529  const css::uno::Reference<css::beans::XPropertySet> xPS(_rxField, UNO_QUERY);
2530  ::dbtools::FormattedColumnValue fmter( xFormatter, xPS );
2531 
2532  return fmter.getFormattedValue();
2533 }
2534 
2535 void DbComboBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2536 {
2537  ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2538  pControl->get_widget().set_entry_text(GetFormatText(_rxField, xFormatter));
2539 }
2540 
2542 {
2543  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbComboBox::updateFromModel: invalid call!" );
2544 
2545  OUString sText;
2546  _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
2547 
2548  ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2549  weld::ComboBox& rComboBox = pControl->get_widget();
2550 
2551  OUString sOldActive = rComboBox.get_active_text();
2552  rComboBox.set_entry_text(sText);
2553  rComboBox.select_entry_region(0, -1);
2554 
2555  if (sOldActive != rComboBox.get_active_text())
2556  pControl->TriggerAuxModify();
2557 }
2558 
2560 {
2561  ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2562  weld::ComboBox& rComboBox = pControl->get_widget();
2563  OUString aText(rComboBox.get_active_text());
2564  m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, makeAny(aText));
2565  return true;
2566 }
2567 
2568 
2570  :DbCellControl(_rColumn)
2571  ,m_bBound(false)
2572 {
2573  setAlignedController( false );
2574 
2577 }
2578 
2579 void DbListBox::_propertyChanged( const css::beans::PropertyChangeEvent& _rEvent )
2580 {
2581  if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
2582  {
2583  SetList(_rEvent.NewValue);
2584  }
2585  else
2586  {
2587  DbCellControl::_propertyChanged( _rEvent ) ;
2588  }
2589 }
2590 
2591 void DbListBox::SetList(const Any& rItems)
2592 {
2593  ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2594 
2595  weld::ComboBox& rFieldList = pField->get_widget();
2596 
2597  rFieldList.clear();
2598  m_bBound = false;
2599 
2600  css::uno::Sequence<OUString> aTest;
2601  if (!(rItems >>= aTest))
2602  return;
2603 
2604  if (aTest.hasElements())
2605  {
2606  for (const OUString& rString : std::as_const(aTest))
2607  rFieldList.append_text(rString);
2608 
2609  m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2610  m_bBound = m_aValueList.hasElements();
2611 
2612  // tell the grid control that this controller is invalid and has to be re-initialized
2614  }
2615 }
2616 
2617 void DbListBox::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
2618 {
2619  m_rColumn.SetAlignment(css::awt::TextAlign::LEFT);
2620 
2622 
2623  // some initial properties
2625  SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2627 
2628  DbCellControl::Init( rParent, xCursor );
2629 }
2630 
2632 {
2633  // ignore FM_PROP_LINECOUNT
2634 }
2635 
2637 {
2638  return new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2639 }
2640 
2641 OUString DbListBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
2642 {
2643  OUString sText;
2644  if ( _rxField.is() )
2645  {
2646  try
2647  {
2648  sText = _rxField->getString();
2649  if ( m_bBound )
2650  {
2651  sal_Int32 nPos = ::comphelper::findValue( m_aValueList, sText );
2652  if ( nPos != -1 )
2653  sText = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget().get_text(nPos);
2654  else
2655  sText.clear();
2656  }
2657  }
2658  catch( const Exception& )
2659  {
2660  DBG_UNHANDLED_EXCEPTION("svx");
2661  }
2662  }
2663  return sText;
2664 }
2665 
2666 void DbListBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2667 {
2668  OUString sFormattedText( GetFormatText( _rxField, xFormatter ) );
2669  weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2670  if (!sFormattedText.isEmpty())
2671  rComboBox.set_active_text(sFormattedText);
2672  else
2673  rComboBox.set_active(-1);
2674 }
2675 
2677 {
2678  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbListBox::updateFromModel: invalid call!" );
2679 
2680  Sequence< sal_Int16 > aSelection;
2681  _rxModel->getPropertyValue( FM_PROP_SELECT_SEQ ) >>= aSelection;
2682 
2683  sal_Int16 nSelection = -1;
2684  if ( aSelection.hasElements() )
2685  nSelection = aSelection[ 0 ];
2686 
2687  ListBoxControl* pControl = static_cast<ListBoxControl*>(m_pWindow.get());
2688  weld::ComboBox& rComboBox = pControl->get_widget();
2689 
2690  int nOldActive = rComboBox.get_active();
2691  if (nSelection >= 0 && nSelection < rComboBox.get_count())
2692  rComboBox.set_active(nSelection);
2693  else
2694  rComboBox.set_active(-1);
2695 
2696  if (nOldActive != rComboBox.get_active())
2697  pControl->TriggerAuxModify();
2698 }
2699 
2701 {
2702  Any aVal;
2703  Sequence<sal_Int16> aSelectSeq;
2704  weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2705  auto nActive = rComboBox.get_active();
2706  if (nActive != -1)
2707  {
2708  aSelectSeq.realloc(1);
2709  *aSelectSeq.getArray() = static_cast<sal_Int16>(nActive);
2710  }
2711  aVal <<= aSelectSeq;
2712  m_rColumn.getModel()->setPropertyValue(FM_PROP_SELECT_SEQ, aVal);
2713  return true;
2714 }
2715 
2717  :DbCellControl(_rColumn)
2718  ,OSQLParserClient(rxContext)
2719  ,m_nControlClass(css::form::FormComponentType::TEXTFIELD)
2720  ,m_bFilterList(false)
2721  ,m_bFilterListFilled(false)
2722 {
2723 
2724  setAlignedController( false );
2725 }
2726 
2728 {
2729  if (m_nControlClass == css::form::FormComponentType::CHECKBOX)
2730  static_cast<CheckBoxControl*>(m_pWindow.get())->SetToggleHdl(Link<weld::CheckButton&,void>());
2731 
2732 }
2733 
2735 {
2736  static const DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter | DrawTextFlags::Left;
2737  switch (m_nControlClass)
2738  {
2739  case FormComponentType::CHECKBOX:
2740  {
2741  // center the checkbox within the space available
2742  CheckBoxControl* pControl = static_cast<CheckBoxControl*>(m_pPainter.get());
2743  Size aBoxSize = pControl->GetBox().get_preferred_size();
2744  tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
2745  rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
2746  aBoxSize);
2747 
2748  DbCellControl::PaintCell(rDev, aRect);
2749  break;
2750  }
2751  case FormComponentType::LISTBOX:
2752  rDev.DrawText(rRect, static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().get_active_text(), nStyle);
2753  break;
2754  default:
2755  rDev.DrawText(rRect, m_aText, nStyle);
2756  }
2757 }
2758 
2759 void DbFilterField::SetList(const Any& rItems, bool bComboBox)
2760 {
2761  css::uno::Sequence<OUString> aTest;
2762  rItems >>= aTest;
2763  if (!aTest.hasElements())
2764  return;
2765 
2766  if (bComboBox)
2767  {
2768  ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
2769  weld::ComboBox& rComboBox = pField->get_widget();
2770  for (const OUString& rString : std::as_const(aTest))
2771  rComboBox.append_text(rString);
2772  }
2773  else
2774  {
2775  ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2776  weld::ComboBox& rFieldBox = pField->get_widget();
2777  for (const OUString& rString : std::as_const(aTest))
2778  rFieldBox.append_text(rString);
2779 
2780  m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2781  }
2782 }
2783 
2784 void DbFilterField::CreateControl(BrowserDataWin* pParent, const Reference< css::beans::XPropertySet >& xModel)
2785 {
2786  switch (m_nControlClass)
2787  {
2788  case css::form::FormComponentType::CHECKBOX:
2790  m_pWindow->SetPaintTransparent( true );
2791  static_cast<CheckBoxControl*>(m_pWindow.get())->SetToggleHdl(LINK(this, DbFilterField, OnToggle));
2792 
2794  m_pPainter->SetPaintTransparent( true );
2795  m_pPainter->SetBackground();
2796  break;
2797  case css::form::FormComponentType::LISTBOX:
2798  {
2800  Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2801  SetList(aItems, false);
2802  } break;
2803  case css::form::FormComponentType::COMBOBOX:
2804  {
2806 
2807  AllSettings aSettings = m_pWindow->GetSettings();
2808  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2809  aStyleSettings.SetSelectionOptions(
2810  aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2811  aSettings.SetStyleSettings(aStyleSettings);
2812  m_pWindow->SetSettings(aSettings, true);
2813 
2814  if (!m_bFilterList)
2815  {
2816  Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2817  SetList(aItems, true);
2818  }
2819 
2820  } break;
2821  default:
2822  {
2824  AllSettings aSettings = m_pWindow->GetSettings();
2825  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2826  aStyleSettings.SetSelectionOptions(
2827  aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2828  aSettings.SetStyleSettings(aStyleSettings);
2829  m_pWindow->SetSettings(aSettings, true);
2830  }
2831  }
2832 }
2833 
2834 void DbFilterField::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
2835 {
2836  Reference< css::beans::XPropertySet > xModel(m_rColumn.getModel());
2837  m_rColumn.SetAlignment(css::awt::TextAlign::LEFT);
2838 
2839  if (xModel.is())
2840  {
2841  m_bFilterList = ::comphelper::hasProperty(FM_PROP_FILTERPROPOSAL, xModel) && ::comphelper::getBOOL(xModel->getPropertyValue(FM_PROP_FILTERPROPOSAL));
2842  if (m_bFilterList)
2843  m_nControlClass = css::form::FormComponentType::COMBOBOX;
2844  else
2845  {
2846  sal_Int16 nClassId = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_CLASSID));
2847  switch (nClassId)
2848  {
2849  case FormComponentType::CHECKBOX:
2850  case FormComponentType::LISTBOX:
2851  case FormComponentType::COMBOBOX:
2852  m_nControlClass = nClassId;
2853  break;
2854  default:
2855  if (m_bFilterList)
2856  m_nControlClass = FormComponentType::COMBOBOX;
2857  else
2858  m_nControlClass = FormComponentType::TEXTFIELD;
2859  }
2860  }
2861  }
2862 
2863  CreateControl( &rParent, xModel );
2864  DbCellControl::Init( rParent, xCursor );
2865 
2866  // filter cells are never readonly
2868 }
2869 
2871 {
2873  switch (m_nControlClass)
2874  {
2875  case css::form::FormComponentType::CHECKBOX:
2876  xController = new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
2877  break;
2878  case css::form::FormComponentType::LISTBOX:
2879  xController = new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2880  break;
2881  case css::form::FormComponentType::COMBOBOX:
2882  xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2883  break;
2884  default:
2885  if (m_bFilterList)
2886  xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2887  else
2888  xController = new EditCellController(static_cast<EditControlBase*>(m_pWindow.get()));
2889  }
2890  return xController;
2891 }
2892 
2894 {
2895  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFilterField::updateFromModel: invalid call!" );
2896 
2897  OSL_FAIL( "DbFilterField::updateFromModel: not implemented yet (how the hell did you reach this?)!" );
2898  // TODO: implement this.
2899  // remember: updateFromModel should be some kind of opposite of commitControl
2900 }
2901 
2903 {
2904  OUString aText(m_aText);
2905  switch (m_nControlClass)
2906  {
2907  case css::form::FormComponentType::CHECKBOX:
2908  return true;
2909  case css::form::FormComponentType::LISTBOX:
2910  {
2911  aText.clear();
2912  weld::ComboBox& rComboBox = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget();
2913  auto nActive = rComboBox.get_active();
2914  if (nActive != -1)
2915  {
2916  sal_Int16 nPos = static_cast<sal_Int16>(nActive);
2917  if ( ( nPos >= 0 ) && ( nPos < m_aValueList.getLength() ) )
2918  aText = m_aValueList.getConstArray()[nPos];
2919  }
2920 
2921  if (m_aText != aText)
2922  {
2923  m_aText = aText;
2924  m_aCommitLink.Call(*this);
2925  }
2926  return true;
2927  }
2928  case css::form::FormComponentType::COMBOBOX:
2929  {
2930  aText = static_cast<ComboBoxControl*>(m_pWindow.get())->get_widget().get_active_text();
2931  break;
2932  }
2933  default:
2934  {
2935  aText = static_cast<EditControlBase*>(m_pWindow.get())->get_widget().get_text();
2936  break;
2937  }
2938  }
2939 
2940  if (m_aText != aText)
2941  {
2942  // check the text with the SQL-Parser
2943  OUString aNewText(comphelper::string::stripEnd(aText, ' '));
2944  if (!aNewText.isEmpty())
2945  {
2946  OUString aErrorMsg;
2948 
2949  std::unique_ptr< OSQLParseNode > pParseNode = predicateTree(aErrorMsg, aNewText,xNumberFormatter, m_rColumn.GetField());
2950  if (pParseNode != nullptr)
2951  {
2952  OUString aPreparedText;
2953 
2954  css::lang::Locale aAppLocale = Application::GetSettings().GetUILanguageTag().getLocale();
2955 
2956  Reference< XRowSet > xDataSourceRowSet(
2957  Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY);
2958  Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
2959 
2960  pParseNode->parseNodeToPredicateStr(aPreparedText,
2961  xConnection,
2962  xNumberFormatter,
2963  m_rColumn.GetField(),
2964  OUString(),
2965  aAppLocale,
2966  OUString("."),
2967  getParseContext());
2968  m_aText = aPreparedText;
2969  }
2970  else
2971  {
2972 
2973  SQLException aError;
2974  aError.Message = aErrorMsg;
2975  displayException(aError, VCLUnoHelper::GetInterface(m_pWindow->GetParent()));
2976  // TODO: transport the title
2977 
2978  return false;
2979  }
2980  }
2981  else
2982  m_aText = aText;
2983 
2984  m_pWindow->SetText(m_aText);
2985  m_aCommitLink.Call(*this);
2986  }
2987  return true;
2988 }
2989 
2990 
2991 void DbFilterField::SetText(const OUString& rText)
2992 {
2993  m_aText = rText;
2994  switch (m_nControlClass)
2995  {
2996  case css::form::FormComponentType::CHECKBOX:
2997  {
2998  TriState eState;
2999  if (rText == "1")
3000  eState = TRISTATE_TRUE;
3001  else if (rText == "0")
3002  eState = TRISTATE_FALSE;
3003  else
3004  eState = TRISTATE_INDET;
3005 
3006  static_cast<CheckBoxControl*>(m_pWindow.get())->SetState(eState);
3007  static_cast<CheckBoxControl*>(m_pPainter.get())->SetState(eState);
3008  } break;
3009  case css::form::FormComponentType::LISTBOX:
3010  {
3011  sal_Int32 nPos = ::comphelper::findValue(m_aValueList, m_aText);
3012  static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().set_active(nPos);
3013  } break;
3014  case css::form::FormComponentType::COMBOBOX:
3015  {
3016  static_cast<ComboBoxControl*>(m_pWindow.get())->get_widget().set_entry_text(m_aText);
3017  break;
3018  }
3019  default:
3020  {
3021  static_cast<EditControlBase*>(m_pWindow.get())->get_widget().set_text(m_aText);
3022  break;
3023  }
3024  }
3025 
3026  // now force a repaint on the window
3028 }
3029 
3030 
3032 {
3033  // should we fill the combobox with a filter proposal?
3035  return;
3036 
3037  m_bFilterListFilled = true;
3038  Reference< css::beans::XPropertySet > xField = m_rColumn.GetField();
3039  if (!xField.is())
3040  return;
3041 
3042  OUString aName;
3043  xField->getPropertyValue(FM_PROP_NAME) >>= aName;
3044 
3045  // the columnmodel
3046  Reference< css::container::XChild > xModelAsChild(m_rColumn.getModel(), UNO_QUERY);
3047  // the grid model
3048  xModelAsChild.set(xModelAsChild->getParent(),UNO_QUERY);
3049  Reference< XRowSet > xForm(xModelAsChild->getParent(), UNO_QUERY);
3050  if (!xForm.is())
3051  return;
3052 
3053  Reference<XPropertySet> xFormProp(xForm,UNO_QUERY);
3054  Reference< XTablesSupplier > xSupTab;
3055  xFormProp->getPropertyValue("SingleSelectQueryComposer") >>= xSupTab;
3056 
3057  Reference< XConnection > xConnection(getConnection(xForm));
3058  if (!xSupTab.is())
3059  return;
3060 
3061  // search the field
3062  Reference< XColumnsSupplier > xSupCol(xSupTab,UNO_QUERY);
3063  Reference< css::container::XNameAccess > xFieldNames = xSupCol->getColumns();
3064  if (!xFieldNames->hasByName(aName))
3065  return;
3066 
3067  Reference< css::container::XNameAccess > xTablesNames = xSupTab->getTables();
3068  Reference< css::beans::XPropertySet > xComposerFieldAsSet(xFieldNames->getByName(aName),UNO_QUERY);
3069 
3070  if (!xComposerFieldAsSet.is() ||
3071  !::comphelper::hasProperty(FM_PROP_TABLENAME, xComposerFieldAsSet) ||
3072  !::comphelper::hasProperty(FM_PROP_FIELDSOURCE, xComposerFieldAsSet))
3073  return;
3074 
3075  OUString aFieldName;
3076  OUString aTableName;
3077  xComposerFieldAsSet->getPropertyValue(FM_PROP_FIELDSOURCE) >>= aFieldName;
3078  xComposerFieldAsSet->getPropertyValue(FM_PROP_TABLENAME) >>= aTableName;
3079 
3080  // no possibility to create a select statement
3081  // looking for the complete table name
3082  if (!xTablesNames->hasByName(aTableName))
3083  return;
3084 
3085  // build a statement and send as query;
3086  // Access to the connection
3087  Reference< XStatement > xStatement;
3088  Reference< XResultSet > xListCursor;
3089  Reference< css::sdb::XColumn > xDataField;
3090 
3091  try
3092  {
3093  Reference< XDatabaseMetaData > xMeta = xConnection->getMetaData();
3094 
3095  OUString aQuote(xMeta->getIdentifierQuoteString());
3096  OUStringBuffer aStatement("SELECT DISTINCT ");
3097  aStatement.append(quoteName(aQuote, aName));
3098  if (!aFieldName.isEmpty() && aName != aFieldName)
3099  {
3100  aStatement.append(" AS ");
3101  aStatement.append(quoteName(aQuote, aFieldName));
3102  }
3103 
3104  aStatement.append(" FROM ");
3105 
3106  Reference< XPropertySet > xTableNameAccess(xTablesNames->getByName(aTableName), UNO_QUERY_THROW);
3107  aStatement.append(composeTableNameForSelect(xConnection, xTableNameAccess));
3108 
3109  xStatement = xConnection->createStatement();
3110  Reference< css::beans::XPropertySet > xStatementProps(xStatement, UNO_QUERY);
3111  xStatementProps->setPropertyValue(FM_PROP_ESCAPE_PROCESSING, makeAny(true));
3112 
3113  xListCursor = xStatement->executeQuery(aStatement.makeStringAndClear());
3114 
3115  Reference< css::sdbcx::XColumnsSupplier > xSupplyCols(xListCursor, UNO_QUERY);
3116  Reference< css::container::XIndexAccess > xFields(xSupplyCols->getColumns(), UNO_QUERY);
3117  xDataField.set(xFields->getByIndex(0), css::uno::UNO_QUERY);
3118  if (!xDataField.is())
3119  return;
3120  }
3121  catch(const Exception&)
3122  {
3123  ::comphelper::disposeComponent(xStatement);
3124  return;
3125  }
3126 
3127  sal_Int16 i = 0;
3128  ::std::vector< OUString > aStringList;
3129  aStringList.reserve(16);
3130  OUString aStr;
3131  css::util::Date aNullDate = m_rColumn.GetParent().getNullDate();
3132  sal_Int32 nFormatKey = m_rColumn.GetKey();
3134  sal_Int16 nKeyType = ::comphelper::getNumberFormatType(xFormatter->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey);
3135 
3136  while (!xListCursor->isAfterLast() && i++ < SHRT_MAX) // max number of entries
3137  {
3138  aStr = getFormattedValue(xDataField, xFormatter, aNullDate, nFormatKey, nKeyType);
3139  aStringList.push_back(aStr);
3140  (void)xListCursor->next();
3141  }
3142 
3143  ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
3144  weld::ComboBox& rComboBox = pField->get_widget();
3145  // filling the entries for the combobox
3146  for (const auto& rString : aStringList)
3147  rComboBox.append_text(rString);
3148 }
3149 
3150 OUString DbFilterField::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
3151 {
3152  return OUString();
3153 }
3154 
3155 void DbFilterField::UpdateFromField(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/)
3156 {
3157  OSL_FAIL( "DbFilterField::UpdateFromField: cannot update a filter control from a field!" );
3158 }
3159 
3161 {
3162  TriState eState = static_cast<CheckBoxControl*>(m_pWindow.get())->GetState();
3163  OUStringBuffer aTextBuf;
3164 
3165  Reference< XRowSet > xDataSourceRowSet(
3166  Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY);
3167  Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
3168  const sal_Int32 nBooleanComparisonMode = ::dbtools::DatabaseMetaData( xConnection ).getBooleanComparisonMode();
3169 
3170  switch (eState)
3171  {
3172  case TRISTATE_TRUE:
3173  ::dbtools::getBooleanComparisonPredicate(u"", true, nBooleanComparisonMode, aTextBuf);
3174  break;
3175  case TRISTATE_FALSE:
3176  ::dbtools::getBooleanComparisonPredicate(u"", false, nBooleanComparisonMode, aTextBuf);
3177  break;
3178  case TRISTATE_INDET:
3179  break;
3180  }
3181 
3182  const OUString aText(aTextBuf.makeStringAndClear());
3183 
3184  if (m_aText != aText)
3185  {
3186  m_aText = aText;
3187  m_aCommitLink.Call(*this);
3188  }
3189 }
3190 
3191 FmXGridCell::FmXGridCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> _pControl )
3192  :OComponentHelper(m_aMutex)
3193  ,m_pColumn(pColumn)
3194  ,m_pCellControl( std::move(_pControl) )
3195  ,m_aWindowListeners( m_aMutex )
3196  ,m_aFocusListeners( m_aMutex )
3197  ,m_aKeyListeners( m_aMutex )
3198  ,m_aMouseListeners( m_aMutex )
3199  ,m_aMouseMotionListeners( m_aMutex )
3200 {
3201 }
3202 
3204 {
3205  svt::ControlBase* pEventWindow( getEventWindow() );
3206  if ( pEventWindow )
3207  {
3208  pEventWindow->AddEventListener( LINK( this, FmXGridCell, OnWindowEvent ) );
3209  pEventWindow->SetFocusInHdl(LINK( this, FmXGridCell, OnFocusGained));
3210  pEventWindow->SetFocusOutHdl(LINK( this, FmXGridCell, OnFocusLost));
3211  pEventWindow->SetMousePressHdl(LINK( this, FmXGridCell, OnMousePress));
3212  pEventWindow->SetMouseReleaseHdl(LINK( this, FmXGridCell, OnMouseRelease));
3213  pEventWindow->SetMouseMoveHdl(LINK( this, FmXGridCell, OnMouseMove));
3214  }
3215 }
3216 
3218 {
3219  if ( m_pCellControl )
3220  return &m_pCellControl->GetWindow();
3221  return nullptr;
3222 }
3223 
3225 {
3226  if (!OComponentHelper::rBHelper.bDisposed)
3227  {
3228  acquire();
3229  dispose();
3230  }
3231 
3232 }
3233 
3235 {
3236  if (m_pCellControl)
3237  m_pCellControl->SetTextLineColor();
3238 }
3239 
3241 {
3242  if (m_pCellControl)
3243  m_pCellControl->SetTextLineColor(_rColor);
3244 }
3245 
3246 // XTypeProvider
3247 
3248 Sequence< Type > SAL_CALL FmXGridCell::getTypes( )
3249 {
3250  Sequence< uno::Type > aTypes = ::comphelper::concatSequences(
3253  );
3254  if ( m_pCellControl )
3255  aTypes = ::comphelper::concatSequences(
3256  aTypes,
3258  );
3259  return aTypes;
3260 }
3261 
3262 
3264 
3265 // OComponentHelper
3266 
3267 void FmXGridCell::disposing()
3268 {
3269  lang::EventObject aEvent( *this );
3270  m_aWindowListeners.disposeAndClear( aEvent );
3271  m_aFocusListeners.disposeAndClear( aEvent );
3272  m_aKeyListeners.disposeAndClear( aEvent );
3273  m_aMouseListeners.disposeAndClear( aEvent );
3274  m_aMouseMotionListeners.disposeAndClear( aEvent );
3275 
3276  OComponentHelper::disposing();
3277  m_pColumn = nullptr;
3278  m_pCellControl.reset();
3279 }
3280 
3281 
3282 Any SAL_CALL FmXGridCell::queryAggregation( const css::uno::Type& _rType )
3283 {
3284  Any aReturn = OComponentHelper::queryAggregation( _rType );
3285 
3286  if ( !aReturn.hasValue() )
3287  aReturn = FmXGridCell_Base::queryInterface( _rType );
3288 
3289  if ( !aReturn.hasValue() && ( m_pCellControl != nullptr ) )
3290  aReturn = FmXGridCell_WindowBase::queryInterface( _rType );
3291 
3292  return aReturn;
3293 }
3294 
3295 // css::awt::XControl
3296 
3297 Reference< XInterface > FmXGridCell::getContext()
3298 {
3299  return Reference< XInterface > ();
3300 }
3301 
3302 
3303 Reference< css::awt::XControlModel > FmXGridCell::getModel()
3304 {
3305  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3306  return Reference< css::awt::XControlModel > (m_pColumn->getModel(), UNO_QUERY);
3307 }
3308 
3309 // css::form::XBoundControl
3310 
3312 {
3313  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3314  return m_pColumn->isLocked();
3315 }
3316 
3317 
3319 {
3320  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3321  if (getLock() == _bLock)
3322  return;
3323  else
3324  {
3325  ::osl::MutexGuard aGuard(m_aMutex);
3326  m_pColumn->setLock(_bLock);
3327  }
3328 }
3329 
3330 
3331 void SAL_CALL FmXGridCell::setPosSize( ::sal_Int32, ::sal_Int32, ::sal_Int32, ::sal_Int32, ::sal_Int16 )
3332 {
3333  OSL_FAIL( "FmXGridCell::setPosSize: not implemented" );
3334  // not allowed to tamper with this for a grid cell
3335 }
3336 
3337 
3338 awt::Rectangle SAL_CALL FmXGridCell::getPosSize( )
3339 {
3340  OSL_FAIL( "FmXGridCell::getPosSize: not implemented" );
3341  return awt::Rectangle();
3342 }
3343 
3344 
3346 {
3347  OSL_FAIL( "FmXGridCell::setVisible: not implemented" );
3348  // not allowed to tamper with this for a grid cell
3349 }
3350 
3351 
3353 {
3354  OSL_FAIL( "FmXGridCell::setEnable: not implemented" );
3355  // not allowed to tamper with this for a grid cell
3356 }
3357 
3358 
3359 void SAL_CALL FmXGridCell::setFocus( )
3360 {
3361  OSL_FAIL( "FmXGridCell::setFocus: not implemented" );
3362  // not allowed to tamper with this for a grid cell
3363 }
3364 
3365 
3366 void SAL_CALL FmXGridCell::addWindowListener( const Reference< awt::XWindowListener >& _rxListener )
3367 {
3368  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3369  m_aWindowListeners.addInterface( _rxListener );
3370 }
3371 
3372 
3373 void SAL_CALL FmXGridCell::removeWindowListener( const Reference< awt::XWindowListener >& _rxListener )
3374 {
3375  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3376  m_aWindowListeners.removeInterface( _rxListener );
3377 }
3378 
3379 
3380 void SAL_CALL FmXGridCell::addFocusListener( const Reference< awt::XFocusListener >& _rxListener )
3381 {
3382  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3383  m_aFocusListeners.addInterface( _rxListener );
3384 }
3385 
3386 
3387 void SAL_CALL FmXGridCell::removeFocusListener( const Reference< awt::XFocusListener >& _rxListener )
3388 {
3389  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3390  m_aFocusListeners.removeInterface( _rxListener );
3391 }
3392 
3393 
3394 void SAL_CALL FmXGridCell::addKeyListener( const Reference< awt::XKeyListener >& _rxListener )
3395 {
3396  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3397  m_aKeyListeners.addInterface( _rxListener );
3398 }
3399 
3400 
3401 void SAL_CALL FmXGridCell::removeKeyListener( const Reference< awt::XKeyListener >& _rxListener )
3402 {
3403  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3404  m_aKeyListeners.removeInterface( _rxListener );
3405 }
3406 
3407 
3408 void SAL_CALL FmXGridCell::addMouseListener( const Reference< awt::XMouseListener >& _rxListener )
3409 {
3410  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3411  m_aMouseListeners.addInterface( _rxListener );
3412 }
3413 
3414 
3415 void SAL_CALL FmXGridCell::removeMouseListener( const Reference< awt::XMouseListener >& _rxListener )
3416 {
3417  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3418  m_aMouseListeners.removeInterface( _rxListener );
3419 }
3420 
3421 
3422 void SAL_CALL FmXGridCell::addMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener )
3423 {
3424  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3425  m_aMouseMotionListeners.addInterface( _rxListener );
3426 }
3427 
3428 
3429 void SAL_CALL FmXGridCell::removeMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener )
3430 {
3431  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3433 }
3434 
3435 void SAL_CALL FmXGridCell::addPaintListener( const Reference< awt::XPaintListener >& )
3436 {
3437  OSL_FAIL( "FmXGridCell::addPaintListener: not implemented" );
3438 }
3439 
3440 void SAL_CALL FmXGridCell::removePaintListener( const Reference< awt::XPaintListener >& )
3441 {
3442  OSL_FAIL( "FmXGridCell::removePaintListener: not implemented" );
3443 }
3444 
3445 IMPL_LINK( FmXGridCell, OnWindowEvent, VclWindowEvent&, _rEvent, void )
3446 {
3447  ENSURE_OR_THROW( _rEvent.GetWindow(), "illegal window" );
3448  onWindowEvent(_rEvent.GetId(), _rEvent.GetData());
3449 }
3450 
3451 void FmXGridCell::onFocusGained( const awt::FocusEvent& _rEvent )
3452 {
3453  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3454  m_aFocusListeners.notifyEach( &awt::XFocusListener::focusGained, _rEvent );
3455 }
3456 
3457 void FmXGridCell::onFocusLost( const awt::FocusEvent& _rEvent )
3458 {
3459  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3460  m_aFocusListeners.notifyEach( &awt::XFocusListener::focusLost, _rEvent );
3461 }
3462 
3464 {
3465  if (!m_aFocusListeners.getLength())
3466  return;
3467 
3468  awt::FocusEvent aEvent;
3469  aEvent.Source = *this;
3470  aEvent.Temporary = false;
3471 
3472  onFocusGained(aEvent);
3473 }
3474 
3476 {
3477  if (!m_aFocusListeners.getLength())
3478  return;
3479 
3480  awt::FocusEvent aEvent;
3481  aEvent.Source = *this;
3482  aEvent.Temporary = false;
3483 
3484  onFocusLost(aEvent);
3485 }
3486 
3487 IMPL_LINK(FmXGridCell, OnMousePress, const MouseEvent&, rEventData, void)
3488 {
3489  if (!m_aMouseListeners.getLength())
3490  return;
3491 
3492  awt::MouseEvent aEvent(VCLUnoHelper::createMouseEvent(rEventData, *this));
3493  m_aMouseListeners.notifyEach(&awt::XMouseListener::mousePressed, aEvent);
3494 }
3495 
3496 IMPL_LINK(FmXGridCell, OnMouseRelease, const MouseEvent&, rEventData, void)
3497 {
3498  if (!m_aMouseListeners.getLength())
3499  return;
3500 
3501  awt::MouseEvent aEvent(VCLUnoHelper::createMouseEvent(rEventData, *this));
3502  m_aMouseListeners.notifyEach(&awt::XMouseListener::mouseReleased, aEvent);
3503 }
3504 
3505 IMPL_LINK(FmXGridCell, OnMouseMove, const MouseEvent&, rMouseEvent, void)
3506 {
3507  if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
3508  {
3509  if ( m_aMouseListeners.getLength() != 0 )
3510  {
3511  awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3512  m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? &awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
3513  }
3514  }
3515  else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() )
3516  {
3517  if ( m_aMouseMotionListeners.getLength() != 0 )
3518  {
3519  awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3520  aEvent.ClickCount = 0;
3521  const bool bSimpleMove = bool( rMouseEvent.GetMode() & MouseEventModifiers::SIMPLEMOVE );
3522  m_aMouseMotionListeners.notifyEach( bSimpleMove ? &awt::XMouseMotionListener::mouseMoved: &awt::XMouseMotionListener::mouseDragged, aEvent );
3523  }
3524  }
3525 }
3526 
3527 void FmXGridCell::onWindowEvent(const VclEventId _nEventId, const void* _pEventData)
3528 {
3529  switch ( _nEventId )
3530  {
3531  case VclEventId::WindowKeyInput:
3532  case VclEventId::WindowKeyUp:
3533  {
3534  if ( !m_aKeyListeners.getLength() )
3535  break;
3536 
3537  const bool bKeyPressed = ( _nEventId == VclEventId::WindowKeyInput );
3538  awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent( *static_cast< const ::KeyEvent* >( _pEventData ), *this ) );
3539  m_aKeyListeners.notifyEach( bKeyPressed ? &awt::XKeyListener::keyPressed: &awt::XKeyListener::keyReleased, aEvent );
3540  }
3541  break;
3542  default: break;
3543  }
3544 }
3545 
3546 
3548  const Reference< css::sdb::XColumn >& _rxField,
3549  const Reference< XNumberFormatter >& xFormatter)
3550 {
3551  m_pCellControl->PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3552 }
3553 
3554 
3556 {
3557  Reference< css::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3558  if (xField.is())
3559  m_pCellControl->UpdateFromField(xField, m_pColumn->GetParent().getNumberFormatter());
3560 }
3561 
3562 
3563 FmXTextCell::FmXTextCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3564  :FmXDataCell( pColumn, std::move(pControl) )
3565  ,m_bIsMultiLineText(false)
3566 {
3567 }
3568 
3569 
3571  const tools::Rectangle& rRect,
3572  const Reference< css::sdb::XColumn >& _rxField,
3573  const Reference< XNumberFormatter >& xFormatter)
3574 {
3575  DrawTextFlags nStyle = DrawTextFlags::Clip;
3576  if ( ( rDev.GetOutDevType() == OUTDEV_WINDOW ) && !rDev.GetOwnerWindow()->IsEnabled() )
3577  nStyle |= DrawTextFlags::Disable;
3578 
3579  switch (m_pColumn->GetAlignment())
3580  {
3581  case css::awt::TextAlign::RIGHT:
3582  nStyle |= DrawTextFlags::Right;
3583  break;
3584  case css::awt::TextAlign::CENTER:
3585  nStyle |= DrawTextFlags::Center;
3586  break;
3587  default:
3588  nStyle |= DrawTextFlags::Left;
3589  }
3590 
3591  if (!m_bIsMultiLineText)
3592  nStyle |= DrawTextFlags::VCenter;
3593  else
3594  nStyle |= DrawTextFlags::Top | DrawTextFlags::MultiLine | DrawTextFlags::WordBreak;
3595 
3596  try
3597  {
3598  const Color* pColor = nullptr;
3599  OUString aText = GetText(_rxField, xFormatter, &pColor);
3600  if (pColor != nullptr)
3601  {
3602  Color aOldTextColor( rDev.GetTextColor() );
3603  rDev.SetTextColor( *pColor );
3604  rDev.DrawText(rRect, aText, nStyle);
3605  rDev.SetTextColor( aOldTextColor );
3606  }
3607  else
3608  rDev.DrawText(rRect, aText, nStyle);
3609  }
3610  catch (const Exception&)
3611  {
3612  TOOLS_WARN_EXCEPTION("svx.fmcomp", "PaintFieldToCell");
3613  }
3614 }
3615 
3616 FmXEditCell::FmXEditCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3617  :FmXTextCell( pColumn, std::move(pControl) )
3618  ,m_aTextListeners(m_aMutex)
3619  ,m_aChangeListeners( m_aMutex )
3620  ,m_pEditImplementation( nullptr )
3621  ,m_bOwnEditImplementation( false )
3622 {
3623 
3624  DbTextField* pTextField = dynamic_cast<DbTextField*>( m_pCellControl.get() );
3625  if ( pTextField )
3626  {
3627 
3629  m_bIsMultiLineText = pTextField->IsMultiLineEdit();
3630  }
3631  else
3632  {
3633  m_pEditImplementation = new EntryImplementation(static_cast<EditControlBase&>(m_pCellControl->GetWindow()));
3634  m_bOwnEditImplementation = true;
3635  }
3637 }
3638 
3640 {
3641  if (!OComponentHelper::rBHelper.bDisposed)
3642  {
3643  acquire();
3644  dispose();
3645  }
3646 }
3647 
3648 // OComponentHelper
3650 {
3651  css::lang::EventObject aEvt(*this);
3654 
3656  delete m_pEditImplementation;
3657  m_pEditImplementation = nullptr;
3658 
3660 }
3661 
3662 Any SAL_CALL FmXEditCell::queryAggregation( const css::uno::Type& _rType )
3663 {
3664  Any aReturn = FmXTextCell::queryAggregation( _rType );
3665 
3666  if ( !aReturn.hasValue() )
3667  aReturn = FmXEditCell_Base::queryInterface( _rType );
3668 
3669  return aReturn;
3670 }
3671 
3672 Sequence< css::uno::Type > SAL_CALL FmXEditCell::getTypes( )
3673 {
3674  return ::comphelper::concatSequences(
3677  );
3678 }
3679 
3681 
3682 // css::awt::XTextComponent
3683 void SAL_CALL FmXEditCell::addTextListener(const Reference< css::awt::XTextListener >& l)
3684 {
3685  m_aTextListeners.addInterface( l );
3686 }
3687 
3688 
3689 void SAL_CALL FmXEditCell::removeTextListener(const Reference< css::awt::XTextListener >& l)
3690 {
3692 }
3693 
3694 void SAL_CALL FmXEditCell::setText( const OUString& aText )
3695 {
3696  ::osl::MutexGuard aGuard( m_aMutex );
3697 
3698  if ( m_pEditImplementation )
3699  {
3700  m_pEditImplementation->SetText( aText );
3701 
3702  // In Java, a textChanged is fired as well; not in VCL.
3703  // css::awt::Toolkit must be Java-compliant...
3704  onTextChanged();
3705  }
3706 }
3707 
3708 void SAL_CALL FmXEditCell::insertText(const css::awt::Selection& rSel, const OUString& aText)
3709 {
3710  ::osl::MutexGuard aGuard( m_aMutex );
3711 
3712  if ( m_pEditImplementation )
3713  {
3714  m_pEditImplementation->SetSelection( Selection( rSel.Min, rSel.Max ) );
3716  }
3717 }
3718 
3719 OUString SAL_CALL FmXEditCell::getText()
3720 {
3721  ::osl::MutexGuard aGuard( m_aMutex );
3722 
3723  OUString aText;
3724  if ( m_pEditImplementation )
3725  {
3727  {
3728  // if the display isn't sync with the cursor we can't ask the edit field
3729  LineEnd eLineEndFormat = getModelLineEndSetting( m_pColumn->getModel() );
3730  aText = m_pEditImplementation->GetText( eLineEndFormat );
3731  }
3732  else
3733  {
3734  Reference< css::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3735  if (xField.is())
3736  aText = GetText(xField, m_pColumn->GetParent().getNumberFormatter());
3737  }
3738  }
3739  return aText;
3740 }
3741 
3742 OUString SAL_CALL FmXEditCell::getSelectedText()
3743 {
3744  ::osl::MutexGuard aGuard( m_aMutex );
3745 
3746  OUString aText;
3747  if ( m_pEditImplementation )
3748  {
3749  LineEnd eLineEndFormat = m_pColumn ? getModelLineEndSetting( m_pColumn->getModel() ) : LINEEND_LF;
3750  aText = m_pEditImplementation->GetSelected( eLineEndFormat );
3751  }
3752  return aText;
3753 }
3754 
3755 void SAL_CALL FmXEditCell::setSelection( const css::awt::Selection& aSelection )
3756 {
3757  ::osl::MutexGuard aGuard( m_aMutex );
3758 
3759  if ( m_pEditImplementation )
3760  m_pEditImplementation->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
3761 }
3762 
3763 css::awt::Selection SAL_CALL FmXEditCell::getSelection()
3764 {
3765  ::osl::MutexGuard aGuard( m_aMutex );
3766 
3767  Selection aSel;
3768  if ( m_pEditImplementation )
3770 
3771  return css::awt::Selection(aSel.Min(), aSel.Max());
3772 }
3773 
3775 {
3776  ::osl::MutexGuard aGuard( m_aMutex );
3777 
3779 }
3780 
3781 void SAL_CALL FmXEditCell::setEditable( sal_Bool bEditable )
3782 {
3783  ::osl::MutexGuard aGuard( m_aMutex );
3784 
3785  if ( m_pEditImplementation )
3786  m_pEditImplementation->SetReadOnly( !bEditable );
3787 }
3788 
3789 sal_Int16 SAL_CALL FmXEditCell::getMaxTextLen()
3790 {
3791  ::osl::MutexGuard aGuard( m_aMutex );
3792 
3794 }
3795 
3796 void SAL_CALL FmXEditCell::setMaxTextLen( sal_Int16 nLen )
3797 {
3798  ::osl::MutexGuard aGuard( m_aMutex );
3799 
3800  if ( m_pEditImplementation )
3802 }
3803 
3804 void SAL_CALL FmXEditCell::addChangeListener( const Reference< form::XChangeListener >& Listener )
3805 {
3806  m_aChangeListeners.addInterface( Listener );
3807 }
3808 
3809 void SAL_CALL FmXEditCell::removeChangeListener( const Reference< form::XChangeListener >& Listener )
3810 {
3811  m_aChangeListeners.removeInterface( Listener );
3812 }
3813 
3815 {
3816  css::awt::TextEvent aEvent;
3817  aEvent.Source = *this;
3818  m_aTextListeners.notifyEach( &awt::XTextListener::textChanged, aEvent );
3819 }
3820 
3821 void FmXEditCell::onFocusGained( const awt::FocusEvent& _rEvent )
3822 {
3823  FmXTextCell::onFocusGained( _rEvent );
3825 }
3826 
3827 void FmXEditCell::onFocusLost( const awt::FocusEvent& _rEvent )
3828 {
3829  FmXTextCell::onFocusLost( _rEvent );
3830 
3831  if ( getText() != m_sValueOnEnter )
3832  {
3833  lang::EventObject aEvent( *this );
3834  m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvent );
3835  }
3836 }
3837 
3839 {
3840  if (m_aTextListeners.getLength())
3841  onTextChanged();
3842 }
3843 
3844 FmXCheckBoxCell::FmXCheckBoxCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3845  :FmXDataCell( pColumn, std::move(pControl) )
3846  ,m_aItemListeners(m_aMutex)
3847  ,m_aActionListeners( m_aMutex )
3848  ,m_pBox( & static_cast< CheckBoxControl& >( m_pCellControl->GetWindow() ) )
3849 {
3850  m_pBox->SetAuxModifyHdl(LINK(this, FmXCheckBoxCell, ModifyHdl));
3851 }
3852 
3854 {
3855  if (!OComponentHelper::rBHelper.bDisposed)
3856  {
3857  acquire();
3858  dispose();
3859  }
3860 }
3861 
3862 // OComponentHelper
3864 {
3865  css::lang::EventObject aEvt(*this);
3868 
3870  m_pBox = nullptr;
3871 
3873 }
3874 
3875 
3876 Any SAL_CALL FmXCheckBoxCell::queryAggregation( const css::uno::Type& _rType )
3877 {
3878  Any aReturn = FmXDataCell::queryAggregation( _rType );
3879 
3880  if ( !aReturn.hasValue() )
3881  aReturn = FmXCheckBoxCell_Base::queryInterface( _rType );
3882 
3883  return aReturn;
3884 }
3885 
3886 
3887 Sequence< css::uno::Type > SAL_CALL FmXCheckBoxCell::getTypes( )
3888 {
3889  return ::comphelper::concatSequences(
3892  );
3893 }
3894 
3895 
3897 
3898 void SAL_CALL FmXCheckBoxCell::addItemListener( const Reference< css::awt::XItemListener >& l )
3899 {
3900  m_aItemListeners.addInterface( l );
3901 }
3902 
3903 void SAL_CALL FmXCheckBoxCell::removeItemListener( const Reference< css::awt::XItemListener >& l )
3904 {
3906 }
3907 
3908 void SAL_CALL FmXCheckBoxCell::setState( sal_Int16 n )
3909 {
3910  ::osl::MutexGuard aGuard( m_aMutex );
3911 
3912  if (m_pBox)
3913  {
3914  UpdateFromColumn();
3915  m_pBox->SetState( static_cast<TriState>(n) );
3916  }
3917 }
3918 
3919 sal_Int16 SAL_CALL FmXCheckBoxCell::getState()
3920 {
3921  ::osl::MutexGuard aGuard( m_aMutex );
3922 
3923  if (m_pBox)
3924  {
3925  UpdateFromColumn();
3926  return static_cast<sal_Int16>(m_pBox->GetState());
3927  }
3928  return TRISTATE_INDET;
3929 }
3930 
3932 {
3933  ::osl::MutexGuard aGuard( m_aMutex );
3934 
3935  if (m_pBox)
3936  m_pBox->EnableTriState( b );
3937 }
3938 
3939 void SAL_CALL FmXCheckBoxCell::addActionListener( const Reference< awt::XActionListener >& Listener )
3940 {
3941  m_aActionListeners.addInterface( Listener );
3942 }
3943 
3944 
3945 void SAL_CALL FmXCheckBoxCell::removeActionListener( const Reference< awt::XActionListener >& Listener )
3946 {
3947  m_aActionListeners.removeInterface( Listener );
3948 }
3949 
3950 void SAL_CALL FmXCheckBoxCell::setLabel( const OUString& Label )
3951 {
3952  SolarMutexGuard aGuard;
3953  if ( m_pColumn )
3954  {
3955  DbGridControl& rGrid( m_pColumn->GetParent() );
3956  rGrid.SetColumnTitle( rGrid.GetColumnId( m_pColumn->GetFieldPos() ), Label );
3957  }
3958 }
3959 
3960 void SAL_CALL FmXCheckBoxCell::setActionCommand( const OUString& Command )
3961 {
3962  m_aActionCommand = Command;
3963 }
3964 
3966 {
3967  // check boxes are to be committed immediately (this holds for ordinary check box controls in
3968  // documents, and this must hold for check boxes in grid columns, too
3969  // 91210 - 22.08.2001 - frank.schoenheit@sun.com
3970  m_pCellControl->Commit();
3971 
3972  Reference< XWindow > xKeepAlive( this );
3973  if ( m_aItemListeners.getLength() && m_pBox )
3974  {
3975  awt::ItemEvent aEvent;
3976  aEvent.Source = *this;
3977  aEvent.Highlighted = 0;
3978  aEvent.Selected = m_pBox->GetState();
3979  m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
3980  }
3981  if ( m_aActionListeners.getLength() )
3982  {
3983  awt::ActionEvent aEvent;
3984  aEvent.Source = *this;
3985  aEvent.ActionCommand = m_aActionCommand;
3986  m_aActionListeners.notifyEach( &awt::XActionListener::actionPerformed, aEvent );
3987  }
3988 }
3989 
3990 FmXListBoxCell::FmXListBoxCell(DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl)
3991  : FmXTextCell(pColumn, std::move(pControl))
3992  , m_aItemListeners(m_aMutex)
3993  , m_aActionListeners(m_aMutex)
3994  , m_pBox(&static_cast<svt::ListBoxControl&>(m_pCellControl->GetWindow()))
3995  , m_nLines(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())
3996  , m_bMulti(false)
3997 {
3998  m_pBox->SetAuxModifyHdl(LINK(this, FmXListBoxCell, ChangedHdl));
3999 }
4000 
4002 {
4003  if (!OComponentHelper::rBHelper.bDisposed)
4004  {
4005  acquire();
4006  dispose();
4007  }
4008 }
4009 
4010 // OComponentHelper
4012 {
4013  css::lang::EventObject aEvt(*this);
4016 
4018  m_pBox = nullptr;
4019 
4021 }
4022 
4023 Any SAL_CALL FmXListBoxCell::queryAggregation( const css::uno::Type& _rType )
4024 {
4025  Any aReturn = FmXTextCell::queryAggregation(_rType);
4026 
4027  if ( !aReturn.hasValue() )
4028  aReturn = FmXListBoxCell_Base::queryInterface( _rType );
4029 
4030  return aReturn;
4031 }
4032 
4033 Sequence< css::uno::Type > SAL_CALL FmXListBoxCell::getTypes( )
4034 {
4035  return ::comphelper::concatSequences(
4038  );
4039 }
4040 
4042 
4043 void SAL_CALL FmXListBoxCell::addItemListener(const Reference< css::awt::XItemListener >& l)
4044 {
4045  m_aItemListeners.addInterface( l );
4046 }
4047 
4048 void SAL_CALL FmXListBoxCell::removeItemListener(const Reference< css::awt::XItemListener >& l)
4049 {
4051 }
4052 
4053 void SAL_CALL FmXListBoxCell::addActionListener(const Reference< css::awt::XActionListener >& l)
4054 {
4056 }
4057 
4058 void SAL_CALL FmXListBoxCell::removeActionListener(const Reference< css::awt::XActionListener >& l)
4059 {
4061 }
4062 
4063 void SAL_CALL FmXListBoxCell::addItem(const OUString& aItem, sal_Int16 nPos)
4064 {
4065  ::osl::MutexGuard aGuard( m_aMutex );
4066  if (m_pBox)
4067  {
4068  weld::ComboBox& rBox = m_pBox->get_widget();
4069  rBox.insert_text(nPos, aItem);
4070  }
4071 }
4072 
4073 void SAL_CALL FmXListBoxCell::addItems(const css::uno::Sequence<OUString>& aItems, sal_Int16 nPos)
4074 {
4075  ::osl::MutexGuard aGuard( m_aMutex );
4076  if (m_pBox)
4077  {
4078  weld::ComboBox& rBox = m_pBox->get_widget();
4079  sal_uInt16 nP = nPos;
4080  for ( const auto& rItem : aItems )
4081  {
4082  rBox.insert_text(nP, rItem);
4083  if ( nPos != -1 ) // Not if 0xFFFF, because LIST_APPEND
4084  nP++;
4085  }
4086  }
4087 }
4088 
4089 void SAL_CALL FmXListBoxCell::removeItems(sal_Int16 nPos, sal_Int16 nCount)
4090 {
4091  ::osl::MutexGuard aGuard( m_aMutex );
4092  if ( m_pBox )
4093  {
4094  weld::ComboBox& rBox = m_pBox->get_widget();
4095  for ( sal_uInt16 n = nCount; n; )
4096  rBox.remove( nPos + (--n) );
4097  }
4098 }
4099 
4100 sal_Int16 SAL_CALL FmXListBoxCell::getItemCount()
4101 {
4102  ::osl::MutexGuard aGuard( m_aMutex );
4103  if (!m_pBox)
4104  return 0;
4105  weld::ComboBox& rBox = m_pBox->get_widget();
4106  return rBox.get_count();
4107 }
4108 
4109 OUString SAL_CALL FmXListBoxCell::getItem(sal_Int16 nPos)
4110 {
4111  ::osl::MutexGuard aGuard( m_aMutex );
4112  if (!m_pBox)
4113  return OUString();
4114  weld::ComboBox& rBox = m_pBox->get_widget();
4115  return rBox.get_text(nPos);
4116 }
4117 
4118 css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getItems()
4119 {
4120  ::osl::MutexGuard aGuard( m_aMutex );
4121 
4122  css::uno::Sequence<OUString> aSeq;
4123  if (m_pBox)
4124  {
4125  weld::ComboBox& rBox = m_pBox->get_widget();
4126  const sal_Int32 nEntries = rBox.get_count();
4127  aSeq = css::uno::Sequence<OUString>( nEntries );
4128  for ( sal_Int32 n = nEntries; n; )
4129  {
4130  --n;
4131  aSeq.getArray()[n] = rBox.get_text( n );
4132  }
4133  }
4134  return aSeq;
4135 }
4136 
4138 {
4139  ::osl::MutexGuard aGuard( m_aMutex );
4140  if (m_pBox)
4141  {
4142  UpdateFromColumn();
4143  weld::ComboBox& rBox = m_pBox->get_widget();
4144  sal_Int32 nPos = rBox.get_active();
4145  if (nPos > SHRT_MAX || nPos < SHRT_MIN)
4146  throw std::out_of_range("awt::XListBox::getSelectedItemPos can only return a short");
4147  return nPos;
4148  }
4149  return 0;
4150 }
4151 
4152 Sequence< sal_Int16 > SAL_CALL FmXListBoxCell::getSelectedItemsPos()
4153 {
4154  ::osl::MutexGuard aGuard( m_aMutex );
4155 
4156  if (m_pBox)
4157  {
4158  UpdateFromColumn();
4159  weld::ComboBox& rBox = m_pBox->get_widget();
4160  auto nActive = rBox.get_active();
4161  if (nActive != -1)
4162  {
4163  return { o3tl::narrowing<short>(nActive) };
4164  }
4165  }
4166  return {};
4167 }
4168 
4170 {
4171  ::osl::MutexGuard aGuard( m_aMutex );
4172 
4173  OUString aItem;
4174 
4175  if (m_pBox)
4176  {
4177  UpdateFromColumn();
4178  weld::ComboBox& rBox = m_pBox->get_widget();
4179  aItem = rBox.get_active_text();
4180  }
4181 
4182  return aItem;
4183 }
4184 
4185 css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getSelectedItems()
4186 {
4187  ::osl::MutexGuard aGuard( m_aMutex );
4188 
4189  if (m_pBox)
4190  {
4191  UpdateFromColumn();
4192  weld::ComboBox& rBox = m_pBox->get_widget();
4193  auto nActive = rBox.get_active();
4194  if (nActive != -1)
4195  {
4196  return { rBox.get_text(nActive) };
4197  }
4198  }
4199  return {};
4200 }
4201 
4202 void SAL_CALL FmXListBoxCell::selectItemPos(sal_Int16 nPos, sal_Bool bSelect)
4203 {
4204  ::osl::MutexGuard aGuard( m_aMutex );
4205 
4206  if (m_pBox)
4207  {
4208  weld::ComboBox& rBox = m_pBox->get_widget();
4209  if (bSelect)
4210  rBox.set_active(nPos);
4211  else if (nPos == rBox.get_active())
4212  rBox.set_active(-1);
4213  }
4214 }
4215 
4216 void SAL_CALL FmXListBoxCell::selectItemsPos(const Sequence< sal_Int16 >& aPositions, sal_Bool bSelect)
4217 {
4218  ::osl::MutexGuard aGuard( m_aMutex );
4219 
4220  if (m_pBox)
4221  {
4222  weld::ComboBox& rBox = m_pBox->get_widget();
4223  for ( sal_uInt16 n = static_cast<sal_uInt16>(aPositions.getLength()); n; )
4224  {
4225  auto nPos = static_cast<sal_uInt16>(aPositions.getConstArray()[--n]);
4226  if (bSelect)
4227  rBox.set_active(nPos);
4228  else if (nPos == rBox.get_active())
4229  rBox.set_active(-1);
4230  }
4231  }
4232 }
4233 
4234 void SAL_CALL FmXListBoxCell::selectItem(const OUString& aItem, sal_Bool bSelect)
4235 {
4236  ::osl::MutexGuard aGuard( m_aMutex );
4237 
4238  if (m_pBox)
4239  {
4240  weld::ComboBox& rBox = m_pBox->get_widget();
4241  auto nPos = rBox.find_text(aItem);
4242  if (bSelect)
4243  rBox.set_active(nPos);
4244  else if (nPos == rBox.get_active())
4245  rBox.set_active(-1);
4246  }
4247 }
4248 
4250 {
4251  ::osl::MutexGuard aGuard( m_aMutex );
4252 
4253  return m_bMulti;
4254 }
4255 
4257 {
4258  ::osl::MutexGuard aGuard( m_aMutex );
4259 
4260  m_bMulti = bMulti;
4261 }
4262 
4264 {
4265  ::osl::MutexGuard aGuard( m_aMutex );
4266  return m_nLines;
4267 }
4268 
4269 void SAL_CALL FmXListBoxCell::setDropDownLineCount(sal_Int16 nLines)
4270 {
4271  ::osl::MutexGuard aGuard( m_aMutex );
4272 
4273  m_nLines = nLines; // just store it to return it
4274 }
4275 
4276 void SAL_CALL FmXListBoxCell::makeVisible(sal_Int16 /*nEntry*/)
4277 {
4278 }
4279 
4280 IMPL_LINK(FmXListBoxCell, ChangedHdl, bool, bInteractive, void)
4281 {
4282  if (!m_pBox)
4283  return;
4284 
4285  weld::ComboBox& rBox = m_pBox->get_widget();
4286 
4287  if (bInteractive && !rBox.changed_by_direct_pick())
4288  return;
4289 
4290  OnDoubleClick();
4291 
4292  css::awt::ItemEvent aEvent;
4293  aEvent.Source = *this;
4294  aEvent.Highlighted = 0;
4295 
4296  // with multiple selection 0xFFFF, otherwise the ID
4297  aEvent.Selected = (rBox.get_active() != -1 )
4298  ? rBox.get_active() : 0xFFFF;
4299 
4300  m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4301 }
4302 
4304 {
4306 
4307  css::awt::ActionEvent aEvent;
4308  aEvent.Source = *this;
4309  weld::ComboBox& rBox = m_pBox->get_widget();
4310  aEvent.ActionCommand = rBox.get_active_text();
4311 
4312  while( aIt.hasMoreElements() )
4313  static_cast< css::awt::XActionListener *>(aIt.next())->actionPerformed( aEvent );
4314 }
4315 
4316 FmXComboBoxCell::FmXComboBoxCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
4317  :FmXTextCell( pColumn, std::move(pControl) )
4320  ,m_pComboBox(&static_cast<ComboBoxControl&>(m_pCellControl->GetWindow()))
4321  ,m_nLines(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())
4322 {
4323  m_pComboBox->SetAuxModifyHdl(LINK(this, FmXComboBoxCell, ChangedHdl));
4324 }
4325 
4327 {
4328  if ( !OComponentHelper::rBHelper.bDisposed )
4329  {
4330  acquire();
4331  dispose();
4332  }
4333 
4334 }
4335 
4337 {
4338  css::lang::EventObject aEvt(*this);
4341 
4343  m_pComboBox = nullptr;
4344 
4346 }
4347 
4348 Any SAL_CALL FmXComboBoxCell::queryAggregation( const css::uno::Type& _rType )
4349 {
4350  Any aReturn = FmXTextCell::queryAggregation(_rType);
4351 
4352  if ( !aReturn.hasValue() )
4353  aReturn = FmXComboBoxCell_Base::queryInterface( _rType );
4354 
4355  return aReturn;
4356 }
4357 
4358 Sequence< Type > SAL_CALL FmXComboBoxCell::getTypes( )
4359 {
4360  return ::comphelper::concatSequences(
4363  );
4364 }
4365 
4367 
4368 void SAL_CALL FmXComboBoxCell::addItemListener(const Reference< awt::XItemListener >& l)
4369 {
4370  m_aItemListeners.addInterface( l );
4371 }
4372 
4373 void SAL_CALL FmXComboBoxCell::removeItemListener(const Reference< awt::XItemListener >& l)
4374 {
4376 }
4377 
4378 void SAL_CALL FmXComboBoxCell::addActionListener(const Reference< awt::XActionListener >& l)
4379 {
4381 }
4382 
4383 
4384 void SAL_CALL FmXComboBoxCell::removeActionListener(const Reference< awt::XActionListener >& l)
4385 {
4387 }
4388 
4389 void SAL_CALL FmXComboBoxCell::addItem( const OUString& Item, sal_Int16 Pos )
4390 {
4391  ::osl::MutexGuard aGuard( m_aMutex );
4392  if (!m_pComboBox)
4393  return;
4395  rBox.insert_text(Pos, Item);
4396 }
4397 
4398 void SAL_CALL FmXComboBoxCell::addItems( const Sequence< OUString >& Items, sal_Int16 Pos )
4399 {
4400  ::osl::MutexGuard aGuard( m_aMutex );
4401  if (!m_pComboBox)
4402  return;
4404  sal_uInt16 nP = Pos;
4405  for ( const auto& rItem : Items )
4406  {
4407  rBox.insert_text(nP, rItem);
4408  if ( Pos != -1 )
4409  nP++;
4410  }
4411 }
4412 
4413 void SAL_CALL FmXComboBoxCell::removeItems( sal_Int16 Pos, sal_Int16 Count )
4414 {
4415  ::osl::MutexGuard aGuard( m_aMutex );
4416  if (!m_pComboBox)
4417  return;
4419  for ( sal_uInt16 n = Count; n; )
4420  rBox.remove( Pos + (--n) );
4421 }
4422 
4423 sal_Int16 SAL_CALL FmXComboBoxCell::getItemCount()
4424 {
4425  ::osl::MutexGuard aGuard( m_aMutex );
4426  if (!m_pComboBox)
4427  return 0;
4429  return rBox.get_count();
4430 }
4431 
4432 OUString SAL_CALL FmXComboBoxCell::getItem( sal_Int16 Pos )
4433 {
4434  ::osl::MutexGuard aGuard( m_aMutex );
4435  if (!m_pComboBox)
4436  return OUString();
4438  return rBox.get_text(Pos);
4439 }
4440 
4442 {
4443  ::osl::MutexGuard aGuard( m_aMutex );
4444 
4445  Sequence< OUString > aItems;
4446  if (m_pComboBox)
4447  {
4449  const sal_Int32 nEntries = rBox.get_count();
4450  aItems.realloc( nEntries );
4451  OUString* pItem = aItems.getArray();
4452  for ( sal_Int32 n=0; n<nEntries; ++n, ++pItem )
4453  *pItem = rBox.get_text(n);
4454  }
4455  return aItems;
4456 }
4457 
4459 {
4460  ::osl::MutexGuard aGuard( m_aMutex );
4461  return m_nLines;
4462 }
4463 
4464 void SAL_CALL FmXComboBoxCell::setDropDownLineCount(sal_Int16 nLines)
4465 {
4466  ::osl::MutexGuard aGuard( m_aMutex );
4467  m_nLines = nLines; // just store it to return it
4468 }
4469 
4470 IMPL_LINK(FmXComboBoxCell, ChangedHdl, bool, bInteractive, void)
4471 {
4472  if (!m_pComboBox)
4473  return;
4474 
4475  weld::ComboBox& rComboBox = m_pComboBox->get_widget();
4476 
4477  if (bInteractive && !rComboBox.changed_by_direct_pick())
4478  return;
4479 
4480  awt::ItemEvent aEvent;
4481  aEvent.Source = *this;
4482  aEvent.Highlighted = 0;
4483 
4484  // with invalid selection 0xFFFF, otherwise the position
4485  aEvent.Selected = ( rComboBox.get_active() != -1 )
4486  ? rComboBox.get_active()
4487  : 0xFFFF;
4488  m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4489 }
4490 
4491 FmXFilterCell::FmXFilterCell(DbGridColumn* pColumn, std::unique_ptr<DbFilterField> pControl )
4492  :FmXGridCell( pColumn, std::move(pControl) )
4493  ,m_aTextListeners(m_aMutex)
4494 {
4495  static_cast<DbFilterField*>(m_pCellControl.get())->SetCommitHdl( LINK( this, FmXFilterCell, OnCommit ) );
4496 }
4497 
4499 {
4500  if (!OComponentHelper::rBHelper.bDisposed)
4501  {
4502  acquire();
4503  dispose();
4504  }
4505 
4506 }
4507 
4508 // XUnoTunnel
4509 sal_Int64 SAL_CALL FmXFilterCell::getSomething( const Sequence< sal_Int8 >& _rIdentifier )
4510 {
4511  return comphelper::getSomethingImpl(_rIdentifier, this);
4512 }
4513 
4514 const Sequence<sal_Int8>& FmXFilterCell::getUnoTunnelId()
4515 {
4516  static const comphelper::UnoIdInit theFmXFilterCellUnoTunnelId;
4517  return theFmXFilterCellUnoTunnelId.getSeq();
4518 }
4519 
4520 
4522 {
4523  static_cast< DbFilterField* >( m_pCellControl.get() )->PaintCell( rDev, rRect );
4524 }
4525 
4526 // OComponentHelper
4527 
4529 {
4530  css::lang::EventObject aEvt(*this);
4532 
4533  static_cast<DbFilterField*>(m_pCellControl.get())->SetCommitHdl(Link<DbFilterField&,void>());
4534 
4536 }
4537 
4538 
4539 Any SAL_CALL FmXFilterCell::queryAggregation( const css::uno::Type& _rType )
4540 {
4541  Any aReturn = FmXGridCell::queryAggregation(_rType);
4542 
4543  if ( !aReturn.hasValue() )
4544  aReturn = FmXFilterCell_Base::queryInterface( _rType );
4545 
4546  return aReturn;
4547 }
4548 
4549 
4550 Sequence< css::uno::Type > SAL_CALL FmXFilterCell::getTypes( )
4551 {
4552  return ::comphelper::concatSequences(
4555  );
4556 }
4557 
4558 
4560 
4561 // css::awt::XTextComponent
4562 
4563 void SAL_CALL FmXFilterCell::addTextListener(const Reference< css::awt::XTextListener >& l)
4564 {
4565  m_aTextListeners.addInterface( l );
4566 }
4567 
4568 
4569 void SAL_CALL FmXFilterCell::removeTextListener(const Reference< css::awt::XTextListener >& l)
4570 {
4572 }
4573 
4574 void SAL_CALL FmXFilterCell::setText( const OUString& aText )
4575 {
4576  ::osl::MutexGuard aGuard( m_aMutex );
4577  static_cast<DbFilterField*>(m_pCellControl.get())->SetText(aText);
4578 }
4579 
4580 void SAL_CALL FmXFilterCell::insertText( const css::awt::Selection& /*rSel*/, const OUString& /*aText*/ )
4581 {
4582 }
4583 
4584 OUString SAL_CALL FmXFilterCell::getText()
4585 {
4586  ::osl::MutexGuard aGuard( m_aMutex );
4587  return static_cast<DbFilterField*>(m_pCellControl.get())->GetText();
4588 }
4589 
4591 {
4592  return getText();
4593 }
4594 
4595 void SAL_CALL FmXFilterCell::setSelection( const css::awt::Selection& /*aSelection*/ )
4596 {
4597 }
4598 
4599 css::awt::Selection SAL_CALL FmXFilterCell::getSelection()
4600 {
4601  return css::awt::Selection();
4602 }
4603 
4605 {
4606  return true;
4607 }
4608 
4609 void SAL_CALL FmXFilterCell::setEditable( sal_Bool /*bEditable*/ )
4610 {
4611 }
4612 
4613 sal_Int16 SAL_CALL FmXFilterCell::getMaxTextLen()
4614 {
4615  return 0;
4616 }
4617 
4618 void SAL_CALL FmXFilterCell::setMaxTextLen( sal_Int16 /*nLen*/ )
4619 {
4620 }
4621 
4623 {
4624  ::comphelper::OInterfaceIteratorHelper2 aIt( m_aTextListeners );
4625  css::awt::TextEvent aEvt;
4626  aEvt.Source = *this;
4627  while( aIt.hasMoreElements() )
4628  static_cast< css::awt::XTextListener *>(aIt.next())->textChanged( aEvt );
4629 }
4630 
4631 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
tools::Long Max() const
virtual void SAL_CALL addItems(const css::uno::Sequence< OUString > &Items,::sal_Int16 Pos) override
Definition: gridcell.cxx:4398
void SetFormatKey(sal_uLong nFormatKey)
bool is() const
const css::uno::Reference< css::beans::XPropertySet > & getModel() const
Definition: gridcell.hxx:122
#define FM_PROP_DATEMIN
Definition: fmprop.hxx:83
const Color & GetTextColor() const
void OnDoubleClick()
Definition: gridcell.cxx:4303
OutDevType GetOutDevType() const
bool IsControlBackground() const
virtual sal_Int16 SAL_CALL getState() override
Definition: gridcell.cxx:3919
::osl::Mutex m_aMutex
Definition: gridcell.hxx:695
virtual OUString GetFormatText(const css::uno::Reference< css::sdb::XColumn > &_rxField, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter, const Color **ppColor=nullptr) override
Definition: gridcell.cxx:2306
void implValuePropertyChanged()
Definition: gridcell.cxx:618
OString stripEnd(std::string_view rIn, char c)
bool m_bNumeric
Definition: gridcell.hxx:93
#define FM_PROP_READONLY
Definition: fmprop.hxx:46
virtual void SAL_CALL removeMouseListener(const css::uno::Reference< css::awt::XMouseListener > &xListener) override
Definition: gridcell.cxx:3415
void ImplInitWindow(vcl::Window const &rParent, const InitWindowFacet _eInitWhat)
Definition: gridcell.cxx:696
virtual ::svt::CellControllerRef CreateController() const override
Definition: gridcell.cxx:2870
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
virtual VclPtr< svt::ControlBase > createField(BrowserDataWin *_pParent, bool bSpinButton, const css::uno::Reference< css::beans::XPropertySet > &_rxModel) override
Definition: gridcell.cxx:2354
void SetState(TriState eState)
virtual void SAL_CALL enableTriState(sal_Bool b) override
Definition: gridcell.cxx:3931
bool m_bObject
Definition: gridcell.hxx:94
virtual void Init(BrowserDataWin &rParent, const css::uno::Reference< css::sdbc::XRowSet > &xCursor) override
Definition: gridcell.cxx:1853
virtual void SAL_CALL addActionListener(const css::uno::Reference< css::awt::XActionListener > &l) override
Definition: gridcell.cxx:3939
virtual void UpdateFromField(const css::uno::Reference< css::sdb::XColumn > &_rxField, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter) override
Definition: gridcell.cxx:1676
void SetFontSize(const Size &)
virtual OUString GetFormatText(const css::uno::Reference< css::sdb::XColumn > &_rxField, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter, const Color **ppColor=nullptr) override
Definition: gridcell.cxx:2056
virtual void updateFromModel(css::uno::Reference< css::beans::XPropertySet > _rxModel)=0
updates the current content of the control (e.g.
virtual css::uno::Reference< css::awt::XControlModel > SAL_CALL getModel() override
Definition: gridcell.cxx:3303
#define FM_PROP_DECIMAL_ACCURACY
Definition: fmprop.hxx:72
virtual void SetMinValue(double dMin) override
virtual bool commitControl() override
commits the content of the control (e.g.
Definition: gridcell.cxx:1190
DbCurrencyField(DbGridColumn &_rColumn)
Definition: gridcell.cxx:2098
std::unique_ptr<::svt::IEditImplementation > m_pEdit
Definition: gridcell.hxx:381
virtual void SAL_CALL setSelection(const css::awt::Selection &aSelection) override
Definition: gridcell.cxx:3755
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: gridcell.cxx:3672
virtual void SAL_CALL acquire() SAL_NOEXCEPT SAL_OVERRIDE
#define FM_PROP_FIELDSOURCE
Definition: fmprop.hxx:108
FmXFilterCell(DbGridColumn *pColumn, std::unique_ptr< DbFilterField > pControl)
Definition: gridcell.cxx:4491
FmXTextCell(DbGridColumn *pColumn, std::unique_ptr< DbCellControl > pControl)
Definition: gridcell.cxx:3563
void PaintCell(OutputDevice &rDev, const tools::Rectangle &rRect)
Definition: gridcell.cxx:4521
#define FM_PROP_FORMATSSUPPLIER
Definition: fmprop.hxx:66
bool m_bIsMultiLineText
Definition: gridcell.hxx:819
void SetCurrencySymbol(const OUString &rStr)
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
DbComboBox(DbGridColumn &_rColumn)
Definition: gridcell.cxx:2457
DECL_LISTENERMULTIPLEXER_END void SAL_CALL textChanged(const css::awt::TextEvent &rEvent) override
DbGridColumn * m_pColumn
Definition: gridcell.hxx:696
void setWidth(tools::Long nWidth)
void SetFocusInHdl(const Link< LinkParamNone *, void > &rHdl)
void SetStrictFormat(bool bStrict)
svt::ControlBase * getEventWindow() const
Definition: gridcell.cxx:3217
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() SAL_OVERRIDE
::comphelper::OInterfaceContainerHelper2 m_aFocusListeners
Definition: gridcell.hxx:701
#define FM_PROP_FIELDTYPE
Definition: fmprop.hxx:75
virtual OUString GetFormatText(const css::uno::Reference< css::sdb::XColumn > &_rxField, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter, const Color **ppColor=nullptr)=0
OUTDEV_VIRDEV
virtual void Init(BrowserDataWin &rParent, const css::uno::Reference< css::sdbc::XRowSet > &xCursor) override
Definition: gridcell.cxx:1226
a field which is bound to a column which supports the MaxTextLen property
Definition: gridcell.hxx:359
virtual ::svt::CellControllerRef CreateController() const override
Definition: gridcell.cxx:1132
virtual void implSetEffectiveMaxTextLen(sal_Int32 _nMaxLen) override
Definition: gridcell.cxx:1207