1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "reffact.hxx"
22 #include "document.hxx"
23 #include "docfunc.hxx"
24 #include "scresid.hxx"
25 #include "globstr.hrc"
26 #include "namedlg.hxx"
27 #include "viewdata.hxx"
28 #include "tabvwsh.hxx"
30 #include "globalnames.hxx"
31 #include "tokenarray.hxx"
33 #include <sfx2/app.hxx>
35 #include <vcl/msgbox.hxx>
36 #include <vcl/settings.hxx>
40 // defines -------------------------------------------------------------------
42 #define ABS_SREF SCA_VALID \
43 | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
44 #define ABS_DREF ABS_SREF \
45 | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
46 #define ABS_DREF3D ABS_DREF | SCA_TAB_3D
50 ScNameDlg::ScNameDlg( SfxBindings
* pB
, SfxChildWindow
* pCW
, vcl::Window
* pParent
,
51 ScViewData
* ptrViewData
,
52 const ScAddress
& aCursorPos
, boost::ptr_map
<OUString
, ScRangeName
>* pRangeMap
)
53 : ScAnyRefDlg(pB
, pCW
, pParent
, "ManageNamesDialog", "modules/scalc/ui/managenamesdialog.ui")
55 , maGlobalNameStr(ScGlobal::GetRscString(STR_GLOBAL_SCOPE
))
56 , maErrInvalidNameStr(ScGlobal::GetRscString(STR_ERR_NAME_INVALID
))
57 , maErrNameInUse(ScGlobal::GetRscString(STR_ERR_NAME_EXISTS
))
58 , maStrMultiSelect(ScGlobal::GetRscString(STR_MULTI_SELECT
))
60 , mpViewData(ptrViewData
)
61 , mpDoc(ptrViewData
->GetDocument())
62 , maCursorPos(aCursorPos
)
64 , mbDataChanged(false)
65 , mbCloseWithoutUndo(false)
67 get(m_pEdName
, "name");
68 get(m_pEdAssign
, "range");
69 m_pEdAssign
->SetReferences(this, m_pEdName
);
70 get(m_pRbAssign
, "assign");
71 m_pRbAssign
->SetReferences(this, m_pEdAssign
);
72 get(m_pLbScope
, "scope");
73 get(m_pBtnPrintArea
, "printrange");
74 get(m_pBtnColHeader
, "colheader");
75 get(m_pBtnCriteria
, "filter");
76 get(m_pBtnRowHeader
, "rowheader");
77 get(m_pBtnAdd
, "add");
78 get(m_pBtnDelete
, "delete");
80 get(m_pBtnCancel
, "cancel");
81 get(m_pFtInfo
, "info");
82 maStrInfoDefault
= m_pFtInfo
->GetText();
83 m_pFtInfo
->SetText(OUString());
87 std::map
<OUString
, ScRangeName
*> aRangeMap
;
88 mpDoc
->GetRangeNameMap(aRangeMap
);
89 std::map
<OUString
, ScRangeName
*>::iterator itr
= aRangeMap
.begin(), itrEnd
= aRangeMap
.end();
90 for (; itr
!= itrEnd
; ++itr
)
92 OUString
aTemp(itr
->first
);
93 maRangeMap
.insert(aTemp
, new ScRangeName(*itr
->second
));
98 maRangeMap
.swap(*pRangeMap
);
103 ScNameDlg::~ScNameDlg()
108 void ScNameDlg::dispose()
110 m_pRangeManagerTable
.disposeAndClear();
115 m_pBtnPrintArea
.clear();
116 m_pBtnColHeader
.clear();
117 m_pBtnCriteria
.clear();
118 m_pBtnRowHeader
.clear();
120 m_pBtnDelete
.clear();
122 m_pBtnCancel
.clear();
124 ScAnyRefDlg::dispose();
127 void ScNameDlg::Init()
131 OSL_ENSURE( mpViewData
&& mpDoc
, "ViewData oder Document nicht gefunden!" );
134 m_pFtInfo
->SetStyle(WB_VCENTER
);
136 SvSimpleTableContainer
*pCtrl
= get
<SvSimpleTableContainer
>("names");
137 pCtrl
->set_height_request(pCtrl
->GetTextHeight()*12);
139 m_pRangeManagerTable
= VclPtr
<ScRangeManagerTable
>::Create(*pCtrl
, maRangeMap
, maCursorPos
);
140 m_pRangeManagerTable
->setInitListener(this);
141 m_pRangeManagerTable
->SetSelectHdl( LINK( this, ScNameDlg
, SelectionChangedHdl_Impl
) );
142 m_pRangeManagerTable
->SetDeselectHdl( LINK( this, ScNameDlg
, SelectionChangedHdl_Impl
) );
144 m_pBtnOk
->SetClickHdl ( LINK( this, ScNameDlg
, OkBtnHdl
) );
145 m_pBtnCancel
->SetClickHdl ( LINK( this, ScNameDlg
, CancelBtnHdl
) );
146 m_pBtnAdd
->SetClickHdl ( LINK( this, ScNameDlg
, AddBtnHdl
) );
147 m_pEdAssign
->SetGetFocusHdl( LINK( this, ScNameDlg
, AssignGetFocusHdl
) );
148 m_pEdAssign
->SetModifyHdl ( LINK( this, ScNameDlg
, EdModifyHdl
) );
149 m_pEdName
->SetModifyHdl ( LINK( this, ScNameDlg
, EdModifyHdl
) );
150 m_pLbScope
->SetSelectHdl( LINK(this, ScNameDlg
, ScopeChangedHdl
) );
151 m_pBtnDelete
->SetClickHdl ( LINK( this, ScNameDlg
, RemoveBtnHdl
) );
152 m_pBtnPrintArea
->SetToggleHdl( LINK(this, ScNameDlg
, EdModifyHdl
) );
153 m_pBtnCriteria
->SetToggleHdl( LINK(this, ScNameDlg
, EdModifyHdl
) );
154 m_pBtnRowHeader
->SetToggleHdl( LINK(this, ScNameDlg
, EdModifyHdl
) );
155 m_pBtnColHeader
->SetToggleHdl( LINK(this, ScNameDlg
, EdModifyHdl
) );
157 // Initialize scope list.
158 m_pLbScope
->InsertEntry(maGlobalNameStr
);
159 m_pLbScope
->SelectEntryPos(0);
160 SCTAB n
= mpDoc
->GetTableCount();
161 for (SCTAB i
= 0; i
< n
; ++i
)
164 mpDoc
->GetName(i
, aTabName
);
165 m_pLbScope
->InsertEntry(aTabName
);
168 CheckForEmptyTable();
171 bool ScNameDlg::IsRefInputMode() const
173 return m_pEdAssign
->IsEnabled();
176 void ScNameDlg::RefInputDone( bool bForced
)
178 ScAnyRefDlg::RefInputDone(bForced
);
179 EdModifyHdl(m_pEdAssign
);
182 void ScNameDlg::SetReference( const ScRange
& rRef
, ScDocument
* pDocP
)
184 if ( m_pEdAssign
->IsEnabled() )
186 if ( rRef
.aStart
!= rRef
.aEnd
)
187 RefInputStart(m_pEdAssign
);
188 OUString
aRefStr(rRef
.Format(ABS_DREF3D
, pDocP
,
189 ScAddress::Details(pDocP
->GetAddressConvention(), 0, 0)));
190 m_pEdAssign
->SetRefString( aRefStr
);
194 bool ScNameDlg::Close()
196 if (mbDataChanged
&& !mbCloseWithoutUndo
)
197 mpViewData
->GetDocFunc().ModifyAllRangeNames(maRangeMap
);
198 return DoClose( ScNameDlgWrapper::GetChildWindowId() );
201 void ScNameDlg::tableInitialized()
203 if (m_pRangeManagerTable
->GetSelectionCount())
207 void ScNameDlg::CheckForEmptyTable()
209 if (!m_pRangeManagerTable
->GetEntryCount())
211 m_pBtnDelete
->Disable();
212 m_pEdAssign
->Disable();
213 m_pRbAssign
->Disable();
214 m_pEdName
->Disable();
215 m_pLbScope
->Disable();
217 m_pBtnCriteria
->Disable();
218 m_pBtnPrintArea
->Disable();
219 m_pBtnColHeader
->Disable();
220 m_pBtnRowHeader
->Disable();
224 m_pBtnDelete
->Enable();
225 m_pEdAssign
->Enable();
226 m_pRbAssign
->Enable();
228 m_pLbScope
->Enable();
230 m_pBtnCriteria
->Enable();
231 m_pBtnPrintArea
->Enable();
232 m_pBtnColHeader
->Enable();
233 m_pBtnRowHeader
->Enable();
237 void ScNameDlg::CancelPushed()
239 DoClose( ScNameDlgWrapper::GetChildWindowId() );
242 void ScNameDlg::SetActive()
244 m_pEdAssign
->GrabFocus();
248 void ScNameDlg::UpdateChecks(ScRangeData
* pData
)
250 // remove handlers, we only want the handlers to process
251 // user input and not when we are syncing the controls with our internal
252 // model ( also UpdateChecks is called already from some other event
253 // handlers, triggering handlers while already processing a handler can
254 // ( and does in this case ) corrupt the internal data
256 m_pBtnCriteria
->SetToggleHdl( Link
<>() );
257 m_pBtnPrintArea
->SetToggleHdl( Link
<>() );
258 m_pBtnColHeader
->SetToggleHdl( Link
<>() );
259 m_pBtnRowHeader
->SetToggleHdl( Link
<>() );
261 m_pBtnCriteria
->Check( pData
->HasType( RT_CRITERIA
) );
262 m_pBtnPrintArea
->Check( pData
->HasType( RT_PRINTAREA
) );
263 m_pBtnColHeader
->Check( pData
->HasType( RT_COLHEADER
) );
264 m_pBtnRowHeader
->Check( pData
->HasType( RT_ROWHEADER
) );
266 // Restore handlers so user input is processed again
267 Link
<> aToggleHandler
= LINK( this, ScNameDlg
, EdModifyHdl
);
268 m_pBtnCriteria
->SetToggleHdl( aToggleHandler
);
269 m_pBtnPrintArea
->SetToggleHdl( aToggleHandler
);
270 m_pBtnColHeader
->SetToggleHdl( aToggleHandler
);
271 m_pBtnRowHeader
->SetToggleHdl( aToggleHandler
);
274 bool ScNameDlg::IsNameValid()
276 OUString aScope
= m_pLbScope
->GetSelectEntry();
277 OUString aName
= m_pEdName
->GetText();
278 aName
= aName
.trim();
283 ScRangeName
* pRangeName
= GetRangeName( aScope
);
285 if (!ScRangeData::IsNameValid( aName
, mpDoc
))
287 m_pFtInfo
->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
288 m_pFtInfo
->SetText(maErrInvalidNameStr
);
291 else if (pRangeName
&& pRangeName
->findByUpperName(ScGlobal::pCharClass
->uppercase(aName
)))
293 m_pFtInfo
->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
294 m_pFtInfo
->SetText(maErrNameInUse
);
297 m_pFtInfo
->SetText( maStrInfoDefault
);
301 bool ScNameDlg::IsFormulaValid()
303 ScCompiler
aComp( mpDoc
, maCursorPos
);
304 aComp
.SetGrammar( mpDoc
->GetGrammar() );
305 ScTokenArray
* pCode
= aComp
.CompileString(m_pEdAssign
->GetText());
306 if (pCode
->GetCodeError())
308 m_pFtInfo
->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
319 ScRangeName
* ScNameDlg::GetRangeName(const OUString
& rScope
)
321 if (rScope
== maGlobalNameStr
)
322 return maRangeMap
.find(OUString(STR_GLOBAL_RANGE_NAME
))->second
;
324 return maRangeMap
.find(rScope
)->second
;
327 void ScNameDlg::ShowOptions(const ScRangeNameLine
& rLine
)
329 ScRangeName
* pRangeName
= GetRangeName(rLine
.aScope
);
330 ScRangeData
* pData
= pRangeName
->findByUpperName(ScGlobal::pCharClass
->uppercase(rLine
.aName
));
337 bool ScNameDlg::AddPushed()
339 mbCloseWithoutUndo
= true;
340 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
341 pViewSh
->SwitchBetweenRefDialogs(this);
345 void ScNameDlg::SetEntry(const OUString
& rName
, const OUString
& rScope
)
347 if (!rName
.isEmpty())
349 mbDataChanged
= true;
350 ScRangeNameLine aLine
;
352 aLine
.aScope
= rScope
;
353 m_pRangeManagerTable
->SetEntry(aLine
);
357 void ScNameDlg::RemovePushed()
359 std::vector
<ScRangeNameLine
> maEntries
= m_pRangeManagerTable
->GetSelectedEntries();
360 m_pRangeManagerTable
->DeleteSelectedEntries();
361 for (std::vector
<ScRangeNameLine
>::iterator itr
= maEntries
.begin(); itr
!= maEntries
.end(); ++itr
)
363 ScRangeName
* pRangeName
= GetRangeName(itr
->aScope
);
364 ScRangeData
* pData
= pRangeName
->findByUpperName(ScGlobal::pCharClass
->uppercase(itr
->aName
));
365 OSL_ENSURE(pData
, "table and model should be in sync");
366 // be safe and check for possible problems
368 pRangeName
->erase(*pData
);
370 mbDataChanged
= true;
372 CheckForEmptyTable();
375 void ScNameDlg::NameModified()
377 ScRangeNameLine aLine
;
378 m_pRangeManagerTable
->GetCurrentLine(aLine
);
379 OUString aOldName
= aLine
.aName
;
380 OUString aNewName
= m_pEdName
->GetText();
381 aNewName
= aNewName
.trim();
382 m_pFtInfo
->SetControlBackground(GetSettings().GetStyleSettings().GetDialogColor());
383 if (aNewName
!= aOldName
)
390 m_pFtInfo
->SetText( maStrInfoDefault
);
393 if (!IsFormulaValid())
395 //TODO: implement an info text
399 OUString aOldScope
= aLine
.aScope
;
401 if (aOldScope
.isEmpty())
403 OUString aExpr
= m_pEdAssign
->GetText();
404 OUString aNewScope
= m_pLbScope
->GetSelectEntry();
406 ScRangeName
* pOldRangeName
= GetRangeName( aOldScope
);
407 ScRangeData
* pData
= pOldRangeName
->findByUpperName( ScGlobal::pCharClass
->uppercase(aOldName
) );
408 ScRangeName
* pNewRangeName
= GetRangeName( aNewScope
);
409 OSL_ENSURE(pData
, "model and table should be in sync");
410 // be safe and check for range data
413 pOldRangeName
->erase(*pData
);
414 mbNeedUpdate
= false;
415 m_pRangeManagerTable
->DeleteSelectedEntries();
416 RangeType nType
= RT_NAME
|
417 (m_pBtnRowHeader
->IsChecked() ? RT_ROWHEADER
: RangeType(0))
418 |(m_pBtnColHeader
->IsChecked() ? RT_COLHEADER
: RangeType(0))
419 |(m_pBtnPrintArea
->IsChecked() ? RT_PRINTAREA
: RangeType(0))
420 |(m_pBtnCriteria
->IsChecked() ? RT_CRITERIA
: RangeType(0));
422 ScRangeData
* pNewEntry
= new ScRangeData( mpDoc
, aNewName
, aExpr
,
424 pNewRangeName
->insert(pNewEntry
);
425 aLine
.aName
= aNewName
;
426 aLine
.aExpression
= aExpr
;
427 aLine
.aScope
= aNewScope
;
428 m_pRangeManagerTable
->addEntry(aLine
);
430 mbDataChanged
= true;
434 void ScNameDlg::SelectionChanged()
436 //don't update if we have just modified due to user input
442 if (m_pRangeManagerTable
->IsMultiSelection())
444 m_pEdName
->SetText(maStrMultiSelect
);
445 m_pEdAssign
->SetText(maStrMultiSelect
);
447 m_pEdName
->Disable();
448 m_pEdAssign
->Disable();
449 m_pRbAssign
->Disable();
450 m_pLbScope
->Disable();
451 m_pBtnRowHeader
->Disable();
452 m_pBtnColHeader
->Disable();
453 m_pBtnPrintArea
->Disable();
454 m_pBtnCriteria
->Disable();
458 ScRangeNameLine aLine
;
459 m_pRangeManagerTable
->GetCurrentLine(aLine
);
460 m_pEdAssign
->SetText(aLine
.aExpression
);
461 m_pEdName
->SetText(aLine
.aName
);
462 m_pLbScope
->SelectEntry(aLine
.aScope
);
464 m_pBtnDelete
->Enable();
466 m_pEdAssign
->Enable();
467 m_pRbAssign
->Enable();
468 m_pLbScope
->Enable();
469 m_pBtnRowHeader
->Enable();
470 m_pBtnColHeader
->Enable();
471 m_pBtnPrintArea
->Enable();
472 m_pBtnCriteria
->Enable();
476 void ScNameDlg::ScopeChanged()
481 void ScNameDlg::GetRangeNames(boost::ptr_map
<OUString
, ScRangeName
>& rRangeMap
)
483 maRangeMap
.swap(rRangeMap
);
486 IMPL_LINK_NOARG(ScNameDlg
, OkBtnHdl
)
492 IMPL_LINK_NOARG(ScNameDlg
, CancelBtnHdl
)
498 IMPL_LINK_NOARG(ScNameDlg
, AddBtnHdl
)
500 return long(AddPushed());
503 IMPL_LINK_NOARG(ScNameDlg
, RemoveBtnHdl
)
509 IMPL_LINK_NOARG(ScNameDlg
, EdModifyHdl
)
515 IMPL_LINK_NOARG(ScNameDlg
, AssignGetFocusHdl
)
517 EdModifyHdl(m_pEdAssign
);
521 IMPL_LINK_NOARG(ScNameDlg
, SelectionChangedHdl_Impl
)
527 IMPL_LINK_NOARG(ScNameDlg
, ScopeChangedHdl
)
533 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */