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/dispatch.hxx>
23 : #include <svl/zforlist.hxx>
24 : #include <vcl/msgbox.hxx>
25 :
26 : #include "uiitems.hxx"
27 : #include "reffact.hxx"
28 : #include "document.hxx"
29 : #include "scresid.hxx"
30 : #include "globstr.hrc"
31 : #include "sc.hrc"
32 :
33 : #define _SOLVRDLG_CXX
34 : #include "solvrdlg.hxx"
35 : #undef _SOLVRDLG_CXX
36 :
37 : namespace
38 : {
39 0 : void lclErrorDialog( Window* pParent, const OUString& aString )
40 : {
41 0 : ErrorBox( pParent, WinBits( WB_OK | WB_DEF_OK), aString ).Execute();
42 0 : }
43 : }
44 :
45 0 : ScSolverDlg::ScSolverDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
46 : ScDocument* pDocument,
47 : ScAddress aCursorPos )
48 :
49 : : ScAnyRefDlg(pB, pCW, pParent, "GoalSeekDialog", "modules/scalc/ui/goalseekdlg.ui")
50 : , theFormulaCell(aCursorPos)
51 : , theVariableCell(aCursorPos)
52 : , pDoc(pDocument)
53 0 : , nCurTab(aCursorPos.Tab())
54 : , pEdActive(NULL)
55 : , bDlgLostFocus(false)
56 0 : , errMsgInvalidVar(ScGlobal::GetRscString(STR_INVALIDVAR))
57 0 : , errMsgInvalidForm(ScGlobal::GetRscString(STR_INVALIDFORM))
58 0 : , errMsgNoFormula(ScGlobal::GetRscString(STR_NOFORMULA))
59 0 : , errMsgInvalidVal(ScGlobal::GetRscString(STR_INVALIDVAL))
60 : {
61 0 : get(m_pFtFormulaCell, "formulatext");
62 0 : get(m_pEdFormulaCell, "formulaedit");
63 0 : m_pEdFormulaCell->SetReferences(this, m_pFtFormulaCell);
64 0 : get(m_pRBFormulaCell, "formulabutton");
65 0 : m_pRBFormulaCell->SetReferences(this, m_pEdFormulaCell),
66 0 : get(m_pEdTargetVal, "target");
67 0 : get(m_pFtVariableCell, "vartext");
68 0 : get(m_pEdVariableCell, "varedit");
69 0 : m_pEdVariableCell->SetReferences(this, m_pFtVariableCell);
70 0 : get(m_pRBVariableCell, "varbutton");
71 0 : m_pRBVariableCell->SetReferences(this, m_pEdVariableCell);
72 0 : get(m_pBtnOk, "ok");
73 0 : get(m_pBtnCancel, "cancel");
74 0 : Init();
75 0 : }
76 :
77 0 : ScSolverDlg::~ScSolverDlg()
78 : {
79 0 : }
80 :
81 0 : void ScSolverDlg::Init()
82 : {
83 0 : m_pBtnOk->SetClickHdl( LINK( this, ScSolverDlg, BtnHdl ) );
84 0 : m_pBtnCancel->SetClickHdl( LINK( this, ScSolverDlg, BtnHdl ) );
85 :
86 0 : Link aLink = LINK( this, ScSolverDlg, GetFocusHdl );
87 0 : m_pEdFormulaCell->SetGetFocusHdl( aLink );
88 0 : m_pRBFormulaCell->SetGetFocusHdl( aLink );
89 0 : m_pEdVariableCell->SetGetFocusHdl( aLink );
90 0 : m_pRBVariableCell->SetGetFocusHdl( aLink );
91 0 : m_pEdTargetVal->SetGetFocusHdl( aLink );
92 :
93 0 : aLink = LINK( this, ScSolverDlg, LoseFocusHdl );
94 0 : m_pEdFormulaCell->SetLoseFocusHdl ( aLink );
95 0 : m_pRBFormulaCell->SetLoseFocusHdl ( aLink );
96 0 : m_pEdVariableCell->SetLoseFocusHdl ( aLink );
97 0 : m_pRBVariableCell->SetLoseFocusHdl ( aLink );
98 :
99 0 : OUString aStr(theFormulaCell.Format(SCA_ABS, NULL, pDoc->GetAddressConvention()));
100 :
101 0 : m_pEdFormulaCell->SetText( aStr );
102 0 : m_pEdFormulaCell->GrabFocus();
103 0 : pEdActive = m_pEdFormulaCell;
104 0 : }
105 :
106 0 : bool ScSolverDlg::Close()
107 : {
108 0 : return DoClose( ScSolverDlgWrapper::GetChildWindowId() );
109 : }
110 :
111 0 : void ScSolverDlg::SetActive()
112 : {
113 0 : if ( bDlgLostFocus )
114 : {
115 0 : bDlgLostFocus = false;
116 0 : if( pEdActive )
117 0 : pEdActive->GrabFocus();
118 : }
119 : else
120 : {
121 0 : GrabFocus();
122 : }
123 0 : RefInputDone();
124 0 : }
125 :
126 0 : void ScSolverDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
127 : {
128 0 : if( pEdActive )
129 : {
130 0 : if ( rRef.aStart != rRef.aEnd )
131 0 : RefInputStart(pEdActive);
132 :
133 0 : ScAddress aAdr = rRef.aStart;
134 0 : sal_uInt16 nFmt = ( aAdr.Tab() == nCurTab )
135 : ? SCA_ABS
136 0 : : SCA_ABS_3D;
137 :
138 0 : OUString aStr(aAdr.Format(nFmt, pDocP, pDocP->GetAddressConvention()));
139 0 : pEdActive->SetRefString( aStr );
140 :
141 0 : if ( pEdActive == m_pEdFormulaCell )
142 0 : theFormulaCell = aAdr;
143 0 : else if ( pEdActive == m_pEdVariableCell )
144 0 : theVariableCell = aAdr;
145 : }
146 0 : }
147 :
148 0 : void ScSolverDlg::RaiseError( ScSolverErr eError )
149 : {
150 0 : switch ( eError )
151 : {
152 : case SOLVERR_NOFORMULA:
153 0 : lclErrorDialog( this, errMsgNoFormula );
154 0 : m_pEdFormulaCell->GrabFocus();
155 0 : break;
156 :
157 : case SOLVERR_INVALID_FORMULA:
158 0 : lclErrorDialog( this, errMsgInvalidForm );
159 0 : m_pEdFormulaCell->GrabFocus();
160 0 : break;
161 :
162 : case SOLVERR_INVALID_VARIABLE:
163 0 : lclErrorDialog( this, errMsgInvalidVar );
164 0 : m_pEdVariableCell->GrabFocus();
165 0 : break;
166 :
167 : case SOLVERR_INVALID_TARGETVALUE:
168 0 : lclErrorDialog( this, errMsgInvalidVal );
169 0 : m_pEdTargetVal->GrabFocus();
170 0 : break;
171 : }
172 0 : }
173 :
174 0 : bool ScSolverDlg::IsRefInputMode() const
175 : {
176 0 : return pEdActive != NULL;
177 : }
178 :
179 0 : bool ScSolverDlg::CheckTargetValue( const OUString& rStrVal )
180 : {
181 0 : sal_uInt32 n1 = 0;
182 : double n2;
183 :
184 0 : return pDoc->GetFormatTable()->IsNumberFormat( rStrVal, n1, n2 );
185 : }
186 :
187 :
188 : // Handler:
189 :
190 0 : IMPL_LINK( ScSolverDlg, BtnHdl, PushButton*, pBtn )
191 : {
192 0 : if (pBtn == m_pBtnOk)
193 : {
194 0 : theTargetValStr = m_pEdTargetVal->GetText();
195 :
196 : // Zu ueberpruefen:
197 : // 1. enthalten die Strings korrekte Tabellenkoordinaten/def.Namen?
198 : // 2. verweist die Formel-Koordinate wirklich auf eine Formelzelle?
199 : // 3. wurde ein korrekter Zielwert eingegeben
200 :
201 0 : const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
202 0 : sal_uInt16 nRes1 = theFormulaCell .Parse( m_pEdFormulaCell->GetText(), pDoc, eConv );
203 0 : sal_uInt16 nRes2 = theVariableCell.Parse( m_pEdVariableCell->GetText(), pDoc, eConv );
204 :
205 0 : if ( SCA_VALID == ( nRes1 & SCA_VALID ) )
206 : {
207 0 : if ( SCA_VALID == ( nRes2 & SCA_VALID ) )
208 : {
209 0 : if ( CheckTargetValue( theTargetValStr ) )
210 : {
211 : CellType eType;
212 0 : pDoc->GetCellType( theFormulaCell.Col(),
213 : theFormulaCell.Row(),
214 0 : theFormulaCell.Tab(),
215 0 : eType );
216 :
217 0 : if ( CELLTYPE_FORMULA == eType )
218 : {
219 : ScSolveParam aOutParam( theFormulaCell,
220 : theVariableCell,
221 0 : theTargetValStr );
222 0 : ScSolveItem aOutItem( SCITEM_SOLVEDATA, &aOutParam );
223 :
224 0 : SetDispatcherLock( false );
225 :
226 0 : SwitchToDocument();
227 0 : GetBindings().GetDispatcher()->Execute( SID_SOLVE,
228 : SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
229 0 : &aOutItem, 0L, 0L );
230 0 : Close();
231 : }
232 0 : else RaiseError( SOLVERR_NOFORMULA );
233 : }
234 0 : else RaiseError( SOLVERR_INVALID_TARGETVALUE );
235 : }
236 0 : else RaiseError( SOLVERR_INVALID_VARIABLE );
237 : }
238 0 : else RaiseError( SOLVERR_INVALID_FORMULA );
239 : }
240 0 : else if (pBtn == m_pBtnCancel)
241 : {
242 0 : Close();
243 : }
244 :
245 0 : return 0;
246 : }
247 :
248 0 : IMPL_LINK( ScSolverDlg, GetFocusHdl, Control*, pCtrl )
249 : {
250 0 : Edit* pEdit = NULL;
251 0 : pEdActive = NULL;
252 :
253 0 : if( (pCtrl == (Control*)m_pEdFormulaCell) || (pCtrl == (Control*)m_pRBFormulaCell) )
254 0 : pEdit = pEdActive = m_pEdFormulaCell;
255 0 : else if( (pCtrl == (Control*)m_pEdVariableCell) || (pCtrl == (Control*)m_pRBVariableCell) )
256 0 : pEdit = pEdActive = m_pEdVariableCell;
257 0 : else if( pCtrl == (Control*)m_pEdTargetVal )
258 0 : pEdit = m_pEdTargetVal;
259 :
260 0 : if( pEdit )
261 0 : pEdit->SetSelection( Selection( 0, SELECTION_MAX ) );
262 :
263 0 : return 0;
264 : }
265 :
266 0 : IMPL_LINK_NOARG(ScSolverDlg, LoseFocusHdl)
267 : {
268 0 : bDlgLostFocus = !IsActive();
269 0 : return 0;
270 0 : }
271 :
272 :
273 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|