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  {
170  if ( rRef.aStart != rRef.aEnd )
172 
173  OUString aStr;
175 
176  if (m_xEdPrintArea.get() == m_pRefInputEdit)
177  {
178  aStr = rRef.Format(*pDoc, ScRefFlags::RANGE_ABS, eConv);
179  OUString aVal = m_xEdPrintArea->GetText();
180  Selection aSel = m_xEdPrintArea->GetSelection();
181  aSel.Justify();
182  aVal = aVal.replaceAt( aSel.Min(), aSel.Len(), aStr );
183  Selection aNewSel( aSel.Min(), aSel.Min()+aStr.getLength() );
184  m_xEdPrintArea->SetRefString( aVal );
185  m_xEdPrintArea->SetSelection( aNewSel );
186  }
187  else
188  {
189  bool bRow = ( m_xEdRepeatRow.get() == m_pRefInputEdit );
190  lcl_GetRepeatRangeString(&rRef, *pDoc, bRow, aStr);
191  m_pRefInputEdit->SetRefString( aStr );
192  }
193  Impl_ModifyHdl( *m_pRefInputEdit );
194  }
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  OUString aStr;
454  SfxStringItem aPrintArea( SID_CHANGE_PRINTAREA, aStr );
455  SfxStringItem aRepeatRow( FN_PARAM_2, aStr );
456  SfxStringItem aRepeatCol( FN_PARAM_3, aStr );
457 
458  // Printing area changed?
459 
460  // first try the list box, if "Entire sheet" is selected
461  bool bEntireSheet = (m_xLbPrintArea->get_active() == SC_AREASDLG_PR_ENTIRE);
462  SfxBoolItem aEntireSheet( FN_PARAM_4, bEntireSheet );
463 
464  bool bDataChanged = bEntireSheet != pDoc->IsPrintEntireSheet( nCurTab );
465  if( !bEntireSheet )
466  {
467  // if new list box selection is not "Entire sheet", get the edit field contents
468  bDataChanged |= Impl_GetItem( m_xEdPrintArea.get(), aPrintArea );
469  }
470 
471  // Repeat row changed?
472 
473  bDataChanged |= Impl_GetItem( m_xEdRepeatRow.get(), aRepeatRow );
474 
475  // Repeat column changed?
476 
477  bDataChanged |= Impl_GetItem( m_xEdRepeatCol.get(), aRepeatCol );
478 
479  if ( bDataChanged )
480  {
481  SetDispatcherLock( false );
482  SwitchToDocument();
483  GetBindings().GetDispatcher()->ExecuteList(SID_CHANGE_PRINTAREA,
484  SfxCallMode::SLOT | SfxCallMode::RECORD,
485  { &aPrintArea, &aRepeatRow, &aRepeatCol, &aEntireSheet });
486  }
487 
488  response(RET_OK);
489  }
490  }
491  else if (m_xBtnCancel.get() == &rBtn)
492  response(RET_CANCEL);
493 }
494 
495 IMPL_LINK(ScPrintAreasDlg, Impl_GetEditFocusHdl, formula::RefEdit&, rCtrl, void)
496 {
497  m_pRefInputEdit = &rCtrl;
498 }
499 
500 IMPL_LINK(ScPrintAreasDlg, Impl_GetFocusHdl, weld::Widget&, rCtrl, void)
501 {
502  if (&rCtrl == m_xLbPrintArea.get())
503  m_pRefInputEdit = m_xEdPrintArea.get();
504  else if (&rCtrl == m_xLbRepeatRow.get())
505  m_pRefInputEdit = m_xEdRepeatRow.get();
506  else if (&rCtrl == m_xLbRepeatCol.get())
507  m_pRefInputEdit = m_xEdRepeatCol.get();
508 }
509 
510 IMPL_LINK( ScPrintAreasDlg, Impl_SelectHdl, weld::ComboBox&, rLb, void )
511 {
512  const sal_Int32 nSelPos = rLb.get_active();
513  formula::RefEdit* pEd = nullptr;
514 
515  // list box positions of specific entries, default to "repeat row/column" list boxes
516  sal_Int32 nAllSheetPos = SC_AREASDLG_RR_NONE;
517  sal_Int32 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
518 
519  // find edit field for list box, and list box positions
520  if (&rLb == m_xLbPrintArea.get())
521  {
522  pEd = m_xEdPrintArea.get();
523  nAllSheetPos = SC_AREASDLG_PR_ENTIRE;
524  nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
525  }
526  else if (&rLb == m_xLbRepeatCol.get())
527  pEd = m_xEdRepeatCol.get();
528  else if (&rLb == m_xLbRepeatRow.get())
529  pEd = m_xEdRepeatRow.get();
530  else
531  return;
532 
533  // fill edit field according to list box selection
534  if( (nSelPos == 0) || (nSelPos == nAllSheetPos) )
535  pEd->SetText( EMPTY_OUSTRING );
536  else if( nSelPos >= nFirstCustomPos )
537  pEd->SetText(rLb.get_id(nSelPos));
538 }
539 
540 IMPL_LINK( ScPrintAreasDlg, Impl_ModifyHdl, formula::RefEdit&, rEd, void )
541 {
542  weld::ComboBox* pLb = nullptr;
543 
544  // list box positions of specific entries, default to "repeat row/column" list boxes
545  sal_Int32 nUserDefPos = SC_AREASDLG_RR_USER;
546  sal_Int32 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
547 
548  if( &rEd == m_xEdPrintArea.get() )
549  {
550  pLb = m_xLbPrintArea.get();
551  nUserDefPos = SC_AREASDLG_PR_USER;
552  nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
553  }
554  else if( &rEd == m_xEdRepeatCol.get() )
555  pLb = m_xLbRepeatCol.get();
556  else if( &rEd == m_xEdRepeatRow.get() )
557  pLb = m_xLbRepeatRow.get();
558  else
559  return;
560 
561  // set list box selection according to edit field
562  const sal_Int32 nEntryCount = pLb->get_count();
563  OUString aStrEd( rEd.GetText() );
564  OUString aEdUpper = aStrEd.toAsciiUpperCase();
565 
566  if ( (nEntryCount > nFirstCustomPos) && !aStrEd.isEmpty() )
567  {
568  bool bFound = false;
569  sal_Int32 i;
570 
571  for ( i=nFirstCustomPos; i<nEntryCount && !bFound; i++ )
572  {
573  const OUString& rSymbol = pLb->get_id(i);
574  bFound = (rSymbol == aStrEd || rSymbol == aEdUpper);
575  }
576 
577  pLb->set_active( bFound ? i-1 : nUserDefPos );
578  }
579  else
580  pLb->set_active( !aStrEd.isEmpty() ? nUserDefPos : 0 );
581 }
582 
583 // global functions:
584 
585 // TODO: It might make sense to move these functions to address.?xx. -kohei
586 
587 static bool lcl_CheckOne_OOO( const ScDocument& rDoc, const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
588 {
589  // Allowed syntax for rStr:
590  // Row: [$]1-MAXTAB
591  // Col: [$]A-IV
592 
593  OUString aStr = rStr;
594  sal_Int32 nLen = aStr.getLength();
595  SCCOLROW nNum = 0;
596  bool bStrOk = ( nLen > 0 ) && ( bIsRow ? ( nLen < 6 ) : ( nLen < 4 ) );
597 
598  if ( bStrOk )
599  {
600  if ( '$' == aStr[0] )
601  aStr = aStr.copy( 1 );
602 
603  if ( bIsRow )
604  {
605  bStrOk = CharClass::isAsciiNumeric(aStr);
606 
607  if ( bStrOk )
608  {
609  sal_Int32 n = aStr.toInt32();
610 
611  bStrOk = (n > 0) && ( n <= MAXROWCOUNT );
612  if ( bStrOk )
613  nNum = static_cast<SCCOLROW>(n - 1);
614  }
615  }
616  else
617  {
618  SCCOL nCol = 0;
619  bStrOk = ::AlphaToCol(rDoc, nCol, aStr);
620  nNum = nCol;
621  }
622  }
623 
624  if ( bStrOk )
625  rVal = nNum;
626 
627  return bStrOk;
628 }
629 
630 static bool lcl_CheckOne_XL_A1( const ScDocument& rDoc, const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
631 {
632  // XL A1 style is identical to OOO one for print range formats.
633  return lcl_CheckOne_OOO(rDoc, rStr, bIsRow, rVal);
634 }
635 
636 static bool lcl_CheckOne_XL_R1C1( const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
637 {
638  sal_Int32 nLen = rStr.getLength();
639  if (nLen <= 1)
640  // There must be at least two characters.
641  return false;
642 
643  const sal_Unicode preUpper = bIsRow ? 'R' : 'C';
644  const sal_Unicode preLower = bIsRow ? 'r' : 'c';
645  if (rStr[0] != preUpper && rStr[0] != preLower)
646  return false;
647 
648  OUString aNumStr = rStr.copy(1);
649  if (!CharClass::isAsciiNumeric(aNumStr))
650  return false;
651 
652  sal_Int32 nNum = aNumStr.toInt32();
653 
654  if (nNum <= 0)
655  return false;
656 
657  if ((bIsRow && nNum > MAXROWCOUNT) || (!bIsRow && nNum > MAXCOLCOUNT))
658  return false;
659 
660  rVal = static_cast<SCCOLROW>(nNum-1);
661  return true;
662 }
663 
664 static bool lcl_CheckRepeatOne( const ScDocument& rDoc, const OUString& rStr, formula::FormulaGrammar::AddressConvention eConv, bool bIsRow, SCCOLROW& rVal )
665 {
666  switch (eConv)
667  {
669  return lcl_CheckOne_OOO(rDoc, rStr, bIsRow, rVal);
671  return lcl_CheckOne_XL_A1(rDoc, rStr, bIsRow, rVal);
673  return lcl_CheckOne_XL_R1C1(rStr, bIsRow, rVal);
674  default:
675  {
676  // added to avoid warnings
677  }
678  }
679  return false;
680 }
681 
682 static bool lcl_CheckRepeatString( const OUString& rStr, const ScDocument& rDoc, bool bIsRow, ScRange* pRange )
683 {
684  // Row: [valid row] rsep [valid row]
685  // Col: [valid col] rsep [valid col]
686 
689 
690  if (pRange)
691  {
692  // initialize the range value.
693  pRange->aStart.SetCol(0);
694  pRange->aStart.SetRow(0);
695  pRange->aEnd.SetCol(0);
696  pRange->aEnd.SetRow(0);
697  }
698 
699  OUString aBuf;
700  SCCOLROW nVal = 0;
701  sal_Int32 nLen = rStr.getLength();
702  bool bEndPos = false;
703  for( sal_Int32 i = 0; i < nLen; ++i )
704  {
705  const sal_Unicode c = rStr[i];
706  if (c == rsep)
707  {
708  if (bEndPos)
709  // We aren't supposed to have more than one range separator.
710  return false;
711 
712  // range separator
713  if (aBuf.isEmpty())
714  return false;
715 
716  bool bRes = lcl_CheckRepeatOne(rDoc, aBuf, eConv, bIsRow, nVal);
717  if (!bRes)
718  return false;
719 
720  if (pRange)
721  {
722  if (bIsRow)
723  {
724  pRange->aStart.SetRow(static_cast<SCROW>(nVal));
725  pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
726  }
727  else
728  {
729  pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
730  pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
731  }
732  }
733 
734  aBuf.clear();
735  bEndPos = true;
736  }
737  else
738  aBuf += OUStringChar(c);
739  }
740 
741  if (!aBuf.isEmpty())
742  {
743  bool bRes = lcl_CheckRepeatOne(rDoc, aBuf, eConv, bIsRow, nVal);
744  if (!bRes)
745  return false;
746 
747  if (pRange)
748  {
749  if (bIsRow)
750  {
751  if (!bEndPos)
752  pRange->aStart.SetRow(static_cast<SCROW>(nVal));
753  pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
754  }
755  else
756  {
757  if (!bEndPos)
758  pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
759  pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
760  }
761  }
762  }
763 
764  return true;
765 }
766 
767 static void lcl_GetRepeatRangeString( const ScRange* pRange, const ScDocument& rDoc, bool bIsRow, OUString& rStr )
768 {
769  rStr.clear();
770  if (!pRange)
771  return;
772 
774  const ScAddress& rStart = pRange->aStart;
775  const ScAddress& rEnd = pRange->aEnd;
776 
777  const ScRefFlags nFmt = bIsRow
778  ? (ScRefFlags::ROW_VALID | ScRefFlags::ROW_ABS)
779  : (ScRefFlags::COL_VALID | ScRefFlags::COL_ABS);
780  rStr += rStart.Format(nFmt, &rDoc, eConv);
781  if ((bIsRow && rStart.Row() != rEnd.Row()) || (!bIsRow && rStart.Col() != rEnd.Col()))
782  {
784  rStr += rEnd.Format(nFmt, &rDoc, eConv);
785  }
786 }
787 
788 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3053
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:2111
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:767
SC_DLLPUBLIC ScRefFlags ParseAny(const OUString &, const ScDocument *, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1)
Definition: address.cxx:1770
SC_DLLPUBLIC const ScRange * GetRepeatColRange(SCTAB nTab)
Definition: document.cxx:6290
ScAddress aStart
Definition: address.hxx:500
#define EMPTY_OUSTRING
Definition: global.hxx:214
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:664
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
long Len() const
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
std::unique_ptr< weld::ComboBox > m_xLbRepeatRow
Definition: areasdlg.hxx:57
RET_CANCEL
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:475
#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:6282
void SetRow(SCROW nRowP)
Definition: address.hxx:275
static sal_Unicode GetNativeSymbolChar(OpCode eOp)
void SetCol(SCCOL nColP)
Definition: address.hxx:279
const SCROW MAXROWCOUNT
Definition: address.hxx:63
bool IsPrintEntireSheet(SCTAB nTab) const
Returns true, if the specified sheet is always printed.
Definition: document.cxx:6269
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)
long Min() const
T * get() const
void Justify()
SC_DLLPUBLIC sal_uInt16 GetPrintRangeCount(SCTAB nTab)
Definition: document.cxx:6274
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:630
virtual void Close() override
Definition: areasdlg.cxx:153
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
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
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
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument *=nullptr, 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:1737
SCCOL Col() const
Definition: address.hxx:267
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:2538
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:682
static bool lcl_CheckOne_OOO(const ScDocument &rDoc, const OUString &rStr, bool bIsRow, SCCOLROW &rVal)
Definition: areasdlg.cxx:587
virtual void Deactivate() override
Definition: areasdlg.cxx:212
SC_DLLPUBLIC const ScRange * GetRepeatRowRange(SCTAB nTab)
Definition: document.cxx:6298
std::unique_ptr< formula::RefButton > m_xRbRepeatCol
Definition: areasdlg.hxx:63
OUString aName
RET_OK
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
static bool lcl_CheckOne_XL_R1C1(const OUString &rStr, bool bIsRow, SCCOLROW &rVal)
Definition: areasdlg.cxx:636
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
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument *=nullptr, 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:1543
aStr
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
Definition: anyrefdg.cxx:725