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