LibreOffice Module sc (master) 1
solvrdlg.cxx
Go to the documentation of this file.
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 <scitems.hxx>
21#include <sfx2/dispatch.hxx>
22#include <svl/numformat.hxx>
23#include <vcl/svapp.hxx>
24#include <vcl/weld.hxx>
25
26#include <uiitems.hxx>
27#include <reffact.hxx>
28#include <document.hxx>
29#include <globstr.hrc>
30#include <scresid.hxx>
31#include <sc.hrc>
32#include <solvrdlg.hxx>
33
35 ScDocument* pDocument,
36 const ScAddress& aCursorPos )
37
38 : ScAnyRefDlgController(pB, pCW, pParent, "modules/scalc/ui/goalseekdlg.ui", "GoalSeekDialog")
39 , theFormulaCell(aCursorPos)
40 , theVariableCell(aCursorPos)
41 , pDoc(pDocument)
42 , nCurTab(aCursorPos.Tab())
43 , bDlgLostFocus(false)
44 , errMsgInvalidVar(ScResId(STR_INVALIDVAR))
45 , errMsgInvalidForm(ScResId(STR_INVALIDFORM))
46 , errMsgNoFormula(ScResId(STR_NOFORMULA))
47 , errMsgInvalidVal(ScResId(STR_INVALIDVAL))
48 , m_pEdActive(nullptr)
49 , m_xFtFormulaCell(m_xBuilder->weld_label("formulatext"))
50 , m_xEdFormulaCell(new formula::RefEdit(m_xBuilder->weld_entry("formulaedit")))
51 , m_xRBFormulaCell(new formula::RefButton(m_xBuilder->weld_button("formulabutton")))
52 , m_xEdTargetVal(m_xBuilder->weld_entry("target"))
53 , m_xFtVariableCell(m_xBuilder->weld_label("vartext"))
54 , m_xEdVariableCell(new formula::RefEdit(m_xBuilder->weld_entry("varedit")))
55 , m_xRBVariableCell(new formula::RefButton(m_xBuilder->weld_button("varbutton")))
56 , m_xBtnOk(m_xBuilder->weld_button("ok"))
57 , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
58{
59 m_xEdFormulaCell->SetReferences(this, m_xFtFormulaCell.get());
60 m_xRBFormulaCell->SetReferences(this, m_xEdFormulaCell.get());
61 m_xEdVariableCell->SetReferences(this, m_xFtVariableCell.get());
62 m_xRBVariableCell->SetReferences(this, m_xEdVariableCell.get());
63 Init();
64}
65
67{
68 if (m_xMessageBox)
69 m_xMessageBox->response(RET_CANCEL);
70 assert(!m_xMessageBox);
71}
72
74{
75 m_xBtnOk->connect_clicked( LINK( this, ScSolverDlg, BtnHdl ) );
76 m_xBtnCancel->connect_clicked( LINK( this, ScSolverDlg, BtnHdl ) );
77
78 Link<formula::RefEdit&,void> aEditLink = LINK( this, ScSolverDlg, GetEditFocusHdl );
79 m_xEdFormulaCell->SetGetFocusHdl( aEditLink );
80 m_xEdVariableCell->SetGetFocusHdl( aEditLink );
81
82 Link<formula::RefButton&,void> aButtonLink = LINK( this, ScSolverDlg, GetButtonFocusHdl );
83 m_xRBFormulaCell->SetGetFocusHdl( aButtonLink );
84 m_xRBVariableCell->SetGetFocusHdl( aButtonLink );
85
86 m_xEdTargetVal->connect_focus_in(LINK(this, ScSolverDlg, GetFocusHdl));
87
88 aEditLink = LINK( this, ScSolverDlg, LoseEditFocusHdl );
89 m_xEdFormulaCell->SetLoseFocusHdl ( aEditLink );
90 m_xEdVariableCell->SetLoseFocusHdl ( aEditLink );
91
92 aButtonLink = LINK( this, ScSolverDlg, LoseButtonFocusHdl );
93 m_xRBFormulaCell->SetLoseFocusHdl ( aButtonLink );
94 m_xRBVariableCell->SetLoseFocusHdl ( aButtonLink );
95
97
98 m_xEdFormulaCell->SetText( aStr );
99 m_xEdFormulaCell->GrabFocus();
101}
102
104{
105 DoClose( ScSolverDlgWrapper::GetChildWindowId() );
106}
107
109{
110 if ( bDlgLostFocus )
111 {
112 bDlgLostFocus = false;
113 if( m_pEdActive )
115 }
116 else
117 {
118 m_xDialog->grab_focus();
119 }
120 RefInputDone();
121}
122
124{
125 if( !m_pEdActive )
126 return;
127
128 if ( rRef.aStart != rRef.aEnd )
130
131 ScAddress aAdr = rRef.aStart;
132 ScRefFlags nFmt = ( aAdr.Tab() == nCurTab )
135
136 OUString aStr(aAdr.Format(nFmt, &rDocP, rDocP.GetAddressConvention()));
138
139 if (m_pEdActive == m_xEdFormulaCell.get())
140 theFormulaCell = aAdr;
141 else if (m_pEdActive == m_xEdVariableCell.get())
142 theVariableCell = aAdr;
143}
144
146{
147 OUString sMessage;
148
149 switch (eError)
150 {
153 break;
156 break;
159 break;
162 break;
163 }
164
166 VclMessageType::Warning, VclButtonsType::Ok,
167 sMessage));
168 m_xMessageBox->runAsync(m_xMessageBox, [this](sal_Int32 /*nResult*/) {
169 m_xEdTargetVal->grab_focus();
170 m_xMessageBox.reset();
171 });
172}
173
175{
176 return m_pEdActive != nullptr;
177}
178
179bool ScSolverDlg::CheckTargetValue( const OUString& rStrVal )
180{
181 sal_uInt32 n1 = 0;
182 double n2;
183
184 return pDoc->GetFormatTable()->IsNumberFormat( rStrVal, n1, n2 );
185}
186
187// Handler:
188
189IMPL_LINK(ScSolverDlg, BtnHdl, weld::Button&, rBtn, void)
190{
191 if (&rBtn == m_xBtnOk.get())
192 {
193 theTargetValStr = m_xEdTargetVal->get_text();
194
195 // The following code checks:
196 // 1. do the strings contain correct references / defined names?
197 // 2. does the formula coordinate refer to a cell containing a formula?
198 // 3. has a valid target value been entered?
199
200 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
201 ScRefFlags nRes1 = theFormulaCell .Parse( m_xEdFormulaCell->GetText(), *pDoc, eConv );
202 ScRefFlags nRes2 = theVariableCell.Parse( m_xEdVariableCell->GetText(), *pDoc, eConv );
203
204 if ( (nRes1 & ScRefFlags::VALID) == ScRefFlags::VALID )
205 {
206 if ( (nRes2 & ScRefFlags::VALID) == ScRefFlags::VALID )
207 {
208 if ( CheckTargetValue( theTargetValStr ) )
209 {
210 CellType eType = pDoc->GetCellType( theFormulaCell.Col(),
211 theFormulaCell.Row(),
212 theFormulaCell.Tab());
213
214 if ( CELLTYPE_FORMULA == eType )
215 {
216 ScSolveParam aOutParam( theFormulaCell,
217 theVariableCell,
218 theTargetValStr );
219 ScSolveItem aOutItem( SCITEM_SOLVEDATA, &aOutParam );
220
221 SetDispatcherLock( false );
222
223 SwitchToDocument();
225 SfxCallMode::SLOT | SfxCallMode::RECORD,
226 { &aOutItem });
227 response(RET_OK);
228 }
229 else RaiseError( SOLVERR_NOFORMULA );
230 }
231 else RaiseError( SOLVERR_INVALID_TARGETVALUE );
232 }
233 else RaiseError( SOLVERR_INVALID_VARIABLE );
234 }
235 else RaiseError( SOLVERR_INVALID_FORMULA );
236 }
237 else if (&rBtn == m_xBtnCancel.get())
238 {
239 response(RET_CANCEL);
240 }
241}
242
243IMPL_LINK(ScSolverDlg, GetEditFocusHdl, formula::RefEdit&, rCtrl, void)
244{
245 if (&rCtrl == m_xEdFormulaCell.get())
246 m_pEdActive = m_xEdFormulaCell.get();
247 else if (&rCtrl == m_xEdVariableCell.get())
248 m_pEdActive = m_xEdVariableCell.get();
249
250 if (m_pEdActive)
251 m_pEdActive->SelectAll();
252}
253
255{
256 m_pEdActive = nullptr;
257 m_xEdTargetVal->select_region(0, -1);
258}
259
260IMPL_LINK(ScSolverDlg, GetButtonFocusHdl, formula::RefButton&, rCtrl, void)
261{
262 if (&rCtrl == m_xRBFormulaCell.get())
263 m_pEdActive = m_xEdFormulaCell.get();
264 else if (&rCtrl == m_xRBVariableCell.get())
265 m_pEdActive = m_xEdVariableCell.get();
266
267 if (m_pEdActive)
268 m_pEdActive->SelectAll();
269}
270
272{
273 bDlgLostFocus = !m_xDialog->has_toplevel_focus();
274}
275
277{
278 bDlgLostFocus = !m_xDialog->has_toplevel_focus();
279}
280
281
282/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScRefFlags
Definition: address.hxx:158
Reference< XExecutableDialog > m_xDialog
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
SCTAB Tab() const
Definition: address.hxx:283
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2074
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:502
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:460
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
Definition: anyrefdg.cxx:749
virtual void RefInputDone(bool bForced=false) override
Definition: anyrefdg.cxx:779
bool DoClose(sal_uInt16 nId)
Definition: anyrefdg.cxx:718
void Init()
Definition: solvrdlg.cxx:73
const SCTAB nCurTab
Definition: solvrdlg.hxx:52
formula::RefEdit * m_pEdActive
Definition: solvrdlg.hxx:59
const OUString errMsgInvalidVar
Definition: solvrdlg.hxx:54
std::unique_ptr< formula::RefEdit > m_xEdFormulaCell
Definition: solvrdlg.hxx:62
std::unique_ptr< weld::Button > m_xBtnCancel
Definition: solvrdlg.hxx:72
ScDocument * pDoc
Definition: solvrdlg.hxx:51
virtual ~ScSolverDlg() override
Definition: solvrdlg.cxx:66
std::shared_ptr< weld::MessageDialog > m_xMessageBox
Definition: solvrdlg.hxx:74
ScAddress theFormulaCell
Definition: solvrdlg.hxx:47
virtual bool IsRefInputMode() const override
Definition: solvrdlg.cxx:174
std::unique_ptr< weld::Button > m_xBtnOk
Definition: solvrdlg.hxx:71
std::unique_ptr< formula::RefEdit > m_xEdVariableCell
Definition: solvrdlg.hxx:68
std::unique_ptr< formula::RefButton > m_xRBVariableCell
Definition: solvrdlg.hxx:69
const OUString errMsgInvalidVal
Definition: solvrdlg.hxx:57
const OUString errMsgNoFormula
Definition: solvrdlg.hxx:56
bool bDlgLostFocus
Definition: solvrdlg.hxx:53
std::unique_ptr< weld::Label > m_xFtFormulaCell
Definition: solvrdlg.hxx:61
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
Definition: solvrdlg.cxx:123
virtual void Close() override
Definition: solvrdlg.cxx:103
std::unique_ptr< weld::Entry > m_xEdTargetVal
Definition: solvrdlg.hxx:65
virtual void SetActive() override
Definition: solvrdlg.cxx:108
ScAddress theVariableCell
Definition: solvrdlg.hxx:48
bool CheckTargetValue(const OUString &rStrVal)
Definition: solvrdlg.cxx:179
std::unique_ptr< formula::RefButton > m_xRBFormulaCell
Definition: solvrdlg.hxx:63
ScSolverDlg(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScDocument *pDocument, const ScAddress &aCursorPos)
Definition: solvrdlg.cxx:34
const OUString errMsgInvalidForm
Definition: solvrdlg.hxx:55
std::unique_ptr< weld::Label > m_xFtVariableCell
Definition: solvrdlg.hxx:67
void RaiseError(ScSolverErr eError)
Definition: solvrdlg.cxx:145
SfxDispatcher * GetDispatcher() const
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber, SvNumInputOptions eInputOptions=SvNumInputOptions::NONE)
void SetRefString(const OUString &rStr)
virtual SfxBindings & GetBindings() override
DocumentType eType
CellType
Definition: global.hxx:270
@ CELLTYPE_FORMULA
Definition: global.hxx:274
aStr
int n2
int n1
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
#define SCITEM_SOLVEDATA
Definition: scitems.hxx:95
IMPL_LINK(ScSolverDlg, BtnHdl, weld::Button &, rBtn, void)
Definition: solvrdlg.cxx:189
IMPL_LINK_NOARG(ScSolverDlg, GetFocusHdl, weld::Widget &, void)
Definition: solvrdlg.cxx:254
ScSolverErr
Definition: solvrdlg.hxx:26
@ SOLVERR_NOFORMULA
Definition: solvrdlg.hxx:27
@ SOLVERR_INVALID_VARIABLE
Definition: solvrdlg.hxx:29
@ SOLVERR_INVALID_FORMULA
Definition: solvrdlg.hxx:28
@ SOLVERR_INVALID_TARGETVALUE
Definition: solvrdlg.hxx:30
OUString sMessage
RET_OK
RET_CANCEL