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 #include <core_resource.hxx>
21 #include <FieldDescControl.hxx>
22 #include <FieldControls.hxx>
23 #include <comphelper/diagnose_ex.hxx>
24 #include <TableDesignHelpBar.hxx>
25 #include <vcl/svapp.hxx>
26 #include <FieldDescriptions.hxx>
27 #include <svl/numuno.hxx>
28 #include <vcl/transfer.hxx>
29 #include <com/sun/star/sdbc/ColumnValue.hpp>
30 #include <com/sun/star/util/NumberFormat.hpp>
31 #include <com/sun/star/util/XNumberFormatPreviewer.hpp>
32 #include <com/sun/star/util/XNumberFormatTypes.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <QEnumTypes.hxx>
35 #include <helpids.h>
36 #include <connectivity/dbtools.hxx>
37 #include <connectivity/dbconversion.hxx>
38 #include <comphelper/numbers.hxx>
39 #include <comphelper/types.hxx>
40 #include <UITools.hxx>
41 #include <strings.hrc>
42 #include <osl/diagnose.h>
43
44 using namespace dbaui;
45 using namespace dbtools;
46 using namespace ::com::sun::star::uno;
47 using namespace ::com::sun::star::beans;
48 using namespace ::com::sun::star::lang;
49 using namespace ::com::sun::star::sdbc;
50 using namespace ::com::sun::star::util;
51
52 namespace
53 {
lcl_HideAndDeleteControl(short & _nPos,std::unique_ptr<T1> & _pControl,std::unique_ptr<T2> & _pControlText)54 template< typename T1, typename T2> void lcl_HideAndDeleteControl(short& _nPos,std::unique_ptr<T1>& _pControl, std::unique_ptr<T2>& _pControlText)
55 {
56 if ( _pControl )
57 {
58 --_nPos;
59 _pControl->hide();
60 _pControlText->hide();
61 _pControl.reset();
62 _pControlText.reset();
63 }
64 }
65 }
66
OFieldDescControl(weld::Container * pPage,OTableDesignHelpBar * pHelpBar)67 OFieldDescControl::OFieldDescControl(weld::Container* pPage, OTableDesignHelpBar* pHelpBar)
68 : m_xBuilder(Application::CreateBuilder(pPage, u"dbaccess/ui/fielddescpage.ui"_ustr))
69 , m_xContainer(m_xBuilder->weld_container(u"FieldDescPage"_ustr))
70 , m_pHelp( pHelpBar )
71 , m_pLastFocusWindow(nullptr)
72 , m_pActFocusWindow(nullptr)
73 , m_nPos(-1)
74 , aYes(DBA_RES(STR_VALUE_YES))
75 , aNo(DBA_RES(STR_VALUE_NO))
76 , m_nEditWidth(50)
77 , pActFieldDescr(nullptr)
78 {
79 if (m_pHelp)
80 m_pHelp->connect_focus_out(LINK(this, OFieldDescControl, HelpFocusOut));
81 }
82
~OFieldDescControl()83 OFieldDescControl::~OFieldDescControl()
84 {
85 dispose();
86 }
87
dispose()88 void OFieldDescControl::dispose()
89 {
90 // Destroy children
91 DeactivateAggregate( tpDefault );
92 DeactivateAggregate( tpRequired );
93 DeactivateAggregate( tpTextLen );
94 DeactivateAggregate( tpNumType );
95 DeactivateAggregate( tpScale );
96 DeactivateAggregate( tpLength );
97 DeactivateAggregate( tpFormat );
98 DeactivateAggregate( tpAutoIncrement );
99 DeactivateAggregate( tpBoolDefault );
100 DeactivateAggregate( tpColumnName );
101 DeactivateAggregate( tpType );
102 DeactivateAggregate( tpAutoIncrementValue );
103 m_pHelp = nullptr;
104 m_pLastFocusWindow = nullptr;
105 m_pActFocusWindow = nullptr;
106 m_xDefaultText.reset();
107 m_xRequiredText.reset();
108 m_xAutoIncrementText.reset();
109 m_xTextLenText.reset();
110 m_xNumTypeText.reset();
111 m_xLengthText.reset();
112 m_xScaleText.reset();
113 m_xFormatText.reset();
114 m_xBoolDefaultText.reset();
115 m_xColumnNameText.reset();
116 m_xTypeText.reset();
117 m_xAutoIncrementValueText.reset();
118 m_xRequired.reset();
119 m_xNumType.reset();
120 m_xAutoIncrement.reset();
121 m_xDefault.reset();
122 m_xTextLen.reset();
123 m_xLength.reset();
124 m_xScale.reset();
125 m_xFormatSample.reset();
126 m_xBoolDefault.reset();
127 m_xColumnName.reset();
128 m_xType.reset();
129 m_xAutoIncrementValue.reset();
130 m_xFormat.reset();
131 m_xContainer.reset();
132 m_xBuilder.reset();
133 }
134
BoolStringPersistent(std::u16string_view rUIString) const135 OUString OFieldDescControl::BoolStringPersistent(std::u16string_view rUIString) const
136 {
137 if (rUIString == aNo)
138 return OUString('0');
139 if (rUIString == aYes)
140 return OUString('1');
141 return OUString();
142 }
143
BoolStringUI(const OUString & rPersistentString) const144 OUString OFieldDescControl::BoolStringUI(const OUString& rPersistentString) const
145 {
146 // Older versions may store a language dependent string as a default
147 if (rPersistentString == aYes || rPersistentString == aNo)
148 return rPersistentString;
149
150 if (rPersistentString == "0")
151 return aNo;
152 if (rPersistentString == "1")
153 return aYes;
154
155 return DBA_RES(STR_VALUE_NONE);
156 }
157
Init()158 void OFieldDescControl::Init()
159 {
160 Reference< css::util::XNumberFormatter > xFormatter = GetFormatter();
161 ::dbaui::setEvalDateFormatForFormatter(xFormatter);
162 }
163
SetReadOnly(bool bReadOnly)164 void OFieldDescControl::SetReadOnly( bool bReadOnly )
165 {
166 // Enable/disable Controls
167 struct final
168 {
169 OWidgetBase * aggregate;
170 weld::Widget * text;
171 } const aggregates[] = {
172 {m_xRequired.get(), m_xRequiredText.get()}
173 , {m_xNumType.get(), m_xNumTypeText.get()}
174 , {m_xAutoIncrement.get(), m_xAutoIncrementText.get()}
175 , {m_xDefault.get(), m_xDefaultText.get()}
176 , {m_xTextLen.get(), m_xTextLenText.get()}
177 , {m_xLength.get(), m_xLengthText.get()}
178 , {m_xScale.get(), m_xScaleText.get()}
179 , {m_xColumnName.get(), m_xColumnNameText.get()}
180 , {m_xType.get(), m_xTypeText.get()}
181 , {m_xAutoIncrementValue.get(), m_xAutoIncrementValueText.get()}};
182
183 for (auto const & aggregate: aggregates)
184 {
185 if (aggregate.text)
186 aggregate.text->set_sensitive(!bReadOnly);
187 if (aggregate.aggregate)
188 aggregate.aggregate->set_sensitive(!bReadOnly);
189 }
190
191 if (m_xFormat)
192 {
193 assert(m_xFormatText);
194 m_xFormat->set_sensitive(!bReadOnly);
195 m_xFormatText->set_sensitive(!bReadOnly);
196 }
197 }
198
SetControlText(sal_uInt16 nControlId,const OUString & rText)199 void OFieldDescControl::SetControlText( sal_uInt16 nControlId, const OUString& rText )
200 {
201 // Set the Controls' texts
202 switch( nControlId )
203 {
204 case FIELD_PROPERTY_BOOL_DEFAULT:
205 if (m_xBoolDefault)
206 {
207 OUString sOld = m_xBoolDefault->get_active_text();
208 m_xBoolDefault->set_active_text(rText);
209 if (sOld != rText)
210 ChangeHdl(m_xBoolDefault->GetComboBox());
211 }
212 break;
213 case FIELD_PROPERTY_DEFAULT:
214 if (m_xDefault)
215 {
216 m_xDefault->set_text(rText);
217 UpdateFormatSample(pActFieldDescr);
218 }
219 break;
220
221 case FIELD_PROPERTY_REQUIRED:
222 if (m_xRequired)
223 m_xRequired->set_active_text(rText);
224 break;
225
226 case FIELD_PROPERTY_TEXTLEN:
227 if (m_xTextLen)
228 m_xTextLen->set_text(rText);
229 break;
230
231 case FIELD_PROPERTY_NUMTYPE:
232 if (m_xNumType)
233 m_xNumType->set_active_text(rText);
234 break;
235
236 case FIELD_PROPERTY_AUTOINC:
237 if (m_xAutoIncrement)
238 {
239 OUString sOld = m_xAutoIncrement->get_active_text();
240 m_xAutoIncrement->set_active_text(rText);
241 if (sOld != rText)
242 ChangeHdl(m_xAutoIncrement->GetComboBox());
243 }
244 break;
245
246 case FIELD_PROPERTY_LENGTH:
247 if (m_xLength)
248 m_xLength->set_text(rText);
249 break;
250
251 case FIELD_PROPERTY_SCALE:
252 if (m_xScale)
253 m_xScale->set_text(rText);
254 break;
255
256 case FIELD_PROPERTY_FORMAT:
257 if (pActFieldDescr)
258 UpdateFormatSample(pActFieldDescr);
259 break;
260 case FIELD_PROPERTY_COLUMNNAME:
261 if (m_xColumnName)
262 m_xColumnName->set_text(rText);
263 break;
264 case FIELD_PROPERTY_TYPE:
265 if (m_xType)
266 m_xType->set_active_text(rText);
267 break;
268 case FIELD_PROPERTY_AUTOINCREMENT:
269 if (m_xAutoIncrementValue)
270 m_xAutoIncrementValue->set_text(rText);
271 break;
272 }
273 }
274
IMPL_LINK_NOARG(OFieldDescControl,FormatClickHdl,weld::Button &,void)275 IMPL_LINK_NOARG(OFieldDescControl, FormatClickHdl, weld::Button&, void)
276 {
277 // Create temporary Column, which is used for data exchange with Dialog
278 if( !pActFieldDescr )
279 return;
280
281 sal_Int32 nOldFormatKey(pActFieldDescr->GetFormatKey());
282 SvxCellHorJustify rOldJustify = pActFieldDescr->GetHorJustify();
283 Reference< XNumberFormatsSupplier > xSupplier = GetFormatter()->getNumberFormatsSupplier();
284 SvNumberFormatsSupplierObj* pSupplierImpl = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>( xSupplier );
285 if (!pSupplierImpl)
286 return;
287
288 SvNumberFormatter* pFormatter = pSupplierImpl->GetNumberFormatter();
289 if(!::dbaui::callColumnFormatDialog(m_xContainer.get(),pFormatter,pActFieldDescr->GetType(),nOldFormatKey,rOldJustify,true))
290 return;
291
292 bool bModified = false;
293 if(nOldFormatKey != pActFieldDescr->GetFormatKey())
294 {
295 pActFieldDescr->SetFormatKey( nOldFormatKey );
296 bModified = true;
297 }
298 if(rOldJustify != pActFieldDescr->GetHorJustify())
299 {
300 pActFieldDescr->SetHorJustify( rOldJustify );
301 bModified = true;
302 }
303
304 if(bModified)
305 {
306 SetModified(true);
307 UpdateFormatSample(pActFieldDescr);
308 }
309 }
310
SetModified(bool)311 void OFieldDescControl::SetModified(bool /*bModified*/)
312 {
313 }
314
IMPL_LINK(OFieldDescControl,ChangeHdl,weld::ComboBox &,rListBox,void)315 IMPL_LINK(OFieldDescControl, ChangeHdl, weld::ComboBox&, rListBox, void)
316 {
317 if (!pActFieldDescr)
318 return;
319
320 if (rListBox.get_value_changed_from_saved())
321 SetModified(true);
322
323 // Special treatment for Bool fields
324 if (m_xRequired && &rListBox == m_xRequired->GetWidget() && m_xBoolDefault)
325 {
326 // If m_xRequired = sal_True then the sal_Bool field must NOT contain <<none>>
327 OUString sDef = BoolStringUI(::comphelper::getString(pActFieldDescr->GetControlDefault()));
328
329 if (m_xRequired->get_active() == 0) // Yes
330 {
331 m_xBoolDefault->remove_text(DBA_RES(STR_VALUE_NONE));
332 if (sDef != aYes && sDef != aNo)
333 m_xBoolDefault->set_active(1); // No as a default
334 else
335 m_xBoolDefault->set_active_text(sDef);
336 }
337 else if (m_xBoolDefault->get_count() < 3)
338 {
339 m_xBoolDefault->append_text(DBA_RES(STR_VALUE_NONE));
340 m_xBoolDefault->set_active_text(sDef);
341 }
342 }
343
344 // A special treatment only for AutoIncrement
345 if (m_xAutoIncrement && &rListBox == m_xAutoIncrement->GetWidget())
346 {
347 if (rListBox.get_active() == 1)
348 { // no
349 DeactivateAggregate( tpAutoIncrementValue );
350 if(pActFieldDescr->IsPrimaryKey())
351 DeactivateAggregate( tpRequired );
352 else if( pActFieldDescr->getTypeInfo()->bNullable )
353 {
354 ActivateAggregate( tpRequired );
355 if (m_xRequired)
356 {
357 if( pActFieldDescr->IsNullable() )
358 m_xRequired->set_active(1); // no
359 else
360 m_xRequired->set_active(0); // yes
361 }
362 }
363 ActivateAggregate( tpDefault );
364 }
365 else
366 {
367 DeactivateAggregate( tpRequired );
368 DeactivateAggregate( tpDefault );
369 ActivateAggregate( tpAutoIncrementValue );
370 }
371 }
372
373 if (m_xType && &rListBox == m_xType->GetWidget())
374 {
375 TOTypeInfoSP pTypeInfo = getTypeInfo(m_xType->get_active());
376 pActFieldDescr->FillFromTypeInfo(pTypeInfo,true,false); // SetType(pTypeInfo);
377
378 DisplayData(pActFieldDescr);
379 CellModified(-1, m_xType->GetPos());
380 }
381 }
382
ActivateAggregate(EControlType eType)383 void OFieldDescControl::ActivateAggregate( EControlType eType )
384 {
385 // Create Controls
386 switch( eType )
387 {
388 case tpDefault:
389 if (m_xDefault)
390 return;
391 m_nPos++;
392 m_xDefaultText = m_xBuilder->weld_label(u"DefaultValueText"_ustr);
393 m_xDefaultText->show();
394 m_xDefault = std::make_unique<OPropEditCtrl>(
395 m_xBuilder->weld_entry(u"DefaultValue"_ustr), STR_HELP_DEFAULT_VALUE, FIELD_PROPERTY_DEFAULT);
396 InitializeControl(m_xDefault->GetWidget(),HID_TAB_ENT_DEFAULT);
397 m_xDefault->show();
398 break;
399 case tpAutoIncrementValue:
400 if (m_xAutoIncrementValue || !isAutoIncrementValueEnabled())
401 return;
402 m_nPos++;
403 m_xAutoIncrementValueText = m_xBuilder->weld_label(u"AutoIncrementValueText"_ustr);
404 m_xAutoIncrementValueText->show();
405 m_xAutoIncrementValue = std::make_unique<OPropEditCtrl>(
406 m_xBuilder->weld_spin_button(u"AutoIncrementValue"_ustr), STR_HELP_AUTOINCREMENT_VALUE,
407 FIELD_PROPERTY_AUTOINCREMENT);
408 m_xAutoIncrementValue->set_text( getAutoIncrementValue() );
409 InitializeControl(m_xAutoIncrementValue->GetWidget(),HID_TAB_AUTOINCREMENTVALUE);
410 m_xAutoIncrementValue->show();
411 break;
412
413 case tpRequired:
414 {
415 if (m_xRequired)
416 return;
417 Reference< XDatabaseMetaData> xMetaData = getMetaData();
418
419 if(xMetaData.is() && xMetaData->supportsNonNullableColumns())
420 {
421 m_nPos++;
422 m_xRequiredText = m_xBuilder->weld_label(u"RequiredText"_ustr);
423 m_xRequiredText->show();
424 m_xRequired = std::make_unique<OPropListBoxCtrl>(
425 m_xBuilder->weld_combo_box(u"Required"_ustr), STR_HELP_AUTOINCREMENT_VALUE,
426 FIELD_PROPERTY_AUTOINCREMENT);
427 m_xRequired->append_text(aYes);
428 m_xRequired->append_text(aNo);
429 m_xRequired->set_active(1);
430
431 InitializeControl(m_xRequired.get(),HID_TAB_ENT_REQUIRED, true);
432 m_xRequired->show();
433 }
434 }
435 break;
436 case tpAutoIncrement:
437 {
438 if (m_xAutoIncrement)
439 return;
440 m_nPos++;
441 m_xAutoIncrementText = m_xBuilder->weld_label(u"AutoIncrementText"_ustr);
442 m_xAutoIncrementText->show();
443 m_xAutoIncrement = std::make_unique<OPropListBoxCtrl>(
444 m_xBuilder->weld_combo_box(u"AutoIncrement"_ustr), STR_HELP_AUTOINCREMENT,
445 FIELD_PROPERTY_AUTOINC);
446 m_xAutoIncrement->append_text(aYes);
447 m_xAutoIncrement->append_text(aNo);
448 m_xAutoIncrement->set_active(0);
449 InitializeControl(m_xAutoIncrement.get(),HID_TAB_ENT_AUTOINCREMENT, true);
450 m_xAutoIncrement->show();
451 }
452 break;
453 case tpTextLen:
454 if (m_xTextLen)
455 return;
456 m_nPos++;
457 m_xTextLenText = m_xBuilder->weld_label(u"TextLengthText"_ustr);
458 m_xTextLenText->show();
459 m_xTextLen = CreateNumericControl(u"TextLength"_ustr, STR_HELP_TEXT_LENGTH, FIELD_PROPERTY_TEXTLEN,HID_TAB_ENT_TEXT_LEN);
460 break;
461
462 case tpType:
463 if (m_xType)
464 return;
465 m_nPos++;
466 m_xTypeText = m_xBuilder->weld_label(u"TypeText"_ustr);
467 m_xTypeText->show();
468 m_xType = std::make_unique<OPropListBoxCtrl>(
469 m_xBuilder->weld_combo_box(u"Type"_ustr), STR_HELP_AUTOINCREMENT, FIELD_PROPERTY_TYPE);
470 {
471 const OTypeInfoMap* pTypeInfo = getTypeInfo();
472 for (auto const& elem : *pTypeInfo)
473 m_xType->append_text(elem.second->aUIName);
474 }
475 m_xType->set_active(0);
476 InitializeControl(m_xType.get(),HID_TAB_ENT_TYPE, true);
477 m_xType->show();
478 break;
479 case tpColumnName:
480 if (m_xColumnName)
481 return;
482 m_nPos++;
483 {
484 sal_Int32 nMax(0);
485 OUString aTmpString;
486 try
487 {
488 Reference< XDatabaseMetaData> xMetaData = getMetaData();
489 if ( xMetaData.is() )
490 {
491 nMax = xMetaData->getMaxColumnNameLength();
492 aTmpString = xMetaData->getExtraNameCharacters();
493 }
494 }
495 catch (const Exception&)
496 {
497 DBG_UNHANDLED_EXCEPTION("dbaccess");
498 }
499 m_xColumnNameText = m_xBuilder->weld_label(u"ColumnNameText"_ustr);
500 m_xColumnNameText->show();
501 m_xColumnName = std::make_unique<OPropColumnEditCtrl>(
502 m_xBuilder->weld_entry(u"ColumnName"_ustr), aTmpString,
503 STR_HELP_DEFAULT_VALUE, FIELD_PROPERTY_COLUMNNAME);
504 m_xColumnName->set_max_length(nMax);
505 m_xColumnName->setCheck( isSQL92CheckEnabled(getConnection()) );
506 }
507
508 InitializeControl(m_xColumnName->GetWidget(),HID_TAB_ENT_COLUMNNAME);
509 m_xColumnName->show();
510 break;
511 case tpNumType:
512 if (m_xNumType)
513 return;
514 m_nPos++;
515 m_xNumTypeText = m_xBuilder->weld_label(u"NumTypeText"_ustr);
516 m_xNumTypeText->show();
517 m_xNumType = std::make_unique<OPropListBoxCtrl>(
518 m_xBuilder->weld_combo_box(u"NumType"_ustr), STR_HELP_NUMERIC_TYPE, FIELD_PROPERTY_NUMTYPE);
519 m_xNumType->append_text(u"Byte"_ustr);
520 m_xNumType->append_text(u"SmallInt"_ustr);
521 m_xNumType->append_text(u"Integer"_ustr);
522 m_xNumType->append_text(u"Single"_ustr);
523 m_xNumType->append_text(u"Double"_ustr);
524 m_xNumType->set_active(2);
525 InitializeControl(m_xNumType.get(),HID_TAB_ENT_NUMTYP, true);
526 m_xNumType->show();
527 break;
528
529 case tpLength:
530 if (m_xLength)
531 return;
532 m_nPos++;
533 m_xLengthText = m_xBuilder->weld_label(u"LengthText"_ustr);
534 m_xLengthText->show();
535 m_xLength = CreateNumericControl(u"Length"_ustr, STR_HELP_LENGTH, FIELD_PROPERTY_LENGTH,HID_TAB_ENT_LEN);
536 break;
537
538 case tpScale:
539 if (m_xScale)
540 return;
541 m_nPos++;
542 m_xScaleText = m_xBuilder->weld_label(u"ScaleText"_ustr);
543 m_xScaleText->show();
544 m_xScale = CreateNumericControl(u"Scale"_ustr, STR_HELP_SCALE, FIELD_PROPERTY_SCALE,HID_TAB_ENT_SCALE);
545 break;
546
547 case tpFormat:
548 if (!m_xFormat)
549 {
550 m_nPos++;
551 m_xFormatText = m_xBuilder->weld_label(u"FormatTextText"_ustr);
552 m_xFormatText->show();
553
554 m_xFormatSample = std::make_unique<OPropEditCtrl>(
555 m_xBuilder->weld_entry(u"FormatText"_ustr), STR_HELP_FORMAT_CODE, -1);
556 m_xFormatSample->set_editable(false);
557 m_xFormatSample->set_sensitive(false);
558 InitializeControl(m_xFormatSample->GetWidget(),HID_TAB_ENT_FORMAT_SAMPLE);
559 m_xFormatSample->show();
560
561 m_xFormat = m_xBuilder->weld_button(u"FormatButton"_ustr);
562 m_xFormat->connect_clicked( LINK( this, OFieldDescControl, FormatClickHdl ) );
563 InitializeControl(m_xFormat.get(),HID_TAB_ENT_FORMAT);
564 m_xFormat->show();
565 }
566
567 UpdateFormatSample(pActFieldDescr);
568 break;
569 case tpBoolDefault:
570 if (m_xBoolDefault)
571 return;
572
573 m_nPos++;
574 m_xBoolDefaultText = m_xBuilder->weld_label(u"BoolDefaultText"_ustr);
575 m_xBoolDefaultText->show();
576 m_xBoolDefault = std::make_unique<OPropListBoxCtrl>(
577 m_xBuilder->weld_combo_box(u"BoolDefault"_ustr), STR_HELP_BOOL_DEFAULT,
578 FIELD_PROPERTY_BOOL_DEFAULT);
579 m_xBoolDefault->append_text(DBA_RES(STR_VALUE_NONE));
580 m_xBoolDefault->append_text(aYes);
581 m_xBoolDefault->append_text(aNo);
582 InitializeControl(m_xBoolDefault->GetWidget(),HID_TAB_ENT_BOOL_DEFAULT);
583 m_xBoolDefault->show();
584 break;
585 }
586 }
587
InitializeControl(OPropListBoxCtrl * _pControl,const OUString & _sHelpId,bool _bAddChangeHandler)588 void OFieldDescControl::InitializeControl(OPropListBoxCtrl* _pControl,const OUString& _sHelpId,bool _bAddChangeHandler)
589 {
590 if ( _bAddChangeHandler )
591 _pControl->GetComboBox().connect_changed(LINK(this,OFieldDescControl,ChangeHdl));
592
593 InitializeControl(_pControl->GetWidget(), _sHelpId);
594 }
595
InitializeControl(weld::Widget * pControl,const OUString & _sHelpId)596 void OFieldDescControl::InitializeControl(weld::Widget* pControl,const OUString& _sHelpId)
597 {
598 pControl->set_help_id(_sHelpId);
599 pControl->connect_focus_in(LINK(this, OFieldDescControl, OnControlFocusGot));
600 pControl->connect_focus_out(LINK(this, OFieldDescControl, OnControlFocusLost));
601
602 if (dynamic_cast<weld::Entry*>(pControl))
603 {
604 int nWidthRequest = Application::GetDefaultDevice()->LogicToPixel(Size(m_nEditWidth, 0), MapMode(MapUnit::MapAppFont)).Width();
605 pControl->set_size_request(nWidthRequest, -1);
606 }
607 }
608
CreateNumericControl(const OUString & rId,TranslateId pHelpId,short _nProperty,const OUString & _sHelpId)609 std::unique_ptr<OPropNumericEditCtrl> OFieldDescControl::CreateNumericControl(const OUString& rId, TranslateId pHelpId, short _nProperty, const OUString& _sHelpId)
610 {
611 auto xControl = std::make_unique<OPropNumericEditCtrl>(
612 m_xBuilder->weld_spin_button(rId), pHelpId, _nProperty);
613 xControl->set_digits(0);
614 xControl->set_range(0, 0x7FFFFFFF); // Should be changed outside, if needed
615 xControl->show();
616
617 InitializeControl(xControl->GetWidget(),_sHelpId);
618
619 return xControl;
620 }
621
DeactivateAggregate(EControlType eType)622 void OFieldDescControl::DeactivateAggregate( EControlType eType )
623 {
624 m_pLastFocusWindow = nullptr;
625 // Destroy Controls
626 switch( eType )
627 {
628 case tpDefault:
629 lcl_HideAndDeleteControl(m_nPos,m_xDefault,m_xDefaultText);
630 break;
631
632 case tpAutoIncrementValue:
633 lcl_HideAndDeleteControl(m_nPos,m_xAutoIncrementValue,m_xAutoIncrementValueText);
634 break;
635
636 case tpColumnName:
637 lcl_HideAndDeleteControl(m_nPos,m_xColumnName,m_xColumnNameText);
638 break;
639
640 case tpType:
641 lcl_HideAndDeleteControl(m_nPos,m_xType,m_xTypeText);
642 break;
643
644 case tpAutoIncrement:
645 lcl_HideAndDeleteControl(m_nPos,m_xAutoIncrement,m_xAutoIncrementText);
646 break;
647
648 case tpRequired:
649 lcl_HideAndDeleteControl(m_nPos,m_xRequired,m_xRequiredText);
650 break;
651
652 case tpTextLen:
653 lcl_HideAndDeleteControl(m_nPos,m_xTextLen,m_xTextLenText);
654 break;
655
656 case tpNumType:
657 lcl_HideAndDeleteControl(m_nPos,m_xNumType,m_xNumTypeText);
658 break;
659
660 case tpLength:
661 lcl_HideAndDeleteControl(m_nPos,m_xLength,m_xLengthText);
662 break;
663
664 case tpScale:
665 lcl_HideAndDeleteControl(m_nPos,m_xScale,m_xScaleText);
666 break;
667
668 case tpFormat:
669 // TODO: we have to check if we have to increment m_nPos again
670 lcl_HideAndDeleteControl(m_nPos,m_xFormat,m_xFormatText);
671 if (m_xFormatSample)
672 {
673 m_xFormatSample->hide();
674 m_xFormatSample.reset();
675 }
676 break;
677 case tpBoolDefault:
678 lcl_HideAndDeleteControl(m_nPos,m_xBoolDefault,m_xBoolDefaultText);
679 break;
680 }
681 }
682
DisplayData(OFieldDescription * pFieldDescr)683 void OFieldDescControl::DisplayData(OFieldDescription* pFieldDescr )
684 {
685 pActFieldDescr = pFieldDescr;
686 if(!pFieldDescr)
687 {
688 if (m_pHelp)
689 m_pHelp->SetHelpText( OUString() );
690 DeactivateAggregate( tpDefault );
691 DeactivateAggregate( tpRequired );
692 DeactivateAggregate( tpTextLen );
693 DeactivateAggregate( tpNumType );
694 DeactivateAggregate( tpScale );
695 DeactivateAggregate( tpLength );
696 DeactivateAggregate( tpFormat );
697 DeactivateAggregate( tpAutoIncrement );
698 DeactivateAggregate( tpBoolDefault );
699 DeactivateAggregate( tpColumnName );
700 DeactivateAggregate( tpType );
701 DeactivateAggregate( tpAutoIncrementValue );
702 m_pPreviousType = TOTypeInfoSP();
703 // Reset the saved focus' pointer
704 m_pLastFocusWindow = nullptr;
705 return;
706 }
707
708 TOTypeInfoSP pFieldType(pFieldDescr->getTypeInfo());
709
710 ActivateAggregate( tpColumnName );
711 ActivateAggregate( tpType );
712
713 OSL_ENSURE(pFieldType,"We need a type information here!");
714 // If the type has changed, substitute Controls
715 if( m_pPreviousType != pFieldType )
716 {
717 // Reset the saved focus' pointer
718 m_pLastFocusWindow = nullptr;
719
720 // Controls, which must NOT be displayed again
721 DeactivateAggregate( tpNumType );
722
723 // determine which controls we should show and which not
724
725 // 1. the required control
726 if ( pFieldType->bNullable )
727 ActivateAggregate( tpRequired );
728 else
729 DeactivateAggregate( tpRequired );
730
731 // 2. the autoincrement
732 if ( pFieldType->bAutoIncrement )
733 {
734 DeactivateAggregate( tpRequired );
735 DeactivateAggregate( tpDefault );
736 ActivateAggregate( tpAutoIncrement );
737 ActivateAggregate( tpAutoIncrementValue );
738 }
739 else
740 {
741 DeactivateAggregate( tpAutoIncrement );
742 DeactivateAggregate( tpAutoIncrementValue );
743 if(pFieldType->bNullable)
744 ActivateAggregate( tpRequired );
745 else
746 DeactivateAggregate( tpRequired );
747 ActivateAggregate( tpDefault );
748 }
749 // 3. the scale and precision
750 if (pFieldType->nPrecision)
751 {
752 ActivateAggregate( tpLength );
753 m_xLength->set_max(std::max<sal_Int32>(pFieldType->nPrecision,pFieldDescr->GetPrecision()));
754 m_xLength->set_editable(!pFieldType->aCreateParams.isEmpty());
755 }
756 else
757 DeactivateAggregate( tpLength );
758
759 if (pFieldType->nMaximumScale)
760 {
761 ActivateAggregate( tpScale );
762 m_xScale->set_range(pFieldType->nMinimumScale,
763 std::max<sal_Int32>(pFieldType->nMaximumScale,pFieldDescr->GetScale()));
764 m_xScale->set_editable(!pFieldType->aCreateParams.isEmpty() && pFieldType->aCreateParams != "PRECISION");
765 }
766 else
767 DeactivateAggregate( tpScale );
768
769 // and now look for type specific things
770 switch( pFieldType->nType )
771 {
772 case DataType::CHAR:
773 case DataType::VARCHAR:
774 case DataType::LONGVARCHAR:
775 DeactivateAggregate( tpLength );
776 DeactivateAggregate( tpBoolDefault );
777
778 ActivateAggregate( tpDefault );
779 ActivateAggregate( tpFormat );
780 if (pFieldType->nPrecision)
781 {
782 ActivateAggregate( tpTextLen );
783 m_xTextLen->set_max(std::max<sal_Int32>(pFieldType->nPrecision,pFieldDescr->GetPrecision()));
784 m_xTextLen->set_editable(!pFieldType->aCreateParams.isEmpty());
785 }
786 else
787 DeactivateAggregate( tpTextLen );
788 break;
789 case DataType::DATE:
790 case DataType::TIME:
791 case DataType::TIMESTAMP:
792 case DataType::TIME_WITH_TIMEZONE:
793 case DataType::TIMESTAMP_WITH_TIMEZONE:
794 DeactivateAggregate( tpLength ); // we don't need a length for date types
795 DeactivateAggregate( tpTextLen );
796 DeactivateAggregate( tpBoolDefault );
797
798 ActivateAggregate( tpDefault );
799 ActivateAggregate( tpFormat );
800 break;
801 case DataType::BIT:
802 if ( !pFieldType->aCreateParams.isEmpty() )
803 {
804 DeactivateAggregate( tpFormat );
805 DeactivateAggregate( tpTextLen );
806 DeactivateAggregate( tpBoolDefault );
807 break;
808 }
809 [[fallthrough]];
810 case DataType::BOOLEAN:
811 DeactivateAggregate( tpTextLen );
812 DeactivateAggregate( tpFormat );
813 DeactivateAggregate( tpDefault );
814
815 ActivateAggregate( tpBoolDefault );
816 break;
817 case DataType::DECIMAL:
818 case DataType::NUMERIC:
819 case DataType::BIGINT:
820 case DataType::FLOAT:
821 case DataType::DOUBLE:
822 case DataType::TINYINT:
823 case DataType::SMALLINT:
824 case DataType::INTEGER:
825 case DataType::REAL:
826 DeactivateAggregate( tpTextLen );
827 DeactivateAggregate( tpBoolDefault );
828
829 ActivateAggregate( tpFormat );
830 break;
831 case DataType::BINARY:
832 case DataType::VARBINARY:
833 DeactivateAggregate( tpDefault );
834 DeactivateAggregate( tpRequired );
835 DeactivateAggregate( tpTextLen );
836 DeactivateAggregate( tpBoolDefault );
837
838 ActivateAggregate( tpFormat );
839 break;
840 case DataType::LONGVARBINARY:
841 case DataType::SQLNULL:
842 case DataType::OBJECT:
843 case DataType::DISTINCT:
844 case DataType::STRUCT:
845 case DataType::ARRAY:
846 case DataType::BLOB:
847 case DataType::CLOB:
848 case DataType::REF:
849 case DataType::OTHER:
850 DeactivateAggregate( tpFormat );
851 DeactivateAggregate( tpTextLen );
852 DeactivateAggregate( tpBoolDefault );
853
854 break;
855 default:
856 OSL_FAIL("Unknown type");
857 }
858 m_pPreviousType = pFieldType;
859 }
860
861 if (pFieldDescr->IsPrimaryKey())
862 {
863 DeactivateAggregate(tpRequired);
864 }
865 else if (!m_xAutoIncrement && pFieldType)
866 {
867 if (pFieldType->bNullable)
868 ActivateAggregate(tpRequired);
869 else
870 DeactivateAggregate(tpRequired);
871 }
872 // Initialize Controls
873 if (m_xAutoIncrement)
874 {
875 if ( pFieldDescr->IsAutoIncrement() )
876 {
877 m_xAutoIncrement->set_active(0); // yes
878 ActivateAggregate( tpAutoIncrementValue );
879 if (m_xAutoIncrementValue)
880 m_xAutoIncrementValue->set_text(pFieldDescr->GetAutoIncrementValue());
881 DeactivateAggregate( tpRequired );
882 DeactivateAggregate( tpDefault );
883 }
884 else
885 {
886 // disable autoincrement value because it should only be visible when autoincrement is to true
887 DeactivateAggregate( tpAutoIncrementValue );
888 m_xAutoIncrement->set_active(1); // no
889 ActivateAggregate( tpDefault );
890 // Affects pRequired
891 if(!pFieldDescr->IsPrimaryKey())
892 ActivateAggregate( tpRequired );
893 }
894 }
895
896 if (m_xDefault)
897 {
898 m_xDefault->set_text(getControlDefault(pFieldDescr));
899 m_xDefault->save_value();
900 }
901
902 if (m_xBoolDefault)
903 {
904 // If m_xRequired = sal_True then the sal_Bool field must NOT contain <<none>>
905 OUString sValue;
906 pFieldDescr->GetControlDefault() >>= sValue;
907 OUString sDef = BoolStringUI(sValue);
908
909 // Make sure that <<none>> is only present if the field can be NULL
910 if ( ( pFieldType && !pFieldType->bNullable ) || !pFieldDescr->IsNullable() )
911 {
912 pFieldDescr->SetIsNullable(ColumnValue::NO_NULLS); // The type says so
913
914 m_xBoolDefault->remove_text(DBA_RES(STR_VALUE_NONE));
915 if ( sDef != aYes && sDef != aNo )
916 m_xBoolDefault->set_active(1); // No as a default
917 else
918 m_xBoolDefault->set_active_text(sDef);
919
920 pFieldDescr->SetControlDefault(Any(BoolStringPersistent(m_xBoolDefault->get_active_text())));
921 }
922 else if (m_xBoolDefault->get_count() < 3)
923 {
924 m_xBoolDefault->append_text(DBA_RES(STR_VALUE_NONE));
925 m_xBoolDefault->set_active_text(sDef);
926 }
927 else
928 m_xBoolDefault->set_active_text(sDef);
929 }
930
931 if (m_xRequired)
932 {
933 if( pFieldDescr->IsNullable() )
934 m_xRequired->set_active(1); // no
935 else
936 m_xRequired->set_active(0); // yes
937 }
938
939 if (m_xTextLen)
940 {
941 m_xTextLen->set_text(OUString::number(pFieldDescr->GetPrecision()));
942 m_xTextLen->save_value();
943 }
944
945 if( m_xNumType )
946 {
947 OSL_FAIL("OFieldDescControl::DisplayData: invalid num type!");
948 }
949
950 if (m_xLength)
951 m_xLength->set_text(OUString::number(pFieldDescr->GetPrecision()));
952
953 if (m_xScale)
954 m_xScale->set_text(OUString::number(pFieldDescr->GetScale()));
955
956 if (m_xFormat)
957 UpdateFormatSample(pFieldDescr);
958
959 if (m_xColumnName)
960 m_xColumnName->set_text(pFieldDescr->GetName());
961
962 if (m_xType)
963 {
964 sal_Int32 nPos = pFieldType ? m_xType->find_text(pFieldDescr->getTypeInfo()->aUIName) : -1;
965 if (nPos == -1)
966 {
967 const OTypeInfoMap* pMap = getTypeInfo();
968 OTypeInfoMap::const_iterator aIter = pMap->find(pFieldType ? pFieldDescr->getTypeInfo()->nType : pFieldDescr->GetType());
969 if(aIter == pMap->end() && !pMap->empty())
970 {
971 aIter = pMap->begin();
972 if(pFieldDescr->GetPrecision() > aIter->second->nPrecision)
973 pFieldDescr->SetPrecision(aIter->second->nPrecision);
974 if(pFieldDescr->GetScale() > aIter->second->nMaximumScale)
975 pFieldDescr->SetScale(0);
976 if(!aIter->second->bNullable && pFieldDescr->IsNullable())
977 pFieldDescr->SetIsNullable(ColumnValue::NO_NULLS);
978 if(!aIter->second->bAutoIncrement && pFieldDescr->IsAutoIncrement())
979 pFieldDescr->SetAutoIncrement(false);
980 }
981 if ( aIter != pMap->end() )
982 {
983 pFieldDescr->SetType(aIter->second);
984 }
985 }
986 m_xType->set_active_text(pFieldDescr->getTypeInfo()->aUIName);
987 }
988
989 // Enable/disable Controls
990 bool bRead(IsReadOnly());
991
992 SetReadOnly( bRead );
993 }
994
IMPL_LINK(OFieldDescControl,OnControlFocusGot,weld::Widget &,rControl,void)995 IMPL_LINK(OFieldDescControl, OnControlFocusGot, weld::Widget&, rControl, void )
996 {
997 OUString strHelpText;
998
999 if (m_xTextLen && &rControl == m_xTextLen->GetWidget())
1000 {
1001 m_xTextLen->save_value();
1002 strHelpText = m_xTextLen->GetHelp();
1003 }
1004 else if (m_xLength && &rControl == m_xLength->GetWidget())
1005 {
1006 m_xLength->save_value();
1007 strHelpText = m_xLength->GetHelp();
1008 }
1009 else if (m_xScale && &rControl == m_xScale->GetWidget())
1010 {
1011 m_xScale->save_value();
1012 strHelpText = m_xScale->GetHelp();
1013 }
1014 else if (m_xColumnName && &rControl == m_xColumnName->GetWidget())
1015 {
1016 m_xColumnName->save_value();
1017 strHelpText = m_xColumnName->GetHelp();
1018 }
1019 else if (m_xDefault && &rControl == m_xDefault->GetWidget())
1020 {
1021 m_xDefault->save_value();
1022 strHelpText = m_xDefault->GetHelp();
1023 }
1024 else if (m_xFormatSample && &rControl == m_xFormatSample->GetWidget())
1025 {
1026 m_xFormatSample->save_value();
1027 strHelpText = m_xFormatSample->GetHelp();
1028 }
1029 else if (m_xAutoIncrementValue && &rControl == m_xAutoIncrementValue->GetWidget())
1030 {
1031 m_xAutoIncrementValue->save_value();
1032 strHelpText = m_xAutoIncrementValue->GetHelp();
1033 }
1034 else if (m_xRequired && &rControl == m_xRequired->GetWidget())
1035 {
1036 m_xRequired->save_value();
1037 strHelpText = m_xRequired->GetHelp();
1038 }
1039 else if (m_xNumType && &rControl == m_xNumType->GetWidget())
1040 {
1041 m_xNumType->save_value();
1042 strHelpText = m_xNumType->GetHelp();
1043 }
1044 else if (m_xAutoIncrement && &rControl == m_xAutoIncrement->GetWidget())
1045 {
1046 m_xAutoIncrement->save_value();
1047 strHelpText = m_xAutoIncrement->GetHelp();
1048 }
1049 else if (m_xBoolDefault && &rControl == m_xBoolDefault->GetWidget())
1050 {
1051 m_xBoolDefault->save_value();
1052 strHelpText = m_xBoolDefault->GetHelp();
1053 }
1054 else if (m_xType && &rControl == m_xType->GetWidget())
1055 {
1056 m_xType->save_value();
1057 strHelpText = m_xType->GetHelp();
1058 }
1059 else if (m_xFormat && &rControl == m_xFormat.get())
1060 strHelpText = DBA_RES(STR_HELP_FORMAT_BUTTON);
1061
1062 if (!strHelpText.isEmpty() && m_pHelp)
1063 m_pHelp->SetHelpText(strHelpText);
1064
1065 m_pActFocusWindow = &rControl;
1066
1067 m_aControlFocusIn.Call(rControl);
1068 }
1069
IMPL_LINK(OFieldDescControl,OnControlFocusLost,weld::Widget &,rControl,void)1070 IMPL_LINK(OFieldDescControl, OnControlFocusLost, weld::Widget&, rControl, void )
1071 {
1072 if (m_xLength && &rControl == m_xLength->GetWidget() && m_xLength->get_value_changed_from_saved())
1073 CellModified(-1, m_xLength->GetPos());
1074 else if (m_xTextLen && &rControl == m_xTextLen->GetWidget() && m_xTextLen->get_value_changed_from_saved())
1075 CellModified(-1, m_xTextLen->GetPos());
1076 else if (m_xScale && &rControl == m_xScale->GetWidget() && m_xScale->get_value_changed_from_saved())
1077 CellModified(-1, m_xScale->GetPos());
1078 else if (m_xColumnName && &rControl == m_xColumnName->GetWidget() && m_xColumnName->get_value_changed_from_saved())
1079 CellModified(-1, m_xColumnName->GetPos());
1080 else if (m_xDefault && &rControl == m_xDefault->GetWidget() && m_xDefault->get_value_changed_from_saved())
1081 CellModified(-1, m_xDefault->GetPos());
1082 else if (m_xFormatSample && &rControl == m_xFormatSample->GetWidget() && m_xFormatSample->get_value_changed_from_saved())
1083 CellModified(-1, m_xFormatSample->GetPos());
1084 else if (m_xAutoIncrementValue && &rControl == m_xAutoIncrementValue->GetWidget() && m_xAutoIncrementValue->get_value_changed_from_saved())
1085 CellModified(-1, m_xAutoIncrementValue->GetPos());
1086 else if (m_xRequired && &rControl == m_xRequired->GetWidget() && m_xRequired->get_value_changed_from_saved())
1087 CellModified(-1, m_xRequired->GetPos());
1088 else if (m_xNumType && &rControl == m_xNumType->GetWidget() && m_xNumType->get_value_changed_from_saved())
1089 CellModified(-1, m_xNumType->GetPos());
1090 else if (m_xAutoIncrement && &rControl == m_xAutoIncrement->GetWidget() && m_xAutoIncrement->get_value_changed_from_saved())
1091 CellModified(-1, m_xAutoIncrement->GetPos());
1092 else if (m_xBoolDefault && &rControl == m_xBoolDefault->GetWidget() && m_xBoolDefault->get_value_changed_from_saved())
1093 CellModified(-1, m_xBoolDefault->GetPos());
1094 else if (m_xType && &rControl == m_xType->GetWidget() && m_xType->get_value_changed_from_saved())
1095 CellModified(-1, m_xType->GetPos());
1096 else if (m_xDefault && &rControl == m_xDefault->GetWidget())
1097 UpdateFormatSample(pActFieldDescr);
1098
1099 implFocusLost(&rControl);
1100 }
1101
SaveData(OFieldDescription * pFieldDescr)1102 void OFieldDescControl::SaveData( OFieldDescription* pFieldDescr )
1103 {
1104 if( !pFieldDescr )
1105 return;
1106
1107 // Read out Controls
1108 OUString sDefault;
1109 if (m_xDefault)
1110 {
1111 // tdf#138409 take the control default in the UI Locale format, e.g. 12,34 and return a string
1112 // suitable as the database default, e.g. 12.34
1113 sDefault = CanonicalizeToControlDefault(pFieldDescr, m_xDefault->get_text());
1114 }
1115 else if (m_xBoolDefault)
1116 {
1117 sDefault = BoolStringPersistent(m_xBoolDefault->get_active_text());
1118 }
1119
1120 if ( !sDefault.isEmpty() )
1121 pFieldDescr->SetControlDefault(Any(sDefault));
1122 else
1123 pFieldDescr->SetControlDefault(Any());
1124
1125 if((m_xRequired && m_xRequired->get_active() == 0) || pFieldDescr->IsPrimaryKey() || (m_xBoolDefault && m_xBoolDefault->get_count() == 2)) // yes
1126 pFieldDescr->SetIsNullable( ColumnValue::NO_NULLS );
1127 else
1128 pFieldDescr->SetIsNullable( ColumnValue::NULLABLE );
1129
1130 if (m_xAutoIncrement)
1131 pFieldDescr->SetAutoIncrement(m_xAutoIncrement->get_active() == 0);
1132
1133 if( m_xTextLen )
1134 pFieldDescr->SetPrecision( static_cast<sal_Int32>(m_xTextLen->get_value()) );
1135 else if (m_xLength)
1136 pFieldDescr->SetPrecision( static_cast<sal_Int32>(m_xLength->get_value()) );
1137 if (m_xScale)
1138 pFieldDescr->SetScale( static_cast<sal_Int32>(m_xScale->get_value()) );
1139
1140 if (m_xColumnName)
1141 pFieldDescr->SetName(m_xColumnName->get_text());
1142
1143 if (m_xAutoIncrementValue && isAutoIncrementValueEnabled())
1144 pFieldDescr->SetAutoIncrementValue(m_xAutoIncrementValue->get_text());
1145 }
1146
UpdateFormatSample(OFieldDescription const * pFieldDescr)1147 void OFieldDescControl::UpdateFormatSample(OFieldDescription const * pFieldDescr)
1148 {
1149 if (pFieldDescr && m_xFormatSample)
1150 m_xFormatSample->set_text(getControlDefault(pFieldDescr,false));
1151 }
1152
GrabFocus()1153 void OFieldDescControl::GrabFocus()
1154 {
1155 m_xContainer->grab_focus();
1156
1157 // Set the Focus to the Control that has been active last
1158 if (m_pLastFocusWindow)
1159 {
1160 m_pLastFocusWindow->grab_focus();
1161 m_pLastFocusWindow = nullptr;
1162 }
1163 }
1164
implFocusLost(weld::Widget * _pWhich)1165 void OFieldDescControl::implFocusLost(weld::Widget* _pWhich)
1166 {
1167 // Remember the active Control
1168 if (!m_pLastFocusWindow)
1169 m_pLastFocusWindow = _pWhich;
1170
1171 // Reset HelpText
1172 if (m_pHelp && !m_pHelp->HasFocus())
1173 m_pHelp->SetHelpText( OUString() );
1174 }
1175
IMPL_LINK_NOARG(OFieldDescControl,HelpFocusOut,weld::Widget &,void)1176 IMPL_LINK_NOARG(OFieldDescControl, HelpFocusOut, weld::Widget&, void)
1177 {
1178 m_pHelp->SetHelpText(OUString());
1179 }
1180
IsFocusInEditableWidget() const1181 bool OFieldDescControl::IsFocusInEditableWidget() const
1182 {
1183 if (m_xDefault && m_pActFocusWindow == m_xDefault->GetWidget())
1184 return true;
1185 if (m_xFormatSample && m_pActFocusWindow == m_xFormatSample->GetWidget())
1186 return true;
1187 if (m_xTextLen && m_pActFocusWindow == m_xTextLen->GetWidget())
1188 return true;
1189 if (m_xLength && m_pActFocusWindow == m_xLength->GetWidget())
1190 return true;
1191 if (m_xScale && m_pActFocusWindow == m_xScale->GetWidget())
1192 return true;
1193 if (m_xColumnName && m_pActFocusWindow == m_xColumnName->GetWidget())
1194 return true;
1195 if (m_xAutoIncrementValue && m_pActFocusWindow == m_xAutoIncrementValue->GetWidget())
1196 return true;
1197 return false;
1198 }
1199
HasChildPathFocus() const1200 bool OFieldDescControl::HasChildPathFocus() const
1201 {
1202 return m_xContainer && m_xContainer->has_child_focus();
1203 }
1204
isCopyAllowed()1205 bool OFieldDescControl::isCopyAllowed()
1206 {
1207 int nStartPos, nEndPos;
1208 bool bAllowed = (m_pActFocusWindow != nullptr) && IsFocusInEditableWidget() &&
1209 dynamic_cast<weld::Entry&>(*m_pActFocusWindow).get_selection_bounds(nStartPos, nEndPos);
1210 return bAllowed;
1211 }
1212
isCutAllowed()1213 bool OFieldDescControl::isCutAllowed()
1214 {
1215 int nStartPos, nEndPos;
1216 bool bAllowed = (m_pActFocusWindow != nullptr) && IsFocusInEditableWidget() &&
1217 dynamic_cast<weld::Entry&>(*m_pActFocusWindow).get_selection_bounds(nStartPos, nEndPos);
1218 return bAllowed;
1219 }
1220
isPasteAllowed()1221 bool OFieldDescControl::isPasteAllowed()
1222 {
1223 bool bAllowed = (m_pActFocusWindow != nullptr) && IsFocusInEditableWidget();
1224 if ( bAllowed )
1225 {
1226 TransferableDataHelper aTransferData(TransferableDataHelper::CreateFromClipboard(m_pActFocusWindow->get_clipboard()));
1227 bAllowed = aTransferData.HasFormat(SotClipboardFormatId::STRING);
1228 }
1229 return bAllowed;
1230 }
1231
cut()1232 void OFieldDescControl::cut()
1233 {
1234 if (isCutAllowed())
1235 dynamic_cast<weld::Entry&>(*m_pActFocusWindow).cut_clipboard();
1236 }
1237
copy()1238 void OFieldDescControl::copy()
1239 {
1240 if (isCopyAllowed()) // this only checks if the focus window is valid
1241 dynamic_cast<weld::Entry&>(*m_pActFocusWindow).copy_clipboard();
1242 }
1243
paste()1244 void OFieldDescControl::paste()
1245 {
1246 if (m_pActFocusWindow) // this only checks if the focus window is valid
1247 dynamic_cast<weld::Entry&>(*m_pActFocusWindow).paste_clipboard();
1248 }
1249
isTextFormat(const OFieldDescription * _pFieldDescr,sal_uInt32 & _nFormatKey) const1250 bool OFieldDescControl::isTextFormat(const OFieldDescription* _pFieldDescr, sal_uInt32& _nFormatKey) const
1251 {
1252 _nFormatKey = _pFieldDescr->GetFormatKey();
1253 bool bTextFormat = true;
1254
1255 try
1256 {
1257 if (!_nFormatKey)
1258 {
1259 Reference< css::util::XNumberFormatTypes> xNumberTypes(GetFormatter()->getNumberFormatsSupplier()->getNumberFormats(),UNO_QUERY);
1260 OSL_ENSURE(xNumberTypes.is(),"XNumberFormatTypes is null!");
1261
1262 _nFormatKey = ::dbtools::getDefaultNumberFormat( _pFieldDescr->GetType(),
1263 _pFieldDescr->GetScale(),
1264 _pFieldDescr->IsCurrency(),
1265 xNumberTypes,
1266 GetLocale());
1267 }
1268 sal_Int32 nNumberFormat = ::comphelper::getNumberFormatType(GetFormatter(),_nFormatKey);
1269 bTextFormat = (nNumberFormat == css::util::NumberFormat::TEXT);
1270 }
1271 catch(const Exception&)
1272 {
1273
1274 }
1275
1276 return bTextFormat;
1277 }
1278
getControlDefault(const OFieldDescription * _pFieldDescr,bool _bCheck) const1279 OUString OFieldDescControl::getControlDefault( const OFieldDescription* _pFieldDescr, bool _bCheck) const
1280 {
1281 OUString sDefault;
1282 bool bCheck = !_bCheck || _pFieldDescr->GetControlDefault().hasValue();
1283 if ( bCheck )
1284 {
1285 try
1286 {
1287 double nValue = 0.0;
1288 sal_uInt32 nFormatKey;
1289 bool bTextFormat = isTextFormat(_pFieldDescr,nFormatKey);
1290 if ( _pFieldDescr->GetControlDefault() >>= sDefault )
1291 {
1292 if ( !bTextFormat )
1293 {
1294 if ( !sDefault.isEmpty() )
1295 {
1296 try
1297 {
1298 nValue = GetFormatter()->convertStringToNumber(nFormatKey,sDefault);
1299 }
1300 catch(const Exception&)
1301 {
1302 return OUString(); // return empty string for format example
1303 }
1304 }
1305 }
1306 }
1307 else
1308 _pFieldDescr->GetControlDefault() >>= nValue;
1309
1310 Reference< css::util::XNumberFormatter> xNumberFormatter = GetFormatter();
1311 Reference<XPropertySet> xFormSet = xNumberFormatter->getNumberFormatsSupplier()->getNumberFormats()->getByKey(nFormatKey);
1312 OSL_ENSURE(xFormSet.is(),"XPropertySet is null!");
1313 OUString sFormat;
1314 xFormSet->getPropertyValue(u"FormatString"_ustr) >>= sFormat;
1315
1316 if ( !bTextFormat )
1317 {
1318 Locale aLocale;
1319 ::comphelper::getNumberFormatProperty(xNumberFormatter,nFormatKey,u"Locale"_ustr) >>= aLocale;
1320
1321 sal_Int32 nNumberFormat = ::comphelper::getNumberFormatType(xNumberFormatter,nFormatKey);
1322 if( (nNumberFormat & css::util::NumberFormat::DATE) == css::util::NumberFormat::DATE
1323 || (nNumberFormat & css::util::NumberFormat::DATETIME) == css::util::NumberFormat::DATETIME )
1324 {
1325 nValue = DBTypeConversion::toNullDate(DBTypeConversion::getNULLDate(xNumberFormatter->getNumberFormatsSupplier()),nValue);
1326 }
1327
1328 Reference< css::util::XNumberFormatPreviewer> xPreviewer(xNumberFormatter,UNO_QUERY);
1329 OSL_ENSURE(xPreviewer.is(),"XNumberFormatPreviewer is null!");
1330 sDefault = xPreviewer->convertNumberToPreviewString(sFormat,nValue,aLocale,true);
1331 }
1332 else if ( !(_bCheck && sDefault.isEmpty()) )
1333 sDefault = xNumberFormatter->formatString(nFormatKey, sDefault.isEmpty() ? sFormat : sDefault);
1334 }
1335 catch(const Exception&)
1336 {
1337
1338 }
1339 }
1340
1341 return sDefault;
1342 }
1343
1344 // tdf#138409 intended to be effectively the reverse of getControlDefault to
1345 // turn a user's possibly 12,34 format into 12.34 format for numerical types
CanonicalizeToControlDefault(const OFieldDescription * pFieldDescr,const OUString & rDefault) const1346 OUString OFieldDescControl::CanonicalizeToControlDefault(const OFieldDescription* pFieldDescr, const OUString& rDefault) const
1347 {
1348 if (rDefault.isEmpty())
1349 return rDefault;
1350
1351 bool bIsNumericalType = false;
1352 switch (pFieldDescr->GetType())
1353 {
1354 case DataType::TINYINT:
1355 case DataType::SMALLINT:
1356 case DataType::INTEGER:
1357 case DataType::BIGINT:
1358 case DataType::FLOAT:
1359 case DataType::REAL:
1360 case DataType::DOUBLE:
1361 case DataType::NUMERIC:
1362 case DataType::DECIMAL:
1363 bIsNumericalType = true;
1364 break;
1365 }
1366
1367 if (!bIsNumericalType)
1368 return rDefault;
1369
1370 try
1371 {
1372 sal_uInt32 nFormatKey;
1373 bool bTextFormat = isTextFormat(pFieldDescr, nFormatKey);
1374 if (bTextFormat)
1375 return rDefault;
1376 double nValue = GetFormatter()->convertStringToNumber(nFormatKey, rDefault);
1377 return OUString::number(nValue);
1378 }
1379 catch(const Exception&)
1380 {
1381 }
1382
1383 return rDefault;
1384 }
1385
1386
1387 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1388