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