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