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>
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
, 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()
105 delete m_pRangeManagerTable
;
108 void ScNameDlg::Init()
112 OSL_ENSURE( mpViewData
&& mpDoc
, "ViewData oder Document nicht gefunden!" );
115 m_pFtInfo
->SetStyle(WB_VCENTER
);
117 SvxSimpleTableContainer
*pCtrl
= get
<SvxSimpleTableContainer
>("names");
118 pCtrl
->set_height_request(pCtrl
->GetTextHeight()*12);
120 m_pRangeManagerTable
= new ScRangeManagerTable(*pCtrl
, maRangeMap
, maCursorPos
);
121 m_pRangeManagerTable
->setInitListener(this);
122 m_pRangeManagerTable
->SetSelectHdl( LINK( this, ScNameDlg
, SelectionChangedHdl_Impl
) );
123 m_pRangeManagerTable
->SetDeselectHdl( LINK( this, ScNameDlg
, SelectionChangedHdl_Impl
) );
125 m_pBtnOk
->SetClickHdl ( LINK( this, ScNameDlg
, OkBtnHdl
) );
126 m_pBtnCancel
->SetClickHdl ( LINK( this, ScNameDlg
, CancelBtnHdl
) );
127 m_pBtnAdd
->SetClickHdl ( LINK( this, ScNameDlg
, AddBtnHdl
) );
128 m_pEdAssign
->SetGetFocusHdl( LINK( this, ScNameDlg
, AssignGetFocusHdl
) );
129 m_pEdAssign
->SetModifyHdl ( LINK( this, ScNameDlg
, EdModifyHdl
) );
130 m_pEdName
->SetModifyHdl ( LINK( this, ScNameDlg
, EdModifyHdl
) );
131 m_pLbScope
->SetSelectHdl( LINK(this, ScNameDlg
, ScopeChangedHdl
) );
132 m_pBtnDelete
->SetClickHdl ( LINK( this, ScNameDlg
, RemoveBtnHdl
) );
133 m_pBtnPrintArea
->SetToggleHdl( LINK(this, ScNameDlg
, EdModifyHdl
) );
134 m_pBtnCriteria
->SetToggleHdl( LINK(this, ScNameDlg
, EdModifyHdl
) );
135 m_pBtnRowHeader
->SetToggleHdl( LINK(this, ScNameDlg
, EdModifyHdl
) );
136 m_pBtnColHeader
->SetToggleHdl( LINK(this, ScNameDlg
, EdModifyHdl
) );
138 // Initialize scope list.
139 m_pLbScope
->InsertEntry(maGlobalNameStr
);
140 m_pLbScope
->SelectEntryPos(0);
141 SCTAB n
= mpDoc
->GetTableCount();
142 for (SCTAB i
= 0; i
< n
; ++i
)
145 mpDoc
->GetName(i
, aTabName
);
146 m_pLbScope
->InsertEntry(aTabName
);
149 CheckForEmptyTable();
152 sal_Bool
ScNameDlg::IsRefInputMode() const
154 return m_pEdAssign
->IsEnabled();
157 void ScNameDlg::RefInputDone( sal_Bool bForced
)
159 ScAnyRefDlg::RefInputDone(bForced
);
160 EdModifyHdl(m_pEdAssign
);
163 void ScNameDlg::SetReference( const ScRange
& rRef
, ScDocument
* pDocP
)
165 if ( m_pEdAssign
->IsEnabled() )
167 if ( rRef
.aStart
!= rRef
.aEnd
)
168 RefInputStart(m_pEdAssign
);
170 rRef
.Format( aRefStr
, ABS_DREF3D
, pDocP
,
171 ScAddress::Details(pDocP
->GetAddressConvention(), 0, 0) );
172 m_pEdAssign
->SetRefString( aRefStr
);
176 sal_Bool
ScNameDlg::Close()
178 if (mbDataChanged
&& !mbCloseWithoutUndo
)
179 mpViewData
->GetDocFunc().ModifyAllRangeNames(maRangeMap
);
180 return DoClose( ScNameDlgWrapper::GetChildWindowId() );
183 void ScNameDlg::tableInitialized()
185 if (m_pRangeManagerTable
->GetSelectionCount())
189 void ScNameDlg::CheckForEmptyTable()
191 if (!m_pRangeManagerTable
->GetEntryCount())
193 m_pBtnDelete
->Disable();
194 m_pEdAssign
->Disable();
195 m_pRbAssign
->Disable();
196 m_pEdName
->Disable();
197 m_pLbScope
->Disable();
199 m_pBtnCriteria
->Disable();
200 m_pBtnPrintArea
->Disable();
201 m_pBtnColHeader
->Disable();
202 m_pBtnRowHeader
->Disable();
206 m_pBtnDelete
->Enable();
207 m_pEdAssign
->Enable();
208 m_pRbAssign
->Enable();
210 m_pLbScope
->Enable();
213 m_pBtnCriteria
->Enable();
214 m_pBtnPrintArea
->Enable();
215 m_pBtnColHeader
->Enable();
216 m_pBtnRowHeader
->Enable();
220 void ScNameDlg::CancelPushed()
222 DoClose( ScNameDlgWrapper::GetChildWindowId() );
225 void ScNameDlg::SetActive()
227 m_pEdAssign
->GrabFocus();
231 void ScNameDlg::UpdateChecks(ScRangeData
* pData
)
233 // remove handlers, we only want the handlers to process
234 // user input and not when we are syncing the controls with our internal
235 // model ( also UpdateChecks is called already from some other event
236 // handlers, triggering handlers while already processing a handler can
237 // ( and does in this case ) corrupt the internal data
239 m_pBtnCriteria
->SetToggleHdl( Link() );
240 m_pBtnPrintArea
->SetToggleHdl( Link() );
241 m_pBtnColHeader
->SetToggleHdl( Link() );
242 m_pBtnRowHeader
->SetToggleHdl( Link() );
244 m_pBtnCriteria
->Check( pData
->HasType( RT_CRITERIA
) );
245 m_pBtnPrintArea
->Check( pData
->HasType( RT_PRINTAREA
) );
246 m_pBtnColHeader
->Check( pData
->HasType( RT_COLHEADER
) );
247 m_pBtnRowHeader
->Check( pData
->HasType( RT_ROWHEADER
) );
249 // Restore handlers so user input is processed again
250 Link aToggleHandler
= LINK( this, ScNameDlg
, EdModifyHdl
);
251 m_pBtnCriteria
->SetToggleHdl( aToggleHandler
);
252 m_pBtnPrintArea
->SetToggleHdl( aToggleHandler
);
253 m_pBtnColHeader
->SetToggleHdl( aToggleHandler
);
254 m_pBtnRowHeader
->SetToggleHdl( aToggleHandler
);
257 bool ScNameDlg::IsNameValid()
259 OUString aScope
= m_pLbScope
->GetSelectEntry();
260 OUString aName
= m_pEdName
->GetText();
261 aName
= aName
.trim();
266 ScRangeName
* pRangeName
= GetRangeName( aScope
);
268 if (!ScRangeData::IsNameValid( aName
, mpDoc
))
270 m_pFtInfo
->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
271 m_pFtInfo
->SetText(maErrInvalidNameStr
);
274 else if (pRangeName
&& pRangeName
->findByUpperName(ScGlobal::pCharClass
->uppercase(aName
)))
276 m_pFtInfo
->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
277 m_pFtInfo
->SetText(maErrNameInUse
);
280 m_pFtInfo
->SetText( maStrInfoDefault
);
284 bool ScNameDlg::IsFormulaValid()
286 ScCompiler
aComp( mpDoc
, maCursorPos
);
287 aComp
.SetGrammar( mpDoc
->GetGrammar() );
288 ScTokenArray
* pCode
= aComp
.CompileString(m_pEdAssign
->GetText());
289 if (pCode
->GetCodeError())
291 m_pFtInfo
->SetControlBackground(GetSettings().GetStyleSettings().GetHighlightColor());
302 ScRangeName
* ScNameDlg::GetRangeName(const OUString
& rScope
)
304 if (rScope
== maGlobalNameStr
)
305 return maRangeMap
.find(OUString(STR_GLOBAL_RANGE_NAME
))->second
;
307 return maRangeMap
.find(rScope
)->second
;
310 void ScNameDlg::ShowOptions(const ScRangeNameLine
& rLine
)
312 ScRangeName
* pRangeName
= GetRangeName(rLine
.aScope
);
313 ScRangeData
* pData
= pRangeName
->findByUpperName(ScGlobal::pCharClass
->uppercase(rLine
.aName
));
321 bool ScNameDlg::AddPushed()
323 mbCloseWithoutUndo
= true;
324 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
325 pViewSh
->SwitchBetweenRefDialogs(this);
329 void ScNameDlg::SetEntry(const OUString
& rName
, const OUString
& rScope
)
331 if (!rName
.isEmpty())
333 mbDataChanged
= true;
334 ScRangeNameLine aLine
;
336 aLine
.aScope
= rScope
;
337 m_pRangeManagerTable
->SetEntry(aLine
);
341 void ScNameDlg::RemovePushed()
343 std::vector
<ScRangeNameLine
> maEntries
= m_pRangeManagerTable
->GetSelectedEntries();
344 m_pRangeManagerTable
->DeleteSelectedEntries();
345 for (std::vector
<ScRangeNameLine
>::iterator itr
= maEntries
.begin(); itr
!= maEntries
.end(); ++itr
)
347 ScRangeName
* pRangeName
= GetRangeName(itr
->aScope
);
348 ScRangeData
* pData
= pRangeName
->findByUpperName(ScGlobal::pCharClass
->uppercase(itr
->aName
));
349 OSL_ENSURE(pData
, "table and model should be in sync");
350 // be safe and check for possible problems
352 pRangeName
->erase(*pData
);
354 mbDataChanged
= true;
356 CheckForEmptyTable();
359 void ScNameDlg::NameModified()
361 ScRangeNameLine aLine
;
362 m_pRangeManagerTable
->GetCurrentLine(aLine
);
363 OUString aOldName
= aLine
.aName
;
364 OUString aNewName
= m_pEdName
->GetText();
365 aNewName
= aNewName
.trim();
366 m_pFtInfo
->SetControlBackground(GetSettings().GetStyleSettings().GetDialogColor());
367 if (aNewName
!= aOldName
)
374 m_pFtInfo
->SetText( maStrInfoDefault
);
377 if (!IsFormulaValid())
379 //TODO: implement an info text
383 OUString aOldScope
= aLine
.aScope
;
385 if (aOldScope
.isEmpty())
387 OUString aExpr
= m_pEdAssign
->GetText();
388 OUString aNewScope
= m_pLbScope
->GetSelectEntry();
390 ScRangeName
* pOldRangeName
= GetRangeName( aOldScope
);
391 ScRangeData
* pData
= pOldRangeName
->findByUpperName( ScGlobal::pCharClass
->uppercase(aOldName
) );
392 ScRangeName
* pNewRangeName
= GetRangeName( aNewScope
);
393 OSL_ENSURE(pData
, "model and table should be in sync");
394 // be safe and check for range data
397 pOldRangeName
->erase(*pData
);
398 mbNeedUpdate
= false;
399 m_pRangeManagerTable
->DeleteSelectedEntries();
400 RangeType nType
= RT_NAME
|
401 (m_pBtnRowHeader
->IsChecked() ? RT_ROWHEADER
: RangeType(0))
402 |(m_pBtnColHeader
->IsChecked() ? RT_COLHEADER
: RangeType(0))
403 |(m_pBtnPrintArea
->IsChecked() ? RT_PRINTAREA
: RangeType(0))
404 |(m_pBtnCriteria
->IsChecked() ? RT_CRITERIA
: RangeType(0));
406 ScRangeData
* pNewEntry
= new ScRangeData( mpDoc
, aNewName
, aExpr
,
408 pNewRangeName
->insert(pNewEntry
);
409 aLine
.aName
= aNewName
;
410 aLine
.aExpression
= aExpr
;
411 aLine
.aScope
= aNewScope
;
412 m_pRangeManagerTable
->addEntry(aLine
);
414 mbDataChanged
= true;
418 void ScNameDlg::SelectionChanged()
420 //don't update if we have just modified due to user input
426 if (m_pRangeManagerTable
->IsMultiSelection())
428 m_pEdName
->SetText(maStrMultiSelect
);
429 m_pEdAssign
->SetText(maStrMultiSelect
);
431 m_pEdName
->Disable();
432 m_pEdAssign
->Disable();
433 m_pRbAssign
->Disable();
434 m_pLbScope
->Disable();
435 m_pBtnRowHeader
->Disable();
436 m_pBtnColHeader
->Disable();
437 m_pBtnPrintArea
->Disable();
438 m_pBtnCriteria
->Disable();
442 ScRangeNameLine aLine
;
443 m_pRangeManagerTable
->GetCurrentLine(aLine
);
444 m_pEdAssign
->SetText(aLine
.aExpression
);
445 m_pEdName
->SetText(aLine
.aName
);
446 m_pLbScope
->SelectEntry(aLine
.aScope
);
448 m_pBtnDelete
->Enable();
450 m_pEdAssign
->Enable();
451 m_pRbAssign
->Enable();
452 m_pLbScope
->Enable();
453 m_pBtnRowHeader
->Enable();
454 m_pBtnColHeader
->Enable();
455 m_pBtnPrintArea
->Enable();
456 m_pBtnCriteria
->Enable();
460 void ScNameDlg::ScopeChanged()
465 void ScNameDlg::GetRangeNames(boost::ptr_map
<OUString
, ScRangeName
>& rRangeMap
)
467 maRangeMap
.swap(rRangeMap
);
470 IMPL_LINK_NOARG(ScNameDlg
, OkBtnHdl
)
476 IMPL_LINK_NOARG(ScNameDlg
, CancelBtnHdl
)
482 IMPL_LINK_NOARG(ScNameDlg
, AddBtnHdl
)
487 IMPL_LINK_NOARG(ScNameDlg
, RemoveBtnHdl
)
493 IMPL_LINK_NOARG(ScNameDlg
, EdModifyHdl
)
499 IMPL_LINK_NOARG(ScNameDlg
, AssignGetFocusHdl
)
501 EdModifyHdl(m_pEdAssign
);
505 IMPL_LINK_NOARG(ScNameDlg
, SelectionChangedHdl_Impl
)
511 IMPL_LINK_NOARG(ScNameDlg
, ScopeChangedHdl
)
517 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */