xref: /aoo42x/main/sc/source/ui/miscdlgs/solvrdlg.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 
32 
33 //----------------------------------------------------------------------------
34 
35 #include "rangelst.hxx"
36 #include "scitems.hxx"
37 #include <sfx2/dispatch.hxx>
38 #include <svl/zforlist.hxx>
39 #include <vcl/msgbox.hxx>
40 
41 #include "uiitems.hxx"
42 #include "reffact.hxx"
43 #include "document.hxx"
44 #include "scresid.hxx"
45 #include "solvrdlg.hrc"
46 
47 #define _SOLVRDLG_CXX
48 #include "solvrdlg.hxx"
49 #undef _SOLVERDLG_CXX
50 
51 
52 #define ERRORBOX(s)	ErrorBox( this, WinBits( WB_OK | WB_DEF_OK), s ).Execute()
53 
54 
55 //============================================================================
56 //	class ScSolverDlg
57 //----------------------------------------------------------------------------
58 
59 ScSolverDlg::ScSolverDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
60 						  ScDocument* pDocument,
61 						  ScAddress	aCursorPos )
62 
63 	:	ScAnyRefDlg			( pB, pCW, pParent, RID_SCDLG_SOLVER ),
64 		//
65         aFlVariables        ( this, ScResId( FL_VARIABLES ) ),
66 		aFtFormulaCell		( this, ScResId( FT_FORMULACELL ) ),
67         aEdFormulaCell      ( this, this, ScResId( ED_FORMULACELL ) ),
68 		aRBFormulaCell		( this, ScResId( RB_FORMULACELL ), &aEdFormulaCell, this ),
69 		aFtTargetVal		( this, ScResId( FT_TARGETVAL ) ),
70 		aEdTargetVal		( this, ScResId( ED_TARGETVAL ) ),
71 		aFtVariableCell		( this, ScResId( FT_VARCELL ) ),
72         aEdVariableCell     ( this, this, ScResId( ED_VARCELL ) ),
73 		aRBVariableCell		( this, ScResId( RB_VARCELL ), &aEdVariableCell, this ),
74 		aBtnOk				( this, ScResId( BTN_OK ) ),
75 		aBtnCancel			( this, ScResId( BTN_CANCEL ) ),
76 		aBtnHelp			( this, ScResId( BTN_HELP ) ),
77 		//
78 		theFormulaCell		( aCursorPos ),
79 		theVariableCell		( aCursorPos ),
80 		pDoc				( pDocument ),
81 		nCurTab				( aCursorPos.Tab() ),
82 		pEdActive			( NULL ),
83 		bDlgLostFocus		( sal_False ),
84 		errMsgInvalidVar	( ScResId( STR_INVALIDVAR ) ),
85 		errMsgInvalidForm	( ScResId( STR_INVALIDFORM ) ),
86 		errMsgNoFormula		( ScResId( STR_NOFORMULA ) ),
87 		errMsgInvalidVal	( ScResId( STR_INVALIDVAL ) )
88 {
89 	Init();
90 	FreeResource();
91 
92 	aRBFormulaCell.SetAccessibleRelationMemberOf(&aFlVariables);
93 	aRBVariableCell.SetAccessibleRelationMemberOf(&aFlVariables);
94 }
95 
96 //----------------------------------------------------------------------------
97 
98 __EXPORT ScSolverDlg::~ScSolverDlg()
99 {
100 }
101 
102 //----------------------------------------------------------------------------
103 
104 void __EXPORT ScSolverDlg::Init()
105 {
106 	String			aStr;
107 
108 	aBtnOk.			SetClickHdl		( LINK( this, ScSolverDlg, BtnHdl ) );
109 	aBtnCancel.		SetClickHdl		( LINK( this, ScSolverDlg, BtnHdl ) );
110 
111     Link aLink = LINK( this, ScSolverDlg, GetFocusHdl );
112     aEdFormulaCell. SetGetFocusHdl  ( aLink );
113     aRBFormulaCell. SetGetFocusHdl  ( aLink );
114     aEdVariableCell.SetGetFocusHdl  ( aLink );
115     aRBVariableCell.SetGetFocusHdl  ( aLink );
116     aEdTargetVal.   SetGetFocusHdl  ( aLink );
117 
118     aLink = LINK( this, ScSolverDlg, LoseFocusHdl );
119     aEdFormulaCell. SetLoseFocusHdl ( aLink );
120     aRBFormulaCell. SetLoseFocusHdl ( aLink );
121     aEdVariableCell.SetLoseFocusHdl ( aLink );
122     aRBVariableCell.SetLoseFocusHdl ( aLink );
123 
124 	theFormulaCell.Format( aStr, SCA_ABS, NULL, pDoc->GetAddressConvention() );
125 
126 	aEdFormulaCell.SetText( aStr );
127 	aEdFormulaCell.GrabFocus();
128 	pEdActive = &aEdFormulaCell;
129 }
130 
131 //----------------------------------------------------------------------------
132 
133 sal_Bool __EXPORT ScSolverDlg::Close()
134 {
135 	return DoClose( ScSolverDlgWrapper::GetChildWindowId() );
136 }
137 
138 //----------------------------------------------------------------------------
139 
140 void ScSolverDlg::SetActive()
141 {
142     if ( bDlgLostFocus )
143 	{
144 		bDlgLostFocus = sal_False;
145         if( pEdActive )
146             pEdActive->GrabFocus();
147 	}
148 	else
149 	{
150 		GrabFocus();
151 	}
152 	RefInputDone();
153 }
154 
155 //----------------------------------------------------------------------------
156 
157 void ScSolverDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
158 {
159     if( pEdActive )
160 	{
161 		if ( rRef.aStart != rRef.aEnd )
162 			RefInputStart(pEdActive);
163 
164 		String		aStr;
165 		ScAddress	aAdr = rRef.aStart;
166 		sal_uInt16	 	nFmt = ( aAdr.Tab() == nCurTab )
167 								? SCA_ABS
168 								: SCA_ABS_3D;
169 
170         aAdr.Format( aStr, nFmt, pDocP, pDocP->GetAddressConvention() );
171 		pEdActive->SetRefString( aStr );
172 
173 		if ( pEdActive == &aEdFormulaCell )
174 			theFormulaCell = aAdr;
175 		else if ( pEdActive == &aEdVariableCell )
176 			theVariableCell = aAdr;
177 	}
178 }
179 
180 //----------------------------------------------------------------------------
181 
182 void ScSolverDlg::RaiseError( ScSolverErr eError )
183 {
184 	switch ( eError )
185 	{
186 		case SOLVERR_NOFORMULA:
187 			ERRORBOX( errMsgNoFormula );
188 			aEdFormulaCell.GrabFocus();
189 			break;
190 
191 		case SOLVERR_INVALID_FORMULA:
192 			ERRORBOX( errMsgInvalidForm );
193 			aEdFormulaCell.GrabFocus();
194 			break;
195 
196 		case SOLVERR_INVALID_VARIABLE:
197 			ERRORBOX( errMsgInvalidVar );
198 			aEdVariableCell.GrabFocus();
199 			break;
200 
201 		case SOLVERR_INVALID_TARGETVALUE:
202 			ERRORBOX( errMsgInvalidVal );
203 			aEdTargetVal.GrabFocus();
204 			break;
205 	}
206 }
207 
208 //----------------------------------------------------------------------------
209 
210 sal_Bool ScSolverDlg::IsRefInputMode() const
211 {
212     return pEdActive != NULL;
213 }
214 
215 //----------------------------------------------------------------------------
216 
217 sal_Bool __EXPORT ScSolverDlg::CheckTargetValue( String& rStrVal )
218 {
219 	sal_uInt32 n1 = 0;
220 	double n2;
221 
222 	return pDoc->GetFormatTable()->IsNumberFormat( rStrVal, n1, n2 );
223 }
224 
225 //----------------------------------------------------------------------------
226 // Handler:
227 
228 IMPL_LINK( ScSolverDlg, BtnHdl, PushButton*, pBtn )
229 {
230 	if ( pBtn == &aBtnOk )
231 	{
232 		theTargetValStr = aEdTargetVal.GetText();
233 
234 		// Zu ueberpruefen:
235 		// 1. enthalten die Strings korrekte Tabellenkoordinaten/def.Namen?
236 		// 2. verweist die Formel-Koordinate wirklich auf eine Formelzelle?
237 		// 3. wurde ein korrekter Zielwert eingegeben
238 
239         const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
240 		sal_uInt16	nRes1 = theFormulaCell .Parse( aEdFormulaCell.GetText(),  pDoc, eConv );
241 		sal_uInt16	nRes2 = theVariableCell.Parse( aEdVariableCell.GetText(), pDoc, eConv );
242 
243 		if ( SCA_VALID == ( nRes1 & SCA_VALID ) )
244 		{
245 			if ( SCA_VALID == ( nRes2 & SCA_VALID ) )
246 			{
247 				if ( CheckTargetValue( theTargetValStr ) )
248 				{
249 					CellType eType;
250 					pDoc->GetCellType( theFormulaCell.Col(),
251 									   theFormulaCell.Row(),
252 									   theFormulaCell.Tab(),
253 									   eType );
254 
255 					if ( CELLTYPE_FORMULA  == eType )
256 					{
257 						ScSolveParam aOutParam( theFormulaCell,
258 												theVariableCell,
259 												theTargetValStr );
260 						ScSolveItem	 aOutItem( SCITEM_SOLVEDATA, &aOutParam );
261 
262 						SetDispatcherLock( sal_False );
263 
264 						SwitchToDocument();
265 						GetBindings().GetDispatcher()->Execute( SID_SOLVE,
266 												  SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
267 												  &aOutItem, 0L, 0L );
268 						Close();
269 					}
270 					else RaiseError( SOLVERR_NOFORMULA );
271 				}
272 				else RaiseError( SOLVERR_INVALID_TARGETVALUE );
273 			}
274 			else RaiseError( SOLVERR_INVALID_VARIABLE );
275 		}
276 		else RaiseError( SOLVERR_INVALID_FORMULA );
277 	}
278 	else if ( pBtn == &aBtnCancel )
279 	{
280 		Close();
281 	}
282 
283 	return 0;
284 }
285 
286 //----------------------------------------------------------------------------
287 
288 IMPL_LINK( ScSolverDlg, GetFocusHdl, Control*, pCtrl )
289 {
290     Edit* pEdit = NULL;
291     pEdActive = NULL;
292 
293     if( (pCtrl == (Control*)&aEdFormulaCell) || (pCtrl == (Control*)&aRBFormulaCell) )
294         pEdit = pEdActive = &aEdFormulaCell;
295     else if( (pCtrl == (Control*)&aEdVariableCell) || (pCtrl == (Control*)&aRBVariableCell) )
296         pEdit = pEdActive = &aEdVariableCell;
297     else if( pCtrl == (Control*)&aEdTargetVal )
298         pEdit = &aEdTargetVal;
299 
300     if( pEdit )
301         pEdit->SetSelection( Selection( 0, SELECTION_MAX ) );
302 
303 	return 0;
304 }
305 
306 //----------------------------------------------------------------------------
307 
308 IMPL_LINK( ScSolverDlg, LoseFocusHdl, Control*, EMPTYARG )
309 {
310 	bDlgLostFocus = !IsActive();
311 	return 0;
312 }
313 
314 
315 
316 
317