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

Generated by: LCOV version 1.10