LibreOffice Module sc (master)  1
crnrdlg.cxx
Go to the documentation of this file.
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  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <reffact.hxx>
21 #include <document.hxx>
22 #include <globstr.hrc>
23 #include <scresid.hxx>
24 #include <docsh.hxx>
25 #include <crnrdlg.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/weld.hxx>
28 #include <memory>
29 
30 namespace
31 {
32  void ERRORBOX(weld::Window* pParent, const OUString& rString)
33  {
34  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
35  VclMessageType::Warning, VclButtonsType::Ok,
36  rString));
37  xBox->run();
38  }
39 
40  int QUERYBOX(weld::Window* pParent, const OUString& rString)
41  {
42  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
43  VclMessageType::Question, VclButtonsType::YesNo,
44  rString));
45  xBox->set_default_response(RET_YES);
46  return xBox->run();
47  }
48 
49 }
50 
54 
55 
56 // note: some of the initialisation is done in Init
58  SfxChildWindow* pCW,
59  weld::Window* pParent,
60  ScViewData& rViewData )
61 
62  : ScAnyRefDlgController(pB, pCW, pParent, "modules/scalc/ui/namerangesdialog.ui", "NameRangesDialog")
63  , m_rViewData(rViewData)
64  , rDoc(rViewData.GetDocument())
65  , bDlgLostFocus(false)
66  , m_pEdActive(nullptr)
67  , m_xLbRange(m_xBuilder->weld_tree_view("range"))
68  , m_xEdAssign(new formula::RefEdit(m_xBuilder->weld_entry("edassign")))
69  , m_xRbAssign(new formula::RefButton(m_xBuilder->weld_button("rbassign")))
70  , m_xBtnColHead(m_xBuilder->weld_radio_button("colhead"))
71  , m_xBtnRowHead(m_xBuilder->weld_radio_button("rowhead"))
72  , m_xEdAssign2(new formula::RefEdit(m_xBuilder->weld_entry("edassign2")))
73  , m_xRbAssign2(new formula::RefButton(m_xBuilder->weld_button("rbassign2")))
74  , m_xBtnOk(m_xBuilder->weld_button("ok"))
75  , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
76  , m_xBtnAdd(m_xBuilder->weld_button("add"))
77  , m_xBtnRemove(m_xBuilder->weld_button("delete"))
78  , m_xRangeFrame(m_xBuilder->weld_frame("rangeframe"))
79  , m_xRangeFT(m_xRangeFrame->weld_label_widget())
80  , m_xDataFT(m_xBuilder->weld_label("datarange"))
81 {
82  m_xRbAssign->SetReferences(this, m_xEdAssign.get());
83  m_xEdAssign->SetReferences(this, m_xRangeFT.get());
84  m_xRbAssign2->SetReferences(this, m_xEdAssign2.get());
85  m_xEdAssign2->SetReferences(this, m_xDataFT.get());
86 
89  Init();
90 }
91 
93 {
94 }
95 
96 // initialises event handlers and start parameters in the dialog
98 {
99  m_xBtnOk->connect_clicked ( LINK( this, ScColRowNameRangesDlg, OkBtnHdl ) );
100  m_xBtnCancel->connect_clicked ( LINK( this, ScColRowNameRangesDlg, CancelBtnHdl ) );
101  m_xBtnAdd->connect_clicked ( LINK( this, ScColRowNameRangesDlg, AddBtnHdl ) );
102  m_xBtnRemove->connect_clicked ( LINK( this, ScColRowNameRangesDlg, RemoveBtnHdl ) );
103  m_xLbRange->connect_changed( LINK( this, ScColRowNameRangesDlg, Range1SelectHdl ) );
104  m_xEdAssign->SetModifyHdl ( LINK( this, ScColRowNameRangesDlg, Range1DataModifyHdl ) );
105  m_xBtnColHead->connect_clicked ( LINK( this, ScColRowNameRangesDlg, ColClickHdl ) );
106  m_xBtnRowHead->connect_clicked ( LINK( this, ScColRowNameRangesDlg, RowClickHdl ) );
107  m_xEdAssign2->SetModifyHdl ( LINK( this, ScColRowNameRangesDlg, Range2DataModifyHdl ) );
108 
109  Link<formula::RefEdit&,void> aEditLink = LINK( this, ScColRowNameRangesDlg, GetEditFocusHdl );
110  m_xEdAssign->SetGetFocusHdl( aEditLink );
111  m_xEdAssign2->SetGetFocusHdl( aEditLink );
112 
113  Link<formula::RefButton&,void> aButtonLink = LINK( this, ScColRowNameRangesDlg, GetButtonFocusHdl );
114  m_xRbAssign->SetGetFocusHdl( aButtonLink );
115  m_xRbAssign2->SetGetFocusHdl( aButtonLink );
116 
117  aEditLink = LINK( this, ScColRowNameRangesDlg, LoseEditFocusHdl );
118  m_xEdAssign->SetLoseFocusHdl( aEditLink );
119  m_xEdAssign2->SetLoseFocusHdl( aEditLink );
120 
121  aButtonLink = LINK( this, ScColRowNameRangesDlg, LoseButtonFocusHdl );
122  m_xRbAssign2->SetLoseFocusHdl( aButtonLink );
123  m_xRbAssign->SetLoseFocusHdl( aButtonLink );
124 
125  m_pEdActive = m_xEdAssign.get();
126 
127  UpdateNames();
128 
129  SCCOL nStartCol = 0;
130  SCROW nStartRow = 0;
131  SCTAB nStartTab = 0;
132  SCCOL nEndCol = 0;
133  SCROW nEndRow = 0;
134  SCTAB nEndTab = 0;
135  m_rViewData.GetSimpleArea(nStartCol, nStartRow, nStartTab,
136  nEndCol, nEndRow, nEndTab );
137  SetColRowData( ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab));
138 
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);
144 
145  Range1SelectHdl( *m_xLbRange );
146 }
147 
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)
151 {
152  theCurData = theCurArea = rLabelRange;
153  bool bValid = true;
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() )
163  {
164  if ( nRow1 == 0 )
165  bValid = false; // limiting case of the whole sheet
166  else
167  { // Header at bottom, data above
168  theCurData.aStart.SetRow( 0 );
169  theCurData.aEnd.SetRow( nRow1 - 1 );
170  }
171  }
172  else
173  { // Header at top, data below
174  theCurData.aStart.SetRow( nRow2 + 1 );
176  }
177  }
178  else
179  { // Column headers
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 );
186  }
187  else
188  { // Header at the left, data to the right
189  theCurData.aStart.SetCol( nCol2 + 1 );
191  }
192  }
193  if ( bValid )
194  {
197 
198  if(bRef)
199  m_xEdAssign->SetRefString( aStr );
200  else
201  m_xEdAssign->SetText( aStr );
202 
203  m_xEdAssign->SetCursorAtLast();
205 
206  if(bRef)
207  m_xEdAssign2->SetRefString( aStr );
208  else
209  m_xEdAssign2->SetText( aStr );
210  }
211  else
212  {
214 
215  if(bRef)
216  {
217  m_xEdAssign->SetRefString( EMPTY_OUSTRING );
218  m_xEdAssign2->SetRefString( EMPTY_OUSTRING );
219  }
220  else
221  {
222  m_xEdAssign->SetText( EMPTY_OUSTRING );
223  m_xEdAssign2->SetText( EMPTY_OUSTRING );
224  }
225 
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);
230  }
231 }
232 
233 // adjust label range and set the data reference form element
234 void ScColRowNameRangesDlg::AdjustColRowData( const ScRange& rDataRange, bool bRef)
235 {
236  theCurData = rDataRange;
237  if ( m_xBtnColHead->get_active() )
238  { // Data range is the same columns as the header
242  {
243  SCROW nRow1 = theCurArea.aStart.Row();
244  SCROW nRow2 = theCurArea.aEnd.Row();
245  if ( nRow1 > 0
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() )
251  }
252  else
253  { // Data below header
254  theCurData.aStart.SetRow( nRow2 + 1 );
255  if ( theCurData.aStart.Row() > theCurData.aEnd.Row() )
257  }
258  }
259  }
260  else
261  { // Data range in the same rows as header
265  {
266  SCCOL nCol1 = theCurArea.aStart.Col();
267  SCCOL nCol2 = theCurArea.aEnd.Col();
268  if ( nCol1 > 0
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() )
274  }
275  else
276  { // Data right of header
277  theCurData.aStart.SetCol( nCol2 + 1 );
278  if ( theCurData.aStart.Col() > theCurData.aEnd.Col() )
280  }
281  }
282  }
284 
285  if(bRef)
286  m_xEdAssign2->SetRefString( aStr );
287  else
288  m_xEdAssign2->SetText( aStr );
289 
290  m_xEdAssign2->SetCursorAtLast();
291 }
292 
293 // Set the reference to a cell range selected with the mouse and update
294 // the selection form element
296 {
297  if ( !m_pEdActive )
298  return;
299 
300  if ( rRef.aStart != rRef.aEnd )
302 
303  if (m_pEdActive == m_xEdAssign.get())
304  SetColRowData( rRef, true );
305  else
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);
311 }
312 
314 {
315  DoClose( ScColRowNameRangesDlgWrapper::GetChildWindowId() );
316 }
317 
319 {
320  if ( bDlgLostFocus )
321  {
322  bDlgLostFocus = false;
323  if( m_pEdActive )
325  }
326  else
327  m_xDialog->grab_focus();
328 
329  if( m_pEdActive == m_xEdAssign.get() )
330  Range1DataModifyHdl( *m_xEdAssign );
331  else if( m_pEdActive == m_xEdAssign2.get() )
332  Range2DataModifyHdl( *m_xEdAssign2 );
333 
334  RefInputDone();
335 }
336 
338 {
339  m_xLbRange->freeze();
340 
341  m_xLbRange->clear();
342  aRangeMap.clear();
343  m_xEdAssign->SetText( EMPTY_OUSTRING );
344 
345  size_t nCount, j;
346 
347  SCCOL nCol1;
348  SCROW nRow1; //Extension for range names
349  SCTAB nTab1;
350  SCCOL nCol2;
351  SCROW nRow2;
352  SCTAB nTab2;
353  OUString rString;
354  const ScAddress::Details aDetails(rDoc.GetAddressConvention());
355 
356  OUString strDelim(" --- ");
357  OUString aString = strDelim + ScResId( STR_COLUMN ) + strDelim;
358  m_xLbRange->append(OUString::number(nEntryDataDelim), aString);
359  if ( xColNameRanges->size() > 0 )
360  {
361  std::vector<const ScRangePair*> aSortArray(xColNameRanges->CreateNameSortedArray(
362  rDoc ));
363  nCount = aSortArray.size();
364  for ( j=0; j < nCount; j++ )
365  {
366  const ScRange aRange(aSortArray[j]->GetRange(0));
367  aString = aRange.Format(rDoc, ScRefFlags::RANGE_ABS_3D, aDetails);
368 
369  //@008 get range parameters from document
370  aSortArray[j]->GetRange(0).GetVars( nCol1, nRow1, nTab1,
371  nCol2, nRow2, nTab2 );
372  SCCOL q=nCol1+3;
373  if(q>nCol2) q=nCol2;
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++)
379  {
380  strShow.append(", ");
381  rString = rDoc.GetString(i, nRow1, nTab1);
382  strShow.append(rString);
383  }
384  if(q<nCol2) // Too long? Add ",..."
385  {
386  strShow.append(", ...");
387  }
388  strShow.append("]");
389 
390  //@008 Add string to listbox
391  OUString aInsStr = aString + strShow.makeStringAndClear();
392  aRangeMap.emplace( aInsStr, aRange );
393  m_xLbRange->append(OUString::number(nEntryDataCol), aInsStr);
394  }
395  }
396  aString = strDelim + ScResId( STR_ROW ) + strDelim;
397  m_xLbRange->append(OUString::number(nEntryDataDelim), aString);
398  if ( xRowNameRanges->size() > 0 )
399  {
400  std::vector<const ScRangePair*> aSortArray(xRowNameRanges->CreateNameSortedArray(
401  rDoc ));
402  nCount = aSortArray.size();
403  for ( j=0; j < nCount; j++ )
404  {
405  const ScRange aRange(aSortArray[j]->GetRange(0));
406  aString = aRange.Format(rDoc, ScRefFlags::RANGE_ABS_3D, aDetails);
407 
408  //@008 Build string for rows below
409  aSortArray[j]->GetRange(0).GetVars( nCol1, nRow1, nTab1,
410  nCol2, nRow2, nTab2 );
411  SCROW q=nRow1+3;
412  if(q>nRow2) q=nRow2;
413  OUStringBuffer strShow = " [";
414  rString = rDoc.GetString(nCol1, nRow1, nTab1);
415  strShow.append(rString);
416  for(SCROW i=nRow1+1;i<=q;i++)
417  {
418  strShow.append(", ");
419  rString = rDoc.GetString(nCol1, i, nTab1);
420  strShow.append(rString);
421  }
422  if(q<nRow2)
423  {
424  strShow.append(", ...");
425  }
426  strShow.append("]");
427 
428  OUString aInsStr = aString + strShow.makeStringAndClear();
429  aRangeMap.emplace( aInsStr, aRange );
430  m_xLbRange->append(OUString::number(nEntryDataRow), aInsStr);
431  }
432  }
433 
434  m_xLbRange->thaw();
435 }
436 
437 void ScColRowNameRangesDlg::UpdateRangeData( const ScRange& rRange, bool bColName )
438 {
439  ScRangePair* pPair = nullptr;
440  bool bFound = false;
441  if ( bColName && (pPair = xColNameRanges->Find( rRange )) != nullptr )
442  bFound = true;
443  else if ( !bColName && (pPair = xRowNameRanges->Find( rRange )) != nullptr )
444  bFound = true;
445 
446  if ( bFound )
447  {
449  theCurArea = rRange;
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);
458  m_xEdAssign2->SetText( aStr );
459  }
460  else
461  {
462  m_xBtnAdd->set_sensitive(true);
463  m_xBtnRemove->set_sensitive(false);
464  }
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);
469 }
470 
472 {
473  return (m_pEdActive != nullptr);
474 }
475 
476 // Handler:
477 
478 // handler called when OK is clicked, calls the add button handler before
479 // passing the range lists to the document
481 {
482  AddBtnHdl(*m_xBtnAdd);
483 
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();
492 
493  response(RET_OK);
494 }
495 
497 {
498  response(RET_CANCEL);
499 }
500 
501 // handler called when add button clicked: set ranges and add to listbox
503 {
504  OUString aNewArea( m_xEdAssign->GetText() );
505  OUString aNewData( m_xEdAssign2->GetText() );
506 
507  if (aNewArea.isEmpty() || aNewData.isEmpty())
508  return;
509 
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)
514  {
515  theCurArea = aRange1;
516  AdjustColRowData( aRange2 );
517  ScRangePair* pPair;
518  if ( ( pPair = xColNameRanges->Find( theCurArea ) ) != nullptr )
519  {
520  xColNameRanges->Remove( *pPair );
521  }
522  if ( ( pPair = xRowNameRanges->Find( theCurArea ) ) != nullptr )
523  {
524  xRowNameRanges->Remove( *pPair );
525  }
526  if ( m_xBtnColHead->get_active() )
527  xColNameRanges->Join( ScRangePair( theCurArea, theCurData ) );
528  else
529  xRowNameRanges->Join( ScRangePair( theCurArea, theCurData ) );
530 
531  UpdateNames();
532 
533  m_xEdAssign->GrabFocus();
534  m_xBtnAdd->set_sensitive(false);
535  m_xBtnRemove->set_sensitive(false);
536  m_xEdAssign->SetText( EMPTY_OUSTRING );
537  m_xBtnColHead->set_active(true);
538  m_xBtnRowHead->set_active(false);
539  m_xEdAssign2->SetText( EMPTY_OUSTRING );
540  theCurArea = ScRange();
541  theCurData = theCurArea;
542  Range1SelectHdl( *m_xLbRange );
543  }
544  else
545  {
546  ERRORBOX(m_xDialog.get(), ScResId(STR_INVALIDTABNAME));
547  if ( !bOk1 )
548  m_xEdAssign->GrabFocus();
549  else
550  m_xEdAssign2->GrabFocus();
551  }
552 }
553 
555 {
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())
561  return;
562  const ScRange& rRange = itr->second;
563 
564  ScRangePair* pPair = nullptr;
565  bool bFound = false;
566  if ( bColName && (pPair = xColNameRanges->Find( rRange )) != nullptr )
567  bFound = true;
568  else if ( !bColName && (pPair = xRowNameRanges->Find( rRange )) != nullptr )
569  bFound = true;
570  if ( !bFound )
571  return;
572 
573  OUString aStrDelMsg = ScResId( STR_QUERY_DELENTRY );
574  OUString aMsg = aStrDelMsg.getToken( 0, '#' )
575  + aRangeStr
576  + aStrDelMsg.getToken( 1, '#' );
577 
578  if (RET_YES != QUERYBOX(m_xDialog.get(), aMsg))
579  return;
580 
581  if ( bColName )
582  xColNameRanges->Remove( *pPair );
583  else
584  xRowNameRanges->Remove( *pPair );
585 
586  UpdateNames();
587  const sal_Int32 nCnt = m_xLbRange->n_children();
588  if ( nSelectPos >= nCnt )
589  {
590  if ( nCnt )
591  nSelectPos = nCnt - 1;
592  else
593  nSelectPos = 0;
594  }
595  m_xLbRange->select(nSelectPos);
596  if (nSelectPos && m_xLbRange->get_id(nSelectPos).toInt32() == nEntryDataDelim)
597  m_xLbRange->select( --nSelectPos ); // ---Row---
598 
599  m_xLbRange->grab_focus();
600  m_xBtnAdd->set_sensitive(false);
601  m_xBtnRemove->set_sensitive(false);
602  m_xEdAssign->SetText( EMPTY_OUSTRING );
603  theCurArea = theCurData = ScRange();
604  m_xBtnColHead->set_active(true);
605  m_xBtnRowHead->set_active(false);
606  m_xEdAssign2->SetText( EMPTY_OUSTRING );
607  Range1SelectHdl( *m_xLbRange );
608 }
609 
610 // handler called when a row in the listbox is selected, updates form input fields
612 {
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)
617  { // skip Delimiter
618  ++nMoves;
619  ++nSelectPos;
620  }
621  OUString aRangeStr = m_xLbRange->get_selected_text();
622  if ( nMoves )
623  {
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();
630  }
631  else if ( nSelectPos > 2 && nSelectPos < nCnt && !aRangeStr.isEmpty()
632  && aRangeStr == m_xEdAssign->GetText() )
633  { // move upwards instead of below to the previous position
634  nSelectPos -= 2;
635  m_xLbRange->select( nSelectPos );
636  aRangeStr = m_xLbRange->get_selected_text();
637  }
638  else
639  m_xLbRange->select(nSelectPos);
640  }
641  NameRangeMap::const_iterator itr = aRangeMap.find(aRangeStr);
642  if ( itr != aRangeMap.end() )
643  {
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);
648  }
649  else
650  {
651  if ( !m_xEdAssign->GetText().isEmpty() )
652  {
653  if ( !m_xEdAssign2->GetText().isEmpty() )
654  m_xBtnAdd->set_sensitive(true);
655  else
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);
661  }
662  else
663  {
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);
669  }
670  m_xBtnRemove->set_sensitive(false);
671  m_xEdAssign->GrabFocus();
672  }
673 
674  m_xEdAssign->GetWidget()->set_sensitive(true);
675  m_xRbAssign->GetWidget()->set_sensitive(true);
676 }
677 
678 // handler called when the label range has changed
680 {
681  OUString aNewArea( m_xEdAssign->GetText() );
682  bool bValid = false;
683  if (!aNewArea.isEmpty())
684  {
685  ScRange aRange;
686  if ( (aRange.ParseAny(aNewArea, rDoc, rDoc.GetAddressConvention() ) & ScRefFlags::VALID) == ScRefFlags::VALID)
687  {
688  SetColRowData( aRange );
689  bValid = true;
690  }
691  }
692  if ( bValid )
693  {
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);
699  }
700  else
701  {
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);
707  }
708  m_xBtnRemove->set_sensitive(false);
709 }
710 
711 // handler called when the data range has changed
713 {
714  OUString aNewData( m_xEdAssign2->GetText() );
715  if ( !aNewData.isEmpty() )
716  {
717  ScRange aRange;
718  if ( (aRange.ParseAny(aNewData, rDoc, rDoc.GetAddressConvention() ) & ScRefFlags::VALID) == ScRefFlags::VALID)
719  {
720  AdjustColRowData( aRange );
721  m_xBtnAdd->set_sensitive(true);
722  }
723  else
724  m_xBtnAdd->set_sensitive(false);
725  }
726  else
727  {
728  m_xBtnAdd->set_sensitive(false);
729  }
730 }
731 
732 // handler for the radio button for columns, adjust ranges
734 {
735  if (!m_xBtnColHead->get_active())
736  return;
737 
738  if ( theCurArea.aStart.Row() == 0 && theCurArea.aEnd.Row() == rDoc.MaxRow() )
739  {
740  theCurArea.aEnd.SetRow( rDoc.MaxRow() - 1 );
741  OUString aStr(theCurArea.Format(rDoc, ScRefFlags::RANGE_ABS_3D, rDoc.GetAddressConvention()));
742  m_xEdAssign->SetText( aStr );
743  }
744  ScRange aRange( theCurData );
745  aRange.aStart.SetRow( std::min( static_cast<long>(theCurArea.aEnd.Row() + 1), static_cast<long>(rDoc.MaxRow()) ) );
746  aRange.aEnd.SetRow( rDoc.MaxRow() );
747  AdjustColRowData( aRange );
748 }
749 
750 // handler for the radio button for columns, adjust range
752 {
753  if (!m_xBtnRowHead->get_active())
754  return;
755 
756  if ( theCurArea.aStart.Col() == 0 && theCurArea.aEnd.Col() == rDoc.MaxCol() )
757  {
758  theCurArea.aEnd.SetCol( rDoc.MaxCol() - 1 );
759  OUString aStr(theCurArea.Format(rDoc, ScRefFlags::RANGE_ABS_3D, rDoc.GetAddressConvention()));
760  m_xEdAssign->SetText( aStr );
761  }
762  ScRange aRange( theCurData );
763  aRange.aStart.SetCol( static_cast<SCCOL>(std::min( static_cast<long>(theCurArea.aEnd.Col() + 1), static_cast<long>(rDoc.MaxCol()) )) );
764  aRange.aEnd.SetCol( rDoc.MaxCol() );
765  AdjustColRowData( aRange );
766 }
767 
768 IMPL_LINK( ScColRowNameRangesDlg, GetEditFocusHdl, formula::RefEdit&, rCtrl, void )
769 {
770  if (&rCtrl == m_xEdAssign.get())
771  m_pEdActive = m_xEdAssign.get();
772  else if (&rCtrl == m_xEdAssign2.get())
773  m_pEdActive = m_xEdAssign2.get();
774  else
775  m_pEdActive = nullptr;
776 
777  if( m_pEdActive )
778  m_pEdActive->SelectAll();
779 }
780 
781 IMPL_LINK( ScColRowNameRangesDlg, GetButtonFocusHdl, formula::RefButton&, rCtrl, void )
782 {
783  if (&rCtrl == m_xRbAssign.get())
784  m_pEdActive = m_xEdAssign.get();
785  else if (&rCtrl == m_xRbAssign2.get())
786  m_pEdActive = m_xEdAssign2.get();
787  else
788  m_pEdActive = nullptr;
789 
790  if( m_pEdActive )
791  m_pEdActive->SelectAll();
792 }
793 
795 {
796  bDlgLostFocus = !m_xDialog->has_toplevel_focus();
797 }
798 
800 {
801  bDlgLostFocus = !m_xDialog->has_toplevel_focus();
802 }
803 
804 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SC_DLLPUBLIC ScRefFlags ParseAny(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1)
Definition: address.cxx:1766
const sal_uLong nEntryDataDelim
Definition: crnrdlg.cxx:53
formula::RefEdit * m_pEdActive
Definition: crnrdlg.hxx:57
ScAddress aStart
Definition: address.hxx:500
#define EMPTY_OUSTRING
Definition: global.hxx:214
ScColRowNameRangesDlg(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScViewData &rViewData)
Definition: crnrdlg.cxx:57
SCROW Row() const
Definition: address.hxx:262
ScViewData & m_rViewData
Definition: crnrdlg.hxx:53
ScDocument & rDoc
Definition: crnrdlg.hxx:54
ScRangePairList * GetColNameRanges()
Definition: document.hxx:808
SC_DLLPUBLIC bool Intersects(const ScRange &rRange) const
Definition: address.cxx:1549
std::unique_ptr< weld::RadioButton > m_xBtnRowHead
Definition: crnrdlg.hxx:63
sal_uIntPtr sal_uLong
sal_Int32 toInt32(OUString const &rStr)
IMPL_LINK_NOARG(ScColRowNameRangesDlg, OkBtnHdl, weld::Button &, void)
Definition: crnrdlg.cxx:480
IMPL_LINK(ScColRowNameRangesDlg, GetEditFocusHdl, formula::RefEdit &, rCtrl, void)
Definition: crnrdlg.cxx:768
void SetDocumentModified()
Definition: docsh.cxx:2819
ScAddress aEnd
Definition: address.hxx:501
std::unique_ptr< weld::Button > m_xBtnOk
Definition: crnrdlg.hxx:67
RET_CANCEL
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:489
std::unique_ptr< weld::Label > m_xDataFT
Definition: crnrdlg.hxx:74
std::unique_ptr< formula::RefEdit > m_xEdAssign2
Definition: crnrdlg.hxx:64
std::unique_ptr< weld::Label > m_xRangeFT
Definition: crnrdlg.hxx:73
const sal_uLong nEntryDataCol
Definition: crnrdlg.cxx:51
RET_YES
void SetColRowData(const ScRange &rLabelRange, bool bRef=false)
Definition: crnrdlg.cxx:150
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:873
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
Definition: crnrdlg.cxx:295
int nCount
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
Definition: document.cxx:3486
virtual bool IsRefInputMode() const override
Definition: crnrdlg.cxx:471
void SetRow(SCROW nRowP)
Definition: address.hxx:275
void SetCol(SCCOL nColP)
Definition: address.hxx:279
std::unique_ptr< weld::TreeView > m_xLbRange
Definition: crnrdlg.hxx:58
ScRangePairListRef xColNameRanges
Definition: crnrdlg.hxx:48
std::unique_ptr< formula::RefButton > m_xRbAssign2
Definition: crnrdlg.hxx:65
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:872
ScRangePairList * Clone() const
Definition: rangelst.cxx:1306
ScRangePairListRef xRowNameRanges
Definition: crnrdlg.hxx:49
int i
virtual void SetActive() override
Definition: crnrdlg.cxx:318
sal_Int16 SCCOL
Definition: types.hxx:22
SC_DLLPUBLIC OUString Format(const ScDocument &rDocument, ScRefFlags nFlags=ScRefFlags::ZERO, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, bool bFullAddressNotation=false) const
Returns string with formatted cell range from aStart to aEnd, according to provided address conventio...
Definition: address.cxx:2203
std::unique_ptr< weld::RadioButton > m_xBtnColHead
Definition: crnrdlg.hxx:62
const ScRange & GetRange(sal_uInt16 n) const
Definition: address.hxx:817
OUString ScResId(const char *pId)
Definition: scdll.cxx:95
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1170
virtual void RefInputDone(bool bForced=false) override
Definition: anyrefdg.cxx:755
virtual ~ScColRowNameRangesDlg() override
Definition: crnrdlg.cxx:92
const SCTAB MAXTAB
Definition: address.hxx:71
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:99
SCCOL Col() const
Definition: address.hxx:267
sal_Int32 SCROW
Definition: types.hxx:18
ScRangePairList * GetRowNameRanges()
Definition: document.hxx:809
void AdjustColRowData(const ScRange &rDataRange, bool bRef=false)
Definition: crnrdlg.cxx:234
size_t size() const
Definition: rangelst.cxx:1231
RET_OK
std::unique_ptr< weld::Button > m_xBtnCancel
Definition: crnrdlg.hxx:68
Reference< XExecutableDialog > m_xDialog
std::unique_ptr< weld::Button > m_xBtnAdd
Definition: crnrdlg.hxx:69
virtual void Close() override
Definition: crnrdlg.cxx:313
std::unique_ptr< formula::RefEdit > m_xEdAssign
Definition: crnrdlg.hxx:60
std::unique_ptr< weld::Button > m_xBtnRemove
Definition: crnrdlg.hxx:70
NameRangeMap aRangeMap
Definition: crnrdlg.hxx:52
std::vector< const ScRangePair * > CreateNameSortedArray(ScDocument &) const
Definition: rangelst.cxx:1525
std::unique_ptr< formula::RefButton > m_xRbAssign
Definition: crnrdlg.hxx:61
bool DoClose(sal_uInt16 nId)
Definition: anyrefdg.cxx:694
const sal_uLong nEntryDataRow
Definition: crnrdlg.cxx:52
void UpdateRangeData(const ScRange &rRange, bool bColName)
Definition: crnrdlg.cxx:437
aStr
ScRangePair * Find(const ScAddress &)
Definition: rangelst.cxx:1286
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
sal_Int16 SCTAB
Definition: types.hxx:23
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
Definition: anyrefdg.cxx:725