nss: upgrade to release 3.73
[LibreOffice.git] / sc / source / ui / namedlg / namedefdlg.cxx
blobb66b1cfc0b275811609adddf2605d02a0fb606e1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <namedefdlg.hxx>
12 #include <vcl/settings.hxx>
13 #include <formula/errorcodes.hxx>
14 #include <sfx2/app.hxx>
15 #include <unotools/charclass.hxx>
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>
28 ScNameDefDlg::ScNameDefDlg( SfxBindings* pB, SfxChildWindow* pCW, weld::Window* pParent,
29 const ScViewData& rViewData, 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(rViewData.GetDocument())
34 , mpDocShell ( rViewData.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"))
55 m_xEdRange->SetReferences(this, m_xFtRange.get());
56 m_xRbRange->SetReferences(this, m_xEdRange.get());
57 maStrInfoDefault = m_xFtInfo->get_label();
59 // Initialize scope list.
60 m_xLbScope->append_text(maGlobalNameStr);
61 m_xLbScope->set_active(0);
62 SCTAB n = mrDoc.GetTableCount();
63 for (SCTAB i = 0; i < n; ++i)
65 OUString aTabName;
66 mrDoc.GetName(i, aTabName);
67 m_xLbScope->append_text(aTabName);
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 ) );
75 m_xBtnAdd->set_sensitive(false); // empty name is invalid
77 ScRange aRange;
79 rViewData.GetSimpleArea( aRange );
80 OUString aAreaStr(aRange.Format(mrDoc, ScRefFlags::RANGE_ABS_3D,
81 ScAddress::Details(mrDoc.GetAddressConvention(), 0, 0)));
83 m_xEdRange->SetText( aAreaStr );
85 m_xEdName->grab_focus();
86 m_xEdName->select_region(0, -1);
89 ScNameDefDlg::~ScNameDefDlg()
93 void ScNameDefDlg::CancelPushed()
95 if (mbUndo)
96 response(RET_CANCEL);
97 else
99 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
100 pViewSh->SwitchBetweenRefDialogs(this);
104 bool ScNameDefDlg::IsFormulaValid()
106 ScCompiler aComp(mrDoc, maCursorPos, mrDoc.GetGrammar());
107 std::unique_ptr<ScTokenArray> pCode = aComp.CompileString(m_xEdRange->GetText());
108 if (pCode->GetCodeError() != FormulaError::NONE)
110 //TODO: info message
111 return false;
113 else
115 return true;
119 bool ScNameDefDlg::IsNameValid()
121 OUString aScope = m_xLbScope->get_active_text();
122 OUString aName = m_xEdName->get_text();
124 ScRangeName* pRangeName = nullptr;
125 if(aScope == maGlobalNameStr)
127 pRangeName = maRangeMap.find(OUString(STR_GLOBAL_RANGE_NAME))->second;
129 else
131 pRangeName = maRangeMap.find(aScope)->second;
134 ScRangeData::IsNameValidType eType;
135 m_xFtInfo->set_label_type(weld::LabelType::Normal);
136 if ( aName.isEmpty() )
138 m_xBtnAdd->set_sensitive(false);
139 m_xFtInfo->set_label(maStrInfoDefault);
140 return false;
142 else if ((eType = ScRangeData::IsNameValid( aName, mrDoc )) != ScRangeData::NAME_VALID)
144 m_xFtInfo->set_label_type(weld::LabelType::Error);
145 if (eType == ScRangeData::NAME_INVALID_BAD_STRING)
147 m_xFtInfo->set_label(maErrInvalidNameStr);
149 else if (eType == ScRangeData::NAME_INVALID_CELL_REF)
151 m_xFtInfo->set_label(maErrInvalidNameCellRefStr);
153 m_xBtnAdd->set_sensitive(false);
154 return false;
156 else if (pRangeName->findByUpperName(ScGlobal::getCharClassPtr()->uppercase(aName)))
158 m_xFtInfo->set_label_type(weld::LabelType::Error);
159 m_xFtInfo->set_label(maErrNameInUse);
160 m_xBtnAdd->set_sensitive(false);
161 return false;
164 if (!IsFormulaValid())
166 m_xFtInfo->set_label_type(weld::LabelType::Error);
167 m_xBtnAdd->set_sensitive(false);
168 return false;
171 m_xFtInfo->set_label(maStrInfoDefault);
172 m_xBtnAdd->set_sensitive(true);
173 return true;
176 void ScNameDefDlg::AddPushed()
178 OUString aScope = m_xLbScope->get_active_text();
179 OUString aName = m_xEdName->get_text();
180 OUString aExpression = m_xEdRange->GetText();
182 if (aName.isEmpty())
184 return;
186 if (aScope.isEmpty())
188 return;
191 ScRangeName* pRangeName = nullptr;
192 if(aScope == maGlobalNameStr)
194 pRangeName = maRangeMap.find(OUString(STR_GLOBAL_RANGE_NAME))->second;
196 else
198 pRangeName = maRangeMap.find(aScope)->second;
200 if (!pRangeName)
201 return;
203 if (!IsNameValid()) //should not happen, but make sure we don't break anything
204 return;
205 else
207 ScRangeData::Type nType = ScRangeData::Type::Name;
209 ScRangeData* pNewEntry = new ScRangeData( mrDoc,
210 aName,
211 aExpression,
212 maCursorPos,
213 nType );
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;
220 pNewEntry->AddType(nType);
222 // aExpression valid?
223 if ( FormulaError::NONE == pNewEntry->GetErrCode() )
225 if ( !pRangeName->insert( pNewEntry, false /*bReuseFreeIndex*/ ) )
226 pNewEntry = nullptr;
228 if (mbUndo)
230 // this means we called directly through the menu
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;
237 assert( pNewEntry); // undo of no insertion smells fishy
238 if (pNewEntry)
239 mpDocShell->GetUndoManager()->AddUndoAction(
240 std::make_unique<ScUndoAddRangeData>( mpDocShell, pNewEntry, nTab) );
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 ) );
247 mpDocShell->SetDocumentModified();
248 Close();
250 else
252 maName = aName;
253 maScope = aScope;
254 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
255 pViewSh->SwitchBetweenRefDialogs(this);
258 else
260 delete pNewEntry;
261 m_xEdRange->GrabFocus();
262 m_xEdRange->SelectAll();
267 void ScNameDefDlg::GetNewData(OUString& rName, OUString& rScope)
269 rName = maName;
270 rScope = maScope;
273 bool ScNameDefDlg::IsRefInputMode() const
275 return m_xEdRange->GetWidget()->get_sensitive();
278 void ScNameDefDlg::RefInputDone( bool bForced)
280 ScAnyRefDlgController::RefInputDone(bForced);
281 IsNameValid();
284 void ScNameDefDlg::SetReference( const ScRange& rRef, ScDocument& rDocP )
286 if (m_xEdRange->GetWidget()->get_sensitive())
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 );
296 void ScNameDefDlg::Close()
298 DoClose( ScNameDefDlgWrapper::GetChildWindowId() );
301 void ScNameDefDlg::SetActive()
303 m_xEdRange->GrabFocus();
304 RefInputDone();
307 IMPL_LINK_NOARG(ScNameDefDlg, CancelBtnHdl, weld::Button&, void)
309 CancelPushed();
312 IMPL_LINK_NOARG(ScNameDefDlg, AddBtnHdl, weld::Button&, void)
314 AddPushed();
317 IMPL_LINK_NOARG(ScNameDefDlg, NameModifyHdl, weld::Entry&, void)
319 IsNameValid();
322 IMPL_LINK_NOARG(ScNameDefDlg, AssignGetFocusHdl, formula::RefEdit&, void)
324 IsNameValid();
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */