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