Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / dbgui / validate.cxx
blob9952af2ef15a1c00d51bf246af7ec32fd6290be4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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
22 #endif
24 #include <comphelper/string.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/builderfactory.hxx>
27 #include <svl/aeitem.hxx>
28 #include <svl/stritem.hxx>
29 #include <svl/eitem.hxx>
30 #include <svl/intitem.hxx>
31 #include <basic/sbmeth.hxx>
32 #include <basic/sbstar.hxx>
33 #include <basic/sbmod.hxx>
34 #include <sfx2/app.hxx>
36 #include "scresid.hxx"
37 #include "sc.hrc"
39 #include "stringutil.hxx"
40 #include "validat.hxx"
41 #include "validate.hxx"
42 #include "compiler.hxx"
43 #include <formula/opcode.hxx>
45 // cell range picker
46 #include "tabvwsh.hxx"
47 #include <sfx2/viewfrm.hxx>
48 #include <sfx2/childwin.hxx>
49 #include "reffact.hxx"
51 /* Position indexes for "Allow" list box.
52 They do not map directly to ScValidationMode and can safely be modified to
53 change the order of the list box entries. */
54 #define SC_VALIDDLG_ALLOW_ANY 0
55 #define SC_VALIDDLG_ALLOW_WHOLE 1
56 #define SC_VALIDDLG_ALLOW_DECIMAL 2
57 #define SC_VALIDDLG_ALLOW_DATE 3
58 #define SC_VALIDDLG_ALLOW_TIME 4
59 #define SC_VALIDDLG_ALLOW_RANGE 5
60 #define SC_VALIDDLG_ALLOW_LIST 6
61 #define SC_VALIDDLG_ALLOW_TEXTLEN 7
63 /* Position indexes for "Data" list box.
64 They do not map directly to ScConditionMode and can safely be modified to
65 change the order of the list box entries. */
66 #define SC_VALIDDLG_DATA_EQUAL 0
67 #define SC_VALIDDLG_DATA_LESS 1
68 #define SC_VALIDDLG_DATA_GREATER 2
69 #define SC_VALIDDLG_DATA_EQLESS 3
70 #define SC_VALIDDLG_DATA_EQGREATER 4
71 #define SC_VALIDDLG_DATA_NOTEQUAL 5
72 #define SC_VALIDDLG_DATA_VALIDRANGE 6
73 #define SC_VALIDDLG_DATA_INVALIDRANGE 7
75 namespace ValidListType = css::sheet::TableValidationVisibility;
77 const sal_uInt16 ScTPValidationValue::pValueRanges[] =
79 FID_VALID_MODE, FID_VALID_ERRTEXT,
80 FID_VALID_LISTTYPE, FID_VALID_LISTTYPE,
84 ScValidationDlg::ScValidationDlg(vcl::Window* pParent, const SfxItemSet* pArgSet,
85 ScTabViewShell *pTabViewSh, SfxBindings *pB /*= NULL*/)
86 : ScValidationDlgBase(pParent ? pParent : SfxGetpApp()->GetTopWindow(),
87 "ValidationDialog", "modules/scalc/ui/validationdialog.ui", pArgSet, pB)
88 , m_pTabVwSh(pTabViewSh)
89 , m_nValuePageId(0)
90 , m_bOwnRefHdlr(false)
91 , m_bRefInputting(false)
93 m_nValuePageId = AddTabPage("criteria", ScTPValidationValue::Create, nullptr);
94 AddTabPage("inputhelp", ScTPValidationHelp::Create, nullptr);
95 AddTabPage("erroralert", ScTPValidationError::Create, nullptr);
96 get(m_pHBox, "refinputbox");
99 ScValidationDlg::~ScValidationDlg()
101 disposeOnce();
104 void ScTPValidationValue::SetReferenceHdl( const ScRange&rRange , ScDocument* pDoc )
106 if ( rRange.aStart != rRange.aEnd )
107 if ( ScValidationDlg *pValidationDlg = GetValidationDlg() )
108 if( m_pRefEdit )
109 pValidationDlg->RefInputStart( m_pRefEdit );
111 if ( m_pRefEdit )
113 OUString aStr(rRange.Format(ScRefFlags::RANGE_ABS_3D, pDoc, pDoc->GetAddressConvention()));
114 m_pRefEdit->SetRefString( aStr );
118 void ScTPValidationValue:: SetActiveHdl()
120 if ( m_pRefEdit ) m_pRefEdit->GrabFocus();
122 if ( ScValidationDlg *pValidationDlg = GetValidationDlg() )
123 if( m_pRefEdit )
125 pValidationDlg->RefInputDone();
129 void ScTPValidationValue::RefInputStartPreHdl( formula::RefEdit* pEdit, formula::RefButton* pButton )
131 if ( ScValidationDlg *pValidationDlg = GetValidationDlg() )
133 vcl::Window *pNewParent = pValidationDlg->get_refinput_shrink_parent();
134 if( pEdit == m_pRefEdit && m_pRefEdit->GetParent() != pNewParent )
136 m_pRefEdit->SetParent(pNewParent);
139 if( pButton == m_pBtnRef && m_pBtnRef->GetParent() != pNewParent )
141 m_pBtnRef->SetParent(pNewParent);
144 pNewParent->Show();
148 void ScTPValidationValue::RefInputDonePostHdl()
150 if( m_pRefEdit && m_pRefEdit->GetParent() != m_pRefGrid )
152 m_pRefEdit->SetParent( m_pRefGrid );
153 m_pBtnRef->SetParent( m_pRefEdit ); //if Edit SetParent but button not, the tab order will be incorrect, need button to setparent to another window and restore parent later in order to restore the tab order
156 if( m_pBtnRef->GetParent() != m_pRefGrid )
157 m_pBtnRef->SetParent( m_pRefGrid );
159 if ( ScValidationDlg *pValidationDlg = GetValidationDlg() )
161 pValidationDlg->get_refinput_shrink_parent()->Hide();
162 ScViewData& rViewData = pValidationDlg->GetTabViewShell()->GetViewData();
163 SCTAB nCurTab = rViewData.GetTabNo();
164 SCTAB nRefTab = rViewData.GetRefTabNo();
165 // If RefInput switched to a different sheet from the data sheet,
166 // switch back: fdo#53920
167 if ( nCurTab != nRefTab )
169 rViewData.GetViewShell()->SetTabNo( nRefTab );
173 if( m_pRefEdit && !m_pRefEdit->HasFocus() )
174 m_pRefEdit->GrabFocus();
177 ScTPValidationValue::ScRefButtonEx::~ScRefButtonEx()
179 disposeOnce();
182 void ScTPValidationValue::ScRefButtonEx::dispose()
184 m_pPage.clear();
185 ::formula::RefButton::dispose();
188 namespace {
190 /** Converts the passed ScValidationMode to the position in the list box. */
191 sal_uInt16 lclGetPosFromValMode( ScValidationMode eValMode )
193 sal_uInt16 nLbPos = SC_VALIDDLG_ALLOW_ANY;
194 switch( eValMode )
196 case SC_VALID_ANY: nLbPos = SC_VALIDDLG_ALLOW_ANY; break;
197 case SC_VALID_WHOLE: nLbPos = SC_VALIDDLG_ALLOW_WHOLE; break;
198 case SC_VALID_DECIMAL: nLbPos = SC_VALIDDLG_ALLOW_DECIMAL; break;
199 case SC_VALID_DATE: nLbPos = SC_VALIDDLG_ALLOW_DATE; break;
200 case SC_VALID_TIME: nLbPos = SC_VALIDDLG_ALLOW_TIME; break;
201 case SC_VALID_TEXTLEN: nLbPos = SC_VALIDDLG_ALLOW_TEXTLEN; break;
202 case SC_VALID_LIST: nLbPos = SC_VALIDDLG_ALLOW_RANGE; break;
203 case SC_VALID_CUSTOM: nLbPos = SC_VALIDDLG_ALLOW_ANY; break; // not supported
204 default: OSL_FAIL( "lclGetPosFromValMode - unknown validity mode" );
206 return nLbPos;
209 /** Converts the passed list box position to an ScValidationMode. */
210 ScValidationMode lclGetValModeFromPos( sal_uInt16 nLbPos )
212 ScValidationMode eValMode = SC_VALID_ANY;
213 switch( nLbPos )
215 case SC_VALIDDLG_ALLOW_ANY: eValMode = SC_VALID_ANY; break;
216 case SC_VALIDDLG_ALLOW_WHOLE: eValMode = SC_VALID_WHOLE; break;
217 case SC_VALIDDLG_ALLOW_DECIMAL: eValMode = SC_VALID_DECIMAL; break;
218 case SC_VALIDDLG_ALLOW_DATE: eValMode = SC_VALID_DATE; break;
219 case SC_VALIDDLG_ALLOW_TIME: eValMode = SC_VALID_TIME; break;
220 case SC_VALIDDLG_ALLOW_RANGE: eValMode = SC_VALID_LIST; break;
221 case SC_VALIDDLG_ALLOW_LIST: eValMode = SC_VALID_LIST; break;
222 case SC_VALIDDLG_ALLOW_TEXTLEN: eValMode = SC_VALID_TEXTLEN; break;
223 default: OSL_FAIL( "lclGetValModeFromPos - invalid list box position" );
225 return eValMode;
228 /** Converts the passed ScConditionMode to the position in the list box. */
229 sal_uInt16 lclGetPosFromCondMode( ScConditionMode eCondMode )
231 sal_uInt16 nLbPos = SC_VALIDDLG_DATA_EQUAL;
232 switch( eCondMode )
234 case SC_COND_NONE: // may occur in old XML files after Excel import
235 case SC_COND_EQUAL: nLbPos = SC_VALIDDLG_DATA_EQUAL; break;
236 case SC_COND_LESS: nLbPos = SC_VALIDDLG_DATA_LESS; break;
237 case SC_COND_GREATER: nLbPos = SC_VALIDDLG_DATA_GREATER; break;
238 case SC_COND_EQLESS: nLbPos = SC_VALIDDLG_DATA_EQLESS; break;
239 case SC_COND_EQGREATER: nLbPos = SC_VALIDDLG_DATA_EQGREATER; break;
240 case SC_COND_NOTEQUAL: nLbPos = SC_VALIDDLG_DATA_NOTEQUAL; break;
241 case SC_COND_BETWEEN: nLbPos = SC_VALIDDLG_DATA_VALIDRANGE; break;
242 case SC_COND_NOTBETWEEN: nLbPos = SC_VALIDDLG_DATA_INVALIDRANGE; break;
243 default: OSL_FAIL( "lclGetPosFromCondMode - unknown condition mode" );
245 return nLbPos;
248 /** Converts the passed list box position to an ScConditionMode. */
249 ScConditionMode lclGetCondModeFromPos( sal_uInt16 nLbPos )
251 ScConditionMode eCondMode = SC_COND_EQUAL;
252 switch( nLbPos )
254 case SC_VALIDDLG_DATA_EQUAL: eCondMode = SC_COND_EQUAL; break;
255 case SC_VALIDDLG_DATA_LESS: eCondMode = SC_COND_LESS; break;
256 case SC_VALIDDLG_DATA_GREATER: eCondMode = SC_COND_GREATER; break;
257 case SC_VALIDDLG_DATA_EQLESS: eCondMode = SC_COND_EQLESS; break;
258 case SC_VALIDDLG_DATA_EQGREATER: eCondMode = SC_COND_EQGREATER; break;
259 case SC_VALIDDLG_DATA_NOTEQUAL: eCondMode = SC_COND_NOTEQUAL; break;
260 case SC_VALIDDLG_DATA_VALIDRANGE: eCondMode = SC_COND_BETWEEN; break;
261 case SC_VALIDDLG_DATA_INVALIDRANGE: eCondMode = SC_COND_NOTBETWEEN; break;
262 default: OSL_FAIL( "lclGetCondModeFromPos - invalid list box position" );
264 return eCondMode;
267 /** Converts line feed separated string to a formula with strings separated by semicolons.
268 @descr Keeps all empty strings.
269 Example: abc\ndef\n\nghi -> "abc";"def";"";"ghi".
270 @param rFmlaStr (out-param) The converted formula string. */
271 void lclGetFormulaFromStringList( OUString& rFmlaStr, const OUString& rStringList, sal_Unicode cFmlaSep )
273 rFmlaStr.clear();
274 sal_Int32 nTokenCnt = comphelper::string::getTokenCount(rStringList, '\n');
275 for( sal_Int32 nToken = 0, nStringIx = 0; nToken < (sal_Int32) nTokenCnt; ++nToken )
277 OUString aToken( rStringList.getToken( 0, '\n', nStringIx ) );
278 ScGlobal::AddQuotes( aToken, '"' );
279 rFmlaStr = ScGlobal::addToken(rFmlaStr, aToken, cFmlaSep);
281 if( rFmlaStr.isEmpty() )
282 rFmlaStr = "\"\"";
285 /** Converts formula with strings separated by semicolons to line feed separated string.
286 @descr Keeps all empty strings. Ignores all empty tokens (multiple semicolons).
287 Example: "abc";;;"def";"";"ghi" -> abc\ndef\n\nghi.
288 @param rStringList (out-param) The converted line feed separated string list.
289 @return true = Conversion successful. */
290 bool lclGetStringListFromFormula( OUString& rStringList, const OUString& rFmlaStr, sal_Unicode cFmlaSep )
292 OUString aQuotes( "\"\"" );
293 sal_Int32 nTokenCnt = ScStringUtil::GetQuotedTokenCount(rFmlaStr, aQuotes, cFmlaSep );
295 rStringList.clear();
296 bool bIsStringList = (nTokenCnt > 0);
297 bool bTokenAdded = false;
299 for( sal_Int32 nToken = 0, nStringIx = 0; bIsStringList && (nToken < nTokenCnt); ++nToken )
301 OUString aToken( ScStringUtil::GetQuotedToken(rFmlaStr, 0, aQuotes, cFmlaSep, nStringIx ) );
302 aToken = comphelper::string::strip(aToken, ' ');
303 if( !aToken.isEmpty() ) // ignore empty tokens, i.e. "a";;"b"
305 bIsStringList = ScGlobal::IsQuoted( aToken, '"' );
306 if( bIsStringList )
308 ScGlobal::EraseQuotes( aToken, '"' );
309 rStringList = ScGlobal::addToken(rStringList, aToken, '\n', 1, bTokenAdded);
310 bTokenAdded = true;
315 return bIsStringList;
318 } // namespace
320 ScTPValidationValue::ScTPValidationValue( vcl::Window* pParent, const SfxItemSet& rArgSet )
321 : SfxTabPage( pParent, "ValidationCriteriaPage",
322 "modules/scalc/ui/validationcriteriapage.ui", &rArgSet)
323 , maStrMin(ScResId(SCSTR_VALID_MINIMUM))
324 , maStrMax(ScResId(SCSTR_VALID_MAXIMUM))
325 , maStrValue(ScResId(SCSTR_VALID_VALUE))
326 , maStrRange(ScResId(SCSTR_VALID_RANGE))
327 , maStrList(ScResId(SCSTR_VALID_LIST))
328 , m_pRefEdit(nullptr)
330 get(m_pLbAllow, "allow");
331 get(m_pCbAllow, "allowempty");
332 get(m_pCbShow, "showlist");
333 get(m_pCbSort, "sortascend");
334 get(m_pFtValue, "valueft");
335 get(m_pLbValue, "data");
336 get(m_pFtMin, "minft");
337 get(m_pMinGrid, "mingrid");
338 get(m_pEdMin, "min");
339 m_pEdMin->SetReferences(nullptr, m_pFtMin);
340 get(m_pEdList, "minlist");
341 Size aSize(LogicToPixel(Size(174, 105), MAP_APPFONT));
342 m_pEdList->set_width_request(aSize.Width());
343 m_pEdList->set_height_request(aSize.Height());
344 get(m_pFtMax, "maxft");
345 get(m_pEdMax, "max");
346 m_pEdMax->SetReferences(nullptr, m_pFtMax);
347 get(m_pFtHint, "hintft");
348 get(m_pBtnRef, "validref");
349 m_pBtnRef->SetParentPage(this);
350 get(m_pRefGrid, "refgrid");
352 //lock in the max size initial config
353 aSize = get_preferred_size();
354 set_width_request(aSize.Width());
355 set_height_request(aSize.Height());
357 Init();
359 // list separator in formulas
360 OUString aListSep = ::ScCompiler::GetNativeSymbol( ocSep );
361 OSL_ENSURE( aListSep.getLength() == 1, "ScTPValidationValue::ScTPValidationValue - list separator error" );
362 mcFmlaSep = aListSep.getLength() ? aListSep[0] : ';';
363 m_pBtnRef->Hide(); // cell range picker
366 ScTPValidationValue::~ScTPValidationValue()
368 disposeOnce();
371 void ScTPValidationValue::dispose()
373 m_pLbAllow.clear();
374 m_pCbAllow.clear();
375 m_pCbShow.clear();
376 m_pCbSort.clear();
377 m_pFtValue.clear();
378 m_pLbValue.clear();
379 m_pFtMin.clear();
380 m_pMinGrid.clear();
381 m_pEdMin.clear();
382 m_pEdList.clear();
383 m_pFtMax.clear();
384 m_pEdMax.clear();
385 m_pFtHint.clear();
386 m_pRefEdit.clear();
387 m_pBtnRef.clear();
388 m_pRefGrid.clear();
389 SfxTabPage::dispose();
393 void ScTPValidationValue::Init()
395 m_pLbAllow->SetSelectHdl( LINK( this, ScTPValidationValue, SelectHdl ) );
396 m_pLbValue->SetSelectHdl( LINK( this, ScTPValidationValue, SelectHdl ) );
397 m_pCbShow->SetClickHdl( LINK( this, ScTPValidationValue, CheckHdl ) );
399 // cell range picker
400 m_pEdMin->SetGetFocusHdl( LINK( this, ScTPValidationValue, EditSetFocusHdl ) );
401 m_pEdMin->SetLoseFocusHdl( LINK( this, ScTPValidationValue, KillFocusHdl ) );
402 m_pEdMax->SetGetFocusHdl( LINK( this, ScTPValidationValue, EditSetFocusHdl ) );
403 m_pBtnRef->SetLoseFocusHdl( LINK( this, ScTPValidationValue, KillFocusHdl ) );
404 m_pEdMax->SetLoseFocusHdl( LINK( this, ScTPValidationValue, KillFocusHdl ) );
406 m_pLbAllow->SelectEntryPos( SC_VALIDDLG_ALLOW_ANY );
407 m_pLbValue->SelectEntryPos( SC_VALIDDLG_DATA_EQUAL );
409 SelectHdl( *m_pLbAllow.get() );
410 CheckHdl( nullptr );
413 VclPtr<SfxTabPage> ScTPValidationValue::Create( vcl::Window* pParent, const SfxItemSet* rArgSet )
415 return VclPtr<ScTPValidationValue>::Create( pParent, *rArgSet );
418 void ScTPValidationValue::Reset( const SfxItemSet* rArgSet )
420 const SfxPoolItem* pItem;
422 sal_uInt16 nLbPos = SC_VALIDDLG_ALLOW_ANY;
423 if( rArgSet->GetItemState( FID_VALID_MODE, true, &pItem ) == SfxItemState::SET )
424 nLbPos = lclGetPosFromValMode( static_cast< ScValidationMode >(
425 static_cast< const SfxAllEnumItem* >( pItem )->GetValue() ) );
426 m_pLbAllow->SelectEntryPos( nLbPos );
428 nLbPos = SC_VALIDDLG_DATA_EQUAL;
429 if( rArgSet->GetItemState( FID_VALID_CONDMODE, true, &pItem ) == SfxItemState::SET )
430 nLbPos = lclGetPosFromCondMode( static_cast< ScConditionMode >(
431 static_cast< const SfxAllEnumItem* >( pItem )->GetValue() ) );
432 m_pLbValue->SelectEntryPos( nLbPos );
434 // *** check boxes ***
435 bool bCheck = true;
436 if( rArgSet->GetItemState( FID_VALID_BLANK, true, &pItem ) == SfxItemState::SET )
437 bCheck = static_cast< const SfxBoolItem* >( pItem )->GetValue();
438 m_pCbAllow->Check( bCheck );
440 sal_Int32 nListType = ValidListType::UNSORTED;
441 if( rArgSet->GetItemState( FID_VALID_LISTTYPE, true, &pItem ) == SfxItemState::SET )
442 nListType = static_cast< const SfxInt16Item* >( pItem )->GetValue();
443 m_pCbShow->Check( nListType != ValidListType::INVISIBLE );
444 m_pCbSort->Check( nListType == ValidListType::SORTEDASCENDING );
446 // *** formulas ***
447 OUString aFmlaStr;
448 if ( rArgSet->GetItemState( FID_VALID_VALUE1, true, &pItem ) == SfxItemState::SET )
449 aFmlaStr = static_cast< const SfxStringItem* >( pItem )->GetValue();
450 SetFirstFormula( aFmlaStr );
452 aFmlaStr.clear();
453 if ( rArgSet->GetItemState( FID_VALID_VALUE2, true, &pItem ) == SfxItemState::SET )
454 aFmlaStr = static_cast< const SfxStringItem* >( pItem )->GetValue();
455 SetSecondFormula( aFmlaStr );
457 SelectHdl( *m_pLbAllow.get() );
458 CheckHdl( nullptr );
461 bool ScTPValidationValue::FillItemSet( SfxItemSet* rArgSet )
463 sal_Int16 nListType = m_pCbShow->IsChecked() ?
464 (m_pCbSort->IsChecked() ? ValidListType::SORTEDASCENDING : ValidListType::UNSORTED) :
465 ValidListType::INVISIBLE;
467 rArgSet->Put( SfxAllEnumItem( FID_VALID_MODE, sal::static_int_cast<sal_uInt16>(
468 lclGetValModeFromPos( m_pLbAllow->GetSelectEntryPos() ) ) ) );
469 rArgSet->Put( SfxAllEnumItem( FID_VALID_CONDMODE, sal::static_int_cast<sal_uInt16>(
470 lclGetCondModeFromPos( m_pLbValue->GetSelectEntryPos() ) ) ) );
471 rArgSet->Put( SfxStringItem( FID_VALID_VALUE1, GetFirstFormula() ) );
472 rArgSet->Put( SfxStringItem( FID_VALID_VALUE2, GetSecondFormula() ) );
473 rArgSet->Put( SfxBoolItem( FID_VALID_BLANK, m_pCbAllow->IsChecked() ) );
474 rArgSet->Put( SfxInt16Item( FID_VALID_LISTTYPE, nListType ) );
475 return true;
478 OUString ScTPValidationValue::GetFirstFormula() const
480 OUString aFmlaStr;
481 if( m_pLbAllow->GetSelectEntryPos() == SC_VALIDDLG_ALLOW_LIST )
482 lclGetFormulaFromStringList( aFmlaStr, m_pEdList->GetText(), mcFmlaSep );
483 else
484 aFmlaStr = m_pEdMin->GetText();
485 return aFmlaStr;
488 OUString ScTPValidationValue::GetSecondFormula() const
490 return m_pEdMax->GetText();
493 void ScTPValidationValue::SetFirstFormula( const OUString& rFmlaStr )
495 // try if formula is a string list, validation mode must already be set
496 OUString aStringList;
497 if( (m_pLbAllow->GetSelectEntryPos() == SC_VALIDDLG_ALLOW_RANGE) &&
498 lclGetStringListFromFormula( aStringList, rFmlaStr, mcFmlaSep ) )
500 m_pEdList->SetText( aStringList );
501 m_pEdMin->SetText( EMPTY_OUSTRING );
502 // change validation mode to string list
503 m_pLbAllow->SelectEntryPos( SC_VALIDDLG_ALLOW_LIST );
505 else
507 m_pEdMin->SetText( rFmlaStr );
508 m_pEdList->SetText( EMPTY_OUSTRING );
512 void ScTPValidationValue::SetSecondFormula( const OUString& rFmlaStr )
514 m_pEdMax->SetText( rFmlaStr );
517 ScValidationDlg * ScTPValidationValue::GetValidationDlg()
519 if( vcl::Window *pParent = GetParent() )
521 if ( dynamic_cast<ScValidationDlg*>( pParent ) )
522 return static_cast< ScValidationDlg * >( pParent );
523 }while ( nullptr != ( pParent = pParent->GetParent() ) );
524 return nullptr;
527 void ScTPValidationValue::SetupRefDlg()
529 if( ScValidationDlg *pValidationDlg = GetValidationDlg() )
531 if( pValidationDlg->SetupRefDlg() )
533 pValidationDlg->SetHandler( this );
534 pValidationDlg->SetSetRefHdl( static_cast<ScRefHandlerHelper::PFUNCSETREFHDLTYPE>( &ScTPValidationValue::SetReferenceHdl ) );
535 pValidationDlg->SetSetActHdl( static_cast<ScRefHandlerHelper::PCOMMONHDLTYPE>( &ScTPValidationValue::SetActiveHdl ) );
536 pValidationDlg->SetRefInputStartPreHdl( static_cast<ScRefHandlerHelper::PINPUTSTARTDLTYPE>( &ScTPValidationValue::RefInputStartPreHdl ) );
537 pValidationDlg->SetRefInputDonePostHdl( static_cast<ScRefHandlerHelper::PCOMMONHDLTYPE>( &ScTPValidationValue::RefInputDonePostHdl ) );
539 vcl::Window *pLabel = nullptr;
541 if ( m_pEdMax->IsVisible() )
543 m_pRefEdit = m_pEdMax;
544 pLabel = m_pFtMax;
546 else if ( m_pEdMin->IsVisible() )
548 m_pRefEdit = m_pEdMin;
549 pLabel = m_pFtMin;
552 if( m_pRefEdit && !m_pRefEdit->HasFocus() )
553 m_pRefEdit->GrabFocus();
555 if( m_pRefEdit )
556 m_pRefEdit->SetReferences( pValidationDlg, pLabel );
558 m_pBtnRef->SetReferences( pValidationDlg, m_pRefEdit );
563 void ScTPValidationValue::RemoveRefDlg()
565 if( ScValidationDlg *pValidationDlg = GetValidationDlg() )
567 if( pValidationDlg->RemoveRefDlg() )
569 pValidationDlg->SetHandler( nullptr );
570 pValidationDlg->SetSetRefHdl( nullptr );
571 pValidationDlg->SetSetActHdl( nullptr );
572 pValidationDlg->SetRefInputStartPreHdl( nullptr );
573 pValidationDlg->SetRefInputDonePostHdl( nullptr );
575 if( m_pRefEdit )
576 m_pRefEdit->SetReferences( nullptr, nullptr );
577 m_pRefEdit = nullptr;
579 m_pBtnRef->SetReferences( nullptr, nullptr );
584 IMPL_LINK_NOARG_TYPED(ScTPValidationValue, EditSetFocusHdl, Control&, void)
586 const sal_Int32 nPos = m_pLbAllow->GetSelectEntryPos();
588 if ( nPos == SC_VALIDDLG_ALLOW_RANGE )
590 SetupRefDlg();
594 IMPL_LINK_TYPED( ScTPValidationValue, KillFocusHdl, Control&, rControl, void )
596 vcl::Window* pWnd = static_cast<vcl::Window*>(&rControl);
597 if( pWnd == m_pRefEdit || pWnd == m_pBtnRef )
598 if( ScValidationDlg *pValidationDlg = GetValidationDlg() )
599 if ( (pValidationDlg->IsActive() || pValidationDlg->IsChildFocus() ) && !pValidationDlg->IsRefInputting() )
600 if( ( !m_pRefEdit || !m_pRefEdit->HasFocus()) && !m_pBtnRef->HasFocus() )
602 RemoveRefDlg();
606 IMPL_LINK_NOARG_TYPED(ScTPValidationValue, SelectHdl, ListBox&, void)
608 const sal_Int32 nLbPos = m_pLbAllow->GetSelectEntryPos();
609 bool bEnable = (nLbPos != SC_VALIDDLG_ALLOW_ANY);
610 bool bRange = (nLbPos == SC_VALIDDLG_ALLOW_RANGE);
611 bool bList = (nLbPos == SC_VALIDDLG_ALLOW_LIST);
613 m_pCbAllow->Enable( bEnable ); // Empty cell
614 m_pFtValue->Enable( bEnable );
615 m_pLbValue->Enable( bEnable );
616 m_pFtMin->Enable( bEnable );
617 m_pEdMin->Enable( bEnable );
618 m_pEdList->Enable( bEnable );
619 m_pFtMax->Enable( bEnable );
620 m_pEdMax->Enable( bEnable );
622 bool bShowMax = false;
623 if( bRange )
624 m_pFtMin->SetText( maStrRange );
625 else if( bList )
626 m_pFtMin->SetText( maStrList );
627 else
629 switch( m_pLbValue->GetSelectEntryPos() )
631 case SC_VALIDDLG_DATA_EQUAL:
632 case SC_VALIDDLG_DATA_NOTEQUAL: m_pFtMin->SetText( maStrValue ); break;
634 case SC_VALIDDLG_DATA_LESS:
635 case SC_VALIDDLG_DATA_EQLESS: m_pFtMin->SetText( maStrMax ); break;
637 case SC_VALIDDLG_DATA_VALIDRANGE:
638 case SC_VALIDDLG_DATA_INVALIDRANGE: bShowMax = true;
639 SAL_FALLTHROUGH;
640 case SC_VALIDDLG_DATA_GREATER:
641 case SC_VALIDDLG_DATA_EQGREATER: m_pFtMin->SetText( maStrMin ); break;
643 default:
644 OSL_FAIL( "ScTPValidationValue::SelectHdl - unknown condition mode" );
648 m_pCbShow->Show( bRange || bList );
649 m_pCbSort->Show( bRange || bList );
650 m_pFtValue->Show( !bRange && !bList );
651 m_pLbValue->Show( !bRange && !bList );
652 m_pEdMin->Show( !bList );
653 m_pEdList->Show( bList );
654 m_pMinGrid->set_vexpand( bList );
655 WinBits nBits = m_pFtMin->GetStyle();
656 nBits &= ~(WB_TOP | WB_VCENTER | WB_BOTTOM);
657 if (bList)
658 nBits |= WB_TOP;
659 else
660 nBits |= WB_VCENTER;
661 m_pFtMin->SetStyle( nBits );
662 m_pFtMax->Show( bShowMax );
663 m_pEdMax->Show( bShowMax );
664 m_pFtHint->Show( bRange );
665 m_pBtnRef->Show( bRange ); // cell range picker
668 IMPL_LINK_NOARG_TYPED(ScTPValidationValue, CheckHdl, Button*, void)
670 m_pCbSort->Enable( m_pCbShow->IsChecked() );
673 // Input Help Page
675 ScTPValidationHelp::ScTPValidationHelp( vcl::Window* pParent,
676 const SfxItemSet& rArgSet )
678 : SfxTabPage ( pParent,
679 "ValidationHelpTabPage" , "modules/scalc/ui/validationhelptabpage.ui" ,
680 &rArgSet )
682 get(pTsbHelp,"tsbhelp");
683 get(pEdtTitle,"title");
684 get(pEdInputHelp,"inputhelp");
685 pEdInputHelp->set_height_request(pEdInputHelp->GetTextHeight() * 12);
686 pEdInputHelp->set_width_request(pEdInputHelp->approximate_char_width() * 50);
687 Init();
690 ScTPValidationHelp::~ScTPValidationHelp()
692 disposeOnce();
695 void ScTPValidationHelp::dispose()
697 pTsbHelp.clear();
698 pEdtTitle.clear();
699 pEdInputHelp.clear();
700 SfxTabPage::dispose();
703 void ScTPValidationHelp::Init()
705 pTsbHelp->EnableTriState( false );
708 VclPtr<SfxTabPage> ScTPValidationHelp::Create( vcl::Window* pParent,
709 const SfxItemSet* rArgSet )
711 return VclPtr<ScTPValidationHelp>::Create( pParent, *rArgSet );
714 void ScTPValidationHelp::Reset( const SfxItemSet* rArgSet )
716 const SfxPoolItem* pItem;
718 if ( rArgSet->GetItemState( FID_VALID_SHOWHELP, true, &pItem ) == SfxItemState::SET )
719 pTsbHelp->SetState( static_cast<const SfxBoolItem*>(pItem)->GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
720 else
721 pTsbHelp->SetState( TRISTATE_FALSE );
723 if ( rArgSet->GetItemState( FID_VALID_HELPTITLE, true, &pItem ) == SfxItemState::SET )
724 pEdtTitle->SetText( static_cast<const SfxStringItem*>(pItem)->GetValue() );
725 else
726 pEdtTitle->SetText( EMPTY_OUSTRING );
728 if ( rArgSet->GetItemState( FID_VALID_HELPTEXT, true, &pItem ) == SfxItemState::SET )
729 pEdInputHelp->SetText( static_cast<const SfxStringItem*>(pItem)->GetValue() );
730 else
731 pEdInputHelp->SetText( EMPTY_OUSTRING );
734 bool ScTPValidationHelp::FillItemSet( SfxItemSet* rArgSet )
736 rArgSet->Put( SfxBoolItem( FID_VALID_SHOWHELP, pTsbHelp->GetState() == TRISTATE_TRUE ) );
737 rArgSet->Put( SfxStringItem( FID_VALID_HELPTITLE, pEdtTitle->GetText() ) );
738 rArgSet->Put( SfxStringItem( FID_VALID_HELPTEXT, pEdInputHelp->GetText() ) );
740 return true;
743 // Error Alert Page
745 ScTPValidationError::ScTPValidationError( vcl::Window* pParent,
746 const SfxItemSet& rArgSet )
748 : SfxTabPage ( pParent,
749 "ErrorAlertTabPage" , "modules/scalc/ui/erroralerttabpage.ui" ,
750 &rArgSet )
752 get(m_pTsbShow,"tsbshow");
753 get(m_pLbAction,"actionCB");
754 get(m_pBtnSearch,"browseBtn");
755 get(m_pEdtTitle,"title");
756 get(m_pFtError,"errormsg_label");
757 get(m_pEdError,"errorMsg");
758 m_pEdError->set_height_request(m_pEdError->GetTextHeight() * 12);
759 m_pEdError->set_width_request(m_pEdError->approximate_char_width() * 50);
760 Init();
763 ScTPValidationError::~ScTPValidationError()
765 disposeOnce();
768 void ScTPValidationError::dispose()
770 m_pTsbShow.clear();
771 m_pLbAction.clear();
772 m_pBtnSearch.clear();
773 m_pEdtTitle.clear();
774 m_pFtError.clear();
775 m_pEdError.clear();
776 SfxTabPage::dispose();
779 void ScTPValidationError::Init()
781 m_pLbAction->SetSelectHdl( LINK( this, ScTPValidationError, SelectActionHdl ) );
782 m_pBtnSearch->SetClickHdl( LINK( this, ScTPValidationError, ClickSearchHdl ) );
784 m_pLbAction->SelectEntryPos( 0 );
785 m_pTsbShow->EnableTriState( false );
787 SelectActionHdl( *m_pLbAction.get() );
790 VclPtr<SfxTabPage> ScTPValidationError::Create( vcl::Window* pParent,
791 const SfxItemSet* rArgSet )
793 return VclPtr<ScTPValidationError>::Create( pParent, *rArgSet );
796 void ScTPValidationError::Reset( const SfxItemSet* rArgSet )
798 const SfxPoolItem* pItem;
800 if ( rArgSet->GetItemState( FID_VALID_SHOWERR, true, &pItem ) == SfxItemState::SET )
801 m_pTsbShow->SetState( static_cast<const SfxBoolItem*>(pItem)->GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
802 else
803 m_pTsbShow->SetState( TRISTATE_TRUE ); // check by default
805 if ( rArgSet->GetItemState( FID_VALID_ERRSTYLE, true, &pItem ) == SfxItemState::SET )
806 m_pLbAction->SelectEntryPos( static_cast<const SfxAllEnumItem*>(pItem)->GetValue() );
807 else
808 m_pLbAction->SelectEntryPos( 0 );
810 if ( rArgSet->GetItemState( FID_VALID_ERRTITLE, true, &pItem ) == SfxItemState::SET )
811 m_pEdtTitle->SetText( static_cast<const SfxStringItem*>(pItem)->GetValue() );
812 else
813 m_pEdtTitle->SetText( EMPTY_OUSTRING );
815 if ( rArgSet->GetItemState( FID_VALID_ERRTEXT, true, &pItem ) == SfxItemState::SET )
816 m_pEdError->SetText( static_cast<const SfxStringItem*>(pItem)->GetValue() );
817 else
818 m_pEdError->SetText( EMPTY_OUSTRING );
820 SelectActionHdl( *m_pLbAction.get() );
823 bool ScTPValidationError::FillItemSet( SfxItemSet* rArgSet )
825 rArgSet->Put( SfxBoolItem( FID_VALID_SHOWERR, m_pTsbShow->GetState() == TRISTATE_TRUE ) );
826 rArgSet->Put( SfxAllEnumItem( FID_VALID_ERRSTYLE, m_pLbAction->GetSelectEntryPos() ) );
827 rArgSet->Put( SfxStringItem( FID_VALID_ERRTITLE, m_pEdtTitle->GetText() ) );
828 rArgSet->Put( SfxStringItem( FID_VALID_ERRTEXT, m_pEdError->GetText() ) );
830 return true;
833 IMPL_LINK_NOARG_TYPED(ScTPValidationError, SelectActionHdl, ListBox&, void)
835 ScValidErrorStyle eStyle = (ScValidErrorStyle) m_pLbAction->GetSelectEntryPos();
836 bool bMacro = ( eStyle == SC_VALERR_MACRO );
838 m_pBtnSearch->Enable( bMacro );
839 m_pFtError->Enable( !bMacro );
840 m_pEdError->Enable( !bMacro );
843 IMPL_LINK_NOARG_TYPED(ScTPValidationError, ClickSearchHdl, Button*, void)
845 // Use static SfxApplication method to bring up selector dialog for
846 // choosing a script
847 OUString aScriptURL = SfxApplication::ChooseScript();
849 if ( aScriptURL != nullptr && !aScriptURL.isEmpty() )
851 m_pEdtTitle->SetText( aScriptURL );
855 bool ScValidationDlg::EnterRefStatus()
857 ScTabViewShell *pTabViewShell = GetTabViewShell();
859 if( !pTabViewShell ) return false;
861 sal_uInt16 nId = SLOTID;
862 SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
863 SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
865 if ( pWnd && pWnd->GetWindow()!= this ) pWnd = nullptr;
867 SC_MOD()->SetRefDialog( nId, pWnd == nullptr );
869 return true;
872 bool ScValidationDlg::LeaveRefStatus()
874 ScTabViewShell *pTabViewShell = GetTabViewShell();
876 if( !pTabViewShell ) return false;
878 sal_uInt16 nId = SLOTID;
879 SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
880 if ( pViewFrm->GetChildWindow( nId ) )
882 DoClose( nId );
884 return true;
887 bool ScValidationDlg::SetupRefDlg()
889 if ( m_bOwnRefHdlr ) return false;
890 if( EnterRefMode() )
892 SetModal( false );
893 return m_bOwnRefHdlr = true && EnterRefStatus();
896 return false;
899 bool ScValidationDlg::RemoveRefDlg( bool bRestoreModal /* = true */ )
901 bool bVisLock = false;
902 bool bFreeWindowLock = false;
904 ScTabViewShell *pTabVwSh = GetTabViewShell();
906 if( !pTabVwSh ) return false;
908 if ( SfxChildWindow* pWnd = pTabVwSh->GetViewFrame()->GetChildWindow( SID_VALIDITY_REFERENCE ) )
910 bVisLock = static_cast<ScValidityRefChildWin*>(pWnd)->LockVisible( true );
911 bFreeWindowLock = static_cast<ScValidityRefChildWin*>(pWnd)->LockFreeWindow( true );
914 if ( !m_bOwnRefHdlr ) return false;
915 if( LeaveRefStatus() && LeaveRefMode() )
917 m_bOwnRefHdlr = false;
919 if( bRestoreModal )
920 SetModal( true );
923 if ( SfxChildWindow* pWnd = pTabVwSh->GetViewFrame()->GetChildWindow( SID_VALIDITY_REFERENCE ) )
925 static_cast<ScValidityRefChildWin*>(pWnd)->LockVisible( bVisLock );
926 static_cast<ScValidityRefChildWin*>(pWnd)->LockFreeWindow( bFreeWindowLock );
929 return true;
932 VCL_BUILDER_DECL_FACTORY(ScRefButtonEx)
934 (void)rMap;
935 rRet = VclPtr<ScTPValidationValue::ScRefButtonEx>::Create(pParent, 0);
938 void ScTPValidationValue::ScRefButtonEx::Click()
940 if( ScTPValidationValue *pParent = GetParentPage() )
941 pParent->OnClick( this );
943 formula::RefButton::Click();
946 void ScTPValidationValue::OnClick( Button *pBtn )
948 if( pBtn == m_pBtnRef )
949 SetupRefDlg();
952 bool ScValidationDlg::IsChildFocus()
954 if ( const vcl::Window *pWin = Application::GetFocusWindow() )
955 while( nullptr != ( pWin = pWin->GetParent() ) )
956 if( pWin == this )
957 return true;
959 return false;
962 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */