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