Line data Source code
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/msgbox.hxx>
13 : #include <vcl/settings.hxx>
14 :
15 : #include <sfx2/app.hxx>
16 :
17 : #include "document.hxx"
18 : #include "globstr.hrc"
19 : #include "globalnames.hxx"
20 : #include "rangenam.hxx"
21 : #include "reffact.hxx"
22 : #include "undorangename.hxx"
23 : #include "tabvwsh.hxx"
24 : #include "tokenarray.hxx"
25 : #include "sc.hrc"
26 :
27 : // defines -------------------------------------------------------------------
28 :
29 : #define ABS_SREF SCA_VALID \
30 : | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
31 : #define ABS_DREF ABS_SREF \
32 : | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
33 : #define ABS_DREF3D ABS_DREF | SCA_TAB_3D
34 :
35 0 : ScNameDefDlg::ScNameDefDlg( SfxBindings* pB, SfxChildWindow* pCW, vcl::Window* pParent,
36 : ScViewData* pViewData, const std::map<OUString, ScRangeName*>& aRangeMap,
37 : const ScAddress& aCursorPos, const bool bUndo )
38 : : ScAnyRefDlg( pB, pCW, pParent, "DefineNameDialog", "modules/scalc/ui/definename.ui" )
39 : ,
40 : mbUndo( bUndo ),
41 0 : mpDoc( pViewData->GetDocument() ),
42 0 : mpDocShell ( pViewData->GetDocShell() ),
43 : maCursorPos( aCursorPos ),
44 :
45 0 : maGlobalNameStr ( ScGlobal::GetRscString(STR_GLOBAL_SCOPE) ),
46 0 : maErrInvalidNameStr( ScGlobal::GetRscString(STR_ERR_NAME_INVALID)),
47 0 : maErrNameInUse ( ScGlobal::GetRscString(STR_ERR_NAME_EXISTS)),
48 0 : maRangeMap( aRangeMap )
49 : {
50 0 : get(m_pEdName, "edit");
51 0 : get(m_pEdRange, "range");
52 0 : m_pEdRange->SetReferences(this, m_pEdName);
53 0 : get(m_pRbRange, "refbutton");
54 0 : m_pRbRange->SetReferences(this, m_pEdRange);
55 0 : get(m_pLbScope, "scope");
56 0 : get(m_pBtnRowHeader, "rowheader");
57 0 : get(m_pBtnColHeader, "colheader");
58 0 : get(m_pBtnPrintArea, "printarea");
59 0 : get(m_pBtnCriteria, "filter");
60 0 : get(m_pBtnAdd, "add");
61 0 : get(m_pBtnCancel, "cancel");
62 0 : get(m_pFtInfo, "label");
63 0 : maStrInfoDefault = m_pFtInfo->GetText();
64 :
65 : // Initialize scope list.
66 0 : m_pLbScope->InsertEntry(maGlobalNameStr);
67 0 : m_pLbScope->SelectEntryPos(0);
68 0 : SCTAB n = mpDoc->GetTableCount();
69 0 : for (SCTAB i = 0; i < n; ++i)
70 : {
71 0 : OUString aTabName;
72 0 : mpDoc->GetName(i, aTabName);
73 0 : m_pLbScope->InsertEntry(aTabName);
74 0 : }
75 :
76 0 : m_pBtnCancel->SetClickHdl( LINK( this, ScNameDefDlg, CancelBtnHdl));
77 0 : m_pBtnAdd->SetClickHdl( LINK( this, ScNameDefDlg, AddBtnHdl ));
78 0 : m_pEdName->SetModifyHdl( LINK( this, ScNameDefDlg, NameModifyHdl ));
79 0 : m_pEdRange->SetGetFocusHdl( LINK( this, ScNameDefDlg, AssignGetFocusHdl ) );
80 :
81 0 : m_pBtnAdd->Disable(); // empty name is invalid
82 :
83 0 : ScRange aRange;
84 :
85 0 : pViewData->GetSimpleArea( aRange );
86 : OUString aAreaStr(aRange.Format(ABS_DREF3D, mpDoc,
87 0 : ScAddress::Details(mpDoc->GetAddressConvention(), 0, 0)));
88 :
89 0 : m_pEdRange->SetText( aAreaStr );
90 :
91 0 : Selection aCurSel = Selection( 0, SELECTION_MAX );
92 0 : m_pEdName->GrabFocus();
93 0 : m_pEdName->SetSelection( aCurSel );
94 0 : }
95 :
96 0 : ScNameDefDlg::~ScNameDefDlg()
97 : {
98 0 : disposeOnce();
99 0 : }
100 :
101 0 : void ScNameDefDlg::dispose()
102 : {
103 0 : m_pEdName.clear();
104 0 : m_pEdRange.clear();
105 0 : m_pRbRange.clear();
106 0 : m_pLbScope.clear();
107 0 : m_pBtnRowHeader.clear();
108 0 : m_pBtnColHeader.clear();
109 0 : m_pBtnPrintArea.clear();
110 0 : m_pBtnCriteria.clear();
111 0 : m_pBtnAdd.clear();
112 0 : m_pBtnCancel.clear();
113 0 : m_pFtInfo.clear();
114 0 : ScAnyRefDlg::dispose();
115 0 : }
116 :
117 0 : void ScNameDefDlg::CancelPushed()
118 : {
119 0 : if (mbUndo)
120 0 : Close();
121 : else
122 : {
123 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
124 0 : pViewSh->SwitchBetweenRefDialogs(this);
125 : }
126 0 : }
127 :
128 0 : bool ScNameDefDlg::IsFormulaValid()
129 : {
130 0 : ScCompiler aComp( mpDoc, maCursorPos);
131 0 : aComp.SetGrammar( mpDoc->GetGrammar() );
132 0 : ScTokenArray* pCode = aComp.CompileString(m_pEdRange->GetText());
133 0 : if (pCode->GetCodeError())
134 : {
135 : //TODO: info message
136 0 : delete pCode;
137 0 : return false;
138 : }
139 : else
140 : {
141 0 : delete pCode;
142 0 : return true;
143 0 : }
144 : }
145 :
146 0 : bool ScNameDefDlg::IsNameValid()
147 : {
148 0 : OUString aScope = m_pLbScope->GetSelectEntry();
149 0 : OUString aName = m_pEdName->GetText();
150 :
151 0 : ScRangeName* pRangeName = NULL;
152 0 : if(aScope == maGlobalNameStr)
153 : {
154 0 : pRangeName = maRangeMap.find(OUString(STR_GLOBAL_RANGE_NAME))->second;
155 : }
156 : else
157 : {
158 0 : pRangeName = maRangeMap.find(aScope)->second;
159 : }
160 :
161 0 : m_pFtInfo->SetControlBackground(GetSettings().GetStyleSettings().GetDialogColor());
162 0 : if ( aName.isEmpty() )
163 : {
164 0 : m_pBtnAdd->Disable();
165 0 : m_pFtInfo->SetText(maStrInfoDefault);
166 0 : return false;
167 : }
168 0 : else if (!ScRangeData::IsNameValid( aName, mpDoc ))
169 : {
170 0 : m_pFtInfo->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
171 0 : m_pFtInfo->SetText(maErrInvalidNameStr);
172 0 : m_pBtnAdd->Disable();
173 0 : return false;
174 : }
175 0 : else if (pRangeName->findByUpperName(ScGlobal::pCharClass->uppercase(aName)))
176 : {
177 0 : m_pFtInfo->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
178 0 : m_pFtInfo->SetText(maErrNameInUse);
179 0 : m_pBtnAdd->Disable();
180 0 : return false;
181 : }
182 :
183 0 : if (!IsFormulaValid())
184 : {
185 0 : m_pFtInfo->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
186 0 : m_pBtnAdd->Disable();
187 0 : return false;
188 : }
189 :
190 0 : m_pFtInfo->SetText(maStrInfoDefault);
191 0 : m_pBtnAdd->Enable();
192 0 : return true;
193 : }
194 :
195 0 : void ScNameDefDlg::AddPushed()
196 : {
197 0 : OUString aScope = m_pLbScope->GetSelectEntry();
198 0 : OUString aName = m_pEdName->GetText();
199 0 : OUString aExpression = m_pEdRange->GetText();
200 :
201 0 : if (aName.isEmpty())
202 : {
203 0 : return;
204 : }
205 0 : if (aScope.isEmpty())
206 : {
207 0 : return;
208 : }
209 :
210 0 : ScRangeName* pRangeName = NULL;
211 0 : if(aScope == maGlobalNameStr)
212 : {
213 0 : pRangeName = maRangeMap.find(OUString(STR_GLOBAL_RANGE_NAME))->second;
214 : }
215 : else
216 : {
217 0 : pRangeName = maRangeMap.find(aScope)->second;
218 : }
219 0 : if (!pRangeName)
220 0 : return;
221 :
222 0 : if (!IsNameValid()) //should not happen, but make sure we don't break anything
223 0 : return;
224 : else
225 : {
226 0 : if ( mpDoc )
227 : {
228 0 : RangeType nType = RT_NAME;
229 :
230 : ScRangeData* pNewEntry = new ScRangeData( mpDoc,
231 : aName,
232 : aExpression,
233 : maCursorPos,
234 0 : nType );
235 :
236 : nType = nType
237 0 : | (m_pBtnRowHeader->IsChecked() ? RT_ROWHEADER : RangeType(0))
238 0 : | (m_pBtnColHeader->IsChecked() ? RT_COLHEADER : RangeType(0))
239 0 : | (m_pBtnPrintArea->IsChecked() ? RT_PRINTAREA : RangeType(0))
240 0 : | (m_pBtnCriteria->IsChecked() ? RT_CRITERIA : RangeType(0));
241 0 : pNewEntry->AddType(nType);
242 :
243 : // aExpression valid?
244 0 : if ( 0 == pNewEntry->GetErrCode() )
245 : {
246 0 : if ( !pRangeName->insert( pNewEntry ) )
247 0 : pNewEntry = NULL;
248 :
249 0 : if (mbUndo)
250 : {
251 : // this means we called directly through the menu
252 :
253 : SCTAB nTab;
254 : // if no table with that name is found, assume global range name
255 0 : if (!mpDoc->GetTable(aScope, nTab))
256 0 : nTab = -1;
257 :
258 : assert( pNewEntry); // undo of no insertion smells fishy
259 0 : if (pNewEntry)
260 0 : mpDocShell->GetUndoManager()->AddUndoAction(
261 0 : new ScUndoAddRangeData( mpDocShell, pNewEntry, nTab) );
262 :
263 : // set table stream invalid, otherwise RangeName won't be saved if no other
264 : // call invalidates the stream
265 0 : if (nTab != -1)
266 0 : mpDoc->SetStreamValid(nTab, false);
267 0 : SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
268 0 : mpDocShell->SetDocumentModified();
269 0 : Close();
270 : }
271 : else
272 : {
273 0 : maName = aName;
274 0 : maScope = aScope;
275 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
276 0 : pViewSh->SwitchBetweenRefDialogs(this);
277 : }
278 : }
279 : else
280 : {
281 0 : delete pNewEntry;
282 0 : Selection aCurSel = Selection( 0, SELECTION_MAX );
283 0 : m_pEdRange->GrabFocus();
284 0 : m_pEdRange->SetSelection( aCurSel );
285 : }
286 : }
287 0 : }
288 : }
289 :
290 0 : void ScNameDefDlg::GetNewData(OUString& rName, OUString& rScope)
291 : {
292 0 : rName = maName;
293 0 : rScope = maScope;
294 0 : }
295 :
296 0 : bool ScNameDefDlg::IsRefInputMode() const
297 : {
298 0 : return m_pEdRange->IsEnabled();
299 : }
300 :
301 0 : void ScNameDefDlg::RefInputDone( bool bForced)
302 : {
303 0 : ScAnyRefDlg::RefInputDone(bForced);
304 0 : IsNameValid();
305 0 : }
306 :
307 0 : void ScNameDefDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
308 : {
309 0 : if ( m_pEdRange->IsEnabled() )
310 : {
311 0 : if ( rRef.aStart != rRef.aEnd )
312 0 : RefInputStart(m_pEdRange);
313 : OUString aRefStr(rRef.Format(ABS_DREF3D, pDocP,
314 0 : ScAddress::Details(pDocP->GetAddressConvention(), 0, 0)));
315 0 : m_pEdRange->SetRefString( aRefStr );
316 : }
317 0 : }
318 :
319 0 : bool ScNameDefDlg::Close()
320 : {
321 0 : return DoClose( ScNameDefDlgWrapper::GetChildWindowId() );
322 : }
323 :
324 0 : void ScNameDefDlg::SetActive()
325 : {
326 0 : m_pEdRange->GrabFocus();
327 0 : RefInputDone();
328 0 : }
329 :
330 0 : IMPL_LINK_NOARG(ScNameDefDlg, CancelBtnHdl)
331 : {
332 0 : CancelPushed();
333 0 : return 0;
334 : }
335 :
336 0 : IMPL_LINK_NOARG(ScNameDefDlg, AddBtnHdl)
337 : {
338 0 : AddPushed();
339 0 : return 0;
340 : };
341 :
342 0 : IMPL_LINK_NOARG(ScNameDefDlg, NameModifyHdl)
343 : {
344 0 : IsNameValid();
345 0 : return 0;
346 : }
347 :
348 0 : IMPL_LINK_NOARG(ScNameDefDlg, AssignGetFocusHdl)
349 : {
350 0 : IsNameValid();
351 0 : return 0;
352 156 : }
353 :
354 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|