LibreOffice Module sc (master)  1
namedefdlg.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 
10 #include <namedefdlg.hxx>
11 
12 #include <formula/errorcodes.hxx>
13 #include <sfx2/app.hxx>
14 #include <unotools/charclass.hxx>
15 
16 #include <compiler.hxx>
17 #include <document.hxx>
18 #include <globstr.hrc>
19 #include <scresid.hxx>
20 #include <globalnames.hxx>
21 #include <rangenam.hxx>
22 #include <reffact.hxx>
23 #include <undorangename.hxx>
24 #include <tabvwsh.hxx>
25 #include <tokenarray.hxx>
26 
28  const ScViewData& rViewData, const std::map<OUString, ScRangeName*>& aRangeMap,
29  const ScAddress& aCursorPos, const bool bUndo )
30  : ScAnyRefDlgController( pB, pCW, pParent, "modules/scalc/ui/definename.ui", "DefineNameDialog")
31  , mbUndo( bUndo )
32  , mrDoc(rViewData.GetDocument())
33  , mpDocShell ( rViewData.GetDocShell() )
34  , maCursorPos( aCursorPos )
35  , maGlobalNameStr ( ScResId(STR_GLOBAL_SCOPE) )
36  , maErrInvalidNameStr( ScResId(STR_ERR_NAME_INVALID))
37  , maErrInvalidNameCellRefStr( ScResId(STR_ERR_NAME_INVALID_CELL_REF))
38  , maErrNameInUse ( ScResId(STR_ERR_NAME_EXISTS))
39  , maRangeMap( aRangeMap )
40  , m_xEdName(m_xBuilder->weld_entry("edit"))
41  , m_xEdRange(new formula::RefEdit(m_xBuilder->weld_entry("range")))
42  , m_xRbRange(new formula::RefButton(m_xBuilder->weld_button("refbutton")))
43  , m_xLbScope(m_xBuilder->weld_combo_box("scope"))
44  , m_xBtnRowHeader(m_xBuilder->weld_check_button("rowheader"))
45  , m_xBtnColHeader(m_xBuilder->weld_check_button("colheader"))
46  , m_xBtnPrintArea(m_xBuilder->weld_check_button("printarea"))
47  , m_xBtnCriteria(m_xBuilder->weld_check_button("filter"))
48  , m_xBtnAdd(m_xBuilder->weld_button("add"))
49  , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
50  , m_xFtInfo(m_xBuilder->weld_label("label"))
51  , m_xExpander(m_xBuilder->weld_expander("more"))
52  , m_xFtRange(m_xBuilder->weld_label("label3"))
53 {
54  m_xEdRange->SetReferences(this, m_xFtRange.get());
55  m_xRbRange->SetReferences(this, m_xEdRange.get());
56  maStrInfoDefault = m_xFtInfo->get_label();
57 
58  // Initialize scope list.
59  m_xLbScope->append_text(maGlobalNameStr);
60  m_xLbScope->set_active(0);
62  for (SCTAB i = 0; i < n; ++i)
63  {
64  OUString aTabName;
65  mrDoc.GetName(i, aTabName);
66  m_xLbScope->append_text(aTabName);
67  }
68 
69  m_xBtnCancel->connect_clicked( LINK( this, ScNameDefDlg, CancelBtnHdl));
70  m_xBtnAdd->connect_clicked( LINK( this, ScNameDefDlg, AddBtnHdl ));
71  m_xEdName->connect_changed( LINK( this, ScNameDefDlg, NameModifyHdl ));
72  m_xEdRange->SetGetFocusHdl( LINK( this, ScNameDefDlg, AssignGetFocusHdl ) );
73 
74  m_xBtnAdd->set_sensitive(false); // empty name is invalid
75 
76  ScRange aRange;
77 
78  rViewData.GetSimpleArea( aRange );
79  OUString aAreaStr(aRange.Format(mrDoc, ScRefFlags::RANGE_ABS_3D,
81 
82  m_xEdRange->SetText( aAreaStr );
83 
84  m_xEdName->grab_focus();
85  m_xEdName->select_region(0, -1);
86 }
87 
89 {
90 }
91 
93 {
94  if (mbUndo)
95  response(RET_CANCEL);
96  else
97  {
99  pViewSh->SwitchBetweenRefDialogs(this);
100  }
101 }
102 
104 {
106  std::unique_ptr<ScTokenArray> pCode = aComp.CompileString(m_xEdRange->GetText());
107  if (pCode->GetCodeError() != FormulaError::NONE)
108  {
109  //TODO: info message
110  return false;
111  }
112  else
113  {
114  return true;
115  }
116 }
117 
119 {
120  OUString aScope = m_xLbScope->get_active_text();
121  OUString aName = m_xEdName->get_text();
122 
123  bool bIsNameValid = true;
124  OUString aHelpText = maStrInfoDefault;
125 
126  ScRangeName* pRangeName = nullptr;
127  if(aScope == maGlobalNameStr)
128  {
129  pRangeName = maRangeMap.find(OUString(STR_GLOBAL_RANGE_NAME))->second;
130  }
131  else
132  {
133  pRangeName = maRangeMap.find(aScope)->second;
134  }
135 
137  if ( aName.isEmpty() )
138  {
139  bIsNameValid = false;
140  }
141  else if ((eType = ScRangeData::IsNameValid(aName, mrDoc))
143  {
145  {
146  aHelpText = maErrInvalidNameStr;
147  }
149  {
150  aHelpText = maErrInvalidNameCellRefStr;
151  }
152  bIsNameValid = false;
153  }
154  else if (pRangeName->findByUpperName(ScGlobal::getCharClassPtr()->uppercase(aName)))
155  {
156  aHelpText = maErrNameInUse;
157  bIsNameValid = false;
158  }
159 
160  if (!IsFormulaValid())
161  {
162  bIsNameValid = false;
163  }
164 
165  m_xEdName->set_tooltip_text(aHelpText);
166  m_xEdName->set_message_type(bIsNameValid || aName.isEmpty() ? weld::EntryMessageType::Normal
168  m_xBtnAdd->set_sensitive(bIsNameValid);
169  return bIsNameValid;
170 }
171 
173 {
174  OUString aScope = m_xLbScope->get_active_text();
175  OUString aName = m_xEdName->get_text();
176  OUString aExpression = m_xEdRange->GetText();
177 
178  if (aName.isEmpty())
179  {
180  return;
181  }
182  if (aScope.isEmpty())
183  {
184  return;
185  }
186 
187  ScRangeName* pRangeName = nullptr;
188  if(aScope == maGlobalNameStr)
189  {
190  pRangeName = maRangeMap.find(OUString(STR_GLOBAL_RANGE_NAME))->second;
191  }
192  else
193  {
194  pRangeName = maRangeMap.find(aScope)->second;
195  }
196  if (!pRangeName)
197  return;
198 
199  if (!IsNameValid()) //should not happen, but make sure we don't break anything
200  return;
201  else
202  {
204 
205  ScRangeData* pNewEntry = new ScRangeData( mrDoc,
206  aName,
207  aExpression,
208  maCursorPos,
209  nType );
210 
211  if ( m_xBtnRowHeader->get_active() ) nType |= ScRangeData::Type::RowHeader;
212  if ( m_xBtnColHeader->get_active() ) nType |= ScRangeData::Type::ColHeader;
213  if ( m_xBtnPrintArea->get_active() ) nType |= ScRangeData::Type::PrintArea;
214  if ( m_xBtnCriteria->get_active() ) nType |= ScRangeData::Type::Criteria;
215 
216  pNewEntry->AddType(nType);
217 
218  // aExpression valid?
219  if ( FormulaError::NONE == pNewEntry->GetErrCode() )
220  {
221  if ( !pRangeName->insert( pNewEntry, false /*bReuseFreeIndex*/ ) )
222  pNewEntry = nullptr;
223 
224  if (mbUndo)
225  {
226  // this means we called directly through the menu
227 
228  SCTAB nTab;
229  // if no table with that name is found, assume global range name
230  if (!mrDoc.GetTable(aScope, nTab))
231  nTab = -1;
232 
233  assert( pNewEntry); // undo of no insertion smells fishy
234  if (pNewEntry)
236  std::make_unique<ScUndoAddRangeData>( mpDocShell, pNewEntry, nTab) );
237 
238  // set table stream invalid, otherwise RangeName won't be saved if no other
239  // call invalidates the stream
240  if (nTab != -1)
241  mrDoc.SetStreamValid(nTab, false);
242  SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
244  Close();
245  }
246  else
247  {
248  maName = aName;
249  maScope = aScope;
251  pViewSh->SwitchBetweenRefDialogs(this);
252  }
253  }
254  else
255  {
256  delete pNewEntry;
257  m_xEdRange->GrabFocus();
258  m_xEdRange->SelectAll();
259  }
260  }
261 }
262 
263 void ScNameDefDlg::GetNewData(OUString& rName, OUString& rScope)
264 {
265  rName = maName;
266  rScope = maScope;
267 }
268 
270 {
271  return m_xEdRange->GetWidget()->get_sensitive();
272 }
273 
274 void ScNameDefDlg::RefInputDone( bool bForced)
275 {
277  IsNameValid();
278 }
279 
280 void ScNameDefDlg::SetReference( const ScRange& rRef, ScDocument& rDocP )
281 {
282  if (m_xEdRange->GetWidget()->get_sensitive())
283  {
284  if ( rRef.aStart != rRef.aEnd )
285  RefInputStart(m_xEdRange.get());
286  OUString aRefStr(rRef.Format(rDocP, ScRefFlags::RANGE_ABS_3D,
287  ScAddress::Details(rDocP.GetAddressConvention(), 0, 0)));
288  m_xEdRange->SetRefString( aRefStr );
289  }
290 }
291 
293 {
294  DoClose( ScNameDefDlgWrapper::GetChildWindowId() );
295 }
296 
298 {
299  m_xEdRange->GrabFocus();
300  RefInputDone();
301 }
302 
304 {
305  CancelPushed();
306 }
307 
309 {
310  AddPushed();
311 };
312 
313 IMPL_LINK_NOARG(ScNameDefDlg, NameModifyHdl, weld::Entry&, void)
314 {
315  IsNameValid();
316 }
317 
318 IMPL_LINK_NOARG(ScNameDefDlg, AssignGetFocusHdl, formula::RefEdit&, void)
319 {
320  IsNameValid();
321 }
322 
323 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScAddress aStart
Definition: address.hxx:499
std::unique_ptr< weld::Button > m_xBtnCancel
Definition: namedefdlg.hxx:54
ScAddress maCursorPos
Definition: namedefdlg.hxx:28
sal_Int64 n
std::unique_ptr< ScTokenArray > CompileString(const OUString &rFormula)
Tokenize formula expression string into an array of tokens.
Definition: compiler.cxx:4542
void SetDocumentModified()
Definition: docsh.cxx:2820
const OUString maErrInvalidNameStr
Definition: namedefdlg.hxx:31
ScAddress aEnd
Definition: address.hxx:500
SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const
Definition: document.hxx:983
std::unique_ptr< weld::Label > m_xFtRange
Definition: namedefdlg.hxx:57
std::unique_ptr< weld::Label > m_xFtInfo
Definition: namedefdlg.hxx:55
RET_CANCEL
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:494
std::unique_ptr< weld::CheckButton > m_xBtnRowHeader
Definition: namedefdlg.hxx:48
std::unique_ptr< weld::Entry > m_xEdName
Definition: namedefdlg.hxx:41
ScNameDefDlg(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, const ScViewData &rViewData, const std::map< OUString, ScRangeName * > &aRangeMap, const ScAddress &aCursorPos, const bool bUndo)
Definition: namedefdlg.cxx:27
SfxApplication * SfxGetpApp()
bool IsFormulaValid()
Definition: namedefdlg.cxx:103
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2806
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:313
void GetNewData(OUString &rName, OUString &rScope)
Definition: namedefdlg.cxx:263
SC_DLLPUBLIC bool GetTable(const OUString &rName, SCTAB &rTab) const
Definition: document.cxx:259
OUString maStrInfoDefault
Definition: namedefdlg.hxx:29
ScDocument & mrDoc
Definition: namedefdlg.hxx:25
DocumentType eType
std::unique_ptr< formula::RefButton > m_xRbRange
Definition: namedefdlg.hxx:44
virtual void RefInputDone(bool bForced=false) override
Definition: namedefdlg.cxx:274
std::unique_ptr< formula::RefEdit > m_xEdRange
Definition: namedefdlg.hxx:43
SC_DLLPUBLIC ScRangeData * findByUpperName(const OUString &rName)
Definition: rangenam.cxx:679
virtual void AddUndoAction(std::unique_ptr< SfxUndoAction > pAction, bool bTryMerg=false)
const OUString maErrInvalidNameCellRefStr
Definition: namedefdlg.hxx:32
#define STR_GLOBAL_RANGE_NAME
Definition: globalnames.hxx:15
int i
std::unique_ptr< weld::Button > m_xBtnAdd
Definition: namedefdlg.hxx:53
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:2212
static SC_DLLPUBLIC IsNameValidType IsNameValid(const OUString &rName, const ScDocument &rDoc)
Definition: rangenam.cxx:464
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
OUString ScResId(const char *pId)
Definition: scdll.cxx:89
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1171
virtual void RefInputDone(bool bForced=false) override
Definition: anyrefdg.cxx:756
void AddType(Type nType)
Definition: rangenam.hxx:171
void CancelPushed()
Definition: namedefdlg.cxx:92
virtual ~ScNameDefDlg() override
Definition: namedefdlg.cxx:88
IMPL_LINK_NOARG(ScNameDefDlg, CancelBtnHdl, weld::Button &, void)
Definition: namedefdlg.cxx:303
bool IsNameValid()
Definition: namedefdlg.cxx:118
std::unique_ptr< weld::CheckButton > m_xBtnColHeader
Definition: namedefdlg.hxx:49
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
Definition: namedefdlg.cxx:280
virtual void SetActive() override
Definition: namedefdlg.cxx:297
void SetStreamValid(SCTAB nTab, bool bSet, bool bIgnoreLock=false)
Definition: document.cxx:924
static ScTabViewShell * GetActiveViewShell()
Definition: tabvwsh4.cxx:1038
std::unique_ptr< weld::ComboBox > m_xLbScope
Definition: namedefdlg.hxx:46
OUString aName
virtual bool IsRefInputMode() const override
Definition: namedefdlg.cxx:269
static SC_DLLPUBLIC const CharClass * getCharClassPtr()
Definition: global.cxx:1009
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:400
SC_DLLPUBLIC FormulaError GetErrCode() const
Definition: rangenam.cxx:496
OUString maScope
Definition: namedefdlg.hxx:37
const OUString maErrNameInUse
Definition: namedefdlg.hxx:33
std::unique_ptr< weld::CheckButton > m_xBtnCriteria
Definition: namedefdlg.hxx:51
std::unique_ptr< weld::CheckButton > m_xBtnPrintArea
Definition: namedefdlg.hxx:50
OUString maName
Definition: namedefdlg.hxx:36
virtual void Close() override
Definition: namedefdlg.cxx:292
bool DoClose(sal_uInt16 nId)
Definition: anyrefdg.cxx:695
ScDocShell * mpDocShell
Definition: namedefdlg.hxx:26
std::map< OUString, ScRangeName * > maRangeMap
Definition: namedefdlg.hxx:39
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:212
SC_DLLPUBLIC bool insert(ScRangeData *p, bool bReuseFreeIndex=true)
Insert object into set.
Definition: rangenam.cxx:807
void AddPushed()
Definition: namedefdlg.cxx:172
const OUString maGlobalNameStr
Definition: namedefdlg.hxx:30
sal_Int16 SCTAB
Definition: types.hxx:22
void SwitchBetweenRefDialogs(SfxModelessDialogController *pDialog)
Definition: tabvwshc.cxx:85
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
Definition: anyrefdg.cxx:726