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

Generated by: LCOV version 1.10