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