Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / pagedlg / areasdlg.cxx
blob0e28c5cdbb708b3c3a90969079cbaba0f8559e29
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <rangelst.hxx>
22 #include <comphelper/string.hxx>
23 #include <sfx2/dispatch.hxx>
24 #include <svl/stritem.hxx>
25 #include <vcl/msgbox.hxx>
26 #include <unotools/charclass.hxx>
27 #include <stdlib.h>
29 #define _AREASDLG_CXX
30 #include "areasdlg.hxx"
31 #undef _AREASDLG_CXX
33 #include "scresid.hxx"
34 #include "rangenam.hxx"
35 #include "reffact.hxx"
36 #include "tabvwsh.hxx"
37 #include "docsh.hxx"
38 #include "globstr.hrc"
39 #include "pagedlg.hrc"
40 #include "compiler.hxx"
41 #include "markdata.hxx"
43 // STATIC DATA ---------------------------------------------------------------
45 // List box positions for print range (PR)
46 const sal_uInt16 SC_AREASDLG_PR_ENTIRE = 1;
47 const sal_uInt16 SC_AREASDLG_PR_USER = 2;
48 const sal_uInt16 SC_AREASDLG_PR_SELECT = 3;
50 // List box positions for repeat ranges (RR)
51 const sal_uInt16 SC_AREASDLG_RR_NONE = 0;
52 const sal_uInt16 SC_AREASDLG_RR_USER = 1;
53 const sal_uInt16 SC_AREASDLG_RR_OFFSET = 2;
55 //============================================================================
58 #define HDL(hdl) LINK( this, ScPrintAreasDlg, hdl )
59 #define ERRORBOX(nId) ErrorBox( this, WinBits(WB_OK|WB_DEF_OK), \
60 ScGlobal::GetRscString( nId ) ).Execute()
62 // globale Funktionen (->am Ende der Datei):
64 static bool lcl_CheckRepeatString( const OUString& rStr, ScDocument* pDoc, bool bIsRow, ScRange* pRange );
65 static void lcl_GetRepeatRangeString( const ScRange* pRange, ScDocument* pDoc, bool bIsRow, OUString& rStr );
67 #if 0
68 // this method is useful when debugging address flags.
69 static void printAddressFlags(sal_uInt16 nFlag)
71 if ((nFlag & SCA_COL_ABSOLUTE ) == SCA_COL_ABSOLUTE ) printf("SCA_COL_ABSOLUTE \n");
72 if ((nFlag & SCA_ROW_ABSOLUTE ) == SCA_ROW_ABSOLUTE ) printf("SCA_ROW_ABSOLUTE \n");
73 if ((nFlag & SCA_TAB_ABSOLUTE ) == SCA_TAB_ABSOLUTE ) printf("SCA_TAB_ABSOLUTE \n");
74 if ((nFlag & SCA_TAB_3D ) == SCA_TAB_3D ) printf("SCA_TAB_3D \n");
75 if ((nFlag & SCA_COL2_ABSOLUTE ) == SCA_COL2_ABSOLUTE ) printf("SCA_COL2_ABSOLUTE\n");
76 if ((nFlag & SCA_ROW2_ABSOLUTE ) == SCA_ROW2_ABSOLUTE ) printf("SCA_ROW2_ABSOLUTE\n");
77 if ((nFlag & SCA_TAB2_ABSOLUTE ) == SCA_TAB2_ABSOLUTE ) printf("SCA_TAB2_ABSOLUTE\n");
78 if ((nFlag & SCA_TAB2_3D ) == SCA_TAB2_3D ) printf("SCA_TAB2_3D \n");
79 if ((nFlag & SCA_VALID_ROW ) == SCA_VALID_ROW ) printf("SCA_VALID_ROW \n");
80 if ((nFlag & SCA_VALID_COL ) == SCA_VALID_COL ) printf("SCA_VALID_COL \n");
81 if ((nFlag & SCA_VALID_TAB ) == SCA_VALID_TAB ) printf("SCA_VALID_TAB \n");
82 if ((nFlag & SCA_FORCE_DOC ) == SCA_FORCE_DOC ) printf("SCA_FORCE_DOC \n");
83 if ((nFlag & SCA_VALID_ROW2 ) == SCA_VALID_ROW2 ) printf("SCA_VALID_ROW2 \n");
84 if ((nFlag & SCA_VALID_COL2 ) == SCA_VALID_COL2 ) printf("SCA_VALID_COL2 \n");
85 if ((nFlag & SCA_VALID_TAB2 ) == SCA_VALID_TAB2 ) printf("SCA_VALID_TAB2 \n");
86 if ((nFlag & SCA_VALID ) == SCA_VALID ) printf("SCA_VALID \n");
87 if ((nFlag & SCA_ABS ) == SCA_ABS ) printf("SCA_ABS \n");
88 if ((nFlag & SCR_ABS ) == SCR_ABS ) printf("SCR_ABS \n");
89 if ((nFlag & SCA_ABS_3D ) == SCA_ABS_3D ) printf("SCA_ABS_3D \n");
90 if ((nFlag & SCR_ABS_3D ) == SCR_ABS_3D ) printf("SCR_ABS_3D \n");
92 #endif
94 //============================================================================
95 // class ScPrintAreasDlg
97 //----------------------------------------------------------------------------
99 ScPrintAreasDlg::ScPrintAreasDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent )
100 : ScAnyRefDlg(pB, pCW, pParent, "PrintAreasDialog", "modules/scalc/ui/printareasdialog.ui")
101 , bDlgLostFocus(false)
102 , pDoc(NULL)
103 , pViewData(NULL)
104 , nCurTab(0)
106 get(pLbPrintArea,"lbprintarea");
107 get(pEdPrintArea,"edprintarea");
108 pEdPrintArea->SetReferences(this, get<VclFrame>("printframe")->get_label_widget());
109 pRefInputEdit = pEdPrintArea;
110 get(pRbPrintArea,"rbprintarea");
111 pRbPrintArea->SetReferences(this, pEdPrintArea);
113 get(pLbRepeatRow,"lbrepeatrow");
114 get(pEdRepeatRow,"edrepeatrow");
115 pEdRepeatRow->SetReferences(this, get<VclFrame>("rowframe")->get_label_widget());
116 get(pRbRepeatRow,"rbrepeatrow");
117 pRbRepeatRow->SetReferences(this, pEdRepeatRow);
119 get(pLbRepeatCol,"lbrepeatcol");
120 get(pEdRepeatCol,"edrepeatcol");
121 pEdRepeatCol->SetReferences(this, get<VclFrame>("colframe")->get_label_widget());
122 get(pRbRepeatCol,"rbrepeatcol");
123 pRbRepeatCol->SetReferences(this, pEdRepeatCol);
125 get(pBtnOk,"ok");
126 get(pBtnCancel,"cancel");
128 ScTabViewShell* pScViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
129 ScDocShell* pScDocSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() );
131 OSL_ENSURE( pScDocSh, "Current DocumentShell not found :-(" );
133 pDoc = pScDocSh->GetDocument();
135 if ( pScViewSh )
137 pViewData = pScViewSh->GetViewData();
138 nCurTab = pViewData->GetTabNo();
141 Impl_Reset();
143 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
144 //SFX_APPWINDOW->Enable();
148 //----------------------------------------------------------------------------
150 ScPrintAreasDlg::~ScPrintAreasDlg()
152 // Extra-Data an ListBox-Entries abraeumen
153 ListBox* aLb[3] = { pLbPrintArea, pLbRepeatRow, pLbRepeatCol };
155 for (sal_uInt16 i = 0; i < SAL_N_ELEMENTS(aLb); ++i)
157 sal_uInt16 nCount = aLb[i]->GetEntryCount();
158 for ( sal_uInt16 j=0; j<nCount; j++ )
159 delete (OUString*)aLb[i]->GetEntryData(j);
164 //----------------------------------------------------------------------------
166 sal_Bool ScPrintAreasDlg::Close()
168 return DoClose( ScPrintAreasDlgWrapper::GetChildWindowId() );
172 //----------------------------------------------------------------------------
174 sal_Bool ScPrintAreasDlg::IsTableLocked() const
176 // Druckbereiche gelten pro Tabelle, darum macht es keinen Sinn,
177 // bei der Eingabe die Tabelle umzuschalten
179 return sal_True;
183 //----------------------------------------------------------------------------
185 void ScPrintAreasDlg::SetReference( const ScRange& rRef, ScDocument* /* pDoc */ )
187 if ( pRefInputEdit )
189 if ( rRef.aStart != rRef.aEnd )
190 RefInputStart( pRefInputEdit );
192 OUString aStr;
193 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
195 if ( pEdPrintArea == pRefInputEdit )
197 aStr = rRef.Format(SCR_ABS, pDoc, eConv);
198 OUString aVal = pEdPrintArea->GetText();
199 Selection aSel = pEdPrintArea->GetSelection();
200 aSel.Justify();
201 aVal = aVal.replaceAt( aSel.Min(), aSel.Len(), aStr );
202 Selection aNewSel( aSel.Min(), aSel.Min()+aStr.getLength() );
203 pEdPrintArea->SetRefString( aVal );
204 pEdPrintArea->SetSelection( aNewSel );
206 else
208 sal_Bool bRow = ( pEdRepeatRow == pRefInputEdit );
209 lcl_GetRepeatRangeString(&rRef, pDoc, bRow, aStr);
210 pRefInputEdit->SetRefString( aStr );
212 Impl_ModifyHdl( pRefInputEdit );
217 //----------------------------------------------------------------------------
219 void ScPrintAreasDlg::AddRefEntry()
221 if ( pRefInputEdit == pEdPrintArea )
223 const sal_Unicode sep = ScCompiler::GetNativeSymbolChar(ocSep);
224 OUString aVal = pEdPrintArea->GetText();
225 aVal += OUString(sep);
226 pEdPrintArea->SetText(aVal);
228 sal_Int32 nLen = aVal.getLength();
229 pEdPrintArea->SetSelection( Selection( nLen, nLen ) );
231 Impl_ModifyHdl( pEdPrintArea );
236 //----------------------------------------------------------------------------
238 void ScPrintAreasDlg::Deactivate()
240 bDlgLostFocus = sal_True;
244 //----------------------------------------------------------------------------
246 void ScPrintAreasDlg::SetActive()
248 if ( bDlgLostFocus )
250 bDlgLostFocus = false;
252 if ( pRefInputEdit )
254 pRefInputEdit->GrabFocus();
255 Impl_ModifyHdl( pRefInputEdit );
258 else
259 GrabFocus();
261 RefInputDone();
265 //----------------------------------------------------------------------------
267 void ScPrintAreasDlg::Impl_Reset()
269 OUString aStrRange;
270 const ScRange* pRepeatColRange = pDoc->GetRepeatColRange( nCurTab );
271 const ScRange* pRepeatRowRange = pDoc->GetRepeatRowRange( nCurTab );
273 pEdPrintArea->SetModifyHdl ( HDL(Impl_ModifyHdl) );
274 pEdRepeatRow->SetModifyHdl ( HDL(Impl_ModifyHdl) );
275 pEdRepeatCol->SetModifyHdl ( HDL(Impl_ModifyHdl) );
276 pEdPrintArea->SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
277 pEdRepeatRow->SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
278 pEdRepeatCol->SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
279 pLbPrintArea->SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
280 pLbRepeatRow->SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
281 pLbRepeatCol->SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
282 pLbPrintArea->SetSelectHdl ( HDL(Impl_SelectHdl) );
283 pLbRepeatRow->SetSelectHdl ( HDL(Impl_SelectHdl) );
284 pLbRepeatCol->SetSelectHdl ( HDL(Impl_SelectHdl) );
285 pBtnOk-> SetClickHdl ( HDL(Impl_BtnHdl) );
286 pBtnCancel-> SetClickHdl ( HDL(Impl_BtnHdl) );
288 Impl_FillLists();
290 //-------------------------
291 // Druckbereich
292 //-------------------------
293 aStrRange = "";
294 OUString aOne;
295 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
296 const sal_Unicode sep = ScCompiler::GetNativeSymbolChar(ocSep);
297 sal_uInt16 nRangeCount = pDoc->GetPrintRangeCount( nCurTab );
298 for (sal_uInt16 i=0; i<nRangeCount; i++)
300 const ScRange* pPrintRange = pDoc->GetPrintRange( nCurTab, i );
301 if (pPrintRange)
303 if ( !aStrRange.isEmpty() )
304 aStrRange += OUString(sep);
305 aOne = pPrintRange->Format(SCR_ABS, pDoc, eConv);
306 aStrRange += aOne;
309 pEdPrintArea->SetText( aStrRange );
311 //-------------------------------
312 // Wiederholungszeile
313 //-------------------------------
314 lcl_GetRepeatRangeString(pRepeatRowRange, pDoc, true, aStrRange);
315 pEdRepeatRow->SetText( aStrRange );
317 //--------------------------------
318 // Wiederholungsspalte
319 //--------------------------------
320 lcl_GetRepeatRangeString(pRepeatColRange, pDoc, false, aStrRange);
321 pEdRepeatCol->SetText( aStrRange );
323 Impl_ModifyHdl( pEdPrintArea );
324 Impl_ModifyHdl( pEdRepeatRow );
325 Impl_ModifyHdl( pEdRepeatCol );
326 if( pDoc->IsPrintEntireSheet( nCurTab ) )
327 pLbPrintArea->SelectEntryPos( SC_AREASDLG_PR_ENTIRE );
329 pEdPrintArea->SaveValue(); // fuer FillItemSet() merken:
330 pEdRepeatRow->SaveValue();
331 pEdRepeatCol->SaveValue();
335 //----------------------------------------------------------------------------
337 bool ScPrintAreasDlg::Impl_GetItem( Edit* pEd, SfxStringItem& rItem )
339 OUString aRangeStr = pEd->GetText();
340 bool bDataChanged = (pEd->GetSavedValue() != aRangeStr);
342 if ( !aRangeStr.isEmpty() && pEdPrintArea != pEd )
344 ScRange aRange;
345 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
346 lcl_CheckRepeatString(aRangeStr, pDoc, pEdRepeatRow == pEd, &aRange);
347 aRangeStr = aRange.Format(SCR_ABS, pDoc, eConv);
350 rItem.SetValue( aRangeStr );
352 return bDataChanged;
356 //----------------------------------------------------------------------------
358 sal_Bool ScPrintAreasDlg::Impl_CheckRefStrings()
360 sal_Bool bOk = false;
361 OUString aStrPrintArea = pEdPrintArea->GetText();
362 OUString aStrRepeatRow = pEdRepeatRow->GetText();
363 OUString aStrRepeatCol = pEdRepeatCol->GetText();
365 sal_Bool bPrintAreaOk = sal_True;
366 if ( !aStrPrintArea.isEmpty() )
368 const sal_uInt16 nValidAddr = SCA_VALID | SCA_VALID_ROW | SCA_VALID_COL;
369 const sal_uInt16 nValidRange = nValidAddr | SCA_VALID_ROW2 | SCA_VALID_COL2;
370 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
371 const sal_Unicode sep = ScCompiler::GetNativeSymbolChar(ocSep);
373 ScAddress aAddr;
374 ScRange aRange;
375 sal_Int32 nSepCount = comphelper::string::getTokenCount(aStrPrintArea, sep);
376 for ( sal_Int32 i = 0; i < nSepCount && bPrintAreaOk; ++i )
378 OUString aOne = aStrPrintArea.getToken(i, sep);
379 sal_uInt16 nResult = aRange.Parse( aOne, pDoc, eConv );
380 if ((nResult & nValidRange) != nValidRange)
382 sal_uInt16 nAddrResult = aAddr.Parse( aOne, pDoc, eConv );
383 if ((nAddrResult & nValidAddr) != nValidAddr)
384 bPrintAreaOk = false;
389 sal_Bool bRepeatRowOk = aStrRepeatRow.isEmpty();
390 if ( !bRepeatRowOk )
391 bRepeatRowOk = lcl_CheckRepeatString(aStrRepeatRow, pDoc, true, NULL);
393 sal_Bool bRepeatColOk = aStrRepeatCol.isEmpty();
394 if ( !bRepeatColOk )
395 bRepeatColOk = lcl_CheckRepeatString(aStrRepeatCol, pDoc, false, NULL);
397 // Fehlermeldungen
399 bOk = (bPrintAreaOk && bRepeatRowOk && bRepeatColOk);
401 if ( !bOk )
403 Edit* pEd = NULL;
405 if ( !bPrintAreaOk ) pEd = pEdPrintArea;
406 else if ( !bRepeatRowOk ) pEd = pEdRepeatRow;
407 else if ( !bRepeatColOk ) pEd = pEdRepeatCol;
409 ERRORBOX( STR_INVALID_TABREF );
411 OSL_ASSERT(pEd);
413 if (pEd)
414 pEd->GrabFocus();
417 return bOk;
421 //----------------------------------------------------------------------------
423 void ScPrintAreasDlg::Impl_FillLists()
425 //------------------------------------------------------
426 // Selektion holen und String in PrintArea-ListBox merken
427 //------------------------------------------------------
428 ScRange aRange;
429 OUString aStrRange;
430 sal_Bool bSimple = sal_True;
432 if ( pViewData )
433 bSimple = (pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE);
435 formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
437 if ( bSimple )
438 aStrRange = aRange.Format(SCR_ABS, pDoc, eConv);
439 else
441 ScRangeListRef aList( new ScRangeList );
442 pViewData->GetMarkData().FillRangeListWithMarks( aList, false );
443 aList->Format(aStrRange, SCR_ABS, pDoc, eConv);
446 pLbPrintArea->SetEntryData( SC_AREASDLG_PR_SELECT, new OUString( aStrRange ) );
448 //------------------------------------------------------
449 // Ranges holen und in ListBoxen merken
450 //------------------------------------------------------
451 ScRangeName* pRangeNames = pDoc->GetRangeName();
453 if (!pRangeNames || pRangeNames->empty())
454 // No range names to process.
455 return;
457 ScRangeName::const_iterator itr = pRangeNames->begin(), itrEnd = pRangeNames->end();
458 for (; itr != itrEnd; ++itr)
460 if (!itr->second->HasType(RT_ABSAREA) && !itr->second->HasType(RT_REFAREA) && !itr->second->HasType(RT_ABSPOS))
461 continue;
463 OUString aName = itr->second->GetName();
464 OUString aSymbol;
465 itr->second->GetSymbol(aSymbol);
466 if (aRange.ParseAny(aSymbol, pDoc, eConv) & SCA_VALID)
468 if (itr->second->HasType(RT_PRINTAREA))
470 aSymbol = aRange.Format(SCR_ABS, pDoc, eConv);
471 pLbPrintArea->SetEntryData(
472 pLbPrintArea->InsertEntry(aName),
473 new OUString(aSymbol) );
476 if (itr->second->HasType(RT_ROWHEADER))
478 lcl_GetRepeatRangeString(&aRange, pDoc, true, aSymbol);
479 pLbRepeatRow->SetEntryData(
480 pLbRepeatRow->InsertEntry(aName),
481 new OUString(aSymbol) );
484 if (itr->second->HasType(RT_COLHEADER))
486 lcl_GetRepeatRangeString(&aRange, pDoc, false, aSymbol);
487 pLbRepeatCol->SetEntryData(
488 pLbRepeatCol->InsertEntry(aName),
489 new OUString(aSymbol));
496 //----------------------------------------------------------------------------
497 // Handler:
498 //----------------------------------------------------------------------------
500 IMPL_LINK( ScPrintAreasDlg, Impl_BtnHdl, PushButton*, pBtn )
502 if ( pBtnOk == pBtn )
504 if ( Impl_CheckRefStrings() )
506 bool bDataChanged = false;
507 OUString aStr;
508 SfxStringItem aPrintArea( SID_CHANGE_PRINTAREA, aStr );
509 SfxStringItem aRepeatRow( FN_PARAM_2, aStr );
510 SfxStringItem aRepeatCol( FN_PARAM_3, aStr );
512 //-------------------------
513 // Druckbereich veraendert?
514 //-------------------------
516 // first try the list box, if "Entite sheet" is selected
517 bool bEntireSheet = (pLbPrintArea->GetSelectEntryPos() == SC_AREASDLG_PR_ENTIRE);
518 SfxBoolItem aEntireSheet( FN_PARAM_4, bEntireSheet );
520 bDataChanged = bEntireSheet != pDoc->IsPrintEntireSheet( nCurTab );
521 if( !bEntireSheet )
523 // if new list box selection is not "Entire sheet", get the edit field contents
524 bDataChanged |= Impl_GetItem( pEdPrintArea, aPrintArea );
527 //-------------------------------
528 // Wiederholungszeile veraendert?
529 //-------------------------------
530 bDataChanged |= Impl_GetItem( pEdRepeatRow, aRepeatRow );
532 //--------------------------------
533 // Wiederholungsspalte veraendert?
534 //--------------------------------
535 bDataChanged |= Impl_GetItem( pEdRepeatCol, aRepeatCol );
537 if ( bDataChanged )
539 SetDispatcherLock( false );
540 SwitchToDocument();
541 GetBindings().GetDispatcher()->Execute( SID_CHANGE_PRINTAREA,
542 SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
543 &aPrintArea, &aRepeatRow, &aRepeatCol, &aEntireSheet, 0L );
546 Close();
549 else if ( pBtnCancel == pBtn )
550 Close();
552 return 0;
556 //----------------------------------------------------------------------------
558 IMPL_LINK( ScPrintAreasDlg, Impl_GetFocusHdl, Control*, pCtr )
560 if ( pCtr ==(Control *) pEdPrintArea ||
561 pCtr ==(Control *) pEdRepeatRow ||
562 pCtr ==(Control *) pEdRepeatCol)
564 pRefInputEdit = (formula::RefEdit*) pCtr;
566 else if ( pCtr ==(Control *) pLbPrintArea)
568 pRefInputEdit = pEdPrintArea;
570 else if ( pCtr ==(Control *) pLbRepeatRow)
572 pRefInputEdit = pEdRepeatRow;
574 else if ( pCtr ==(Control *) pLbRepeatCol)
576 pRefInputEdit = pEdRepeatCol;
579 return 0;
583 //----------------------------------------------------------------------------
585 IMPL_LINK( ScPrintAreasDlg, Impl_SelectHdl, ListBox*, pLb )
587 sal_uInt16 nSelPos = pLb->GetSelectEntryPos();
588 Edit* pEd = NULL;
590 // list box positions of specific entries, default to "repeat row/column" list boxes
591 sal_uInt16 nAllSheetPos = SC_AREASDLG_RR_NONE;
592 sal_uInt16 nUserDefPos = SC_AREASDLG_RR_USER;
593 sal_uInt16 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
595 // find edit field for list box, and list box positions
596 if( pLb == pLbPrintArea )
598 pEd = pEdPrintArea;
599 nAllSheetPos = SC_AREASDLG_PR_ENTIRE;
600 nUserDefPos = SC_AREASDLG_PR_USER;
601 nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
603 else if( pLb == pLbRepeatCol )
604 pEd = pEdRepeatCol;
605 else if( pLb == pLbRepeatRow )
606 pEd = pEdRepeatRow;
607 else
608 return 0;
610 // fill edit field according to list box selection
611 if( (nSelPos == 0) || (nSelPos == nAllSheetPos) )
612 pEd->SetText( EMPTY_OUSTRING );
613 else if( nSelPos == nUserDefPos && !pLb->IsTravelSelect() && pEd->GetText().isEmpty())
614 pLb->SelectEntryPos( 0 );
615 else if( nSelPos >= nFirstCustomPos )
616 pEd->SetText( *static_cast< OUString* >( pLb->GetEntryData( nSelPos ) ) );
618 return 0;
622 //----------------------------------------------------------------------------
624 IMPL_LINK( ScPrintAreasDlg, Impl_ModifyHdl, formula::RefEdit*, pEd )
626 ListBox* pLb = NULL;
628 // list box positions of specific entries, default to "repeat row/column" list boxes
629 sal_uInt16 nUserDefPos = SC_AREASDLG_RR_USER;
630 sal_uInt16 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
632 if( pEd == pEdPrintArea )
634 pLb = pLbPrintArea;
635 nUserDefPos = SC_AREASDLG_PR_USER;
636 nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
638 else if( pEd == pEdRepeatCol )
639 pLb = pLbRepeatCol;
640 else if( pEd == pEdRepeatRow )
641 pLb = pLbRepeatRow;
642 else
643 return 0;
645 // set list box selection according to edit field
646 sal_uInt16 nEntryCount = pLb->GetEntryCount();
647 OUString aStrEd( pEd->GetText() );
648 OUString aEdUpper = aStrEd.toAsciiUpperCase();
650 if ( (nEntryCount > nFirstCustomPos) && !aStrEd.isEmpty() )
652 sal_Bool bFound = false;
653 OUString* pSymbol = NULL;
654 sal_uInt16 i;
656 for ( i=nFirstCustomPos; i<nEntryCount && !bFound; i++ )
658 pSymbol = (OUString*)pLb->GetEntryData( i );
659 bFound = ( (*pSymbol) ==aStrEd || (*pSymbol) == aEdUpper );
662 pLb->SelectEntryPos( bFound ? i-1 : nUserDefPos );
664 else
665 pLb->SelectEntryPos( !aStrEd.isEmpty() ? nUserDefPos : 0 );
667 return 0;
671 //============================================================================
672 // globale Funktionen:
674 // ----------------------------------------------------------------------------
676 // TODO: It might make sense to move these functions to address.?xx. -kohei
678 static bool lcl_CheckOne_OOO( const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
680 // Zulaessige Syntax fuer rStr:
681 // Row: [$]1-MAXTAB
682 // Col: [$]A-IV
684 OUString aStr = rStr;
685 sal_Int32 nLen = aStr.getLength();
686 SCCOLROW nNum = 0;
687 sal_Bool bStrOk = ( nLen > 0 ) && ( bIsRow ? ( nLen < 6 ) : ( nLen < 4 ) );
689 if ( bStrOk )
691 if ( '$' == aStr[0] )
692 aStr = aStr.copy( 1 );
694 if ( bIsRow )
696 bStrOk = CharClass::isAsciiNumeric(aStr);
698 if ( bStrOk )
700 sal_Int32 n = aStr.toInt32();
702 if ( ( bStrOk = (n > 0) && ( n <= MAXROWCOUNT ) ) != false )
703 nNum = static_cast<SCCOLROW>(n - 1);
706 else
708 SCCOL nCol = 0;
709 bStrOk = ::AlphaToCol( nCol, aStr);
710 nNum = nCol;
714 if ( bStrOk )
715 rVal = nNum;
717 return bStrOk;
720 static bool lcl_CheckOne_XL_A1( const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
722 // XL A1 style is identical to OOO one for print range formats.
723 return lcl_CheckOne_OOO(rStr, bIsRow, rVal);
726 static bool lcl_CheckOne_XL_R1C1( const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
728 sal_Int32 nLen = rStr.getLength();
729 if (nLen <= 1)
730 // There must be at least two characters.
731 return false;
733 const sal_Unicode preUpper = bIsRow ? 'R' : 'C';
734 const sal_Unicode preLower = bIsRow ? 'r' : 'c';
735 if (rStr[0] != preUpper && rStr[0] != preLower)
736 return false;
738 OUString aNumStr = rStr.copy(1);
739 if (!CharClass::isAsciiNumeric(aNumStr))
740 return false;
742 sal_Int32 nNum = aNumStr.toInt32();
744 if (nNum <= 0)
745 return false;
747 if ((bIsRow && nNum > MAXROWCOUNT) || (!bIsRow && nNum > MAXCOLCOUNT))
748 return false;
750 rVal = static_cast<SCCOLROW>(nNum-1);
751 return true;
754 static bool lcl_CheckRepeatOne( const OUString& rStr, formula::FormulaGrammar::AddressConvention eConv, bool bIsRow, SCCOLROW& rVal )
756 switch (eConv)
758 case formula::FormulaGrammar::CONV_OOO:
759 return lcl_CheckOne_OOO(rStr, bIsRow, rVal);
760 case formula::FormulaGrammar::CONV_XL_A1:
761 return lcl_CheckOne_XL_A1(rStr, bIsRow, rVal);
762 case formula::FormulaGrammar::CONV_XL_R1C1:
763 return lcl_CheckOne_XL_R1C1(rStr, bIsRow, rVal);
764 default:
766 // added to avoid warnings
769 return false;
772 static bool lcl_CheckRepeatString( const OUString& rStr, ScDocument* pDoc, bool bIsRow, ScRange* pRange )
774 // Row: [valid row] rsep [valid row]
775 // Col: [valid col] rsep [valid col]
777 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
778 const sal_Unicode rsep = ScCompiler::GetNativeSymbolChar(ocRange);
780 if (pRange)
782 // initialize the range value.
783 pRange->aStart.SetCol(0);
784 pRange->aStart.SetRow(0);
785 pRange->aEnd.SetCol(0);
786 pRange->aEnd.SetRow(0);
789 OUString aBuf;
790 SCCOLROW nVal = 0;
791 sal_Int32 nLen = rStr.getLength();
792 bool bEndPos = false;
793 for( sal_Int32 i = 0; i < nLen; ++i )
795 const sal_Unicode c = rStr[i];
796 if (c == rsep)
798 if (bEndPos)
799 // We aren't supposed to have more than one range separator.
800 return false;
802 // range separator
803 if (aBuf.isEmpty())
804 return false;
806 bool bRes = lcl_CheckRepeatOne(aBuf, eConv, bIsRow, nVal);
807 if (!bRes)
808 return false;
810 if (pRange)
812 if (bIsRow)
814 pRange->aStart.SetRow(static_cast<SCROW>(nVal));
815 pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
817 else
819 pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
820 pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
824 aBuf = "";
825 bEndPos = true;
827 else
828 aBuf += OUString(c);
831 if (!aBuf.isEmpty())
833 bool bRes = lcl_CheckRepeatOne(aBuf, eConv, bIsRow, nVal);
834 if (!bRes)
835 return false;
837 if (pRange)
839 if (bIsRow)
841 if (!bEndPos)
842 pRange->aStart.SetRow(static_cast<SCROW>(nVal));
843 pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
845 else
847 if (!bEndPos)
848 pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
849 pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
854 return true;
857 // ----------------------------------------------------------------------------
859 static void lcl_GetRepeatRangeString( const ScRange* pRange, ScDocument* pDoc, bool bIsRow, OUString& rStr )
861 rStr = "";
862 if (!pRange)
863 return;
865 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
866 const ScAddress& rStart = pRange->aStart;
867 const ScAddress& rEnd = pRange->aEnd;
869 const sal_uInt16 nFmt = bIsRow ? (SCA_VALID_ROW | SCA_ROW_ABSOLUTE) : (SCA_VALID_COL | SCA_COL_ABSOLUTE);
870 rStr += rStart.Format(nFmt, pDoc, eConv);
871 if ((bIsRow && rStart.Row() != rEnd.Row()) || (!bIsRow && rStart.Col() != rEnd.Col()))
873 rStr += ScCompiler::GetNativeSymbol(ocRange);
874 rStr += rEnd.Format(nFmt, pDoc, eConv);
878 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */