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