/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ //---------------------------------------------------------------------------- #include "rangelst.hxx" #include "scitems.hxx" #include #include #include #include "uiitems.hxx" #include "reffact.hxx" #include "document.hxx" #include "scresid.hxx" #include "solvrdlg.hrc" #define _SOLVRDLG_CXX #include "solvrdlg.hxx" #undef _SOLVERDLG_CXX #define ERRORBOX(s) ErrorBox( this, WinBits( WB_OK | WB_DEF_OK), s ).Execute() //============================================================================ // class ScSolverDlg //---------------------------------------------------------------------------- ScSolverDlg::ScSolverDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent, ScDocument* pDocument, ScAddress aCursorPos ) : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_SOLVER ), // aFlVariables ( this, ScResId( FL_VARIABLES ) ), aFtFormulaCell ( this, ScResId( FT_FORMULACELL ) ), aEdFormulaCell ( this, this, ScResId( ED_FORMULACELL ) ), aRBFormulaCell ( this, ScResId( RB_FORMULACELL ), &aEdFormulaCell, this ), aFtTargetVal ( this, ScResId( FT_TARGETVAL ) ), aEdTargetVal ( this, ScResId( ED_TARGETVAL ) ), aFtVariableCell ( this, ScResId( FT_VARCELL ) ), aEdVariableCell ( this, this, ScResId( ED_VARCELL ) ), aRBVariableCell ( this, ScResId( RB_VARCELL ), &aEdVariableCell, this ), aBtnOk ( this, ScResId( BTN_OK ) ), aBtnCancel ( this, ScResId( BTN_CANCEL ) ), aBtnHelp ( this, ScResId( BTN_HELP ) ), // theFormulaCell ( aCursorPos ), theVariableCell ( aCursorPos ), pDoc ( pDocument ), nCurTab ( aCursorPos.Tab() ), pEdActive ( NULL ), bDlgLostFocus ( false ), errMsgInvalidVar ( ScResId( STR_INVALIDVAR ) ), errMsgInvalidForm ( ScResId( STR_INVALIDFORM ) ), errMsgNoFormula ( ScResId( STR_NOFORMULA ) ), errMsgInvalidVal ( ScResId( STR_INVALIDVAL ) ) { Init(); FreeResource(); aRBFormulaCell.SetAccessibleRelationMemberOf(&aFlVariables); aRBVariableCell.SetAccessibleRelationMemberOf(&aFlVariables); } //---------------------------------------------------------------------------- ScSolverDlg::~ScSolverDlg() { } //---------------------------------------------------------------------------- void ScSolverDlg::Init() { String aStr; aBtnOk. SetClickHdl ( LINK( this, ScSolverDlg, BtnHdl ) ); aBtnCancel. SetClickHdl ( LINK( this, ScSolverDlg, BtnHdl ) ); Link aLink = LINK( this, ScSolverDlg, GetFocusHdl ); aEdFormulaCell. SetGetFocusHdl ( aLink ); aRBFormulaCell. SetGetFocusHdl ( aLink ); aEdVariableCell.SetGetFocusHdl ( aLink ); aRBVariableCell.SetGetFocusHdl ( aLink ); aEdTargetVal. SetGetFocusHdl ( aLink ); aLink = LINK( this, ScSolverDlg, LoseFocusHdl ); aEdFormulaCell. SetLoseFocusHdl ( aLink ); aRBFormulaCell. SetLoseFocusHdl ( aLink ); aEdVariableCell.SetLoseFocusHdl ( aLink ); aRBVariableCell.SetLoseFocusHdl ( aLink ); theFormulaCell.Format( aStr, SCA_ABS, NULL, pDoc->GetAddressConvention() ); aEdFormulaCell.SetText( aStr ); aEdFormulaCell.GrabFocus(); pEdActive = &aEdFormulaCell; } //---------------------------------------------------------------------------- sal_Bool ScSolverDlg::Close() { return DoClose( ScSolverDlgWrapper::GetChildWindowId() ); } //---------------------------------------------------------------------------- void ScSolverDlg::SetActive() { if ( bDlgLostFocus ) { bDlgLostFocus = false; if( pEdActive ) pEdActive->GrabFocus(); } else { GrabFocus(); } RefInputDone(); } //---------------------------------------------------------------------------- void ScSolverDlg::SetReference( const ScRange& rRef, ScDocument* pDocP ) { if( pEdActive ) { if ( rRef.aStart != rRef.aEnd ) RefInputStart(pEdActive); String aStr; ScAddress aAdr = rRef.aStart; sal_uInt16 nFmt = ( aAdr.Tab() == nCurTab ) ? SCA_ABS : SCA_ABS_3D; aAdr.Format( aStr, nFmt, pDocP, pDocP->GetAddressConvention() ); pEdActive->SetRefString( aStr ); if ( pEdActive == &aEdFormulaCell ) theFormulaCell = aAdr; else if ( pEdActive == &aEdVariableCell ) theVariableCell = aAdr; } } //---------------------------------------------------------------------------- void ScSolverDlg::RaiseError( ScSolverErr eError ) { switch ( eError ) { case SOLVERR_NOFORMULA: ERRORBOX( errMsgNoFormula ); aEdFormulaCell.GrabFocus(); break; case SOLVERR_INVALID_FORMULA: ERRORBOX( errMsgInvalidForm ); aEdFormulaCell.GrabFocus(); break; case SOLVERR_INVALID_VARIABLE: ERRORBOX( errMsgInvalidVar ); aEdVariableCell.GrabFocus(); break; case SOLVERR_INVALID_TARGETVALUE: ERRORBOX( errMsgInvalidVal ); aEdTargetVal.GrabFocus(); break; } } //---------------------------------------------------------------------------- sal_Bool ScSolverDlg::IsRefInputMode() const { return pEdActive != NULL; } //---------------------------------------------------------------------------- sal_Bool ScSolverDlg::CheckTargetValue( String& rStrVal ) { sal_uInt32 n1 = 0; double n2; return pDoc->GetFormatTable()->IsNumberFormat( rStrVal, n1, n2 ); } //---------------------------------------------------------------------------- // Handler: IMPL_LINK( ScSolverDlg, BtnHdl, PushButton*, pBtn ) { if ( pBtn == &aBtnOk ) { theTargetValStr = aEdTargetVal.GetText(); // Zu ueberpruefen: // 1. enthalten die Strings korrekte Tabellenkoordinaten/def.Namen? // 2. verweist die Formel-Koordinate wirklich auf eine Formelzelle? // 3. wurde ein korrekter Zielwert eingegeben const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); sal_uInt16 nRes1 = theFormulaCell .Parse( aEdFormulaCell.GetText(), pDoc, eConv ); sal_uInt16 nRes2 = theVariableCell.Parse( aEdVariableCell.GetText(), pDoc, eConv ); if ( SCA_VALID == ( nRes1 & SCA_VALID ) ) { if ( SCA_VALID == ( nRes2 & SCA_VALID ) ) { if ( CheckTargetValue( theTargetValStr ) ) { CellType eType; pDoc->GetCellType( theFormulaCell.Col(), theFormulaCell.Row(), theFormulaCell.Tab(), eType ); if ( CELLTYPE_FORMULA == eType ) { ScSolveParam aOutParam( theFormulaCell, theVariableCell, theTargetValStr ); ScSolveItem aOutItem( SCITEM_SOLVEDATA, &aOutParam ); SetDispatcherLock( false ); SwitchToDocument(); GetBindings().GetDispatcher()->Execute( SID_SOLVE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aOutItem, 0L, 0L ); Close(); } else RaiseError( SOLVERR_NOFORMULA ); } else RaiseError( SOLVERR_INVALID_TARGETVALUE ); } else RaiseError( SOLVERR_INVALID_VARIABLE ); } else RaiseError( SOLVERR_INVALID_FORMULA ); } else if ( pBtn == &aBtnCancel ) { Close(); } return 0; } //---------------------------------------------------------------------------- IMPL_LINK( ScSolverDlg, GetFocusHdl, Control*, pCtrl ) { Edit* pEdit = NULL; pEdActive = NULL; if( (pCtrl == (Control*)&aEdFormulaCell) || (pCtrl == (Control*)&aRBFormulaCell) ) pEdit = pEdActive = &aEdFormulaCell; else if( (pCtrl == (Control*)&aEdVariableCell) || (pCtrl == (Control*)&aRBVariableCell) ) pEdit = pEdActive = &aEdVariableCell; else if( pCtrl == (Control*)&aEdTargetVal ) pEdit = &aEdTargetVal; if( pEdit ) pEdit->SetSelection( Selection( 0, SELECTION_MAX ) ); return 0; } //---------------------------------------------------------------------------- IMPL_LINK_NOARG(ScSolverDlg, LoseFocusHdl) { bDlgLostFocus = !IsActive(); return 0; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */