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