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 
950 {
951  if ( m_pPainter->GetParent() == &_rDev )
952  {
959 
960  vcl::Font aFont( _rDev.GetFont() );
961  aFont.SetTransparent( true );
962  m_pPainter->SetFont( aFont );
963 
964  m_pPainter->SetPosSizePixel( _rRect.TopLeft(), _rRect.GetSize() );
965  m_pPainter->Show();
968  m_pPainter->Hide();
970  }
971  else
972  {
973  m_pPainter->SetSizePixel( _rRect.GetSize() );
974  m_pPainter->Draw( &_rDev, _rRect.TopLeft(), DrawFlags::NONE );
975  }
976 }
977 
978 void DbCellControl::PaintFieldToCell( OutputDevice& _rDev, const tools::Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
979 {
980  m_pPainter->SetText( GetFormatText( _rxField, _rxFormatter ) );
981  PaintCell( _rDev, _rRect );
982 }
983 
984 
985 double DbCellControl::GetValue(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter) const
986 {
987  double fValue = 0;
988  if (m_rColumn.IsNumeric())
989  {
990  try
991  {
992  fValue = _rxField->getDouble();
993  }
994  catch(const Exception&) { }
995  }
996  else
997  {
998  bool bSuccess = false;
999  try
1000  {
1001  fValue = _rxField->getDouble();
1002  bSuccess = true;
1003  }
1004  catch(const Exception&) { }
1005  if (!bSuccess)
1006  {
1007  try
1008  {
1009  fValue = xFormatter->convertStringToNumber(m_rColumn.GetKey(), _rxField->getString());
1010  }
1011  catch(const Exception&) { }
1012  }
1013  }
1014  return fValue;
1015 }
1016 
1017 
1019 {
1021 }
1022 
1023 // CellModels
1024 
1026  :DbCellControl( _rColumn )
1027 {
1029 }
1030 
1031 
1032 void DbLimitedLengthField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1033 {
1034  DBG_ASSERT( m_pWindow, "DbLimitedLengthField::implAdjustGenericFieldSetting: not to be called without window!" );
1035  DBG_ASSERT( _rxModel.is(), "DbLimitedLengthField::implAdjustGenericFieldSetting: invalid model!" );
1036  if ( m_pWindow && _rxModel.is() )
1037  {
1038  sal_Int16 nMaxLen = 0;
1039  _rxModel->getPropertyValue( FM_PROP_MAXTEXTLEN ) >>= nMaxLen;
1040  implSetMaxTextLen( nMaxLen );
1041  }
1042 }
1043 
1045 {
1046  dynamic_cast<EditControlBase&>(*m_pWindow).get_widget().set_max_length(nMaxLen);
1047  if (m_pPainter)
1048  dynamic_cast<EditControlBase&>(*m_pPainter).get_widget().set_max_length(nMaxLen);
1049 }
1050 
1052  :DbLimitedLengthField(_rColumn)
1053  ,m_bIsSimpleEdit( true )
1054 {
1055 }
1056 
1058 {
1059  m_pPainterImplementation.reset();
1060  m_pEdit.reset();
1061 }
1062 
1063 void DbTextField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
1064 {
1065  sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1066 
1067  Reference< XPropertySet > xModel( m_rColumn.getModel() );
1068 
1069  WinBits nStyle = WB_LEFT;
1070  switch (nAlignment)
1071  {
1072  case awt::TextAlign::RIGHT:
1073  nStyle = WB_RIGHT;
1074  break;
1075 
1076  case awt::TextAlign::CENTER:
1077  nStyle = WB_CENTER;
1078  break;
1079  }
1080 
1081  // is this a multi-line field?
1082  bool bIsMultiLine = false;
1083  try
1084  {
1085  if ( xModel.is() )
1086  {
1087  OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MULTILINE ) >>= bIsMultiLine );
1088  }
1089  }
1090  catch( const Exception& )
1091  {
1092  DBG_UNHANDLED_EXCEPTION("svx");
1093  OSL_FAIL( "DbTextField::Init: caught an exception while determining the multi-line capabilities!" );
1094  }
1095 
1096  m_bIsSimpleEdit = !bIsMultiLine;
1097  if ( bIsMultiLine )
1098  {
1099  m_pWindow = VclPtr<MultiLineTextCell>::Create( &rParent, nStyle );
1100  m_pEdit.reset(new MultiLineEditImplementation( *static_cast< MultiLineTextCell* >( m_pWindow.get() ) ));
1101 
1102  m_pPainter = VclPtr<MultiLineTextCell>::Create( &rParent, nStyle );
1103  m_pPainterImplementation.reset(new MultiLineEditImplementation( *static_cast< MultiLineTextCell* >( m_pPainter.get() ) ));
1104  }
1105  else
1106  {
1107  auto xEditControl = VclPtr<EditControl>::Create(&rParent);
1108  auto xEditPainter = VclPtr<EditControl>::Create(&rParent);
1109 
1110  switch (nAlignment)
1111  {
1112  case awt::TextAlign::RIGHT:
1113  xEditControl->get_widget().set_alignment(TxtAlign::Right);
1114  xEditPainter->get_widget().set_alignment(TxtAlign::Right);
1115  break;
1116  case awt::TextAlign::CENTER:
1117  xEditControl->get_widget().set_alignment(TxtAlign::Center);
1118  xEditPainter->get_widget().set_alignment(TxtAlign::Center);
1119  break;
1120  }
1121 
1122  m_pWindow = xEditControl;
1123  m_pEdit.reset(new EntryImplementation(*xEditControl));
1124 
1125  m_pPainter = xEditPainter;
1126  m_pPainterImplementation.reset(new EntryImplementation(*xEditPainter));
1127  }
1128 
1129  if ( WB_LEFT == nStyle )
1130  {
1131  // this is so that when getting the focus, the selection is oriented left-to-right
1132  AllSettings aSettings = m_pWindow->GetSettings();
1133  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1134  aStyleSettings.SetSelectionOptions(
1135  aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
1136  aSettings.SetStyleSettings(aStyleSettings);
1137  m_pWindow->SetSettings(aSettings);
1138  }
1139 
1141 
1142  DbLimitedLengthField::Init( rParent, xCursor );
1143 }
1144 
1145 
1147 {
1148  return new EditCellController( m_pEdit.get() );
1149 }
1150 
1151 
1152 void DbTextField::PaintFieldToCell( OutputDevice& _rDev, const tools::Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1153 {
1155  m_pPainterImplementation->SetText( GetFormatText( _rxField, _rxFormatter ) );
1156 
1157  DbLimitedLengthField::PaintFieldToCell( _rDev, _rRect, _rxField, _rxFormatter );
1158 }
1159 
1160 
1161 OUString DbTextField::GetFormatText(const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, Color** /*ppColor*/)
1162 {
1163  if (!_rxField.is())
1164  return OUString();
1165 
1166  const css::uno::Reference<css::beans::XPropertySet> xPS(_rxField, UNO_QUERY);
1167  FormattedColumnValue fmter( xFormatter, xPS );
1168 
1169  try
1170  {
1171  return fmter.getFormattedValue();
1172  }
1173  catch( const Exception& )
1174  {
1175  DBG_UNHANDLED_EXCEPTION("svx");
1176  }
1177  return OUString();
1178 
1179 }
1180 
1181 
1182 void DbTextField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
1183 {
1184  m_pEdit->SetText( GetFormatText( _rxField, xFormatter ) );
1185  m_pEdit->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1186 }
1187 
1188 
1189 void DbTextField::updateFromModel( Reference< XPropertySet > _rxModel )
1190 {
1191  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTextField::updateFromModel: invalid call!" );
1192 
1193  OUString sText;
1194  _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
1195 
1196  sal_Int32 nMaxTextLen = m_pEdit->GetMaxTextLen();
1197  if ( EDIT_NOLIMIT != nMaxTextLen && sText.getLength() > nMaxTextLen )
1198  {
1199  sal_Int32 nDiff = sText.getLength() - nMaxTextLen;
1200  sText = sText.replaceAt(sText.getLength() - nDiff,nDiff, OUString());
1201  }
1202 
1203 
1204  m_pEdit->SetText( sText );
1205  m_pEdit->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1206 }
1207 
1208 
1210 {
1211  OUString aText( m_pEdit->GetText( getModelLineEndSetting( m_rColumn.getModel() ) ) );
1212  // we have to check if the length before we can decide if the value was modified
1213  sal_Int32 nMaxTextLen = m_pEdit->GetMaxTextLen();
1214  if ( EDIT_NOLIMIT != nMaxTextLen )
1215  {
1216  OUString sOldValue;
1217  m_rColumn.getModel()->getPropertyValue( FM_PROP_TEXT ) >>= sOldValue;
1218  // if the new value didn't change we must set the old long value again
1219  if ( sOldValue.getLength() > nMaxTextLen && sOldValue.compareTo(aText,nMaxTextLen) == 0 )
1220  aText = sOldValue;
1221  }
1222  m_rColumn.getModel()->setPropertyValue( FM_PROP_TEXT, makeAny( aText ) );
1223  return true;
1224 }
1225 
1226 
1228 {
1229  if ( m_pEdit )
1230  m_pEdit->SetMaxTextLen( _nMaxLen );
1232  m_pPainterImplementation->SetMaxTextLen( _nMaxLen );
1233 }
1234 
1236  :DbLimitedLengthField(_rColumn)
1237 {
1238  // if our model's format key changes we want to propagate the new value to our windows
1240 }
1241 
1243 {
1244 }
1245 
1246 void DbFormattedField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
1247 {
1248  sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1249 
1250  Reference< css::beans::XPropertySet > xUnoModel = m_rColumn.getModel();
1251 
1252  auto xEditControl = VclPtr<FormattedControl>::Create(&rParent);
1253  auto xEditPainter = VclPtr<FormattedControl>::Create(&rParent);
1254 
1255  weld::EntryFormatter& rControlFormatter = xEditControl->get_formatter();
1256  weld::EntryFormatter& rPainterFormatter = xEditPainter->get_formatter();
1257 
1258  m_pWindow = xEditControl.get();
1259  m_pPainter = xEditPainter.get();
1260 
1261  switch (nAlignment)
1262  {
1263  case awt::TextAlign::RIGHT:
1264  xEditControl->get_widget().set_alignment(TxtAlign::Right);
1265  xEditPainter->get_widget().set_alignment(TxtAlign::Right);
1266  break;
1267  case awt::TextAlign::CENTER:
1268  xEditControl->get_widget().set_alignment(TxtAlign::Center);
1269  xEditPainter->get_widget().set_alignment(TxtAlign::Center);
1270  break;
1271  default:
1272  {
1273  // Everything just so that the selection goes from right to left when getting focus
1274  SelectionOptions eOptions = rControlFormatter.GetEntrySelectionOptions();
1275  rControlFormatter.SetEntrySelectionOptions(eOptions | SelectionOptions::ShowFirst);
1276  break;
1277  }
1278  }
1279 
1280  implAdjustGenericFieldSetting( xUnoModel );
1281 
1282  rControlFormatter.SetStrictFormat(false);
1283  rPainterFormatter.SetStrictFormat(false);
1284  // if one allows any formatting, one cannot make an entry check anyway
1285  // (the FormattedField does not support that anyway, only derived classes)
1286 
1287  // get the formatter from the uno model
1288  // (I could theoretically also go via the css::util::NumberFormatter, which the cursor would
1289  // surely give me. The problem is that I can not really rely on the fact that the two
1290  // formatters are the same. Clean is the whole thing if I go via the UNO model.)
1291  sal_Int32 nFormatKey = -1;
1292 
1293  // let's see if the model has one ...
1294  DBG_ASSERT(::comphelper::hasProperty(FM_PROP_FORMATSSUPPLIER, xUnoModel), "DbFormattedField::Init : invalid UNO model !");
1295  Any aSupplier( xUnoModel->getPropertyValue(FM_PROP_FORMATSSUPPLIER));
1296  if (aSupplier.hasValue())
1297  {
1298  m_xSupplier.set(aSupplier, css::uno::UNO_QUERY);
1299  if (m_xSupplier.is())
1300  {
1301  // if we take the supplier from the model, then also the key
1302  Any aFmtKey( xUnoModel->getPropertyValue(FM_PROP_FORMATKEY));
1303  if (aFmtKey.hasValue())
1304  {
1305  DBG_ASSERT(aFmtKey.getValueType().getTypeClass() == TypeClass_LONG, "DbFormattedField::Init : invalid format key property (no sal_Int32) !");
1306  nFormatKey = ::comphelper::getINT32(aFmtKey);
1307  }
1308  else
1309  {
1310  SAL_INFO("svx.fmcomp", "DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !");
1311  // the OFormattedModel which we usually are working with ensures that the model has a format key
1312  // as soon as the form is loaded. Unfortunally this method here is called from within loaded, too.
1313  // So if our LoadListener is called before the LoadListener of the model, this "else case" is
1314  // allowed.
1315  // Of course our property listener for the FormatKey property will notify us if the prop is changed,
1316  // so this here isn't really bad...
1317  nFormatKey = 0;
1318  }
1319  }
1320  }
1321 
1322  // No? Maybe the css::form::component::Form behind the cursor?
1323  if (!m_xSupplier.is())
1324  {
1325  if (xCursor.is())
1326  { // If we take the formatter from the cursor, then also the key from the field to which we are bound
1328 
1329  if (m_rColumn.GetField().is())
1330  nFormatKey = ::comphelper::getINT32(m_rColumn.GetField()->getPropertyValue(FM_PROP_FORMATKEY));
1331  }
1332  }
1333 
1334  SvNumberFormatter* pFormatterUsed = nullptr;
1335  if (m_xSupplier.is())
1336  {
1337  SvNumberFormatsSupplierObj* pImplmentation = comphelper::getUnoTunnelImplementation<SvNumberFormatsSupplierObj>(m_xSupplier);
1338  if (pImplmentation)
1339  pFormatterUsed = pImplmentation->GetNumberFormatter();
1340  else
1341  // Everything is invalid: the supplier is of the wrong type, then we can not
1342  // rely on a standard formatter to know the (possibly non-standard) key.
1343  nFormatKey = -1;
1344  }
1345 
1346  // a standard formatter ...
1347  if (pFormatterUsed == nullptr)
1348  {
1349  pFormatterUsed = rControlFormatter.StandardFormatter();
1350  DBG_ASSERT(pFormatterUsed != nullptr, "DbFormattedField::Init : no standard formatter given by the numeric field !");
1351  }
1352  // ... and a standard key
1353  if (nFormatKey == -1)
1354  nFormatKey = 0;
1355 
1356  rControlFormatter.SetFormatter(pFormatterUsed);
1357  rPainterFormatter.SetFormatter(pFormatterUsed);
1358 
1359  rControlFormatter.SetFormatKey(nFormatKey);
1360  rPainterFormatter.SetFormatKey(nFormatKey);
1361 
1362  rControlFormatter.TreatAsNumber(m_rColumn.IsNumeric());
1363  rPainterFormatter.TreatAsNumber(m_rColumn.IsNumeric());
1364 
1365  // min and max values
1366  if (m_rColumn.IsNumeric())
1367  {
1368  bool bClearMin = true;
1370  {
1371  Any aMin( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MIN));
1372  if (aMin.getValueType().getTypeClass() != TypeClass_VOID)
1373  {
1374  DBG_ASSERT(aMin.getValueType().getTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid min value !");
1375  double dMin = ::comphelper::getDouble(aMin);
1376  rControlFormatter.SetMinValue(dMin);
1377  rPainterFormatter.SetMinValue(dMin);
1378  bClearMin = false;
1379  }
1380  }
1381  if (bClearMin)
1382  {
1383  rControlFormatter.ClearMinValue();
1384  rPainterFormatter.ClearMinValue();
1385  }
1386  bool bClearMax = true;
1388  {
1389  Any aMax(xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MAX));
1390  if (aMax.getValueType().getTypeClass() != TypeClass_VOID)
1391  {
1392  DBG_ASSERT(aMax.getValueType().getTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid max value !");
1393  double dMax = ::comphelper::getDouble(aMax);
1394  rControlFormatter.SetMaxValue(dMax);
1395  rPainterFormatter.SetMaxValue(dMax);
1396  bClearMax = false;
1397  }
1398  }
1399  if (bClearMax)
1400  {
1401  rControlFormatter.ClearMaxValue();
1402  rPainterFormatter.ClearMaxValue();
1403  }
1404  }
1405 
1406  // the default value
1407  Any aDefault( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_DEFAULT));
1408  if (aDefault.hasValue())
1409  { // the thing can be a double or a string
1410  switch (aDefault.getValueType().getTypeClass())
1411  {
1412  case TypeClass_DOUBLE:
1413  if (m_rColumn.IsNumeric())
1414  {
1415  rControlFormatter.SetDefaultValue(::comphelper::getDouble(aDefault));
1416  rPainterFormatter.SetDefaultValue(::comphelper::getDouble(aDefault));
1417  }
1418  else
1419  {
1420  OUString sConverted;
1421  Color* pDummy;
1422  pFormatterUsed->GetOutputString(::comphelper::getDouble(aDefault), 0, sConverted, &pDummy);
1423  rControlFormatter.SetDefaultText(sConverted);
1424  rPainterFormatter.SetDefaultText(sConverted);
1425  }
1426  break;
1427  case TypeClass_STRING:
1428  {
1429  OUString sDefault( ::comphelper::getString(aDefault) );
1430  if (m_rColumn.IsNumeric())
1431  {
1432  double dVal;
1433  sal_uInt32 nTestFormat(0);
1434  if (pFormatterUsed->IsNumberFormat(sDefault, nTestFormat, dVal))
1435  {
1436  rControlFormatter.SetDefaultValue(dVal);
1437  rPainterFormatter.SetDefaultValue(dVal);
1438  }
1439  }
1440  else
1441  {
1442  rControlFormatter.SetDefaultText(sDefault);
1443  rPainterFormatter.SetDefaultText(sDefault);
1444  }
1445  }
1446  break;
1447  default:
1448  OSL_FAIL( "DbFormattedField::Init: unexpected value type!" );
1449  break;
1450  }
1451  }
1452  DbLimitedLengthField::Init( rParent, xCursor );
1453 }
1454 
1456 {
1457  return new ::svt::FormattedFieldCellController(static_cast<FormattedControl*>(m_pWindow.get()));
1458 }
1459 
1460 void DbFormattedField::_propertyChanged( const PropertyChangeEvent& _rEvent )
1461 {
1462  if (_rEvent.PropertyName == FM_PROP_FORMATKEY )
1463  {
1464  sal_Int32 nNewKey = _rEvent.NewValue.hasValue() ? ::comphelper::getINT32(_rEvent.NewValue) : 0;
1465 
1466  DBG_ASSERT(m_pWindow && m_pPainter, "DbFormattedField::_propertyChanged : where are my windows ?");
1467  if (m_pWindow)
1468  static_cast<FormattedControl*>(m_pWindow.get())->get_formatter().SetFormatKey(nNewKey);
1469  if (m_pPainter)
1470  static_cast<FormattedControl*>(m_pPainter.get())->get_formatter().SetFormatKey(nNewKey);
1471  }
1472  else
1473  {
1475  }
1476 }
1477 
1478 OUString DbFormattedField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** ppColor)
1479 {
1480  // no color specification by default
1481  if (ppColor != nullptr)
1482  *ppColor = nullptr;
1483 
1484  // NULL value -> empty text
1485  if (!_rxField.is())
1486  return OUString();
1487 
1488  FormattedControl* pControl = static_cast<FormattedControl*>(m_pPainter.get());
1489  weld::EntryFormatter& rPainterFormatter = pControl->get_formatter();
1490 
1491  OUString aText;
1492  try
1493  {
1494  if (m_rColumn.IsNumeric())
1495  {
1496  // The IsNumeric at the column says nothing about the class of the used format, but
1497  // about the class of the field bound to the column. So when you bind a FormattedField
1498  // column to a double field and format it as text, m_rColumn.IsNumeric() returns
1499  // sal_True. So that simply means that I can query the contents of the variant using
1500  // getDouble, and then I can leave the rest (the formatting) to the FormattedField.
1501  double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1502  if (_rxField->wasNull())
1503  return aText;
1504  rPainterFormatter.SetValue(dValue);
1505  }
1506  else
1507  {
1508  // Here I can not work with a double, since the field can not provide it to me.
1509  // So simply bind the text from the css::util::NumberFormatter to the correct css::form::component::Form.
1510  aText = _rxField->getString();
1511  if (_rxField->wasNull())
1512  return aText;
1513  rPainterFormatter.SetTextFormatted(aText);
1514  }
1515  }
1516  catch( const Exception& )
1517  {
1518  DBG_UNHANDLED_EXCEPTION("svx");
1519  }
1520 
1521  aText = pControl->get_widget().get_text();
1522  if (ppColor != nullptr)
1523  *ppColor = rPainterFormatter.GetLastOutputColor();
1524 
1525  return aText;
1526 }
1527 
1528 void DbFormattedField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1529 {
1530  try
1531  {
1532  FormattedControl* pEditControl = static_cast<FormattedControl*>(m_pWindow.get());
1533  weld::Entry& rEntry = pEditControl->get_widget();
1534  weld::EntryFormatter& rEditFormatter = pEditControl->get_formatter();
1535 
1536  if (!_rxField.is())
1537  {
1538  // NULL value -> empty text
1539  rEntry.set_text(OUString());
1540  }
1541  else if (m_rColumn.IsNumeric())
1542  {
1543  // The IsNumeric at the column says nothing about the class of the used format, but
1544  // about the class of the field bound to the column. So when you bind a FormattedField
1545  // column to a double field and format it as text, m_rColumn.IsNumeric() returns
1546  // sal_True. So that simply means that I can query the contents of the variant using
1547  // getDouble, and then I can leave the rest (the formatting) to the FormattedField.
1548  double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1549  if (_rxField->wasNull())
1550  rEntry.set_text(OUString());
1551  else
1552  rEditFormatter.SetValue(dValue);
1553  }
1554  else
1555  {
1556  // Here I can not work with a double, since the field can not provide it to me.
1557  // So simply bind the text from the css::util::NumberFormatter to the correct css::form::component::Form.
1558  OUString sText( _rxField->getString());
1559 
1560  rEditFormatter.SetTextFormatted( sText );
1561  rEntry.select_region(0, -1);
1562  }
1563  }
1564  catch( const Exception& )
1565  {
1566  DBG_UNHANDLED_EXCEPTION("svx");
1567  }
1568 }
1569 
1570 void DbFormattedField::updateFromModel( Reference< XPropertySet > _rxModel )
1571 {
1572  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFormattedField::updateFromModel: invalid call!" );
1573 
1574  FormattedControl* pEditControl = static_cast<FormattedControl*>(m_pWindow.get());
1575  weld::Entry& rEntry = pEditControl->get_widget();
1576  weld::EntryFormatter& rEditFormatter = pEditControl->get_formatter();
1577 
1578  OUString sText;
1579  Any aValue = _rxModel->getPropertyValue( FM_PROP_EFFECTIVE_VALUE );
1580  if ( !aValue.hasValue() || (aValue >>= sText) )
1581  {
1582  // our effective value is transferred as string
1583  rEditFormatter.SetTextFormatted( sText );
1584  rEntry.select_region(0, -1);
1585  }
1586  else
1587  {
1588  double dValue = 0;
1589  aValue >>= dValue;
1590  rEditFormatter.SetValue(dValue);
1591  }
1592 }
1593 
1595 {
1596  Any aNewVal;
1597 
1598  FormattedControl* pEditControl = static_cast<FormattedControl*>(m_pWindow.get());
1599  weld::Entry& rEntry = pEditControl->get_widget();
1600  weld::EntryFormatter& rEditFormatter = pEditControl->get_formatter();
1601 
1602  if (m_rColumn.IsNumeric())
1603  {
1604  if (!rEntry.get_text().isEmpty())
1605  aNewVal <<= rEditFormatter.GetValue();
1606  // an empty string is passed on as void by default, to start with
1607  }
1608  else
1609  aNewVal <<= rEditFormatter.GetTextValue();
1610 
1611  m_rColumn.getModel()->setPropertyValue(FM_PROP_EFFECTIVE_VALUE, aNewVal);
1612  return true;
1613 }
1614 
1616  :DbCellControl( _rColumn )
1617 {
1618  setAlignedController( false );
1619 }
1620 
1621 namespace
1622 {
1623  void setCheckBoxStyle( vcl::Window* _pWindow, bool bMono )
1624  {
1625  AllSettings aSettings = _pWindow->GetSettings();
1626  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1627  if( bMono )
1628  aStyleSettings.SetOptions( aStyleSettings.GetOptions() | StyleSettingsOptions::Mono );
1629  else
1630  aStyleSettings.SetOptions( aStyleSettings.GetOptions() & (~StyleSettingsOptions::Mono) );
1631  aSettings.SetStyleSettings( aStyleSettings );
1632  _pWindow->SetSettings( aSettings );
1633  }
1634 }
1635 
1636 
1637 void DbCheckBox::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor )
1638 {
1639  setTransparent( true );
1640 
1643 
1644  m_pWindow->SetPaintTransparent( true );
1646 
1648 
1649  try
1650  {
1651  Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW );
1652 
1653  sal_Int16 nStyle = awt::VisualEffect::LOOK3D;
1654  OSL_VERIFY( xModel->getPropertyValue( FM_PROP_VISUALEFFECT ) >>= nStyle );
1655 
1656  setCheckBoxStyle( m_pWindow, nStyle == awt::VisualEffect::FLAT );
1657  setCheckBoxStyle( m_pPainter, nStyle == awt::VisualEffect::FLAT );
1658 
1659  bool bTristate = true;
1660  OSL_VERIFY( xModel->getPropertyValue( FM_PROP_TRISTATE ) >>= bTristate );
1661  static_cast< CheckBoxControl* >( m_pWindow.get() )->GetBox().EnableTriState( bTristate );
1662  static_cast< CheckBoxControl* >( m_pPainter.get() )->GetBox().EnableTriState( bTristate );
1663  }
1664  catch( const Exception& )
1665  {
1666  DBG_UNHANDLED_EXCEPTION("svx");
1667  }
1668 
1669  DbCellControl::Init( rParent, xCursor );
1670 }
1671 
1672 
1674 {
1675  return new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
1676 }
1677 
1678 static void lcl_setCheckBoxState( const Reference< css::sdb::XColumn >& _rxField,
1679  CheckBoxControl* _pCheckBoxControl )
1680 {
1681  TriState eState = TRISTATE_INDET;
1682  if (_rxField.is())
1683  {
1684  try
1685  {
1686  bool bValue = _rxField->getBoolean();
1687  if (!_rxField->wasNull())
1688  eState = bValue ? TRISTATE_TRUE : TRISTATE_FALSE;
1689  }
1690  catch( const Exception& )
1691  {
1692  DBG_UNHANDLED_EXCEPTION("svx");
1693  }
1694  }
1695  _pCheckBoxControl->GetBox().SetState(eState);
1696 }
1697 
1698 
1699 void DbCheckBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1700 {
1701  lcl_setCheckBoxState( _rxField, static_cast<CheckBoxControl*>(m_pWindow.get()) );
1702 }
1703 
1704 
1706  const Reference< css::sdb::XColumn >& _rxField,
1707  const Reference< XNumberFormatter >& xFormatter)
1708 {
1709  lcl_setCheckBoxState( _rxField, static_cast<CheckBoxControl*>(m_pPainter.get()) );
1710  DbCellControl::PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
1711 }
1712 
1713 
1714 void DbCheckBox::updateFromModel( Reference< XPropertySet > _rxModel )
1715 {
1716  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCheckBox::updateFromModel: invalid call!" );
1717 
1718  sal_Int16 nState = TRISTATE_INDET;
1719  _rxModel->getPropertyValue( FM_PROP_STATE ) >>= nState;
1720  static_cast< CheckBoxControl* >( m_pWindow.get() )->GetBox().SetState( static_cast< TriState >( nState ) );
1721 }
1722 
1723 
1725 {
1726  m_rColumn.getModel()->setPropertyValue( FM_PROP_STATE,
1727  makeAny( static_cast<sal_Int16>( static_cast< CheckBoxControl* >( m_pWindow.get() )->GetBox().GetState() ) ) );
1728  return true;
1729 }
1730 
1731 
1732 OUString DbCheckBox::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
1733 {
1734  return OUString();
1735 }
1736 
1738  :DbCellControl( _rColumn )
1739  ,m_xContext( _rContext )
1740 {
1744 }
1745 
1746 
1747 void DbPatternField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1748 {
1749  DBG_ASSERT( m_pWindow, "DbPatternField::implAdjustGenericFieldSetting: not to be called without window!" );
1750  DBG_ASSERT( _rxModel.is(), "DbPatternField::implAdjustGenericFieldSetting: invalid model!" );
1751  if ( !m_pWindow || !_rxModel.is() )
1752  return;
1753 
1754  OUString aLitMask;
1755  OUString aEditMask;
1756  bool bStrict = false;
1757 
1758  _rxModel->getPropertyValue( FM_PROP_LITERALMASK ) >>= aLitMask;
1759  _rxModel->getPropertyValue( FM_PROP_EDITMASK ) >>= aEditMask;
1760  _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) >>= bStrict;
1761 
1762  OString aAsciiEditMask(OUStringToOString(aEditMask, RTL_TEXTENCODING_ASCII_US));
1763 
1764  static_cast< PatternField* >( m_pWindow.get() )->SetMask( aAsciiEditMask, aLitMask );
1765  static_cast< PatternField* >( m_pPainter.get() )->SetMask( aAsciiEditMask, aLitMask );
1766  static_cast< PatternField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
1767  static_cast< PatternField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
1768 }
1769 
1770 
1771 void DbPatternField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
1772 {
1774 
1775  m_pWindow = VclPtr<PatternField>::Create( &rParent, 0 );
1776  m_pPainter= VclPtr<PatternField>::Create( &rParent, 0 );
1777 
1778  Reference< XPropertySet > xModel( m_rColumn.getModel() );
1780 
1781  DbCellControl::Init( rParent, xCursor );
1782 }
1783 
1784 
1786 {
1787  return new SpinCellController( static_cast< PatternField* >( m_pWindow.get() ) );
1788 }
1789 
1790 
1791 OUString DbPatternField::impl_formatText( const OUString& _rText )
1792 {
1793  m_pPainter->SetText( _rText );
1794  static_cast< PatternField* >( m_pPainter.get() )->ReformatAll();
1795  return m_pPainter->GetText();
1796 }
1797 
1798 
1799 OUString DbPatternField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
1800 {
1801  bool bIsForPaint = _rxField != m_rColumn.GetField();
1802  ::std::unique_ptr< FormattedColumnValue >& rpFormatter = bIsForPaint ? m_pPaintFormatter : m_pValueFormatter;
1803 
1804  if (!rpFormatter)
1805  {
1806  rpFormatter = std::make_unique< FormattedColumnValue> (
1807  m_xContext, getCursor(), Reference< XPropertySet >( _rxField, UNO_QUERY ) );
1808  OSL_ENSURE(rpFormatter, "DbPatternField::Init: no value formatter!");
1809  }
1810  else
1811  OSL_ENSURE( rpFormatter->getColumn() == _rxField, "DbPatternField::GetFormatText: my value formatter is working for another field ...!" );
1812  // re-creating the value formatter here every time would be quite expensive ...
1813 
1814  OUString sText;
1815  if (rpFormatter)
1816  sText = rpFormatter->getFormattedValue();
1817 
1818  return impl_formatText( sText );
1819 }
1820 
1821 
1822 void DbPatternField::UpdateFromField( const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1823 {
1824  static_cast< Edit* >( m_pWindow.get() )->SetText( GetFormatText( _rxField, _rxFormatter ) );
1825  static_cast< Edit* >( m_pWindow.get() )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1826 }
1827 
1828 
1829 void DbPatternField::updateFromModel( Reference< XPropertySet > _rxModel )
1830 {
1831  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbPatternField::updateFromModel: invalid call!" );
1832 
1833  OUString sText;
1834  _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
1835 
1836  static_cast< Edit* >( m_pWindow.get() )->SetText( impl_formatText( sText ) );
1837  static_cast< Edit* >( m_pWindow.get() )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1838 }
1839 
1840 
1842 {
1843  OUString aText(m_pWindow->GetText());
1844  m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, makeAny(aText));
1845  return true;
1846 }
1847 
1848 DbSpinField::DbSpinField( DbGridColumn& _rColumn, sal_Int16 _nStandardAlign )
1849  :DbCellControl( _rColumn )
1850  ,m_nStandardAlign( _nStandardAlign )
1851 {
1852 }
1853 
1854 
1855 void DbSpinField::Init( vcl::Window& _rParent, const Reference< XRowSet >& _rxCursor )
1856 {
1858 
1859  Reference< XPropertySet > xModel( m_rColumn.getModel() );
1860 
1861  // determine the WinBits for the field
1862  WinBits nFieldStyle = 0;
1863  if ( ::comphelper::getBOOL( xModel->getPropertyValue( FM_PROP_SPIN ) ) )
1864  nFieldStyle = WB_REPEAT | WB_SPIN;
1865  // create the fields
1866  m_pWindow = createField( &_rParent, nFieldStyle, xModel );
1867  m_pPainter = createField( &_rParent, nFieldStyle, xModel );
1868 
1869  // adjust all other settings which depend on the property values
1871 
1872  // call the base class
1873  DbCellControl::Init( _rParent, _rxCursor );
1874 }
1875 
1876 
1878 {
1879  return new SpinCellController( static_cast< SpinField* >( m_pWindow.get() ) );
1880 }
1881 
1883  :DbSpinField( _rColumn )
1884 {
1891 }
1892 
1893 
1894 void DbNumericField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1895 {
1896  DBG_ASSERT( m_pWindow, "DbNumericField::implAdjustGenericFieldSetting: not to be called without window!" );
1897  DBG_ASSERT( _rxModel.is(), "DbNumericField::implAdjustGenericFieldSetting: invalid model!" );
1898  if ( !m_pWindow || !_rxModel.is() )
1899  return;
1900 
1901  sal_Int32 nMin = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) ));
1902  sal_Int32 nMax = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) ));
1903  sal_Int32 nStep = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) ));
1904  bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
1905  sal_Int16 nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
1906  bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
1907 
1908  Formatter* pEditFormatter = static_cast<DoubleNumericField*>(m_pWindow.get())->GetFormatter();
1909  pEditFormatter->SetMinValue(nMin);
1910  pEditFormatter->SetMaxValue(nMax);
1911  pEditFormatter->SetSpinSize(nStep);
1912  pEditFormatter->SetStrictFormat(bStrict);
1913 
1914  Formatter* pPaintFormatter = static_cast<DoubleNumericField*>(m_pPainter.get())->GetFormatter();
1915  pPaintFormatter->SetMinValue(nMin);
1916  pPaintFormatter->SetMaxValue(nMax);
1917  pPaintFormatter->SetStrictFormat(bStrict);
1918 
1919  // give a formatter to the field and the painter;
1920  // test first if I can get from the service behind a connection
1921  Reference< css::util::XNumberFormatsSupplier > xSupplier;
1922  Reference< XRowSet > xForm;
1923  if ( m_rColumn.GetParent().getDataSource() )
1924  xForm.set( Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY );
1925  if ( xForm.is() )
1926  xSupplier = getNumberFormats( getConnection( xForm ), true );
1927  SvNumberFormatter* pFormatterUsed = nullptr;
1928  if ( xSupplier.is() )
1929  {
1930  SvNumberFormatsSupplierObj* pImplmentation = comphelper::getUnoTunnelImplementation<SvNumberFormatsSupplierObj>( xSupplier );
1931  pFormatterUsed = pImplmentation ? pImplmentation->GetNumberFormatter() : nullptr;
1932  }
1933  if ( nullptr == pFormatterUsed )
1934  { // the cursor didn't lead to success -> standard
1935  pFormatterUsed = pEditFormatter->StandardFormatter();
1936  DBG_ASSERT( pFormatterUsed != nullptr, "DbNumericField::implAdjustGenericFieldSetting: no standard formatter given by the numeric field !" );
1937  }
1938  pEditFormatter->SetFormatter( pFormatterUsed );
1939  pPaintFormatter->SetFormatter( pFormatterUsed );
1940 
1941  // and then generate a format which has the desired length after the decimal point, etc.
1943  OUString sFormatString = pFormatterUsed->GenerateFormat(0, aAppLanguage, bThousand, false, nScale);
1944 
1945  pEditFormatter->SetFormat( sFormatString, aAppLanguage );
1946  pPaintFormatter->SetFormat( sFormatString, aAppLanguage );
1947 }
1948 
1949 
1950 VclPtr<SpinField> DbNumericField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/ )
1951 {
1952  return VclPtr<DoubleNumericField>::Create( _pParent, _nFieldStyle );
1953 }
1954 
1955 namespace
1956 {
1957 
1958  OUString lcl_setFormattedNumeric_nothrow( DoubleNumericField& _rField, const DbCellControl& _rControl,
1959  const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1960  {
1961  OUString sValue;
1962  if ( _rxField.is() )
1963  {
1964  try
1965  {
1966  double fValue = _rControl.GetValue( _rxField, _rxFormatter );
1967  if ( !_rxField->wasNull() )
1968  {
1969  _rField.GetFormatter()->SetValue( fValue );
1970  sValue = _rField.GetText();
1971  }
1972  }
1973  catch( const Exception& )
1974  {
1975  DBG_UNHANDLED_EXCEPTION("svx");
1976  }
1977  }
1978  return sValue;
1979  }
1980 }
1981 
1982 OUString DbNumericField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter, Color** /*ppColor*/)
1983 {
1984  return lcl_setFormattedNumeric_nothrow(dynamic_cast<DoubleNumericField&>(*m_pPainter), *this, _rxField, _rxFormatter);
1985 }
1986 
1987 void DbNumericField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter)
1988 {
1989  lcl_setFormattedNumeric_nothrow(dynamic_cast<DoubleNumericField&>(*m_pWindow), *this, _rxField, _rxFormatter);
1990 }
1991 
1992 void DbNumericField::updateFromModel( Reference< XPropertySet > _rxModel )
1993 {
1994  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbNumericField::updateFromModel: invalid call!" );
1995 
1996  double dValue = 0;
1997  if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
1998  {
1999  Formatter* pFormatter = static_cast<DoubleNumericField*>(m_pWindow.get())->GetFormatter();
2000  pFormatter->SetValue(dValue);
2001  }
2002  else
2003  m_pWindow->SetText( OUString() );
2004 }
2005 
2007 {
2008  OUString aText( m_pWindow->GetText());
2009  Any aVal;
2010 
2011  if (!aText.isEmpty()) // not empty
2012  {
2013  Formatter* pFormatter = static_cast<DoubleNumericField*>(m_pWindow.get())->GetFormatter();
2014  double fValue = pFormatter->GetValue();
2015  aVal <<= fValue;
2016  }
2017  m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2018  return true;
2019 }
2020 
2022  :DbSpinField( _rColumn )
2023  ,m_nScale( 0 )
2024 {
2032 }
2033 
2034 
2035 void DbCurrencyField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2036 {
2037  DBG_ASSERT( m_pWindow, "DbCurrencyField::implAdjustGenericFieldSetting: not to be called without window!" );
2038  DBG_ASSERT( _rxModel.is(), "DbCurrencyField::implAdjustGenericFieldSetting: invalid model!" );
2039  if ( !m_pWindow || !_rxModel.is() )
2040  return;
2041 
2042  m_nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
2043  double nMin = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) );
2044  double nMax = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) );
2045  double nStep = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) );
2046  bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2047  bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
2048  OUString aStr( getString( _rxModel->getPropertyValue(FM_PROP_CURRENCYSYMBOL ) ) );
2049 
2050  //fdo#42747 the min/max/first/last of vcl NumericFormatters needs to be
2051  //multiplied by the no of decimal places. See also
2052  //VclBuilder::mungeAdjustment
2053  int nMul = rtl_math_pow10Exp(1, m_nScale);
2054  nMin *= nMul;
2055  nMax *= nMul;
2056 
2057  static_cast< LongCurrencyField* >( m_pWindow.get() )->SetUseThousandSep( bThousand );
2058  static_cast< LongCurrencyField* >( m_pWindow.get() )->SetDecimalDigits( m_nScale );
2059  static_cast< LongCurrencyField* >( m_pWindow.get() )->SetCurrencySymbol( aStr );
2060  static_cast< LongCurrencyField* >( m_pWindow.get() )->SetFirst( nMin );
2061  static_cast< LongCurrencyField* >( m_pWindow.get() )->SetLast( nMax );
2062  static_cast< LongCurrencyField* >( m_pWindow.get() )->SetMin( nMin );
2063  static_cast< LongCurrencyField* >( m_pWindow.get() )->SetMax( nMax );
2064  static_cast< LongCurrencyField* >( m_pWindow.get() )->SetSpinSize( nStep );
2065  static_cast< LongCurrencyField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
2066 
2067  static_cast< LongCurrencyField* >( m_pPainter.get() )->SetUseThousandSep( bThousand );
2068  static_cast< LongCurrencyField* >( m_pPainter.get() )->SetDecimalDigits( m_nScale );
2069  static_cast< LongCurrencyField* >( m_pPainter.get() )->SetCurrencySymbol( aStr );
2070  static_cast< LongCurrencyField* >( m_pPainter.get() )->SetFirst( nMin );
2071  static_cast< LongCurrencyField* >( m_pPainter.get() )->SetLast( nMax );
2072  static_cast< LongCurrencyField* >( m_pPainter.get() )->SetMin( nMin );
2073  static_cast< LongCurrencyField* >( m_pPainter.get() )->SetMax( nMax );
2074  static_cast< LongCurrencyField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
2075 }
2076 
2077 
2078 VclPtr<SpinField> DbCurrencyField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/ )
2079 {
2080  return VclPtr<LongCurrencyField>::Create( _pParent, _nFieldStyle );
2081 }
2082 
2083 
2084 double DbCurrencyField::GetCurrency(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter) const
2085 {
2086  double fValue = GetValue(_rxField, xFormatter);
2087  if (m_nScale)
2088  {
2089  // SAL_INFO("svx",("double = %.64f ",fValue);
2090  fValue = ::rtl::math::pow10Exp(fValue, m_nScale);
2091  fValue = ::rtl::math::round(fValue);
2092  }
2093  return fValue;
2094 }
2095 
2096 namespace
2097 {
2098 
2099  OUString lcl_setFormattedCurrency_nothrow( LongCurrencyField& _rField, const DbCurrencyField& _rControl,
2100  const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
2101  {
2102  OUString sValue;
2103  if ( _rxField.is() )
2104  {
2105  try
2106  {
2107  double fValue = _rControl.GetCurrency( _rxField, _rxFormatter );
2108  if ( !_rxField->wasNull() )
2109  {
2110  _rField.SetValue( fValue );
2111  sValue = _rField.GetText();
2112  }
2113  }
2114  catch( const Exception& )
2115  {
2116  DBG_UNHANDLED_EXCEPTION("svx");
2117  }
2118  }
2119  return sValue;
2120  }
2121 }
2122 
2123 
2124 OUString DbCurrencyField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter, Color** /*ppColor*/)
2125 {
2126  return lcl_setFormattedCurrency_nothrow( dynamic_cast< LongCurrencyField& >( *m_pPainter ), *this, _rxField, _rxFormatter );
2127 }
2128 
2129 
2130 void DbCurrencyField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter)
2131 {
2132  lcl_setFormattedCurrency_nothrow( dynamic_cast< LongCurrencyField& >( *m_pWindow ), *this, _rxField, _rxFormatter );
2133 }
2134 
2135 
2136 void DbCurrencyField::updateFromModel( Reference< XPropertySet > _rxModel )
2137 {
2138  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCurrencyField::updateFromModel: invalid call!" );
2139 
2140  double dValue = 0;
2141  if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
2142  {
2143  if ( m_nScale )
2144  {
2145  dValue = ::rtl::math::pow10Exp( dValue, m_nScale );
2146  dValue = ::rtl::math::round(dValue);
2147  }
2148 
2149  static_cast< LongCurrencyField* >( m_pWindow.get() )->SetValue( dValue );
2150  }
2151  else
2152  m_pWindow->SetText( OUString() );
2153 }
2154 
2155 
2157 {
2158  OUString aText(m_pWindow->GetText());
2159  Any aVal;
2160  if (!aText.isEmpty()) // not empty
2161  {
2162  double fValue = static_cast<LongCurrencyField*>(m_pWindow.get())->GetValue();
2163  if (m_nScale)
2164  {
2165  fValue /= ::rtl::math::pow10Exp(1.0, m_nScale);
2166  }
2167  aVal <<= fValue;
2168  }
2169  m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2170  return true;
2171 }
2172 
2174  :DbSpinField( _rColumn )
2175 {
2181 }
2182 
2183 VclPtr<SpinField> DbDateField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& _rxModel )
2184 {
2185  // check if there is a DropDown property set to TRUE
2186  bool bDropDown = !hasProperty( FM_PROP_DROPDOWN, _rxModel )
2187  || getBOOL( _rxModel->getPropertyValue( FM_PROP_DROPDOWN ) );
2188  if ( bDropDown )
2189  _nFieldStyle |= WB_DROPDOWN;
2190 
2191  VclPtr<CalendarField> pField = VclPtr<CalendarField>::Create( _pParent, _nFieldStyle );
2192 
2193  pField->EnableToday();
2194  pField->EnableNone();
2195 
2196  return pField;
2197 }
2198 
2199 void DbDateField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2200 {
2201  DBG_ASSERT( m_pWindow, "DbDateField::implAdjustGenericFieldSetting: not to be called without window!" );
2202  DBG_ASSERT( _rxModel.is(), "DbDateField::implAdjustGenericFieldSetting: invalid model!" );
2203  if ( !m_pWindow || !_rxModel.is() )
2204  return;
2205 
2206  sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_DATEFORMAT ) );
2207  util::Date aMin;
2208  OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMIN ) >>= aMin );
2209  util::Date aMax;
2210  OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMAX ) >>= aMax );
2211  bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2212 
2213  Any aCentury = _rxModel->getPropertyValue( FM_PROP_DATE_SHOW_CENTURY );
2214  if ( aCentury.getValueType().getTypeClass() != TypeClass_VOID )
2215  {
2216  bool bShowDateCentury = getBOOL( aCentury );
2217 
2218  static_cast<DateField*>( m_pWindow.get() )->SetShowDateCentury( bShowDateCentury );
2219  static_cast<DateField*>( m_pPainter.get() )->SetShowDateCentury( bShowDateCentury );
2220  }
2221 
2222  static_cast< DateField* >( m_pWindow.get() )->SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) );
2223  static_cast< DateField* >( m_pWindow.get() )->SetMin( aMin );
2224  static_cast< DateField* >( m_pWindow.get() )->SetMax( aMax );
2225  static_cast< DateField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
2226  static_cast< DateField* >( m_pWindow.get() )->EnableEmptyFieldValue( true );
2227 
2228  static_cast< DateField* >( m_pPainter.get() )->SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) );
2229  static_cast< DateField* >( m_pPainter.get() )->SetMin( aMin );
2230  static_cast< DateField* >( m_pPainter.get() )->SetMax( aMax );
2231  static_cast< DateField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
2232  static_cast< DateField* >( m_pPainter.get() )->EnableEmptyFieldValue( true );
2233 }
2234 
2235 namespace
2236 {
2237 
2238  OUString lcl_setFormattedDate_nothrow( DateField& _rField, const Reference< XColumn >& _rxField )
2239  {
2240  OUString sDate;
2241  if ( _rxField.is() )
2242  {
2243  try
2244  {
2245  css::util::Date aValue = _rxField->getDate();
2246  if ( _rxField->wasNull() )
2247  _rField.SetText( sDate );
2248  else
2249  {
2250  _rField.SetDate( ::Date( aValue.Day, aValue.Month, aValue.Year ) );
2251  sDate = _rField.GetText();
2252  }
2253  }
2254  catch( const Exception& )
2255  {
2256  DBG_UNHANDLED_EXCEPTION("svx");
2257  }
2258  }
2259  return sDate;
2260  }
2261 }
2262 
2263 OUString DbDateField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2264 {
2265  return lcl_setFormattedDate_nothrow(dynamic_cast<DateField&>(*m_pPainter), _rxField);
2266 }
2267 
2268 
2269 void DbDateField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2270 {
2271  lcl_setFormattedDate_nothrow(dynamic_cast<DateField&>(*m_pWindow), _rxField);
2272 }
2273 
2274 
2275 void DbDateField::updateFromModel( Reference< XPropertySet > _rxModel )
2276 {
2277  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbDateField::updateFromModel: invalid call!" );
2278 
2279  util::Date aDate;
2280  if ( _rxModel->getPropertyValue( FM_PROP_DATE ) >>= aDate )
2281  static_cast< DateField* >( m_pWindow.get() )->SetDate( ::Date( aDate ) );
2282  else
2283  static_cast< DateField* >( m_pWindow.get() )->SetText( OUString() );
2284 }
2285 
2286 
2288 {
2289  OUString aText(m_pWindow->GetText());
2290  Any aVal;
2291  if (!aText.isEmpty())
2292  aVal <<= static_cast<DateField*>(m_pWindow.get())->GetDate().GetUNODate();
2293  else
2294  aVal.clear();
2295 
2296  m_rColumn.getModel()->setPropertyValue(FM_PROP_DATE, aVal);
2297  return true;
2298 }
2299 
2301  :DbSpinField( _rColumn, css::awt::TextAlign::LEFT )
2302 {
2307 }
2308 
2309 
2310 VclPtr<SpinField> DbTimeField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/ )
2311 {
2312  return VclPtr<TimeField>::Create( _pParent, _nFieldStyle );
2313 }
2314 
2315 
2316 void DbTimeField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2317 {
2318  DBG_ASSERT( m_pWindow, "DbTimeField::implAdjustGenericFieldSetting: not to be called without window!" );
2319  DBG_ASSERT( _rxModel.is(), "DbTimeField::implAdjustGenericFieldSetting: invalid model!" );
2320  if ( !m_pWindow || !_rxModel.is() )
2321  return;
2322 
2323  sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_TIMEFORMAT ) );
2324  util::Time aMin;
2325  OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMIN ) >>= aMin );
2326  util::Time aMax;
2327  OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMAX ) >>= aMax );
2328  bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2329 
2330  static_cast< TimeField* >( m_pWindow.get() )->SetExtFormat( static_cast<ExtTimeFieldFormat>(nFormat) );
2331  static_cast< TimeField* >( m_pWindow.get() )->SetMin( aMin );
2332  static_cast< TimeField* >( m_pWindow.get() )->SetMax( aMax );
2333  static_cast< TimeField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
2334  static_cast< TimeField* >( m_pWindow.get() )->EnableEmptyFieldValue( true );
2335 
2336  static_cast< TimeField* >( m_pPainter.get() )->SetExtFormat( static_cast<ExtTimeFieldFormat>(nFormat) );
2337  static_cast< TimeField* >( m_pPainter.get() )->SetMin( aMin );
2338  static_cast< TimeField* >( m_pPainter.get() )->SetMax( aMax );
2339  static_cast< TimeField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
2340  static_cast< TimeField* >( m_pPainter.get() )->EnableEmptyFieldValue( true );
2341 }
2342 
2343 namespace
2344 {
2345 
2346  OUString lcl_setFormattedTime_nothrow( TimeField& _rField, const Reference< XColumn >& _rxField )
2347  {
2348  OUString sTime;
2349  if ( _rxField.is() )
2350  {
2351  try
2352  {
2353  css::util::Time aValue = _rxField->getTime();
2354  if ( _rxField->wasNull() )
2355  _rField.SetText( sTime );
2356  else
2357  {
2358  _rField.SetTime( ::tools::Time( aValue ) );
2359  sTime = _rField.GetText();
2360  }
2361  }
2362  catch( const Exception& )
2363  {
2364  DBG_UNHANDLED_EXCEPTION("svx");
2365  }
2366  }
2367  return sTime;
2368  }
2369 }
2370 
2371 OUString DbTimeField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2372 {
2373  return lcl_setFormattedTime_nothrow( *static_cast< TimeField* >( m_pPainter.get() ), _rxField );
2374 }
2375 
2376 
2377 void DbTimeField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2378 {
2379  lcl_setFormattedTime_nothrow( *static_cast< TimeField* >( m_pWindow.get() ), _rxField );
2380 }
2381 
2382 
2383 void DbTimeField::updateFromModel( Reference< XPropertySet > _rxModel )
2384 {
2385  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTimeField::updateFromModel: invalid call!" );
2386 
2387  util::Time aTime;
2388  if ( _rxModel->getPropertyValue( FM_PROP_TIME ) >>= aTime )
2389  static_cast< TimeField* >( m_pWindow.get() )->SetTime( ::tools::Time( aTime ) );
2390  else
2391  static_cast< TimeField* >( m_pWindow.get() )->SetText( OUString() );
2392 }
2393 
2394 
2396 {
2397  OUString aText(m_pWindow->GetText());
2398  Any aVal;
2399  if (!aText.isEmpty())
2400  aVal <<= static_cast<TimeField*>(m_pWindow.get())->GetTime().GetUNOTime();
2401  else
2402  aVal.clear();
2403 
2404  m_rColumn.getModel()->setPropertyValue(FM_PROP_TIME, aVal);
2405  return true;
2406 }
2407 
2409  :DbCellControl(_rColumn)
2410 {
2411  setAlignedController( false );
2412 
2415 }
2416 
2417 void DbComboBox::_propertyChanged( const PropertyChangeEvent& _rEvent )
2418 {
2419  if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
2420  {
2421  SetList(_rEvent.NewValue);
2422  }
2423  else
2424  {
2425  DbCellControl::_propertyChanged( _rEvent ) ;
2426  }
2427 }
2428 
2429 void DbComboBox::SetList(const Any& rItems)
2430 {
2431  ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
2432  weld::ComboBox& rComboBox = pField->get_widget();
2433  rComboBox.clear();
2434 
2435  css::uno::Sequence<OUString> aTest;
2436  if (rItems >>= aTest)
2437  {
2438  for (const OUString& rString : std::as_const(aTest))
2439  rComboBox.append_text(rString);
2440 
2441  // tell the grid control that this controller is invalid and has to be re-initialized
2443  }
2444 }
2445 
2446 void DbComboBox::implAdjustGenericFieldSetting(const Reference<XPropertySet>&)
2447 {
2448  // we no longer pay attention to FM_PROP_LINECOUNT
2449 }
2450 
2451 void DbComboBox::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor )
2452 {
2453  m_rColumn.SetAlignmentFromModel(css::awt::TextAlign::LEFT);
2454 
2456 
2457  // selection from right to left
2458  AllSettings aSettings = m_pWindow->GetSettings();
2459  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2460  aStyleSettings.SetSelectionOptions(
2461  aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2462  aSettings.SetStyleSettings(aStyleSettings);
2463  m_pWindow->SetSettings(aSettings, true);
2464 
2465  // some initial properties
2466  Reference< XPropertySet > xModel(m_rColumn.getModel());
2467  SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2469 
2470  DbCellControl::Init( rParent, xCursor );
2471 }
2472 
2473 
2475 {
2476  return new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2477 }
2478 
2479 
2480 OUString DbComboBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, Color** /*ppColor*/)
2481 {
2482  const css::uno::Reference<css::beans::XPropertySet> xPS(_rxField, UNO_QUERY);
2483  ::dbtools::FormattedColumnValue fmter( xFormatter, xPS );
2484 
2485  return fmter.getFormattedValue();
2486 }
2487 
2488 void DbComboBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2489 {
2490  ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2491  pControl->get_widget().set_entry_text(GetFormatText(_rxField, xFormatter));
2492 }
2493 
2494 void DbComboBox::updateFromModel( Reference< XPropertySet > _rxModel )
2495 {
2496  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbComboBox::updateFromModel: invalid call!" );
2497 
2498  OUString sText;
2499  _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
2500 
2501  ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2502  weld::ComboBox& rComboBox = pControl->get_widget();
2503  rComboBox.set_entry_text(sText);
2504  rComboBox.select_entry_region(0, -1);
2505 }
2506 
2508 {
2509  ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2510  weld::ComboBox& rComboBox = pControl->get_widget();
2511  OUString aText(rComboBox.get_active_text());
2512  m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, makeAny(aText));
2513  return true;
2514 }
2515 
2516 
2518  :DbCellControl(_rColumn)
2519  ,m_bBound(false)
2520 {
2521  setAlignedController( false );
2522 
2525 }
2526 
2527 void DbListBox::_propertyChanged( const css::beans::PropertyChangeEvent& _rEvent )
2528 {
2529  if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
2530  {
2531  SetList(_rEvent.NewValue);
2532  }
2533  else
2534  {
2535  DbCellControl::_propertyChanged( _rEvent ) ;
2536  }
2537 }
2538 
2539 void DbListBox::SetList(const Any& rItems)
2540 {
2541  ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2542 
2543  weld::ComboBox& rFieldList = pField->get_widget();
2544 
2545  rFieldList.clear();
2546  m_bBound = false;
2547 
2548  css::uno::Sequence<OUString> aTest;
2549  if (rItems >>= aTest)
2550  {
2551  if (aTest.hasElements())
2552  {
2553  for (const OUString& rString : std::as_const(aTest))
2554  rFieldList.append_text(rString);
2555 
2556  m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2557  m_bBound = m_aValueList.hasElements();
2558 
2559  // tell the grid control that this controller is invalid and has to be re-initialized
2561  }
2562  }
2563 }
2564 
2565 void DbListBox::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
2566 {
2567  m_rColumn.SetAlignment(css::awt::TextAlign::LEFT);
2568 
2570 
2571  // some initial properties
2572  Reference< XPropertySet > xModel( m_rColumn.getModel() );
2573  SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2575 
2576  DbCellControl::Init( rParent, xCursor );
2577 }
2578 
2579 void DbListBox::implAdjustGenericFieldSetting( const Reference< XPropertySet >& /*rxModel*/ )
2580 {
2581  // ignore FM_PROP_LINECOUNT
2582 }
2583 
2585 {
2586  return new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2587 }
2588 
2589 OUString DbListBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2590 {
2591  OUString sText;
2592  if ( _rxField.is() )
2593  {
2594  try
2595  {
2596  sText = _rxField->getString();
2597  if ( m_bBound )
2598  {
2599  sal_Int32 nPos = ::comphelper::findValue( m_aValueList, sText );
2600  if ( nPos != -1 )
2601  sText = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget().get_text(nPos);
2602  else
2603  sText.clear();
2604  }
2605  }
2606  catch( const Exception& )
2607  {
2608  DBG_UNHANDLED_EXCEPTION("svx");
2609  }
2610  }
2611  return sText;
2612 }
2613 
2614 void DbListBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2615 {
2616  OUString sFormattedText( GetFormatText( _rxField, xFormatter ) );
2617  weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2618  if (!sFormattedText.isEmpty())
2619  rComboBox.set_active_text(sFormattedText);
2620  else
2621  rComboBox.set_active(-1);
2622 }
2623 
2624 void DbListBox::updateFromModel( Reference< XPropertySet > _rxModel )
2625 {
2626  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbListBox::updateFromModel: invalid call!" );
2627 
2628  Sequence< sal_Int16 > aSelection;
2629  _rxModel->getPropertyValue( FM_PROP_SELECT_SEQ ) >>= aSelection;
2630 
2631  sal_Int16 nSelection = -1;
2632  if ( aSelection.hasElements() )
2633  nSelection = aSelection[ 0 ];
2634 
2635  weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2636 
2637  if (nSelection >= 0 && nSelection < rComboBox.get_count())
2638  rComboBox.set_active(nSelection);
2639  else
2640  rComboBox.set_active(-1);
2641 }
2642 
2644 {
2645  Any aVal;
2646  Sequence<sal_Int16> aSelectSeq;
2647  weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2648  auto nActive = rComboBox.get_active();
2649  if (nActive != -1)
2650  {
2651  aSelectSeq.realloc(1);
2652  *aSelectSeq.getArray() = static_cast<sal_Int16>(nActive);
2653  }
2654  aVal <<= aSelectSeq;
2655  m_rColumn.getModel()->setPropertyValue(FM_PROP_SELECT_SEQ, aVal);
2656  return true;
2657 }
2658 
2660  :DbCellControl(_rColumn)
2661  ,OSQLParserClient(rxContext)
2662  ,m_nControlClass(css::form::FormComponentType::TEXTFIELD)
2663  ,m_bFilterList(false)
2664  ,m_bFilterListFilled(false)
2665 {
2666 
2667  setAlignedController( false );
2668 }
2669 
2671 {
2672  if (m_nControlClass == css::form::FormComponentType::CHECKBOX)
2673  static_cast<CheckBoxControl*>(m_pWindow.get())->SetClickHdl( Link<VclPtr<CheckBox>,void>() );
2674 
2675 }
2676 
2678 {
2679  static const DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter | DrawTextFlags::Left;
2680  switch (m_nControlClass)
2681  {
2682  case FormComponentType::CHECKBOX:
2683  DbCellControl::PaintCell( rDev, rRect );
2684  break;
2685  case FormComponentType::LISTBOX:
2686  rDev.DrawText(rRect, static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().get_active_text(), nStyle);
2687  break;
2688  default:
2689  rDev.DrawText(rRect, m_aText, nStyle);
2690  }
2691 }
2692 
2693 void DbFilterField::SetList(const Any& rItems, bool bComboBox)
2694 {
2695  css::uno::Sequence<OUString> aTest;
2696  rItems >>= aTest;
2697  if (aTest.hasElements())
2698  {
2699  if (bComboBox)
2700  {
2701  ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
2702  weld::ComboBox& rComboBox = pField->get_widget();
2703  for (const OUString& rString : std::as_const(aTest))
2704  rComboBox.append_text(rString);
2705  }
2706  else
2707  {
2708  ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2709  weld::ComboBox& rFieldBox = pField->get_widget();
2710  for (const OUString& rString : std::as_const(aTest))
2711  rFieldBox.append_text(rString);
2712 
2713  m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2714  }
2715  }
2716 }
2717 
2718 void DbFilterField::CreateControl(vcl::Window* pParent, const Reference< css::beans::XPropertySet >& xModel)
2719 {
2720  switch (m_nControlClass)
2721  {
2722  case css::form::FormComponentType::CHECKBOX:
2724  m_pWindow->SetPaintTransparent( true );
2725  static_cast<CheckBoxControl*>(m_pWindow.get())->SetClickHdl( LINK( this, DbFilterField, OnClick ) );
2726 
2730  break;
2731  case css::form::FormComponentType::LISTBOX:
2732  {
2734  Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2735  SetList(aItems, false);
2736  } break;
2737  case css::form::FormComponentType::COMBOBOX:
2738  {
2740 
2741  AllSettings aSettings = m_pWindow->GetSettings();
2742  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2743  aStyleSettings.SetSelectionOptions(
2744  aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2745  aSettings.SetStyleSettings(aStyleSettings);
2746  m_pWindow->SetSettings(aSettings, true);
2747 
2748  if (!m_bFilterList)
2749  {
2750  Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2751  SetList(aItems, true);
2752  }
2753 
2754  } break;
2755  default:
2756  {
2758  AllSettings aSettings = m_pWindow->GetSettings();
2759  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2760  aStyleSettings.SetSelectionOptions(
2761  aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2762  aSettings.SetStyleSettings(aStyleSettings);
2763  m_pWindow->SetSettings(aSettings, true);
2764  }
2765  }
2766 }
2767 
2768 
2769 void DbFilterField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor )
2770 {
2771  Reference< css::beans::XPropertySet > xModel(m_rColumn.getModel());
2772  m_rColumn.SetAlignment(css::awt::TextAlign::LEFT);
2773 
2774  if (xModel.is())
2775  {
2776  m_bFilterList = ::comphelper::hasProperty(FM_PROP_FILTERPROPOSAL, xModel) && ::comphelper::getBOOL(xModel->getPropertyValue(FM_PROP_FILTERPROPOSAL));
2777  if (m_bFilterList)
2778  m_nControlClass = css::form::FormComponentType::COMBOBOX;
2779  else
2780  {
2781  sal_Int16 nClassId = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_CLASSID));
2782  switch (nClassId)
2783  {
2784  case FormComponentType::CHECKBOX:
2785  case FormComponentType::LISTBOX:
2786  case FormComponentType::COMBOBOX:
2787  m_nControlClass = nClassId;
2788  break;
2789  default:
2790  if (m_bFilterList)
2791  m_nControlClass = FormComponentType::COMBOBOX;
2792  else
2793  m_nControlClass = FormComponentType::TEXTFIELD;
2794  }
2795  }
2796  }
2797 
2798  CreateControl( &rParent, xModel );
2799  DbCellControl::Init( rParent, xCursor );
2800 
2801  // filter cells are never readonly
2802  Edit* pAsEdit = dynamic_cast< Edit* >( m_pWindow.get() );
2803  if ( pAsEdit )
2804  pAsEdit->SetReadOnly( false );
2805 }
2806 
2808 {
2810  switch (m_nControlClass)
2811  {
2812  case css::form::FormComponentType::CHECKBOX:
2813  xController = new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
2814  break;
2815  case css::form::FormComponentType::LISTBOX:
2816  xController = new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2817  break;
2818  case css::form::FormComponentType::COMBOBOX:
2819  xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2820  break;
2821  default:
2822  if (m_bFilterList)
2823  xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2824  else
2825  xController = new EditCellController(static_cast<Edit*>(m_pWindow.get()));
2826  }
2827  return xController;
2828 }
2829 
2830 void DbFilterField::updateFromModel( Reference< XPropertySet > _rxModel )
2831 {
2832  OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFilterField::updateFromModel: invalid call!" );
2833 
2834  OSL_FAIL( "DbListBox::updateFromModel: not implemented yet (how the hell did you reach this?)!" );
2835  // TODO: implement this.
2836  // remember: updateFromModel should be some kind of opposite of commitControl
2837 }
2838 
2840 {
2841  OUString aText(m_aText);
2842  switch (m_nControlClass)
2843  {
2844  case css::form::FormComponentType::CHECKBOX:
2845  return true;
2846  case css::form::FormComponentType::LISTBOX:
2847  {
2848  aText.clear();
2849  weld::ComboBox& rComboBox = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget();
2850  auto nActive = rComboBox.get_active();
2851  if (nActive != -1)
2852  {
2853  sal_Int16 nPos = static_cast<sal_Int16>(nActive);
2854  if ( ( nPos >= 0 ) && ( nPos < m_aValueList.getLength() ) )
2855  aText = m_aValueList.getConstArray()[nPos];
2856  }
2857 
2858  if (m_aText != aText)
2859  {
2860  m_aText = aText;
2861  m_aCommitLink.Call(*this);
2862  }
2863  return true;
2864  }
2865  default:
2866  aText = m_pWindow->GetText();
2867  }
2868 
2869  if (m_aText != aText)
2870  {
2871  // check the text with the SQL-Parser
2872  OUString aNewText(comphelper::string::stripEnd(aText, ' '));
2873  if (!aNewText.isEmpty())
2874  {
2875  OUString aErrorMsg;
2877 
2878  std::unique_ptr< OSQLParseNode > pParseNode = predicateTree(aErrorMsg, aNewText,xNumberFormatter, m_rColumn.GetField());
2879  if (pParseNode != nullptr)
2880  {
2881  OUString aPreparedText;
2882 
2883  css::lang::Locale aAppLocale = Application::GetSettings().GetUILanguageTag().getLocale();
2884 
2885  Reference< XRowSet > xDataSourceRowSet(
2887  Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
2888 
2889  pParseNode->parseNodeToPredicateStr(aPreparedText,
2890  xConnection,
2891  xNumberFormatter,
2892  m_rColumn.GetField(),
2893  OUString(),
2894  aAppLocale,
2895  OUString("."),
2896  getParseContext());
2897  m_aText = aPreparedText;
2898  }
2899  else
2900  {
2901 
2902  SQLException aError;
2903  aError.Message = aErrorMsg;
2904  displayException(aError, m_pWindow->GetParent());
2905  // TODO: transport the title
2906 
2907  return false;
2908  }
2909  }
2910  else
2911  m_aText = aText;
2912 
2914  m_aCommitLink.Call(*this);
2915  }
2916  return true;
2917 }
2918 
2919 
2920 void DbFilterField::SetText(const OUString& rText)
2921 {
2922  m_aText = rText;
2923  switch (m_nControlClass)
2924  {
2925  case css::form::FormComponentType::CHECKBOX:
2926  {
2927  TriState eState;
2928  if (rText == "1")
2929  eState = TRISTATE_TRUE;
2930  else if (rText == "0")
2931  eState = TRISTATE_FALSE;
2932  else
2933  eState = TRISTATE_INDET;
2934 
2935  static_cast<CheckBoxControl*>(m_pWindow.get())->GetBox().SetState(eState);
2936  static_cast<CheckBoxControl*>(m_pPainter.get())->GetBox().SetState(eState);
2937  } break;
2938  case css::form::FormComponentType::LISTBOX:
2939  {
2940  sal_Int32 nPos = ::comphelper::findValue(m_aValueList, m_aText);
2941  static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().set_active(nPos);
2942  } break;
2943  default:
2945  }
2946 
2947  // now force a repaint on the window
2949 }
2950 
2951 
2953 {
2954  // should we fill the combobox with a filter proposal?
2956  return;
2957 
2958  m_bFilterListFilled = true;
2959  Reference< css::beans::XPropertySet > xField = m_rColumn.GetField();
2960  if (!xField.is())
2961  return;
2962 
2963  OUString aName;
2964  xField->getPropertyValue(FM_PROP_NAME) >>= aName;
2965 
2966  // the columnmodel
2967  Reference< css::container::XChild > xModelAsChild(m_rColumn.getModel(), UNO_QUERY);
2968  // the grid model
2969  xModelAsChild.set(xModelAsChild->getParent(),UNO_QUERY);
2970  Reference< XRowSet > xForm(xModelAsChild->getParent(), UNO_QUERY);
2971  if (!xForm.is())
2972  return;
2973 
2974  Reference<XPropertySet> xFormProp(xForm,UNO_QUERY);
2975  Reference< XTablesSupplier > xSupTab;
2976  xFormProp->getPropertyValue("SingleSelectQueryComposer") >>= xSupTab;
2977 
2978  Reference< XConnection > xConnection(getConnection(xForm));
2979  if (!xSupTab.is())
2980  return;
2981 
2982  // search the field
2983  Reference< XColumnsSupplier > xSupCol(xSupTab,UNO_QUERY);
2984  Reference< css::container::XNameAccess > xFieldNames = xSupCol->getColumns();
2985  if (!xFieldNames->hasByName(aName))
2986  return;
2987 
2988  Reference< css::container::XNameAccess > xTablesNames = xSupTab->getTables();
2989  Reference< css::beans::XPropertySet > xComposerFieldAsSet(xFieldNames->getByName(aName),UNO_QUERY);
2990 
2991  if (!xComposerFieldAsSet.is() ||
2992  !::comphelper::hasProperty(FM_PROP_TABLENAME, xComposerFieldAsSet) ||
2993  !::comphelper::hasProperty(FM_PROP_FIELDSOURCE, xComposerFieldAsSet))
2994  return;
2995 
2996  OUString aFieldName;
2997  OUString aTableName;
2998  xComposerFieldAsSet->getPropertyValue(FM_PROP_FIELDSOURCE) >>= aFieldName;
2999  xComposerFieldAsSet->getPropertyValue(FM_PROP_TABLENAME) >>= aTableName;
3000 
3001  // no possibility to create a select statement
3002  // looking for the complete table name
3003  if (!xTablesNames->hasByName(aTableName))
3004  return;
3005 
3006  // build a statement and send as query;
3007  // Access to the connection
3008  Reference< XStatement > xStatement;
3009  Reference< XResultSet > xListCursor;
3010  Reference< css::sdb::XColumn > xDataField;
3011 
3012  try
3013  {
3014  Reference< XDatabaseMetaData > xMeta = xConnection->getMetaData();
3015 
3016  OUString aQuote(xMeta->getIdentifierQuoteString());
3017  OUStringBuffer aStatement("SELECT DISTINCT ");
3018  aStatement.append(quoteName(aQuote, aName));
3019  if (!aFieldName.isEmpty() && aName != aFieldName)
3020  {
3021  aStatement.append(" AS ");
3022  aStatement.append(quoteName(aQuote, aFieldName));
3023  }
3024 
3025  aStatement.append(" FROM ");
3026 
3027  Reference< XPropertySet > xTableNameAccess(xTablesNames->getByName(aTableName), UNO_QUERY_THROW);
3028  aStatement.append(composeTableNameForSelect(xConnection, xTableNameAccess));
3029 
3030  xStatement = xConnection->createStatement();
3031  Reference< css::beans::XPropertySet > xStatementProps(xStatement, UNO_QUERY);
3032  xStatementProps->setPropertyValue(FM_PROP_ESCAPE_PROCESSING, makeAny(true));
3033 
3034  xListCursor = xStatement->executeQuery(aStatement.makeStringAndClear());
3035 
3036  Reference< css::sdbcx::XColumnsSupplier > xSupplyCols(xListCursor, UNO_QUERY);
3037  Reference< css::container::XIndexAccess > xFields(xSupplyCols->getColumns(), UNO_QUERY);
3038  xDataField.set(xFields->getByIndex(0), css::uno::UNO_QUERY);
3039  if (!xDataField.is())
3040  return;
3041  }
3042  catch(const Exception&)
3043  {
3044  ::comphelper::disposeComponent(xStatement);
3045  return;
3046  }
3047 
3048  sal_Int16 i = 0;
3049  ::std::vector< OUString > aStringList;
3050  aStringList.reserve(16);
3051  OUString aStr;
3052  css::util::Date aNullDate = m_rColumn.GetParent().getNullDate();
3053  sal_Int32 nFormatKey = m_rColumn.GetKey();
3055  sal_Int16 nKeyType = ::comphelper::getNumberFormatType(xFormatter->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey);
3056 
3057  while (!xListCursor->isAfterLast() && i++ < SHRT_MAX) // max number of entries
3058  {
3059  aStr = getFormattedValue(xDataField, xFormatter, aNullDate, nFormatKey, nKeyType);
3060  aStringList.push_back(aStr);
3061  (void)xListCursor->next();
3062  }
3063 
3064  ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
3065  weld::ComboBox& rComboBox = pField->get_widget();
3066  // filling the entries for the combobox
3067  for (const auto& rString : aStringList)
3068  rComboBox.append_text(rString);
3069 }
3070 
3071 OUString DbFilterField::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
3072 {
3073  return OUString();
3074 }
3075 
3076 
3077 void DbFilterField::UpdateFromField(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/)
3078 {
3079  OSL_FAIL( "DbFilterField::UpdateFromField: cannot update a filter control from a field!" );
3080 }
3081 
3082 
3084 {
3085  TriState eState = static_cast<CheckBoxControl*>(m_pWindow.get())->GetBox().GetState();
3086  OUStringBuffer aTextBuf;
3087 
3088  Reference< XRowSet > xDataSourceRowSet(
3089  Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY);
3090  Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
3091  const sal_Int32 nBooleanComparisonMode = ::dbtools::DatabaseMetaData( xConnection ).getBooleanComparisonMode();
3092 
3093  switch (eState)
3094  {
3095  case TRISTATE_TRUE:
3096  ::dbtools::getBooleanComparisonPredicate("", true, nBooleanComparisonMode, aTextBuf);
3097  break;
3098  case TRISTATE_FALSE:
3099  ::dbtools::getBooleanComparisonPredicate("", false, nBooleanComparisonMode, aTextBuf);
3100  break;
3101  case TRISTATE_INDET:
3102  break;
3103  }
3104 
3105  const OUString aText(aTextBuf.makeStringAndClear());
3106 
3107  if (m_aText != aText)
3108  {
3109  m_aText = aText;
3110  m_aCommitLink.Call(*this);
3111  }
3112 }
3113 
3114 
3115 FmXGridCell::FmXGridCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> _pControl )
3116  :OComponentHelper(m_aMutex)
3117  ,m_pColumn(pColumn)
3118  ,m_pCellControl( std::move(_pControl) )
3119  ,m_aWindowListeners( m_aMutex )
3120  ,m_aFocusListeners( m_aMutex )
3121  ,m_aKeyListeners( m_aMutex )
3122  ,m_aMouseListeners( m_aMutex )
3123  ,m_aMouseMotionListeners( m_aMutex )
3124 {
3125 }
3126 
3127 
3129 {
3130  vcl::Window* pEventWindow( getEventWindow() );
3131  if ( pEventWindow )
3132  pEventWindow->AddEventListener( LINK( this, FmXGridCell, OnWindowEvent ) );
3133 }
3134 
3135 
3137 {
3138  if ( m_pCellControl )
3139  return &m_pCellControl->GetWindow();
3140  return nullptr;
3141 }
3142 
3143 
3145 {
3146  if (!OComponentHelper::rBHelper.bDisposed)
3147  {
3148  acquire();
3149  dispose();
3150  }
3151 
3152 }
3153 
3154 
3156 {
3157  if (m_pCellControl)
3158  m_pCellControl->SetTextLineColor();
3159 }
3160 
3161 
3163 {
3164  if (m_pCellControl)
3165  m_pCellControl->SetTextLineColor(_rColor);
3166 }
3167 
3168 // XTypeProvider
3169 
3170 Sequence< Type > SAL_CALL FmXGridCell::getTypes( )
3171 {
3172  Sequence< uno::Type > aTypes = ::comphelper::concatSequences(
3175  );
3176  if ( m_pCellControl )
3177  aTypes = ::comphelper::concatSequences(
3178  aTypes,
3180  );
3181  return aTypes;
3182 }
3183 
3184 
3186 
3187 // OComponentHelper
3188 
3189 void FmXGridCell::disposing()
3190 {
3191  lang::EventObject aEvent( *this );
3192  m_aWindowListeners.disposeAndClear( aEvent );
3193  m_aFocusListeners.disposeAndClear( aEvent );
3194  m_aKeyListeners.disposeAndClear( aEvent );
3195  m_aMouseListeners.disposeAndClear( aEvent );
3196  m_aMouseMotionListeners.disposeAndClear( aEvent );
3197 
3198  OComponentHelper::disposing();
3199  m_pColumn = nullptr;
3200  m_pCellControl.reset();
3201 }
3202 
3203 
3204 Any SAL_CALL FmXGridCell::queryAggregation( const css::uno::Type& _rType )
3205 {
3206  Any aReturn = OComponentHelper::queryAggregation( _rType );
3207 
3208  if ( !aReturn.hasValue() )
3209  aReturn = FmXGridCell_Base::queryInterface( _rType );
3210 
3211  if ( !aReturn.hasValue() && ( m_pCellControl != nullptr ) )
3212  aReturn = FmXGridCell_WindowBase::queryInterface( _rType );
3213 
3214  return aReturn;
3215 }
3216 
3217 // css::awt::XControl
3218 
3220 {
3221  return Reference< XInterface > ();
3222 }
3223 
3224 
3225 Reference< css::awt::XControlModel > FmXGridCell::getModel()
3226 {
3227  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3228  return Reference< css::awt::XControlModel > (m_pColumn->getModel(), UNO_QUERY);
3229 }
3230 
3231 // css::form::XBoundControl
3232 
3234 {
3235  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3236  return m_pColumn->isLocked();
3237 }
3238 
3239 
3241 {
3242  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3243  if (getLock() == _bLock)
3244  return;
3245  else
3246  {
3247  ::osl::MutexGuard aGuard(m_aMutex);
3248  m_pColumn->setLock(_bLock);
3249  }
3250 }
3251 
3252 
3253 void SAL_CALL FmXGridCell::setPosSize( ::sal_Int32, ::sal_Int32, ::sal_Int32, ::sal_Int32, ::sal_Int16 )
3254 {
3255  OSL_FAIL( "FmXGridCell::setPosSize: not implemented" );
3256  // not allowed to tamper with this for a grid cell
3257 }
3258 
3259 
3260 awt::Rectangle SAL_CALL FmXGridCell::getPosSize( )
3261 {
3262  OSL_FAIL( "FmXGridCell::getPosSize: not implemented" );
3263  return awt::Rectangle();
3264 }
3265 
3266 
3268 {
3269  OSL_FAIL( "FmXGridCell::setVisible: not implemented" );
3270  // not allowed to tamper with this for a grid cell
3271 }
3272 
3273 
3275 {
3276  OSL_FAIL( "FmXGridCell::setEnable: not implemented" );
3277  // not allowed to tamper with this for a grid cell
3278 }
3279 
3280 
3281 void SAL_CALL FmXGridCell::setFocus( )
3282 {
3283  OSL_FAIL( "FmXGridCell::setFocus: not implemented" );
3284  // not allowed to tamper with this for a grid cell
3285 }
3286 
3287 
3288 void SAL_CALL FmXGridCell::addWindowListener( const Reference< awt::XWindowListener >& _rxListener )
3289 {
3290  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3291  m_aWindowListeners.addInterface( _rxListener );
3292 }
3293 
3294 
3295 void SAL_CALL FmXGridCell::removeWindowListener( const Reference< awt::XWindowListener >& _rxListener )
3296 {
3297  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3298  m_aWindowListeners.removeInterface( _rxListener );
3299 }
3300 
3301 
3302 void SAL_CALL FmXGridCell::addFocusListener( const Reference< awt::XFocusListener >& _rxListener )
3303 {
3304  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3305  m_aFocusListeners.addInterface( _rxListener );
3306 }
3307 
3308 
3309 void SAL_CALL FmXGridCell::removeFocusListener( const Reference< awt::XFocusListener >& _rxListener )
3310 {
3311  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3312  m_aFocusListeners.removeInterface( _rxListener );
3313 }
3314 
3315 
3316 void SAL_CALL FmXGridCell::addKeyListener( const Reference< awt::XKeyListener >& _rxListener )
3317 {
3318  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3319  m_aKeyListeners.addInterface( _rxListener );
3320 }
3321 
3322 
3323 void SAL_CALL FmXGridCell::removeKeyListener( const Reference< awt::XKeyListener >& _rxListener )
3324 {
3325  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3326  m_aKeyListeners.removeInterface( _rxListener );
3327 }
3328 
3329 
3330 void SAL_CALL FmXGridCell::addMouseListener( const Reference< awt::XMouseListener >& _rxListener )
3331 {
3332  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3333  m_aMouseListeners.addInterface( _rxListener );
3334 }
3335 
3336 
3337 void SAL_CALL FmXGridCell::removeMouseListener( const Reference< awt::XMouseListener >& _rxListener )
3338 {
3339  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3340  m_aMouseListeners.removeInterface( _rxListener );
3341 }
3342 
3343 
3344 void SAL_CALL FmXGridCell::addMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener )
3345 {
3346  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3347  m_aMouseMotionListeners.addInterface( _rxListener );
3348 }
3349 
3350 
3351 void SAL_CALL FmXGridCell::removeMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener )
3352 {
3353  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3355 }
3356 
3357 
3358 void SAL_CALL FmXGridCell::addPaintListener( const Reference< awt::XPaintListener >& )
3359 {
3360  OSL_FAIL( "FmXGridCell::addPaintListener: not implemented" );
3361 }
3362 
3363 
3364 void SAL_CALL FmXGridCell::removePaintListener( const Reference< awt::XPaintListener >& )
3365 {
3366  OSL_FAIL( "FmXGridCell::removePaintListener: not implemented" );
3367 }
3368 
3369 
3370 IMPL_LINK( FmXGridCell, OnWindowEvent, VclWindowEvent&, _rEvent, void )
3371 {
3372  ENSURE_OR_THROW( _rEvent.GetWindow(), "illegal window" );
3373  onWindowEvent( _rEvent.GetId(), *_rEvent.GetWindow(), _rEvent.GetData() );
3374 }
3375 
3376 
3377 void FmXGridCell::onFocusGained( const awt::FocusEvent& _rEvent )
3378 {
3379  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3380  m_aFocusListeners.notifyEach( &awt::XFocusListener::focusGained, _rEvent );
3381 }
3382 
3383 
3384 void FmXGridCell::onFocusLost( const awt::FocusEvent& _rEvent )
3385 {
3386  checkDisposed(OComponentHelper::rBHelper.bDisposed);
3387  m_aFocusListeners.notifyEach( &awt::XFocusListener::focusLost, _rEvent );
3388 }
3389 
3390 
3391 void FmXGridCell::onWindowEvent( const VclEventId _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
3392 {
3393  switch ( _nEventId )
3394  {
3395  case VclEventId::ControlGetFocus:
3396  case VclEventId::WindowGetFocus:
3397  case VclEventId::ControlLoseFocus:
3398  case VclEventId::WindowLoseFocus:
3399  {
3400  if ( ( _rWindow.IsCompoundControl()
3401  && ( _nEventId == VclEventId::ControlGetFocus
3402  || _nEventId == VclEventId::ControlLoseFocus
3403  )
3404  )
3405  || ( !_rWindow.IsCompoundControl()
3406  && ( _nEventId == VclEventId::WindowGetFocus
3407  || _nEventId == VclEventId::WindowLoseFocus
3408  )
3409  )
3410  )
3411  {
3412  if ( !m_aFocusListeners.getLength() )
3413  break;
3414 
3415  bool bFocusGained = ( _nEventId == VclEventId::ControlGetFocus ) || ( _nEventId == VclEventId::WindowGetFocus );
3416 
3417  awt::FocusEvent aEvent;
3418  aEvent.Source = *this;
3419  aEvent.FocusFlags = static_cast<sal_Int16>(_rWindow.GetGetFocusFlags());
3420  aEvent.Temporary = false;
3421 
3422  if ( bFocusGained )
3423  onFocusGained( aEvent );
3424  else
3425  onFocusLost( aEvent );
3426  }
3427  }
3428  break;
3429  case VclEventId::WindowMouseButtonDown:
3430  case VclEventId::WindowMouseButtonUp:
3431  {
3432  if ( !m_aMouseListeners.getLength() )
3433  break;
3434 
3435  const bool bButtonDown = ( _nEventId == VclEventId::WindowMouseButtonDown );
3436 
3437  awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast< const ::MouseEvent* >( _pEventData ), *this ) );
3438  m_aMouseListeners.notifyEach( bButtonDown ? &awt::XMouseListener::mousePressed : &awt::XMouseListener::mouseReleased, aEvent );
3439  }
3440  break;
3441  case VclEventId::WindowMouseMove:
3442  {
3443  const MouseEvent& rMouseEvent = *static_cast< const ::MouseEvent* >( _pEventData );
3444  if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
3445  {
3446  if ( m_aMouseListeners.getLength() != 0 )
3447  {
3448  awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3449  m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? &awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
3450  }
3451  }
3452  else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() )
3453  {
3454  if ( m_aMouseMotionListeners.getLength() != 0 )
3455  {
3456  awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3457  aEvent.ClickCount = 0;
3458  const bool bSimpleMove = bool( rMouseEvent.GetMode() & MouseEventModifiers::SIMPLEMOVE );
3459  m_aMouseMotionListeners.notifyEach( bSimpleMove ? &awt::XMouseMotionListener::mouseMoved: &awt::XMouseMotionListener::mouseDragged, aEvent );
3460  }
3461  }
3462  }
3463  break;
3464  case VclEventId::WindowKeyInput:
3465  case VclEventId::WindowKeyUp:
3466  {
3467  if ( !m_aKeyListeners.getLength() )
3468  break;
3469 
3470  const bool bKeyPressed = ( _nEventId == VclEventId::WindowKeyInput );
3471  awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent( *static_cast< const ::KeyEvent* >( _pEventData ), *this ) );
3472  m_aKeyListeners.notifyEach( bKeyPressed ? &awt::XKeyListener::keyPressed: &awt::XKeyListener::keyReleased, aEvent );
3473  }
3474  break;
3475  default: break;
3476  }
3477 }
3478 
3479 
3481  const Reference< css::sdb::XColumn >& _rxField,
3482  const Reference< XNumberFormatter >& xFormatter)
3483 {
3484  m_pCellControl->PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3485 }
3486 
3487 
3489 {
3490  Reference< css::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3491  if (xField.is())
3492  m_pCellControl->UpdateFromField(xField, m_pColumn->GetParent().getNumberFormatter());
3493 }
3494 
3495 
3496 FmXTextCell::FmXTextCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3497  :FmXDataCell( pColumn, std::move(pControl) )
3498  ,m_bFastPaint( true )
3499 {
3500 }
3501 
3502 
3504  const tools::Rectangle& rRect,
3505  const Reference< css::sdb::XColumn >& _rxField,
3506  const Reference< XNumberFormatter >& xFormatter)
3507 {
3508  if ( !m_bFastPaint )
3509  {
3510  FmXDataCell::PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3511  return;
3512  }
3513 
3514  DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter;
3515  if ( ( rDev.GetOutDevType() == OUTDEV_WINDOW ) && !static_cast< vcl::Window& >( rDev ).IsEnabled() )
3516  nStyle |= DrawTextFlags::Disable;
3517 
3518  switch (m_pColumn->GetAlignment())
3519  {
3520  case css::awt::TextAlign::RIGHT:
3521  nStyle |= DrawTextFlags::Right;
3522  break;
3523  case css::awt::TextAlign::CENTER:
3524  nStyle |= DrawTextFlags::Center;
3525  break;
3526  default:
3527  nStyle |= DrawTextFlags::Left;
3528  }
3529 
3530  try
3531  {
3532  Color* pColor = nullptr;
3533  OUString aText = GetText(_rxField, xFormatter, &pColor);
3534  if (pColor != nullptr)
3535  {
3536  Color aOldTextColor( rDev.GetTextColor() );
3537  rDev.SetTextColor( *pColor );
3538  rDev.DrawText(rRect, aText, nStyle);
3539  rDev.SetTextColor( aOldTextColor );
3540  }
3541  else
3542  rDev.DrawText(rRect, aText, nStyle);
3543  }
3544  catch (const Exception&)
3545  {
3546  TOOLS_WARN_EXCEPTION("svx.fmcomp", "PaintFieldToCell");
3547  }
3548 }
3549 
3550 FmXEditCell::FmXEditCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3551  :FmXTextCell( pColumn, std::move(pControl) )
3552  ,m_aTextListeners(m_aMutex)
3553  ,m_aChangeListeners( m_aMutex )
3554  ,m_pEditImplementation( nullptr )
3555  ,m_bOwnEditImplementation( false )
3556 {
3557 
3558  DbTextField* pTextField = dynamic_cast<DbTextField*>( m_pCellControl.get() );
3559  if ( pTextField )
3560  {
3561 
3563  if ( !pTextField->IsSimpleEdit() )
3564  m_bFastPaint = false;
3565  }
3566  else
3567  {
3568  m_pEditImplementation = new EntryImplementation(static_cast<EditControlBase&>(m_pCellControl->GetWindow()));
3569  m_bOwnEditImplementation = true;
3570  }
3571 }
3572 
3574 {
3575  if (!OComponentHelper::rBHelper.bDisposed)
3576  {
3577  acquire();
3578  dispose();
3579  }
3580 
3581 
3582 }
3583 
3584 // OComponentHelper
3585 
3587 {
3588  css::lang::EventObject aEvt(*this);
3591 
3594  delete m_pEditImplementation;
3595  m_pEditImplementation = nullptr;
3596 
3598 }
3599 
3600 
3601 Any SAL_CALL FmXEditCell::queryAggregation( const css::uno::Type& _rType )
3602 {
3603  Any aReturn = FmXTextCell::queryAggregation( _rType );
3604 
3605  if ( !aReturn.hasValue() )
3606  aReturn = FmXEditCell_Base::queryInterface( _rType );
3607 
3608  return aReturn;
3609 }
3610 
3611 
3612 Sequence< css::uno::Type > SAL_CALL FmXEditCell::getTypes( )
3613 {
3614  return ::comphelper::concatSequences(
3617  );
3618 }
3619 
3620 
3622 
3623 // css::awt::XTextComponent
3624 
3625 void SAL_CALL FmXEditCell::addTextListener(const Reference< css::awt::XTextListener >& l)
3626 {
3627  m_aTextListeners.addInterface( l );
3628 }
3629 
3630 
3631 void SAL_CALL FmXEditCell::removeTextListener(const Reference< css::awt::XTextListener >& l)
3632 {
3634 }
3635 
3636 
3637 void SAL_CALL FmXEditCell::setText( const OUString& aText )
3638 {
3639  ::osl::MutexGuard aGuard( m_aMutex );
3640 
3641  if ( m_pEditImplementation )
3642  {
3643  m_pEditImplementation->SetText( aText );
3644 
3645  // In Java, a textChanged is fired as well; not in VCL.
3646  // css::awt::Toolkit must be Java-compliant...
3647  onTextChanged();
3648  }
3649 }
3650 
3651 
3652 void SAL_CALL FmXEditCell::insertText(const css::awt::Selection& rSel, const OUString& aText)
3653 {
3654  ::osl::MutexGuard aGuard( m_aMutex );
3655 
3656  if ( m_pEditImplementation )
3657  {
3658  m_pEditImplementation->SetSelection( Selection( rSel.Min, rSel.Max ) );
3659  m_pEditImplementation->ReplaceSelected( aText );
3660  }
3661 }
3662 
3663 
3664 OUString SAL_CALL FmXEditCell::getText()
3665 {
3666  ::osl::MutexGuard aGuard( m_aMutex );
3667 
3668  OUString aText;
3669  if ( m_pEditImplementation )
3670  {
3671  if ( m_pEditImplementation->GetControl().IsVisible() && m_pColumn->GetParent().getDisplaySynchron())
3672  {
3673  // if the display isn't sync with the cursor we can't ask the edit field
3674  LineEnd eLineEndFormat = getModelLineEndSetting( m_pColumn->getModel() );
3675  aText = m_pEditImplementation->GetText( eLineEndFormat );
3676  }
3677  else
3678  {
3679  Reference< css::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3680  if (xField.is())
3681  aText = GetText(xField, m_pColumn->GetParent().getNumberFormatter());
3682  }
3683  }
3684  return aText;
3685 }
3686 
3687 
3688 OUString SAL_CALL FmXEditCell::getSelectedText()
3689 {
3690  ::osl::MutexGuard aGuard( m_aMutex );
3691 
3692  OUString aText;
3693  if ( m_pEditImplementation )
3694  {
3695  LineEnd eLineEndFormat = m_pColumn ? getModelLineEndSetting( m_pColumn->getModel() ) : LINEEND_LF;
3696  aText = m_pEditImplementation->GetSelected( eLineEndFormat );
3697  }
3698  return aText;
3699 }
3700 
3701 
3702 void SAL_CALL FmXEditCell::setSelection( const css::awt::Selection& aSelection )
3703 {
3704  ::osl::MutexGuard aGuard( m_aMutex );
3705 
3706  if ( m_pEditImplementation )
3707  m_pEditImplementation->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
3708 }
3709 
3710 
3711 css::awt::Selection SAL_CALL FmXEditCell::getSelection()
3712 {
3713  ::osl::MutexGuard aGuard( m_aMutex );
3714 
3715  Selection aSel;
3716  if ( m_pEditImplementation )
3717  aSel = m_pEditImplementation->GetSelection();
3718 
3719  return css::awt::Selection(aSel.Min(), aSel.Max());
3720 }
3721 
3722 
3724 {
3725  ::osl::MutexGuard aGuard( m_aMutex );
3726 
3727  return m_pEditImplementation && !m_pEditImplementation->IsReadOnly() && m_pEditImplementation->GetControl().IsEnabled();
3728 }
3729 
3730 
3731 void SAL_CALL FmXEditCell::setEditable( sal_Bool bEditable )
3732 {
3733  ::osl::MutexGuard aGuard( m_aMutex );
3734 
3735  if ( m_pEditImplementation )
3736  m_pEditImplementation->SetReadOnly( !bEditable );
3737 }
3738 
3739 
3740 sal_Int16 SAL_CALL FmXEditCell::getMaxTextLen()
3741 {
3742  ::osl::MutexGuard aGuard( m_aMutex );
3743 
3744  return m_pEditImplementation ? m_pEditImplementation->GetMaxTextLen() : 0;
3745 }
3746 
3747 
3748 void SAL_CALL FmXEditCell::setMaxTextLen( sal_Int16 nLen )
3749 {
3750  ::osl::MutexGuard aGuard( m_aMutex );
3751 
3752  if ( m_pEditImplementation )
3753  m_pEditImplementation->SetMaxTextLen( nLen );
3754 }
3755 
3756 
3757 void SAL_CALL FmXEditCell::addChangeListener( const Reference< form::XChangeListener >& Listener )
3758 {
3759  m_aChangeListeners.addInterface( Listener );
3760 }
3761 
3762 
3763 void SAL_CALL FmXEditCell::removeChangeListener( const Reference< form::XChangeListener >& Listener )
3764 {
3765  m_aChangeListeners.removeInterface( Listener );
3766 }
3767 
3768 
3770 {
3771  css::awt::TextEvent aEvent;
3772  aEvent.Source = *this;
3773  m_aTextListeners.notifyEach( &awt::XTextListener::textChanged, aEvent );
3774 }
3775 
3776 
3777 void FmXEditCell::onFocusGained( const awt::FocusEvent& _rEvent )
3778 {
3779  FmXTextCell::onFocusGained( _rEvent );
3781 }
3782 
3783 
3784 void FmXEditCell::onFocusLost( const awt::FocusEvent& _rEvent )
3785 {
3786  FmXTextCell::onFocusLost( _rEvent );
3787 
3788  if ( getText() != m_sValueOnEnter )
3789  {
3790  lang::EventObject aEvent( *this );
3791  m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvent );
3792  }
3793 }
3794 
3795 
3796 void FmXEditCell::onWindowEvent( const VclEventId _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
3797 {
3798  switch ( _nEventId )
3799  {
3800  case VclEventId::EditModify:
3801  {
3803  onTextChanged();
3804  return;
3805  }
3806  default: break;
3807  }
3808 
3809  FmXTextCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
3810 }
3811 
3812 FmXCheckBoxCell::FmXCheckBoxCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3813  :FmXDataCell( pColumn, std::move(pControl) )
3814  ,m_aItemListeners(m_aMutex)
3815  ,m_aActionListeners( m_aMutex )
3816  ,m_pBox( & static_cast< CheckBoxControl& >( m_pCellControl->GetWindow() ).GetBox() )
3817 {
3818 }
3819 
3820 
3822 {
3823  if (!OComponentHelper::rBHelper.bDisposed)
3824  {
3825  acquire();
3826  dispose();
3827  }
3828 
3829 }
3830 
3831 // OComponentHelper
3832 
3834 {
3835  css::lang::EventObject aEvt(*this);
3838 
3839  static_cast< CheckBoxControl& >( m_pCellControl->GetWindow() ).SetClickHdl(Link<VclPtr<CheckBox>,void>());
3840  m_pBox = nullptr;
3841 
3843 }
3844 
3845 
3846 Any SAL_CALL FmXCheckBoxCell::queryAggregation( const css::uno::Type& _rType )
3847 {
3848  Any aReturn = FmXDataCell::queryAggregation( _rType );
3849 
3850  if ( !aReturn.hasValue() )
3851  aReturn = FmXCheckBoxCell_Base::queryInterface( _rType );
3852 
3853  return aReturn;
3854 }
3855 
3856 
3857 Sequence< css::uno::Type > SAL_CALL FmXCheckBoxCell::getTypes( )
3858 {
3859  return ::comphelper::concatSequences(
3862  );
3863 }
3864 
3865 
3867 
3868 
3869 void SAL_CALL FmXCheckBoxCell::addItemListener( const Reference< css::awt::XItemListener >& l )
3870 {
3871  m_aItemListeners.addInterface( l );
3872 }
3873 
3874 
3875 void SAL_CALL FmXCheckBoxCell::removeItemListener( const Reference< css::awt::XItemListener >& l )
3876 {
3878 }
3879 
3880 
3881 void SAL_CALL FmXCheckBoxCell::setState( sal_Int16 n )
3882 {
3883  ::osl::MutexGuard aGuard( m_aMutex );
3884 
3885  if (m_pBox)
3886  {
3887  UpdateFromColumn();
3888  m_pBox->SetState( static_cast<TriState>(n) );
3889  }
3890 }
3891 
3892 
3893 sal_Int16 SAL_CALL FmXCheckBoxCell::getState()
3894 {
3895  ::osl::MutexGuard aGuard( m_aMutex );
3896 
3897  if (m_pBox)
3898  {
3899  UpdateFromColumn();
3900  return static_cast<sal_Int16>(m_pBox->GetState());
3901  }
3902  return TRISTATE_INDET;
3903 }
3904 
3905 
3907 {
3908  ::osl::MutexGuard aGuard( m_aMutex );
3909 
3910  if (m_pBox)
3911  m_pBox->EnableTriState( b );
3912 }
3913 
3914 
3915 void SAL_CALL FmXCheckBoxCell::addActionListener( const Reference< awt::XActionListener >& Listener )
3916 {
3917  m_aActionListeners.addInterface( Listener );
3918 }
3919 
3920 
3921 void SAL_CALL FmXCheckBoxCell::removeActionListener( const Reference< awt::XActionListener >& Listener )
3922 {
3923  m_aActionListeners.removeInterface( Listener );
3924 }
3925 
3926 
3927 void SAL_CALL FmXCheckBoxCell::setLabel( const OUString& Label )
3928 {
3929  SolarMutexGuard aGuard;
3930  if ( m_pColumn )
3931  {
3932  DbGridControl& rGrid( m_pColumn->GetParent() );
3933  rGrid.SetColumnTitle( rGrid.GetColumnId( m_pColumn->GetFieldPos() ), Label );
3934  }
3935 }
3936 
3937 
3938 void SAL_CALL FmXCheckBoxCell::setActionCommand( const OUString& Command )
3939 {
3940  m_aActionCommand = Command;
3941 }
3942 
3943 
3945 {
3946  return m_pBox;
3947 }
3948 
3949 
3950 void FmXCheckBoxCell::onWindowEvent( const VclEventId _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
3951 {
3952  switch ( _nEventId )
3953  {
3954  case VclEventId::CheckboxToggle:
3955  {
3956  // check boxes are to be committed immediately (this holds for ordinary check box controls in
3957  // documents, and this must hold for check boxes in grid columns, too
3958  // 91210 - 22.08.2001 - frank.schoenheit@sun.com
3959  m_pCellControl->Commit();
3960 
3961  Reference< XWindow > xKeepAlive( this );
3962  if ( m_aItemListeners.getLength() && m_pBox )
3963  {
3964  awt::ItemEvent aEvent;
3965  aEvent.Source = *this;
3966  aEvent.Highlighted = 0;
3967  aEvent.Selected = m_pBox->GetState();
3968  m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
3969  }
3970  if ( m_aActionListeners.getLength() )
3971  {
3972  awt::ActionEvent aEvent;
3973  aEvent.Source = *this;
3974  aEvent.ActionCommand = m_aActionCommand;
3975  m_aActionListeners.notifyEach( &awt::XActionListener::actionPerformed, aEvent );
3976  }
3977  }
3978  break;
3979 
3980  default:
3981  FmXDataCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
3982  break;
3983  }
3984 }
3985 
3986 FmXListBoxCell::FmXListBoxCell(DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl)
3987  : FmXTextCell(pColumn, std::move(pControl))
3988  , m_aItemListeners(m_aMutex)
3989  , m_aActionListeners(m_aMutex)
3990  , m_pBox(&static_cast<svt::ListBoxControl&>(m_pCellControl->GetWindow()).get_widget())
3991 {
3992  m_pBox->connect_changed(LINK(this, FmXListBoxCell, ChangedHdl));
3993 }
3994 
3996 {
3997  if (!OComponentHelper::rBHelper.bDisposed)
3998  {
3999  acquire();
4000  dispose();
4001  }
4002 }
4003 
4004 // OComponentHelper
4006 {
4007  css::lang::EventObject aEvt(*this);
4010 
4012  m_pBox = nullptr;
4013 
4015 }
4016 
4018 
4020 {
4021  if (!m_pBox || !m_pBox->changed_by_direct_pick())
4022  return;
4023 
4024  OnDoubleClick();
4025 
4026  css::awt::ItemEvent aEvent;
4027  aEvent.Source = *this;
4028  aEvent.Highlighted = 0;
4029 
4030  // with multiple selection 0xFFFF, otherwise the ID
4031  aEvent.Selected = (m_pBox->get_active() != -1 )
4032  ? m_pBox->get_active() : 0xFFFF;
4033 
4034  m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4035  return;
4036 }
4037 
4039 {
4041 
4042  css::awt::ActionEvent aEvent;
4043  aEvent.Source = *this;
4044  aEvent.ActionCommand = m_pBox->get_active_text();
4045 
4046  while( aIt.hasMoreElements() )
4047  static_cast< css::awt::XActionListener *>(aIt.next())->actionPerformed( aEvent );
4048 }
4049 
4050 FmXComboBoxCell::FmXComboBoxCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
4051  :FmXTextCell( pColumn, std::move(pControl) )
4052  ,m_aItemListeners( m_aMutex )
4053  ,m_aActionListeners( m_aMutex )
4054  ,m_pComboBox(&static_cast<ComboBoxControl&>(m_pCellControl->GetWindow()).get_widget())
4055  ,m_nLines(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())
4056 {
4057  m_pComboBox->connect_changed(LINK(this, FmXComboBoxCell, ChangedHdl));
4058 }
4059 
4061 {
4062  if ( !OComponentHelper::rBHelper.bDisposed )
4063  {
4064  acquire();
4065  dispose();
4066  }
4067 
4068 }
4069 
4071 {
4072  css::lang::EventObject aEvt(*this);
4075 
4077  m_pComboBox = nullptr;
4078 
4080 }
4081 
4082 Any SAL_CALL FmXComboBoxCell::queryAggregation( const css::uno::Type& _rType )
4083 {
4084  Any aReturn = FmXTextCell::queryAggregation(_rType);
4085 
4086  if ( !aReturn.hasValue() )
4087  aReturn = FmXComboBoxCell_Base::queryInterface( _rType );
4088 
4089  return aReturn;
4090 }
4091 
4092 Sequence< Type > SAL_CALL FmXComboBoxCell::getTypes( )
4093 {
4094  return ::comphelper::concatSequences(
4097  );
4098 }
4099 
4101 
4102 void SAL_CALL FmXComboBoxCell::addItemListener(const Reference< awt::XItemListener >& l)
4103 {
4104  m_aItemListeners.addInterface( l );
4105 }
4106 
4107 void SAL_CALL FmXComboBoxCell::removeItemListener(const Reference< awt::XItemListener >& l)
4108 {
4110 }
4111 
4112 void SAL_CALL FmXComboBoxCell::addActionListener(const Reference< awt::XActionListener >& l)
4113 {
4115 }
4116 
4117 
4118 void SAL_CALL FmXComboBoxCell::removeActionListener(const Reference< awt::XActionListener >& l)
4119 {
4121 }
4122 
4123 void SAL_CALL FmXComboBoxCell::addItem( const OUString& Item, sal_Int16 Pos )
4124 {
4125  ::osl::MutexGuard aGuard( m_aMutex );
4126  if (!m_pComboBox)
4127  return;
4128  m_pComboBox->insert_text(Pos, Item);
4129 }
4130 
4131 void SAL_CALL FmXComboBoxCell::addItems( const Sequence< OUString >& Items, sal_Int16 Pos )
4132 {
4133  ::osl::MutexGuard aGuard( m_aMutex );
4134  if (!m_pComboBox)
4135  return;
4136  sal_uInt16 nP = Pos;
4137  for ( const auto& rItem : Items )
4138  {
4139  m_pComboBox->insert_text(nP, rItem);
4140  if ( Pos != -1 )
4141  nP++;
4142  }
4143 }
4144 
4145 void SAL_CALL FmXComboBoxCell::removeItems( sal_Int16 Pos, sal_Int16 Count )
4146 {
4147  ::osl::MutexGuard aGuard( m_aMutex );
4148  if (!m_pComboBox)
4149  return;
4150  for ( sal_uInt16 n = Count; n; )
4151  m_pComboBox->remove( Pos + (--n) );
4152 }
4153 
4154 sal_Int16 SAL_CALL FmXComboBoxCell::getItemCount()
4155 {
4156  ::osl::MutexGuard aGuard( m_aMutex );
4157  if (!m_pComboBox)
4158  return 0;
4159  return m_pComboBox->get_count();
4160 }
4161 
4162 OUString SAL_CALL FmXComboBoxCell::getItem( sal_Int16 Pos )
4163 {
4164  ::osl::MutexGuard aGuard( m_aMutex );
4165  if (!m_pComboBox)
4166  return OUString();
4167  return m_pComboBox->get_text(Pos);
4168 }
4169 
4171 {
4172  ::osl::MutexGuard aGuard( m_aMutex );
4173 
4174  Sequence< OUString > aItems;
4175  if (m_pComboBox)
4176  {
4177  const sal_Int32 nEntries = m_pComboBox->get_count();
4178  aItems.realloc( nEntries );
4179  OUString* pItem = aItems.getArray();
4180  for ( sal_Int32 n=0; n<nEntries; ++n, ++pItem )
4181  *pItem = m_pComboBox->get_text(n);
4182  }
4183  return aItems;
4184 }
4185 
4187 {
4188  ::osl::MutexGuard aGuard( m_aMutex );
4189  return m_nLines;
4190 }
4191 
4192 void SAL_CALL FmXComboBoxCell::setDropDownLineCount(sal_Int16 nLines)
4193 {
4194  ::osl::MutexGuard aGuard( m_aMutex );
4195  m_nLines = nLines; // just store it to return it
4196 }
4197 
4199 {
4200  if (!m_pComboBox || !m_pComboBox->changed_by_direct_pick())
4201  return;
4202 
4203  awt::ItemEvent aEvent;
4204  aEvent.Source = *this;
4205  aEvent.Highlighted = 0;
4206 
4207  // with invalid selection 0xFFFF, otherwise the position
4208  aEvent.Selected = ( m_pComboBox->get_active() != -1 )
4209  ? m_pComboBox->get_active()
4210  : 0xFFFF;
4211  m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4212 }
4213 
4214 FmXFilterCell::FmXFilterCell(DbGridColumn* pColumn, std::unique_ptr<DbFilterField> pControl )
4215  :FmXGridCell( pColumn, std::move(pControl) )
4216  ,m_aTextListeners(m_aMutex)
4217 {
4218  static_cast<DbFilterField*>(m_pCellControl.get())->SetCommitHdl( LINK( this, FmXFilterCell, OnCommit ) );
4219 }
4220 
4222 {
4223  if (!OComponentHelper::rBHelper.bDisposed)
4224  {
4225  acquire();
4226  dispose();
4227  }
4228 
4229 }
4230 
4231 // XUnoTunnel
4232 sal_Int64 SAL_CALL FmXFilterCell::getSomething( const Sequence< sal_Int8 >& _rIdentifier )
4233 {
4234  sal_Int64 nReturn(0);
4235 
4236  if ( isUnoTunnelId<FmXFilterCell>(_rIdentifier) )
4237  {
4238  nReturn = reinterpret_cast<sal_Int64>(this);
4239  }
4240 
4241  return nReturn;
4242 }
4243 
4244 namespace
4245 {
4246  class theFmXFilterCellUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theFmXFilterCellUnoTunnelId > {};
4247 }
4248 
4249 const Sequence<sal_Int8>& FmXFilterCell::getUnoTunnelId()
4250 {
4251  return theFmXFilterCellUnoTunnelId::get().getSeq();
4252 }
4253 
4254 
4256 {
4257  static_cast< DbFilterField* >( m_pCellControl.get() )->PaintCell( rDev, rRect );
4258 }
4259 
4260 // OComponentHelper
4261 
4263 {
4264  css::lang::EventObject aEvt(*this);
4266 
4267  static_cast<DbFilterField*>(m_pCellControl.get())->SetCommitHdl(Link<DbFilterField&,void>());
4268 
4270 }
4271 
4272 
4273 Any SAL_CALL FmXFilterCell::queryAggregation( const css::uno::Type& _rType )
4274 {
4275  Any aReturn = FmXGridCell::queryAggregation(_rType);
4276 
4277  if ( !aReturn.hasValue() )
4278  aReturn = FmXFilterCell_Base::queryInterface( _rType );
4279 
4280  return aReturn;
4281 }
4282 
4283 
4284 Sequence< css::uno::Type > SAL_CALL FmXFilterCell::getTypes( )
4285 {
4286  return ::comphelper::concatSequences(
4289  );
4290 }
4291 
4292 
4294 
4295 // css::awt::XTextComponent
4296 
4297 void SAL_CALL FmXFilterCell::addTextListener(const Reference< css::awt::XTextListener >& l)
4298 {
4299  m_aTextListeners.addInterface( l );
4300 }
4301 
4302 
4303 void SAL_CALL FmXFilterCell::removeTextListener(const Reference< css::awt::XTextListener >& l)
4304 {
4306 }
4307 
4308 
4309 void SAL_CALL FmXFilterCell::setText( const OUString& aText )
4310 {
4311  ::osl::MutexGuard aGuard( m_aMutex );
4312  static_cast<DbFilterField*>(m_pCellControl.get())->SetText(aText);
4313 }
4314 
4315 
4316 void SAL_CALL FmXFilterCell::insertText( const css::awt::Selection& /*rSel*/, const OUString& /*aText*/ )
4317 {
4318 }
4319 
4320 
4321 OUString SAL_CALL FmXFilterCell::getText()
4322 {
4323  ::osl::MutexGuard aGuard( m_aMutex );
4324  return static_cast<DbFilterField*>(m_pCellControl.get())->GetText();
4325 }
4326 
4327 
4329 {
4330  return getText();
4331 }
4332 
4333 
4334 void SAL_CALL FmXFilterCell::setSelection( const css::awt::Selection& /*aSelection*/ )
4335 {
4336 }
4337 
4338 
4339 css::awt::Selection SAL_CALL FmXFilterCell::getSelection()
4340 {
4341  return css::awt::Selection();
4342 }
4343 
4344 
4346 {
4347  return true;
4348 }
4349 
4350 
4351 void SAL_CALL FmXFilterCell::setEditable( sal_Bool /*bEditable*/ )
4352 {
4353 }
4354 
4355 
4356 sal_Int16 SAL_CALL FmXFilterCell::getMaxTextLen()
4357 {
4358  return 0;
4359 }
4360 
4361 
4362 void SAL_CALL FmXFilterCell::setMaxTextLen( sal_Int16 /*nLen*/ )
4363 {
4364 }
4365 
4366 
4368 {
4369  ::comphelper::OInterfaceIteratorHelper2 aIt( m_aTextListeners );
4370  css::awt::TextEvent aEvt;
4371  aEvt.Source = *this;
4372  while( aIt.hasMoreElements() )
4373  static_cast< css::awt::XTextListener *>(aIt.next())->textChanged( aEvt );
4374 }
4375 
4376 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual vcl::Window * getEventWindow() const override
Definition: gridcell.cxx:3944
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:4131
void SetFormatKey(sal_uLong nFormatKey)
bool is() const
const css::uno::Reference< css::beans::XPropertySet > & getModel() const
Definition: gridcell.hxx:122
#define FM_PROP_DATEMIN
Definition: fmprop.hxx:83
const Color & GetTextColor() const
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, MetricVector *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
void OnDoubleClick()
Definition: gridcell.cxx:4038
OutDevType GetOutDevType() const
bool IsControlBackground() const
virtual sal_Int16 SAL_CALL getState() override
Definition: gridcell.cxx:3893
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:3337
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:2807
weld::ComboBox * m_pBox
Definition: gridcell.hxx:974
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
const Wallpaper & GetBackground() const
virtual void SAL_CALL enableTriState(sal_Bool b) override
Definition: gridcell.cxx:3906
bool m_bObject
Definition: gridcell.hxx:94
virtual void SAL_CALL addActionListener(const css::uno::Reference< css::awt::XActionListener > &l) override
Definition: gridcell.cxx:3915
virtual void UpdateFromField(const css::uno::Reference< css::sdb::XColumn > &_rxField, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter) override
Definition: gridcell.cxx:1699
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:3225
#define FM_PROP_DECIMAL_ACCURACY
Definition: fmprop.hxx:72
virtual bool commitControl() override
commits the content of the control (e.g.
Definition: gridcell.cxx:1209
DbCurrencyField(DbGridColumn &_rColumn)
Definition: gridcell.cxx:2021
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:3702
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: gridcell.cxx:3612
#define FM_PROP_FIELDSOURCE
Definition: fmprop.hxx:108
FmXFilterCell(DbGridColumn *pColumn, std::unique_ptr< DbFilterField > pControl)
Definition: gridcell.cxx:4214
FmXTextCell(DbGridColumn *pColumn, std::unique_ptr< DbCellControl > pControl)
Definition: gridcell.cxx:3496
void PaintCell(OutputDevice &rDev, const tools::Rectangle &rRect)
Definition: gridcell.cxx:4255
#define FM_PROP_FORMATSSUPPLIER
Definition: fmprop.hxx:66
osl::Mutex m_aMutex
DbComboBox(DbGridColumn &_rColumn)
Definition: gridcell.cxx:2408
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:2124
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:1146
virtual void implSetEffectiveMaxTextLen(sal_Int32 _nMaxLen) override
Definition: gridcell.cxx:1227
#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:2488
virtual void SAL_CALL setText(const OUString &aText) override
Definition: gridcell.cxx:4309
virtual void SAL_CALL disposing() override
Definition: gridcell.cxx:4005
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
const LanguageTag & GetUILanguageTag() const
void insert_text(int pos, const OUString &rStr)
virtual void implSetEffectiveMaxTextLen(sal_Int32 _nMaxLen)
Definition: gridcell.cxx:1044
DbPatternField(DbGridColumn &_rColumn, const css::uno::Reference< css::uno::XComponentContext > &_rContext)
Definition: gridcell.cxx:1737
virtual SelectionOptions GetEntrySelectionOptions() const override
virtual ~DbFormattedField() override
Definition: gridcell.cxx:1242
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:1246
void SetStyleSettings(const StyleSettings &rSet)
::comphelper::OInterfaceContainerHelper2 m_aItemListeners
Definition: gridcell.hxx:915
const Color & GetTextLineColor() const
#define FM_PROP_VALUE_SEQ
Definition: fmprop.hxx:70
sal_Int16 m_nControlClass
Definition: gridcell.hxx:688
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &_rType) override
Definition: gridcell.cxx:4082
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:2429
virtual OUString SAL_CALL getText() override
Definition: gridcell.cxx:3664
SelectionOptions GetSelectionOptions() const
virtual void Init(vcl::Window &rParent, const css::uno::Reference< css::sdbc::XRowSet > &xCursor) override
Definition: gridcell.cxx:2565
virtual void Init(vcl::Window &rParent, const css::uno::Reference< css::sdbc::XRowSet > &xCursor) override
Definition: gridcell.cxx:2769
SelectionOptions
virtual OUString get_text(int pos) const =0
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:2614
bool IsNew() const
Definition: gridctrl.hxx:88
FmXEditCell(DbGridColumn *pColumn, std::unique_ptr< DbCellControl > pControl)
Definition: gridcell.cxx:3550
MouseEventModifiers GetMode() const
SvNumberFormatter * StandardFormatter()
virtual void SAL_CALL setMaxTextLen(sal_Int16 nLen) override
Definition: gridcell.cxx:3748
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
virtual void SAL_CALL setVisible(sal_Bool Visible) override
Definition: gridcell.cxx:3267
sal_Int32 addInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
bool getBOOL(const Any &_rAny)
sal_Int16 m_nFieldType
Definition: gridcell.hxx:85
virtual bool commitControl() override
commits the content of the control (e.g.
Definition: gridcell.cxx:2006
bool IsTextLineColor() const
void ImplInitWindow(vcl::Window const &rParent, const InitWindowFacet _eInitWhat)
Definition: gridcell.cxx:518
virtual sal_Bool SAL_CALL isEditable() override
Definition: gridcell.cxx:4345
virtual void UpdateFromField(const css::uno::Reference< css::sdb::XColumn > &_rxField, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter) override
Definition: gridcell.cxx:1528
sal_Int64 n
virtual void _propertyChanged(const css::beans::PropertyChangeEvent &evt) override
Definition: gridcell.cxx:1460
#define FM_PROP_MULTILINE
Definition: fmprop.hxx:51
#define FM_PROP_TIMEMIN
Definition: fmprop.hxx:87
Any GetTime(const OUString &val)
css::beans::Optional< css::uno::Any > getValue(OUString const &id)
exports com.sun.star. awt
void CreateControl(sal_Int32 _nFieldPos, const css::uno::Reference< css::beans::XPropertySet > &xField, sal_Int32 nTypeId)
Definition: gridcell.cxx:140
virtual void SetSizePixel(const Size &rNewSize)
WinBits const WB_RIGHT
virtual bool commitControl() override
commits the content of the control (e.g.
Definition: gridcell.cxx:2643
virtual void SAL_CALL setEditable(sal_Bool bEditable) override
Definition: gridcell.cxx:3731
vcl::Window & GetDataWindow() const
sal_Int32 m_nFormatKey
Definition: gridcell.hxx:84
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
Definition: gridcell.cxx:4249
void disposeAndClear(const css::lang::EventObject &rEvt)
sal_Int32 getElementPos(const Reference< css::container::XIndexAccess > &xCont, const Reference< XInterface > &xElement)
Definition: fmtools.cxx:128
FmXListBoxCell(DbGridColumn *pColumn, std::unique_ptr< DbCellControl > pControl)
Definition: gridcell.cxx:3986
void SetTextFillColor()
virtual void DeactivateCell(bool bUpdate=true)
void SetDefaultValue(double dDefault)
virtual bool commitControl() override
commits the content of the control (e.g.
Definition: gridcell.cxx:1594
virtual OUString SAL_CALL getItem(::sal_Int16 Pos) override
Definition: gridcell.cxx:4162
void implSetMaxTextLen(sal_Int16 _nMaxLen)
Definition: gridcell.hxx:372
sal_Int16 GetFieldPos() const
Definition: gridcell.hxx:130
virtual ~FmXFilterCell() override
Definition: gridcell.cxx:4221
virtual sal_Int16 SAL_CALL getMaxTextLen() override
Definition: gridcell.cxx:4356
const css::uno::Reference< css::sdbc::XRowSet > & getCursor() const
Definition: gridcell.hxx:219
void SetParentUpdateMode(bool bUpdate)
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:1982
void init()
Definition: gridcell.cxx:3128
virtual void SetSettings(const AllSettings &rSettings) override
const Color & GetControlBackground() const
virtual void ActivateCell(long nRow, sal_uInt16 nCol, bool bSetCellFocus=true)
sal_Int32 removeInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
virtual void PaintCell(OutputDevice &_rDev, const tools::Rectangle &_rRect)
Definition: gridcell.cxx:949
bool IsControlFont() const
virtual void SAL_CALL removeFocusListener(const css::uno::Reference< css::awt::XFocusListener > &xListener) override
Definition: gridcell.cxx:3309
void SetState(TriState eState)
virtual void SAL_CALL addKeyListener(const css::uno::Reference< css::awt::XKeyListener > &xListener) override
Definition: gridcell.cxx:3316
sal_Int16 m_nStandardAlign
Definition: gridcell.hxx:536
virtual void SAL_CALL addWindowListener(const css::uno::Reference< css::awt::XWindowListener > &xListener) override
Definition: gridcell.cxx:3288
sal_Int16 SetAlignmentFromModel(sal_Int16 nStandardAlign)
Definition: gridcell.cxx:377
virtual void PaintFieldToCell(OutputDevice &_rDev, const tools::Rectangle &_rRect, const css::uno::Reference< css::sdb::XColumn > &_rxField, const css::uno::Reference< css::util::XNumberFormatter > &_rxFormatter) override
Definition: gridcell.cxx:1152
LINEEND_CR
virtual void SAL_CALL addPaintListener(const css::uno::Reference< css::awt::XPaintListener > &xListener) override
Definition: gridcell.cxx:3358
Reference< XNumberFormatsSupplier > getNumberFormats(const Reference< XConnection > &_rxConn, bool _bAlloweDefault, const Reference< XComponentContext > &_rxContext)
bool bReadOnly
virtual int get_active() const =0
#define FM_PROP_DATE_SHOW_CENTURY
Definition: fmprop.hxx:85
rtl::Reference< FmXGridCell > m_pCell
Definition: gridcell.hxx:77
void PaintImmediately()
#define FM_PROP_STRINGITEMLIST
Definition: fmprop.hxx:59
virtual void set_text(const OUString &rText)=0
TRISTATE_TRUE
DbLimitedLengthField(DbGridColumn &_rColumn)
Definition: gridcell.cxx:1025
#define FM_PROP_AUTOINCREMENT
Definition: fmprop.hxx:48
::comphelper::OInterfaceContainerHelper2 m_aTextListeners
Definition: gridcell.hxx:1066
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:1478
const vcl::Font & GetFieldFont() const
bool IsNumeric() const
Definition: gridcell.hxx:131
bool m_bLocked
Definition: gridcell.hxx:96
void SetMinValue(double dMin)
DbCellControl(DbGridColumn &_rColumn)
Definition: gridcell.cxx:528
static void lcl_clearBroadCaster(rtl::Reference<::comphelper::OPropertyChangeMultiplexer > &_pBroadcaster)
Definition: gridcell.cxx:606
void implAdjustReadOnly(const css::uno::Reference< css::beans::XPropertySet > &_rxModel, bool i_bReadOnly)
updates the "readonly" setting on m_pWindow, according to the respective property value in the given ...
Definition: gridcell.cxx:809
virtual bool commitControl() override
commits the content of the control (e.g.
Definition: gridcell.cxx:2287
virtual void SAL_CALL setActionCommand(const OUString &Command) override
Definition: gridcell.cxx:3938
virtual int get_count() const =0
#define TYPE_CHECKBOX
Definition: gridcols.hxx:37
css::uno::Sequence< OUString > m_aValueList
Definition: gridcell.hxx:685
virtual void UpdateFromField(const css::uno::Reference< css::sdb::XColumn > &_rxField, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter) override
Definition: gridcell.cxx:2130
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
::std::unique_ptr< ::dbtools::FormattedColumnValue > m_pPaintFormatter
Definition: gridcell.hxx:528
FmXGridCell(DbGridColumn *pColumn, std::unique_ptr< DbCellControl > pControl)
Definition: gridcell.cxx:3115
virtual void onWindowEvent(const VclEventId _nEventId, const vcl::Window &_rWindow, const void *_pEventData) override
Definition: gridcell.cxx:3796
IMPL_LINK_NOARG(DbFilterField, OnClick, VclPtr< CheckBox >, void)
Definition: gridcell.cxx:3083
virtual void SAL_CALL removeKeyListener(const css::uno::Reference< css::awt::XKeyListener > &xListener) override
Definition: gridcell.cxx:3323
css::uno::Reference< css::sdb::XColumn > GetCurrentFieldValue() const
Definition: gridcell.cxx:439
bool IsFilterMode() const
Definition: gridctrl.hxx:430
OOO_DLLPUBLIC_DBTOOLS OUString getFormattedValue(const css::uno::Reference< css::beans::XPropertySet > &_xColumn, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter, const css::lang::Locale &_rLocale, const css::util::Date &rNullDate)
#define FM_PROP_NAME
Definition: fmprop.hxx:29
const Fraction & GetZoom() const
VclPtr< vcl::Window > m_pPainter
Definition: gridcell.hxx:214
virtual void onFocusGained(const css::awt::FocusEvent &_rEvent)
Definition: gridcell.cxx:3377
#define TYPE_PATTERNFIELD
Definition: gridcols.hxx:44
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: gridcell.hxx:529
#define FM_PROP_LITERALMASK
Definition: fmprop.hxx:79
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getContext() override
Definition: gridcell.cxx:3219
virtual void _propertyChanged(const css::beans::PropertyChangeEvent &evt) override
Definition: gridcell.cxx:2417
DECL_LISTENERMULTIPLEXER_END void SAL_CALL actionPerformed(const css::awt::ActionEvent &rEvent) override
virtual bool commitControl()=0
commits the content of the control (e.g.
sal_Int64 WinBits
::svt::IEditImplementation * m_pEditImplementation
Definition: gridcell.hxx:904
void SetBackground()
Reference< XController > xController
::comphelper::OInterfaceContainerHelper2 m_aChangeListeners
Definition: gridcell.hxx:903
virtual ::svt::CellControllerRef CreateController() const override
Definition: gridcell.cxx:2474
virtual void SAL_CALL setText(const OUString &aText) override
Definition: gridcell.cxx:3637
bool HasField(sal_uInt32 nPos) const
Definition: gridctrl.hxx:82
#define FM_PROP_TRISTATE
Definition: fmprop.hxx:58
bool isTransparent() const
Definition: gridcell.hxx:222
void Enable(bool bEnable=true, bool bChild=true)
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: gridcell.cxx:3170
void implAdjustEnabled(const css::uno::Reference< css::beans::XPropertySet > &_rxModel)
updates the "enabled" setting on m_pWindow, according to the respective property value in the given m...
Definition: gridcell.cxx:829
const css::uno::Reference< css::beans::XPropertySet > & GetField() const
Definition: gridcell.hxx:135
css::uno::Reference< css::sdbc::XRowSet > m_xCursor
Definition: gridcell.hxx:210
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
virtual void Update() override
Definition: gridcell.cxx:2952
OUTDEV_WINDOW
const vcl::Font & GetFont() const
void implAdjustGenericFieldSetting(const css::uno::Reference< css::beans::XPropertySet > &_rxModel) override
initializes everything which relates to the properties describing the numeric behaviour ...
Definition: gridcell.cxx:1894
bool IsControlForeground() const
bool IsEnterWindow() const
CursorWrapper * getDataSource() const
Definition: gridctrl.hxx:403
double GetValue()
virtual bool commitControl() override
commits the content of the control (e.g.
Definition: gridcell.cxx:2839
virtual void updateFromModel(css::uno::Reference< css::beans::XPropertySet > _rxModel) override
updates the current content of the control (e.g.
Definition: gridcell.cxx:2275
void TreatAsNumber(bool bDoSo)
#define FM_PROP_CLASSID
Definition: fmprop.hxx:30
void SetOptions(StyleSettingsOptions nOptions)
#define FM_PROP_BOUNDFIELD
Definition: fmprop.hxx:101
virtual void SAL_CALL addChangeListener(const css::uno::Reference< css::form::XChangeListener > &aListener) override
Definition: gridcell.cxx:3757
bool m_bIsSimpleEdit
Definition: gridcell.hxx:384
VclEventId
#define TYPE_NUMERICFIELD
Definition: gridcols.hxx:43
virtual bool commitControl() override
commits the content of the control (e.g.
Definition: gridcell.cxx:2507
const css::uno::Reference< css::sdb::XColumn > & getColumn() const
const css::uno::Reference< css::util::XNumberFormatter > & getNumberFormatter() const
Definition: gridctrl.hxx:395
virtual void SAL_CALL addActionListener(const css::uno::Reference< css::awt::XActionListener > &Listener) override
Definition: gridcell.cxx:4112
virtual sal_Bool SAL_CALL isEditable() override
Definition: gridcell.cxx:3723
virtual OUString GetText() const
virtual void UpdateFromField(const css::uno::Reference< css::sdb::XColumn > &_rxField, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter) override
Definition: gridcell.cxx:1822
uno::Reference< sdbc::XRow > xRow
#define FM_PROP_EFFECTIVE_VALUE
Definition: fmprop.hxx:102
#define TYPE_CURRENCYFIELD
Definition: gridcols.hxx:39
#define FM_PROP_SPIN
Definition: fmprop.hxx:45
::comphelper::OInterfaceContainerHelper2 m_aActionListeners
Definition: gridcell.hxx:972
virtual void SAL_CALL addMouseMotionListener(const css::uno::Reference< css::awt::XMouseMotionListener > &xListener) override
Definition: gridcell.cxx:3344
::comphelper::OInterfaceContainerHelper2 m_aMouseListeners
Definition: gridcell.hxx:714
virtual void SAL_CALL insertText(const css::awt::Selection &Sel, const OUString &Text) override
Definition: gridcell.cxx:3652
TRISTATE_INDET
#define TYPE_TEXTFIELD
Definition: gridcols.hxx:45
virtual void SAL_CALL setEditable(sal_Bool bEditable) override
Definition: gridcell.cxx:4351
::comphelper::OInterfaceContainerHelper2 m_aItemListeners
Definition: gridcell.hxx:984
::svt::CellControllerRef s_xEmptyController
Definition: gridcell.hxx:98
virtual bool commitControl() override
commits the content of the control (e.g.
Definition: gridcell.cxx:2395
TriState GetState() const
void SetTextLineColor()
void SetTextFormatted(const OUString &rText)
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:1732
sal_Int16 m_nAlign
Definition: gridcell.hxx:89
sal_Int16 getINT16(const Any &_rAny)
#define FM_PROP_TIME
Definition: fmprop.hxx:56
const Color & GetControlForeground() const
bool m_bFilterList
Definition: gridcell.hxx:689
void SetFormatter(SvNumberFormatter *pFormatter, bool bResetFormat=true)
virtual css::uno::Sequence< OUString > SAL_CALL getItems() override
Definition: gridcell.cxx:4170
virtual void UpdateFromField(const css::uno::Reference< css::sdb::XColumn > &_rxField, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter) override
Definition: gridcell.cxx:1987
virtual css::awt::Selection SAL_CALL getSelection() override
Definition: gridcell.cxx:4339
sal_Int16 GetAlignment() const
Definition: gridcell.hxx:129
virtual ::sal_Int16 SAL_CALL getDropDownLineCount() override
Definition: gridcell.cxx:4186
bool isAlignedController() const
Definition: gridcell.hxx:273