1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 28 29 //---------------------------------------------------------------------------- 30 31 #include "rangelst.hxx" 32 #include "scitems.hxx" 33 #include <sfx2/dispatch.hxx> 34 #include <svl/zforlist.hxx> 35 #include <vcl/msgbox.hxx> 36 37 #include "uiitems.hxx" 38 #include "reffact.hxx" 39 #include "document.hxx" 40 #include "scresid.hxx" 41 #include "solvrdlg.hrc" 42 43 #define _SOLVRDLG_CXX 44 #include "solvrdlg.hxx" 45 #undef _SOLVERDLG_CXX 46 47 48 #define ERRORBOX(s) ErrorBox( this, WinBits( WB_OK | WB_DEF_OK), s ).Execute() 49 50 51 //============================================================================ 52 // class ScSolverDlg 53 //---------------------------------------------------------------------------- 54 55 ScSolverDlg::ScSolverDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent, 56 ScDocument* pDocument, 57 ScAddress aCursorPos ) 58 59 : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_SOLVER ), 60 // 61 aFlVariables ( this, ScResId( FL_VARIABLES ) ), 62 aFtFormulaCell ( this, ScResId( FT_FORMULACELL ) ), 63 aEdFormulaCell ( this, this, ScResId( ED_FORMULACELL ) ), 64 aRBFormulaCell ( this, ScResId( RB_FORMULACELL ), &aEdFormulaCell, this ), 65 aFtTargetVal ( this, ScResId( FT_TARGETVAL ) ), 66 aEdTargetVal ( this, ScResId( ED_TARGETVAL ) ), 67 aFtVariableCell ( this, ScResId( FT_VARCELL ) ), 68 aEdVariableCell ( this, this, ScResId( ED_VARCELL ) ), 69 aRBVariableCell ( this, ScResId( RB_VARCELL ), &aEdVariableCell, this ), 70 aBtnOk ( this, ScResId( BTN_OK ) ), 71 aBtnCancel ( this, ScResId( BTN_CANCEL ) ), 72 aBtnHelp ( this, ScResId( BTN_HELP ) ), 73 // 74 theFormulaCell ( aCursorPos ), 75 theVariableCell ( aCursorPos ), 76 pDoc ( pDocument ), 77 nCurTab ( aCursorPos.Tab() ), 78 pEdActive ( NULL ), 79 bDlgLostFocus ( sal_False ), 80 errMsgInvalidVar ( ScResId( STR_INVALIDVAR ) ), 81 errMsgInvalidForm ( ScResId( STR_INVALIDFORM ) ), 82 errMsgNoFormula ( ScResId( STR_NOFORMULA ) ), 83 errMsgInvalidVal ( ScResId( STR_INVALIDVAL ) ) 84 { 85 Init(); 86 FreeResource(); 87 88 aRBFormulaCell.SetAccessibleRelationMemberOf(&aFlVariables); 89 aRBVariableCell.SetAccessibleRelationMemberOf(&aFlVariables); 90 } 91 92 //---------------------------------------------------------------------------- 93 94 __EXPORT ScSolverDlg::~ScSolverDlg() 95 { 96 } 97 98 //---------------------------------------------------------------------------- 99 100 void __EXPORT ScSolverDlg::Init() 101 { 102 String aStr; 103 104 aBtnOk. SetClickHdl ( LINK( this, ScSolverDlg, BtnHdl ) ); 105 aBtnCancel. SetClickHdl ( LINK( this, ScSolverDlg, BtnHdl ) ); 106 107 Link aLink = LINK( this, ScSolverDlg, GetFocusHdl ); 108 aEdFormulaCell. SetGetFocusHdl ( aLink ); 109 aRBFormulaCell. SetGetFocusHdl ( aLink ); 110 aEdVariableCell.SetGetFocusHdl ( aLink ); 111 aRBVariableCell.SetGetFocusHdl ( aLink ); 112 aEdTargetVal. SetGetFocusHdl ( aLink ); 113 114 aLink = LINK( this, ScSolverDlg, LoseFocusHdl ); 115 aEdFormulaCell. SetLoseFocusHdl ( aLink ); 116 aRBFormulaCell. SetLoseFocusHdl ( aLink ); 117 aEdVariableCell.SetLoseFocusHdl ( aLink ); 118 aRBVariableCell.SetLoseFocusHdl ( aLink ); 119 120 theFormulaCell.Format( aStr, SCA_ABS, NULL, pDoc->GetAddressConvention() ); 121 122 aEdFormulaCell.SetText( aStr ); 123 aEdFormulaCell.GrabFocus(); 124 pEdActive = &aEdFormulaCell; 125 } 126 127 //---------------------------------------------------------------------------- 128 129 sal_Bool __EXPORT ScSolverDlg::Close() 130 { 131 return DoClose( ScSolverDlgWrapper::GetChildWindowId() ); 132 } 133 134 //---------------------------------------------------------------------------- 135 136 void ScSolverDlg::SetActive() 137 { 138 if ( bDlgLostFocus ) 139 { 140 bDlgLostFocus = sal_False; 141 if( pEdActive ) 142 pEdActive->GrabFocus(); 143 } 144 else 145 { 146 GrabFocus(); 147 } 148 RefInputDone(); 149 } 150 151 //---------------------------------------------------------------------------- 152 153 void ScSolverDlg::SetReference( const ScRange& rRef, ScDocument* pDocP ) 154 { 155 if( pEdActive ) 156 { 157 if ( rRef.aStart != rRef.aEnd ) 158 RefInputStart(pEdActive); 159 160 String aStr; 161 ScAddress aAdr = rRef.aStart; 162 sal_uInt16 nFmt = ( aAdr.Tab() == nCurTab ) 163 ? SCA_ABS 164 : SCA_ABS_3D; 165 166 aAdr.Format( aStr, nFmt, pDocP, pDocP->GetAddressConvention() ); 167 pEdActive->SetRefString( aStr ); 168 169 if ( pEdActive == &aEdFormulaCell ) 170 theFormulaCell = aAdr; 171 else if ( pEdActive == &aEdVariableCell ) 172 theVariableCell = aAdr; 173 } 174 } 175 176 //---------------------------------------------------------------------------- 177 178 void ScSolverDlg::RaiseError( ScSolverErr eError ) 179 { 180 switch ( eError ) 181 { 182 case SOLVERR_NOFORMULA: 183 ERRORBOX( errMsgNoFormula ); 184 aEdFormulaCell.GrabFocus(); 185 break; 186 187 case SOLVERR_INVALID_FORMULA: 188 ERRORBOX( errMsgInvalidForm ); 189 aEdFormulaCell.GrabFocus(); 190 break; 191 192 case SOLVERR_INVALID_VARIABLE: 193 ERRORBOX( errMsgInvalidVar ); 194 aEdVariableCell.GrabFocus(); 195 break; 196 197 case SOLVERR_INVALID_TARGETVALUE: 198 ERRORBOX( errMsgInvalidVal ); 199 aEdTargetVal.GrabFocus(); 200 break; 201 } 202 } 203 204 //---------------------------------------------------------------------------- 205 206 sal_Bool ScSolverDlg::IsRefInputMode() const 207 { 208 return pEdActive != NULL; 209 } 210 211 //---------------------------------------------------------------------------- 212 213 sal_Bool __EXPORT ScSolverDlg::CheckTargetValue( String& rStrVal ) 214 { 215 sal_uInt32 n1 = 0; 216 double n2; 217 218 return pDoc->GetFormatTable()->IsNumberFormat( rStrVal, n1, n2 ); 219 } 220 221 //---------------------------------------------------------------------------- 222 // Handler: 223 224 IMPL_LINK( ScSolverDlg, BtnHdl, PushButton*, pBtn ) 225 { 226 if ( pBtn == &aBtnOk ) 227 { 228 theTargetValStr = aEdTargetVal.GetText(); 229 230 // Zu ueberpruefen: 231 // 1. enthalten die Strings korrekte Tabellenkoordinaten/def.Namen? 232 // 2. verweist die Formel-Koordinate wirklich auf eine Formelzelle? 233 // 3. wurde ein korrekter Zielwert eingegeben 234 235 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); 236 sal_uInt16 nRes1 = theFormulaCell .Parse( aEdFormulaCell.GetText(), pDoc, eConv ); 237 sal_uInt16 nRes2 = theVariableCell.Parse( aEdVariableCell.GetText(), pDoc, eConv ); 238 239 if ( SCA_VALID == ( nRes1 & SCA_VALID ) ) 240 { 241 if ( SCA_VALID == ( nRes2 & SCA_VALID ) ) 242 { 243 if ( CheckTargetValue( theTargetValStr ) ) 244 { 245 CellType eType; 246 pDoc->GetCellType( theFormulaCell.Col(), 247 theFormulaCell.Row(), 248 theFormulaCell.Tab(), 249 eType ); 250 251 if ( CELLTYPE_FORMULA == eType ) 252 { 253 ScSolveParam aOutParam( theFormulaCell, 254 theVariableCell, 255 theTargetValStr ); 256 ScSolveItem aOutItem( SCITEM_SOLVEDATA, &aOutParam ); 257 258 SetDispatcherLock( sal_False ); 259 260 SwitchToDocument(); 261 GetBindings().GetDispatcher()->Execute( SID_SOLVE, 262 SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, 263 &aOutItem, 0L, 0L ); 264 Close(); 265 } 266 else RaiseError( SOLVERR_NOFORMULA ); 267 } 268 else RaiseError( SOLVERR_INVALID_TARGETVALUE ); 269 } 270 else RaiseError( SOLVERR_INVALID_VARIABLE ); 271 } 272 else RaiseError( SOLVERR_INVALID_FORMULA ); 273 } 274 else if ( pBtn == &aBtnCancel ) 275 { 276 Close(); 277 } 278 279 return 0; 280 } 281 282 //---------------------------------------------------------------------------- 283 284 IMPL_LINK( ScSolverDlg, GetFocusHdl, Control*, pCtrl ) 285 { 286 Edit* pEdit = NULL; 287 pEdActive = NULL; 288 289 if( (pCtrl == (Control*)&aEdFormulaCell) || (pCtrl == (Control*)&aRBFormulaCell) ) 290 pEdit = pEdActive = &aEdFormulaCell; 291 else if( (pCtrl == (Control*)&aEdVariableCell) || (pCtrl == (Control*)&aRBVariableCell) ) 292 pEdit = pEdActive = &aEdVariableCell; 293 else if( pCtrl == (Control*)&aEdTargetVal ) 294 pEdit = &aEdTargetVal; 295 296 if( pEdit ) 297 pEdit->SetSelection( Selection( 0, SELECTION_MAX ) ); 298 299 return 0; 300 } 301 302 //---------------------------------------------------------------------------- 303 304 IMPL_LINK( ScSolverDlg, LoseFocusHdl, Control*, EMPTYARG ) 305 { 306 bDlgLostFocus = !IsActive(); 307 return 0; 308 } 309 310 311 312 313