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 
2449  OUString sOldActive = rComboBox.get_active_text();
2450  rComboBox.set_entry_text(sText);
2451  rComboBox.select_entry_region(0, -1);
2452 
2453  if (sOldActive != rComboBox.get_active_text())
2454  pControl->TriggerAuxModify();
2455 }
2456 
2458 {
2459  ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2460  weld::ComboBox& rComboBox = pControl->get_widget();
2461  OUString aText(rComboBox.get_active_text());
2462  m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, makeAny(aText));
2463  return true;
2464 }
2465 
2466 
2468  :DbCellControl(_rColumn)
2469  ,m_bBound(false)
2470 {
2471  setAlignedController( false );
2472 
2475 }
2476 
2477 void DbListBox::_propertyChanged( const css::beans::PropertyChangeEvent& _rEvent )
2478 {
2479  if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
2480  {
2481  SetList(_rEvent.NewValue);
2482  }
2483  else
2484  {
2485  DbCellControl::_propertyChanged( _rEvent ) ;
2486  }
2487 }
2488 
2489 void DbListBox::SetList(const Any& rItems)
2490 {
2491  ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2492 
2493  weld::ComboBox& rFieldList = pField->get_widget();
2494 
2495  rFieldList.clear();
2496  m_bBound = false;
2497 
2498  css::uno::Sequence<OUString> aTest;
2499  if (!(rItems >>= aTest))
2500  return;
2501 
2502  if (aTest.hasElements())
2503  {
2504  for (const OUString& rString : std::as_const(aTest))
2505  rFieldList.append_text(rString);
2506 
2507  m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2508  m_bBound = m_aValueList.hasElements();
2509 
2510  // tell the grid control that this controller is invalid and has to be re-initialized
2512  }
2513 }
2514 
2515 void DbListBox::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
2516 {
2517  m_rColumn.SetAlignment(css::awt::TextAlign::LEFT);
2518 
2520 
2521  // some initial properties
2523  SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2525 
2526  DbCellControl::Init( rParent, xCursor );
2527 }
2528 
2530 {
2531  // ignore FM_PROP_LINECOUNT
2532 }
2533 
2535 {
2536  return new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2537 }
2538 
2539 OUString DbListBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
2540 {
2541  OUString sText;
2542  if ( _rxField.is() )
2543  {
2544  try
2545  {
2546  sText = _rxField->getString();
2547  if ( m_bBound )
2548  {
2549  sal_Int32 nPos = ::comphelper::findValue( m_aValueList, sText );
2550  if ( nPos != -1 )
2551  sText = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget().get_text(nPos);
2552  else
2553  sText.clear();
2554  }
2555  }
2556  catch( const Exception& )
2557  {
2558  DBG_UNHANDLED_EXCEPTION("svx");
2559  }
2560  }
2561  return sText;
2562 }
2563 
2564 void DbListBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2565 {
2566  OUString sFormattedText( GetFormatText( _rxField, xFormatter ) );
2567  weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2568  if (!sFormattedText.isEmpty())
2569  rComboBox.set_active_text(sFormattedText);
2570  else
2571  rComboBox.set_active(-1);
2572 }
2573 
2575 {
2576  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbListBox::updateFromModel: invalid call!" );
2577 
2578  Sequence< sal_Int16 > aSelection;
2579  _rxModel->getPropertyValue( FM_PROP_SELECT_SEQ ) >>= aSelection;
2580 
2581  sal_Int16 nSelection = -1;
2582  if ( aSelection.hasElements() )
2583  nSelection = aSelection[ 0 ];
2584 
2585  ListBoxControl* pControl = static_cast<ListBoxControl*>(m_pWindow.get());
2586  weld::ComboBox& rComboBox = pControl->get_widget();
2587 
2588  int nOldActive = rComboBox.get_active();
2589  if (nSelection >= 0 && nSelection < rComboBox.get_count())
2590  rComboBox.set_active(nSelection);
2591  else
2592  rComboBox.set_active(-1);
2593 
2594  if (nOldActive != rComboBox.get_active())
2595  pControl->TriggerAuxModify();
2596 }
2597 
2599 {
2600  Any aVal;
2601  Sequence<sal_Int16> aSelectSeq;
2602  weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2603  auto nActive = rComboBox.get_active();
2604  if (nActive != -1)
2605  {
2606  aSelectSeq.realloc(1);
2607  *aSelectSeq.getArray() = static_cast<sal_Int16>(nActive);
2608  }
2609  aVal <<= aSelectSeq;
2610  m_rColumn.getModel()->setPropertyValue(FM_PROP_SELECT_SEQ, aVal);
2611  return true;
2612 }
2613 
2615  :DbCellControl(_rColumn)
2616  ,OSQLParserClient(rxContext)
2617  ,m_nControlClass(css::form::FormComponentType::TEXTFIELD)
2618  ,m_bFilterList(false)
2619  ,m_bFilterListFilled(false)
2620 {
2621 
2622  setAlignedController( false );
2623 }
2624 
2626 {
2627  if (m_nControlClass == css::form::FormComponentType::CHECKBOX)
2628  static_cast<CheckBoxControl*>(m_pWindow.get())->SetClickHdl( Link<weld::Button&,void>() );
2629 
2630 }
2631 
2633 {
2634  static const DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter | DrawTextFlags::Left;
2635  switch (m_nControlClass)
2636  {
2637  case FormComponentType::CHECKBOX:
2638  {
2639  // center the checkbox within the space available
2640  CheckBoxControl* pControl = static_cast<CheckBoxControl*>(m_pPainter.get());
2641  Size aBoxSize = pControl->GetBox().get_preferred_size();
2642  tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
2643  rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
2644  aBoxSize);
2645 
2646  DbCellControl::PaintCell(rDev, aRect);
2647  break;
2648  }
2649  case FormComponentType::LISTBOX:
2650  rDev.DrawText(rRect, static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().get_active_text(), nStyle);
2651  break;
2652  default:
2653  rDev.DrawText(rRect, m_aText, nStyle);
2654  }
2655 }
2656 
2657 void DbFilterField::SetList(const Any& rItems, bool bComboBox)
2658 {
2659  css::uno::Sequence<OUString> aTest;
2660  rItems >>= aTest;
2661  if (!aTest.hasElements())
2662  return;
2663 
2664  if (bComboBox)
2665  {
2666  ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
2667  weld::ComboBox& rComboBox = pField->get_widget();
2668  for (const OUString& rString : std::as_const(aTest))
2669  rComboBox.append_text(rString);
2670  }
2671  else
2672  {
2673  ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2674  weld::ComboBox& rFieldBox = pField->get_widget();
2675  for (const OUString& rString : std::as_const(aTest))
2676  rFieldBox.append_text(rString);
2677 
2678  m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2679  }
2680 }
2681 
2682 void DbFilterField::CreateControl(BrowserDataWin* pParent, const Reference< css::beans::XPropertySet >& xModel)
2683 {
2684  switch (m_nControlClass)
2685  {
2686  case css::form::FormComponentType::CHECKBOX:
2688  m_pWindow->SetPaintTransparent( true );
2689  static_cast<CheckBoxControl*>(m_pWindow.get())->SetClickHdl( LINK( this, DbFilterField, OnClick ) );
2690 
2694  break;
2695  case css::form::FormComponentType::LISTBOX:
2696  {
2698  Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2699  SetList(aItems, false);
2700  } break;
2701  case css::form::FormComponentType::COMBOBOX:
2702  {
2704 
2705  AllSettings aSettings = m_pWindow->GetSettings();
2706  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2707  aStyleSettings.SetSelectionOptions(
2708  aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2709  aSettings.SetStyleSettings(aStyleSettings);
2710  m_pWindow->SetSettings(aSettings, true);
2711 
2712  if (!m_bFilterList)
2713  {
2714  Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2715  SetList(aItems, true);
2716  }
2717 
2718  } break;
2719  default:
2720  {
2722  AllSettings aSettings = m_pWindow->GetSettings();
2723  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2724  aStyleSettings.SetSelectionOptions(
2725  aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2726  aSettings.SetStyleSettings(aStyleSettings);
2727  m_pWindow->SetSettings(aSettings, true);
2728  }
2729  }
2730 }
2731 
2732 void DbFilterField::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
2733 {
2734  Reference< css::beans::XPropertySet > xModel(m_rColumn.getModel());
2735  m_rColumn.SetAlignment(css::awt::TextAlign::LEFT);
2736 
2737  if (xModel.is())
2738  {
2739  m_bFilterList = ::comphelper::hasProperty(FM_PROP_FILTERPROPOSAL, xModel) && ::comphelper::getBOOL(xModel->getPropertyValue(FM_PROP_FILTERPROPOSAL));
2740  if (m_bFilterList)
2741  m_nControlClass = css::form::FormComponentType::COMBOBOX;
2742  else
2743  {
2744  sal_Int16 nClassId = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_CLASSID));
2745  switch (nClassId)
2746  {
2747  case FormComponentType::CHECKBOX:
2748  case FormComponentType::LISTBOX:
2749  case FormComponentType::COMBOBOX:
2750  m_nControlClass = nClassId;
2751  break;
2752  default:
2753  if (m_bFilterList)
2754  m_nControlClass = FormComponentType::COMBOBOX;
2755  else
2756  m_nControlClass = FormComponentType::TEXTFIELD;
2757  }
2758  }
2759  }
2760 
2761  CreateControl( &rParent, xModel );
2762  DbCellControl::Init( rParent, xCursor );
2763 
2764  // filter cells are never readonly
2765  ControlBase* pAsEdit = dynamic_cast<ControlBase*>(m_pWindow.get());
2766  if (pAsEdit)
2767  pAsEdit->SetEditableReadOnly(false);
2768 }
2769 
2771 {
2773  switch (m_nControlClass)
2774  {
2775  case css::form::FormComponentType::CHECKBOX:
2776  xController = new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
2777  break;
2778  case css::form::FormComponentType::LISTBOX:
2779  xController = new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2780  break;
2781  case css::form::FormComponentType::COMBOBOX:
2782  xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2783  break;
2784  default:
2785  if (m_bFilterList)
2786  xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2787  else
2788  xController = new EditCellController(static_cast<EditControlBase*>(m_pWindow.get()));
2789  }
2790  return xController;
2791 }
2792 
2794 {
2795  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFilterField::updateFromModel: invalid call!" );
2796 
2797  OSL_FAIL( "DbFilterField::updateFromModel: not implemented yet (how the hell did you reach this?)!" );
2798  // TODO: implement this.
2799  // remember: updateFromModel should be some kind of opposite of commitControl
2800 }
2801 
2803 {
2804  OUString aText(m_aText);
2805  switch (m_nControlClass)
2806  {
2807  case css::form::FormComponentType::CHECKBOX:
2808  return true;
2809  case css::form::FormComponentType::LISTBOX:
2810  {
2811  aText.clear();
2812  weld::ComboBox& rComboBox = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget();
2813  auto nActive = rComboBox.get_active();
2814  if (nActive != -1)
2815  {
2816  sal_Int16 nPos = static_cast<sal_Int16>(nActive);
2817  if ( ( nPos >= 0 ) && ( nPos < m_aValueList.getLength() ) )
2818  aText = m_aValueList.getConstArray()[nPos];
2819  }
2820 
2821  if (m_aText != aText)
2822  {
2823  m_aText = aText;
2824  m_aCommitLink.Call(*this);
2825  }
2826  return true;
2827  }
2828  case css::form::FormComponentType::COMBOBOX:
2829  {
2830  aText = static_cast<ComboBoxControl*>(m_pWindow.get())->get_widget().get_active_text();
2831  break;
2832  }
2833  default:
2834  {
2835  aText = static_cast<EditControlBase*>(m_pWindow.get())->get_widget().get_text();
2836  break;
2837  }
2838  }
2839 
2840  if (m_aText != aText)
2841  {
2842  // check the text with the SQL-Parser
2843  OUString aNewText(comphelper::string::stripEnd(aText, ' '));
2844  if (!aNewText.isEmpty())
2845  {
2846  OUString aErrorMsg;
2848 
2849  std::unique_ptr< OSQLParseNode > pParseNode = predicateTree(aErrorMsg, aNewText,xNumberFormatter, m_rColumn.GetField());
2850  if (pParseNode != nullptr)
2851  {
2852  OUString aPreparedText;
2853 
2854  css::lang::Locale aAppLocale = Application::GetSettings().GetUILanguageTag().getLocale();
2855 
2856  Reference< XRowSet > xDataSourceRowSet(
2857  Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY);
2858  Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
2859 
2860  pParseNode->parseNodeToPredicateStr(aPreparedText,
2861  xConnection,
2862  xNumberFormatter,
2863  m_rColumn.GetField(),
2864  OUString(),
2865  aAppLocale,
2866  OUString("."),
2867  getParseContext());
2868  m_aText = aPreparedText;
2869  }
2870  else
2871  {
2872 
2873  SQLException aError;
2874  aError.Message = aErrorMsg;
2876  // TODO: transport the title
2877 
2878  return false;
2879  }
2880  }
2881  else
2882  m_aText = aText;
2883 
2885  m_aCommitLink.Call(*this);
2886  }
2887  return true;
2888 }
2889 
2890 
2891 void DbFilterField::SetText(const OUString& rText)
2892 {
2893  m_aText = rText;
2894  switch (m_nControlClass)
2895  {
2896  case css::form::FormComponentType::CHECKBOX:
2897  {
2898  TriState eState;
2899  if (rText == "1")
2900  eState = TRISTATE_TRUE;
2901  else if (rText == "0")
2902  eState = TRISTATE_FALSE;
2903  else
2904  eState = TRISTATE_INDET;
2905 
2906  static_cast<CheckBoxControl*>(m_pWindow.get())->SetState(eState);
2907  static_cast<CheckBoxControl*>(m_pPainter.get())->SetState(eState);
2908  } break;
2909  case css::form::FormComponentType::LISTBOX:
2910  {
2911  sal_Int32 nPos = ::comphelper::findValue(m_aValueList, m_aText);
2912  static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().set_active(nPos);
2913  } break;
2914  case css::form::FormComponentType::COMBOBOX:
2915  {
2916  static_cast<ComboBoxControl*>(m_pWindow.get())->get_widget().set_entry_text(m_aText);
2917  break;
2918  }
2919  default:
2920  {
2921  static_cast<EditControlBase*>(m_pWindow.get())->get_widget().set_text(m_aText);
2922  break;
2923  }
2924  }
2925 
2926  // now force a repaint on the window
2928 }
2929 
2930 
2932 {
2933  // should we fill the combobox with a filter proposal?
2935  return;
2936 
2937  m_bFilterListFilled = true;
2938  Reference< css::beans::XPropertySet > xField = m_rColumn.GetField();
2939  if (!xField.is())
2940  return;
2941 
2942  OUString aName;
2943  xField->getPropertyValue(FM_PROP_NAME) >>= aName;
2944 
2945  // the columnmodel
2946  Reference< css::container::XChild > xModelAsChild(m_rColumn.getModel(), UNO_QUERY);
2947  // the grid model
2948  xModelAsChild.set(xModelAsChild->getParent(),UNO_QUERY);
2949  Reference< XRowSet > xForm(xModelAsChild->getParent(), UNO_QUERY);
2950  if (!xForm.is())
2951  return;
2952 
2953  Reference<XPropertySet> xFormProp(xForm,UNO_QUERY);
2954  Reference< XTablesSupplier > xSupTab;
2955  xFormProp->getPropertyValue("SingleSelectQueryComposer") >>= xSupTab;
2956 
2957  Reference< XConnection > xConnection(getConnection(xForm));
2958  if (!xSupTab.is())
2959  return;
2960 
2961  // search the field
2962  Reference< XColumnsSupplier > xSupCol(xSupTab,UNO_QUERY);
2963  Reference< css::container::XNameAccess > xFieldNames = xSupCol->getColumns();
2964  if (!xFieldNames->hasByName(aName))
2965  return;
2966 
2967  Reference< css::container::XNameAccess > xTablesNames = xSupTab->getTables();
2968  Reference< css::beans::XPropertySet > xComposerFieldAsSet(xFieldNames->getByName(aName),UNO_QUERY);
2969 
2970  if (!xComposerFieldAsSet.is() ||
2971  !::comphelper::hasProperty(FM_PROP_TABLENAME, xComposerFieldAsSet) ||
2972  !::comphelper::hasProperty(FM_PROP_FIELDSOURCE, xComposerFieldAsSet))
2973  return;
2974 
2975  OUString aFieldName;
2976  OUString aTableName;
2977  xComposerFieldAsSet->getPropertyValue(FM_PROP_FIELDSOURCE) >>= aFieldName;
2978  xComposerFieldAsSet->getPropertyValue(FM_PROP_TABLENAME) >>= aTableName;
2979 
2980  // no possibility to create a select statement
2981  // looking for the complete table name
2982  if (!xTablesNames->hasByName(aTableName))
2983  return;
2984 
2985  // build a statement and send as query;
2986  // Access to the connection
2987  Reference< XStatement > xStatement;
2988  Reference< XResultSet > xListCursor;
2989  Reference< css::sdb::XColumn > xDataField;
2990 
2991  try
2992  {
2993  Reference< XDatabaseMetaData > xMeta = xConnection->getMetaData();
2994 
2995  OUString aQuote(xMeta->getIdentifierQuoteString());
2996  OUStringBuffer aStatement("SELECT DISTINCT ");
2997  aStatement.append(quoteName(aQuote, aName));
2998  if (!aFieldName.isEmpty() && aName != aFieldName)
2999  {
3000  aStatement.append(" AS ");
3001  aStatement.append(quoteName(aQuote, aFieldName));
3002  }
3003 
3004  aStatement.append(" FROM ");
3005 
3006  Reference< XPropertySet > xTableNameAccess(xTablesNames->getByName(aTableName), UNO_QUERY_THROW);
3007  aStatement.append(composeTableNameForSelect(xConnection, xTableNameAccess));
3008 
3009  xStatement = xConnection->createStatement();
3010  Reference< css::beans::XPropertySet > xStatementProps(xStatement, UNO_QUERY);
3011  xStatementProps->setPropertyValue(FM_PROP_ESCAPE_PROCESSING, makeAny(true));
3012 
3013  xListCursor = xStatement->executeQuery(aStatement.makeStringAndClear());
3014 
3015  Reference< css::sdbcx::XColumnsSupplier > xSupplyCols(xListCursor, UNO_QUERY);
3016  Reference< css::container::XIndexAccess > xFields(xSupplyCols->getColumns(), UNO_QUERY);
3017  xDataField.set(xFields->getByIndex(0), css::uno::UNO_QUERY);
3018  if (!xDataField.is())
3019  return;
3020  }
3021  catch(const Exception&)
3022  {
3023  ::comphelper::disposeComponent(xStatement);
3024  return;
3025  }
3026 
3027  sal_Int16 i = 0;
3028  ::std::vector< OUString > aStringList;
3029  aStringList.reserve(16);
3030  OUString aStr;
3031  css::util::Date aNullDate = m_rColumn.GetParent().getNullDate();
3032  sal_Int32 nFormatKey = m_rColumn.GetKey();
3034  sal_Int16 nKeyType = ::comphelper::getNumberFormatType(xFormatter->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey);
3035 
3036  while (!xListCursor->isAfterLast() && i++ < SHRT_MAX) // max number of entries
3037  {
3038  aStr = getFormattedValue(xDataField, xFormatter, aNullDate, nFormatKey, nKeyType);
3039  aStringList.push_back(aStr);
3040  (void)xListCursor->next();
3041  }
3042 
3043  ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
3044  weld::ComboBox& rComboBox = pField->get_widget();
3045  // filling the entries for the combobox
3046  for (const auto& rString : aStringList)
3047  rComboBox.append_text(rString);
3048 }
3049 
3050 OUString DbFilterField::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
3051 {
3052  return OUString();
3053 }
3054 
3055 void DbFilterField::UpdateFromField(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/)
3056 {
3057  OSL_FAIL( "DbFilterField::UpdateFromField: cannot update a filter control from a field!" );
3058 }
3059 
3061 {
3062  TriState eState = static_cast<CheckBoxControl*>(m_pWindow.get())->GetState();
3063  OUStringBuffer aTextBuf;
3064 
3065  Reference< XRowSet > xDataSourceRowSet(
3066  Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY);
3067  Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
3068  const sal_Int32 nBooleanComparisonMode = ::dbtools::DatabaseMetaData( xConnection ).getBooleanComparisonMode();
3069 
3070  switch (eState)
3071  {
3072  case TRISTATE_TRUE:
3073  ::dbtools::getBooleanComparisonPredicate(u"", true, nBooleanComparisonMode, aTextBuf);
3074  break;
3075  case TRISTATE_FALSE:
3076  ::dbtools::getBooleanComparisonPredicate(u"", false, nBooleanComparisonMode, aTextBuf);
3077  break;
3078  case TRISTATE_INDET:
3079  break;
3080  }
3081 
3082  const OUString aText(aTextBuf.makeStringAndClear());
3083 
3084  if (m_aText != aText)
3085  {
3086  m_aText = aText;
3087  m_aCommitLink.Call(*this);
3088  }
3089 }
3090 
3091 
3092 FmXGridCell::FmXGridCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> _pControl )
3093  :OComponentHelper(m_aMutex)
3094  ,m_pColumn(pColumn)
3095  ,m_pCellControl( std::move(_pControl) )
3096  ,m_aWindowListeners( m_aMutex )
3097  ,m_aFocusListeners( m_aMutex )
3098  ,m_aKeyListeners( m_aMutex )
3099  ,m_aMouseListeners( m_aMutex )
3100  ,m_aMouseMotionListeners( m_aMutex )
3101 {
3102 }
3103 
3104 
3106 {
3107  vcl::Window* pEventWindow( getEventWindow() );
3108  if ( pEventWindow )
3109  pEventWindow->AddEventListener( LINK( this, FmXGridCell, OnWindowEvent ) );
3110 }
3111 
3112 
3114 {
3115  if ( m_pCellControl )
3116  return &m_pCellControl->GetWindow();
3117  return nullptr;
3118 }
3119 
3120 
3122 {
3123  if (!OComponentHelper::rBHelper.bDisposed)
3124  {
3125  acquire();
3126  dispose();
3127  }
3128 
3129 }
3130 
3131 
3133 {
3134  if (m_pCellControl)
3135  m_pCellControl->SetTextLineColor();
3136 }
3137 
3138 
3140 {
3141  if (m_pCellControl)
3142  m_pCellControl->SetTextLineColor(_rColor);
3143 }
3144 
3145 // XTypeProvider
3146 
3147 Sequence< Type > SAL_CALL FmXGridCell::getTypes( )
3148 {
3149  Sequence< uno::Type > aTypes = ::comphelper::concatSequences(
3152  );
3153  if ( m_pCellControl )
3154  aTypes = ::comphelper::concatSequences(
3155  aTypes,
3157  );
3158  return aTypes;
3159 }
3160 
3161 
3163 
3164 // OComponentHelper
3165 
3166 void FmXGridCell::disposing()
3167 {
3168  lang::EventObject aEvent( *this );
3169  m_aWindowListeners.disposeAndClear( aEvent );
3170  m_aFocusListeners.disposeAndClear( aEvent );
3171  m_aKeyListeners.disposeAndClear( aEvent );
3172  m_aMouseListeners.disposeAndClear( aEvent );
3173  m_aMouseMotionListeners.disposeAndClear( aEvent );
3174 
3175  OComponentHelper::disposing();
3176  m_pColumn = nullptr;
3177  m_pCellControl.reset();
3178 }
3179 
3180 
3181 Any SAL_CALL FmXGridCell::queryAggregation( const css::uno::Type& _rType )
3182 {
3183  Any aReturn = OComponentHelper::queryAggregation( _rType );
3184 
3185  if ( !aReturn.hasValue() )
3186  aReturn = FmXGridCell_Base::queryInterface( _rType );
3187 
3188  if ( !aReturn.hasValue() && ( m_pCellControl != nullptr ) )
3189  aReturn = FmXGridCell_WindowBase::queryInterface( _rType );
3190 
3191  return aReturn;
3192 }
3193 
3194 // css::awt::XControl
3195 
3196 Reference< XInterface > FmXGridCell::getContext()
3197 {
3198  return Reference< XInterface > ();
3199 }
3200 
3201 
3202 Reference< css::awt::XControlModel > FmXGridCell::getModel()
3203 {
3204  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3205  return Reference< css::awt::XControlModel > (m_pColumn->getModel(), UNO_QUERY);
3206 }
3207 
3208 // css::form::XBoundControl
3209 
3211 {
3212  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3213  return m_pColumn->isLocked();
3214 }
3215 
3216 
3218 {
3219  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3220  if (getLock() == _bLock)
3221  return;
3222  else
3223  {
3224  ::osl::MutexGuard aGuard(m_aMutex);
3225  m_pColumn->setLock(_bLock);
3226  }
3227 }
3228 
3229 
3230 void SAL_CALL FmXGridCell::setPosSize( ::sal_Int32, ::sal_Int32, ::sal_Int32, ::sal_Int32, ::sal_Int16 )
3231 {
3232  OSL_FAIL( "FmXGridCell::setPosSize: not implemented" );
3233  // not allowed to tamper with this for a grid cell
3234 }
3235 
3236 
3237 awt::Rectangle SAL_CALL FmXGridCell::getPosSize( )
3238 {
3239  OSL_FAIL( "FmXGridCell::getPosSize: not implemented" );
3240  return awt::Rectangle();
3241 }
3242 
3243 
3245 {
3246  OSL_FAIL( "FmXGridCell::setVisible: not implemented" );
3247  // not allowed to tamper with this for a grid cell
3248 }
3249 
3250 
3252 {
3253  OSL_FAIL( "FmXGridCell::setEnable: not implemented" );
3254  // not allowed to tamper with this for a grid cell
3255 }
3256 
3257 
3258 void SAL_CALL FmXGridCell::setFocus( )
3259 {
3260  OSL_FAIL( "FmXGridCell::setFocus: not implemented" );
3261  // not allowed to tamper with this for a grid cell
3262 }
3263 
3264 
3265 void SAL_CALL FmXGridCell::addWindowListener( const Reference< awt::XWindowListener >& _rxListener )
3266 {
3267  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3268  m_aWindowListeners.addInterface( _rxListener );
3269 }
3270 
3271 
3272 void SAL_CALL FmXGridCell::removeWindowListener( const Reference< awt::XWindowListener >& _rxListener )
3273 {
3274  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3275  m_aWindowListeners.removeInterface( _rxListener );
3276 }
3277 
3278 
3279 void SAL_CALL FmXGridCell::addFocusListener( const Reference< awt::XFocusListener >& _rxListener )
3280 {
3281  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3282  m_aFocusListeners.addInterface( _rxListener );
3283 }
3284 
3285 
3286 void SAL_CALL FmXGridCell::removeFocusListener( const Reference< awt::XFocusListener >& _rxListener )
3287 {
3288  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3289  m_aFocusListeners.removeInterface( _rxListener );
3290 }
3291 
3292 
3293 void SAL_CALL FmXGridCell::addKeyListener( const Reference< awt::XKeyListener >& _rxListener )
3294 {
3295  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3296  m_aKeyListeners.addInterface( _rxListener );
3297 }
3298 
3299 
3300 void SAL_CALL FmXGridCell::removeKeyListener( const Reference< awt::XKeyListener >& _rxListener )
3301 {
3302  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3303  m_aKeyListeners.removeInterface( _rxListener );
3304 }
3305 
3306 
3307 void SAL_CALL FmXGridCell::addMouseListener( const Reference< awt::XMouseListener >& _rxListener )
3308 {
3309  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3310  m_aMouseListeners.addInterface( _rxListener );
3311 }
3312 
3313 
3314 void SAL_CALL FmXGridCell::removeMouseListener( const Reference< awt::XMouseListener >& _rxListener )
3315 {
3316  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3317  m_aMouseListeners.removeInterface( _rxListener );
3318 }
3319 
3320 
3321 void SAL_CALL FmXGridCell::addMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener )
3322 {
3323  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3324  m_aMouseMotionListeners.addInterface( _rxListener );
3325 }
3326 
3327 
3328 void SAL_CALL FmXGridCell::removeMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener )
3329 {
3330  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3332 }
3333 
3334 
3335 void SAL_CALL FmXGridCell::addPaintListener( const Reference< awt::XPaintListener >& )
3336 {
3337  OSL_FAIL( "FmXGridCell::addPaintListener: not implemented" );
3338 }
3339 
3340 
3341 void SAL_CALL FmXGridCell::removePaintListener( const Reference< awt::XPaintListener >& )
3342 {
3343  OSL_FAIL( "FmXGridCell::removePaintListener: not implemented" );
3344 }
3345 
3346 
3347 IMPL_LINK( FmXGridCell, OnWindowEvent, VclWindowEvent&, _rEvent, void )
3348 {
3349  ENSURE_OR_THROW( _rEvent.GetWindow(), "illegal window" );
3350  onWindowEvent( _rEvent.GetId(), *_rEvent.GetWindow(), _rEvent.GetData() );
3351 }
3352 
3353 
3354 void FmXGridCell::onFocusGained( const awt::FocusEvent& _rEvent )
3355 {
3356  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3357  m_aFocusListeners.notifyEach( &awt::XFocusListener::focusGained, _rEvent );
3358 }
3359 
3360 
3361 void FmXGridCell::onFocusLost( const awt::FocusEvent& _rEvent )
3362 {
3363  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3364  m_aFocusListeners.notifyEach( &awt::XFocusListener::focusLost, _rEvent );
3365 }
3366 
3367 
3368 void FmXGridCell::onWindowEvent( const VclEventId _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
3369 {
3370  switch ( _nEventId )
3371  {
3372  case VclEventId::ControlGetFocus:
3373  case VclEventId::WindowGetFocus:
3374  case VclEventId::ControlLoseFocus:
3375  case VclEventId::WindowLoseFocus:
3376  {
3377  if ( ( _rWindow.IsCompoundControl()
3378  && ( _nEventId == VclEventId::ControlGetFocus
3379  || _nEventId == VclEventId::ControlLoseFocus
3380  )
3381  )
3382  || ( !_rWindow.IsCompoundControl()
3383  && ( _nEventId == VclEventId::WindowGetFocus
3384  || _nEventId == VclEventId::WindowLoseFocus
3385  )
3386  )
3387  )
3388  {
3389  if ( !m_aFocusListeners.getLength() )
3390  break;
3391 
3392  bool bFocusGained = ( _nEventId == VclEventId::ControlGetFocus ) || ( _nEventId == VclEventId::WindowGetFocus );
3393 
3394  awt::FocusEvent aEvent;
3395  aEvent.Source = *this;
3396  aEvent.FocusFlags = static_cast<sal_Int16>(_rWindow.GetGetFocusFlags());
3397  aEvent.Temporary = false;
3398 
3399  if ( bFocusGained )
3400  onFocusGained( aEvent );
3401  else
3402  onFocusLost( aEvent );
3403  }
3404  }
3405  break;
3406  case VclEventId::WindowMouseButtonDown:
3407  case VclEventId::WindowMouseButtonUp:
3408  {
3409  if ( !m_aMouseListeners.getLength() )
3410  break;
3411 
3412  const bool bButtonDown = ( _nEventId == VclEventId::WindowMouseButtonDown );
3413 
3414  awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast< const ::MouseEvent* >( _pEventData ), *this ) );
3415  m_aMouseListeners.notifyEach( bButtonDown ? &awt::XMouseListener::mousePressed : &awt::XMouseListener::mouseReleased, aEvent );
3416  }
3417  break;
3418  case VclEventId::WindowMouseMove:
3419  {
3420  const MouseEvent& rMouseEvent = *static_cast< const ::MouseEvent* >( _pEventData );
3421  if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
3422  {
3423  if ( m_aMouseListeners.getLength() != 0 )
3424  {
3425  awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3426  m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? &awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
3427  }
3428  }
3429  else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() )
3430  {
3431  if ( m_aMouseMotionListeners.getLength() != 0 )
3432  {
3433  awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3434  aEvent.ClickCount = 0;
3435  const bool bSimpleMove = bool( rMouseEvent.GetMode() & MouseEventModifiers::SIMPLEMOVE );
3436  m_aMouseMotionListeners.notifyEach( bSimpleMove ? &awt::XMouseMotionListener::mouseMoved: &awt::XMouseMotionListener::mouseDragged, aEvent );
3437  }
3438  }
3439  }
3440  break;
3441  case VclEventId::WindowKeyInput:
3442  case VclEventId::WindowKeyUp:
3443  {
3444  if ( !m_aKeyListeners.getLength() )
3445  break;
3446 
3447  const bool bKeyPressed = ( _nEventId == VclEventId::WindowKeyInput );
3448  awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent( *static_cast< const ::KeyEvent* >( _pEventData ), *this ) );
3449  m_aKeyListeners.notifyEach( bKeyPressed ? &awt::XKeyListener::keyPressed: &awt::XKeyListener::keyReleased, aEvent );
3450  }
3451  break;
3452  default: break;
3453  }
3454 }
3455 
3456 
3458  const Reference< css::sdb::XColumn >& _rxField,
3459  const Reference< XNumberFormatter >& xFormatter)
3460 {
3461  m_pCellControl->PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3462 }
3463 
3464 
3466 {
3467  Reference< css::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3468  if (xField.is())
3469  m_pCellControl->UpdateFromField(xField, m_pColumn->GetParent().getNumberFormatter());
3470 }
3471 
3472 
3473 FmXTextCell::FmXTextCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3474  :FmXDataCell( pColumn, std::move(pControl) )
3475  ,m_bFastPaint( true )
3476 {
3477 }
3478 
3479 
3481  const tools::Rectangle& rRect,
3482  const Reference< css::sdb::XColumn >& _rxField,
3483  const Reference< XNumberFormatter >& xFormatter)
3484 {
3485  if ( !m_bFastPaint )
3486  {
3487  FmXDataCell::PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3488  return;
3489  }
3490 
3491  DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter;
3492  if ( ( rDev.GetOutDevType() == OUTDEV_WINDOW ) && !static_cast< vcl::Window& >( rDev ).IsEnabled() )
3493  nStyle |= DrawTextFlags::Disable;
3494 
3495  switch (m_pColumn->GetAlignment())
3496  {
3497  case css::awt::TextAlign::RIGHT:
3498  nStyle |= DrawTextFlags::Right;
3499  break;
3500  case css::awt::TextAlign::CENTER:
3501  nStyle |= DrawTextFlags::Center;
3502  break;
3503  default:
3504  nStyle |= DrawTextFlags::Left;
3505  }
3506 
3507  try
3508  {
3509  const Color* pColor = nullptr;
3510  OUString aText = GetText(_rxField, xFormatter, &pColor);
3511  if (pColor != nullptr)
3512  {
3513  Color aOldTextColor( rDev.GetTextColor() );
3514  rDev.SetTextColor( *pColor );
3515  rDev.DrawText(rRect, aText, nStyle);
3516  rDev.SetTextColor( aOldTextColor );
3517  }
3518  else
3519  rDev.DrawText(rRect, aText, nStyle);
3520  }
3521  catch (const Exception&)
3522  {
3523  TOOLS_WARN_EXCEPTION("svx.fmcomp", "PaintFieldToCell");
3524  }
3525 }
3526 
3527 FmXEditCell::FmXEditCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3528  :FmXTextCell( pColumn, std::move(pControl) )
3529  ,m_aTextListeners(m_aMutex)
3530  ,m_aChangeListeners( m_aMutex )
3531  ,m_pEditImplementation( nullptr )
3532  ,m_bOwnEditImplementation( false )
3533 {
3534 
3535  DbTextField* pTextField = dynamic_cast<DbTextField*>( m_pCellControl.get() );
3536  if ( pTextField )
3537  {
3538 
3540  if ( !pTextField->IsSimpleEdit() )
3541  m_bFastPaint = false;
3542  }
3543  else
3544  {
3545  m_pEditImplementation = new EntryImplementation(static_cast<EditControlBase&>(m_pCellControl->GetWindow()));
3546  m_bOwnEditImplementation = true;
3547  }
3548  m_pEditImplementation->SetAuxModifyHdl(LINK(this, FmXEditCell, ModifyHdl));
3549 }
3550 
3552 {
3553  if (!OComponentHelper::rBHelper.bDisposed)
3554  {
3555  acquire();
3556  dispose();
3557  }
3558 }
3559 
3560 // OComponentHelper
3562 {
3563  css::lang::EventObject aEvt(*this);
3566 
3568  delete m_pEditImplementation;
3569  m_pEditImplementation = nullptr;
3570 
3572 }
3573 
3574 Any SAL_CALL FmXEditCell::queryAggregation( const css::uno::Type& _rType )
3575 {
3576  Any aReturn = FmXTextCell::queryAggregation( _rType );
3577 
3578  if ( !aReturn.hasValue() )
3579  aReturn = FmXEditCell_Base::queryInterface( _rType );
3580 
3581  return aReturn;
3582 }
3583 
3584 Sequence< css::uno::Type > SAL_CALL FmXEditCell::getTypes( )
3585 {
3586  return ::comphelper::concatSequences(
3589  );
3590 }
3591 
3593 
3594 // css::awt::XTextComponent
3595 void SAL_CALL FmXEditCell::addTextListener(const Reference< css::awt::XTextListener >& l)
3596 {
3597  m_aTextListeners.addInterface( l );
3598 }
3599 
3600 
3601 void SAL_CALL FmXEditCell::removeTextListener(const Reference< css::awt::XTextListener >& l)
3602 {
3604 }
3605 
3606 void SAL_CALL FmXEditCell::setText( const OUString& aText )
3607 {
3608  ::osl::MutexGuard aGuard( m_aMutex );
3609 
3610  if ( m_pEditImplementation )
3611  {
3612  m_pEditImplementation->SetText( aText );
3613 
3614  // In Java, a textChanged is fired as well; not in VCL.
3615  // css::awt::Toolkit must be Java-compliant...
3616  onTextChanged();
3617  }
3618 }
3619 
3620 void SAL_CALL FmXEditCell::insertText(const css::awt::Selection& rSel, const OUString& aText)
3621 {
3622  ::osl::MutexGuard aGuard( m_aMutex );
3623 
3624  if ( m_pEditImplementation )
3625  {
3626  m_pEditImplementation->SetSelection( Selection( rSel.Min, rSel.Max ) );
3627  m_pEditImplementation->ReplaceSelected( aText );
3628  }
3629 }
3630 
3631 OUString SAL_CALL FmXEditCell::getText()
3632 {
3633  ::osl::MutexGuard aGuard( m_aMutex );
3634 
3635  OUString aText;
3636  if ( m_pEditImplementation )
3637  {
3638  if ( m_pEditImplementation->GetControl().IsVisible() && m_pColumn->GetParent().getDisplaySynchron())
3639  {
3640  // if the display isn't sync with the cursor we can't ask the edit field
3641  LineEnd eLineEndFormat = getModelLineEndSetting( m_pColumn->getModel() );
3642  aText = m_pEditImplementation->GetText( eLineEndFormat );
3643  }
3644  else
3645  {
3646  Reference< css::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3647  if (xField.is())
3648  aText = GetText(xField, m_pColumn->GetParent().getNumberFormatter());
3649  }
3650  }
3651  return aText;
3652 }
3653 
3654 OUString SAL_CALL FmXEditCell::getSelectedText()
3655 {
3656  ::osl::MutexGuard aGuard( m_aMutex );
3657 
3658  OUString aText;
3659  if ( m_pEditImplementation )
3660  {
3661  LineEnd eLineEndFormat = m_pColumn ? getModelLineEndSetting( m_pColumn->getModel() ) : LINEEND_LF;
3662  aText = m_pEditImplementation->GetSelected( eLineEndFormat );
3663  }
3664  return aText;
3665 }
3666 
3667 void SAL_CALL FmXEditCell::setSelection( const css::awt::Selection& aSelection )
3668 {
3669  ::osl::MutexGuard aGuard( m_aMutex );
3670 
3671  if ( m_pEditImplementation )
3672  m_pEditImplementation->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
3673 }
3674 
3675 css::awt::Selection SAL_CALL FmXEditCell::getSelection()
3676 {
3677  ::osl::MutexGuard aGuard( m_aMutex );
3678 
3679  Selection aSel;
3680  if ( m_pEditImplementation )
3681  aSel = m_pEditImplementation->GetSelection();
3682 
3683  return css::awt::Selection(aSel.Min(), aSel.Max());
3684 }
3685 
3687 {
3688  ::osl::MutexGuard aGuard( m_aMutex );
3689 
3690  return m_pEditImplementation && !m_pEditImplementation->IsReadOnly() && m_pEditImplementation->GetControl().IsEnabled();
3691 }
3692 
3693 void SAL_CALL FmXEditCell::setEditable( sal_Bool bEditable )
3694 {
3695  ::osl::MutexGuard aGuard( m_aMutex );
3696 
3697  if ( m_pEditImplementation )
3698  m_pEditImplementation->SetReadOnly( !bEditable );
3699 }
3700 
3701 sal_Int16 SAL_CALL FmXEditCell::getMaxTextLen()
3702 {
3703  ::osl::MutexGuard aGuard( m_aMutex );
3704 
3705  return m_pEditImplementation ? m_pEditImplementation->GetMaxTextLen() : 0;
3706 }
3707 
3708 void SAL_CALL FmXEditCell::setMaxTextLen( sal_Int16 nLen )
3709 {
3710  ::osl::MutexGuard aGuard( m_aMutex );
3711 
3712  if ( m_pEditImplementation )
3713  m_pEditImplementation->SetMaxTextLen( nLen );
3714 }
3715 
3716 void SAL_CALL FmXEditCell::addChangeListener( const Reference< form::XChangeListener >& Listener )
3717 {
3718  m_aChangeListeners.addInterface( Listener );
3719 }
3720 
3721 void SAL_CALL FmXEditCell::removeChangeListener( const Reference< form::XChangeListener >& Listener )
3722 {
3723  m_aChangeListeners.removeInterface( Listener );
3724 }
3725 
3727 {
3728  css::awt::TextEvent aEvent;
3729  aEvent.Source = *this;
3730  m_aTextListeners.notifyEach( &awt::XTextListener::textChanged, aEvent );
3731 }
3732 
3733 void FmXEditCell::onFocusGained( const awt::FocusEvent& _rEvent )
3734 {
3735  FmXTextCell::onFocusGained( _rEvent );
3737 }
3738 
3739 void FmXEditCell::onFocusLost( const awt::FocusEvent& _rEvent )
3740 {
3741  FmXTextCell::onFocusLost( _rEvent );
3742 
3743  if ( getText() != m_sValueOnEnter )
3744  {
3745  lang::EventObject aEvent( *this );
3746  m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvent );
3747  }
3748 }
3749 
3751 {
3752  if (m_aTextListeners.getLength())
3753  onTextChanged();
3754 }
3755 
3756 FmXCheckBoxCell::FmXCheckBoxCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3757  :FmXDataCell( pColumn, std::move(pControl) )
3758  ,m_aItemListeners(m_aMutex)
3759  ,m_aActionListeners( m_aMutex )
3760  ,m_pBox( & static_cast< CheckBoxControl& >( m_pCellControl->GetWindow() ) )
3761 {
3762  m_pBox->SetAuxModifyHdl(LINK(this, FmXCheckBoxCell, ModifyHdl));
3763 }
3764 
3766 {
3767  if (!OComponentHelper::rBHelper.bDisposed)
3768  {
3769  acquire();
3770  dispose();
3771  }
3772 }
3773 
3774 // OComponentHelper
3776 {
3777  css::lang::EventObject aEvt(*this);
3780 
3782  m_pBox = nullptr;
3783 
3785 }
3786 
3787 
3788 Any SAL_CALL FmXCheckBoxCell::queryAggregation( const css::uno::Type& _rType )
3789 {
3790  Any aReturn = FmXDataCell::queryAggregation( _rType );
3791 
3792  if ( !aReturn.hasValue() )
3793  aReturn = FmXCheckBoxCell_Base::queryInterface( _rType );
3794 
3795  return aReturn;
3796 }
3797 
3798 
3799 Sequence< css::uno::Type > SAL_CALL FmXCheckBoxCell::getTypes( )
3800 {
3801  return ::comphelper::concatSequences(
3804  );
3805 }
3806 
3807 
3809 
3810 void SAL_CALL FmXCheckBoxCell::addItemListener( const Reference< css::awt::XItemListener >& l )
3811 {
3812  m_aItemListeners.addInterface( l );
3813 }
3814 
3815 void SAL_CALL FmXCheckBoxCell::removeItemListener( const Reference< css::awt::XItemListener >& l )
3816 {
3818 }
3819 
3820 void SAL_CALL FmXCheckBoxCell::setState( sal_Int16 n )
3821 {
3822  ::osl::MutexGuard aGuard( m_aMutex );
3823 
3824  if (m_pBox)
3825  {
3826  UpdateFromColumn();
3827  m_pBox->SetState( static_cast<TriState>(n) );
3828  }
3829 }
3830 
3831 sal_Int16 SAL_CALL FmXCheckBoxCell::getState()
3832 {
3833  ::osl::MutexGuard aGuard( m_aMutex );
3834 
3835  if (m_pBox)
3836  {
3837  UpdateFromColumn();
3838  return static_cast<sal_Int16>(m_pBox->GetState());
3839  }
3840  return TRISTATE_INDET;
3841 }
3842 
3844 {
3845  ::osl::MutexGuard aGuard( m_aMutex );
3846 
3847  if (m_pBox)
3848  m_pBox->EnableTriState( b );
3849 }
3850 
3851 void SAL_CALL FmXCheckBoxCell::addActionListener( const Reference< awt::XActionListener >& Listener )
3852 {
3853  m_aActionListeners.addInterface( Listener );
3854 }
3855 
3856 
3857 void SAL_CALL FmXCheckBoxCell::removeActionListener( const Reference< awt::XActionListener >& Listener )
3858 {
3859  m_aActionListeners.removeInterface( Listener );
3860 }
3861 
3862 void SAL_CALL FmXCheckBoxCell::setLabel( const OUString& Label )
3863 {
3864  SolarMutexGuard aGuard;
3865  if ( m_pColumn )
3866  {
3867  DbGridControl& rGrid( m_pColumn->GetParent() );
3868  rGrid.SetColumnTitle( rGrid.GetColumnId( m_pColumn->GetFieldPos() ), Label );
3869  }
3870 }
3871 
3872 void SAL_CALL FmXCheckBoxCell::setActionCommand( const OUString& Command )
3873 {
3874  m_aActionCommand = Command;
3875 }
3876 
3878 {
3879  // check boxes are to be committed immediately (this holds for ordinary check box controls in
3880  // documents, and this must hold for check boxes in grid columns, too
3881  // 91210 - 22.08.2001 - frank.schoenheit@sun.com
3882  m_pCellControl->Commit();
3883 
3884  Reference< XWindow > xKeepAlive( this );
3885  if ( m_aItemListeners.getLength() && m_pBox )
3886  {
3887  awt::ItemEvent aEvent;
3888  aEvent.Source = *this;
3889  aEvent.Highlighted = 0;
3890  aEvent.Selected = m_pBox->GetState();
3891  m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
3892  }
3893  if ( m_aActionListeners.getLength() )
3894  {
3895  awt::ActionEvent aEvent;
3896  aEvent.Source = *this;
3897  aEvent.ActionCommand = m_aActionCommand;
3898  m_aActionListeners.notifyEach( &awt::XActionListener::actionPerformed, aEvent );
3899  }
3900 }
3901 
3902 FmXListBoxCell::FmXListBoxCell(DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl)
3903  : FmXTextCell(pColumn, std::move(pControl))
3904  , m_aItemListeners(m_aMutex)
3905  , m_aActionListeners(m_aMutex)
3906  , m_pBox(&static_cast<svt::ListBoxControl&>(m_pCellControl->GetWindow()))
3907  , m_nLines(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())
3908  , m_bMulti(false)
3909 {
3910  m_pBox->SetAuxModifyHdl(LINK(this, FmXListBoxCell, ChangedHdl));
3911 }
3912 
3914 {
3915  if (!OComponentHelper::rBHelper.bDisposed)
3916  {
3917  acquire();
3918  dispose();
3919  }
3920 }
3921 
3922 // OComponentHelper
3924 {
3925  css::lang::EventObject aEvt(*this);
3928 
3930  m_pBox = nullptr;
3931 
3933 }
3934 
3935 Any SAL_CALL FmXListBoxCell::queryAggregation( const css::uno::Type& _rType )
3936 {
3937  Any aReturn = FmXTextCell::queryAggregation(_rType);
3938 
3939  if ( !aReturn.hasValue() )
3940  aReturn = FmXListBoxCell_Base::queryInterface( _rType );
3941 
3942  return aReturn;
3943 }
3944 
3945 Sequence< css::uno::Type > SAL_CALL FmXListBoxCell::getTypes( )
3946 {
3947  return ::comphelper::concatSequences(
3950  );
3951 }
3952 
3954 
3955 void SAL_CALL FmXListBoxCell::addItemListener(const Reference< css::awt::XItemListener >& l)
3956 {
3957  m_aItemListeners.addInterface( l );
3958 }
3959 
3960 void SAL_CALL FmXListBoxCell::removeItemListener(const Reference< css::awt::XItemListener >& l)
3961 {
3963 }
3964 
3965 void SAL_CALL FmXListBoxCell::addActionListener(const Reference< css::awt::XActionListener >& l)
3966 {
3968 }
3969 
3970 void SAL_CALL FmXListBoxCell::removeActionListener(const Reference< css::awt::XActionListener >& l)
3971 {
3973 }
3974 
3975 void SAL_CALL FmXListBoxCell::addItem(const OUString& aItem, sal_Int16 nPos)
3976 {
3977  ::osl::MutexGuard aGuard( m_aMutex );
3978  if (m_pBox)
3979  {
3980  weld::ComboBox& rBox = m_pBox->get_widget();
3981  rBox.insert_text(nPos, aItem);
3982  }
3983 }
3984 
3985 void SAL_CALL FmXListBoxCell::addItems(const css::uno::Sequence<OUString>& aItems, sal_Int16 nPos)
3986 {
3987  ::osl::MutexGuard aGuard( m_aMutex );
3988  if (m_pBox)
3989  {
3990  weld::ComboBox& rBox = m_pBox->get_widget();
3991  sal_uInt16 nP = nPos;
3992  for ( const auto& rItem : aItems )
3993  {
3994  rBox.insert_text(nP, rItem);
3995  if ( nPos != -1 ) // Not if 0xFFFF, because LIST_APPEND
3996  nP++;
3997  }
3998  }
3999 }
4000 
4001 void SAL_CALL FmXListBoxCell::removeItems(sal_Int16 nPos, sal_Int16 nCount)
4002 {
4003  ::osl::MutexGuard aGuard( m_aMutex );
4004  if ( m_pBox )
4005  {
4006  weld::ComboBox& rBox = m_pBox->get_widget();
4007  for ( sal_uInt16 n = nCount; n; )
4008  rBox.remove( nPos + (--n) );
4009  }
4010 }
4011 
4012 sal_Int16 SAL_CALL FmXListBoxCell::getItemCount()
4013 {
4014  ::osl::MutexGuard aGuard( m_aMutex );
4015  if (!m_pBox)
4016  return 0;
4017  weld::ComboBox& rBox = m_pBox->get_widget();
4018  return rBox.get_count();
4019 }
4020 
4021 OUString SAL_CALL FmXListBoxCell::getItem(sal_Int16 nPos)
4022 {
4023  ::osl::MutexGuard aGuard( m_aMutex );
4024  if (!m_pBox)
4025  return OUString();
4026  weld::ComboBox& rBox = m_pBox->get_widget();
4027  return rBox.get_text(nPos);
4028 }
4029 
4030 css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getItems()
4031 {
4032  ::osl::MutexGuard aGuard( m_aMutex );
4033 
4034  css::uno::Sequence<OUString> aSeq;
4035  if (m_pBox)
4036  {
4037  weld::ComboBox& rBox = m_pBox->get_widget();
4038  const sal_Int32 nEntries = rBox.get_count();
4039  aSeq = css::uno::Sequence<OUString>( nEntries );
4040  for ( sal_Int32 n = nEntries; n; )
4041  {
4042  --n;
4043  aSeq.getArray()[n] = rBox.get_text( n );
4044  }
4045  }
4046  return aSeq;
4047 }
4048 
4050 {
4051  ::osl::MutexGuard aGuard( m_aMutex );
4052  if (m_pBox)
4053  {
4054  UpdateFromColumn();
4055  weld::ComboBox& rBox = m_pBox->get_widget();
4056  sal_Int32 nPos = rBox.get_active();
4057  if (nPos > SHRT_MAX || nPos < SHRT_MIN)
4058  throw std::out_of_range("awt::XListBox::getSelectedItemPos can only return a short");
4059  return nPos;
4060  }
4061  return 0;
4062 }
4063 
4064 Sequence< sal_Int16 > SAL_CALL FmXListBoxCell::getSelectedItemsPos()
4065 {
4066  ::osl::MutexGuard aGuard( m_aMutex );
4067  Sequence<sal_Int16> aSeq;
4068 
4069  if (m_pBox)
4070  {
4071  UpdateFromColumn();
4072  weld::ComboBox& rBox = m_pBox->get_widget();
4073  auto nActive = rBox.get_active();
4074  if (nActive != -1)
4075  {
4076  aSeq = Sequence<sal_Int16>(1);
4077  aSeq.getArray()[0] = nActive;
4078  }
4079  }
4080  return aSeq;
4081 }
4082 
4084 {
4085  ::osl::MutexGuard aGuard( m_aMutex );
4086 
4087  OUString aItem;
4088 
4089  if (m_pBox)
4090  {
4091  UpdateFromColumn();
4092  weld::ComboBox& rBox = m_pBox->get_widget();
4093  aItem = rBox.get_active_text();
4094  }
4095 
4096  return aItem;
4097 }
4098 
4099 css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getSelectedItems()
4100 {
4101  ::osl::MutexGuard aGuard( m_aMutex );
4102 
4103  css::uno::Sequence<OUString> aSeq;
4104 
4105  if (m_pBox)
4106  {
4107  UpdateFromColumn();
4108  weld::ComboBox& rBox = m_pBox->get_widget();
4109  auto nActive = rBox.get_active();
4110  if (nActive != -1)
4111  {
4112  aSeq = css::uno::Sequence<OUString>(1);
4113  aSeq.getArray()[0] = rBox.get_text(nActive);
4114  }
4115  }
4116  return aSeq;
4117 }
4118 
4119 void SAL_CALL FmXListBoxCell::selectItemPos(sal_Int16 nPos, sal_Bool bSelect)
4120 {
4121  ::osl::MutexGuard aGuard( m_aMutex );
4122 
4123  if (m_pBox)
4124  {
4125  weld::ComboBox& rBox = m_pBox->get_widget();
4126  if (bSelect)
4127  rBox.set_active(nPos);
4128  else if (nPos == rBox.get_active())
4129  rBox.set_active(-1);
4130  }
4131 }
4132 
4133 void SAL_CALL FmXListBoxCell::selectItemsPos(const Sequence< sal_Int16 >& aPositions, sal_Bool bSelect)
4134 {
4135  ::osl::MutexGuard aGuard( m_aMutex );
4136 
4137  if (m_pBox)
4138  {
4139  weld::ComboBox& rBox = m_pBox->get_widget();
4140  for ( sal_uInt16 n = static_cast<sal_uInt16>(aPositions.getLength()); n; )
4141  {
4142  auto nPos = static_cast<sal_uInt16>(aPositions.getConstArray()[--n]);
4143  if (bSelect)
4144  rBox.set_active(nPos);
4145  else if (nPos == rBox.get_active())
4146  rBox.set_active(-1);
4147  }
4148  }
4149 }
4150 
4151 void SAL_CALL FmXListBoxCell::selectItem(const OUString& aItem, sal_Bool bSelect)
4152 {
4153  ::osl::MutexGuard aGuard( m_aMutex );
4154 
4155  if (m_pBox)
4156  {
4157  weld::ComboBox& rBox = m_pBox->get_widget();
4158  auto nPos = rBox.find_text(aItem);
4159  if (bSelect)
4160  rBox.set_active(nPos);
4161  else if (nPos == rBox.get_active())
4162  rBox.set_active(-1);
4163  }
4164 }
4165 
4167 {
4168  ::osl::MutexGuard aGuard( m_aMutex );
4169 
4170  return m_bMulti;
4171 }
4172 
4174 {
4175  ::osl::MutexGuard aGuard( m_aMutex );
4176 
4177  m_bMulti = bMulti;
4178 }
4179 
4181 {
4182  ::osl::MutexGuard aGuard( m_aMutex );
4183  return m_nLines;
4184 }
4185 
4186 void SAL_CALL FmXListBoxCell::setDropDownLineCount(sal_Int16 nLines)
4187 {
4188  ::osl::MutexGuard aGuard( m_aMutex );
4189 
4190  m_nLines = nLines; // just store it to return it
4191 }
4192 
4193 void SAL_CALL FmXListBoxCell::makeVisible(sal_Int16 /*nEntry*/)
4194 {
4195 }
4196 
4197 IMPL_LINK(FmXListBoxCell, ChangedHdl, bool, bInteractive, void)
4198 {
4199  if (!m_pBox)
4200  return;
4201 
4202  weld::ComboBox& rBox = m_pBox->get_widget();
4203 
4204  if (bInteractive && !rBox.changed_by_direct_pick())
4205  return;
4206 
4207  OnDoubleClick();
4208 
4209  css::awt::ItemEvent aEvent;
4210  aEvent.Source = *this;
4211  aEvent.Highlighted = 0;
4212 
4213  // with multiple selection 0xFFFF, otherwise the ID
4214  aEvent.Selected = (rBox.get_active() != -1 )
4215  ? rBox.get_active() : 0xFFFF;
4216 
4217  m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4218 }
4219 
4221 {
4223 
4224  css::awt::ActionEvent aEvent;
4225  aEvent.Source = *this;
4226  weld::ComboBox& rBox = m_pBox->get_widget();
4227  aEvent.ActionCommand = rBox.get_active_text();
4228 
4229  while( aIt.hasMoreElements() )
4230  static_cast< css::awt::XActionListener *>(aIt.next())->actionPerformed( aEvent );
4231 }
4232 
4233 FmXComboBoxCell::FmXComboBoxCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
4234  :FmXTextCell( pColumn, std::move(pControl) )
4235  ,m_aItemListeners( m_aMutex )
4236  ,m_aActionListeners( m_aMutex )
4237  ,m_pComboBox(&static_cast<ComboBoxControl&>(m_pCellControl->GetWindow()))
4238  ,m_nLines(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())
4239 {
4240  m_pComboBox->SetAuxModifyHdl(LINK(this, FmXComboBoxCell, ChangedHdl));
4241 }
4242 
4244 {
4245  if ( !OComponentHelper::rBHelper.bDisposed )
4246  {
4247  acquire();
4248  dispose();
4249  }
4250 
4251 }
4252 
4254 {
4255  css::lang::EventObject aEvt(*this);
4258 
4260  m_pComboBox = nullptr;
4261 
4263 }
4264 
4265 Any SAL_CALL FmXComboBoxCell::queryAggregation( const css::uno::Type& _rType )
4266 {
4267  Any aReturn = FmXTextCell::queryAggregation(_rType);
4268 
4269  if ( !aReturn.hasValue() )
4270  aReturn = FmXComboBoxCell_Base::queryInterface( _rType );
4271 
4272  return aReturn;
4273 }
4274 
4275 Sequence< Type > SAL_CALL FmXComboBoxCell::getTypes( )
4276 {
4277  return ::comphelper::concatSequences(
4280  );
4281 }
4282 
4284 
4285 void SAL_CALL FmXComboBoxCell::addItemListener(const Reference< awt::XItemListener >& l)
4286 {
4287  m_aItemListeners.addInterface( l );
4288 }
4289 
4290 void SAL_CALL FmXComboBoxCell::removeItemListener(const Reference< awt::XItemListener >& l)
4291 {
4293 }
4294 
4295 void SAL_CALL FmXComboBoxCell::addActionListener(const Reference< awt::XActionListener >& l)
4296 {
4298 }
4299 
4300 
4301 void SAL_CALL FmXComboBoxCell::removeActionListener(const Reference< awt::XActionListener >& l)
4302 {
4304 }
4305 
4306 void SAL_CALL FmXComboBoxCell::addItem( const OUString& Item, sal_Int16 Pos )
4307 {
4308  ::osl::MutexGuard aGuard( m_aMutex );
4309  if (!m_pComboBox)
4310  return;
4312  rBox.insert_text(Pos, Item);
4313 }
4314 
4315 void SAL_CALL FmXComboBoxCell::addItems( const Sequence< OUString >& Items, sal_Int16 Pos )
4316 {
4317  ::osl::MutexGuard aGuard( m_aMutex );
4318  if (!m_pComboBox)
4319  return;
4321  sal_uInt16 nP = Pos;
4322  for ( const auto& rItem : Items )
4323  {
4324  rBox.insert_text(nP, rItem);
4325  if ( Pos != -1 )
4326  nP++;
4327  }
4328 }
4329 
4330 void SAL_CALL FmXComboBoxCell::removeItems( sal_Int16 Pos, sal_Int16 Count )
4331 {
4332  ::osl::MutexGuard aGuard( m_aMutex );
4333  if (!m_pComboBox)
4334  return;
4336  for ( sal_uInt16 n = Count; n; )
4337  rBox.remove( Pos + (--n) );
4338 }
4339 
4340 sal_Int16 SAL_CALL FmXComboBoxCell::getItemCount()
4341 {
4342  ::osl::MutexGuard aGuard( m_aMutex );
4343  if (!m_pComboBox)
4344  return 0;
4346  return rBox.get_count();
4347 }
4348 
4349 OUString SAL_CALL FmXComboBoxCell::getItem( sal_Int16 Pos )
4350 {
4351  ::osl::MutexGuard aGuard( m_aMutex );
4352  if (!m_pComboBox)
4353  return OUString();
4355  return rBox.get_text(Pos);
4356 }
4357 
4359 {
4360  ::osl::MutexGuard aGuard( m_aMutex );
4361 
4362  Sequence< OUString > aItems;
4363  if (m_pComboBox)
4364  {
4366  const sal_Int32 nEntries = rBox.get_count();
4367  aItems.realloc( nEntries );
4368  OUString* pItem = aItems.getArray();
4369  for ( sal_Int32 n=0; n<nEntries; ++n, ++pItem )
4370  *pItem = rBox.get_text(n);
4371  }
4372  return aItems;
4373 }
4374 
4376 {
4377  ::osl::MutexGuard aGuard( m_aMutex );
4378  return m_nLines;
4379 }
4380 
4381 void SAL_CALL FmXComboBoxCell::setDropDownLineCount(sal_Int16 nLines)
4382 {
4383  ::osl::MutexGuard aGuard( m_aMutex );
4384  m_nLines = nLines; // just store it to return it
4385 }
4386 
4387 IMPL_LINK(FmXComboBoxCell, ChangedHdl, bool, bInteractive, void)
4388 {
4389  if (!m_pComboBox)
4390  return;
4391 
4392  weld::ComboBox& rComboBox = m_pComboBox->get_widget();
4393 
4394  if (bInteractive && !rComboBox.changed_by_direct_pick())
4395  return;
4396 
4397  awt::ItemEvent aEvent;
4398  aEvent.Source = *this;
4399  aEvent.Highlighted = 0;
4400 
4401  // with invalid selection 0xFFFF, otherwise the position
4402  aEvent.Selected = ( rComboBox.get_active() != -1 )
4403  ? rComboBox.get_active()
4404  : 0xFFFF;
4405  m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4406 }
4407 
4408 FmXFilterCell::FmXFilterCell(DbGridColumn* pColumn, std::unique_ptr<DbFilterField> pControl )
4409  :FmXGridCell( pColumn, std::move(pControl) )
4410  ,m_aTextListeners(m_aMutex)
4411 {
4412  static_cast<DbFilterField*>(m_pCellControl.get())->SetCommitHdl( LINK( this, FmXFilterCell, OnCommit ) );
4413 }
4414 
4416 {
4417  if (!OComponentHelper::rBHelper.bDisposed)
4418  {
4419  acquire();
4420  dispose();
4421  }
4422 
4423 }
4424 
4425 // XUnoTunnel
4426 sal_Int64 SAL_CALL FmXFilterCell::getSomething( const Sequence< sal_Int8 >& _rIdentifier )
4427 {
4428  sal_Int64 nReturn(0);
4429 
4430  if ( isUnoTunnelId<FmXFilterCell>(_rIdentifier) )
4431  {
4432  nReturn = reinterpret_cast<sal_Int64>(this);
4433  }
4434 
4435  return nReturn;
4436 }
4437 
4438 const Sequence<sal_Int8>& FmXFilterCell::getUnoTunnelId()
4439 {
4440  static const UnoTunnelIdInit theFmXFilterCellUnoTunnelId;
4441  return theFmXFilterCellUnoTunnelId.getSeq();
4442 }
4443 
4444 
4446 {
4447  static_cast< DbFilterField* >( m_pCellControl.get() )->PaintCell( rDev, rRect );
4448 }
4449 
4450 // OComponentHelper
4451 
4453 {
4454  css::lang::EventObject aEvt(*this);
4456 
4457  static_cast<DbFilterField*>(m_pCellControl.get())->SetCommitHdl(Link<DbFilterField&,void>());
4458 
4460 }
4461 
4462 
4463 Any SAL_CALL FmXFilterCell::queryAggregation( const css::uno::Type& _rType )
4464 {
4465  Any aReturn = FmXGridCell::queryAggregation(_rType);
4466 
4467  if ( !aReturn.hasValue() )
4468  aReturn = FmXFilterCell_Base::queryInterface( _rType );
4469 
4470  return aReturn;
4471 }
4472 
4473 
4474 Sequence< css::uno::Type > SAL_CALL FmXFilterCell::getTypes( )
4475 {
4476  return ::comphelper::concatSequences(
4479  );
4480 }
4481 
4482 
4484 
4485 // css::awt::XTextComponent
4486 
4487 void SAL_CALL FmXFilterCell::addTextListener(const Reference< css::awt::XTextListener >& l)
4488 {
4489  m_aTextListeners.addInterface( l );
4490 }
4491 
4492 
4493 void SAL_CALL FmXFilterCell::removeTextListener(const Reference< css::awt::XTextListener >& l)
4494 {
4496 }
4497 
4498 void SAL_CALL FmXFilterCell::setText( const OUString& aText )
4499 {
4500  ::osl::MutexGuard aGuard( m_aMutex );
4501  static_cast<DbFilterField*>(m_pCellControl.get())->SetText(aText);
4502 }
4503 
4504 void SAL_CALL FmXFilterCell::insertText( const css::awt::Selection& /*rSel*/, const OUString& /*aText*/ )
4505 {
4506 }
4507 
4508 OUString SAL_CALL FmXFilterCell::getText()
4509 {
4510  ::osl::MutexGuard aGuard( m_aMutex );
4511  return static_cast<DbFilterField*>(m_pCellControl.get())->GetText();
4512 }
4513 
4515 {
4516  return getText();
4517 }
4518 
4519 void SAL_CALL FmXFilterCell::setSelection( const css::awt::Selection& /*aSelection*/ )
4520 {
4521 }
4522 
4523 css::awt::Selection SAL_CALL FmXFilterCell::getSelection()
4524 {
4525  return css::awt::Selection();
4526 }
4527 
4529 {
4530  return true;
4531 }
4532 
4533 void SAL_CALL FmXFilterCell::setEditable( sal_Bool /*bEditable*/ )
4534 {
4535 }
4536 
4537 sal_Int16 SAL_CALL FmXFilterCell::getMaxTextLen()
4538 {
4539  return 0;
4540 }
4541 
4542 void SAL_CALL FmXFilterCell::setMaxTextLen( sal_Int16 /*nLen*/ )
4543 {
4544 }
4545 
4547 {
4548  ::comphelper::OInterfaceIteratorHelper2 aIt( m_aTextListeners );
4549  css::awt::TextEvent aEvt;
4550  aEvt.Source = *this;
4551  while( aIt.hasMoreElements() )
4552  static_cast< css::awt::XTextListener *>(aIt.next())->textChanged( aEvt );
4553 }
4554 
4555 /* 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:4315
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:4220
OutDevType GetOutDevType() const
bool IsControlBackground() const
virtual sal_Int16 SAL_CALL getState() override
Definition: gridcell.cxx:3831
::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:3314
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:2770
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:3843
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:3851
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:3202
#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:3667
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: gridcell.cxx:3584
#define FM_PROP_FIELDSOURCE
Definition: fmprop.hxx:108
FmXFilterCell(DbGridColumn *pColumn, std::unique_ptr< DbFilterField > pControl)
Definition: gridcell.cxx:4408
FmXTextCell(DbGridColumn *pColumn, std::unique_ptr< DbCellControl > pControl)
Definition: gridcell.cxx:3473
void PaintCell(OutputDevice &rDev, const tools::Rectangle &rRect)
Definition: gridcell.cxx:4445
#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:4498
virtual void SAL_CALL disposing() override
Definition: gridcell.cxx:3923
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
void SetAuxModifyHdl(const Link< bool, void > &rLink)
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:2682
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:4193
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:4151
sal_Int16 m_nControlClass
Definition: gridcell.hxx:680
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &_rType) override
Definition: gridcell.cxx:4265
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:2732
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:3631
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:2564
bool IsNew() const
Definition: gridctrl.hxx:85
FmXEditCell(DbGridColumn *pColumn, std::unique_ptr< DbCellControl > pControl)
Definition: gridcell.cxx:3527
MouseEventModifiers GetMode() const
SvNumberFormatter * StandardFormatter()
virtual sal_Int16 SAL_CALL getDropDownLineCount() override
Definition: gridcell.cxx:4180
virtual void SAL_CALL setMaxTextLen(sal_Int16 nLen) override
Definition: gridcell.cxx:3708
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
virtual void SAL_CALL setVisible(sal_Bool Visible) override
Definition: gridcell.cxx:3244
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:4528
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:4119
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:4083
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:2598
virtual void SAL_CALL setEditable(sal_Bool bEditable) override
Definition: gridcell.cxx:3693
sal_Int32 m_nFormatKey
Definition: gridcell.hxx:84
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
Definition: gridcell.cxx:4438
void disposeAndClear(const css::lang::EventObject &rEvt)
sal_Int32 getElementPos(const Reference< css::container::XIndexAccess > &xCont, const Reference< XInterface > &xElement)
Definition: fmtools.cxx:118
virtual css::uno::Sequence< OUString > SAL_CALL getItems() override
Definition: gridcell.cxx:4030
FmXListBoxCell(DbGridColumn *pColumn, std::unique_ptr< DbCellControl > pControl)
Definition: gridcell.cxx:3902
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: gri