1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_sc.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir //---------------------------------------------------------------------------- 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include "rangelst.hxx" 34*cdf0e10cSrcweir #include "scitems.hxx" 35*cdf0e10cSrcweir #include <sfx2/bindings.hxx> 36*cdf0e10cSrcweir #include <sfx2/imagemgr.hxx> 37*cdf0e10cSrcweir #include <svl/zforlist.hxx> 38*cdf0e10cSrcweir #include <vcl/msgbox.hxx> 39*cdf0e10cSrcweir #include <vcl/svapp.hxx> 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #include "uiitems.hxx" 42*cdf0e10cSrcweir #include "reffact.hxx" 43*cdf0e10cSrcweir #include "docsh.hxx" 44*cdf0e10cSrcweir #include "docfunc.hxx" 45*cdf0e10cSrcweir #include "cell.hxx" 46*cdf0e10cSrcweir #include "rangeutl.hxx" 47*cdf0e10cSrcweir #include "scresid.hxx" 48*cdf0e10cSrcweir #include "convuno.hxx" 49*cdf0e10cSrcweir #include "unonames.hxx" 50*cdf0e10cSrcweir #include "solveroptions.hxx" 51*cdf0e10cSrcweir #include "solverutil.hxx" 52*cdf0e10cSrcweir #include "optsolver.hrc" 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir #include "optsolver.hxx" 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir #include <com/sun/star/sheet/Solver.hpp> 57*cdf0e10cSrcweir #include <com/sun/star/sheet/XSolverDescription.hpp> 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir using namespace com::sun::star; 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir //---------------------------------------------------------------------------- 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir ScSolverProgressDialog::ScSolverProgressDialog( Window* pParent ) 64*cdf0e10cSrcweir : ModelessDialog( pParent, ScResId( RID_SCDLG_SOLVER_PROGRESS ) ), 65*cdf0e10cSrcweir maFtProgress ( this, ScResId( FT_PROGRESS ) ), 66*cdf0e10cSrcweir maFtTime ( this, ScResId( FT_TIMELIMIT ) ), 67*cdf0e10cSrcweir maFlButtons ( this, ScResId( FL_BUTTONS ) ), 68*cdf0e10cSrcweir maBtnOk ( this, ScResId( BTN_OK ) ) 69*cdf0e10cSrcweir { 70*cdf0e10cSrcweir maBtnOk.Enable(sal_False); 71*cdf0e10cSrcweir FreeResource(); 72*cdf0e10cSrcweir } 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir ScSolverProgressDialog::~ScSolverProgressDialog() 75*cdf0e10cSrcweir { 76*cdf0e10cSrcweir } 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir void ScSolverProgressDialog::HideTimeLimit() 79*cdf0e10cSrcweir { 80*cdf0e10cSrcweir maFtTime.Hide(); 81*cdf0e10cSrcweir } 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir void ScSolverProgressDialog::SetTimeLimit( sal_Int32 nSeconds ) 84*cdf0e10cSrcweir { 85*cdf0e10cSrcweir String aOld = maFtTime.GetText(); 86*cdf0e10cSrcweir String aNew = aOld.GetToken(0,'#'); 87*cdf0e10cSrcweir aNew += String::CreateFromInt32( nSeconds ); 88*cdf0e10cSrcweir aNew += aOld.GetToken(1,'#'); 89*cdf0e10cSrcweir maFtTime.SetText( aNew ); 90*cdf0e10cSrcweir } 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir //---------------------------------------------------------------------------- 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir ScSolverNoSolutionDialog::ScSolverNoSolutionDialog( Window* pParent, const String& rErrorText ) 95*cdf0e10cSrcweir : ModalDialog( pParent, ScResId( RID_SCDLG_SOLVER_NOSOLUTION ) ), 96*cdf0e10cSrcweir maFtNoSolution ( this, ScResId( FT_NOSOLUTION ) ), 97*cdf0e10cSrcweir maFtErrorText ( this, ScResId( FT_ERRORTEXT ) ), 98*cdf0e10cSrcweir maFlButtons ( this, ScResId( FL_BUTTONS ) ), 99*cdf0e10cSrcweir maBtnOk ( this, ScResId( BTN_OK ) ) 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir maFtErrorText.SetText( rErrorText ); 102*cdf0e10cSrcweir FreeResource(); 103*cdf0e10cSrcweir } 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir ScSolverNoSolutionDialog::~ScSolverNoSolutionDialog() 106*cdf0e10cSrcweir { 107*cdf0e10cSrcweir } 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir //---------------------------------------------------------------------------- 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir ScSolverSuccessDialog::ScSolverSuccessDialog( Window* pParent, const String& rSolution ) 112*cdf0e10cSrcweir : ModalDialog( pParent, ScResId( RID_SCDLG_SOLVER_SUCCESS ) ), 113*cdf0e10cSrcweir maFtSuccess ( this, ScResId( FT_SUCCESS ) ), 114*cdf0e10cSrcweir maFtResult ( this, ScResId( FT_RESULT ) ), 115*cdf0e10cSrcweir maFtQuestion ( this, ScResId( FT_QUESTION ) ), 116*cdf0e10cSrcweir maFlButtons ( this, ScResId( FL_BUTTONS ) ), 117*cdf0e10cSrcweir maBtnOk ( this, ScResId( BTN_OK ) ), 118*cdf0e10cSrcweir maBtnCancel ( this, ScResId( BTN_CANCEL ) ) 119*cdf0e10cSrcweir { 120*cdf0e10cSrcweir String aMessage = maFtResult.GetText(); 121*cdf0e10cSrcweir aMessage.Append( (sal_Char) ' ' ); 122*cdf0e10cSrcweir aMessage.Append( rSolution ); 123*cdf0e10cSrcweir maFtResult.SetText( aMessage ); 124*cdf0e10cSrcweir FreeResource(); 125*cdf0e10cSrcweir } 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir ScSolverSuccessDialog::~ScSolverSuccessDialog() 128*cdf0e10cSrcweir { 129*cdf0e10cSrcweir } 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir //---------------------------------------------------------------------------- 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir ScCursorRefEdit::ScCursorRefEdit( ScAnyRefDlg* pParent, const ResId& rResId ) : 134*cdf0e10cSrcweir formula::RefEdit( pParent, pParent, rResId ) 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir void ScCursorRefEdit::SetCursorLinks( const Link& rUp, const Link& rDown ) 139*cdf0e10cSrcweir { 140*cdf0e10cSrcweir maCursorUpLink = rUp; 141*cdf0e10cSrcweir maCursorDownLink = rDown; 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir void ScCursorRefEdit::KeyInput( const KeyEvent& rKEvt ) 145*cdf0e10cSrcweir { 146*cdf0e10cSrcweir KeyCode aCode = rKEvt.GetKeyCode(); 147*cdf0e10cSrcweir bool bUp = (aCode.GetCode() == KEY_UP); 148*cdf0e10cSrcweir bool bDown = (aCode.GetCode() == KEY_DOWN); 149*cdf0e10cSrcweir if ( !aCode.IsShift() && !aCode.IsMod1() && !aCode.IsMod2() && ( bUp || bDown ) ) 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir if ( bUp ) 152*cdf0e10cSrcweir maCursorUpLink.Call( this ); 153*cdf0e10cSrcweir else 154*cdf0e10cSrcweir maCursorDownLink.Call( this ); 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir else 157*cdf0e10cSrcweir formula::RefEdit::KeyInput( rKEvt ); 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir //---------------------------------------------------------------------------- 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir ScOptSolverSave::ScOptSolverSave( const String& rObjective, sal_Bool bMax, sal_Bool bMin, sal_Bool bValue, 163*cdf0e10cSrcweir const String& rTarget, const String& rVariable, 164*cdf0e10cSrcweir const std::vector<ScOptConditionRow>& rConditions, 165*cdf0e10cSrcweir const String& rEngine, 166*cdf0e10cSrcweir const uno::Sequence<beans::PropertyValue>& rProperties ) : 167*cdf0e10cSrcweir maObjective( rObjective ), 168*cdf0e10cSrcweir mbMax( bMax ), 169*cdf0e10cSrcweir mbMin( bMin ), 170*cdf0e10cSrcweir mbValue( bValue ), 171*cdf0e10cSrcweir maTarget( rTarget ), 172*cdf0e10cSrcweir maVariable( rVariable ), 173*cdf0e10cSrcweir maConditions( rConditions ), 174*cdf0e10cSrcweir maEngine( rEngine ), 175*cdf0e10cSrcweir maProperties( rProperties ) 176*cdf0e10cSrcweir { 177*cdf0e10cSrcweir } 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir //============================================================================ 180*cdf0e10cSrcweir // class ScOptSolverDlg 181*cdf0e10cSrcweir //---------------------------------------------------------------------------- 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir ScOptSolverDlg::ScOptSolverDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent, 184*cdf0e10cSrcweir ScDocShell* pDocSh, ScAddress aCursorPos ) 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_OPTSOLVER ), 187*cdf0e10cSrcweir // 188*cdf0e10cSrcweir maFtObjectiveCell ( this, ScResId( FT_OBJECTIVECELL ) ), 189*cdf0e10cSrcweir maEdObjectiveCell ( this, this, ScResId( ED_OBJECTIVECELL ) ), 190*cdf0e10cSrcweir maRBObjectiveCell ( this, ScResId( IB_OBJECTIVECELL ), &maEdObjectiveCell, this ), 191*cdf0e10cSrcweir maFtDirection ( this, ScResId( FT_DIRECTION ) ), 192*cdf0e10cSrcweir maRbMax ( this, ScResId( RB_MAX ) ), 193*cdf0e10cSrcweir maRbMin ( this, ScResId( RB_MIN ) ), 194*cdf0e10cSrcweir maRbValue ( this, ScResId( RB_VALUE ) ), 195*cdf0e10cSrcweir maEdTargetValue ( this, this, ScResId( ED_TARGET ) ), 196*cdf0e10cSrcweir maRBTargetValue ( this, ScResId( IB_TARGET ), &maEdTargetValue, this ), 197*cdf0e10cSrcweir maFtVariableCells ( this, ScResId( FT_VARIABLECELLS ) ), 198*cdf0e10cSrcweir maEdVariableCells ( this, this, ScResId( ED_VARIABLECELLS ) ), 199*cdf0e10cSrcweir maRBVariableCells ( this, ScResId( IB_VARIABLECELLS ), &maEdVariableCells, this), 200*cdf0e10cSrcweir maFlConditions ( this, ScResId( FL_CONDITIONS ) ), 201*cdf0e10cSrcweir maFtCellRef ( this, ScResId( FT_CELLREF ) ), 202*cdf0e10cSrcweir maEdLeft1 ( this, ScResId( ED_LEFT1 ) ), 203*cdf0e10cSrcweir maRBLeft1 ( this, ScResId( IB_LEFT1 ), &maEdLeft1, this ), 204*cdf0e10cSrcweir maFtOperator ( this, ScResId( FT_OPERATOR ) ), 205*cdf0e10cSrcweir maLbOp1 ( this, ScResId( LB_OP1 ) ), 206*cdf0e10cSrcweir maFtConstraint ( this, ScResId( FT_CONSTRAINT ) ), 207*cdf0e10cSrcweir maEdRight1 ( this, ScResId( ED_RIGHT1 ) ), 208*cdf0e10cSrcweir maRBRight1 ( this, ScResId( IB_RIGHT1 ), &maEdRight1, this ), 209*cdf0e10cSrcweir maBtnDel1 ( this, ScResId( IB_DELETE1 ) ), 210*cdf0e10cSrcweir maEdLeft2 ( this, ScResId( ED_LEFT2 ) ), 211*cdf0e10cSrcweir maRBLeft2 ( this, ScResId( IB_LEFT2 ), &maEdLeft2, this ), 212*cdf0e10cSrcweir maLbOp2 ( this, ScResId( LB_OP2 ) ), 213*cdf0e10cSrcweir maEdRight2 ( this, ScResId( ED_RIGHT2 ) ), 214*cdf0e10cSrcweir maRBRight2 ( this, ScResId( IB_RIGHT2 ), &maEdRight2, this ), 215*cdf0e10cSrcweir maBtnDel2 ( this, ScResId( IB_DELETE2 ) ), 216*cdf0e10cSrcweir maEdLeft3 ( this, ScResId( ED_LEFT3 ) ), 217*cdf0e10cSrcweir maRBLeft3 ( this, ScResId( IB_LEFT3 ), &maEdLeft3, this ), 218*cdf0e10cSrcweir maLbOp3 ( this, ScResId( LB_OP3 ) ), 219*cdf0e10cSrcweir maEdRight3 ( this, ScResId( ED_RIGHT3 ) ), 220*cdf0e10cSrcweir maRBRight3 ( this, ScResId( IB_RIGHT3 ), &maEdRight3, this ), 221*cdf0e10cSrcweir maBtnDel3 ( this, ScResId( IB_DELETE3 ) ), 222*cdf0e10cSrcweir maEdLeft4 ( this, ScResId( ED_LEFT4 ) ), 223*cdf0e10cSrcweir maRBLeft4 ( this, ScResId( IB_LEFT4 ), &maEdLeft4, this ), 224*cdf0e10cSrcweir maLbOp4 ( this, ScResId( LB_OP4 ) ), 225*cdf0e10cSrcweir maEdRight4 ( this, ScResId( ED_RIGHT4 ) ), 226*cdf0e10cSrcweir maRBRight4 ( this, ScResId( IB_RIGHT4 ), &maEdRight4, this ), 227*cdf0e10cSrcweir maBtnDel4 ( this, ScResId( IB_DELETE4 ) ), 228*cdf0e10cSrcweir maScrollBar ( this, ScResId( SB_SCROLL ) ), 229*cdf0e10cSrcweir maFlButtons ( this, ScResId( FL_BUTTONS ) ), 230*cdf0e10cSrcweir maBtnOpt ( this, ScResId( BTN_OPTIONS ) ), 231*cdf0e10cSrcweir maBtnHelp ( this, ScResId( BTN_HELP ) ), 232*cdf0e10cSrcweir maBtnCancel ( this, ScResId( BTN_CLOSE ) ), 233*cdf0e10cSrcweir maBtnSolve ( this, ScResId( BTN_SOLVE ) ), 234*cdf0e10cSrcweir maInputError ( ScResId( STR_INVALIDINPUT ) ), 235*cdf0e10cSrcweir maConditionError ( ScResId( STR_INVALIDCONDITION ) ), 236*cdf0e10cSrcweir // 237*cdf0e10cSrcweir mpDocShell ( pDocSh ), 238*cdf0e10cSrcweir mpDoc ( pDocSh->GetDocument() ), 239*cdf0e10cSrcweir mnCurTab ( aCursorPos.Tab() ), 240*cdf0e10cSrcweir mpEdActive ( NULL ), 241*cdf0e10cSrcweir mbDlgLostFocus ( false ), 242*cdf0e10cSrcweir nScrollPos ( 0 ) 243*cdf0e10cSrcweir { 244*cdf0e10cSrcweir mpLeftEdit[0] = &maEdLeft1; 245*cdf0e10cSrcweir mpLeftButton[0] = &maRBLeft1; 246*cdf0e10cSrcweir mpRightEdit[0] = &maEdRight1; 247*cdf0e10cSrcweir mpRightButton[0] = &maRBRight1; 248*cdf0e10cSrcweir mpOperator[0] = &maLbOp1; 249*cdf0e10cSrcweir mpDelButton[0] = &maBtnDel1; 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir mpLeftEdit[1] = &maEdLeft2; 252*cdf0e10cSrcweir mpLeftButton[1] = &maRBLeft2; 253*cdf0e10cSrcweir mpRightEdit[1] = &maEdRight2; 254*cdf0e10cSrcweir mpRightButton[1] = &maRBRight2; 255*cdf0e10cSrcweir mpOperator[1] = &maLbOp2; 256*cdf0e10cSrcweir mpDelButton[1] = &maBtnDel2; 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir mpLeftEdit[2] = &maEdLeft3; 259*cdf0e10cSrcweir mpLeftButton[2] = &maRBLeft3; 260*cdf0e10cSrcweir mpRightEdit[2] = &maEdRight3; 261*cdf0e10cSrcweir mpRightButton[2] = &maRBRight3; 262*cdf0e10cSrcweir mpOperator[2] = &maLbOp3; 263*cdf0e10cSrcweir mpDelButton[2] = &maBtnDel3; 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir mpLeftEdit[3] = &maEdLeft4; 266*cdf0e10cSrcweir mpLeftButton[3] = &maRBLeft4; 267*cdf0e10cSrcweir mpRightEdit[3] = &maEdRight4; 268*cdf0e10cSrcweir mpRightButton[3] = &maRBRight4; 269*cdf0e10cSrcweir mpOperator[3] = &maLbOp4; 270*cdf0e10cSrcweir mpDelButton[3] = &maBtnDel4; 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir maRbMax.SetAccessibleRelationMemberOf(&maFtDirection); 273*cdf0e10cSrcweir maRbMin.SetAccessibleRelationMemberOf(&maFtDirection); 274*cdf0e10cSrcweir maRbValue.SetAccessibleRelationMemberOf(&maFtDirection); 275*cdf0e10cSrcweir maEdLeft2.SetAccessibleName(maFtCellRef.GetText()); 276*cdf0e10cSrcweir maLbOp2.SetAccessibleName(maFtOperator.GetText()); 277*cdf0e10cSrcweir maEdRight2.SetAccessibleName(maFtConstraint.GetText()); 278*cdf0e10cSrcweir maEdLeft3.SetAccessibleName(maFtCellRef.GetText()); 279*cdf0e10cSrcweir maLbOp3.SetAccessibleName(maFtOperator.GetText()); 280*cdf0e10cSrcweir maEdRight3.SetAccessibleName(maFtConstraint.GetText()); 281*cdf0e10cSrcweir maEdLeft4.SetAccessibleName(maFtCellRef.GetText()); 282*cdf0e10cSrcweir maLbOp4.SetAccessibleName(maFtOperator.GetText()); 283*cdf0e10cSrcweir maEdRight4.SetAccessibleName(maFtConstraint.GetText()); 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir Init( aCursorPos ); 286*cdf0e10cSrcweir FreeResource(); 287*cdf0e10cSrcweir } 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir //---------------------------------------------------------------------------- 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir ScOptSolverDlg::~ScOptSolverDlg() 292*cdf0e10cSrcweir { 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir //---------------------------------------------------------------------------- 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir void ScOptSolverDlg::Init(const ScAddress& rCursorPos) 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir // Get the "Delete Rows" commandimagelist images from sfx instead of 300*cdf0e10cSrcweir // adding a second copy to sc (see ScTbxInsertCtrl::StateChanged) 301*cdf0e10cSrcweir 302*cdf0e10cSrcweir rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); 303*cdf0e10cSrcweir aSlotURL += rtl::OUString::valueOf( sal_Int32( SID_DEL_ROWS ) ); 304*cdf0e10cSrcweir uno::Reference<frame::XFrame> xFrame = GetBindings().GetActiveFrame(); 305*cdf0e10cSrcweir Image aDelNm = ::GetImage( xFrame, aSlotURL, sal_False, sal_False ); 306*cdf0e10cSrcweir Image aDelHC = ::GetImage( xFrame, aSlotURL, sal_False, sal_True ); // high contrast 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow ) 309*cdf0e10cSrcweir { 310*cdf0e10cSrcweir mpDelButton[nRow]->SetModeImage( aDelNm, BMP_COLOR_NORMAL ); 311*cdf0e10cSrcweir mpDelButton[nRow]->SetModeImage( aDelHC, BMP_COLOR_HIGHCONTRAST ); 312*cdf0e10cSrcweir } 313*cdf0e10cSrcweir 314*cdf0e10cSrcweir maBtnOpt.SetClickHdl( LINK( this, ScOptSolverDlg, BtnHdl ) ); 315*cdf0e10cSrcweir maBtnCancel.SetClickHdl( LINK( this, ScOptSolverDlg, BtnHdl ) ); 316*cdf0e10cSrcweir maBtnSolve.SetClickHdl( LINK( this, ScOptSolverDlg, BtnHdl ) ); 317*cdf0e10cSrcweir 318*cdf0e10cSrcweir Link aLink = LINK( this, ScOptSolverDlg, GetFocusHdl ); 319*cdf0e10cSrcweir maEdObjectiveCell.SetGetFocusHdl( aLink ); 320*cdf0e10cSrcweir maRBObjectiveCell.SetGetFocusHdl( aLink ); 321*cdf0e10cSrcweir maEdTargetValue.SetGetFocusHdl( aLink ); 322*cdf0e10cSrcweir maRBTargetValue.SetGetFocusHdl( aLink ); 323*cdf0e10cSrcweir maEdVariableCells.SetGetFocusHdl( aLink ); 324*cdf0e10cSrcweir maRBVariableCells.SetGetFocusHdl( aLink ); 325*cdf0e10cSrcweir maRbValue.SetGetFocusHdl( aLink ); 326*cdf0e10cSrcweir for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow ) 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir mpLeftEdit[nRow]->SetGetFocusHdl( aLink ); 329*cdf0e10cSrcweir mpLeftButton[nRow]->SetGetFocusHdl( aLink ); 330*cdf0e10cSrcweir mpRightEdit[nRow]->SetGetFocusHdl( aLink ); 331*cdf0e10cSrcweir mpRightButton[nRow]->SetGetFocusHdl( aLink ); 332*cdf0e10cSrcweir mpOperator[nRow]->SetGetFocusHdl( aLink ); 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir aLink = LINK( this, ScOptSolverDlg, LoseFocusHdl ); 336*cdf0e10cSrcweir maEdObjectiveCell.SetLoseFocusHdl( aLink ); 337*cdf0e10cSrcweir maRBObjectiveCell.SetLoseFocusHdl( aLink ); 338*cdf0e10cSrcweir maEdTargetValue. SetLoseFocusHdl( aLink ); 339*cdf0e10cSrcweir maRBTargetValue. SetLoseFocusHdl( aLink ); 340*cdf0e10cSrcweir maEdVariableCells.SetLoseFocusHdl( aLink ); 341*cdf0e10cSrcweir maRBVariableCells.SetLoseFocusHdl( aLink ); 342*cdf0e10cSrcweir for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow ) 343*cdf0e10cSrcweir { 344*cdf0e10cSrcweir mpLeftEdit[nRow]->SetLoseFocusHdl( aLink ); 345*cdf0e10cSrcweir mpLeftButton[nRow]->SetLoseFocusHdl( aLink ); 346*cdf0e10cSrcweir mpRightEdit[nRow]->SetLoseFocusHdl( aLink ); 347*cdf0e10cSrcweir mpRightButton[nRow]->SetLoseFocusHdl( aLink ); 348*cdf0e10cSrcweir } 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir Link aCursorUp = LINK( this, ScOptSolverDlg, CursorUpHdl ); 351*cdf0e10cSrcweir Link aCursorDown = LINK( this, ScOptSolverDlg, CursorDownHdl ); 352*cdf0e10cSrcweir Link aCondModify = LINK( this, ScOptSolverDlg, CondModifyHdl ); 353*cdf0e10cSrcweir for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow ) 354*cdf0e10cSrcweir { 355*cdf0e10cSrcweir mpLeftEdit[nRow]->SetCursorLinks( aCursorUp, aCursorDown ); 356*cdf0e10cSrcweir mpRightEdit[nRow]->SetCursorLinks( aCursorUp, aCursorDown ); 357*cdf0e10cSrcweir mpLeftEdit[nRow]->SetModifyHdl( aCondModify ); 358*cdf0e10cSrcweir mpRightEdit[nRow]->SetModifyHdl( aCondModify ); 359*cdf0e10cSrcweir mpDelButton[nRow]->SetClickHdl( LINK( this, ScOptSolverDlg, DelBtnHdl ) ); 360*cdf0e10cSrcweir mpOperator[nRow]->SetSelectHdl( LINK( this, ScOptSolverDlg, SelectHdl ) ); 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir maEdTargetValue.SetModifyHdl( LINK( this, ScOptSolverDlg, TargetModifyHdl ) ); 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir maScrollBar.SetEndScrollHdl( LINK( this, ScOptSolverDlg, ScrollHdl ) ); 365*cdf0e10cSrcweir maScrollBar.SetScrollHdl( LINK( this, ScOptSolverDlg, ScrollHdl ) ); 366*cdf0e10cSrcweir 367*cdf0e10cSrcweir maScrollBar.SetPageSize( EDIT_ROW_COUNT ); 368*cdf0e10cSrcweir maScrollBar.SetVisibleSize( EDIT_ROW_COUNT ); 369*cdf0e10cSrcweir maScrollBar.SetLineSize( 1 ); 370*cdf0e10cSrcweir // Range is set in ShowConditions 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir // get available solver implementations 373*cdf0e10cSrcweir //! sort by descriptions? 374*cdf0e10cSrcweir ScSolverUtil::GetImplementations( maImplNames, maDescriptions ); 375*cdf0e10cSrcweir sal_Int32 nImplCount = maImplNames.getLength(); 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir const ScOptSolverSave* pOldData = mpDocShell->GetSolverSaveData(); 378*cdf0e10cSrcweir if ( pOldData ) 379*cdf0e10cSrcweir { 380*cdf0e10cSrcweir maEdObjectiveCell.SetRefString( pOldData->GetObjective() ); 381*cdf0e10cSrcweir maRbMax.Check( pOldData->GetMax() ); 382*cdf0e10cSrcweir maRbMin.Check( pOldData->GetMin() ); 383*cdf0e10cSrcweir maRbValue.Check( pOldData->GetValue() ); 384*cdf0e10cSrcweir maEdTargetValue.SetRefString( pOldData->GetTarget() ); 385*cdf0e10cSrcweir maEdVariableCells.SetRefString( pOldData->GetVariable() ); 386*cdf0e10cSrcweir maConditions = pOldData->GetConditions(); 387*cdf0e10cSrcweir maEngine = pOldData->GetEngine(); 388*cdf0e10cSrcweir maProperties = pOldData->GetProperties(); 389*cdf0e10cSrcweir } 390*cdf0e10cSrcweir else 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir maRbMax.Check(); 393*cdf0e10cSrcweir String aCursorStr; 394*cdf0e10cSrcweir if ( !mpDoc->GetRangeAtBlock( ScRange(rCursorPos), &aCursorStr ) ) 395*cdf0e10cSrcweir rCursorPos.Format( aCursorStr, SCA_ABS, NULL, mpDoc->GetAddressConvention() ); 396*cdf0e10cSrcweir maEdObjectiveCell.SetRefString( aCursorStr ); 397*cdf0e10cSrcweir if ( nImplCount > 0 ) 398*cdf0e10cSrcweir maEngine = maImplNames[0]; // use first implementation 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir ShowConditions(); 401*cdf0e10cSrcweir 402*cdf0e10cSrcweir maEdObjectiveCell.GrabFocus(); 403*cdf0e10cSrcweir mpEdActive = &maEdObjectiveCell; 404*cdf0e10cSrcweir } 405*cdf0e10cSrcweir 406*cdf0e10cSrcweir //---------------------------------------------------------------------------- 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir void ScOptSolverDlg::ReadConditions() 409*cdf0e10cSrcweir { 410*cdf0e10cSrcweir for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow ) 411*cdf0e10cSrcweir { 412*cdf0e10cSrcweir ScOptConditionRow aRowEntry; 413*cdf0e10cSrcweir aRowEntry.aLeftStr = mpLeftEdit[nRow]->GetText(); 414*cdf0e10cSrcweir aRowEntry.aRightStr = mpRightEdit[nRow]->GetText(); 415*cdf0e10cSrcweir aRowEntry.nOperator = mpOperator[nRow]->GetSelectEntryPos(); 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir long nVecPos = nScrollPos + nRow; 418*cdf0e10cSrcweir if ( nVecPos >= (long)maConditions.size() && !aRowEntry.IsDefault() ) 419*cdf0e10cSrcweir maConditions.resize( nVecPos + 1 ); 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir if ( nVecPos < (long)maConditions.size() ) 422*cdf0e10cSrcweir maConditions[nVecPos] = aRowEntry; 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir // remove default entries at the end 425*cdf0e10cSrcweir size_t nSize = maConditions.size(); 426*cdf0e10cSrcweir while ( nSize > 0 && maConditions[ nSize-1 ].IsDefault() ) 427*cdf0e10cSrcweir --nSize; 428*cdf0e10cSrcweir maConditions.resize( nSize ); 429*cdf0e10cSrcweir } 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir void ScOptSolverDlg::ShowConditions() 433*cdf0e10cSrcweir { 434*cdf0e10cSrcweir for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow ) 435*cdf0e10cSrcweir { 436*cdf0e10cSrcweir ScOptConditionRow aRowEntry; 437*cdf0e10cSrcweir 438*cdf0e10cSrcweir long nVecPos = nScrollPos + nRow; 439*cdf0e10cSrcweir if ( nVecPos < (long)maConditions.size() ) 440*cdf0e10cSrcweir aRowEntry = maConditions[nVecPos]; 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir mpLeftEdit[nRow]->SetRefString( aRowEntry.aLeftStr ); 443*cdf0e10cSrcweir mpRightEdit[nRow]->SetRefString( aRowEntry.aRightStr ); 444*cdf0e10cSrcweir mpOperator[nRow]->SelectEntryPos( aRowEntry.nOperator ); 445*cdf0e10cSrcweir } 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir // allow to scroll one page behind the visible or stored rows 448*cdf0e10cSrcweir long nVisible = nScrollPos + EDIT_ROW_COUNT; 449*cdf0e10cSrcweir long nMax = std::max( nVisible, (long) maConditions.size() ); 450*cdf0e10cSrcweir maScrollBar.SetRange( Range( 0, nMax + EDIT_ROW_COUNT ) ); 451*cdf0e10cSrcweir maScrollBar.SetThumbPos( nScrollPos ); 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir EnableButtons(); 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir 456*cdf0e10cSrcweir void ScOptSolverDlg::EnableButtons() 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow ) 459*cdf0e10cSrcweir { 460*cdf0e10cSrcweir long nVecPos = nScrollPos + nRow; 461*cdf0e10cSrcweir mpDelButton[nRow]->Enable( nVecPos < (long)maConditions.size() ); 462*cdf0e10cSrcweir } 463*cdf0e10cSrcweir } 464*cdf0e10cSrcweir 465*cdf0e10cSrcweir //---------------------------------------------------------------------------- 466*cdf0e10cSrcweir 467*cdf0e10cSrcweir sal_Bool ScOptSolverDlg::Close() 468*cdf0e10cSrcweir { 469*cdf0e10cSrcweir return DoClose( ScOptSolverDlgWrapper::GetChildWindowId() ); 470*cdf0e10cSrcweir } 471*cdf0e10cSrcweir 472*cdf0e10cSrcweir //---------------------------------------------------------------------------- 473*cdf0e10cSrcweir 474*cdf0e10cSrcweir void ScOptSolverDlg::SetActive() 475*cdf0e10cSrcweir { 476*cdf0e10cSrcweir if ( mbDlgLostFocus ) 477*cdf0e10cSrcweir { 478*cdf0e10cSrcweir mbDlgLostFocus = false; 479*cdf0e10cSrcweir if( mpEdActive ) 480*cdf0e10cSrcweir mpEdActive->GrabFocus(); 481*cdf0e10cSrcweir } 482*cdf0e10cSrcweir else 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir GrabFocus(); 485*cdf0e10cSrcweir } 486*cdf0e10cSrcweir RefInputDone(); 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir //---------------------------------------------------------------------------- 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir void ScOptSolverDlg::SetReference( const ScRange& rRef, ScDocument* pDocP ) 492*cdf0e10cSrcweir { 493*cdf0e10cSrcweir if( mpEdActive ) 494*cdf0e10cSrcweir { 495*cdf0e10cSrcweir if ( rRef.aStart != rRef.aEnd ) 496*cdf0e10cSrcweir RefInputStart(mpEdActive); 497*cdf0e10cSrcweir 498*cdf0e10cSrcweir // "target"/"value": single cell 499*cdf0e10cSrcweir bool bSingle = ( mpEdActive == &maEdObjectiveCell || mpEdActive == &maEdTargetValue ); 500*cdf0e10cSrcweir 501*cdf0e10cSrcweir String aStr; 502*cdf0e10cSrcweir ScAddress aAdr = rRef.aStart; 503*cdf0e10cSrcweir ScRange aNewRef( rRef ); 504*cdf0e10cSrcweir if ( bSingle ) 505*cdf0e10cSrcweir aNewRef.aEnd = aAdr; 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir String aName; 508*cdf0e10cSrcweir if ( pDocP->GetRangeAtBlock( aNewRef, &aName ) ) // named range: show name 509*cdf0e10cSrcweir aStr = aName; 510*cdf0e10cSrcweir else // format cell/range reference 511*cdf0e10cSrcweir { 512*cdf0e10cSrcweir sal_uInt16 nFmt = ( aAdr.Tab() == mnCurTab ) ? SCA_ABS : SCA_ABS_3D; 513*cdf0e10cSrcweir if ( bSingle ) 514*cdf0e10cSrcweir aAdr.Format( aStr, nFmt, pDocP, pDocP->GetAddressConvention() ); 515*cdf0e10cSrcweir else 516*cdf0e10cSrcweir rRef.Format( aStr, nFmt | SCR_ABS, pDocP, pDocP->GetAddressConvention() ); 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir // variable cells can be several ranges, so only the selection is replaced 520*cdf0e10cSrcweir if ( mpEdActive == &maEdVariableCells ) 521*cdf0e10cSrcweir { 522*cdf0e10cSrcweir String aVal = mpEdActive->GetText(); 523*cdf0e10cSrcweir Selection aSel = mpEdActive->GetSelection(); 524*cdf0e10cSrcweir aSel.Justify(); 525*cdf0e10cSrcweir aVal.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() ); 526*cdf0e10cSrcweir aVal.Insert( aStr, (xub_StrLen)aSel.Min() ); 527*cdf0e10cSrcweir Selection aNewSel( aSel.Min(), aSel.Min()+aStr.Len() ); 528*cdf0e10cSrcweir mpEdActive->SetRefString( aVal ); 529*cdf0e10cSrcweir mpEdActive->SetSelection( aNewSel ); 530*cdf0e10cSrcweir } 531*cdf0e10cSrcweir else 532*cdf0e10cSrcweir mpEdActive->SetRefString( aStr ); 533*cdf0e10cSrcweir 534*cdf0e10cSrcweir ReadConditions(); 535*cdf0e10cSrcweir EnableButtons(); 536*cdf0e10cSrcweir 537*cdf0e10cSrcweir // select "Value of" if a ref is input into "target" edit 538*cdf0e10cSrcweir if ( mpEdActive == &maEdTargetValue ) 539*cdf0e10cSrcweir maRbValue.Check(); 540*cdf0e10cSrcweir } 541*cdf0e10cSrcweir } 542*cdf0e10cSrcweir 543*cdf0e10cSrcweir //---------------------------------------------------------------------------- 544*cdf0e10cSrcweir 545*cdf0e10cSrcweir sal_Bool ScOptSolverDlg::IsRefInputMode() const 546*cdf0e10cSrcweir { 547*cdf0e10cSrcweir return mpEdActive != NULL; 548*cdf0e10cSrcweir } 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir //---------------------------------------------------------------------------- 551*cdf0e10cSrcweir // Handler: 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir IMPL_LINK( ScOptSolverDlg, BtnHdl, PushButton*, pBtn ) 554*cdf0e10cSrcweir { 555*cdf0e10cSrcweir if ( pBtn == &maBtnSolve || pBtn == &maBtnCancel ) 556*cdf0e10cSrcweir { 557*cdf0e10cSrcweir bool bSolve = ( pBtn == &maBtnSolve ); 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir SetDispatcherLock( sal_False ); 560*cdf0e10cSrcweir SwitchToDocument(); 561*cdf0e10cSrcweir 562*cdf0e10cSrcweir bool bClose = true; 563*cdf0e10cSrcweir if ( bSolve ) 564*cdf0e10cSrcweir bClose = CallSolver(); 565*cdf0e10cSrcweir 566*cdf0e10cSrcweir if ( bClose ) 567*cdf0e10cSrcweir { 568*cdf0e10cSrcweir // Close: write dialog settings to DocShell for subsequent calls 569*cdf0e10cSrcweir ReadConditions(); 570*cdf0e10cSrcweir ScOptSolverSave aSave( 571*cdf0e10cSrcweir maEdObjectiveCell.GetText(), maRbMax.IsChecked(), maRbMin.IsChecked(), maRbValue.IsChecked(), 572*cdf0e10cSrcweir maEdTargetValue.GetText(), maEdVariableCells.GetText(), maConditions, maEngine, maProperties ); 573*cdf0e10cSrcweir mpDocShell->SetSolverSaveData( aSave ); 574*cdf0e10cSrcweir Close(); 575*cdf0e10cSrcweir } 576*cdf0e10cSrcweir else 577*cdf0e10cSrcweir { 578*cdf0e10cSrcweir // no solution -> dialog is kept open 579*cdf0e10cSrcweir SetDispatcherLock( sal_True ); 580*cdf0e10cSrcweir } 581*cdf0e10cSrcweir } 582*cdf0e10cSrcweir else if ( pBtn == &maBtnOpt ) 583*cdf0e10cSrcweir { 584*cdf0e10cSrcweir //! move options dialog to UI lib? 585*cdf0e10cSrcweir ScSolverOptionsDialog* pOptDlg = 586*cdf0e10cSrcweir new ScSolverOptionsDialog( this, maImplNames, maDescriptions, maEngine, maProperties ); 587*cdf0e10cSrcweir if ( pOptDlg->Execute() == RET_OK ) 588*cdf0e10cSrcweir { 589*cdf0e10cSrcweir maEngine = pOptDlg->GetEngine(); 590*cdf0e10cSrcweir maProperties = pOptDlg->GetProperties(); 591*cdf0e10cSrcweir } 592*cdf0e10cSrcweir delete pOptDlg; 593*cdf0e10cSrcweir } 594*cdf0e10cSrcweir 595*cdf0e10cSrcweir return 0; 596*cdf0e10cSrcweir } 597*cdf0e10cSrcweir 598*cdf0e10cSrcweir //---------------------------------------------------------------------------- 599*cdf0e10cSrcweir 600*cdf0e10cSrcweir IMPL_LINK( ScOptSolverDlg, GetFocusHdl, Control*, pCtrl ) 601*cdf0e10cSrcweir { 602*cdf0e10cSrcweir Edit* pEdit = NULL; 603*cdf0e10cSrcweir mpEdActive = NULL; 604*cdf0e10cSrcweir 605*cdf0e10cSrcweir if( pCtrl == &maEdObjectiveCell || pCtrl == &maRBObjectiveCell ) 606*cdf0e10cSrcweir pEdit = mpEdActive = &maEdObjectiveCell; 607*cdf0e10cSrcweir else if( pCtrl == &maEdTargetValue || pCtrl == &maRBTargetValue ) 608*cdf0e10cSrcweir pEdit = mpEdActive = &maEdTargetValue; 609*cdf0e10cSrcweir else if( pCtrl == &maEdVariableCells || pCtrl == &maRBVariableCells ) 610*cdf0e10cSrcweir pEdit = mpEdActive = &maEdVariableCells; 611*cdf0e10cSrcweir for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow ) 612*cdf0e10cSrcweir { 613*cdf0e10cSrcweir if( pCtrl == mpLeftEdit[nRow] || pCtrl == mpLeftButton[nRow] ) 614*cdf0e10cSrcweir pEdit = mpEdActive = mpLeftEdit[nRow]; 615*cdf0e10cSrcweir else if( pCtrl == mpRightEdit[nRow] || pCtrl == mpRightButton[nRow] ) 616*cdf0e10cSrcweir pEdit = mpEdActive = mpRightEdit[nRow]; 617*cdf0e10cSrcweir else if( pCtrl == mpOperator[nRow] ) // focus on "operator" list box 618*cdf0e10cSrcweir mpEdActive = mpRightEdit[nRow]; // use right edit for ref input, but don't change selection 619*cdf0e10cSrcweir } 620*cdf0e10cSrcweir if( pCtrl == &maRbValue ) // focus on "Value of" radio button 621*cdf0e10cSrcweir mpEdActive = &maEdTargetValue; // use value edit for ref input, but don't change selection 622*cdf0e10cSrcweir 623*cdf0e10cSrcweir if( pEdit ) 624*cdf0e10cSrcweir pEdit->SetSelection( Selection( 0, SELECTION_MAX ) ); 625*cdf0e10cSrcweir 626*cdf0e10cSrcweir return 0; 627*cdf0e10cSrcweir } 628*cdf0e10cSrcweir 629*cdf0e10cSrcweir //---------------------------------------------------------------------------- 630*cdf0e10cSrcweir 631*cdf0e10cSrcweir IMPL_LINK( ScOptSolverDlg, LoseFocusHdl, Control*, EMPTYARG ) 632*cdf0e10cSrcweir { 633*cdf0e10cSrcweir mbDlgLostFocus = !IsActive(); 634*cdf0e10cSrcweir return 0; 635*cdf0e10cSrcweir } 636*cdf0e10cSrcweir 637*cdf0e10cSrcweir //---------------------------------------------------------------------------- 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir IMPL_LINK( ScOptSolverDlg, DelBtnHdl, PushButton*, pBtn ) 640*cdf0e10cSrcweir { 641*cdf0e10cSrcweir for ( sal_uInt16 nRow = 0; nRow < EDIT_ROW_COUNT; ++nRow ) 642*cdf0e10cSrcweir if( pBtn == mpDelButton[nRow] ) 643*cdf0e10cSrcweir { 644*cdf0e10cSrcweir sal_Bool bHadFocus = pBtn->HasFocus(); 645*cdf0e10cSrcweir 646*cdf0e10cSrcweir ReadConditions(); 647*cdf0e10cSrcweir long nVecPos = nScrollPos + nRow; 648*cdf0e10cSrcweir if ( nVecPos < (long)maConditions.size() ) 649*cdf0e10cSrcweir { 650*cdf0e10cSrcweir maConditions.erase( maConditions.begin() + nVecPos ); 651*cdf0e10cSrcweir ShowConditions(); 652*cdf0e10cSrcweir 653*cdf0e10cSrcweir if ( bHadFocus && !pBtn->IsEnabled() ) 654*cdf0e10cSrcweir { 655*cdf0e10cSrcweir // If the button is disabled, focus would normally move to the next control, 656*cdf0e10cSrcweir // (left edit of the next row). Move it to left edit of this row instead. 657*cdf0e10cSrcweir 658*cdf0e10cSrcweir mpEdActive = mpLeftEdit[nRow]; 659*cdf0e10cSrcweir mpEdActive->GrabFocus(); 660*cdf0e10cSrcweir } 661*cdf0e10cSrcweir } 662*cdf0e10cSrcweir } 663*cdf0e10cSrcweir 664*cdf0e10cSrcweir return 0; 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir 667*cdf0e10cSrcweir //---------------------------------------------------------------------------- 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir IMPL_LINK( ScOptSolverDlg, TargetModifyHdl, Edit*, EMPTYARG ) 670*cdf0e10cSrcweir { 671*cdf0e10cSrcweir // modify handler for the target edit: 672*cdf0e10cSrcweir // select "Value of" if something is input into the edit 673*cdf0e10cSrcweir if ( maEdTargetValue.GetText().Len() ) 674*cdf0e10cSrcweir maRbValue.Check(); 675*cdf0e10cSrcweir return 0; 676*cdf0e10cSrcweir } 677*cdf0e10cSrcweir 678*cdf0e10cSrcweir IMPL_LINK( ScOptSolverDlg, CondModifyHdl, Edit*, EMPTYARG ) 679*cdf0e10cSrcweir { 680*cdf0e10cSrcweir // modify handler for the condition edits, just to enable/disable "delete" buttons 681*cdf0e10cSrcweir ReadConditions(); 682*cdf0e10cSrcweir EnableButtons(); 683*cdf0e10cSrcweir return 0; 684*cdf0e10cSrcweir } 685*cdf0e10cSrcweir 686*cdf0e10cSrcweir IMPL_LINK( ScOptSolverDlg, SelectHdl, ListBox*, EMPTYARG ) 687*cdf0e10cSrcweir { 688*cdf0e10cSrcweir // select handler for operator list boxes, just to enable/disable "delete" buttons 689*cdf0e10cSrcweir ReadConditions(); 690*cdf0e10cSrcweir EnableButtons(); 691*cdf0e10cSrcweir return 0; 692*cdf0e10cSrcweir } 693*cdf0e10cSrcweir 694*cdf0e10cSrcweir IMPL_LINK( ScOptSolverDlg, ScrollHdl, ScrollBar*, EMPTYARG ) 695*cdf0e10cSrcweir { 696*cdf0e10cSrcweir ReadConditions(); 697*cdf0e10cSrcweir nScrollPos = maScrollBar.GetThumbPos(); 698*cdf0e10cSrcweir ShowConditions(); 699*cdf0e10cSrcweir if( mpEdActive ) 700*cdf0e10cSrcweir mpEdActive->SetSelection( Selection( 0, SELECTION_MAX ) ); 701*cdf0e10cSrcweir return 0; 702*cdf0e10cSrcweir } 703*cdf0e10cSrcweir 704*cdf0e10cSrcweir IMPL_LINK( ScOptSolverDlg, CursorUpHdl, ScCursorRefEdit*, pEdit ) 705*cdf0e10cSrcweir { 706*cdf0e10cSrcweir if ( pEdit == mpLeftEdit[0] || pEdit == mpRightEdit[0] ) 707*cdf0e10cSrcweir { 708*cdf0e10cSrcweir if ( nScrollPos > 0 ) 709*cdf0e10cSrcweir { 710*cdf0e10cSrcweir ReadConditions(); 711*cdf0e10cSrcweir --nScrollPos; 712*cdf0e10cSrcweir ShowConditions(); 713*cdf0e10cSrcweir if( mpEdActive ) 714*cdf0e10cSrcweir mpEdActive->SetSelection( Selection( 0, SELECTION_MAX ) ); 715*cdf0e10cSrcweir } 716*cdf0e10cSrcweir } 717*cdf0e10cSrcweir else 718*cdf0e10cSrcweir { 719*cdf0e10cSrcweir formula::RefEdit* pFocus = NULL; 720*cdf0e10cSrcweir for ( sal_uInt16 nRow = 1; nRow < EDIT_ROW_COUNT; ++nRow ) // second row or below: move focus 721*cdf0e10cSrcweir { 722*cdf0e10cSrcweir if ( pEdit == mpLeftEdit[nRow] ) 723*cdf0e10cSrcweir pFocus = mpLeftEdit[nRow-1]; 724*cdf0e10cSrcweir else if ( pEdit == mpRightEdit[nRow] ) 725*cdf0e10cSrcweir pFocus = mpRightEdit[nRow-1]; 726*cdf0e10cSrcweir } 727*cdf0e10cSrcweir if (pFocus) 728*cdf0e10cSrcweir { 729*cdf0e10cSrcweir mpEdActive = pFocus; 730*cdf0e10cSrcweir pFocus->GrabFocus(); 731*cdf0e10cSrcweir } 732*cdf0e10cSrcweir } 733*cdf0e10cSrcweir 734*cdf0e10cSrcweir return 0; 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir 737*cdf0e10cSrcweir IMPL_LINK( ScOptSolverDlg, CursorDownHdl, ScCursorRefEdit*, pEdit ) 738*cdf0e10cSrcweir { 739*cdf0e10cSrcweir if ( pEdit == mpLeftEdit[EDIT_ROW_COUNT-1] || pEdit == mpRightEdit[EDIT_ROW_COUNT-1] ) 740*cdf0e10cSrcweir { 741*cdf0e10cSrcweir //! limit scroll position? 742*cdf0e10cSrcweir ReadConditions(); 743*cdf0e10cSrcweir ++nScrollPos; 744*cdf0e10cSrcweir ShowConditions(); 745*cdf0e10cSrcweir if( mpEdActive ) 746*cdf0e10cSrcweir mpEdActive->SetSelection( Selection( 0, SELECTION_MAX ) ); 747*cdf0e10cSrcweir } 748*cdf0e10cSrcweir else 749*cdf0e10cSrcweir { 750*cdf0e10cSrcweir formula::RefEdit* pFocus = NULL; 751*cdf0e10cSrcweir for ( sal_uInt16 nRow = 0; nRow+1 < EDIT_ROW_COUNT; ++nRow ) // before last row: move focus 752*cdf0e10cSrcweir { 753*cdf0e10cSrcweir if ( pEdit == mpLeftEdit[nRow] ) 754*cdf0e10cSrcweir pFocus = mpLeftEdit[nRow+1]; 755*cdf0e10cSrcweir else if ( pEdit == mpRightEdit[nRow] ) 756*cdf0e10cSrcweir pFocus = mpRightEdit[nRow+1]; 757*cdf0e10cSrcweir } 758*cdf0e10cSrcweir if (pFocus) 759*cdf0e10cSrcweir { 760*cdf0e10cSrcweir mpEdActive = pFocus; 761*cdf0e10cSrcweir pFocus->GrabFocus(); 762*cdf0e10cSrcweir } 763*cdf0e10cSrcweir } 764*cdf0e10cSrcweir 765*cdf0e10cSrcweir return 0; 766*cdf0e10cSrcweir } 767*cdf0e10cSrcweir 768*cdf0e10cSrcweir //---------------------------------------------------------------------------- 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir void ScOptSolverDlg::ShowError( bool bCondition, formula::RefEdit* pFocus ) 771*cdf0e10cSrcweir { 772*cdf0e10cSrcweir String aMessage = bCondition ? maConditionError : maInputError; 773*cdf0e10cSrcweir ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ), aMessage ).Execute(); 774*cdf0e10cSrcweir if (pFocus) 775*cdf0e10cSrcweir { 776*cdf0e10cSrcweir mpEdActive = pFocus; 777*cdf0e10cSrcweir pFocus->GrabFocus(); 778*cdf0e10cSrcweir } 779*cdf0e10cSrcweir } 780*cdf0e10cSrcweir 781*cdf0e10cSrcweir //---------------------------------------------------------------------------- 782*cdf0e10cSrcweir 783*cdf0e10cSrcweir bool ScOptSolverDlg::ParseRef( ScRange& rRange, const String& rInput, bool bAllowRange ) 784*cdf0e10cSrcweir { 785*cdf0e10cSrcweir ScRangeUtil aRangeUtil; 786*cdf0e10cSrcweir ScAddress::Details aDetails(mpDoc->GetAddressConvention(), 0, 0); 787*cdf0e10cSrcweir sal_uInt16 nFlags = rRange.ParseAny( rInput, mpDoc, aDetails ); 788*cdf0e10cSrcweir if ( nFlags & SCA_VALID ) 789*cdf0e10cSrcweir { 790*cdf0e10cSrcweir if ( (nFlags & SCA_TAB_3D) == 0 ) 791*cdf0e10cSrcweir rRange.aStart.SetTab( mnCurTab ); 792*cdf0e10cSrcweir if ( (nFlags & SCA_TAB2_3D) == 0 ) 793*cdf0e10cSrcweir rRange.aEnd.SetTab( rRange.aStart.Tab() ); 794*cdf0e10cSrcweir return ( bAllowRange || rRange.aStart == rRange.aEnd ); 795*cdf0e10cSrcweir } 796*cdf0e10cSrcweir else if ( aRangeUtil.MakeRangeFromName( rInput, mpDoc, mnCurTab, rRange, RUTL_NAMES, aDetails ) ) 797*cdf0e10cSrcweir return ( bAllowRange || rRange.aStart == rRange.aEnd ); 798*cdf0e10cSrcweir 799*cdf0e10cSrcweir return false; // not recognized 800*cdf0e10cSrcweir } 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir bool ScOptSolverDlg::FindTimeout( sal_Int32& rTimeout ) 803*cdf0e10cSrcweir { 804*cdf0e10cSrcweir bool bFound = false; 805*cdf0e10cSrcweir 806*cdf0e10cSrcweir if ( !maProperties.getLength() ) 807*cdf0e10cSrcweir maProperties = ScSolverUtil::GetDefaults( maEngine ); // get property defaults from component 808*cdf0e10cSrcweir 809*cdf0e10cSrcweir sal_Int32 nPropCount = maProperties.getLength(); 810*cdf0e10cSrcweir for (sal_Int32 nProp=0; nProp<nPropCount && !bFound; ++nProp) 811*cdf0e10cSrcweir { 812*cdf0e10cSrcweir const beans::PropertyValue& rValue = maProperties[nProp]; 813*cdf0e10cSrcweir if ( rValue.Name.equalsAscii( SC_UNONAME_TIMEOUT ) ) 814*cdf0e10cSrcweir bFound = ( rValue.Value >>= rTimeout ); 815*cdf0e10cSrcweir } 816*cdf0e10cSrcweir return bFound; 817*cdf0e10cSrcweir } 818*cdf0e10cSrcweir 819*cdf0e10cSrcweir bool ScOptSolverDlg::CallSolver() // return true -> close dialog after calling 820*cdf0e10cSrcweir { 821*cdf0e10cSrcweir // show progress dialog 822*cdf0e10cSrcweir 823*cdf0e10cSrcweir ScSolverProgressDialog aProgress( this ); 824*cdf0e10cSrcweir sal_Int32 nTimeout = 0; 825*cdf0e10cSrcweir if ( FindTimeout( nTimeout ) ) 826*cdf0e10cSrcweir aProgress.SetTimeLimit( nTimeout ); 827*cdf0e10cSrcweir else 828*cdf0e10cSrcweir aProgress.HideTimeLimit(); 829*cdf0e10cSrcweir aProgress.Show(); 830*cdf0e10cSrcweir aProgress.Update(); 831*cdf0e10cSrcweir aProgress.Sync(); 832*cdf0e10cSrcweir // try to make sure the progress dialog is painted before continuing 833*cdf0e10cSrcweir Application::Reschedule(true); 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir // collect solver parameters 836*cdf0e10cSrcweir 837*cdf0e10cSrcweir ReadConditions(); 838*cdf0e10cSrcweir 839*cdf0e10cSrcweir uno::Reference<sheet::XSpreadsheetDocument> xDocument( mpDocShell->GetModel(), uno::UNO_QUERY ); 840*cdf0e10cSrcweir 841*cdf0e10cSrcweir ScRange aObjRange; 842*cdf0e10cSrcweir if ( !ParseRef( aObjRange, maEdObjectiveCell.GetText(), false ) ) 843*cdf0e10cSrcweir { 844*cdf0e10cSrcweir ShowError( false, &maEdObjectiveCell ); 845*cdf0e10cSrcweir return false; 846*cdf0e10cSrcweir } 847*cdf0e10cSrcweir table::CellAddress aObjective( aObjRange.aStart.Tab(), aObjRange.aStart.Col(), aObjRange.aStart.Row() ); 848*cdf0e10cSrcweir 849*cdf0e10cSrcweir // "changing cells" can be several ranges 850*cdf0e10cSrcweir ScRangeList aVarRanges; 851*cdf0e10cSrcweir if ( !ParseWithNames( aVarRanges, maEdVariableCells.GetText(), mpDoc ) ) 852*cdf0e10cSrcweir { 853*cdf0e10cSrcweir ShowError( false, &maEdVariableCells ); 854*cdf0e10cSrcweir return false; 855*cdf0e10cSrcweir } 856*cdf0e10cSrcweir uno::Sequence<table::CellAddress> aVariables; 857*cdf0e10cSrcweir sal_Int32 nVarPos = 0; 858*cdf0e10cSrcweir sal_uLong nRangeCount = aVarRanges.Count(); 859*cdf0e10cSrcweir for (sal_uLong nRangePos=0; nRangePos<nRangeCount; ++nRangePos) 860*cdf0e10cSrcweir { 861*cdf0e10cSrcweir ScRange aRange(*aVarRanges.GetObject(nRangePos)); 862*cdf0e10cSrcweir aRange.Justify(); 863*cdf0e10cSrcweir SCTAB nTab = aRange.aStart.Tab(); 864*cdf0e10cSrcweir 865*cdf0e10cSrcweir // resolve into single cells 866*cdf0e10cSrcweir 867*cdf0e10cSrcweir sal_Int32 nAdd = ( aRange.aEnd.Col() - aRange.aStart.Col() + 1 ) * 868*cdf0e10cSrcweir ( aRange.aEnd.Row() - aRange.aStart.Row() + 1 ); 869*cdf0e10cSrcweir aVariables.realloc( nVarPos + nAdd ); 870*cdf0e10cSrcweir 871*cdf0e10cSrcweir for (SCROW nRow = aRange.aStart.Row(); nRow <= aRange.aEnd.Row(); ++nRow) 872*cdf0e10cSrcweir for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol) 873*cdf0e10cSrcweir aVariables[nVarPos++] = table::CellAddress( nTab, nCol, nRow ); 874*cdf0e10cSrcweir } 875*cdf0e10cSrcweir 876*cdf0e10cSrcweir uno::Sequence<sheet::SolverConstraint> aConstraints; 877*cdf0e10cSrcweir sal_Int32 nConstrPos = 0; 878*cdf0e10cSrcweir for ( std::vector<ScOptConditionRow>::const_iterator aConstrIter = maConditions.begin(); 879*cdf0e10cSrcweir aConstrIter != maConditions.end(); ++aConstrIter ) 880*cdf0e10cSrcweir { 881*cdf0e10cSrcweir if ( aConstrIter->aLeftStr.Len() ) 882*cdf0e10cSrcweir { 883*cdf0e10cSrcweir sheet::SolverConstraint aConstraint; 884*cdf0e10cSrcweir // order of list box entries must match enum values 885*cdf0e10cSrcweir aConstraint.Operator = static_cast<sheet::SolverConstraintOperator>(aConstrIter->nOperator); 886*cdf0e10cSrcweir 887*cdf0e10cSrcweir ScRange aLeftRange; 888*cdf0e10cSrcweir if ( !ParseRef( aLeftRange, aConstrIter->aLeftStr, true ) ) 889*cdf0e10cSrcweir { 890*cdf0e10cSrcweir ShowError( true, NULL ); 891*cdf0e10cSrcweir return false; 892*cdf0e10cSrcweir } 893*cdf0e10cSrcweir 894*cdf0e10cSrcweir bool bIsRange = false; 895*cdf0e10cSrcweir ScRange aRightRange; 896*cdf0e10cSrcweir if ( ParseRef( aRightRange, aConstrIter->aRightStr, true ) ) 897*cdf0e10cSrcweir { 898*cdf0e10cSrcweir if ( aRightRange.aStart == aRightRange.aEnd ) 899*cdf0e10cSrcweir aConstraint.Right <<= table::CellAddress( aRightRange.aStart.Tab(), 900*cdf0e10cSrcweir aRightRange.aStart.Col(), aRightRange.aStart.Row() ); 901*cdf0e10cSrcweir else if ( aRightRange.aEnd.Col()-aRightRange.aStart.Col() == aLeftRange.aEnd.Col()-aLeftRange.aStart.Col() && 902*cdf0e10cSrcweir aRightRange.aEnd.Row()-aRightRange.aStart.Row() == aLeftRange.aEnd.Row()-aLeftRange.aStart.Row() ) 903*cdf0e10cSrcweir bIsRange = true; // same size as "left" range, resolve into single cells 904*cdf0e10cSrcweir else 905*cdf0e10cSrcweir { 906*cdf0e10cSrcweir ShowError( true, NULL ); 907*cdf0e10cSrcweir return false; 908*cdf0e10cSrcweir } 909*cdf0e10cSrcweir } 910*cdf0e10cSrcweir else 911*cdf0e10cSrcweir { 912*cdf0e10cSrcweir sal_uInt32 nFormat = 0; //! explicit language? 913*cdf0e10cSrcweir double fValue = 0.0; 914*cdf0e10cSrcweir if ( mpDoc->GetFormatTable()->IsNumberFormat( aConstrIter->aRightStr, nFormat, fValue ) ) 915*cdf0e10cSrcweir aConstraint.Right <<= fValue; 916*cdf0e10cSrcweir else if ( aConstraint.Operator != sheet::SolverConstraintOperator_INTEGER && 917*cdf0e10cSrcweir aConstraint.Operator != sheet::SolverConstraintOperator_BINARY ) 918*cdf0e10cSrcweir { 919*cdf0e10cSrcweir ShowError( true, NULL ); 920*cdf0e10cSrcweir return false; 921*cdf0e10cSrcweir } 922*cdf0e10cSrcweir } 923*cdf0e10cSrcweir 924*cdf0e10cSrcweir // resolve into single cells 925*cdf0e10cSrcweir 926*cdf0e10cSrcweir sal_Int32 nAdd = ( aLeftRange.aEnd.Col() - aLeftRange.aStart.Col() + 1 ) * 927*cdf0e10cSrcweir ( aLeftRange.aEnd.Row() - aLeftRange.aStart.Row() + 1 ); 928*cdf0e10cSrcweir aConstraints.realloc( nConstrPos + nAdd ); 929*cdf0e10cSrcweir 930*cdf0e10cSrcweir for (SCROW nRow = aLeftRange.aStart.Row(); nRow <= aLeftRange.aEnd.Row(); ++nRow) 931*cdf0e10cSrcweir for (SCCOL nCol = aLeftRange.aStart.Col(); nCol <= aLeftRange.aEnd.Col(); ++nCol) 932*cdf0e10cSrcweir { 933*cdf0e10cSrcweir aConstraint.Left = table::CellAddress( aLeftRange.aStart.Tab(), nCol, nRow ); 934*cdf0e10cSrcweir if ( bIsRange ) 935*cdf0e10cSrcweir aConstraint.Right <<= table::CellAddress( aRightRange.aStart.Tab(), 936*cdf0e10cSrcweir aRightRange.aStart.Col() + ( nCol - aLeftRange.aStart.Col() ), 937*cdf0e10cSrcweir aRightRange.aStart.Row() + ( nRow - aLeftRange.aStart.Row() ) ); 938*cdf0e10cSrcweir 939*cdf0e10cSrcweir aConstraints[nConstrPos++] = aConstraint; 940*cdf0e10cSrcweir } 941*cdf0e10cSrcweir } 942*cdf0e10cSrcweir } 943*cdf0e10cSrcweir 944*cdf0e10cSrcweir sal_Bool bMaximize = maRbMax.IsChecked(); 945*cdf0e10cSrcweir if ( maRbValue.IsChecked() ) 946*cdf0e10cSrcweir { 947*cdf0e10cSrcweir // handle "value of" with an additional constraint (and then minimize) 948*cdf0e10cSrcweir 949*cdf0e10cSrcweir sheet::SolverConstraint aConstraint; 950*cdf0e10cSrcweir aConstraint.Left = aObjective; 951*cdf0e10cSrcweir aConstraint.Operator = sheet::SolverConstraintOperator_EQUAL; 952*cdf0e10cSrcweir 953*cdf0e10cSrcweir String aValStr = maEdTargetValue.GetText(); 954*cdf0e10cSrcweir ScRange aRightRange; 955*cdf0e10cSrcweir if ( ParseRef( aRightRange, aValStr, false ) ) 956*cdf0e10cSrcweir aConstraint.Right <<= table::CellAddress( aRightRange.aStart.Tab(), 957*cdf0e10cSrcweir aRightRange.aStart.Col(), aRightRange.aStart.Row() ); 958*cdf0e10cSrcweir else 959*cdf0e10cSrcweir { 960*cdf0e10cSrcweir sal_uInt32 nFormat = 0; //! explicit language? 961*cdf0e10cSrcweir double fValue = 0.0; 962*cdf0e10cSrcweir if ( mpDoc->GetFormatTable()->IsNumberFormat( aValStr, nFormat, fValue ) ) 963*cdf0e10cSrcweir aConstraint.Right <<= fValue; 964*cdf0e10cSrcweir else 965*cdf0e10cSrcweir { 966*cdf0e10cSrcweir ShowError( false, &maEdTargetValue ); 967*cdf0e10cSrcweir return false; 968*cdf0e10cSrcweir } 969*cdf0e10cSrcweir } 970*cdf0e10cSrcweir 971*cdf0e10cSrcweir aConstraints.realloc( nConstrPos + 1 ); 972*cdf0e10cSrcweir aConstraints[nConstrPos++] = aConstraint; 973*cdf0e10cSrcweir } 974*cdf0e10cSrcweir 975*cdf0e10cSrcweir // copy old document values 976*cdf0e10cSrcweir 977*cdf0e10cSrcweir sal_Int32 nVarCount = aVariables.getLength(); 978*cdf0e10cSrcweir uno::Sequence<double> aOldValues; 979*cdf0e10cSrcweir aOldValues.realloc( nVarCount ); 980*cdf0e10cSrcweir for (nVarPos=0; nVarPos<nVarCount; ++nVarPos) 981*cdf0e10cSrcweir { 982*cdf0e10cSrcweir ScAddress aCellPos; 983*cdf0e10cSrcweir ScUnoConversion::FillScAddress( aCellPos, aVariables[nVarPos] ); 984*cdf0e10cSrcweir aOldValues[nVarPos] = mpDoc->GetValue( aCellPos ); 985*cdf0e10cSrcweir } 986*cdf0e10cSrcweir 987*cdf0e10cSrcweir // create and initialize solver 988*cdf0e10cSrcweir 989*cdf0e10cSrcweir uno::Reference<sheet::XSolver> xSolver = ScSolverUtil::GetSolver( maEngine ); 990*cdf0e10cSrcweir DBG_ASSERT( xSolver.is(), "can't get solver component" ); 991*cdf0e10cSrcweir if ( !xSolver.is() ) 992*cdf0e10cSrcweir return false; 993*cdf0e10cSrcweir 994*cdf0e10cSrcweir xSolver->setDocument( xDocument ); 995*cdf0e10cSrcweir xSolver->setObjective( aObjective ); 996*cdf0e10cSrcweir xSolver->setVariables( aVariables ); 997*cdf0e10cSrcweir xSolver->setConstraints( aConstraints ); 998*cdf0e10cSrcweir xSolver->setMaximize( bMaximize ); 999*cdf0e10cSrcweir 1000*cdf0e10cSrcweir // set options 1001*cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xOptProp(xSolver, uno::UNO_QUERY); 1002*cdf0e10cSrcweir if ( xOptProp.is() ) 1003*cdf0e10cSrcweir { 1004*cdf0e10cSrcweir sal_Int32 nPropCount = maProperties.getLength(); 1005*cdf0e10cSrcweir for (sal_Int32 nProp=0; nProp<nPropCount; ++nProp) 1006*cdf0e10cSrcweir { 1007*cdf0e10cSrcweir const beans::PropertyValue& rValue = maProperties[nProp]; 1008*cdf0e10cSrcweir try 1009*cdf0e10cSrcweir { 1010*cdf0e10cSrcweir xOptProp->setPropertyValue( rValue.Name, rValue.Value ); 1011*cdf0e10cSrcweir } 1012*cdf0e10cSrcweir catch ( uno::Exception & ) 1013*cdf0e10cSrcweir { 1014*cdf0e10cSrcweir DBG_ERRORFILE("Exception in solver option property"); 1015*cdf0e10cSrcweir } 1016*cdf0e10cSrcweir } 1017*cdf0e10cSrcweir } 1018*cdf0e10cSrcweir 1019*cdf0e10cSrcweir xSolver->solve(); 1020*cdf0e10cSrcweir sal_Bool bSuccess = xSolver->getSuccess(); 1021*cdf0e10cSrcweir 1022*cdf0e10cSrcweir aProgress.Hide(); 1023*cdf0e10cSrcweir bool bClose = false; 1024*cdf0e10cSrcweir bool bRestore = true; // restore old values unless a solution is accepted 1025*cdf0e10cSrcweir if ( bSuccess ) 1026*cdf0e10cSrcweir { 1027*cdf0e10cSrcweir // put solution into document so it is visible when asking 1028*cdf0e10cSrcweir uno::Sequence<double> aSolution = xSolver->getSolution(); 1029*cdf0e10cSrcweir if ( aSolution.getLength() == nVarCount ) 1030*cdf0e10cSrcweir { 1031*cdf0e10cSrcweir mpDocShell->LockPaint(); 1032*cdf0e10cSrcweir ScDocFunc aFunc(*mpDocShell); 1033*cdf0e10cSrcweir for (nVarPos=0; nVarPos<nVarCount; ++nVarPos) 1034*cdf0e10cSrcweir { 1035*cdf0e10cSrcweir ScAddress aCellPos; 1036*cdf0e10cSrcweir ScUnoConversion::FillScAddress( aCellPos, aVariables[nVarPos] ); 1037*cdf0e10cSrcweir aFunc.PutCell( aCellPos, new ScValueCell( aSolution[nVarPos] ), sal_True ); 1038*cdf0e10cSrcweir } 1039*cdf0e10cSrcweir mpDocShell->UnlockPaint(); 1040*cdf0e10cSrcweir } 1041*cdf0e10cSrcweir //! else error? 1042*cdf0e10cSrcweir 1043*cdf0e10cSrcweir // take formatted result from document (result value from component is ignored) 1044*cdf0e10cSrcweir String aResultStr; 1045*cdf0e10cSrcweir mpDoc->GetString( (SCCOL)aObjective.Column, (SCROW)aObjective.Row, (SCTAB)aObjective.Sheet, aResultStr ); 1046*cdf0e10cSrcweir ScSolverSuccessDialog aDialog( this, aResultStr ); 1047*cdf0e10cSrcweir if ( aDialog.Execute() == RET_OK ) 1048*cdf0e10cSrcweir { 1049*cdf0e10cSrcweir // keep results and close dialog 1050*cdf0e10cSrcweir bRestore = false; 1051*cdf0e10cSrcweir bClose = true; 1052*cdf0e10cSrcweir } 1053*cdf0e10cSrcweir } 1054*cdf0e10cSrcweir else 1055*cdf0e10cSrcweir { 1056*cdf0e10cSrcweir rtl::OUString aError; 1057*cdf0e10cSrcweir uno::Reference<sheet::XSolverDescription> xDesc( xSolver, uno::UNO_QUERY ); 1058*cdf0e10cSrcweir if ( xDesc.is() ) 1059*cdf0e10cSrcweir aError = xDesc->getStatusDescription(); // error description from component 1060*cdf0e10cSrcweir ScSolverNoSolutionDialog aDialog( this, aError ); 1061*cdf0e10cSrcweir aDialog.Execute(); 1062*cdf0e10cSrcweir } 1063*cdf0e10cSrcweir 1064*cdf0e10cSrcweir if ( bRestore ) // restore old values 1065*cdf0e10cSrcweir { 1066*cdf0e10cSrcweir mpDocShell->LockPaint(); 1067*cdf0e10cSrcweir ScDocFunc aFunc(*mpDocShell); 1068*cdf0e10cSrcweir for (nVarPos=0; nVarPos<nVarCount; ++nVarPos) 1069*cdf0e10cSrcweir { 1070*cdf0e10cSrcweir ScAddress aCellPos; 1071*cdf0e10cSrcweir ScUnoConversion::FillScAddress( aCellPos, aVariables[nVarPos] ); 1072*cdf0e10cSrcweir aFunc.PutCell( aCellPos, new ScValueCell( aOldValues[nVarPos] ), sal_True ); 1073*cdf0e10cSrcweir } 1074*cdf0e10cSrcweir mpDocShell->UnlockPaint(); 1075*cdf0e10cSrcweir } 1076*cdf0e10cSrcweir 1077*cdf0e10cSrcweir return bClose; 1078*cdf0e10cSrcweir } 1079*cdf0e10cSrcweir 1080