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 <o3tl/string_view.hxx>
23#include <sfx2/dispatch.hxx>
24#include <svl/stritem.hxx>
25#include <vcl/svapp.hxx>
26#include <vcl/weld.hxx>
28
29#include <areasdlg.hxx>
30#include <rangenam.hxx>
31#include <reffact.hxx>
32#include <tabvwsh.hxx>
33#include <docsh.hxx>
34#include <globstr.hrc>
35#include <scresid.hxx>
36#include <compiler.hxx>
37#include <markdata.hxx>
38
39// List box positions for print range (PR)
40enum {
44};
45
46// List box positions for repeat ranges (RR)
47enum {
51};
52
53namespace
54{
55 void ERRORBOX(weld::Window* pParent, TranslateId 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
66static bool lcl_CheckRepeatString( std::u16string_view aStr, const ScDocument& rDoc, bool bIsRow, ScRange* pRange );
67static void lcl_GetRepeatRangeString( std::optional<ScRange> oRange, const ScDocument& rDoc, bool bIsRow, OUString& rStr );
68
69#if 0
70// this method is useful when debugging address flags.
71static 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
166void 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.Normalize();
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);
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 std::optional<ScRange> oRepeatColRange = pDoc->GetRepeatColRange( nCurTab );
239 std::optional<ScRange> oRepeatRowRange = pDoc->GetRepeatRowRange( nCurTab );
240
241 m_xEdPrintArea->SetModifyHdl (LINK( this, ScPrintAreasDlg, Impl_ModifyHdl));
242 m_xEdRepeatRow->SetModifyHdl (LINK( this, ScPrintAreasDlg, Impl_ModifyHdl));
243 m_xEdRepeatCol->SetModifyHdl (LINK( this, ScPrintAreasDlg, Impl_ModifyHdl));
244 m_xEdPrintArea->SetGetFocusHdl(LINK( this, ScPrintAreasDlg, Impl_GetEditFocusHdl));
245 m_xEdRepeatRow->SetGetFocusHdl(LINK( this, ScPrintAreasDlg, Impl_GetEditFocusHdl));
246 m_xEdRepeatCol->SetGetFocusHdl(LINK( this, ScPrintAreasDlg, Impl_GetEditFocusHdl));
247 m_xLbPrintArea->connect_focus_in(LINK( this, ScPrintAreasDlg, Impl_GetFocusHdl));
248 m_xLbRepeatRow->connect_focus_in(LINK( this, ScPrintAreasDlg, Impl_GetFocusHdl));
249 m_xLbRepeatCol->connect_focus_in(LINK( this, ScPrintAreasDlg, Impl_GetFocusHdl));
250 m_xLbPrintArea->connect_changed(LINK( this, ScPrintAreasDlg, Impl_SelectHdl));
251 m_xLbRepeatRow->connect_changed(LINK( this, ScPrintAreasDlg, Impl_SelectHdl));
252 m_xLbRepeatCol->connect_changed(LINK( this, ScPrintAreasDlg, Impl_SelectHdl));
253 m_xBtnOk->connect_clicked(LINK( this, ScPrintAreasDlg, Impl_BtnHdl));
254 m_xBtnCancel->connect_clicked(LINK( this, ScPrintAreasDlg, Impl_BtnHdl));
255
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(oRepeatRowRange, *pDoc, true, aStrRange);
279 m_xEdRepeatRow->SetText( aStrRange );
280
281 // repeat column
282
283 lcl_GetRepeatRangeString(oRepeatColRange, *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 {
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 = rEntry.second->GetSymbol();
421 if (aRange.ParseAny(aSymbol, *pDoc, eConv) & ScRefFlags::VALID)
422 {
423 if (rEntry.second->HasType(ScRangeData::Type::PrintArea))
424 {
425 aSymbol = aRange.Format(*pDoc, ScRefFlags::RANGE_ABS, eConv);
426 m_xLbPrintArea->append(aSymbol, aName);
427 }
428
429 if (rEntry.second->HasType(ScRangeData::Type::RowHeader))
430 {
431 lcl_GetRepeatRangeString(aRange, *pDoc, true, aSymbol);
432 m_xLbRepeatRow->append(aSymbol, aName);
433 }
434
435 if (rEntry.second->HasType(ScRangeData::Type::ColHeader))
436 {
437 lcl_GetRepeatRangeString(aRange, *pDoc, false, aSymbol);
438 m_xLbRepeatCol->append(aSymbol, aName);
439 }
440 }
441 }
442}
443
444// Handler:
445
446IMPL_LINK(ScPrintAreasDlg, Impl_BtnHdl, weld::Button&, rBtn, void)
447{
448 if (m_xBtnOk.get() == &rBtn)
449 {
450 if ( Impl_CheckRefStrings() )
451 {
452 SfxStringItem aPrintArea( SID_CHANGE_PRINTAREA, "" );
453 SfxStringItem aRepeatRow( FN_PARAM_2, "" );
454 SfxStringItem aRepeatCol( FN_PARAM_3, "" );
455
456 // Printing area changed?
457
458 // first try the list box, if "Entire sheet" is selected
459 bool bEntireSheet = (m_xLbPrintArea->get_active() == SC_AREASDLG_PR_ENTIRE);
460 SfxBoolItem aEntireSheet( FN_PARAM_4, bEntireSheet );
461
462 bool bDataChanged = bEntireSheet != pDoc->IsPrintEntireSheet( nCurTab );
463 if( !bEntireSheet )
464 {
465 // if new list box selection is not "Entire sheet", get the edit field contents
466 bDataChanged |= Impl_GetItem( m_xEdPrintArea.get(), aPrintArea );
467 }
468
469 // Repeat row changed?
470
471 bDataChanged |= Impl_GetItem( m_xEdRepeatRow.get(), aRepeatRow );
472
473 // Repeat column changed?
474
475 bDataChanged |= Impl_GetItem( m_xEdRepeatCol.get(), aRepeatCol );
476
477 if ( bDataChanged )
478 {
479 SetDispatcherLock( false );
480 SwitchToDocument();
481 GetBindings().GetDispatcher()->ExecuteList(SID_CHANGE_PRINTAREA,
482 SfxCallMode::SLOT | SfxCallMode::RECORD,
483 { &aPrintArea, &aRepeatRow, &aRepeatCol, &aEntireSheet });
484 }
485
486 response(RET_OK);
487 }
488 }
489 else if (m_xBtnCancel.get() == &rBtn)
490 response(RET_CANCEL);
491}
492
493IMPL_LINK(ScPrintAreasDlg, Impl_GetEditFocusHdl, formula::RefEdit&, rCtrl, void)
494{
495 m_pRefInputEdit = &rCtrl;
496}
497
498IMPL_LINK(ScPrintAreasDlg, Impl_GetFocusHdl, weld::Widget&, rCtrl, void)
499{
500 if (&rCtrl == m_xLbPrintArea.get())
501 m_pRefInputEdit = m_xEdPrintArea.get();
502 else if (&rCtrl == m_xLbRepeatRow.get())
503 m_pRefInputEdit = m_xEdRepeatRow.get();
504 else if (&rCtrl == m_xLbRepeatCol.get())
505 m_pRefInputEdit = m_xEdRepeatCol.get();
506}
507
508IMPL_LINK( ScPrintAreasDlg, Impl_SelectHdl, weld::ComboBox&, rLb, void )
509{
510 const sal_Int32 nSelPos = rLb.get_active();
511 formula::RefEdit* pEd = nullptr;
512
513 // list box positions of specific entries, default to "repeat row/column" list boxes
514 sal_Int32 nAllSheetPos = SC_AREASDLG_RR_NONE;
515 sal_Int32 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
516
517 // find edit field for list box, and list box positions
518 if (&rLb == m_xLbPrintArea.get())
519 {
520 pEd = m_xEdPrintArea.get();
521 nAllSheetPos = SC_AREASDLG_PR_ENTIRE;
522 nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
523 }
524 else if (&rLb == m_xLbRepeatCol.get())
525 pEd = m_xEdRepeatCol.get();
526 else if (&rLb == m_xLbRepeatRow.get())
527 pEd = m_xEdRepeatRow.get();
528 else
529 return;
530
531 // fill edit field according to list box selection
532 if( (nSelPos == 0) || (nSelPos == nAllSheetPos) )
533 pEd->SetText( OUString() );
534 else if( nSelPos >= nFirstCustomPos )
535 pEd->SetText(rLb.get_id(nSelPos));
536}
537
538IMPL_LINK( ScPrintAreasDlg, Impl_ModifyHdl, formula::RefEdit&, rEd, void )
539{
540 weld::ComboBox* pLb = nullptr;
541
542 // list box positions of specific entries, default to "repeat row/column" list boxes
543 sal_Int32 nUserDefPos = SC_AREASDLG_RR_USER;
544 sal_Int32 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
545
546 if( &rEd == m_xEdPrintArea.get() )
547 {
548 pLb = m_xLbPrintArea.get();
549 nUserDefPos = SC_AREASDLG_PR_USER;
550 nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
551 }
552 else if( &rEd == m_xEdRepeatCol.get() )
553 pLb = m_xLbRepeatCol.get();
554 else if( &rEd == m_xEdRepeatRow.get() )
555 pLb = m_xLbRepeatRow.get();
556 else
557 return;
558
559 // set list box selection according to edit field
560 const sal_Int32 nEntryCount = pLb->get_count();
561 OUString aStrEd( rEd.GetText() );
562 OUString aEdUpper = aStrEd.toAsciiUpperCase();
563
564 if ( (nEntryCount > nFirstCustomPos) && !aStrEd.isEmpty() )
565 {
566 bool bFound = false;
567 sal_Int32 i;
568
569 for ( i=nFirstCustomPos; i<nEntryCount && !bFound; i++ )
570 {
571 const OUString& rSymbol = pLb->get_id(i);
572 bFound = (rSymbol == aStrEd || rSymbol == aEdUpper);
573 }
574
575 pLb->set_active( bFound ? i-1 : nUserDefPos );
576 }
577 else
578 pLb->set_active( !aStrEd.isEmpty() ? nUserDefPos : 0 );
579}
580
581// global functions:
582
583// TODO: It might make sense to move these functions to address.?xx. -kohei
584
585static bool lcl_CheckOne_OOO( const ScDocument& rDoc, const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
586{
587 // Allowed syntax for rStr:
588 // Row: [$]1-MAXTAB
589 // Col: [$]A-IV
590
591 OUString aStr = rStr;
592 sal_Int32 nLen = aStr.getLength();
593 SCCOLROW nNum = 0;
594 bool bStrOk = ( nLen > 0 ) && ( bIsRow ? ( nLen < 6 ) : ( nLen < 4 ) );
595
596 if ( bStrOk )
597 {
598 if ( '$' == aStr[0] )
599 aStr = aStr.copy( 1 );
600
601 if ( bIsRow )
602 {
604
605 if ( bStrOk )
606 {
607 sal_Int32 n = aStr.toInt32();
608
609 bStrOk = (n > 0) && ( n <= rDoc.GetSheetLimits().GetMaxRowCount() );
610 if ( bStrOk )
611 nNum = static_cast<SCCOLROW>(n - 1);
612 }
613 }
614 else
615 {
616 SCCOL nCol = 0;
617 bStrOk = ::AlphaToCol(rDoc, nCol, aStr);
618 nNum = nCol;
619 }
620 }
621
622 if ( bStrOk )
623 rVal = nNum;
624
625 return bStrOk;
626}
627
628static bool lcl_CheckOne_XL_A1( const ScDocument& rDoc, const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
629{
630 // XL A1 style is identical to OOO one for print range formats.
631 return lcl_CheckOne_OOO(rDoc, rStr, bIsRow, rVal);
632}
633
634static bool lcl_CheckOne_XL_R1C1( const ScDocument& rDoc, std::u16string_view aStr, bool bIsRow, SCCOLROW& rVal )
635{
636 sal_Int32 nLen = aStr.size();
637 if (nLen <= 1)
638 // There must be at least two characters.
639 return false;
640
641 const sal_Unicode preUpper = bIsRow ? 'R' : 'C';
642 const sal_Unicode preLower = bIsRow ? 'r' : 'c';
643 if (aStr[0] != preUpper && aStr[0] != preLower)
644 return false;
645
646 std::u16string_view aNumStr = aStr.substr(1);
647 if (!CharClass::isAsciiNumeric(aNumStr))
648 return false;
649
650 sal_Int32 nNum = o3tl::toInt32(aNumStr);
651
652 if (nNum <= 0)
653 return false;
654
655 if ((bIsRow && nNum > rDoc.GetSheetLimits().GetMaxRowCount()) ||
656 (!bIsRow && nNum > rDoc.GetSheetLimits().GetMaxColCount()))
657 return false;
658
659 rVal = static_cast<SCCOLROW>(nNum-1);
660 return true;
661}
662
663static 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
681static bool lcl_CheckRepeatString( std::u16string_view aStr, 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 = aStr.size();
701 bool bEndPos = false;
702 for( sal_Int32 i = 0; i < nLen; ++i )
703 {
704 const sal_Unicode c = aStr[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
766static void lcl_GetRepeatRangeString( std::optional<ScRange> oRange, const ScDocument& rDoc, bool bIsRow, OUString& rStr )
767{
768 rStr.clear();
769 if (!oRange)
770 return;
771
773 const ScAddress& rStart = oRange->aStart;
774 const ScAddress& rEnd = oRange->aEnd;
775
776 const ScRefFlags nFmt = bIsRow
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: */
bool AlphaToCol(const ScDocument &rDoc, SCCOL &rCol, std::u16string_view rStr)
get column number of A..IV... string
Definition: address.cxx:2509
ScRefFlags
Definition: address.hxx:158
@ SC_AREASDLG_PR_ENTIRE
Definition: areasdlg.cxx:41
@ SC_AREASDLG_PR_SELECT
Definition: areasdlg.cxx:43
@ SC_AREASDLG_PR_USER
Definition: areasdlg.cxx:42
static void lcl_GetRepeatRangeString(std::optional< ScRange > oRange, const ScDocument &rDoc, bool bIsRow, OUString &rStr)
Definition: areasdlg.cxx:766
@ SC_AREASDLG_RR_USER
Definition: areasdlg.cxx:49
@ SC_AREASDLG_RR_OFFSET
Definition: areasdlg.cxx:50
@ SC_AREASDLG_RR_NONE
Definition: areasdlg.cxx:48
static bool lcl_CheckOne_XL_R1C1(const ScDocument &rDoc, std::u16string_view aStr, bool bIsRow, SCCOLROW &rVal)
Definition: areasdlg.cxx:634
static bool lcl_CheckRepeatString(std::u16string_view aStr, const ScDocument &rDoc, bool bIsRow, ScRange *pRange)
Definition: areasdlg.cxx:681
static bool lcl_CheckOne_XL_A1(const ScDocument &rDoc, const OUString &rStr, bool bIsRow, SCCOLROW &rVal)
Definition: areasdlg.cxx:628
static bool lcl_CheckOne_OOO(const ScDocument &rDoc, const OUString &rStr, bool bIsRow, SCCOLROW &rVal)
Definition: areasdlg.cxx:585
static bool lcl_CheckRepeatOne(const ScDocument &rDoc, const OUString &rStr, formula::FormulaGrammar::AddressConvention eConv, bool bIsRow, SCCOLROW &rVal)
Definition: areasdlg.cxx:663
IMPL_LINK(ScPrintAreasDlg, Impl_BtnHdl, weld::Button &, rBtn, void)
Definition: areasdlg.cxx:446
Reference< XExecutableDialog > m_xDialog
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
static bool isAsciiNumeric(std::u16string_view rStr)
void SetValue(const OUString &rTheValue)
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2074
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:1537
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
SCCOL Col() const
Definition: address.hxx:279
const ScDocument & GetDocument() const
Definition: docsh.hxx:219
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:898
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:492
SC_DLLPUBLIC const ScRange * GetPrintRange(SCTAB nTab, sal_uInt16 nPos)
Definition: document.cxx:6268
SC_DLLPUBLIC std::optional< ScRange > GetRepeatColRange(SCTAB nTab)
Definition: document.cxx:6276
SC_DLLPUBLIC std::optional< ScRange > GetRepeatRowRange(SCTAB nTab)
Definition: document.cxx:6284
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:171
SC_DLLPUBLIC sal_uInt16 GetPrintRangeCount(SCTAB nTab)
Definition: document.cxx:6261
bool IsPrintEntireSheet(SCTAB nTab) const
Returns true, if the specified sheet is always printed.
Definition: document.cxx:6255
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
Definition: markdata.cxx:372
std::unique_ptr< formula::RefButton > m_xRbPrintArea
Definition: areasdlg.hxx:54
std::unique_ptr< weld::Button > m_xBtnOk
Definition: areasdlg.hxx:64
bool Impl_CheckRefStrings()
Definition: areasdlg.cxx:315
virtual void AddRefEntry() override
Definition: areasdlg.cxx:197
void Impl_Reset()
Definition: areasdlg.cxx:235
std::unique_ptr< weld::ComboBox > m_xLbRepeatRow
Definition: areasdlg.hxx:56
virtual ~ScPrintAreasDlg() override
Definition: areasdlg.cxx:149
virtual void Deactivate() override
Definition: areasdlg.cxx:212
std::unique_ptr< weld::ComboBox > m_xLbPrintArea
Definition: areasdlg.hxx:52
virtual void SetReference(const ScRange &rRef, ScDocument &rDoc) override
Definition: areasdlg.cxx:166
std::unique_ptr< formula::RefEdit > m_xEdRepeatRow
Definition: areasdlg.hxx:57
std::unique_ptr< weld::Label > m_xPrintFrameFT
Definition: areasdlg.hxx:71
ScPrintAreasDlg(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent)
Definition: areasdlg.cxx:97
void Impl_FillLists()
Definition: areasdlg.cxx:379
std::unique_ptr< formula::RefEdit > m_xEdPrintArea
Definition: areasdlg.hxx:53
formula::RefEdit * m_pRefInputEdit
Definition: areasdlg.hxx:50
std::unique_ptr< weld::Button > m_xBtnCancel
Definition: areasdlg.hxx:65
std::unique_ptr< weld::Label > m_xRowFrameFT
Definition: areasdlg.hxx:72
virtual bool IsTableLocked() const override
Definition: areasdlg.cxx:158
virtual void SetActive() override
Definition: areasdlg.cxx:217
std::unique_ptr< formula::RefEdit > m_xEdRepeatCol
Definition: areasdlg.hxx:61
std::unique_ptr< formula::RefButton > m_xRbRepeatCol
Definition: areasdlg.hxx:62
ScViewData * pViewData
Definition: areasdlg.hxx:47
bool bDlgLostFocus
Definition: areasdlg.hxx:45
std::unique_ptr< formula::RefButton > m_xRbRepeatRow
Definition: areasdlg.hxx:58
std::unique_ptr< weld::ComboBox > m_xLbRepeatCol
Definition: areasdlg.hxx:60
std::unique_ptr< weld::Label > m_xColFrameFT
Definition: areasdlg.hxx:73
ScDocument * pDoc
Definition: areasdlg.hxx:46
virtual void Close() override
Definition: areasdlg.cxx:153
bool Impl_GetItem(const formula::RefEdit *pEd, SfxStringItem &rItem)
Definition: areasdlg.cxx:297
bool empty() const
Definition: rangenam.hxx:249
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:2170
ScAddress aEnd
Definition: address.hxx:498
ScRefFlags ParseAny(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1)
Definition: address.cxx:1733
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:1700
ScAddress aStart
Definition: address.hxx:497
virtual void RefInputStart(formula::RefEdit *pEdit, formula::RefButton *pButton=nullptr) override
Definition: anyrefdg.cxx:745
virtual void RefInputDone(bool bForced=false) override
Definition: anyrefdg.cxx:775
bool DoClose(sal_uInt16 nId)
Definition: anyrefdg.cxx:714
ScViewData & GetViewData()
Definition: tabview.hxx:344
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3146
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1182
tools::Long Min() const
tools::Long Len() const
void Normalize()
SfxDispatcher * GetDispatcher() const
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
static SAL_WARN_UNUSED_RESULT SfxObjectShell * Current()
static SAL_WARN_UNUSED_RESULT SfxViewShell * Current()
static const OUString & GetNativeSymbol(OpCode eOp)
static sal_Unicode GetNativeSymbolChar(OpCode eOp)
bool IsValueChangedFromSaved() const
void SetText(const OUString &rStr)
void SetRefString(const OUString &rStr)
OUString GetText() const
T * get() const
virtual OUString get_id(int pos) const=0
virtual void set_active(int pos)=0
virtual int get_count() const=0
virtual SfxBindings & GetBindings() override
OUString aName
sal_Int64 n
aStr
aBuf
int i
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
ocRange
ocSep
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
SCROW GetMaxRowCount() const
Definition: sheetlimits.hxx:66
SCCOL GetMaxColCount() const
Definition: sheetlimits.hxx:68
sal_uInt16 sal_Unicode
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:23
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
RET_OK
RET_CANCEL
@ SC_MARK_SIMPLE
Definition: viewdata.hxx:65