blob: a062dc45a1a336205718c509fce67f9af4e77e83 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
//----------------------------------------------------------------------------
#include "rangelst.hxx"
#include "scitems.hxx"
#include <sfx2/dispatch.hxx>
#include <svl/zforlist.hxx>
#include <vcl/msgbox.hxx>
#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 ( sal_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);
}
//----------------------------------------------------------------------------
__EXPORT ScSolverDlg::~ScSolverDlg()
{
}
//----------------------------------------------------------------------------
void __EXPORT 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 __EXPORT ScSolverDlg::Close()
{
return DoClose( ScSolverDlgWrapper::GetChildWindowId() );
}
//----------------------------------------------------------------------------
void ScSolverDlg::SetActive()
{
if ( bDlgLostFocus )
{
bDlgLostFocus = sal_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 __EXPORT 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( sal_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( ScSolverDlg, LoseFocusHdl, Control*, EMPTYARG )
{
bDlgLostFocus = !IsActive();
return 0;
}