1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifdef SC_DLLIMPLEMENTATION
21 #undef SC_DLLIMPLEMENTATION
24 #include <com/sun/star/sheet/TableValidationVisibility.hpp>
25 #include <comphelper/string.hxx>
26 #include <svl/stritem.hxx>
27 #include <svl/eitem.hxx>
28 #include <svl/intitem.hxx>
29 #include <sfx2/app.hxx>
30 #include <o3tl/string_view.hxx>
32 #include <scresid.hxx>
33 #include <strings.hrc>
35 #include <stringutil.hxx>
36 #include <validat.hxx>
37 #include <validate.hxx>
38 #include <compiler.hxx>
39 #include <formula/opcode.hxx>
42 #include <tabvwsh.hxx>
43 #include <sfx2/viewfrm.hxx>
44 #include <sfx2/childwin.hxx>
45 #include <reffact.hxx>
46 #include <comphelper/lok.hxx>
48 /* Position indexes for "Allow" list box.
49 They do not map directly to ScValidationMode and can safely be modified to
50 change the order of the list box entries. */
51 #define SC_VALIDDLG_ALLOW_ANY 0
52 #define SC_VALIDDLG_ALLOW_WHOLE 1
53 #define SC_VALIDDLG_ALLOW_DECIMAL 2
54 #define SC_VALIDDLG_ALLOW_DATE 3
55 #define SC_VALIDDLG_ALLOW_TIME 4
56 #define SC_VALIDDLG_ALLOW_RANGE 5
57 #define SC_VALIDDLG_ALLOW_LIST 6
58 #define SC_VALIDDLG_ALLOW_TEXTLEN 7
59 #define SC_VALIDDLG_ALLOW_CUSTOM 8
61 /* Position indexes for "Data" list box.
62 They do not map directly to ScConditionMode and can safely be modified to
63 change the order of the list box entries. */
64 #define SC_VALIDDLG_DATA_EQUAL 0
65 #define SC_VALIDDLG_DATA_LESS 1
66 #define SC_VALIDDLG_DATA_GREATER 2
67 #define SC_VALIDDLG_DATA_EQLESS 3
68 #define SC_VALIDDLG_DATA_EQGREATER 4
69 #define SC_VALIDDLG_DATA_NOTEQUAL 5
70 #define SC_VALIDDLG_DATA_VALIDRANGE 6
71 #define SC_VALIDDLG_DATA_INVALIDRANGE 7
72 #define SC_VALIDDLG_DATA_DIRECT 8
74 namespace ValidListType
= css::sheet::TableValidationVisibility
;
76 const WhichRangesContainer
ScTPValidationValue::pValueRanges(svl::Items
<
77 FID_VALID_LISTTYPE
, FID_VALID_LISTTYPE
,
78 FID_VALID_MODE
, FID_VALID_ERRTEXT
81 static bool isLOKMobilePhone()
83 if (!comphelper::LibreOfficeKit::isActive())
85 SfxViewShell
* pViewShell
= SfxViewShell::Current();
86 return pViewShell
&& pViewShell
->isLOKMobilePhone();
89 ScValidationDlg::ScValidationDlg(weld::Window
* pParent
, const SfxItemSet
* pArgSet
,
90 ScTabViewShell
*pTabViewSh
)
91 : ScValidationDlgBase(pParent
,
92 u
"modules/scalc/ui/validationdialog.ui"_ustr
, u
"ValidationDialog"_ustr
, pArgSet
, nullptr)
93 , m_pTabVwSh(pTabViewSh
)
94 , m_sValuePageId(u
"criteria"_ustr
)
95 , m_bOwnRefHdlr(false)
96 , m_bRefInputting(false)
97 , m_xHBox(m_xBuilder
->weld_container(u
"refinputbox"_ustr
))
99 AddTabPage(m_sValuePageId
, ScTPValidationValue::Create
, nullptr);
100 AddTabPage(u
"inputhelp"_ustr
, ScTPValidationHelp::Create
, nullptr);
101 AddTabPage(u
"erroralert"_ustr
, ScTPValidationError::Create
, nullptr);
103 if (isLOKMobilePhone())
105 m_xBuilder
->weld_button(u
"cancel"_ustr
)->hide();
106 m_xBuilder
->weld_button(u
"help"_ustr
)->hide();
110 void ScValidationDlg::EndDialog(int nResponse
)
112 // tdf#155708 - do not close, just hide validation window if we click in another sheet
113 if (nResponse
== nCloseResponseToJustHide
&& getDialog()->get_visible())
118 // tdf#137215 ensure original modality of true is restored before dialog loop ends
121 ScValidationDlgBase::EndDialog(nResponse
);
124 ScValidationDlg::~ScValidationDlg()
130 void ScTPValidationValue::SetReferenceHdl( const ScRange
&rRange
, const ScDocument
& rDoc
)
132 if ( rRange
.aStart
!= rRange
.aEnd
)
133 if ( ScValidationDlg
*pValidationDlg
= GetValidationDlg() )
135 pValidationDlg
->RefInputStart( m_pRefEdit
);
139 OUString
aStr(rRange
.Format(rDoc
, ScRefFlags::RANGE_ABS_3D
, rDoc
.GetAddressConvention()));
140 m_pRefEdit
->SetRefString( aStr
);
144 void ScTPValidationValue:: SetActiveHdl()
146 if ( m_pRefEdit
) m_pRefEdit
->GrabFocus();
148 if ( ScValidationDlg
*pValidationDlg
= GetValidationDlg() )
151 pValidationDlg
->RefInputDone();
155 void ScTPValidationValue::RefInputStartPreHdl( formula::RefEdit
* pEdit
, const formula::RefButton
* pButton
)
157 ScValidationDlg
*pValidationDlg
= GetValidationDlg();
161 weld::Container
* pNewParent
= pValidationDlg
->get_refinput_shrink_parent();
162 if (pEdit
== m_pRefEdit
&& pNewParent
!= m_pRefEditParent
)
164 m_xRefGrid
->move(m_pRefEdit
->GetWidget(), pNewParent
);
165 m_pRefEditParent
= pNewParent
;
168 if (pNewParent
!= m_pBtnRefParent
)
170 // if Edit SetParent but button not, the tab order will be
171 // incorrect, so move button anyway, and restore
172 // parent later in order to restore the tab order. But
173 // hide it if it's moved but unwanted.
174 m_xRefGrid
->move(m_xBtnRef
->GetWidget(), pNewParent
);
175 m_xBtnRef
->GetWidget()->set_visible(pButton
== m_xBtnRef
.get());
176 m_pBtnRefParent
= pNewParent
;
182 void ScTPValidationValue::RefInputDonePostHdl()
184 if (ScValidationDlg
*pValidationDlg
= GetValidationDlg())
186 weld::Container
* pOldParent
= pValidationDlg
->get_refinput_shrink_parent();
188 if (m_pRefEdit
&& m_pRefEditParent
!= m_xRefGrid
.get())
190 pOldParent
->move(m_pRefEdit
->GetWidget(), m_xRefGrid
.get());
191 m_pRefEditParent
= m_xRefGrid
.get();
194 if (m_pBtnRefParent
!= m_xRefGrid
.get())
196 pOldParent
->move(m_xBtnRef
->GetWidget(), m_xRefGrid
.get());
197 m_xBtnRef
->GetWidget()->show();
198 m_pBtnRefParent
= m_xRefGrid
.get();
202 ScViewData
& rViewData
= pValidationDlg
->GetTabViewShell()->GetViewData();
203 SCTAB nCurTab
= rViewData
.GetTabNo();
204 SCTAB nRefTab
= rViewData
.GetRefTabNo();
205 // If RefInput switched to a different sheet from the data sheet,
206 // switch back: fdo#53920
207 if ( nCurTab
!= nRefTab
)
209 rViewData
.GetViewShell()->SetTabNo( nRefTab
);
213 if (m_pRefEdit
&& !m_pRefEdit
->GetWidget()->has_focus())
214 m_pRefEdit
->GrabFocus();
219 /** Converts the passed ScValidationMode to the position in the list box. */
220 sal_uInt16
lclGetPosFromValMode( ScValidationMode eValMode
)
222 sal_uInt16 nLbPos
= SC_VALIDDLG_ALLOW_ANY
;
225 case SC_VALID_ANY
: nLbPos
= SC_VALIDDLG_ALLOW_ANY
; break;
226 case SC_VALID_WHOLE
: nLbPos
= SC_VALIDDLG_ALLOW_WHOLE
; break;
227 case SC_VALID_DECIMAL
: nLbPos
= SC_VALIDDLG_ALLOW_DECIMAL
; break;
228 case SC_VALID_DATE
: nLbPos
= SC_VALIDDLG_ALLOW_DATE
; break;
229 case SC_VALID_TIME
: nLbPos
= SC_VALIDDLG_ALLOW_TIME
; break;
230 case SC_VALID_TEXTLEN
: nLbPos
= SC_VALIDDLG_ALLOW_TEXTLEN
; break;
231 case SC_VALID_LIST
: nLbPos
= SC_VALIDDLG_ALLOW_RANGE
; break;
232 case SC_VALID_CUSTOM
: nLbPos
= SC_VALIDDLG_ALLOW_CUSTOM
; break;
233 default: OSL_FAIL( "lclGetPosFromValMode - unknown validity mode" );
238 /** Converts the passed list box position to an ScValidationMode. */
239 ScValidationMode
lclGetValModeFromPos( sal_uInt16 nLbPos
)
241 ScValidationMode eValMode
= SC_VALID_ANY
;
244 case SC_VALIDDLG_ALLOW_ANY
: eValMode
= SC_VALID_ANY
; break;
245 case SC_VALIDDLG_ALLOW_WHOLE
: eValMode
= SC_VALID_WHOLE
; break;
246 case SC_VALIDDLG_ALLOW_DECIMAL
: eValMode
= SC_VALID_DECIMAL
; break;
247 case SC_VALIDDLG_ALLOW_DATE
: eValMode
= SC_VALID_DATE
; break;
248 case SC_VALIDDLG_ALLOW_TIME
: eValMode
= SC_VALID_TIME
; break;
249 case SC_VALIDDLG_ALLOW_RANGE
: eValMode
= SC_VALID_LIST
; break;
250 case SC_VALIDDLG_ALLOW_LIST
: eValMode
= SC_VALID_LIST
; break;
251 case SC_VALIDDLG_ALLOW_TEXTLEN
: eValMode
= SC_VALID_TEXTLEN
; break;
252 case SC_VALIDDLG_ALLOW_CUSTOM
: eValMode
= SC_VALID_CUSTOM
; break;
253 default: OSL_FAIL( "lclGetValModeFromPos - invalid list box position" );
258 /** Converts the passed ScConditionMode to the position in the list box. */
259 sal_uInt16
lclGetPosFromCondMode( ScConditionMode eCondMode
)
261 sal_uInt16 nLbPos
= SC_VALIDDLG_DATA_EQUAL
;
264 case ScConditionMode::NONE
: // may occur in old XML files after Excel import
265 case ScConditionMode::Equal
: nLbPos
= SC_VALIDDLG_DATA_EQUAL
; break;
266 case ScConditionMode::Less
: nLbPos
= SC_VALIDDLG_DATA_LESS
; break;
267 case ScConditionMode::Greater
: nLbPos
= SC_VALIDDLG_DATA_GREATER
; break;
268 case ScConditionMode::EqLess
: nLbPos
= SC_VALIDDLG_DATA_EQLESS
; break;
269 case ScConditionMode::EqGreater
: nLbPos
= SC_VALIDDLG_DATA_EQGREATER
; break;
270 case ScConditionMode::NotEqual
: nLbPos
= SC_VALIDDLG_DATA_NOTEQUAL
; break;
271 case ScConditionMode::Between
: nLbPos
= SC_VALIDDLG_DATA_VALIDRANGE
; break;
272 case ScConditionMode::NotBetween
: nLbPos
= SC_VALIDDLG_DATA_INVALIDRANGE
; break;
273 case ScConditionMode::Direct
: nLbPos
= SC_VALIDDLG_DATA_DIRECT
; break;
274 default: OSL_FAIL( "lclGetPosFromCondMode - unknown condition mode" );
279 /** Converts the passed list box position to an ScConditionMode. */
280 ScConditionMode
lclGetCondModeFromPos( sal_uInt16 nLbPos
)
282 ScConditionMode eCondMode
= ScConditionMode::Equal
;
285 case SC_VALIDDLG_DATA_EQUAL
: eCondMode
= ScConditionMode::Equal
; break;
286 case SC_VALIDDLG_DATA_LESS
: eCondMode
= ScConditionMode::Less
; break;
287 case SC_VALIDDLG_DATA_GREATER
: eCondMode
= ScConditionMode::Greater
; break;
288 case SC_VALIDDLG_DATA_EQLESS
: eCondMode
= ScConditionMode::EqLess
; break;
289 case SC_VALIDDLG_DATA_EQGREATER
: eCondMode
= ScConditionMode::EqGreater
; break;
290 case SC_VALIDDLG_DATA_NOTEQUAL
: eCondMode
= ScConditionMode::NotEqual
; break;
291 case SC_VALIDDLG_DATA_VALIDRANGE
: eCondMode
= ScConditionMode::Between
; break;
292 case SC_VALIDDLG_DATA_INVALIDRANGE
: eCondMode
= ScConditionMode::NotBetween
; break;
293 case SC_VALIDDLG_DATA_DIRECT
: eCondMode
= ScConditionMode::Direct
; break;
294 default: OSL_FAIL( "lclGetCondModeFromPos - invalid list box position" );
299 /** Converts line feed separated string to a formula with strings separated by semicolons.
300 @descr Keeps all empty strings.
301 Example: abc\ndef\n\nghi -> "abc";"def";"";"ghi".
302 @param rFmlaStr (out-param) The converted formula string. */
303 void lclGetFormulaFromStringList( OUString
& rFmlaStr
, std::u16string_view rStringList
, sal_Unicode cFmlaSep
)
306 if (!rStringList
.empty())
311 OUString aToken
{o3tl::getToken(rStringList
, 0, '\n', nIdx
)};
312 ScGlobal::AddQuotes( aToken
, '"' );
313 rFmlaStr
= ScGlobal::addToken(rFmlaStr
, aToken
, cFmlaSep
);
317 if( rFmlaStr
.isEmpty() )
321 /** Converts formula with strings separated by semicolons to line feed separated string.
322 @descr Keeps all empty strings. Ignores all empty tokens (multiple semicolons).
323 Example: "abc";;;"def";"";"ghi" -> abc\ndef\n\nghi.
324 @param rStringList (out-param) The converted line feed separated string list.
325 @return true = Conversion successful. */
326 bool lclGetStringListFromFormula( OUString
& rStringList
, const OUString
& rFmlaStr
, sal_Unicode cFmlaSep
)
328 static constexpr OUStringLiteral
aQuotes( u
"\"\"" );
331 bool bIsStringList
= !rFmlaStr
.isEmpty();
332 bool bTokenAdded
= false;
334 for ( sal_Int32 nStringIx
= 0; bIsStringList
&& nStringIx
>=0; )
336 OUString
aToken( ScStringUtil::GetQuotedToken(rFmlaStr
, 0, aQuotes
, cFmlaSep
, nStringIx
) );
337 aToken
= comphelper::string::strip(aToken
, ' ');
338 if( !aToken
.isEmpty() ) // ignore empty tokens, i.e. "a";;"b"
340 bIsStringList
= ScGlobal::IsQuoted( aToken
, '"' );
343 ScGlobal::EraseQuotes( aToken
, '"' );
344 rStringList
= ScGlobal::addToken(rStringList
, aToken
, '\n', 1, bTokenAdded
);
350 return bIsStringList
;
355 ScTPValidationValue::ScTPValidationValue(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rArgSet
)
356 : SfxTabPage(pPage
, pController
, u
"modules/scalc/ui/validationcriteriapage.ui"_ustr
,
357 u
"ValidationCriteriaPage"_ustr
, &rArgSet
)
358 , maStrMin(ScResId(SCSTR_VALID_MINIMUM
))
359 , maStrMax(ScResId(SCSTR_VALID_MAXIMUM
))
360 , maStrValue(ScResId(SCSTR_VALID_VALUE
))
361 , maStrFormula(ScResId(SCSTR_VALID_FORMULA
))
362 , maStrRange(ScResId(SCSTR_VALID_RANGE
))
363 , maStrList(ScResId(SCSTR_VALID_LIST
))
364 , m_pRefEdit(nullptr)
365 , m_xLbAllow(m_xBuilder
->weld_combo_box(u
"allow"_ustr
))
366 , m_xCbAllow(m_xBuilder
->weld_check_button(u
"allowempty"_ustr
))
367 , m_xCbCaseSens(m_xBuilder
->weld_check_button(u
"casesens"_ustr
))
368 , m_xCbShow(m_xBuilder
->weld_check_button(u
"showlist"_ustr
))
369 , m_xCbSort(m_xBuilder
->weld_check_button(u
"sortascend"_ustr
))
370 , m_xFtValue(m_xBuilder
->weld_label(u
"valueft"_ustr
))
371 , m_xLbValue(m_xBuilder
->weld_combo_box(u
"data"_ustr
))
372 , m_xFtMin(m_xBuilder
->weld_label(u
"minft"_ustr
))
373 , m_xMinGrid(m_xBuilder
->weld_widget(u
"mingrid"_ustr
))
374 , m_xEdMin(new formula::RefEdit(m_xBuilder
->weld_entry(u
"min"_ustr
)))
375 , m_xEdList(m_xBuilder
->weld_text_view(u
"minlist"_ustr
))
376 , m_xFtMax(m_xBuilder
->weld_label(u
"maxft"_ustr
))
377 , m_xEdMax(new formula::RefEdit(m_xBuilder
->weld_entry(u
"max"_ustr
)))
378 , m_xFtHint(m_xBuilder
->weld_label(u
"hintft"_ustr
))
379 , m_xBtnRef(new formula::RefButton(m_xBuilder
->weld_button(u
"validref"_ustr
)))
380 , m_xRefGrid(m_xBuilder
->weld_container(u
"refgrid"_ustr
))
381 , m_pRefEditParent(m_xRefGrid
.get())
382 , m_pBtnRefParent(m_xRefGrid
.get())
384 m_xEdMin
->SetReferences(nullptr, m_xFtMin
.get());
386 Size
aSize(m_xEdList
->get_approximate_digit_width() * 40,
387 m_xEdList
->get_height_rows(10));
388 m_xEdList
->set_size_request(aSize
.Width(), aSize
.Height());
389 m_xEdMax
->SetReferences(nullptr, m_xFtMax
.get());
391 m_xBtnRef
->SetClickHdl(LINK(this, ScTPValidationValue
, ClickHdl
));
393 //lock in the max size initial config
394 aSize
= m_xContainer
->get_preferred_size();
395 m_xContainer
->set_size_request(aSize
.Width(), aSize
.Height());
399 // list separator in formulas
400 OUString aListSep
= ::ScCompiler::GetNativeSymbol( ocSep
);
401 OSL_ENSURE( aListSep
.getLength() == 1, "ScTPValidationValue::ScTPValidationValue - list separator error" );
402 mcFmlaSep
= aListSep
.getLength() ? aListSep
[0] : ';';
403 m_xBtnRef
->GetWidget()->hide(); // cell range picker
406 ScTPValidationValue::~ScTPValidationValue()
413 void ScTPValidationValue::Init()
415 m_xLbAllow
->connect_changed( LINK( this, ScTPValidationValue
, SelectHdl
) );
416 m_xLbValue
->connect_changed( LINK( this, ScTPValidationValue
, SelectHdl
) );
417 m_xCbShow
->connect_toggled( LINK( this, ScTPValidationValue
, CheckHdl
) );
420 m_xEdMin
->SetGetFocusHdl( LINK( this, ScTPValidationValue
, EditSetFocusHdl
) );
421 m_xEdMin
->SetLoseFocusHdl( LINK( this, ScTPValidationValue
, KillEditFocusHdl
) );
422 m_xEdMax
->SetGetFocusHdl( LINK( this, ScTPValidationValue
, EditSetFocusHdl
) );
423 m_xEdMax
->SetLoseFocusHdl( LINK( this, ScTPValidationValue
, KillEditFocusHdl
) );
424 m_xBtnRef
->SetLoseFocusHdl( LINK( this, ScTPValidationValue
, KillButtonFocusHdl
) );
426 m_xLbAllow
->set_active( SC_VALIDDLG_ALLOW_ANY
);
427 m_xLbValue
->set_active( SC_VALIDDLG_DATA_EQUAL
);
429 SelectHdl( *m_xLbAllow
);
430 CheckHdl( *m_xCbShow
);
433 std::unique_ptr
<SfxTabPage
> ScTPValidationValue::Create(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rArgSet
)
435 return std::make_unique
<ScTPValidationValue
>(pPage
, pController
, *rArgSet
);
438 void ScTPValidationValue::Reset( const SfxItemSet
* rArgSet
)
440 sal_uInt16 nLbPos
= SC_VALIDDLG_ALLOW_ANY
;
441 if( const SfxUInt16Item
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_MODE
) )
442 nLbPos
= lclGetPosFromValMode( static_cast< ScValidationMode
>( pItem
->GetValue() ) );
443 m_xLbAllow
->set_active( nLbPos
);
445 nLbPos
= SC_VALIDDLG_DATA_EQUAL
;
446 if( const SfxUInt16Item
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_CONDMODE
) )
447 nLbPos
= lclGetPosFromCondMode( static_cast< ScConditionMode
>( pItem
->GetValue() ) );
448 m_xLbValue
->set_active( nLbPos
);
450 // *** check boxes ***
452 if( const SfxBoolItem
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_BLANK
) )
453 bCheck
= pItem
->GetValue();
454 m_xCbAllow
->set_active( bCheck
);
456 bool bCaseSensetive
= false;
457 if (const SfxBoolItem
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_CASESENS
) )
458 bCaseSensetive
= pItem
->GetValue();
459 m_xCbCaseSens
->set_active( bCaseSensetive
);
461 sal_Int32 nListType
= ValidListType::UNSORTED
;
462 if( const SfxInt16Item
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_LISTTYPE
) )
463 nListType
= pItem
->GetValue();
464 m_xCbShow
->set_active( nListType
!= ValidListType::INVISIBLE
);
465 m_xCbSort
->set_active( nListType
== ValidListType::SORTEDASCENDING
);
469 if ( const SfxStringItem
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_VALUE1
) )
470 aFmlaStr
= pItem
->GetValue();
471 SetFirstFormula( aFmlaStr
);
474 if ( const SfxStringItem
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_VALUE2
) )
475 aFmlaStr
= pItem
->GetValue();
476 SetSecondFormula( aFmlaStr
);
478 SelectHdl( *m_xLbAllow
);
479 CheckHdl( *m_xCbShow
);
482 bool ScTPValidationValue::FillItemSet( SfxItemSet
* rArgSet
)
484 sal_Int16 nListType
= m_xCbShow
->get_active() ?
485 (m_xCbSort
->get_active() ? ValidListType::SORTEDASCENDING
: ValidListType::UNSORTED
) :
486 ValidListType::INVISIBLE
;
488 const sal_Int32 nLbPos
= m_xLbAllow
->get_active();
489 bool bCustom
= (nLbPos
== SC_VALIDDLG_ALLOW_CUSTOM
);
490 ScConditionMode eCondMode
= bCustom
?
491 ScConditionMode::Direct
: lclGetCondModeFromPos( m_xLbValue
->get_active() );
493 rArgSet
->Put( SfxUInt16Item( FID_VALID_MODE
, sal::static_int_cast
<sal_uInt16
>(
494 lclGetValModeFromPos( nLbPos
) ) ) );
495 rArgSet
->Put( SfxUInt16Item( FID_VALID_CONDMODE
, sal::static_int_cast
<sal_uInt16
>( eCondMode
) ) );
496 rArgSet
->Put( SfxStringItem( FID_VALID_VALUE1
, GetFirstFormula() ) );
497 rArgSet
->Put( SfxStringItem( FID_VALID_VALUE2
, GetSecondFormula() ) );
498 rArgSet
->Put( SfxBoolItem( FID_VALID_BLANK
, m_xCbAllow
->get_active() ) );
499 rArgSet
->Put( SfxBoolItem( FID_VALID_CASESENS
, m_xCbCaseSens
->get_active() ) );
500 rArgSet
->Put( SfxInt16Item( FID_VALID_LISTTYPE
, nListType
) );
504 OUString
ScTPValidationValue::GetFirstFormula() const
507 if( m_xLbAllow
->get_active() == SC_VALIDDLG_ALLOW_LIST
)
508 lclGetFormulaFromStringList( aFmlaStr
, m_xEdList
->get_text(), mcFmlaSep
);
510 aFmlaStr
= m_xEdMin
->GetText();
514 OUString
ScTPValidationValue::GetSecondFormula() const
516 return m_xEdMax
->GetText();
519 void ScTPValidationValue::SetFirstFormula( const OUString
& rFmlaStr
)
521 // try if formula is a string list, validation mode must already be set
522 OUString aStringList
;
523 if( (m_xLbAllow
->get_active() == SC_VALIDDLG_ALLOW_RANGE
) &&
524 lclGetStringListFromFormula( aStringList
, rFmlaStr
, mcFmlaSep
) )
526 m_xEdList
->set_text( aStringList
);
527 m_xEdMin
->SetText( OUString() );
528 // change validation mode to string list
529 m_xLbAllow
->set_active( SC_VALIDDLG_ALLOW_LIST
);
533 m_xEdMin
->SetText( rFmlaStr
);
534 m_xEdList
->set_text( OUString() );
538 void ScTPValidationValue::SetSecondFormula( const OUString
& rFmlaStr
)
540 m_xEdMax
->SetText( rFmlaStr
);
543 ScValidationDlg
* ScTPValidationValue::GetValidationDlg()
545 return dynamic_cast<ScValidationDlg
*>(GetDialogController());
548 void ScTPValidationValue::SetupRefDlg()
550 ScValidationDlg
*pValidationDlg
= GetValidationDlg();
551 if( !pValidationDlg
)
554 if( !pValidationDlg
->SetupRefDlg() )
557 pValidationDlg
->SetHandler( this );
558 pValidationDlg
->SetSetRefHdl( static_cast<ScRefHandlerHelper::PFUNCSETREFHDLTYPE
>( &ScTPValidationValue::SetReferenceHdl
) );
559 pValidationDlg
->SetSetActHdl( static_cast<ScRefHandlerHelper::PCOMMONHDLTYPE
>( &ScTPValidationValue::SetActiveHdl
) );
560 pValidationDlg
->SetRefInputStartPreHdl( static_cast<ScRefHandlerHelper::PINPUTSTARTDLTYPE
>( &ScTPValidationValue::RefInputStartPreHdl
) );
561 pValidationDlg
->SetRefInputDonePostHdl( static_cast<ScRefHandlerHelper::PCOMMONHDLTYPE
>( &ScTPValidationValue::RefInputDonePostHdl
) );
563 weld::Label
* pLabel
= nullptr;
565 if (m_xEdMax
->GetWidget()->get_visible())
567 m_pRefEdit
= m_xEdMax
.get();
568 pLabel
= m_xFtMax
.get();
570 else if (m_xEdMin
->GetWidget()->get_visible())
572 m_pRefEdit
= m_xEdMin
.get();
573 pLabel
= m_xFtMin
.get();
576 if (m_pRefEdit
&& !m_pRefEdit
->GetWidget()->has_focus())
577 m_pRefEdit
->GrabFocus();
580 m_pRefEdit
->SetReferences( pValidationDlg
, pLabel
);
582 m_xBtnRef
->SetReferences( pValidationDlg
, m_pRefEdit
);
585 void ScTPValidationValue::RemoveRefDlg(bool bRestoreModal
)
587 ScValidationDlg
*pValidationDlg
= GetValidationDlg();
588 if( !pValidationDlg
)
591 if( !pValidationDlg
->RemoveRefDlg(bRestoreModal
) )
594 pValidationDlg
->SetHandler( nullptr );
595 pValidationDlg
->SetSetRefHdl( nullptr );
596 pValidationDlg
->SetSetActHdl( nullptr );
597 pValidationDlg
->SetRefInputStartPreHdl( nullptr );
598 pValidationDlg
->SetRefInputDonePostHdl( nullptr );
601 m_pRefEdit
->SetReferences( nullptr, nullptr );
602 m_pRefEdit
= nullptr;
604 m_xBtnRef
->SetReferences( nullptr, nullptr );
607 IMPL_LINK_NOARG(ScTPValidationValue
, EditSetFocusHdl
, formula::RefEdit
&, void)
609 const sal_Int32 nPos
= m_xLbAllow
->get_active();
611 if ( nPos
== SC_VALIDDLG_ALLOW_RANGE
)
617 IMPL_LINK( ScTPValidationValue
, KillEditFocusHdl
, formula::RefEdit
&, rWnd
, void )
619 if (&rWnd
!= m_pRefEdit
)
621 if( ScValidationDlg
*pValidationDlg
= GetValidationDlg() )
623 if (pValidationDlg
->IsChildFocus() && !pValidationDlg
->IsRefInputting())
625 if( ( !m_pRefEdit
|| !m_pRefEdit
->GetWidget()->has_focus()) && !m_xBtnRef
->GetWidget()->has_focus() )
633 IMPL_LINK( ScTPValidationValue
, KillButtonFocusHdl
, formula::RefButton
&, rWnd
, void )
635 if( &rWnd
!= m_xBtnRef
.get())
637 if( ScValidationDlg
*pValidationDlg
= GetValidationDlg() )
638 if (pValidationDlg
->IsChildFocus() && !pValidationDlg
->IsRefInputting())
639 if( ( !m_pRefEdit
|| !m_pRefEdit
->GetWidget()->has_focus()) && !m_xBtnRef
->GetWidget()->has_focus() )
645 IMPL_LINK_NOARG(ScTPValidationValue
, SelectHdl
, weld::ComboBox
&, void)
647 const sal_Int32 nLbPos
= m_xLbAllow
->get_active();
648 bool bEnable
= (nLbPos
!= SC_VALIDDLG_ALLOW_ANY
);
649 bool bRange
= (nLbPos
== SC_VALIDDLG_ALLOW_RANGE
);
650 bool bList
= (nLbPos
== SC_VALIDDLG_ALLOW_LIST
);
651 bool bCustom
= (nLbPos
== SC_VALIDDLG_ALLOW_CUSTOM
);
653 m_xCbAllow
->set_sensitive( bEnable
); // Empty cell
654 m_xCbCaseSens
->set_sensitive( bEnable
&&
655 (bRange
|| bList
|| bCustom
) ); // Case Sensitive
656 m_xFtValue
->set_sensitive( bEnable
);
657 m_xLbValue
->set_sensitive( bEnable
);
658 m_xFtMin
->set_sensitive( bEnable
);
659 m_xEdMin
->GetWidget()->set_sensitive( bEnable
);
660 m_xEdList
->set_sensitive( bEnable
);
661 m_xFtMax
->set_sensitive( bEnable
);
662 m_xEdMax
->GetWidget()->set_sensitive( bEnable
);
664 bool bShowMax
= false;
667 m_xFtMin
->set_label( maStrRange
);
669 m_xFtMin
->set_label( maStrList
);
671 m_xFtMin
->set_label( maStrFormula
);
674 switch( m_xLbValue
->get_active() )
676 case SC_VALIDDLG_DATA_EQUAL
:
677 case SC_VALIDDLG_DATA_NOTEQUAL
: m_xFtMin
->set_label( maStrValue
); break;
679 case SC_VALIDDLG_DATA_LESS
:
680 case SC_VALIDDLG_DATA_EQLESS
: m_xFtMin
->set_label( maStrMax
); break;
682 case SC_VALIDDLG_DATA_VALIDRANGE
:
683 case SC_VALIDDLG_DATA_INVALIDRANGE
: bShowMax
= true;
685 case SC_VALIDDLG_DATA_GREATER
:
686 case SC_VALIDDLG_DATA_EQGREATER
: m_xFtMin
->set_label( maStrMin
); break;
689 OSL_FAIL( "ScTPValidationValue::SelectHdl - unknown condition mode" );
693 m_xCbCaseSens
->set_visible( bRange
|| bList
|| bCustom
); // Case Sensitive
694 m_xCbShow
->set_visible( bRange
|| bList
);
695 m_xCbSort
->set_visible( bRange
|| bList
);
696 m_xFtValue
->set_visible( !bRange
&& !bList
&& !bCustom
);
697 m_xLbValue
->set_visible( !bRange
&& !bList
&& !bCustom
);
698 m_xEdMin
->GetWidget()->set_visible( !bList
);
699 m_xEdList
->set_visible( bList
);
700 m_xMinGrid
->set_vexpand( bList
);
701 m_xFtMax
->set_visible( bShowMax
);
702 m_xEdMax
->GetWidget()->set_visible( bShowMax
);
703 m_xFtHint
->set_visible( bRange
);
704 m_xBtnRef
->GetWidget()->set_visible( bRange
); // cell range picker
707 IMPL_LINK_NOARG(ScTPValidationValue
, CheckHdl
, weld::Toggleable
&, void)
709 m_xCbSort
->set_sensitive( m_xCbShow
->get_active() );
714 ScTPValidationHelp::ScTPValidationHelp(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rArgSet
)
715 : SfxTabPage(pPage
, pController
, u
"modules/scalc/ui/validationhelptabpage.ui"_ustr
, u
"ValidationHelpTabPage"_ustr
, &rArgSet
)
716 , m_xTsbHelp(m_xBuilder
->weld_check_button(u
"tsbhelp"_ustr
))
717 , m_xEdtTitle(m_xBuilder
->weld_entry(u
"title"_ustr
))
718 , m_xEdInputHelp(m_xBuilder
->weld_text_view(u
"inputhelp_text"_ustr
))
720 m_xEdInputHelp
->set_size_request(m_xEdInputHelp
->get_approximate_digit_width() * 40, m_xEdInputHelp
->get_height_rows(13));
723 ScTPValidationHelp::~ScTPValidationHelp()
727 std::unique_ptr
<SfxTabPage
> ScTPValidationHelp::Create(weld::Container
* pPage
, weld::DialogController
* pController
,
728 const SfxItemSet
* rArgSet
)
730 return std::make_unique
<ScTPValidationHelp
>(pPage
, pController
, *rArgSet
);
733 void ScTPValidationHelp::Reset( const SfxItemSet
* rArgSet
)
735 if ( const SfxBoolItem
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_SHOWHELP
) )
736 m_xTsbHelp
->set_state( pItem
->GetValue() ? TRISTATE_TRUE
: TRISTATE_FALSE
);
738 m_xTsbHelp
->set_state( TRISTATE_FALSE
);
740 if ( const SfxStringItem
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_HELPTITLE
) )
741 m_xEdtTitle
->set_text( pItem
->GetValue() );
743 m_xEdtTitle
->set_text( OUString() );
745 if ( const SfxStringItem
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_HELPTEXT
) )
746 m_xEdInputHelp
->set_text( pItem
->GetValue() );
748 m_xEdInputHelp
->set_text( OUString() );
751 bool ScTPValidationHelp::FillItemSet( SfxItemSet
* rArgSet
)
753 rArgSet
->Put( SfxBoolItem( FID_VALID_SHOWHELP
, m_xTsbHelp
->get_state() == TRISTATE_TRUE
) );
754 rArgSet
->Put( SfxStringItem( FID_VALID_HELPTITLE
, m_xEdtTitle
->get_text() ) );
755 rArgSet
->Put( SfxStringItem( FID_VALID_HELPTEXT
, m_xEdInputHelp
->get_text() ) );
762 ScTPValidationError::ScTPValidationError(weld::Container
* pPage
, weld::DialogController
* pController
,
763 const SfxItemSet
& rArgSet
)
765 : SfxTabPage ( pPage
, pController
,
766 u
"modules/scalc/ui/erroralerttabpage.ui"_ustr
, u
"ErrorAlertTabPage"_ustr
,
768 , m_xTsbShow(m_xBuilder
->weld_check_button(u
"tsbshow"_ustr
))
769 , m_xLbAction(m_xBuilder
->weld_combo_box(u
"actionCB"_ustr
))
770 , m_xBtnSearch(m_xBuilder
->weld_button(u
"browseBtn"_ustr
))
771 , m_xEdtTitle(m_xBuilder
->weld_entry(u
"erroralert_title"_ustr
))
772 , m_xFtError(m_xBuilder
->weld_label(u
"errormsg_label"_ustr
))
773 , m_xEdError(m_xBuilder
->weld_text_view(u
"errorMsg"_ustr
))
775 m_xEdError
->set_size_request(m_xEdError
->get_approximate_digit_width() * 40, m_xEdError
->get_height_rows(12));
779 ScTPValidationError::~ScTPValidationError()
783 void ScTPValidationError::Init()
785 m_xLbAction
->connect_changed(LINK(this, ScTPValidationError
, SelectActionHdl
));
786 m_xBtnSearch
->connect_clicked(LINK( this, ScTPValidationError
, ClickSearchHdl
));
788 m_xLbAction
->set_active(0);
790 SelectActionHdl(*m_xLbAction
);
793 std::unique_ptr
<SfxTabPage
> ScTPValidationError::Create(weld::Container
* pPage
, weld::DialogController
* pController
,
794 const SfxItemSet
* rArgSet
)
796 return std::make_unique
<ScTPValidationError
>(pPage
, pController
, *rArgSet
);
799 void ScTPValidationError::Reset( const SfxItemSet
* rArgSet
)
801 if ( const SfxBoolItem
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_SHOWERR
) )
802 m_xTsbShow
->set_state( pItem
->GetValue() ? TRISTATE_TRUE
: TRISTATE_FALSE
);
804 m_xTsbShow
->set_state( TRISTATE_TRUE
); // check by default
806 if ( const SfxUInt16Item
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_ERRSTYLE
) )
807 m_xLbAction
->set_active( pItem
->GetValue() );
809 m_xLbAction
->set_active( 0 );
811 if ( const SfxStringItem
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_ERRTITLE
) )
812 m_xEdtTitle
->set_text( pItem
->GetValue() );
814 m_xEdtTitle
->set_text( OUString() );
816 if ( const SfxStringItem
* pItem
= rArgSet
->GetItemIfSet( FID_VALID_ERRTEXT
) )
817 m_xEdError
->set_text( pItem
->GetValue() );
819 m_xEdError
->set_text( OUString() );
821 SelectActionHdl(*m_xLbAction
);
824 bool ScTPValidationError::FillItemSet( SfxItemSet
* rArgSet
)
826 rArgSet
->Put( SfxBoolItem( FID_VALID_SHOWERR
, m_xTsbShow
->get_state() == TRISTATE_TRUE
) );
827 rArgSet
->Put( SfxUInt16Item( FID_VALID_ERRSTYLE
, m_xLbAction
->get_active() ) );
828 rArgSet
->Put( SfxStringItem( FID_VALID_ERRTITLE
, m_xEdtTitle
->get_text() ) );
829 rArgSet
->Put( SfxStringItem( FID_VALID_ERRTEXT
, m_xEdError
->get_text() ) );
834 IMPL_LINK_NOARG(ScTPValidationError
, SelectActionHdl
, weld::ComboBox
&, void)
836 ScValidErrorStyle eStyle
= static_cast<ScValidErrorStyle
>(m_xLbAction
->get_active());
837 bool bMacro
= ( eStyle
== SC_VALERR_MACRO
);
839 m_xBtnSearch
->set_sensitive( bMacro
);
840 m_xFtError
->set_sensitive( !bMacro
);
841 m_xEdError
->set_sensitive( !bMacro
);
844 IMPL_LINK_NOARG(ScTPValidationError
, ClickSearchHdl
, weld::Button
&, void)
846 // Use static SfxApplication method to bring up selector dialog for
848 OUString aScriptURL
= SfxApplication::ChooseScript(GetFrameWeld());
850 if ( !aScriptURL
.isEmpty() )
852 m_xEdtTitle
->set_text( aScriptURL
);
856 bool ScValidationDlg::EnterRefStatus()
858 ScTabViewShell
*pTabViewShell
= GetTabViewShell();
860 if( !pTabViewShell
) return false;
862 sal_uInt16 nId
= SLOTID
;
863 SfxViewFrame
& rViewFrm
= pTabViewShell
->GetViewFrame();
864 SfxChildWindow
* pWnd
= rViewFrm
.GetChildWindow( nId
);
866 if (pWnd
&& pWnd
->GetController().get() != this) pWnd
= nullptr;
868 ScModule::get()->SetRefDialog(nId
, pWnd
== nullptr);
873 bool ScValidationDlg::LeaveRefStatus()
875 ScTabViewShell
*pTabViewShell
= GetTabViewShell();
877 if( !pTabViewShell
) return false;
879 sal_uInt16 nId
= SLOTID
;
880 SfxViewFrame
& rViewFrm
= pTabViewShell
->GetViewFrame();
881 if (rViewFrm
.GetChildWindow(nId
))
888 bool ScValidationDlg::SetupRefDlg()
890 if ( m_bOwnRefHdlr
) return false;
894 m_bOwnRefHdlr
= true;
895 return EnterRefStatus();
901 bool ScValidationDlg::RemoveRefDlg( bool bRestoreModal
/* = true */ )
903 bool bVisLock
= false;
904 bool bFreeWindowLock
= false;
906 ScTabViewShell
*pTabVwSh
= GetTabViewShell();
908 if( !pTabVwSh
) return false;
910 if ( SfxChildWindow
* pWnd
= pTabVwSh
->GetViewFrame().GetChildWindow( SID_VALIDITY_REFERENCE
) )
912 bVisLock
= static_cast<ScValidityRefChildWin
*>(pWnd
)->LockVisible( true );
913 bFreeWindowLock
= static_cast<ScValidityRefChildWin
*>(pWnd
)->LockFreeWindow( true );
916 if ( !m_bOwnRefHdlr
) return false;
917 if( LeaveRefStatus() && LeaveRefMode() )
919 m_bOwnRefHdlr
= false;
927 if ( SfxChildWindow
* pWnd
= pTabVwSh
->GetViewFrame().GetChildWindow( SID_VALIDITY_REFERENCE
) )
929 static_cast<ScValidityRefChildWin
*>(pWnd
)->LockVisible( bVisLock
);
930 static_cast<ScValidityRefChildWin
*>(pWnd
)->LockFreeWindow( bFreeWindowLock
);
936 IMPL_LINK_NOARG(ScTPValidationValue
, ClickHdl
, formula::RefButton
&, void)
941 bool ScValidationDlg::IsChildFocus() const
943 return m_xDialog
->has_toplevel_focus();
946 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */