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, Window* pParent,
36 : ScViewData* pViewData, 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 : void ScNameDefDlg::CancelPushed()
97 : {
98 0 : if (mbUndo)
99 0 : Close();
100 : else
101 : {
102 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
103 0 : pViewSh->SwitchBetweenRefDialogs(this);
104 : }
105 0 : }
106 :
107 0 : bool ScNameDefDlg::IsFormulaValid()
108 : {
109 0 : ScCompiler aComp( mpDoc, maCursorPos);
110 0 : aComp.SetGrammar( mpDoc->GetGrammar() );
111 0 : ScTokenArray* pCode = aComp.CompileString(m_pEdRange->GetText());
112 0 : if (pCode->GetCodeError())
113 : {
114 : //TODO: info message
115 0 : delete pCode;
116 0 : return false;
117 : }
118 : else
119 : {
120 0 : delete pCode;
121 0 : return true;
122 0 : }
123 : }
124 :
125 0 : bool ScNameDefDlg::IsNameValid()
126 : {
127 0 : OUString aScope = m_pLbScope->GetSelectEntry();
128 0 : OUString aName = m_pEdName->GetText();
129 :
130 0 : ScRangeName* pRangeName = NULL;
131 0 : if(aScope == maGlobalNameStr)
132 : {
133 0 : pRangeName = maRangeMap.find(OUString(STR_GLOBAL_RANGE_NAME))->second;
134 : }
135 : else
136 : {
137 0 : pRangeName = maRangeMap.find(aScope)->second;
138 : }
139 :
140 0 : m_pFtInfo->SetControlBackground(GetSettings().GetStyleSettings().GetDialogColor());
141 0 : if ( aName.isEmpty() )
142 : {
143 0 : m_pBtnAdd->Disable();
144 0 : m_pFtInfo->SetText(maStrInfoDefault);
145 0 : return false;
146 : }
147 0 : else if (!ScRangeData::IsNameValid( aName, mpDoc ))
148 : {
149 0 : m_pFtInfo->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
150 0 : m_pFtInfo->SetText(maErrInvalidNameStr);
151 0 : m_pBtnAdd->Disable();
152 0 : return false;
153 : }
154 0 : else if (pRangeName->findByUpperName(ScGlobal::pCharClass->uppercase(aName)))
155 : {
156 0 : m_pFtInfo->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
157 0 : m_pFtInfo->SetText(maErrNameInUse);
158 0 : m_pBtnAdd->Disable();
159 0 : return false;
160 : }
161 :
162 0 : if (!IsFormulaValid())
163 : {
164 0 : m_pFtInfo->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
165 0 : m_pBtnAdd->Disable();
166 0 : return false;
167 : }
168 :
169 0 : m_pFtInfo->SetText(maStrInfoDefault);
170 0 : m_pBtnAdd->Enable();
171 0 : return true;
172 : }
173 :
174 0 : void ScNameDefDlg::AddPushed()
175 : {
176 0 : OUString aScope = m_pLbScope->GetSelectEntry();
177 0 : OUString aName = m_pEdName->GetText();
178 0 : OUString aExpression = m_pEdRange->GetText();
179 :
180 0 : if (aName.isEmpty())
181 : {
182 0 : return;
183 : }
184 0 : if (aScope.isEmpty())
185 : {
186 0 : return;
187 : }
188 :
189 0 : ScRangeName* pRangeName = NULL;
190 0 : if(aScope == maGlobalNameStr)
191 : {
192 0 : pRangeName = maRangeMap.find(OUString(STR_GLOBAL_RANGE_NAME))->second;
193 : }
194 : else
195 : {
196 0 : pRangeName = maRangeMap.find(aScope)->second;
197 : }
198 0 : if (!pRangeName)
199 0 : return;
200 :
201 0 : if (!IsNameValid()) //should not happen, but make sure we don't break anything
202 0 : return;
203 : else
204 : {
205 0 : if ( mpDoc )
206 : {
207 0 : ScRangeData* pNewEntry = NULL;
208 0 : RangeType nType = RT_NAME;
209 :
210 : pNewEntry = new ScRangeData( mpDoc,
211 : aName,
212 : aExpression,
213 : maCursorPos,
214 0 : nType );
215 0 : if (pNewEntry)
216 : {
217 : nType = nType
218 0 : | (m_pBtnRowHeader->IsChecked() ? RT_ROWHEADER : RangeType(0))
219 0 : | (m_pBtnColHeader->IsChecked() ? RT_COLHEADER : RangeType(0))
220 0 : | (m_pBtnPrintArea->IsChecked() ? RT_PRINTAREA : RangeType(0))
221 0 : | (m_pBtnCriteria->IsChecked() ? RT_CRITERIA : RangeType(0));
222 0 : pNewEntry->AddType(nType);
223 : }
224 :
225 : // aExpression valid?
226 0 : if ( 0 == pNewEntry->GetErrCode() )
227 : {
228 0 : if ( !pRangeName->insert( pNewEntry ) )
229 0 : pNewEntry = NULL;
230 :
231 0 : if (mbUndo)
232 : {
233 : // this means we called directly through the menu
234 :
235 : SCTAB nTab;
236 : // if no table with that name is found, assume global range name
237 0 : if (!mpDoc->GetTable(aScope, nTab))
238 0 : nTab = -1;
239 :
240 0 : mpDocShell->GetUndoManager()->AddUndoAction(
241 0 : new ScUndoAddRangeData( mpDocShell, pNewEntry, nTab) );
242 :
243 : // set table stream invalid, otherwise RangeName won't be saved if no other
244 : // call invalidates the stream
245 0 : if (nTab != -1)
246 0 : mpDoc->SetStreamValid(nTab, false);
247 0 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
248 0 : Close();
249 : }
250 : else
251 : {
252 0 : maName = aName;
253 0 : maScope = aScope;
254 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
255 0 : pViewSh->SwitchBetweenRefDialogs(this);
256 : }
257 : }
258 : else
259 : {
260 0 : delete pNewEntry;
261 0 : Selection aCurSel = Selection( 0, SELECTION_MAX );
262 0 : m_pEdRange->GrabFocus();
263 0 : m_pEdRange->SetSelection( aCurSel );
264 : }
265 : }
266 0 : }
267 : }
268 :
269 0 : void ScNameDefDlg::GetNewData(OUString& rName, OUString& rScope)
270 : {
271 0 : rName = maName;
272 0 : rScope = maScope;
273 0 : }
274 :
275 0 : bool ScNameDefDlg::IsRefInputMode() const
276 : {
277 0 : return m_pEdRange->IsEnabled();
278 : }
279 :
280 0 : void ScNameDefDlg::RefInputDone( bool bForced)
281 : {
282 0 : ScAnyRefDlg::RefInputDone(bForced);
283 0 : IsNameValid();
284 0 : }
285 :
286 0 : void ScNameDefDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
287 : {
288 0 : if ( m_pEdRange->IsEnabled() )
289 : {
290 0 : if ( rRef.aStart != rRef.aEnd )
291 0 : RefInputStart(m_pEdRange);
292 : OUString aRefStr(rRef.Format(ABS_DREF3D, pDocP,
293 0 : ScAddress::Details(pDocP->GetAddressConvention(), 0, 0)));
294 0 : m_pEdRange->SetRefString( aRefStr );
295 : }
296 0 : }
297 :
298 0 : bool ScNameDefDlg::Close()
299 : {
300 0 : return DoClose( ScNameDefDlgWrapper::GetChildWindowId() );
301 : }
302 :
303 0 : void ScNameDefDlg::SetActive()
304 : {
305 0 : m_pEdRange->GrabFocus();
306 0 : RefInputDone();
307 0 : }
308 :
309 0 : IMPL_LINK_NOARG(ScNameDefDlg, CancelBtnHdl)
310 : {
311 0 : CancelPushed();
312 0 : return 0;
313 : }
314 :
315 0 : IMPL_LINK_NOARG(ScNameDefDlg, AddBtnHdl)
316 : {
317 0 : AddPushed();
318 0 : return 0;
319 : };
320 :
321 0 : IMPL_LINK_NOARG(ScNameDefDlg, NameModifyHdl)
322 : {
323 0 : IsNameValid();
324 0 : return 0;
325 : }
326 :
327 0 : IMPL_LINK_NOARG(ScNameDefDlg, AssignGetFocusHdl)
328 : {
329 0 : IsNameValid();
330 0 : return 0;
331 0 : }
332 :
333 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|