LibreOffice Module sc (master)  1
areasdlg.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 <rangelst.hxx>
21 
22 #include <sfx2/dispatch.hxx>
23 #include <svl/stritem.hxx>
24 #include <vcl/svapp.hxx>
25 #include <vcl/weld.hxx>
26 #include <unotools/charclass.hxx>
27 
28 #include <areasdlg.hxx>
29 #include <rangenam.hxx>
30 #include <reffact.hxx>
31 #include <tabvwsh.hxx>
32 #include <docsh.hxx>
33 #include <globstr.hrc>
34 #include <scresid.hxx>
35 #include <compiler.hxx>
36 #include <markdata.hxx>
37 
38 // List box positions for print range (PR)
39 enum {
43 };
44 
45 // List box positions for repeat ranges (RR)
46 enum {
50 };
51 
52 #define HDL(hdl) LINK( this, ScPrintAreasDlg, hdl )
53 namespace
54 {
55  void ERRORBOX(weld::Window* pParent, const char* rId)
56  {
57  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
58  VclMessageType::Warning, VclButtonsType::Ok,
59  ScResId(rId)));
60  xBox->run();
61  }
62 }
63 
64 // global functions (->at the end of the file):
65 
66 static bool lcl_CheckRepeatString( const OUString& rStr, const ScDocument& rDoc, bool bIsRow, ScRange* pRange );
67 static void lcl_GetRepeatRangeString( const ScRange* pRange, const ScDocument& rDoc, bool bIsRow, OUString& rStr );
68 
69 #if 0
70 // this method is useful when debugging address flags.
71 static void printAddressFlags(ScRefFlags nFlag)
72 {
73  if ((nFlag & ScRefFlags::COL_ABS ) == ScRefFlags::COL_ABS ) printf("ScRefFlags::COL_ABS \n");
74  if ((nFlag & ScRefFlags::ROW_ABS ) == ScRefFlags::ROW_ABS ) printf("ScRefFlags::ROW_ABS \n");
75  if ((nFlag & ScRefFlags::TAB_ABS ) == ScRefFlags::TAB_ABS ) printf("ScRefFlags::TAB_ABS \n");
76  if ((nFlag & ScRefFlags::TAB_3D ) == ScRefFlags::TAB_3D ) printf("ScRefFlags::TAB_3D \n");
77  if ((nFlag & ScRefFlags::COL2_ABS ) == ScRefFlags::COL2_ABS ) printf("ScRefFlags::COL2_ABS \n");
78  if ((nFlag & ScRefFlags::ROW2_ABS ) == ScRefFlags::ROW2_ABS ) printf("ScRefFlags::ROW2_ABS \n");
79  if ((nFlag & ScRefFlags::TAB2_ABS ) == ScRefFlags::TAB2_ABS ) printf("ScRefFlags::TAB2_ABS \n");
80  if ((nFlag & ScRefFlags::TAB2_3D ) == ScRefFlags::TAB2_3D ) printf("ScRefFlags::TAB2_3D \n");
81  if ((nFlag & ScRefFlags::ROW_VALID ) == ScRefFlags::ROW_VALID ) printf("ScRefFlags::ROW_VALID \n");
82  if ((nFlag & ScRefFlags::COL_VALID ) == ScRefFlags::COL_VALID ) printf("ScRefFlags::COL_VALID \n");
83  if ((nFlag & ScRefFlags::TAB_VALID ) == ScRefFlags::TAB_VALID ) printf("ScRefFlags::TAB_VALID \n");
84  if ((nFlag & ScRefFlags::FORCE_DOC ) == ScRefFlags::FORCE_DOC ) printf("ScRefFlags::FORCE_DOC \n");
85  if ((nFlag & ScRefFlags::ROW2_VALID ) == ScRefFlags::ROW2_VALID ) printf("ScRefFlags::ROW2_VALID \n");
86  if ((nFlag & ScRefFlags::COL2_VALID ) == ScRefFlags::COL2_VALID ) printf("ScRefFlags::COL2_VALID \n");
87  if ((nFlag & ScRefFlags::TAB2_VALID ) == ScRefFlags::TAB2_VALID ) printf("ScRefFlags::TAB2_VALID \n");
88  if ((nFlag & ScRefFlags::VALID ) == ScRefFlags::VALID ) printf("ScRefFlags::VALID \n");
89  if ((nFlag & ScRefFlags::ADDR_ABS ) == ScRefFlags::ADDR_ABS ) printf("ScRefFlags::ADDR_ABS \n");
90  if ((nFlag & ScRefFlags::RANGE_ABS ) == ScRefFlags::RANGE_ABS ) printf("ScRefFlags::RANGE_ABS \n");
91  if ((nFlag & ScRefFlags::ADDR_ABS_3D ) == ScRefFlags::ADDR_ABS_3D ) printf("ScRefFlags::ADDR_ABS_3D \n");
92  if ((nFlag & ScRefFlags::RANGE_ABS_3D ) == ScRefFlags::RANGE_ABS_3D ) printf("ScRefFlags::RANGE_ABS_3D \n");
93 }
94 #endif
95 
96 
98  : ScAnyRefDlgController(pB, pCW, pParent, "modules/scalc/ui/printareasdialog.ui", "PrintAreasDialog")
99  , bDlgLostFocus(false)
100  , pDoc(nullptr)
101  , pViewData(nullptr)
102  , nCurTab(0)
103  , m_xLbPrintArea(m_xBuilder->weld_combo_box("lbprintarea"))
104  , m_xEdPrintArea(new formula::RefEdit(m_xBuilder->weld_entry("edprintarea")))
105  , m_xRbPrintArea(new formula::RefButton(m_xBuilder->weld_button("rbprintarea")))
106  , m_xLbRepeatRow(m_xBuilder->weld_combo_box("lbrepeatrow"))
107  , m_xEdRepeatRow(new formula::RefEdit(m_xBuilder->weld_entry("edrepeatrow")))
108  , m_xRbRepeatRow(new formula::RefButton(m_xBuilder->weld_button("rbrepeatrow")))
109  , m_xLbRepeatCol(m_xBuilder->weld_combo_box("lbrepeatcol"))
110  , m_xEdRepeatCol(new formula::RefEdit(m_xBuilder->weld_entry("edrepeatcol")))
111  , m_xRbRepeatCol(new formula::RefButton(m_xBuilder->weld_button("rbrepeatcol")))
112  , m_xBtnOk(m_xBuilder->weld_button("ok"))
113  , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
114  , m_xPrintFrame(m_xBuilder->weld_frame("printframe"))
115  , m_xRowFrame(m_xBuilder->weld_frame("rowframe"))
116  , m_xColFrame(m_xBuilder->weld_frame("colframe"))
117  , m_xPrintFrameFT(m_xPrintFrame->weld_label_widget())
118  , m_xRowFrameFT(m_xRowFrame->weld_label_widget())
119  , m_xColFrameFT(m_xColFrame->weld_label_widget())
120 {
121  m_xEdPrintArea->SetReferences(this, m_xPrintFrameFT.get());
123  m_xRbPrintArea->SetReferences(this, m_xEdPrintArea.get());
124 
125  m_xEdRepeatRow->SetReferences(this, m_xRowFrameFT.get());
126  m_xRbRepeatRow->SetReferences(this, m_xEdRepeatRow.get());
127 
128  m_xEdRepeatCol->SetReferences(this, m_xColFrameFT.get());
129  m_xRbRepeatCol->SetReferences(this, m_xEdRepeatCol.get());
130 
131  ScTabViewShell* pScViewSh = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() );
132  ScDocShell* pScDocSh = dynamic_cast<ScDocShell*>(SfxObjectShell::Current());
133  assert(pScDocSh && "Current DocumentShell not found :-(");
134 
135  pDoc = &pScDocSh->GetDocument();
136 
137  if ( pScViewSh )
138  {
139  pViewData = &pScViewSh->GetViewData();
141  }
142 
143  Impl_Reset();
144 
145  //@BugID 54702 Enable/Disable only in base class
146  //SFX_APPWINDOW->Enable();
147 }
148 
150 {
151 }
152 
154 {
155  DoClose( ScPrintAreasDlgWrapper::GetChildWindowId() );
156 }
157 
159 {
160  // Printing areas are per table, therefore it makes no sense,
161  // to switch the table during input
162 
163  return true;
164 }
165 
166 void ScPrintAreasDlg::SetReference( const ScRange& rRef, ScDocument& /* rDoc */ )
167 {
168  if ( !m_pRefInputEdit )
169  return;
170 
171  if ( rRef.aStart != rRef.aEnd )
173 
174  OUString aStr;
176 
177  if (m_xEdPrintArea.get() == m_pRefInputEdit)
178  {
179  aStr = rRef.Format(*pDoc, ScRefFlags::RANGE_ABS, eConv);
180  OUString aVal = m_xEdPrintArea->GetText();
181  Selection aSel = m_xEdPrintArea->GetSelection();
182  aSel.Justify();
183  aVal = aVal.replaceAt( aSel.Min(), aSel.Len(), aStr );
184  Selection aNewSel( aSel.Min(), aSel.Min()+aStr.getLength() );
185  m_xEdPrintArea->SetRefString( aVal );
186  m_xEdPrintArea->SetSelection( aNewSel );
187  }
188  else
189  {
190  bool bRow = ( m_xEdRepeatRow.get() == m_pRefInputEdit );
191  lcl_GetRepeatRangeString(&rRef, *pDoc, bRow, aStr);
192  m_pRefInputEdit->SetRefString( aStr );
193  }
194  Impl_ModifyHdl( *m_pRefInputEdit );
195 }
196 
198 {
199  if (m_pRefInputEdit == m_xEdPrintArea.get())
200  {
202  OUString aVal = m_xEdPrintArea->GetText() + OUStringChar(sep);
203  m_xEdPrintArea->SetText(aVal);
204 
205  sal_Int32 nLen = aVal.getLength();
206  m_xEdPrintArea->SetSelection( Selection( nLen, nLen ) );
207 
208  Impl_ModifyHdl( *m_xEdPrintArea );
209  }
210 }
211 
213 {
214  bDlgLostFocus = true;
215 }
216 
218 {
219  if ( bDlgLostFocus )
220  {
221  bDlgLostFocus = false;
222 
223  if ( m_pRefInputEdit )
224  {
226  Impl_ModifyHdl( *m_pRefInputEdit );
227  }
228  }
229  else
230  m_xDialog->grab_focus();
231 
232  RefInputDone();
233 }
234 
236 {
237  OUString aStrRange;
238  const ScRange* pRepeatColRange = pDoc->GetRepeatColRange( nCurTab );
239  const ScRange* pRepeatRowRange = pDoc->GetRepeatRowRange( nCurTab );
240 
241  m_xEdPrintArea->SetModifyHdl ( HDL(Impl_ModifyHdl) );
242  m_xEdRepeatRow->SetModifyHdl ( HDL(Impl_ModifyHdl) );
243  m_xEdRepeatCol->SetModifyHdl ( HDL(Impl_ModifyHdl) );
244  m_xEdPrintArea->SetGetFocusHdl( HDL(Impl_GetEditFocusHdl) );
245  m_xEdRepeatRow->SetGetFocusHdl( HDL(Impl_GetEditFocusHdl) );
246  m_xEdRepeatCol->SetGetFocusHdl( HDL(Impl_GetEditFocusHdl) );
247  m_xLbPrintArea->connect_focus_in( HDL(Impl_GetFocusHdl) );
248  m_xLbRepeatRow->connect_focus_in( HDL(Impl_GetFocusHdl) );
249  m_xLbRepeatCol->connect_focus_in( HDL(Impl_GetFocusHdl) );
250  m_xLbPrintArea->connect_changed( HDL(Impl_SelectHdl) );
251  m_xLbRepeatRow->connect_changed( HDL(Impl_SelectHdl) );
252  m_xLbRepeatCol->connect_changed( HDL(Impl_SelectHdl) );
253  m_xBtnOk->connect_clicked( HDL(Impl_BtnHdl) );
254  m_xBtnCancel->connect_clicked( HDL(Impl_BtnHdl) );
255 
256  Impl_FillLists();
257 
258  // printing area
259 
260  aStrRange.clear();
263  sal_uInt16 nRangeCount = pDoc->GetPrintRangeCount( nCurTab );
264  for (sal_uInt16 i=0; i<nRangeCount; i++)
265  {
266  const ScRange* pPrintRange = pDoc->GetPrintRange( nCurTab, i );
267  if (pPrintRange)
268  {
269  if ( !aStrRange.isEmpty() )
270  aStrRange += OUStringChar(sep);
271  aStrRange += pPrintRange->Format(*pDoc, ScRefFlags::RANGE_ABS, eConv);
272  }
273  }
274  m_xEdPrintArea->SetText( aStrRange );
275 
276  // repeat row
277 
278  lcl_GetRepeatRangeString(pRepeatRowRange, *pDoc, true, aStrRange);
279  m_xEdRepeatRow->SetText( aStrRange );
280 
281  // repeat column
282 
283  lcl_GetRepeatRangeString(pRepeatColRange, *pDoc, false, aStrRange);
284  m_xEdRepeatCol->SetText( aStrRange );
285 
286  Impl_ModifyHdl( *m_xEdPrintArea );
287  Impl_ModifyHdl( *m_xEdRepeatRow );
288  Impl_ModifyHdl( *m_xEdRepeatCol );
291 
292  m_xEdPrintArea->SaveValue(); // save for FillItemSet():
293  m_xEdRepeatRow->SaveValue();
294  m_xEdRepeatCol->SaveValue();
295 }
296 
298 {
299  OUString aRangeStr = pEd->GetText();
300  bool bDataChanged = pEd->IsValueChangedFromSaved();
301 
302  if ( !aRangeStr.isEmpty() && m_xEdPrintArea.get() != pEd )
303  {
304  ScRange aRange;
306  lcl_CheckRepeatString(aRangeStr, *pDoc, m_xEdRepeatRow.get() == pEd, &aRange);
307  aRangeStr = aRange.Format(*pDoc, ScRefFlags::RANGE_ABS, eConv);
308  }
309 
310  rItem.SetValue( aRangeStr );
311 
312  return bDataChanged;
313 }
314 
316 {
317  bool bOk = false;
318  OUString aStrPrintArea = m_xEdPrintArea->GetText();
319  OUString aStrRepeatRow = m_xEdRepeatRow->GetText();
320  OUString aStrRepeatCol = m_xEdRepeatCol->GetText();
321 
322  bool bPrintAreaOk = true;
323  if ( !aStrPrintArea.isEmpty() )
324  {
325  const ScRefFlags nValidAddr = ScRefFlags::VALID | ScRefFlags::ROW_VALID | ScRefFlags::COL_VALID;
326  const ScRefFlags nValidRange = nValidAddr | ScRefFlags::ROW2_VALID | ScRefFlags::COL2_VALID;
329 
330  ScAddress aAddr;
331  ScRange aRange;
332  for ( sal_Int32 nIdx = 0; nIdx >= 0; )
333  {
334  const OUString aOne = aStrPrintArea.getToken(0, sep, nIdx);
335  ScRefFlags nResult = aRange.Parse( aOne, *pDoc, eConv );
336  if ((nResult & nValidRange) != nValidRange)
337  {
338  ScRefFlags nAddrResult = aAddr.Parse( aOne, *pDoc, eConv );
339  if ((nAddrResult & nValidAddr) != nValidAddr)
340  {
341  bPrintAreaOk = false;
342  break;
343  }
344  }
345  }
346  }
347 
348  bool bRepeatRowOk = aStrRepeatRow.isEmpty();
349  if ( !bRepeatRowOk )
350  bRepeatRowOk = lcl_CheckRepeatString(aStrRepeatRow, *pDoc, true, nullptr);
351 
352  bool bRepeatColOk = aStrRepeatCol.isEmpty();
353  if ( !bRepeatColOk )
354  bRepeatColOk = lcl_CheckRepeatString(aStrRepeatCol, *pDoc, false, nullptr);
355 
356  // error messages
357 
358  bOk = (bPrintAreaOk && bRepeatRowOk && bRepeatColOk);
359 
360  if ( !bOk )
361  {
362  formula::RefEdit* pEd = nullptr;
363 
364  if ( !bPrintAreaOk ) pEd = m_xEdPrintArea.get();
365  else if ( !bRepeatRowOk ) pEd = m_xEdRepeatRow.get();
366  else if ( !bRepeatColOk ) pEd = m_xEdRepeatCol.get();
367 
368  ERRORBOX(m_xDialog.get(), STR_INVALID_TABREF);
369 
370  OSL_ASSERT(pEd);
371 
372  if (pEd)
373  pEd->GrabFocus();
374  }
375 
376  return bOk;
377 }
378 
380 {
381 
382  // Get selection and remember String in PrintArea-ListBox
383 
384  ScRange aRange;
385  OUString aStrRange;
386  bool bSimple = true;
387 
388  if ( pViewData )
389  bSimple = (pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE);
390 
392 
393  if ( bSimple )
394  aStrRange = aRange.Format(*pDoc, ScRefFlags::RANGE_ABS, eConv);
395  else
396  {
397  ScRangeListRef aList( new ScRangeList );
398  pViewData->GetMarkData().FillRangeListWithMarks( aList.get(), false );
399  aList->Format(aStrRange, ScRefFlags::RANGE_ABS, *pDoc, eConv);
400  }
401 
402  m_xLbPrintArea->set_id(SC_AREASDLG_PR_SELECT, aStrRange);
403 
404  // Get ranges and remember in ListBoxen
405 
406  ScRangeName* pRangeNames = pDoc->GetRangeName();
407 
408  if (!pRangeNames || pRangeNames->empty())
409  // No range names to process.
410  return;
411 
412  for (const auto& rEntry : *pRangeNames)
413  {
414  if (!rEntry.second->HasType(ScRangeData::Type::AbsArea )
415  && !rEntry.second->HasType(ScRangeData::Type::RefArea)
416  && !rEntry.second->HasType(ScRangeData::Type::AbsPos ))
417  continue;
418 
419  OUString aName = rEntry.second->GetName();
420  OUString aSymbol;
421  rEntry.second->GetSymbol(aSymbol);
422  if (aRange.ParseAny(aSymbol, *pDoc, eConv) & ScRefFlags::VALID)
423  {
424  if (rEntry.second->HasType(ScRangeData::Type::PrintArea))
425  {
426  aSymbol = aRange.Format(*pDoc, ScRefFlags::RANGE_ABS, eConv);
427  m_xLbPrintArea->append(aSymbol, aName);
428  }
429 
430  if (rEntry.second->HasType(ScRangeData::Type::RowHeader))
431  {
432  lcl_GetRepeatRangeString(&aRange, *pDoc, true, aSymbol);
433  m_xLbRepeatRow->append(aSymbol, aName);
434  }
435 
436  if (rEntry.second->HasType(ScRangeData::Type::ColHeader))
437  {
438  lcl_GetRepeatRangeString(&aRange, *pDoc, false, aSymbol);
439  m_xLbRepeatCol->append(aSymbol, aName);
440  }
441  }
442  }
443 }
444 
445 // Handler:
446 
447 IMPL_LINK(ScPrintAreasDlg, Impl_BtnHdl, weld::Button&, rBtn, void)
448 {
449  if (m_xBtnOk.get() == &rBtn)
450  {
451  if ( Impl_CheckRefStrings() )
452  {
453  SfxStringItem aPrintArea( SID_CHANGE_PRINTAREA, "" );
454  SfxStringItem aRepeatRow( FN_PARAM_2, "" );
455  SfxStringItem aRepeatCol( FN_PARAM_3, "" );
456 
457  // Printing area changed?
458 
459  // first try the list box, if "Entire sheet" is selected
460  bool bEntireSheet = (m_xLbPrintArea->get_active() == SC_AREASDLG_PR_ENTIRE);
461  SfxBoolItem aEntireSheet( FN_PARAM_4, bEntireSheet );
462 
463  bool bDataChanged = bEntireSheet != pDoc->IsPrintEntireSheet( nCurTab );
464  if( !bEntireSheet )
465  {
466  // if new list box selection is not "Entire sheet", get the edit field contents
467  bDataChanged |= Impl_GetItem( m_xEdPrintArea.get(), aPrintArea );
468  }
469 
470  // Repeat row changed?
471 
472  bDataChanged |= Impl_GetItem( m_xEdRepeatRow.get(), aRepeatRow );
473 
474  // Repeat column changed?
475 
476  bDataChanged |= Impl_GetItem( m_xEdRepeatCol.get(), aRepeatCol );
477 
478  if ( bDataChanged )
479  {
480  SetDispatcherLock( false );
481  SwitchToDocument();
482  GetBindings().GetDispatcher()->ExecuteList(SID_CHANGE_PRINTAREA,
483  SfxCallMode::SLOT | SfxCallMode::RECORD,
484  { &aPrintArea, &aRepeatRow, &aRepeatCol, &aEntireSheet });
485  }
486 
487  response(RET_OK);
488  }
489  }
490  else if (m_xBtnCancel.get() == &rBtn)
491  response(RET_CANCEL);
492 }
493 
494 IMPL_LINK(ScPrintAreasDlg, Impl_GetEditFocusHdl, formula::RefEdit&, rCtrl, void)
495 {
496  m_pRefInputEdit = &rCtrl;
497 }
498 
499 IMPL_LINK(ScPrintAreasDlg, Impl_GetFocusHdl, weld::Widget&, rCtrl, void)
500 {
501  if (&rCtrl == m_xLbPrintArea.get())
502  m_pRefInputEdit = m_xEdPrintArea.get();
503  else if (&rCtrl == m_xLbRepeatRow.get())
504  m_pRefInputEdit = m_xEdRepeatRow.get();
505  else if (&rCtrl == m_xLbRepeatCol.get())
506  m_pRefInputEdit = m_xEdRepeatCol.get();
507 }
508 
509 IMPL_LINK( ScPrintAreasDlg, Impl_SelectHdl, weld::ComboBox&, rLb, void )
510 {
511  const sal_Int32 nSelPos = rLb.get_active();
512  formula::RefEdit* pEd = nullptr;
513 
514  // list box positions of specific entries, default to "repeat row/column" list boxes
515  sal_Int32 nAllSheetPos = SC_AREASDLG_RR_NONE;
516  sal_Int32 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
517 
518  // find edit field for list box, and list box positions
519  if (&rLb == m_xLbPrintArea.get())
520  {
521  pEd = m_xEdPrintArea.get();
522  nAllSheetPos = SC_AREASDLG_PR_ENTIRE;
523  nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
524  }
525  else if (&rLb == m_xLbRepeatCol.get())
526  pEd = m_xEdRepeatCol.get();
527  else if (&rLb == m_xLbRepeatRow.get())
528  pEd = m_xEdRepeatRow.get();
529  else
530  return;
531 
532  // fill edit field according to list box selection
533  if( (nSelPos == 0) || (nSelPos == nAllSheetPos) )
534  pEd->SetText( EMPTY_OUSTRING );
535  else if( nSelPos >= nFirstCustomPos )
536  pEd->SetText(rLb.get_id(nSelPos));
537 }
538 
539 IMPL_LINK( ScPrintAreasDlg, Impl_ModifyHdl, formula::RefEdit&, rEd, void )
540 {
541  weld::ComboBox* pLb = nullptr;
542 
543  // list box positions of specific entries, default to "repeat row/column" list boxes
544  sal_Int32 nUserDefPos = SC_AREASDLG_RR_USER;
545  sal_Int32 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
546 
547  if( &rEd == m_xEdPrintArea.get() )
548  {
549  pLb = m_xLbPrintArea.get();
550  nUserDefPos = SC_AREASDLG_PR_USER;
551  nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
552  }
553  else if( &rEd == m_xEdRepeatCol.get() )
554  pLb = m_xLbRepeatCol.get();
555  else if( &rEd == m_xEdRepeatRow.get() )
556  pLb = m_xLbRepeatRow.get();
557  else
558  return;
559 
560  // set list box selection according to edit field
561  const sal_Int32 nEntryCount = pLb->get_count();
562  OUString aStrEd( rEd.GetText() );
563  OUString aEdUpper = aStrEd.toAsciiUpperCase();
564 
565  if ( (nEntryCount > nFirstCustomPos) && !aStrEd.isEmpty() )
566  {
567  bool bFound = false;
568  sal_Int32 i;
569 
570  for ( i=nFirstCustomPos; i<nEntryCount && !bFound; i++ )
571  {
572  const OUString& rSymbol = pLb->get_id(i);
573  bFound = (rSymbol == aStrEd || rSymbol == aEdUpper);
574  }
575 
576  pLb->set_active( bFound ? i-1 : nUserDefPos );
577  }
578  else
579  pLb->set_active( !aStrEd.isEmpty() ? nUserDefPos : 0 );
580 }
581 
582 // global functions:
583 
584 // TODO: It might make sense to move these functions to address.?xx. -kohei
585 
586 static bool lcl_CheckOne_OOO( const ScDocument& rDoc, const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
587 {
588  // Allowed syntax for rStr:
589  // Row: [$]1-MAXTAB
590  // Col: [$]A-IV
591 
592  OUString aStr = rStr;
593  sal_Int32 nLen = aStr.getLength();
594  SCCOLROW nNum = 0;
595  bool bStrOk = ( nLen > 0 ) && ( bIsRow ? ( nLen < 6 ) : ( nLen < 4 ) );
596 
597  if ( bStrOk )
598  {
599  if ( '$' == aStr[0] )
600  aStr = aStr.copy( 1 );
601 
602  if ( bIsRow )
603  {
604  bStrOk = CharClass::isAsciiNumeric(aStr);
605 
606  if ( bStrOk )
607  {
608  sal_Int32 n = aStr.toInt32();
609 
610  bStrOk = (n > 0) && ( n <= rDoc.GetSheetLimits().GetMaxRowCount() );
611  if ( bStrOk )
612  nNum = static_cast<SCCOLROW>(n - 1);
613  }
614  }
615  else
616  {
617  SCCOL nCol = 0;
618  bStrOk = ::AlphaToCol(rDoc, nCol, aStr);
619  nNum = nCol;
620  }
621  }
622 
623  if ( bStrOk )
624  rVal = nNum;
625 
626  return bStrOk;
627 }
628 
629 static bool lcl_CheckOne_XL_A1( const ScDocument& rDoc, const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
630 {
631  // XL A1 style is identical to OOO one for print range formats.
632  return lcl_CheckOne_OOO(rDoc, rStr, bIsRow, rVal);
633 }
634 
635 static bool lcl_CheckOne_XL_R1C1( const ScDocument& rDoc, const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
636 {
637  sal_Int32 nLen = rStr.getLength();
638  if (nLen <= 1)
639  // There must be at least two characters.
640  return false;
641 
642  const sal_Unicode preUpper = bIsRow ? 'R' : 'C';
643  const sal_Unicode preLower = bIsRow ? 'r' : 'c';
644  if (rStr[0] != preUpper && rStr[0] != preLower)
645  return false;
646 
647  OUString aNumStr = rStr.copy(1);
648  if (!CharClass::isAsciiNumeric(aNumStr))
649  return false;
650 
651  sal_Int32 nNum = aNumStr.toInt32();
652 
653  if (nNum <= 0)
654  return false;
655 
656  if ((bIsRow && nNum > rDoc.GetSheetLimits().GetMaxRowCount()) || (!bIsRow && nNum > MAXCOLCOUNT))
657  return false;
658 
659  rVal = static_cast<SCCOLROW>(nNum-1);
660  return true;
661 }
662 
663 static bool lcl_CheckRepeatOne( const ScDocument& rDoc, const OUString& rStr, formula::FormulaGrammar::AddressConvention eConv, bool bIsRow, SCCOLROW& rVal )
664 {
665  switch (eConv)
666  {
668  return lcl_CheckOne_OOO(rDoc, rStr, bIsRow, rVal);
670  return lcl_CheckOne_XL_A1(rDoc, rStr, bIsRow, rVal);
672  return lcl_CheckOne_XL_R1C1(rDoc, rStr, bIsRow, rVal);
673  default:
674  {
675  // added to avoid warnings
676  }
677  }
678  return false;
679 }
680 
681 static bool lcl_CheckRepeatString( const OUString& rStr, const ScDocument& rDoc, bool bIsRow, ScRange* pRange )
682 {
683  // Row: [valid row] rsep [valid row]
684  // Col: [valid col] rsep [valid col]
685 
688 
689  if (pRange)
690  {
691  // initialize the range value.
692  pRange->aStart.SetCol(0);
693  pRange->aStart.SetRow(0);
694  pRange->aEnd.SetCol(0);
695  pRange->aEnd.SetRow(0);
696  }
697 
698  OUString aBuf;
699  SCCOLROW nVal = 0;
700  sal_Int32 nLen = rStr.getLength();
701  bool bEndPos = false;
702  for( sal_Int32 i = 0; i < nLen; ++i )
703  {
704  const sal_Unicode c = rStr[i];
705  if (c == rsep)
706  {
707  if (bEndPos)
708  // We aren't supposed to have more than one range separator.
709  return false;
710 
711  // range separator
712  if (aBuf.isEmpty())
713  return false;
714 
715  bool bRes = lcl_CheckRepeatOne(rDoc, aBuf, eConv, bIsRow, nVal);
716  if (!bRes)
717  return false;
718 
719  if (pRange)
720  {
721  if (bIsRow)
722  {
723  pRange->aStart.SetRow(static_cast<SCROW>(nVal));
724  pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
725  }
726  else
727  {
728  pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
729  pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
730  }
731  }
732 
733  aBuf.clear();
734  bEndPos = true;
735  }
736  else
737  aBuf += OUStringChar(c);
738  }
739 
740  if (!aBuf.isEmpty())
741  {
742  bool bRes = lcl_CheckRepeatOne(rDoc, aBuf, eConv, bIsRow, nVal);
743  if (!bRes)
744  return false;
745 
746  if (pRange)
747  {
748  if (bIsRow)
749  {
750  if (!bEndPos)
751  pRange->aStart.SetRow(static_cast<SCROW>(nVal));
752  pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
753  }
754  else
755  {
756  if (!bEndPos)
757  pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
758  pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
759  }
760  }
761  }
762 
763  return true;
764 }
765 
766 static void lcl_GetRepeatRangeString( const ScRange* pRange, const ScDocument& rDoc, bool bIsRow, OUString& rStr )
767 {
768  rStr.clear();
769  if (!pRange)
770  return;
771 
773  const ScAddress& rStart = pRange->aStart;
774  const ScAddress& rEnd = pRange->aEnd;
775 
776  const ScRefFlags nFmt = bIsRow
777  ? (ScRefFlags::ROW_VALID | ScRefFlags::ROW_ABS)
778  : (ScRefFlags::COL_VALID | ScRefFlags::COL_ABS);
779  rStr += rStart.Format(nFmt, &rDoc, eConv);
780  if ((bIsRow && rStart.Row() != rEnd.Row()) || (!bIsRow && rStart.Col() != rEnd.Col()))
781  {
783  rStr += rEnd.Format(nFmt, &rDoc, eConv);
784  }
785 }
786 
787 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3046
SC_DLLPUBLIC ScRefFlags ParseAny(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1)
Definition: address.cxx:1766
virtual ~ScPrintAreasDlg() override
Definition: areasdlg.cxx:149
std::unique_ptr< weld::Label > m_xRowFrameFT
Definition: areasdlg.hxx:73
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2107
virtual bool IsTableLocked() const override
Definition: areasdlg.cxx:158
static void lcl_GetRepeatRangeString(const ScRange *pRange, const ScDocument &rDoc, bool bIsRow, OUString &rStr)
Definition: areasdlg.cxx:766
SC_DLLPUBLIC const ScRange * GetRepeatColRange(SCTAB nTab)
Definition: document.cxx:6287
ScAddress aStart
Definition: address.hxx:500
#define EMPTY_OUSTRING
Definition: global.hxx:215
SCROW Row() const
Definition: address.hxx:262
std::unique_ptr< weld::ComboBox > m_xLbRepeatCol
Definition: areasdlg.hxx:61
std::unique_ptr< weld::Label > m_xColFrameFT
Definition: areasdlg.hxx:74
static bool lcl_CheckRepeatOne(const ScDocument &rDoc, const OUString &rStr, formula::FormulaGrammar::AddressConvention eConv, bool bIsRow, SCCOLROW &rVal)
Definition: areasdlg.cxx:663
void Format(OUString &, ScRefFlags nFlags, const ScDocument &, formula::FormulaGrammar::AddressConvention eConv=formula::FormulaGrammar::CONV_OOO, sal_Unicode cDelimiter=0, bool bFullAddressNotation=false) const
Definition: rangelst.cxx:146
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:168
bool Impl_CheckRefStrings()
Definition: areasdlg.cxx:315
sal_Int64 n
aBuf
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
Definition: markdata.cxx:387
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
ScAddress aEnd
Definition: address.hxx:501
std::unique_ptr< weld::ComboBox > m_xLbPrintArea
Definition: areasdlg.hxx:53
std::unique_ptr< weld::Button > m_xBtnOk
Definition: areasdlg.hxx:65
static SfxObjectShell * Current()
bool Impl_GetItem(const formula::RefEdit *pEd, SfxStringItem &rItem)
Definition: areasdlg.cxx:297
const SCCOL MAXCOLCOUNT
Definition: address.hxx:64
SCROW GetMaxRowCount() const
Definition: sheetlimits.hxx:61
std::unique_ptr< weld::ComboBox > m_xLbRepeatRow
Definition: areasdlg.hxx:57
RET_CANCEL
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:489
#define HDL(hdl)
Definition: areasdlg.cxx:52
virtual int get_count() const =0
std::unique_ptr< formula::RefEdit > m_xEdRepeatCol
Definition: areasdlg.hxx:62
std::unique_ptr< formula::RefEdit > m_xEdRepeatRow
Definition: areasdlg.hxx:58
sal_uInt16 sal_Unicode
void Impl_FillLists()
Definition: areasdlg.cxx:379
void SetValue(const OUString &rTheValue)
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:24
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
bool empty() const
Definition: rangenam.cxx:805
static SfxViewShell * Current()
SC_DLLPUBLIC const ScRange * GetPrintRange(SCTAB nTab, sal_uInt16 nPos)
Definition: document.cxx:6279
void SetRow(SCROW nRowP)
Definition: address.hxx:275
static sal_Unicode GetNativeSymbolChar(OpCode eOp)
void SetCol(SCCOL nColP)
Definition: address.hxx:279
bool IsPrintEntireSheet(SCTAB nTab) const
Returns true, if the specified sheet is always printed.
Definition: document.cxx:6266
ScViewData & GetViewData()
Definition: tabview.hxx:332
ScPrintAreasDlg(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent)
Definition: areasdlg.cxx:97
ocSep
std::unique_ptr< weld::Button > m_xBtnCancel
Definition: areasdlg.hxx:66
void Impl_Reset()
Definition: areasdlg.cxx:235
void SetRefString(const OUString &rStr)
T * get() const
void Justify()
SC_DLLPUBLIC sal_uInt16 GetPrintRangeCount(SCTAB nTab)
Definition: document.cxx:6271
static const OUString & GetNativeSymbol(OpCode eOp)
virtual void AddRefEntry() override
Definition: areasdlg.cxx:197
int i
std::unique_ptr< formula::RefButton > m_xRbPrintArea
Definition: areasdlg.hxx:55
sal_Int16 SCCOL
Definition: types.hxx:22
static bool lcl_CheckOne_XL_A1(const ScDocument &rDoc, const OUString &rStr, bool bIsRow, SCCOLROW &rVal)
Definition: areasdlg.cxx:629
virtual void Close() override
Definition: areasdlg.cxx:153
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:874
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
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
void SetText(const OUString &rStr)
std::unique_ptr< formula::RefButton > m_xRbRepeatRow
Definition: areasdlg.hxx:59
virtual void RefInputDone(bool bForced=false) override
Definition: anyrefdg.cxx:755
ScViewData * pViewData
Definition: areasdlg.hxx:48
OUString GetText() const
virtual void set_active(int pos)=0
IMPL_LINK(ScPrintAreasDlg, Impl_BtnHdl, weld::Button &, rBtn, void)
Definition: areasdlg.cxx:447
SCCOL Col() const
Definition: address.hxx:267
tools::Long Len() const
formula::RefEdit * m_pRefInputEdit
Definition: areasdlg.hxx:51
bool AlphaToCol(const ScDocument &rDoc, SCCOL &rCol, const OUString &rStr)
get column number of A..IV... string
Definition: address.cxx:2532
std::unique_ptr< formula::RefEdit > m_xEdPrintArea
Definition: areasdlg.hxx:54
bool IsValueChangedFromSaved() const
static bool lcl_CheckRepeatString(const OUString &rStr, const ScDocument &rDoc, bool bIsRow, ScRange *pRange)
Definition: areasdlg.cxx:681
static bool lcl_CheckOne_OOO(const ScDocument &rDoc, const OUString &rStr, bool bIsRow, SCCOLROW &rVal)
Definition: areasdlg.cxx:586
virtual void Deactivate() override
Definition: areasdlg.cxx:212
SC_DLLPUBLIC const ScRange * GetRepeatRowRange(SCTAB nTab)
Definition: document.cxx:6295
std::unique_ptr< formula::RefButton > m_xRbRepeatCol
Definition: areasdlg.hxx:63
tools::Long Min() const
OUString aName
RET_OK
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, ScAddress::ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1733
virtual void SetActive() override
Definition: areasdlg.cxx:217
Reference< XExecutableDialog > m_xDialog
const ScDocument & GetDocument() const
Definition: docsh.hxx:216
virtual OUString get_id(int pos) const =0
static bool isAsciiNumeric(const OUString &rStr)
ScDocument * pDoc
Definition: areasdlg.hxx:47
std::unique_ptr< weld::Label > m_xPrintFrameFT
Definition: areasdlg.hxx:72
bool bDlgLostFocus
Definition: areasdlg.hxx:46
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument &, const Details &rDetails=detailsOOOa1, ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, sal_Int32 *pSheetEndPos=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1539
ScRefFlags
Definition: address.hxx:145
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
Definition: areasdlg.cxx:166
bool DoClose(sal_uInt16 nId)
Definition: anyrefdg.cxx:694
ocRange
aStr
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
static bool lcl_CheckOne_XL_R1C1(const ScDocument &rDoc, const OUString &rStr, bool bIsRow, SCCOLROW &rVal)
Definition: areasdlg.cxx:635
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
Definition: anyrefdg.cxx:725