LCOV - code coverage report
Current view: top level - sc/source/ui/miscdlgs - optsolver.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 615 0.2 %
Date: 2014-11-03 Functions: 2 49 4.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10