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