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