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 .
20 #include <reffact.hxx>
21 #include <document.hxx>
22 #include <globstr.hrc>
23 #include <scresid.hxx>
25 #include <crnrdlg.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/weld.hxx>
28 #include <o3tl/string_view.hxx>
33 void ERRORBOX(weld::Window
* pParent
, const OUString
& rString
)
35 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(pParent
,
36 VclMessageType::Warning
, VclButtonsType::Ok
,
41 int QUERYBOX(weld::Window
* pParent
, const OUString
& rString
)
43 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(pParent
,
44 VclMessageType::Question
, VclButtonsType::YesNo
,
46 xBox
->set_default_response(RET_YES
);
52 const sal_uLong nEntryDataCol
= 0;
53 const sal_uLong nEntryDataRow
= 1;
54 const sal_uLong nEntryDataDelim
= 2;
57 // note: some of the initialisation is done in Init
58 ScColRowNameRangesDlg::ScColRowNameRangesDlg( SfxBindings
* pB
,
60 weld::Window
* pParent
,
61 ScViewData
& rViewData
)
63 : ScAnyRefDlgController(pB
, pCW
, pParent
, u
"modules/scalc/ui/namerangesdialog.ui"_ustr
, u
"NameRangesDialog"_ustr
)
64 , m_rViewData(rViewData
)
65 , rDoc(rViewData
.GetDocument())
66 , bDlgLostFocus(false)
67 , m_pEdActive(nullptr)
68 , m_xLbRange(m_xBuilder
->weld_tree_view(u
"range"_ustr
))
69 , m_xEdAssign(new formula::RefEdit(m_xBuilder
->weld_entry(u
"edassign"_ustr
)))
70 , m_xRbAssign(new formula::RefButton(m_xBuilder
->weld_button(u
"rbassign"_ustr
)))
71 , m_xBtnColHead(m_xBuilder
->weld_radio_button(u
"colhead"_ustr
))
72 , m_xBtnRowHead(m_xBuilder
->weld_radio_button(u
"rowhead"_ustr
))
73 , m_xEdAssign2(new formula::RefEdit(m_xBuilder
->weld_entry(u
"edassign2"_ustr
)))
74 , m_xRbAssign2(new formula::RefButton(m_xBuilder
->weld_button(u
"rbassign2"_ustr
)))
75 , m_xBtnOk(m_xBuilder
->weld_button(u
"ok"_ustr
))
76 , m_xBtnCancel(m_xBuilder
->weld_button(u
"cancel"_ustr
))
77 , m_xBtnAdd(m_xBuilder
->weld_button(u
"add"_ustr
))
78 , m_xBtnRemove(m_xBuilder
->weld_button(u
"delete"_ustr
))
79 , m_xRangeFrame(m_xBuilder
->weld_frame(u
"rangeframe"_ustr
))
80 , m_xRangeFT(m_xRangeFrame
->weld_label_widget())
81 , m_xDataFT(m_xBuilder
->weld_label(u
"datarange"_ustr
))
83 m_xRbAssign
->SetReferences(this, m_xEdAssign
.get());
84 m_xEdAssign
->SetReferences(this, m_xRangeFT
.get());
85 m_xRbAssign2
->SetReferences(this, m_xEdAssign2
.get());
86 m_xEdAssign2
->SetReferences(this, m_xDataFT
.get());
88 xColNameRanges
= rDoc
.GetColNameRanges()->Clone();
89 xRowNameRanges
= rDoc
.GetRowNameRanges()->Clone();
93 ScColRowNameRangesDlg::~ScColRowNameRangesDlg()
97 // initialises event handlers and start parameters in the dialog
98 void ScColRowNameRangesDlg::Init()
100 m_xBtnOk
->connect_clicked ( LINK( this, ScColRowNameRangesDlg
, OkBtnHdl
) );
101 m_xBtnCancel
->connect_clicked ( LINK( this, ScColRowNameRangesDlg
, CancelBtnHdl
) );
102 m_xBtnAdd
->connect_clicked ( LINK( this, ScColRowNameRangesDlg
, AddBtnHdl
) );
103 m_xBtnRemove
->connect_clicked ( LINK( this, ScColRowNameRangesDlg
, RemoveBtnHdl
) );
104 m_xLbRange
->connect_selection_changed(LINK(this, ScColRowNameRangesDlg
, Range1SelectHdl
));
105 m_xEdAssign
->SetModifyHdl ( LINK( this, ScColRowNameRangesDlg
, Range1DataModifyHdl
) );
106 m_xBtnColHead
->connect_toggled ( LINK( this, ScColRowNameRangesDlg
, ColRowToggleHdl
) );
107 m_xEdAssign2
->SetModifyHdl ( LINK( this, ScColRowNameRangesDlg
, Range2DataModifyHdl
) );
109 Link
<formula::RefEdit
&,void> aEditLink
= LINK( this, ScColRowNameRangesDlg
, GetEditFocusHdl
);
110 m_xEdAssign
->SetGetFocusHdl( aEditLink
);
111 m_xEdAssign2
->SetGetFocusHdl( aEditLink
);
113 Link
<formula::RefButton
&,void> aButtonLink
= LINK( this, ScColRowNameRangesDlg
, GetButtonFocusHdl
);
114 m_xRbAssign
->SetGetFocusHdl( aButtonLink
);
115 m_xRbAssign2
->SetGetFocusHdl( aButtonLink
);
117 aEditLink
= LINK( this, ScColRowNameRangesDlg
, LoseEditFocusHdl
);
118 m_xEdAssign
->SetLoseFocusHdl( aEditLink
);
119 m_xEdAssign2
->SetLoseFocusHdl( aEditLink
);
121 aButtonLink
= LINK( this, ScColRowNameRangesDlg
, LoseButtonFocusHdl
);
122 m_xRbAssign2
->SetLoseFocusHdl( aButtonLink
);
123 m_xRbAssign
->SetLoseFocusHdl( aButtonLink
);
125 m_pEdActive
= m_xEdAssign
.get();
135 m_rViewData
.GetSimpleArea(nStartCol
, nStartRow
, nStartTab
,
136 nEndCol
, nEndRow
, nEndTab
);
137 SetColRowData( ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
));
139 m_xBtnColHead
->set_sensitive(true);
140 m_xBtnRowHead
->set_sensitive(true);
141 m_xEdAssign
->GetWidget()->set_sensitive(true);
142 m_xEdAssign
->GrabFocus();
143 m_xRbAssign
->GetWidget()->set_sensitive(true);
145 Range1SelectHdl( *m_xLbRange
);
148 // set data range of a labeled range to default values and set the
149 // form elements for the reference
150 void ScColRowNameRangesDlg::SetColRowData( const ScRange
& rLabelRange
, bool bRef
)
152 theCurData
= theCurArea
= rLabelRange
;
154 SCCOL nCol1
= theCurArea
.aStart
.Col();
155 SCCOL nCol2
= theCurArea
.aEnd
.Col();
156 SCROW nRow1
= theCurArea
.aStart
.Row();
157 SCROW nRow2
= theCurArea
.aEnd
.Row();
158 if ( (static_cast<SCCOLROW
>(nCol2
- nCol1
) >= nRow2
- nRow1
) || (nCol1
== 0 && nCol2
== rDoc
.MaxCol()) )
159 { // Column headers and the limiting case of the whole sheet
160 m_xBtnColHead
->set_active(true);
161 m_xBtnRowHead
->set_active(false);
162 if ( nRow2
== rDoc
.MaxRow() )
165 bValid
= false; // limiting case of the whole sheet
167 { // Header at bottom, data above
168 theCurData
.aStart
.SetRow( 0 );
169 theCurData
.aEnd
.SetRow( nRow1
- 1 );
173 { // Header at top, data below
174 theCurData
.aStart
.SetRow( nRow2
+ 1 );
175 theCurData
.aEnd
.SetRow( rDoc
.MaxRow() );
180 m_xBtnRowHead
->set_active(true);
181 m_xBtnColHead
->set_active(false);
182 if ( nCol2
== rDoc
.MaxCol() )
183 { // Header at the right, data to the left
184 theCurData
.aStart
.SetCol( 0 );
185 theCurData
.aEnd
.SetCol( nCol2
- 1 );
188 { // Header at the left, data to the right
189 theCurData
.aStart
.SetCol( nCol2
+ 1 );
190 theCurData
.aEnd
.SetCol( rDoc
.MaxCol() );
195 const formula::FormulaGrammar::AddressConvention eConv
= rDoc
.GetAddressConvention();
196 OUString
aStr(theCurArea
.Format(rDoc
, ScRefFlags::RANGE_ABS_3D
, eConv
));
199 m_xEdAssign
->SetRefString( aStr
);
201 m_xEdAssign
->SetText( aStr
);
203 m_xEdAssign
->SetCursorAtLast();
204 aStr
= theCurData
.Format(rDoc
, ScRefFlags::RANGE_ABS_3D
, eConv
);
207 m_xEdAssign2
->SetRefString( aStr
);
209 m_xEdAssign2
->SetText( aStr
);
213 theCurData
= theCurArea
= ScRange();
217 m_xEdAssign
->SetRefString( OUString() );
218 m_xEdAssign2
->SetRefString( OUString() );
222 m_xEdAssign
->SetText( OUString() );
223 m_xEdAssign2
->SetText( OUString() );
226 m_xBtnColHead
->set_sensitive(false);
227 m_xBtnRowHead
->set_sensitive(false);
228 m_xEdAssign2
->GetWidget()->set_sensitive(false);
229 m_xRbAssign2
->GetWidget()->set_sensitive(false);
233 // adjust label range and set the data reference form element
234 void ScColRowNameRangesDlg::AdjustColRowData( const ScRange
& rDataRange
, bool bRef
)
236 theCurData
= rDataRange
;
237 if ( m_xBtnColHead
->get_active() )
238 { // Data range is the same columns as the header
239 theCurData
.aStart
.SetCol( theCurArea
.aStart
.Col() );
240 theCurData
.aEnd
.SetCol( theCurArea
.aEnd
.Col() );
241 if ( theCurData
.Intersects( theCurArea
) )
243 SCROW nRow1
= theCurArea
.aStart
.Row();
244 SCROW nRow2
= theCurArea
.aEnd
.Row();
246 && (theCurData
.aEnd
.Row() < nRow2
|| nRow2
== rDoc
.MaxRow()) )
247 { // Data above header
248 theCurData
.aEnd
.SetRow( nRow1
- 1 );
249 if ( theCurData
.aStart
.Row() > theCurData
.aEnd
.Row() )
250 theCurData
.aStart
.SetRow( theCurData
.aEnd
.Row() );
253 { // Data below header
254 theCurData
.aStart
.SetRow( nRow2
+ 1 );
255 if ( theCurData
.aStart
.Row() > theCurData
.aEnd
.Row() )
256 theCurData
.aEnd
.SetRow( theCurData
.aStart
.Row() );
261 { // Data range in the same rows as header
262 theCurData
.aStart
.SetRow( theCurArea
.aStart
.Row() );
263 theCurData
.aEnd
.SetRow( theCurArea
.aEnd
.Row() );
264 if ( theCurData
.Intersects( theCurArea
) )
266 SCCOL nCol1
= theCurArea
.aStart
.Col();
267 SCCOL nCol2
= theCurArea
.aEnd
.Col();
269 && (theCurData
.aEnd
.Col() < nCol2
|| nCol2
== rDoc
.MaxCol()) )
270 { // Data left of header
271 theCurData
.aEnd
.SetCol( nCol1
- 1 );
272 if ( theCurData
.aStart
.Col() > theCurData
.aEnd
.Col() )
273 theCurData
.aStart
.SetCol( theCurData
.aEnd
.Col() );
276 { // Data right of header
277 theCurData
.aStart
.SetCol( nCol2
+ 1 );
278 if ( theCurData
.aStart
.Col() > theCurData
.aEnd
.Col() )
279 theCurData
.aEnd
.SetCol( theCurData
.aStart
.Col() );
283 OUString
aStr(theCurData
.Format(rDoc
, ScRefFlags::RANGE_ABS_3D
, rDoc
.GetAddressConvention()));
286 m_xEdAssign2
->SetRefString( aStr
);
288 m_xEdAssign2
->SetText( aStr
);
290 m_xEdAssign2
->SetCursorAtLast();
293 // Set the reference to a cell range selected with the mouse and update
294 // the selection form element
295 void ScColRowNameRangesDlg::SetReference( const ScRange
& rRef
, ScDocument
& /* rDoc */ )
300 if ( rRef
.aStart
!= rRef
.aEnd
)
301 RefInputStart( m_pEdActive
);
303 if (m_pEdActive
== m_xEdAssign
.get())
304 SetColRowData( rRef
, true );
306 AdjustColRowData( rRef
, true );
307 m_xBtnColHead
->set_sensitive(true);
308 m_xBtnRowHead
->set_sensitive(true);
309 m_xBtnAdd
->set_sensitive(true);
310 m_xBtnRemove
->set_sensitive(false);
313 void ScColRowNameRangesDlg::Close()
315 DoClose( ScColRowNameRangesDlgWrapper::GetChildWindowId() );
318 void ScColRowNameRangesDlg::SetActive()
322 bDlgLostFocus
= false;
324 m_pEdActive
->GrabFocus();
327 m_xDialog
->grab_focus();
329 if( m_pEdActive
== m_xEdAssign
.get() )
330 Range1DataModifyHdl( *m_xEdAssign
);
331 else if( m_pEdActive
== m_xEdAssign2
.get() )
332 Range2DataModifyHdl( *m_xEdAssign2
);
337 void ScColRowNameRangesDlg::UpdateNames()
339 m_xLbRange
->freeze();
343 m_xEdAssign
->SetText( OUString() );
348 SCROW nRow1
; //Extension for range names
354 const ScAddress::Details
aDetails(rDoc
.GetAddressConvention());
356 OUString
strDelim(u
" --- "_ustr
);
357 OUString aString
= strDelim
+ ScResId( STR_COLUMN
) + strDelim
;
358 m_xLbRange
->append(OUString::number(nEntryDataDelim
), aString
);
359 if ( xColNameRanges
->size() > 0 )
361 std::vector
<const ScRangePair
*> aSortArray(xColNameRanges
->CreateNameSortedArray(
363 nCount
= aSortArray
.size();
364 for ( j
=0; j
< nCount
; j
++ )
366 const ScRange
aRange(aSortArray
[j
]->GetRange(0));
367 aString
= aRange
.Format(rDoc
, ScRefFlags::RANGE_ABS_3D
, aDetails
);
369 //@008 get range parameters from document
370 aSortArray
[j
]->GetRange(0).GetVars( nCol1
, nRow1
, nTab1
,
371 nCol2
, nRow2
, nTab2
);
374 //@008 construct string
375 OUStringBuffer strShow
= " [";
376 rString
= rDoc
.GetString(nCol1
, nRow1
, nTab1
);
377 strShow
.append(rString
);
378 for(SCCOL i
=nCol1
+1;i
<=q
;i
++)
380 strShow
.append(", ");
381 rString
= rDoc
.GetString(i
, nRow1
, nTab1
);
382 strShow
.append(rString
);
384 if(q
<nCol2
) // Too long? Add ",..."
386 strShow
.append(", ...");
390 //@008 Add string to listbox
391 OUString aInsStr
= aString
+ strShow
;
392 aRangeMap
.emplace( aInsStr
, aRange
);
393 m_xLbRange
->append(OUString::number(nEntryDataCol
), aInsStr
);
396 aString
= strDelim
+ ScResId( STR_ROW
) + strDelim
;
397 m_xLbRange
->append(OUString::number(nEntryDataDelim
), aString
);
398 if ( xRowNameRanges
->size() > 0 )
400 std::vector
<const ScRangePair
*> aSortArray(xRowNameRanges
->CreateNameSortedArray(
402 nCount
= aSortArray
.size();
403 for ( j
=0; j
< nCount
; j
++ )
405 const ScRange
aRange(aSortArray
[j
]->GetRange(0));
406 aString
= aRange
.Format(rDoc
, ScRefFlags::RANGE_ABS_3D
, aDetails
);
408 //@008 Build string for rows below
409 aSortArray
[j
]->GetRange(0).GetVars( nCol1
, nRow1
, nTab1
,
410 nCol2
, nRow2
, nTab2
);
413 OUStringBuffer strShow
= " [";
414 rString
= rDoc
.GetString(nCol1
, nRow1
, nTab1
);
415 strShow
.append(rString
);
416 for(SCROW i
=nRow1
+1;i
<=q
;i
++)
418 strShow
.append(", ");
419 rString
= rDoc
.GetString(nCol1
, i
, nTab1
);
420 strShow
.append(rString
);
424 strShow
.append(", ...");
428 OUString aInsStr
= aString
+ strShow
;
429 aRangeMap
.emplace( aInsStr
, aRange
);
430 m_xLbRange
->append(OUString::number(nEntryDataRow
), aInsStr
);
437 void ScColRowNameRangesDlg::UpdateRangeData( const ScRange
& rRange
, bool bColName
)
439 ScRangePair
* pPair
= nullptr;
441 if ( bColName
&& (pPair
= xColNameRanges
->Find( rRange
)) != nullptr )
443 else if ( !bColName
&& (pPair
= xRowNameRanges
->Find( rRange
)) != nullptr )
448 const formula::FormulaGrammar::AddressConvention eConv
= rDoc
.GetAddressConvention();
450 OUString
aStr(theCurArea
.Format(rDoc
, ScRefFlags::RANGE_ABS_3D
, eConv
));
451 m_xEdAssign
->SetText( aStr
);
452 m_xBtnAdd
->set_sensitive(false);
453 m_xBtnRemove
->set_sensitive(true);
454 m_xBtnColHead
->set_active(bColName
);
455 m_xBtnRowHead
->set_active(!bColName
);
456 theCurData
= pPair
->GetRange(1);
457 aStr
= theCurData
.Format(rDoc
, ScRefFlags::RANGE_ABS_3D
, eConv
);
458 m_xEdAssign2
->SetText( aStr
);
462 m_xBtnAdd
->set_sensitive(true);
463 m_xBtnRemove
->set_sensitive(false);
465 m_xBtnColHead
->set_sensitive(true);
466 m_xBtnRowHead
->set_sensitive(true);
467 m_xEdAssign2
->GetWidget()->set_sensitive(true);
468 m_xRbAssign2
->GetWidget()->set_sensitive(true);
471 bool ScColRowNameRangesDlg::IsRefInputMode() const
473 return (m_pEdActive
!= nullptr);
478 // handler called when OK is clicked, calls the add button handler before
479 // passing the range lists to the document
480 IMPL_LINK_NOARG(ScColRowNameRangesDlg
, OkBtnHdl
, weld::Button
&, void)
482 AddBtnHdl(*m_xBtnAdd
);
484 // assign RangeLists to the references in the document
485 rDoc
.GetColNameRangesRef() = xColNameRanges
;
486 rDoc
.GetRowNameRangesRef() = xRowNameRanges
;
487 // changed ranges need to take effect
488 rDoc
.CompileColRowNameFormula();
489 ScDocShell
* pDocShell
= m_rViewData
.GetDocShell();
490 pDocShell
->PostPaint(ScRange(0, 0, 0, rDoc
.MaxCol(), rDoc
.MaxRow(), MAXTAB
), PaintPartFlags::Grid
);
491 pDocShell
->SetDocumentModified();
496 IMPL_LINK_NOARG(ScColRowNameRangesDlg
, CancelBtnHdl
, weld::Button
&, void)
498 response(RET_CANCEL
);
501 // handler called when add button clicked: set ranges and add to listbox
502 IMPL_LINK_NOARG(ScColRowNameRangesDlg
, AddBtnHdl
, weld::Button
&, void)
504 OUString
aNewArea( m_xEdAssign
->GetText() );
505 OUString
aNewData( m_xEdAssign2
->GetText() );
507 if (aNewArea
.isEmpty() || aNewData
.isEmpty())
510 const formula::FormulaGrammar::AddressConvention eConv
= rDoc
.GetAddressConvention();
511 ScRange aRange1
, aRange2
;
512 bool bOk1
= (aRange1
.ParseAny( aNewArea
, rDoc
, eConv
) & ScRefFlags::VALID
) == ScRefFlags::VALID
;
513 if ( bOk1
&& (aRange2
.ParseAny( aNewData
, rDoc
, eConv
) & ScRefFlags::VALID
) == ScRefFlags::VALID
)
515 theCurArea
= aRange1
;
516 AdjustColRowData( aRange2
);
518 if ( ( pPair
= xColNameRanges
->Find( theCurArea
) ) != nullptr )
520 xColNameRanges
->Remove( *pPair
);
522 if ( ( pPair
= xRowNameRanges
->Find( theCurArea
) ) != nullptr )
524 xRowNameRanges
->Remove( *pPair
);
526 if ( m_xBtnColHead
->get_active() )
527 xColNameRanges
->Join( ScRangePair( theCurArea
, theCurData
) );
529 xRowNameRanges
->Join( ScRangePair( theCurArea
, theCurData
) );
533 m_xEdAssign
->GrabFocus();
534 m_xBtnAdd
->set_sensitive(false);
535 m_xBtnRemove
->set_sensitive(false);
536 m_xEdAssign
->SetText( OUString() );
537 m_xBtnColHead
->set_active(true);
538 m_xBtnRowHead
->set_active(false);
539 m_xEdAssign2
->SetText( OUString() );
540 theCurArea
= ScRange();
541 theCurData
= theCurArea
;
542 Range1SelectHdl( *m_xLbRange
);
546 ERRORBOX(m_xDialog
.get(), ScResId(STR_INVALIDTABNAME
));
548 m_xEdAssign
->GrabFocus();
550 m_xEdAssign2
->GrabFocus();
554 IMPL_LINK_NOARG(ScColRowNameRangesDlg
, RemoveBtnHdl
, weld::Button
&, void)
556 OUString aRangeStr
= m_xLbRange
->get_selected_text();
557 sal_Int32 nSelectPos
= m_xLbRange
->get_selected_index();
558 bool bColName
= nSelectPos
!= -1 && m_xLbRange
->get_id(nSelectPos
).toInt32() == nEntryDataCol
;
559 NameRangeMap::const_iterator itr
= aRangeMap
.find(aRangeStr
);
560 if (itr
== aRangeMap
.end())
562 const ScRange
& rRange
= itr
->second
;
564 ScRangePair
* pPair
= nullptr;
566 if ( bColName
&& (pPair
= xColNameRanges
->Find( rRange
)) != nullptr )
568 else if ( !bColName
&& (pPair
= xRowNameRanges
->Find( rRange
)) != nullptr )
573 OUString aStrDelMsg
= ScResId( STR_QUERY_DELENTRY
);
574 OUString aMsg
= o3tl::getToken(aStrDelMsg
, 0, '#' )
576 + o3tl::getToken(aStrDelMsg
, 1, '#' );
578 if (RET_YES
!= QUERYBOX(m_xDialog
.get(), aMsg
))
582 xColNameRanges
->Remove( *pPair
);
584 xRowNameRanges
->Remove( *pPair
);
587 const sal_Int32 nCnt
= m_xLbRange
->n_children();
588 if ( nSelectPos
>= nCnt
)
591 nSelectPos
= nCnt
- 1;
595 m_xLbRange
->select(nSelectPos
);
596 if (nSelectPos
&& m_xLbRange
->get_id(nSelectPos
).toInt32() == nEntryDataDelim
)
597 m_xLbRange
->select( --nSelectPos
); // ---Row---
599 m_xLbRange
->grab_focus();
600 m_xBtnAdd
->set_sensitive(false);
601 m_xBtnRemove
->set_sensitive(false);
602 m_xEdAssign
->SetText( OUString() );
603 theCurArea
= theCurData
= ScRange();
604 m_xBtnColHead
->set_active(true);
605 m_xBtnRowHead
->set_active(false);
606 m_xEdAssign2
->SetText( OUString() );
607 Range1SelectHdl( *m_xLbRange
);
610 // handler called when a row in the listbox is selected, updates form input fields
611 IMPL_LINK_NOARG(ScColRowNameRangesDlg
, Range1SelectHdl
, weld::TreeView
&, void)
613 sal_Int32 nSelectPos
= m_xLbRange
->get_selected_index();
614 const sal_Int32 nCnt
= m_xLbRange
->n_children();
615 sal_uInt16 nMoves
= 0;
616 while (nSelectPos
!= -1 && nSelectPos
< nCnt
&& m_xLbRange
->get_id(nSelectPos
).toInt32() == nEntryDataDelim
)
621 OUString aRangeStr
= m_xLbRange
->get_selected_text();
624 if ( nSelectPos
> 1 && nSelectPos
>= nCnt
)
625 { // if entries exist before the " --- Row --- " Delimiter then
626 // do not stop at the delimiter
627 nSelectPos
= nCnt
- 2;
628 m_xLbRange
->select(nSelectPos
);
629 aRangeStr
= m_xLbRange
->get_selected_text();
631 else if ( nSelectPos
> 2 && nSelectPos
< nCnt
&& !aRangeStr
.isEmpty()
632 && aRangeStr
== m_xEdAssign
->GetText() )
633 { // move upwards instead of below to the previous position
635 m_xLbRange
->select( nSelectPos
);
636 aRangeStr
= m_xLbRange
->get_selected_text();
639 m_xLbRange
->select(nSelectPos
);
641 NameRangeMap::const_iterator itr
= aRangeMap
.find(aRangeStr
);
642 if ( itr
!= aRangeMap
.end() )
644 bool bColName
= m_xLbRange
->get_id(nSelectPos
).toInt32() == nEntryDataCol
;
645 UpdateRangeData( itr
->second
, bColName
);
646 m_xBtnAdd
->set_sensitive(false);
647 m_xBtnRemove
->set_sensitive(true);
651 if ( !m_xEdAssign
->GetText().isEmpty() )
653 if ( !m_xEdAssign2
->GetText().isEmpty() )
654 m_xBtnAdd
->set_sensitive(true);
656 m_xBtnAdd
->set_sensitive(false);
657 m_xBtnColHead
->set_sensitive(true);
658 m_xBtnRowHead
->set_sensitive(true);
659 m_xEdAssign2
->GetWidget()->set_sensitive(true);
660 m_xRbAssign2
->GetWidget()->set_sensitive(true);
664 m_xBtnAdd
->set_sensitive(false);
665 m_xBtnColHead
->set_sensitive(false);
666 m_xBtnRowHead
->set_sensitive(false);
667 m_xEdAssign2
->GetWidget()->set_sensitive(false);
668 m_xRbAssign2
->GetWidget()->set_sensitive(false);
670 m_xBtnRemove
->set_sensitive(false);
671 m_xEdAssign
->GrabFocus();
674 m_xEdAssign
->GetWidget()->set_sensitive(true);
675 m_xRbAssign
->GetWidget()->set_sensitive(true);
678 // handler called when the label range has changed
679 IMPL_LINK_NOARG(ScColRowNameRangesDlg
, Range1DataModifyHdl
, formula::RefEdit
&, void)
681 OUString
aNewArea( m_xEdAssign
->GetText() );
683 if (!aNewArea
.isEmpty())
686 if ( (aRange
.ParseAny(aNewArea
, rDoc
, rDoc
.GetAddressConvention() ) & ScRefFlags::VALID
) == ScRefFlags::VALID
)
688 SetColRowData( aRange
);
694 m_xBtnAdd
->set_sensitive(true);
695 m_xBtnColHead
->set_sensitive(true);
696 m_xBtnRowHead
->set_sensitive(true);
697 m_xEdAssign2
->GetWidget()->set_sensitive(true);
698 m_xRbAssign2
->GetWidget()->set_sensitive(true);
702 m_xBtnAdd
->set_sensitive(false);
703 m_xBtnColHead
->set_sensitive(false);
704 m_xBtnRowHead
->set_sensitive(false);
705 m_xEdAssign2
->GetWidget()->set_sensitive(false);
706 m_xRbAssign2
->GetWidget()->set_sensitive(false);
708 m_xBtnRemove
->set_sensitive(false);
711 // handler called when the data range has changed
712 IMPL_LINK_NOARG(ScColRowNameRangesDlg
, Range2DataModifyHdl
, formula::RefEdit
&, void)
714 OUString
aNewData( m_xEdAssign2
->GetText() );
715 if ( !aNewData
.isEmpty() )
718 if ( (aRange
.ParseAny(aNewData
, rDoc
, rDoc
.GetAddressConvention() ) & ScRefFlags::VALID
) == ScRefFlags::VALID
)
720 AdjustColRowData( aRange
);
721 m_xBtnAdd
->set_sensitive(true);
724 m_xBtnAdd
->set_sensitive(false);
728 m_xBtnAdd
->set_sensitive(false);
732 IMPL_LINK_NOARG(ScColRowNameRangesDlg
, ColRowToggleHdl
, weld::Toggleable
&, void)
734 if (m_xBtnColHead
->get_active())
736 // handler for the radio button for columns, adjust ranges
737 if ( theCurArea
.aStart
.Row() == 0 && theCurArea
.aEnd
.Row() == rDoc
.MaxRow() )
739 theCurArea
.aEnd
.SetRow( rDoc
.MaxRow() - 1 );
740 OUString
aStr(theCurArea
.Format(rDoc
, ScRefFlags::RANGE_ABS_3D
, rDoc
.GetAddressConvention()));
741 m_xEdAssign
->SetText( aStr
);
743 ScRange
aRange( theCurData
);
744 aRange
.aStart
.SetRow( std::min( static_cast<tools::Long
>(theCurArea
.aEnd
.Row() + 1), static_cast<tools::Long
>(rDoc
.MaxRow()) ) );
745 aRange
.aEnd
.SetRow( rDoc
.MaxRow() );
746 AdjustColRowData( aRange
);
748 else if (m_xBtnRowHead
->get_active())
750 // handler for the radio button for columns, adjust range
751 if ( theCurArea
.aStart
.Col() == 0 && theCurArea
.aEnd
.Col() == rDoc
.MaxCol() )
753 theCurArea
.aEnd
.SetCol( rDoc
.MaxCol() - 1 );
754 OUString
aStr(theCurArea
.Format(rDoc
, ScRefFlags::RANGE_ABS_3D
, rDoc
.GetAddressConvention()));
755 m_xEdAssign
->SetText( aStr
);
757 ScRange
aRange( theCurData
);
758 aRange
.aStart
.SetCol( static_cast<SCCOL
>(std::min( static_cast<tools::Long
>(theCurArea
.aEnd
.Col() + 1), static_cast<tools::Long
>(rDoc
.MaxCol()) )) );
759 aRange
.aEnd
.SetCol( rDoc
.MaxCol() );
760 AdjustColRowData( aRange
);
764 IMPL_LINK( ScColRowNameRangesDlg
, GetEditFocusHdl
, formula::RefEdit
&, rCtrl
, void )
766 if (&rCtrl
== m_xEdAssign
.get())
767 m_pEdActive
= m_xEdAssign
.get();
768 else if (&rCtrl
== m_xEdAssign2
.get())
769 m_pEdActive
= m_xEdAssign2
.get();
771 m_pEdActive
= nullptr;
774 m_pEdActive
->SelectAll();
777 IMPL_LINK( ScColRowNameRangesDlg
, GetButtonFocusHdl
, formula::RefButton
&, rCtrl
, void )
779 if (&rCtrl
== m_xRbAssign
.get())
780 m_pEdActive
= m_xEdAssign
.get();
781 else if (&rCtrl
== m_xRbAssign2
.get())
782 m_pEdActive
= m_xEdAssign2
.get();
784 m_pEdActive
= nullptr;
787 m_pEdActive
->SelectAll();
790 IMPL_LINK_NOARG(ScColRowNameRangesDlg
, LoseEditFocusHdl
, formula::RefEdit
&, void)
792 bDlgLostFocus
= !m_xDialog
->has_toplevel_focus();
795 IMPL_LINK_NOARG(ScColRowNameRangesDlg
, LoseButtonFocusHdl
, formula::RefButton
&, void)
797 bDlgLostFocus
= !m_xDialog
->has_toplevel_focus();
800 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */