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