Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License or as specified alternatively below. You may obtain a copy of
8 : * the License at http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * Major Contributor(s):
16 : * Copyright (C) 2011 Markus Mohrhard <markus.mohrhard@googlemail.com> (initial developer) ]
17 : *
18 : * All Rights Reserved.
19 : *
20 : * For minor contributions see the git repository.
21 : *
22 : * Alternatively, the contents of this file may be used under the terms of
23 : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
24 : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
25 : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
26 : * instead of those above.
27 : */
28 :
29 : #include "namedefdlg.hxx"
30 :
31 : #include <vcl/msgbox.hxx>
32 : #include <sfx2/app.hxx>
33 :
34 : #include "document.hxx"
35 : #include "globstr.hrc"
36 : #include "globalnames.hxx"
37 : #include "rangenam.hxx"
38 : #include "reffact.hxx"
39 : #include "undorangename.hxx"
40 : #include "tabvwsh.hxx"
41 :
42 : // defines -------------------------------------------------------------------
43 :
44 : #define ABS_SREF SCA_VALID \
45 : | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
46 : #define ABS_DREF ABS_SREF \
47 : | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
48 : #define ABS_SREF3D ABS_SREF | SCA_TAB_3D
49 : #define ABS_DREF3D ABS_DREF | SCA_TAB_3D
50 :
51 0 : ScNameDefDlg::ScNameDefDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
52 : ScViewData* pViewData, std::map<rtl::OUString, ScRangeName*> aRangeMap,
53 : const ScAddress& aCursorPos, const bool bUndo ) :
54 : ScAnyRefDlg( pB, pCW, pParent, RID_SCDLG_NAMES_DEFINE ),
55 : maEdName( this, ScResId( ED_NAME ) ),
56 : maEdRange( this, this, ScResId( ED_RANGE ) ),
57 : maRbRange( this, ScResId( RB_RANGE ), &maEdRange, this ),
58 : maLbScope( this, ScResId( LB_SCOPE ) ),
59 : maBtnMore( this, ScResId( BTN_MORE ) ),
60 : maBtnRowHeader( this, ScResId( BTN_ROWHEADER ) ),
61 : maBtnColHeader( this, ScResId( BTN_COLHEADER ) ),
62 : maBtnPrintArea( this, ScResId( BTN_PRINTAREA ) ),
63 : maBtnCriteria( this, ScResId( BTN_CRITERIA ) ),
64 : maBtnAdd( this, ScResId( BTN_ADD ) ),
65 : maBtnCancel( this, ScResId( BTN_CANCEL ) ),
66 : maFtInfo( this, ScResId( FT_INFO ) ),
67 : maFtName( this, ScResId( FT_NAME ) ),
68 : maFtRange( this, ScResId( FT_RANGE ) ),
69 : maFtScope( this, ScResId( FT_SCOPE ) ),
70 : maFlDiv( this, ScResId( FL_DIV ) ),
71 : mbUndo( bUndo ),
72 0 : mpDoc( pViewData->GetDocument() ),
73 0 : mpDocShell ( pViewData->GetDocShell() ),
74 : maCursorPos( aCursorPos ),
75 :
76 0 : maGlobalNameStr ( ScGlobal::GetRscString(STR_GLOBAL_SCOPE) ),
77 0 : maErrInvalidNameStr( ScGlobal::GetRscString(STR_ERR_NAME_INVALID)),
78 0 : maErrNameInUse ( ScGlobal::GetRscString(STR_ERR_NAME_EXISTS)),
79 : maStrInfoDefault ( SC_RESSTR(STR_DEFAULT_INFO)),
80 0 : maRangeMap( aRangeMap )
81 : {
82 : // Initialize scope list.
83 0 : maLbScope.InsertEntry(maGlobalNameStr);
84 0 : maLbScope.SelectEntryPos(0);
85 0 : SCTAB n = mpDoc->GetTableCount();
86 0 : for (SCTAB i = 0; i < n; ++i)
87 : {
88 0 : rtl::OUString aTabName;
89 0 : mpDoc->GetName(i, aTabName);
90 0 : maLbScope.InsertEntry(aTabName);
91 0 : }
92 :
93 0 : maBtnCancel.SetClickHdl( LINK( this, ScNameDefDlg, CancelBtnHdl));
94 0 : maBtnAdd.SetClickHdl( LINK( this, ScNameDefDlg, AddBtnHdl ));
95 0 : maBtnMore.SetClickHdl( LINK( this, ScNameDefDlg, MoreBtnHdl ));
96 0 : maEdName.SetModifyHdl( LINK( this, ScNameDefDlg, NameModifyHdl ));
97 0 : maEdRange.SetGetFocusHdl( LINK( this, ScNameDefDlg, AssignGetFocusHdl ) );
98 :
99 0 : maFtInfo.SetStyle(WB_VCENTER);
100 0 : maFtInfo.SetText(maStrInfoDefault);
101 :
102 0 : maBtnAdd.Disable(); // empty name is invalid
103 :
104 0 : maBtnRowHeader.Hide();
105 0 : maBtnColHeader.Hide();
106 0 : maBtnCriteria.Hide();
107 0 : maBtnPrintArea.Hide();
108 :
109 0 : FreeResource();
110 :
111 0 : String aAreaStr;
112 0 : ScRange aRange;
113 :
114 0 : pViewData->GetSimpleArea( aRange );
115 : aRange.Format( aAreaStr, ABS_DREF3D, mpDoc,
116 0 : ScAddress::Details(mpDoc->GetAddressConvention(), 0, 0) );
117 :
118 0 : maEdRange.SetText( aAreaStr );
119 :
120 0 : Selection aCurSel = Selection( 0, SELECTION_MAX );
121 0 : maEdName.GrabFocus();
122 0 : maEdName.SetSelection( aCurSel );
123 0 : }
124 :
125 0 : void ScNameDefDlg::CancelPushed()
126 : {
127 0 : if (mbUndo)
128 0 : Close();
129 : else
130 : {
131 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
132 0 : pViewSh->SwitchBetweenRefDialogs(this);
133 : }
134 0 : }
135 :
136 0 : bool ScNameDefDlg::IsFormulaValid()
137 : {
138 0 : ScCompiler aComp( mpDoc, maCursorPos);
139 0 : aComp.SetGrammar( mpDoc->GetGrammar() );
140 0 : ScTokenArray* pCode = aComp.CompileString(maEdRange.GetText());
141 0 : if (pCode->GetCodeError())
142 : {
143 : //TODO: info message
144 0 : delete pCode;
145 0 : return false;
146 : }
147 : else
148 : {
149 0 : delete pCode;
150 0 : return true;
151 0 : }
152 : }
153 :
154 0 : bool ScNameDefDlg::IsNameValid()
155 : {
156 0 : rtl::OUString aScope = maLbScope.GetSelectEntry();
157 0 : rtl::OUString aName = maEdName.GetText();
158 :
159 0 : ScRangeName* pRangeName = NULL;
160 0 : if(aScope == maGlobalNameStr)
161 : {
162 0 : pRangeName = maRangeMap.find(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(STR_GLOBAL_RANGE_NAME)))->second;
163 : }
164 : else
165 : {
166 0 : pRangeName = maRangeMap.find(aScope)->second;
167 : }
168 :
169 0 : maFtInfo.SetControlBackground(GetSettings().GetStyleSettings().GetDialogColor());
170 0 : if ( aName.isEmpty() )
171 : {
172 0 : maBtnAdd.Disable();
173 0 : maFtInfo.SetText(maStrInfoDefault);
174 0 : return false;
175 : }
176 0 : else if (!ScRangeData::IsNameValid( aName, mpDoc ))
177 : {
178 0 : maFtInfo.SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
179 0 : maFtInfo.SetText(maErrInvalidNameStr);
180 0 : maBtnAdd.Disable();
181 0 : return false;
182 : }
183 0 : else if (pRangeName->findByUpperName(ScGlobal::pCharClass->uppercase(aName)))
184 : {
185 0 : maFtInfo.SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
186 0 : maFtInfo.SetText(maErrNameInUse);
187 0 : maBtnAdd.Disable();
188 0 : return false;
189 : }
190 :
191 0 : if (!IsFormulaValid())
192 : {
193 0 : maFtInfo.SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
194 0 : maBtnAdd.Disable();
195 0 : return false;
196 : }
197 :
198 0 : maFtInfo.SetText(maStrInfoDefault);
199 0 : maBtnAdd.Enable();
200 0 : return true;
201 : }
202 :
203 0 : void ScNameDefDlg::AddPushed()
204 : {
205 0 : rtl::OUString aScope = maLbScope.GetSelectEntry();
206 0 : rtl::OUString aName = maEdName.GetText();
207 0 : rtl::OUString aExpression = maEdRange.GetText();
208 :
209 0 : if (aName.isEmpty())
210 : {
211 : return;
212 : }
213 0 : if (aScope.isEmpty())
214 : {
215 : return;
216 : }
217 :
218 0 : ScRangeName* pRangeName = NULL;
219 0 : if(aScope == maGlobalNameStr)
220 : {
221 0 : pRangeName = maRangeMap.find(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(STR_GLOBAL_RANGE_NAME)))->second;
222 : }
223 : else
224 : {
225 0 : pRangeName = maRangeMap.find(aScope)->second;
226 : }
227 0 : if (!pRangeName)
228 : return;
229 :
230 0 : if (!IsNameValid()) //should not happen, but make sure we don't break anything
231 : return;
232 : else
233 : {
234 0 : if ( mpDoc )
235 : {
236 0 : ScRangeData* pNewEntry = NULL;
237 0 : RangeType nType = RT_NAME;
238 :
239 : pNewEntry = new ScRangeData( mpDoc,
240 : aName,
241 : aExpression,
242 : maCursorPos,
243 0 : nType );
244 0 : if (pNewEntry)
245 : {
246 : nType = nType
247 0 : | (maBtnRowHeader .IsChecked() ? RT_ROWHEADER : RangeType(0))
248 0 : | (maBtnColHeader .IsChecked() ? RT_COLHEADER : RangeType(0))
249 0 : | (maBtnPrintArea .IsChecked() ? RT_PRINTAREA : RangeType(0))
250 0 : | (maBtnCriteria .IsChecked() ? RT_CRITERIA : RangeType(0));
251 0 : pNewEntry->AddType(nType);
252 : }
253 :
254 : // aExpression valid?
255 0 : if ( 0 == pNewEntry->GetErrCode() )
256 : {
257 0 : if ( !pRangeName->insert( pNewEntry ) )
258 0 : pNewEntry = NULL;
259 :
260 0 : if (mbUndo)
261 : {
262 : // this means we called directly through the menu
263 :
264 : SCTAB nTab;
265 : // if no table with that name is found, assume global range name
266 0 : if (!mpDoc->GetTable(aScope, nTab))
267 0 : nTab = -1;
268 :
269 0 : mpDocShell->GetUndoManager()->AddUndoAction(
270 0 : new ScUndoAddRangeData( mpDocShell, pNewEntry, nTab) );
271 :
272 : // set table stream invalid, otherwise RangeName won't be saved if no other
273 : // call invalidates the stream
274 0 : if (nTab != -1)
275 0 : mpDoc->SetStreamValid(nTab, false);
276 0 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
277 0 : Close();
278 : }
279 : else
280 : {
281 0 : maName = aName;
282 0 : maScope = aScope;
283 0 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
284 0 : pViewSh->SwitchBetweenRefDialogs(this);
285 : }
286 : }
287 : else
288 : {
289 0 : delete pNewEntry;
290 0 : Selection aCurSel = Selection( 0, SELECTION_MAX );
291 0 : maEdRange.GrabFocus();
292 0 : maEdRange.SetSelection( aCurSel );
293 : }
294 : }
295 0 : }
296 : }
297 :
298 0 : void ScNameDefDlg::GetNewData(rtl::OUString& rName, rtl::OUString& rScope)
299 : {
300 0 : rName = maName;
301 0 : rScope = maScope;
302 0 : }
303 :
304 0 : sal_Bool ScNameDefDlg::IsRefInputMode() const
305 : {
306 0 : return maEdRange.IsEnabled();
307 : }
308 :
309 0 : void ScNameDefDlg::RefInputDone( sal_Bool bForced)
310 : {
311 0 : ScAnyRefDlg::RefInputDone(bForced);
312 0 : IsNameValid();
313 0 : }
314 :
315 0 : void ScNameDefDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
316 : {
317 0 : if ( maEdRange.IsEnabled() )
318 : {
319 0 : if ( rRef.aStart != rRef.aEnd )
320 0 : RefInputStart(&maEdRange);
321 0 : String aRefStr;
322 : rRef.Format( aRefStr, ABS_DREF3D, pDocP,
323 0 : ScAddress::Details(pDocP->GetAddressConvention(), 0, 0) );
324 0 : maEdRange.SetRefString( aRefStr );
325 : }
326 0 : }
327 :
328 0 : sal_Bool ScNameDefDlg::Close()
329 : {
330 0 : return DoClose( ScNameDefDlgWrapper::GetChildWindowId() );
331 : }
332 :
333 0 : void ScNameDefDlg::SetActive()
334 : {
335 0 : maEdRange.GrabFocus();
336 0 : RefInputDone();
337 0 : }
338 :
339 : namespace {
340 :
341 0 : void MoveWindow( Window& rButton, long nPixel)
342 : {
343 0 : Point aPoint = rButton.GetPosPixel();
344 0 : aPoint.Y() += nPixel;
345 0 : rButton.SetPosPixel(aPoint);
346 0 : }
347 :
348 : }
349 :
350 0 : void ScNameDefDlg::MorePushed()
351 : {
352 0 : Size nSize = GetSizePixel();
353 :
354 : //depending on the state of the button, move all elements below up/down
355 0 : long nPixel = 65;
356 0 : if (!maBtnMore.GetState())
357 : {
358 0 : nPixel *= -1;
359 0 : maBtnRowHeader.Hide();
360 0 : maBtnColHeader.Hide();
361 0 : maBtnPrintArea.Hide();
362 0 : maBtnCriteria.Hide();
363 : }
364 : else
365 : {
366 0 : maBtnRowHeader.Show();
367 0 : maBtnColHeader.Show();
368 0 : maBtnPrintArea.Show();
369 0 : maBtnCriteria.Show();
370 : }
371 0 : nSize.Height() += nPixel;
372 0 : SetSizePixel(nSize);
373 0 : MoveWindow(maBtnAdd, nPixel);
374 0 : MoveWindow(maBtnCancel, nPixel);
375 0 : MoveWindow(maFlDiv, nPixel);
376 0 : }
377 :
378 0 : IMPL_LINK_NOARG(ScNameDefDlg, CancelBtnHdl)
379 : {
380 0 : CancelPushed();
381 0 : return 0;
382 : }
383 :
384 0 : IMPL_LINK_NOARG(ScNameDefDlg, AddBtnHdl)
385 : {
386 0 : AddPushed();
387 0 : return 0;
388 : };
389 :
390 0 : IMPL_LINK_NOARG(ScNameDefDlg, NameModifyHdl)
391 : {
392 0 : IsNameValid();
393 0 : return 0;
394 : }
395 :
396 0 : IMPL_LINK_NOARG(ScNameDefDlg, AssignGetFocusHdl)
397 : {
398 0 : IsNameValid();
399 0 : return 0;
400 : }
401 :
402 0 : IMPL_LINK_NOARG(ScNameDefDlg, MoreBtnHdl)
403 : {
404 0 : MorePushed();
405 0 : return 0;
406 15 : }
407 :
408 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|