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* ptrViewData )
61 
62  : ScAnyRefDlgController(pB, pCW, pParent, "modules/scalc/ui/namerangesdialog.ui", "NameRangesDialog")
63  , pViewData(ptrViewData)
64  , pDoc(ptrViewData->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  if (pViewData)
130  {
131  SCCOL nStartCol = 0;
132  SCROW nStartRow = 0;
133  SCTAB nStartTab = 0;
134  SCCOL nEndCol = 0;
135  SCROW nEndRow = 0;
136  SCTAB nEndTab = 0;
137  pViewData->GetSimpleArea( nStartCol, nStartRow, nStartTab,
138  nEndCol, nEndRow, nEndTab );
139  SetColRowData( ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab));
140  }
141  else
142  {
143  m_xBtnColHead->set_active(true);
144  m_xBtnRowHead->set_active(false);
145  m_xEdAssign->SetText( EMPTY_OUSTRING );
146  m_xEdAssign2->SetText( EMPTY_OUSTRING );
147  }
148 
149  m_xBtnColHead->set_sensitive(true);
150  m_xBtnRowHead->set_sensitive(true);
151  m_xEdAssign->GetWidget()->set_sensitive(true);
152  m_xEdAssign->GrabFocus();
153  m_xRbAssign->GetWidget()->set_sensitive(true);
154 
155  Range1SelectHdl( *m_xLbRange );
156 }
157 
158 // set data range of a labeled range to default values and set the
159 // form elements for the reference
160 void ScColRowNameRangesDlg::SetColRowData( const ScRange& rLabelRange, bool bRef)
161 {
162  theCurData = theCurArea = rLabelRange;
163  bool bValid = true;
164  SCCOL nCol1 = theCurArea.aStart.Col();
165  SCCOL nCol2 = theCurArea.aEnd.Col();
166  SCROW nRow1 = theCurArea.aStart.Row();
167  SCROW nRow2 = theCurArea.aEnd.Row();
168  if ( (static_cast<SCCOLROW>(nCol2 - nCol1) >= nRow2 - nRow1) || (nCol1 == 0 && nCol2 == pDoc->MaxCol()) )
169  { // Column headers and the limiting case of the whole sheet
170  m_xBtnColHead->set_active(true);
171  m_xBtnRowHead->set_active(false);
172  if ( nRow2 == pDoc->MaxRow() )
173  {
174  if ( nRow1 == 0 )
175  bValid = false; // limiting case of the whole sheet
176  else
177  { // Header at bottom, data above
178  theCurData.aStart.SetRow( 0 );
179  theCurData.aEnd.SetRow( nRow1 - 1 );
180  }
181  }
182  else
183  { // Header at top, data below
184  theCurData.aStart.SetRow( nRow2 + 1 );
186  }
187  }
188  else
189  { // Column headers
190  m_xBtnRowHead->set_active(true);
191  m_xBtnColHead->set_active(false);
192  if ( nCol2 == pDoc->MaxCol() )
193  { // Header at the right, data to the left
194  theCurData.aStart.SetCol( 0 );
195  theCurData.aEnd.SetCol( nCol2 - 1 );
196  }
197  else
198  { // Header at the left, data to the right
199  theCurData.aStart.SetCol( nCol2 + 1 );
201  }
202  }
203  if ( bValid )
204  {
206  OUString aStr(theCurArea.Format(*pDoc, ScRefFlags::RANGE_ABS_3D, eConv));
207 
208  if(bRef)
209  m_xEdAssign->SetRefString( aStr );
210  else
211  m_xEdAssign->SetText( aStr );
212 
213  m_xEdAssign->SetCursorAtLast();
215 
216  if(bRef)
217  m_xEdAssign2->SetRefString( aStr );
218  else
219  m_xEdAssign2->SetText( aStr );
220  }
221  else
222  {
224 
225  if(bRef)
226  {
227  m_xEdAssign->SetRefString( EMPTY_OUSTRING );
228  m_xEdAssign2->SetRefString( EMPTY_OUSTRING );
229  }
230  else
231  {
232  m_xEdAssign->SetText( EMPTY_OUSTRING );
233  m_xEdAssign2->SetText( EMPTY_OUSTRING );
234  }
235 
236  m_xBtnColHead->set_sensitive(false);
237  m_xBtnRowHead->set_sensitive(false);
238  m_xEdAssign2->GetWidget()->set_sensitive(false);
239  m_xRbAssign2->GetWidget()->set_sensitive(false);
240  }
241 }
242 
243 // adjust label range and set the data reference form element
244 void ScColRowNameRangesDlg::AdjustColRowData( const ScRange& rDataRange, bool bRef)
245 {
246  theCurData = rDataRange;
247  if ( m_xBtnColHead->get_active() )
248  { // Data range is the same columns as the header
252  {
253  SCROW nRow1 = theCurArea.aStart.Row();
254  SCROW nRow2 = theCurArea.aEnd.Row();
255  if ( nRow1 > 0
256  && (theCurData.aEnd.Row() < nRow2 || nRow2 == pDoc->MaxRow()) )
257  { // Data above header
258  theCurData.aEnd.SetRow( nRow1 - 1 );
259  if ( theCurData.aStart.Row() > theCurData.aEnd.Row() )
261  }
262  else
263  { // Data below header
264  theCurData.aStart.SetRow( nRow2 + 1 );
265  if ( theCurData.aStart.Row() > theCurData.aEnd.Row() )
267  }
268  }
269  }
270  else
271  { // Data range in the same rows as header
275  {
276  SCCOL nCol1 = theCurArea.aStart.Col();
277  SCCOL nCol2 = theCurArea.aEnd.Col();
278  if ( nCol1 > 0
279  && (theCurData.aEnd.Col() < nCol2 || nCol2 == pDoc->MaxCol()) )
280  { // Data left of header
281  theCurData.aEnd.SetCol( nCol1 - 1 );
282  if ( theCurData.aStart.Col() > theCurData.aEnd.Col() )
284  }
285  else
286  { // Data right of header
287  theCurData.aStart.SetCol( nCol2 + 1 );
288  if ( theCurData.aStart.Col() > theCurData.aEnd.Col() )
290  }
291  }
292  }
294 
295  if(bRef)
296  m_xEdAssign2->SetRefString( aStr );
297  else
298  m_xEdAssign2->SetText( aStr );
299 
300  m_xEdAssign2->SetCursorAtLast();
301 }
302 
303 // Set the reference to a cell range selected with the mouse and update
304 // the selection form element
306 {
307  if ( !m_pEdActive )
308  return;
309 
310  if ( rRef.aStart != rRef.aEnd )
312 
313  if (m_pEdActive == m_xEdAssign.get())
314  SetColRowData( rRef, true );
315  else
316  AdjustColRowData( rRef, true );
317  m_xBtnColHead->set_sensitive(true);
318  m_xBtnRowHead->set_sensitive(true);
319  m_xBtnAdd->set_sensitive(true);
320  m_xBtnRemove->set_sensitive(false);
321 }
322 
324 {
325  DoClose( ScColRowNameRangesDlgWrapper::GetChildWindowId() );
326 }
327 
329 {
330  if ( bDlgLostFocus )
331  {
332  bDlgLostFocus = false;
333  if( m_pEdActive )
335  }
336  else
337  m_xDialog->grab_focus();
338 
339  if( m_pEdActive == m_xEdAssign.get() )
340  Range1DataModifyHdl( *m_xEdAssign );
341  else if( m_pEdActive == m_xEdAssign2.get() )
342  Range2DataModifyHdl( *m_xEdAssign2 );
343 
344  RefInputDone();
345 }
346 
348 {
349  m_xLbRange->freeze();
350 
351  m_xLbRange->clear();
352  aRangeMap.clear();
353  m_xEdAssign->SetText( EMPTY_OUSTRING );
354 
355  size_t nCount, j;
356 
357  SCCOL nCol1;
358  SCROW nRow1; //Extension for range names
359  SCTAB nTab1;
360  SCCOL nCol2;
361  SCROW nRow2;
362  SCTAB nTab2;
363  OUString rString;
364  const ScAddress::Details aDetails(pDoc->GetAddressConvention());
365 
366  OUString strDelim(" --- ");
367  OUString aString = strDelim + ScResId( STR_COLUMN ) + strDelim;
368  m_xLbRange->append(OUString::number(nEntryDataDelim), aString);
369  if ( xColNameRanges->size() > 0 )
370  {
371  std::vector<const ScRangePair*> aSortArray(xColNameRanges->CreateNameSortedArray(
372  pDoc ));
373  nCount = aSortArray.size();
374  for ( j=0; j < nCount; j++ )
375  {
376  const ScRange aRange(aSortArray[j]->GetRange(0));
377  aString = aRange.Format(*pDoc, ScRefFlags::RANGE_ABS_3D, aDetails);
378 
379  //@008 get range parameters from document
380  aSortArray[j]->GetRange(0).GetVars( nCol1, nRow1, nTab1,
381  nCol2, nRow2, nTab2 );
382  SCCOL q=nCol1+3;
383  if(q>nCol2) q=nCol2;
384  //@008 construct string
385  OUStringBuffer strShow = " [";
386  rString = pDoc->GetString(nCol1, nRow1, nTab1);
387  strShow.append(rString);
388  for(SCCOL i=nCol1+1;i<=q;i++)
389  {
390  strShow.append(", ");
391  rString = pDoc->GetString(i, nRow1, nTab1);
392  strShow.append(rString);
393  }
394  if(q<nCol2) // Too long? Add ",..."
395  {
396  strShow.append(", ...");
397  }
398  strShow.append("]");
399 
400  //@008 Add string to listbox
401  OUString aInsStr = aString + strShow.makeStringAndClear();
402  aRangeMap.emplace( aInsStr, aRange );
403  m_xLbRange->append(OUString::number(nEntryDataCol), aInsStr);
404  }
405  }
406  aString = strDelim + ScResId( STR_ROW ) + strDelim;
407  m_xLbRange->append(OUString::number(nEntryDataDelim), aString);
408  if ( xRowNameRanges->size() > 0 )
409  {
410  std::vector<const ScRangePair*> aSortArray(xRowNameRanges->CreateNameSortedArray(
411  pDoc ));
412  nCount = aSortArray.size();
413  for ( j=0; j < nCount; j++ )
414  {
415  const ScRange aRange(aSortArray[j]->GetRange(0));
416  aString = aRange.Format(*pDoc, ScRefFlags::RANGE_ABS_3D, aDetails);
417 
418  //@008 Build string for rows below
419  aSortArray[j]->GetRange(0).GetVars( nCol1, nRow1, nTab1,
420  nCol2, nRow2, nTab2 );
421  SCROW q=nRow1+3;
422  if(q>nRow2) q=nRow2;
423  OUStringBuffer strShow = " [";
424  rString = pDoc->GetString(nCol1, nRow1, nTab1);
425  strShow.append(rString);
426  for(SCROW i=nRow1+1;i<=q;i++)
427  {
428  strShow.append(", ");
429  rString = pDoc->GetString(nCol1, i, nTab1);
430  strShow.append(rString);
431  }
432  if(q<nRow2)
433  {
434  strShow.append(", ...");
435  }
436  strShow.append("]");
437 
438  OUString aInsStr = aString + strShow.makeStringAndClear();
439  aRangeMap.emplace( aInsStr, aRange );
440  m_xLbRange->append(OUString::number(nEntryDataRow), aInsStr);
441  }
442  }
443 
444  m_xLbRange->thaw();
445 }
446 
447 void ScColRowNameRangesDlg::UpdateRangeData( const ScRange& rRange, bool bColName )
448 {
449  ScRangePair* pPair = nullptr;
450  bool bFound = false;
451  if ( bColName && (pPair = xColNameRanges->Find( rRange )) != nullptr )
452  bFound = true;
453  else if ( !bColName && (pPair = xRowNameRanges->Find( rRange )) != nullptr )
454  bFound = true;
455 
456  if ( bFound )
457  {
459  theCurArea = rRange;
460  OUString aStr(theCurArea.Format(*pDoc, ScRefFlags::RANGE_ABS_3D, eConv));
461  m_xEdAssign->SetText( aStr );
462  m_xBtnAdd->set_sensitive(false);
463  m_xBtnRemove->set_sensitive(true);
464  m_xBtnColHead->set_active(bColName);
465  m_xBtnRowHead->set_active(!bColName);
466  theCurData = pPair->GetRange(1);
468  m_xEdAssign2->SetText( aStr );
469  }
470  else
471  {
472  m_xBtnAdd->set_sensitive(true);
473  m_xBtnRemove->set_sensitive(false);
474  }
475  m_xBtnColHead->set_sensitive(true);
476  m_xBtnRowHead->set_sensitive(true);
477  m_xEdAssign2->GetWidget()->set_sensitive(true);
478  m_xRbAssign2->GetWidget()->set_sensitive(true);
479 }
480 
482 {
483  return (m_pEdActive != nullptr);
484 }
485 
486 // Handler:
487 
488 // handler called when OK is clicked, calls the add button handler before
489 // passing the range lists to the document
491 {
492  AddBtnHdl(*m_xBtnAdd);
493 
494  // assign RangeLists to the references in the document
495  pDoc->GetColNameRangesRef() = xColNameRanges;
496  pDoc->GetRowNameRangesRef() = xRowNameRanges;
497  // changed ranges need to take effect
498  pDoc->CompileColRowNameFormula();
499  ScDocShell* pDocShell = pViewData->GetDocShell();
500  pDocShell->PostPaint(ScRange(0, 0, 0, pDoc->MaxCol(), pDoc->MaxRow(), MAXTAB), PaintPartFlags::Grid);
501  pDocShell->SetDocumentModified();
502 
503  response(RET_OK);
504 }
505 
507 {
508  response(RET_CANCEL);
509 }
510 
511 // handler called when add button clicked: set ranges and add to listbox
513 {
514  OUString aNewArea( m_xEdAssign->GetText() );
515  OUString aNewData( m_xEdAssign2->GetText() );
516 
517  if (aNewArea.isEmpty() || aNewData.isEmpty())
518  return;
519 
520  const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
521  ScRange aRange1, aRange2;
522  bool bOk1 = (aRange1.ParseAny( aNewArea, pDoc, eConv ) & ScRefFlags::VALID) == ScRefFlags::VALID;
523  if ( bOk1 && (aRange2.ParseAny( aNewData, pDoc, eConv ) & ScRefFlags::VALID) == ScRefFlags::VALID)
524  {
525  theCurArea = aRange1;
526  AdjustColRowData( aRange2 );
527  ScRangePair* pPair;
528  if ( ( pPair = xColNameRanges->Find( theCurArea ) ) != nullptr )
529  {
530  xColNameRanges->Remove( *pPair );
531  }
532  if ( ( pPair = xRowNameRanges->Find( theCurArea ) ) != nullptr )
533  {
534  xRowNameRanges->Remove( *pPair );
535  }
536  if ( m_xBtnColHead->get_active() )
537  xColNameRanges->Join( ScRangePair( theCurArea, theCurData ) );
538  else
539  xRowNameRanges->Join( ScRangePair( theCurArea, theCurData ) );
540 
541  UpdateNames();
542 
543  m_xEdAssign->GrabFocus();
544  m_xBtnAdd->set_sensitive(false);
545  m_xBtnRemove->set_sensitive(false);
546  m_xEdAssign->SetText( EMPTY_OUSTRING );
547  m_xBtnColHead->set_active(true);
548  m_xBtnRowHead->set_active(false);
549  m_xEdAssign2->SetText( EMPTY_OUSTRING );
550  theCurArea = ScRange();
551  theCurData = theCurArea;
552  Range1SelectHdl( *m_xLbRange );
553  }
554  else
555  {
556  ERRORBOX(m_xDialog.get(), ScResId(STR_INVALIDTABNAME));
557  if ( !bOk1 )
558  m_xEdAssign->GrabFocus();
559  else
560  m_xEdAssign2->GrabFocus();
561  }
562 }
563 
565 {
566  OUString aRangeStr = m_xLbRange->get_selected_text();
567  sal_Int32 nSelectPos = m_xLbRange->get_selected_index();
568  bool bColName = nSelectPos != -1 && m_xLbRange->get_id(nSelectPos).toInt32() == nEntryDataCol;
569  NameRangeMap::const_iterator itr = aRangeMap.find(aRangeStr);
570  if (itr == aRangeMap.end())
571  return;
572  const ScRange& rRange = itr->second;
573 
574  ScRangePair* pPair = nullptr;
575  bool bFound = false;
576  if ( bColName && (pPair = xColNameRanges->Find( rRange )) != nullptr )
577  bFound = true;
578  else if ( !bColName && (pPair = xRowNameRanges->Find( rRange )) != nullptr )
579  bFound = true;
580  if ( !bFound )
581  return;
582 
583  OUString aStrDelMsg = ScResId( STR_QUERY_DELENTRY );
584  OUString aMsg = aStrDelMsg.getToken( 0, '#' )
585  + aRangeStr
586  + aStrDelMsg.getToken( 1, '#' );
587 
588  if (RET_YES != QUERYBOX(m_xDialog.get(), aMsg))
589  return;
590 
591  if ( bColName )
592  xColNameRanges->Remove( *pPair );
593  else
594  xRowNameRanges->Remove( *pPair );
595 
596  UpdateNames();
597  const sal_Int32 nCnt = m_xLbRange->n_children();
598  if ( nSelectPos >= nCnt )
599  {
600  if ( nCnt )
601  nSelectPos = nCnt - 1;
602  else
603  nSelectPos = 0;
604  }
605  m_xLbRange->select(nSelectPos);
606  if (nSelectPos && m_xLbRange->get_id(nSelectPos).toInt32() == nEntryDataDelim)
607  m_xLbRange->select( --nSelectPos ); // ---Row---
608 
609  m_xLbRange->grab_focus();
610  m_xBtnAdd->set_sensitive(false);
611  m_xBtnRemove->set_sensitive(false);
612  m_xEdAssign->SetText( EMPTY_OUSTRING );
613  theCurArea = theCurData = ScRange();
614  m_xBtnColHead->set_active(true);
615  m_xBtnRowHead->set_active(false);
616  m_xEdAssign2->SetText( EMPTY_OUSTRING );
617  Range1SelectHdl( *m_xLbRange );
618 }
619 
620 // handler called when a row in the listbox is selected, updates form input fields
622 {
623  sal_Int32 nSelectPos = m_xLbRange->get_selected_index();
624  const sal_Int32 nCnt = m_xLbRange->n_children();
625  sal_uInt16 nMoves = 0;
626  while (nSelectPos != -1 && nSelectPos < nCnt && m_xLbRange->get_id(nSelectPos).toInt32() == nEntryDataDelim)
627  { // skip Delimiter
628  ++nMoves;
629  ++nSelectPos;
630  }
631  OUString aRangeStr = m_xLbRange->get_selected_text();
632  if ( nMoves )
633  {
634  if ( nSelectPos > 1 && nSelectPos >= nCnt )
635  { // if entries exist before the " --- Row --- " Delimiter then
636  // do not stop at the delimiter
637  nSelectPos = nCnt - 2;
638  m_xLbRange->select(nSelectPos);
639  aRangeStr = m_xLbRange->get_selected_text();
640  }
641  else if ( nSelectPos > 2 && nSelectPos < nCnt && !aRangeStr.isEmpty()
642  && aRangeStr == m_xEdAssign->GetText() )
643  { // move upwards instead of below to the previous position
644  nSelectPos -= 2;
645  m_xLbRange->select( nSelectPos );
646  aRangeStr = m_xLbRange->get_selected_text();
647  }
648  else
649  m_xLbRange->select(nSelectPos);
650  }
651  NameRangeMap::const_iterator itr = aRangeMap.find(aRangeStr);
652  if ( itr != aRangeMap.end() )
653  {
654  bool bColName = m_xLbRange->get_id(nSelectPos).toInt32() == nEntryDataCol;
655  UpdateRangeData( itr->second, bColName );
656  m_xBtnAdd->set_sensitive(false);
657  m_xBtnRemove->set_sensitive(true);
658  }
659  else
660  {
661  if ( !m_xEdAssign->GetText().isEmpty() )
662  {
663  if ( !m_xEdAssign2->GetText().isEmpty() )
664  m_xBtnAdd->set_sensitive(true);
665  else
666  m_xBtnAdd->set_sensitive(false);
667  m_xBtnColHead->set_sensitive(true);
668  m_xBtnRowHead->set_sensitive(true);
669  m_xEdAssign2->GetWidget()->set_sensitive(true);
670  m_xRbAssign2->GetWidget()->set_sensitive(true);
671  }
672  else
673  {
674  m_xBtnAdd->set_sensitive(false);
675  m_xBtnColHead->set_sensitive(false);
676  m_xBtnRowHead->set_sensitive(false);
677  m_xEdAssign2->GetWidget()->set_sensitive(false);
678  m_xRbAssign2->GetWidget()->set_sensitive(false);
679  }
680  m_xBtnRemove->set_sensitive(false);
681  m_xEdAssign->GrabFocus();
682  }
683 
684  m_xEdAssign->GetWidget()->set_sensitive(true);
685  m_xRbAssign->GetWidget()->set_sensitive(true);
686 }
687 
688 // handler called when the label range has changed
690 {
691  OUString aNewArea( m_xEdAssign->GetText() );
692  bool bValid = false;
693  if (!aNewArea.isEmpty() && pDoc)
694  {
695  ScRange aRange;
696  if ( (aRange.ParseAny(aNewArea, pDoc, pDoc->GetAddressConvention() ) & ScRefFlags::VALID) == ScRefFlags::VALID)
697  {
698  SetColRowData( aRange );
699  bValid = true;
700  }
701  }
702  if ( bValid )
703  {
704  m_xBtnAdd->set_sensitive(true);
705  m_xBtnColHead->set_sensitive(true);
706  m_xBtnRowHead->set_sensitive(true);
707  m_xEdAssign2->GetWidget()->set_sensitive(true);
708  m_xRbAssign2->GetWidget()->set_sensitive(true);
709  }
710  else
711  {
712  m_xBtnAdd->set_sensitive(false);
713  m_xBtnColHead->set_sensitive(false);
714  m_xBtnRowHead->set_sensitive(false);
715  m_xEdAssign2->GetWidget()->set_sensitive(false);
716  m_xRbAssign2->GetWidget()->set_sensitive(false);
717  }
718  m_xBtnRemove->set_sensitive(false);
719 }
720 
721 // handler called when the data range has changed
723 {
724  OUString aNewData( m_xEdAssign2->GetText() );
725  if ( !aNewData.isEmpty() )
726  {
727  ScRange aRange;
728  if ( (aRange.ParseAny(aNewData, pDoc, pDoc->GetAddressConvention() ) & ScRefFlags::VALID) == ScRefFlags::VALID)
729  {
730  AdjustColRowData( aRange );
731  m_xBtnAdd->set_sensitive(true);
732  }
733  else
734  m_xBtnAdd->set_sensitive(false);
735  }
736  else
737  {
738  m_xBtnAdd->set_sensitive(false);
739  }
740 }
741 
742 // handler for the radio button for columns, adjust ranges
744 {
745  if (!m_xBtnColHead->get_active())
746  return;
747 
748  if ( theCurArea.aStart.Row() == 0 && theCurArea.aEnd.Row() == pDoc->MaxRow() )
749  {
750  theCurArea.aEnd.SetRow( pDoc->MaxRow() - 1 );
751  OUString aStr(theCurArea.Format(*pDoc, ScRefFlags::RANGE_ABS_3D, pDoc->GetAddressConvention()));
752  m_xEdAssign->SetText( aStr );
753  }
754  ScRange aRange( theCurData );
755  aRange.aStart.SetRow( std::min( static_cast<long>(theCurArea.aEnd.Row() + 1), static_cast<long>(pDoc->MaxRow()) ) );
756  aRange.aEnd.SetRow( pDoc->MaxRow() );
757  AdjustColRowData( aRange );
758 }
759 
760 // handler for the radio button for columns, adjust range
762 {
763  if (!m_xBtnRowHead->get_active())
764  return;
765 
766  if ( theCurArea.aStart.Col() == 0 && theCurArea.aEnd.Col() == pDoc->MaxCol() )
767  {
768  theCurArea.aEnd.SetCol( pDoc->MaxCol() - 1 );
769  OUString aStr(theCurArea.Format(*pDoc, ScRefFlags::RANGE_ABS_3D, pDoc->GetAddressConvention()));
770  m_xEdAssign->SetText( aStr );
771  }
772  ScRange aRange( theCurData );
773  aRange.aStart.SetCol( static_cast<SCCOL>(std::min( static_cast<long>(theCurArea.aEnd.Col() + 1), static_cast<long>(pDoc->MaxCol()) )) );
774  aRange.aEnd.SetCol( pDoc->MaxCol() );
775  AdjustColRowData( aRange );
776 }
777 
778 IMPL_LINK( ScColRowNameRangesDlg, GetEditFocusHdl, formula::RefEdit&, rCtrl, void )
779 {
780  if (&rCtrl == m_xEdAssign.get())
781  m_pEdActive = m_xEdAssign.get();
782  else if (&rCtrl == m_xEdAssign2.get())
783  m_pEdActive = m_xEdAssign2.get();
784  else
785  m_pEdActive = nullptr;
786 
787  if( m_pEdActive )
788  m_pEdActive->SelectAll();
789 }
790 
791 IMPL_LINK( ScColRowNameRangesDlg, GetButtonFocusHdl, formula::RefButton&, rCtrl, void )
792 {
793  if (&rCtrl == m_xRbAssign.get())
794  m_pEdActive = m_xEdAssign.get();
795  else if (&rCtrl == m_xRbAssign2.get())
796  m_pEdActive = m_xEdAssign2.get();
797  else
798  m_pEdActive = nullptr;
799 
800  if( m_pEdActive )
801  m_pEdActive->SelectAll();
802 }
803 
805 {
806  bDlgLostFocus = !m_xDialog->has_toplevel_focus();
807 }
808 
810 {
811  bDlgLostFocus = !m_xDialog->has_toplevel_focus();
812 }
813 
814 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const sal_uLong nEntryDataDelim
Definition: crnrdlg.cxx:53
SC_DLLPUBLIC ScRefFlags ParseAny(const OUString &, const ScDocument *, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1)
Definition: address.cxx:1770
formula::RefEdit * m_pEdActive
Definition: crnrdlg.hxx:57
ScAddress aStart
Definition: address.hxx:500
#define EMPTY_OUSTRING
Definition: global.hxx:214
SCROW Row() const
Definition: address.hxx:262
ScRangePairList * GetColNameRanges()
Definition: document.hxx:808
SC_DLLPUBLIC bool Intersects(const ScRange &rRange) const
Definition: address.cxx:1553
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:490
IMPL_LINK(ScColRowNameRangesDlg, GetEditFocusHdl, formula::RefEdit &, rCtrl, void)
Definition: crnrdlg.cxx:778
void SetDocumentModified()
Definition: docsh.cxx:2820
ScViewData * pViewData
Definition: crnrdlg.hxx:53
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:475
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
ScDocument * pDoc
Definition: crnrdlg.hxx:54
RET_YES
void SetColRowData(const ScRange &rLabelRange, bool bRef=false)
Definition: crnrdlg.cxx:160
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:873
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
Definition: crnrdlg.cxx:305
int nCount
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
Definition: document.cxx:3489
virtual bool IsRefInputMode() const override
Definition: crnrdlg.cxx:481
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:328
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:2207
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:1173
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:244
std::vector< const ScRangePair * > CreateNameSortedArray(ScDocument *) const
Definition: rangelst.cxx:1525
size_t size() const
Definition: rangelst.cxx:1231
RET_OK
ScColRowNameRangesDlg(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScViewData *ptrViewData)
Definition: crnrdlg.cxx:57
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:323
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::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:447
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