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