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