LibreOffice Module sc (master)  1
tabopdlg.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 <sfx2/dispatch.hxx>
21 #include <vcl/svapp.hxx>
22 #include <vcl/weld.hxx>
23 
24 #include <uiitems.hxx>
25 #include <document.hxx>
26 #include <scresid.hxx>
27 #include <sc.hrc>
28 #include <strings.hrc>
29 #include <reffact.hxx>
30 
31 #include <tabopdlg.hxx>
32 
33 
35  ScDocument* pDocument,
36  const ScRefAddress& rCursorPos )
37  : ScAnyRefDlgController(pB, pCW, pParent, "modules/scalc/ui/multipleoperationsdialog.ui",
38  "MultipleOperationsDialog")
39  , theFormulaCell(rCursorPos)
40  , pDoc(pDocument)
41  , nCurTab(theFormulaCell.Tab())
42  , bDlgLostFocus(false)
43  , errMsgNoFormula(ScResId(STR_NOFORMULASPECIFIED))
44  , errMsgNoColRow(ScResId(STR_NOCOLROW))
45  , errMsgWrongFormula(ScResId(STR_WRONGFORMULA))
46  , errMsgWrongRowCol(ScResId(STR_WRONGROWCOL))
47  , errMsgNoColFormula(ScResId(STR_NOCOLFORMULA))
48  , errMsgNoRowFormula(ScResId(STR_NOROWFORMULA))
49  , m_pEdActive(nullptr)
50  , m_xFtFormulaRange(m_xBuilder->weld_label("formulasft"))
51  , m_xEdFormulaRange(new formula::RefEdit(m_xBuilder->weld_entry("formulas")))
52  , m_xRBFormulaRange(new formula::RefButton(m_xBuilder->weld_button("formulasref")))
53  , m_xFtRowCell(m_xBuilder->weld_label("rowft"))
54  , m_xEdRowCell(new formula::RefEdit(m_xBuilder->weld_entry("row")))
55  , m_xRBRowCell(new formula::RefButton(m_xBuilder->weld_button("rowref")))
56  , m_xFtColCell(m_xBuilder->weld_label("colft"))
57  , m_xEdColCell(new formula::RefEdit(m_xBuilder->weld_entry("col")))
58  , m_xRBColCell(new formula::RefButton(m_xBuilder->weld_button("colref")))
59  , m_xBtnOk(m_xBuilder->weld_button("ok"))
60  , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
61 {
62  m_xEdFormulaRange->SetReferences(this, m_xFtFormulaRange.get());
63  m_xRBFormulaRange->SetReferences(this, m_xEdFormulaRange.get());
64 
65  m_xEdRowCell->SetReferences(this, m_xFtRowCell.get());
66  m_xRBRowCell->SetReferences(this, m_xEdRowCell.get());
67 
68  m_xEdColCell->SetReferences(this, m_xFtColCell.get());
69  m_xRBColCell->SetReferences(this, m_xEdColCell.get());
70 
71  Init();
72 }
73 
75 {
76 }
77 
79 {
80  m_xBtnOk->connect_clicked( LINK( this, ScTabOpDlg, BtnHdl ) );
81  m_xBtnCancel->connect_clicked( LINK( this, ScTabOpDlg, BtnHdl ) );
82 
83  Link<formula::RefEdit&,void> aEditLink = LINK( this, ScTabOpDlg, GetEditFocusHdl );
84  m_xEdFormulaRange->SetGetFocusHdl( aEditLink );
85  m_xEdRowCell->SetGetFocusHdl( aEditLink );
86  m_xEdColCell->SetGetFocusHdl( aEditLink );
87 
88  Link<formula::RefButton&,void> aButtonLink = LINK( this, ScTabOpDlg, GetButtonFocusHdl );
89  m_xRBFormulaRange->SetGetFocusHdl( aButtonLink );
90  m_xRBRowCell->SetGetFocusHdl( aButtonLink );
91  m_xRBColCell->SetGetFocusHdl( aButtonLink );
92 
93  aEditLink = LINK( this, ScTabOpDlg, LoseEditFocusHdl );
94  m_xEdFormulaRange->SetLoseFocusHdl( aEditLink );
95  m_xEdRowCell->SetLoseFocusHdl( aEditLink );
96  m_xEdColCell->SetLoseFocusHdl( aEditLink );
97 
98  aButtonLink = LINK( this, ScTabOpDlg, LoseButtonFocusHdl );
99  m_xRBFormulaRange->SetLoseFocusHdl( aButtonLink );
100  m_xRBRowCell->SetLoseFocusHdl( aButtonLink );
101  m_xRBColCell->SetLoseFocusHdl( aButtonLink );
102 
103  m_xEdFormulaRange->GrabFocus();
105 }
106 
108 {
109  DoClose( ScTabOpDlgWrapper::GetChildWindowId() );
110 }
111 
113 {
114  if ( bDlgLostFocus )
115  {
116  bDlgLostFocus = false;
117  if (m_pEdActive)
119  }
120  else
121  m_xDialog->grab_focus();
122 
123  RefInputDone();
124 }
125 
126 void ScTabOpDlg::SetReference( const ScRange& rRef, ScDocument& rDocP )
127 {
128  if (m_pEdActive)
129  {
130  ScAddress::Details aDetails(rDocP.GetAddressConvention(), 0, 0);
131 
132  if ( rRef.aStart != rRef.aEnd )
134 
135  OUString aStr;
136  ScRefFlags nFmt = ( rRef.aStart.Tab() == nCurTab )
139 
140  if (m_pEdActive == m_xEdFormulaRange.get())
141  {
142  theFormulaCell.Set( rRef.aStart, false, false, false);
143  theFormulaEnd.Set( rRef.aEnd, false, false, false);
144  aStr = rRef.Format(rDocP, nFmt, aDetails);
145  }
146  else if (m_pEdActive == m_xEdRowCell.get())
147  {
148  theRowCell.Set( rRef.aStart, false, false, false);
149  aStr = rRef.aStart.Format(nFmt, &rDocP, aDetails);
150  }
151  else if (m_pEdActive == m_xEdColCell.get())
152  {
153  theColCell.Set( rRef.aStart, false, false, false);
154  aStr = rRef.aStart.Format(nFmt, &rDocP, aDetails);
155  }
156 
157  m_pEdActive->SetRefString( aStr );
158  }
159 }
160 
162 {
163  const OUString* pMsg = &errMsgNoFormula;
164  formula::RefEdit* pEd = m_xEdFormulaRange.get();
165 
166  switch ( eError )
167  {
168  case TABOPERR_NOFORMULA:
169  pMsg = &errMsgNoFormula;
170  pEd = m_xEdFormulaRange.get();
171  break;
172 
173  case TABOPERR_NOCOLROW:
174  pMsg = &errMsgNoColRow;
175  pEd = m_xEdRowCell.get();
176  break;
177 
179  pMsg = &errMsgWrongFormula;
180  pEd = m_xEdFormulaRange.get();
181  break;
182 
183  case TABOPERR_WRONGROW:
184  pMsg = &errMsgWrongRowCol;
185  pEd = m_xEdRowCell.get();
186  break;
187 
189  pMsg = &errMsgNoColFormula;
190  pEd = m_xEdFormulaRange.get();
191  break;
192 
193  case TABOPERR_WRONGCOL:
194  pMsg = &errMsgWrongRowCol;
195  pEd = m_xEdColCell.get();
196  break;
197 
199  pMsg = &errMsgNoRowFormula;
200  pEd = m_xEdFormulaRange.get();
201  break;
202  }
203 
204  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
205  VclMessageType::Error, VclButtonsType::OkCancel, *pMsg));
206  xBox->run();
207  pEd->GrabFocus();
208 }
209 
210 static bool lcl_Parse( const OUString& rString, const ScDocument* pDoc, SCTAB nCurTab,
211  ScRefAddress& rStart, ScRefAddress& rEnd )
212 {
213  bool bRet = false;
215  if ( rString.indexOf(':') != -1 )
216  bRet = ConvertDoubleRef( pDoc, rString, nCurTab, rStart, rEnd, eConv );
217  else
218  {
219  bRet = ConvertSingleRef( pDoc, rString, nCurTab, rStart, eConv );
220  rEnd = rStart;
221  }
222  return bRet;
223 }
224 
225 // Handler:
226 
227 IMPL_LINK(ScTabOpDlg, BtnHdl, weld::Button&, rBtn, void)
228 {
229  if (&rBtn == m_xBtnOk.get())
230  {
232  sal_uInt16 nError = 0;
233 
234  // The following code checks:
235  // 1. do the strings contain correct cell references / defined names?
236  // 2. is formula range row if row is empty or column if column is empty
237  // or single reference if both?
238  // 3. is at least one of row or column non-empty?
239 
240  if (m_xEdFormulaRange->GetText().isEmpty())
241  nError = TABOPERR_NOFORMULA;
242  else if (m_xEdRowCell->GetText().isEmpty() &&
243  m_xEdColCell->GetText().isEmpty())
244  nError = TABOPERR_NOCOLROW;
245  else if ( !lcl_Parse( m_xEdFormulaRange->GetText(), pDoc, nCurTab,
246  theFormulaCell, theFormulaEnd ) )
247  nError = TABOPERR_WRONGFORMULA;
248  else
249  {
250  const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
251  if (!m_xEdRowCell->GetText().isEmpty())
252  {
253  if (!ConvertSingleRef( pDoc, m_xEdRowCell->GetText(), nCurTab,
254  theRowCell, eConv ))
255  nError = TABOPERR_WRONGROW;
256  else
257  {
258  if (m_xEdColCell->GetText().isEmpty() &&
259  theFormulaCell.Col() != theFormulaEnd.Col())
260  nError = TABOPERR_NOCOLFORMULA;
261  else
262  eMode = ScTabOpParam::Row;
263  }
264  }
265  if (!m_xEdColCell->GetText().isEmpty())
266  {
267  if (!ConvertSingleRef( pDoc, m_xEdColCell->GetText(), nCurTab,
268  theColCell, eConv ))
269  nError = TABOPERR_WRONGCOL;
270  else
271  {
272  if (eMode == ScTabOpParam::Row) // both
273  {
274  eMode = ScTabOpParam::Both;
275  ConvertSingleRef( pDoc, m_xEdFormulaRange->GetText(), nCurTab,
276  theFormulaCell, eConv );
277  }
278  else if (theFormulaCell.Row() != theFormulaEnd.Row())
279  nError = TABOPERR_NOROWFORMULA;
280  else
281  eMode = ScTabOpParam::Column;
282  }
283  }
284  }
285 
286  if (nError)
287  RaiseError( static_cast<ScTabOpErr>(nError) );
288  else
289  {
290  ScTabOpParam aOutParam(theFormulaCell, theFormulaEnd, theRowCell, theColCell, eMode);
291  ScTabOpItem aOutItem( SID_TABOP, &aOutParam );
292 
293  SetDispatcherLock( false );
294  SwitchToDocument();
295  GetBindings().GetDispatcher()->ExecuteList(SID_TABOP,
296  SfxCallMode::SLOT | SfxCallMode::RECORD,
297  { &aOutItem });
298  response(RET_OK);
299  }
300  }
301  else if (&rBtn == m_xBtnCancel.get())
302  response(RET_CANCEL);
303 }
304 
305 IMPL_LINK( ScTabOpDlg, GetEditFocusHdl, formula::RefEdit&, rCtrl, void )
306 {
307  if (&rCtrl == m_xEdFormulaRange.get())
308  m_pEdActive = m_xEdFormulaRange.get();
309  else if (&rCtrl == m_xEdRowCell.get())
310  m_pEdActive = m_xEdRowCell.get();
311  else if (&rCtrl == m_xEdColCell.get())
312  m_pEdActive = m_xEdColCell.get();
313  else
314  m_pEdActive = nullptr;
315 
316  if( m_pEdActive )
317  m_pEdActive->SelectAll();
318 }
319 
320 IMPL_LINK( ScTabOpDlg, GetButtonFocusHdl, formula::RefButton&, rCtrl, void )
321 {
322  if (&rCtrl == m_xRBFormulaRange.get())
323  m_pEdActive = m_xEdFormulaRange.get();
324  else if (&rCtrl == m_xRBRowCell.get())
325  m_pEdActive = m_xEdRowCell.get();
326  else if (&rCtrl == m_xRBColCell.get())
327  m_pEdActive = m_xEdColCell.get();
328  else
329  m_pEdActive = nullptr;
330 
331  if( m_pEdActive )
332  m_pEdActive->SelectAll();
333 }
334 
335 IMPL_LINK_NOARG(ScTabOpDlg, LoseEditFocusHdl, formula::RefEdit&, void)
336 {
337  bDlgLostFocus = !m_xDialog->has_toplevel_focus();
338 }
339 
340 IMPL_LINK_NOARG(ScTabOpDlg, LoseButtonFocusHdl, formula::RefButton&, void)
341 {
342  bDlgLostFocus = !m_xDialog->has_toplevel_focus();
343 }
344 
345 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool ConvertSingleRef(const ScDocument *pDoc, const OUString &rRefString, SCTAB nDefTab, ScRefAddress &rRefAddress, const ScAddress::Details &rDetails, ScAddress::ExternalInfo *pExtInfo)
Definition: address.cxx:1495
void Set(const ScAddress &rAdr, bool bNewRelCol, bool bNewRelRow, bool bNewRelTab)
Definition: address.hxx:921
IMPL_LINK(ScTabOpDlg, BtnHdl, weld::Button &, rBtn, void)
Definition: tabopdlg.cxx:227
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2111
ScAddress aStart
Definition: address.hxx:500
static bool lcl_Parse(const OUString &rString, const ScDocument *pDoc, SCTAB nCurTab, ScRefAddress &rStart, ScRefAddress &rEnd)
Definition: tabopdlg.cxx:210
ScRefAddress theRowCell
Definition: tabopdlg.hxx:54
ScTabOpDlg(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScDocument *pDocument, const ScRefAddress &rCursorPos)
Definition: tabopdlg.cxx:34
ScAddress aEnd
Definition: address.hxx:501
const OUString errMsgWrongFormula
Definition: tabopdlg.hxx:62
RET_CANCEL
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:475
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
Definition: tabopdlg.cxx:126
bool bDlgLostFocus
Definition: tabopdlg.hxx:59
std::unique_ptr< formula::RefButton > m_xRBFormulaRange
Definition: tabopdlg.hxx:70
formula::RefEdit * m_pEdActive
Definition: tabopdlg.hxx:67
std::unique_ptr< weld::Button > m_xBtnCancel
Definition: tabopdlg.hxx:81
ScRefAddress theColCell
Definition: tabopdlg.hxx:55
std::unique_ptr< formula::RefEdit > m_xEdFormulaRange
Definition: tabopdlg.hxx:69
Mode eMode
SCTAB Tab() const
Definition: address.hxx:271
ScTabOpErr
Definition: tabopdlg.hxx:26
std::unique_ptr< weld::Label > m_xFtRowCell
Definition: tabopdlg.hxx:72
void RaiseError(ScTabOpErr eError)
Definition: tabopdlg.cxx:161
std::unique_ptr< weld::Label > m_xFtFormulaRange
Definition: tabopdlg.hxx:68
bool ConvertDoubleRef(const ScDocument *pDoc, const OUString &rRefString, SCTAB nDefTab, ScRefAddress &rStartRefAddress, ScRefAddress &rEndRefAddress, const ScAddress::Details &rDetails, ScAddress::ExternalInfo *pExtInfo)
Definition: address.cxx:1517
void SetRefString(const OUString &rStr)
Parameter for data table aka multiple operations.
Definition: paramisc.hxx:46
ScRefAddress theFormulaCell
Definition: tabopdlg.hxx:52
std::unique_ptr< weld::Button > m_xBtnOk
Definition: tabopdlg.hxx:80
SC_DLLPUBLIC OUString Format(const ScDocument &rDocument, ScRefFlags nFlags=ScRefFlags::ZERO, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, bool bFullAddressNotation=false) const
Returns string with formatted cell range from aStart to aEnd, according to provided address conventio...
Definition: address.cxx:2207
const OUString errMsgNoRowFormula
Definition: tabopdlg.hxx:65
virtual void Close() override
Definition: tabopdlg.cxx:107
OUString ScResId(const char *pId)
Definition: scdll.cxx:95
const OUString errMsgNoColRow
Definition: tabopdlg.hxx:61
const SCTAB nCurTab
Definition: tabopdlg.hxx:58
virtual void RefInputDone(bool bForced=false) override
Definition: anyrefdg.cxx:755
std::unique_ptr< formula::RefEdit > m_xEdRowCell
Definition: tabopdlg.hxx:73
std::unique_ptr< formula::RefButton > m_xRBRowCell
Definition: tabopdlg.hxx:74
std::unique_ptr< weld::Label > m_xFtColCell
Definition: tabopdlg.hxx:76
RET_OK
const OUString errMsgNoFormula
Definition: tabopdlg.hxx:60
virtual ~ScTabOpDlg() override
Definition: tabopdlg.cxx:74
const OUString errMsgNoColFormula
Definition: tabopdlg.hxx:64
Reference< XExecutableDialog > m_xDialog
std::unique_ptr< formula::RefButton > m_xRBColCell
Definition: tabopdlg.hxx:78
std::unique_ptr< formula::RefEdit > m_xEdColCell
Definition: tabopdlg.hxx:77
void Init()
Definition: tabopdlg.cxx:78
virtual void SetActive() override
Definition: tabopdlg.cxx:112
ScRefFlags
Definition: address.hxx:145
bool DoClose(sal_uInt16 nId)
Definition: anyrefdg.cxx:694
IMPL_LINK_NOARG(ScTabOpDlg, LoseEditFocusHdl, formula::RefEdit &, void)
Definition: tabopdlg.cxx:335
aStr
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
const OUString errMsgWrongRowCol
Definition: tabopdlg.hxx:63
sal_Int16 SCTAB
Definition: types.hxx:23
ScRefAddress theFormulaEnd
Definition: tabopdlg.hxx:53
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
Definition: anyrefdg.cxx:725