merge the formfield patch from ooo-build
[ooovba.git] / sc / source / ui / pagedlg / areasdlg.cxx
blob414d478d898ff6f88f30875e2e6c0e99f7d87918
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: areasdlg.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 //----------------------------------------------------------------------------
37 #include <rangelst.hxx>
39 #include <sfx2/dispatch.hxx>
40 #include <svtools/stritem.hxx>
41 #include <vcl/msgbox.hxx>
42 #include <unotools/charclass.hxx>
43 #include <stdlib.h>
45 #define _AREASDLG_CXX
46 #include "areasdlg.hxx"
47 #undef _AREASDLG_CXX
49 #include "scresid.hxx"
50 #include "rangenam.hxx"
51 #include "reffact.hxx"
52 #include "tabvwsh.hxx"
53 #include "docsh.hxx"
54 #include "globstr.hrc"
55 #include "pagedlg.hrc"
56 #include "compiler.hxx"
58 // STATIC DATA ---------------------------------------------------------------
60 // List box positions for print range (PR)
61 const USHORT SC_AREASDLG_PR_NONE = 0;
62 const USHORT SC_AREASDLG_PR_ENTIRE = 1;
63 const USHORT SC_AREASDLG_PR_USER = 2;
64 const USHORT SC_AREASDLG_PR_SELECT = 3;
65 const USHORT SC_AREASDLG_PR_OFFSET = 4;
67 // List box positions for repeat ranges (RR)
68 const USHORT SC_AREASDLG_RR_NONE = 0;
69 const USHORT SC_AREASDLG_RR_USER = 1;
70 const USHORT SC_AREASDLG_RR_OFFSET = 2;
72 //============================================================================
74 #define HDL(hdl) LINK( this, ScPrintAreasDlg, hdl )
75 #define ERRORBOX(nId) ErrorBox( this, WinBits(WB_OK|WB_DEF_OK), \
76 ScGlobal::GetRscString( nId ) ).Execute()
77 #define SWAP(x1,x2) { int n=x1; x1=x2; x2=n; }
79 // globale Funktionen (->am Ende der Datei):
81 bool lcl_CheckRepeatString( const String& rStr, ScDocument* pDoc, bool bIsRow, ScRange* pRange );
82 void lcl_GetRepeatRangeString( const ScRange* pRange, ScDocument* pDoc, bool bIsRow, String& rStr );
84 #if 0
85 static void printAddressFlags(USHORT nFlag)
87 if ((nFlag & SCA_COL_ABSOLUTE ) == SCA_COL_ABSOLUTE ) printf("SCA_COL_ABSOLUTE \n");
88 if ((nFlag & SCA_ROW_ABSOLUTE ) == SCA_ROW_ABSOLUTE ) printf("SCA_ROW_ABSOLUTE \n");
89 if ((nFlag & SCA_TAB_ABSOLUTE ) == SCA_TAB_ABSOLUTE ) printf("SCA_TAB_ABSOLUTE \n");
90 if ((nFlag & SCA_TAB_3D ) == SCA_TAB_3D ) printf("SCA_TAB_3D \n");
91 if ((nFlag & SCA_COL2_ABSOLUTE ) == SCA_COL2_ABSOLUTE ) printf("SCA_COL2_ABSOLUTE\n");
92 if ((nFlag & SCA_ROW2_ABSOLUTE ) == SCA_ROW2_ABSOLUTE ) printf("SCA_ROW2_ABSOLUTE\n");
93 if ((nFlag & SCA_TAB2_ABSOLUTE ) == SCA_TAB2_ABSOLUTE ) printf("SCA_TAB2_ABSOLUTE\n");
94 if ((nFlag & SCA_TAB2_3D ) == SCA_TAB2_3D ) printf("SCA_TAB2_3D \n");
95 if ((nFlag & SCA_VALID_ROW ) == SCA_VALID_ROW ) printf("SCA_VALID_ROW \n");
96 if ((nFlag & SCA_VALID_COL ) == SCA_VALID_COL ) printf("SCA_VALID_COL \n");
97 if ((nFlag & SCA_VALID_TAB ) == SCA_VALID_TAB ) printf("SCA_VALID_TAB \n");
98 if ((nFlag & SCA_FORCE_DOC ) == SCA_FORCE_DOC ) printf("SCA_FORCE_DOC \n");
99 if ((nFlag & SCA_VALID_ROW2 ) == SCA_VALID_ROW2 ) printf("SCA_VALID_ROW2 \n");
100 if ((nFlag & SCA_VALID_COL2 ) == SCA_VALID_COL2 ) printf("SCA_VALID_COL2 \n");
101 if ((nFlag & SCA_VALID_TAB2 ) == SCA_VALID_TAB2 ) printf("SCA_VALID_TAB2 \n");
102 if ((nFlag & SCA_VALID ) == SCA_VALID ) printf("SCA_VALID \n");
103 if ((nFlag & SCA_ABS ) == SCA_ABS ) printf("SCA_ABS \n");
104 if ((nFlag & SCR_ABS ) == SCR_ABS ) printf("SCR_ABS \n");
105 if ((nFlag & SCA_ABS_3D ) == SCA_ABS_3D ) printf("SCA_ABS_3D \n");
106 if ((nFlag & SCR_ABS_3D ) == SCR_ABS_3D ) printf("SCR_ABS_3D \n");
108 #endif
110 //============================================================================
111 // class ScPrintAreasDlg
113 //----------------------------------------------------------------------------
115 ScPrintAreasDlg::ScPrintAreasDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent )
116 : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_AREAS),
118 aLbPrintArea ( this, ScResId( LB_PRINTAREA ) ),
119 aFlPrintArea ( this, ScResId( FL_PRINTAREA ) ),
120 aEdPrintArea ( this, this, ScResId( ED_PRINTAREA ) ),
121 aRbPrintArea ( this, ScResId( RB_PRINTAREA ), &aEdPrintArea, this ),
123 aLbRepeatRow ( this, ScResId( LB_REPEATROW ) ),
124 aFlRepeatRow ( this, ScResId( FL_REPEATROW ) ),
125 aEdRepeatRow ( this, this, ScResId( ED_REPEATROW ) ),
126 aRbRepeatRow ( this, ScResId( RB_REPEATROW ), &aEdRepeatRow, this ),
128 aLbRepeatCol ( this, ScResId( LB_REPEATCOL ) ),
129 aFlRepeatCol ( this, ScResId( FL_REPEATCOL ) ),
130 aEdRepeatCol ( this, this, ScResId( ED_REPEATCOL ) ),
131 aRbRepeatCol ( this, ScResId( RB_REPEATCOL ), &aEdRepeatCol, this ),
133 aBtnOk ( this, ScResId( BTN_OK ) ),
134 aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
135 aBtnHelp ( this, ScResId( BTN_HELP ) ),
137 bDlgLostFocus ( FALSE ),
138 pRefInputEdit ( &aEdPrintArea ),
139 pDoc ( NULL ),
140 pViewData ( NULL ),
141 nCurTab ( 0 )
143 ScTabViewShell* pScViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
144 ScDocShell* pScDocSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() );
146 DBG_ASSERT( pScDocSh, "Current DocumentShell not found :-(" );
148 pDoc = pScDocSh->GetDocument();
150 if ( pScViewSh )
152 pViewData = pScViewSh->GetViewData();
153 nCurTab = pViewData->GetTabNo();
156 Impl_Reset();
158 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
159 //SFX_APPWINDOW->Enable();
161 FreeResource();
165 //----------------------------------------------------------------------------
167 ScPrintAreasDlg::~ScPrintAreasDlg()
169 // Extra-Data an ListBox-Entries abraeumen
170 ListBox* pLb[3] = { &aLbPrintArea, &aLbRepeatRow, &aLbRepeatCol };
172 for ( USHORT i=0; i<3; i++ )
174 USHORT nCount = pLb[i]->GetEntryCount();
175 for ( USHORT j=0; j<nCount; j++ )
176 delete (String*)pLb[i]->GetEntryData(j);
181 //----------------------------------------------------------------------------
183 BOOL ScPrintAreasDlg::Close()
185 return DoClose( ScPrintAreasDlgWrapper::GetChildWindowId() );
189 //----------------------------------------------------------------------------
191 BOOL ScPrintAreasDlg::IsTableLocked() const
193 // Druckbereiche gelten pro Tabelle, darum macht es keinen Sinn,
194 // bei der Eingabe die Tabelle umzuschalten
196 return TRUE;
200 //----------------------------------------------------------------------------
202 void ScPrintAreasDlg::SetReference( const ScRange& rRef, ScDocument* /* pDoc */ )
204 if ( pRefInputEdit )
206 if ( rRef.aStart != rRef.aEnd )
207 RefInputStart( pRefInputEdit );
209 String aStr;
210 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
212 if ( &aEdPrintArea == pRefInputEdit )
214 rRef.Format( aStr, SCR_ABS, pDoc, eConv );
216 // aEdPrintArea.ReplaceSelected( aStr );
218 String aVal = aEdPrintArea.GetText();
219 Selection aSel = aEdPrintArea.GetSelection();
220 aSel.Justify();
221 aVal.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
222 aVal.Insert( aStr, (xub_StrLen)aSel.Min() );
223 Selection aNewSel( aSel.Min(), aSel.Min()+aStr.Len() );
224 aEdPrintArea.SetRefString( aVal );
225 aEdPrintArea.SetSelection( aNewSel );
227 else
229 BOOL bRow = ( &aEdRepeatRow == pRefInputEdit );
230 lcl_GetRepeatRangeString(&rRef, pDoc, bRow, aStr);
231 pRefInputEdit->SetRefString( aStr );
235 Impl_ModifyHdl( pRefInputEdit );
239 //----------------------------------------------------------------------------
241 void ScPrintAreasDlg::AddRefEntry()
243 if ( pRefInputEdit == &aEdPrintArea )
245 const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
246 String aVal = aEdPrintArea.GetText();
247 aVal += sep;
248 aEdPrintArea.SetText(aVal);
250 xub_StrLen nLen = aVal.Len();
251 aEdPrintArea.SetSelection( Selection( nLen, nLen ) );
253 Impl_ModifyHdl( &aEdPrintArea );
258 //----------------------------------------------------------------------------
260 void ScPrintAreasDlg::Deactivate()
262 bDlgLostFocus = TRUE;
266 //----------------------------------------------------------------------------
268 void ScPrintAreasDlg::SetActive()
270 if ( bDlgLostFocus )
272 bDlgLostFocus = FALSE;
274 if ( pRefInputEdit )
276 pRefInputEdit->GrabFocus();
277 Impl_ModifyHdl( pRefInputEdit );
280 else
281 GrabFocus();
283 RefInputDone();
287 //----------------------------------------------------------------------------
289 void ScPrintAreasDlg::Impl_Reset()
291 String aStrRange;
292 const ScRange* pRepeatColRange = pDoc->GetRepeatColRange( nCurTab );
293 const ScRange* pRepeatRowRange = pDoc->GetRepeatRowRange( nCurTab );
295 aEdPrintArea.SetModifyHdl ( HDL(Impl_ModifyHdl) );
296 aEdRepeatRow.SetModifyHdl ( HDL(Impl_ModifyHdl) );
297 aEdRepeatCol.SetModifyHdl ( HDL(Impl_ModifyHdl) );
298 aEdPrintArea.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
299 aEdRepeatRow.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
300 aEdRepeatCol.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
301 aLbPrintArea.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
302 aLbRepeatRow.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
303 aLbRepeatCol.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
304 aLbPrintArea.SetSelectHdl ( HDL(Impl_SelectHdl) );
305 aLbRepeatRow.SetSelectHdl ( HDL(Impl_SelectHdl) );
306 aLbRepeatCol.SetSelectHdl ( HDL(Impl_SelectHdl) );
307 aBtnOk .SetClickHdl ( HDL(Impl_BtnHdl) );
308 aBtnCancel .SetClickHdl ( HDL(Impl_BtnHdl) );
310 Impl_FillLists();
312 //-------------------------
313 // Druckbereich
314 //-------------------------
315 aStrRange.Erase();
316 String aOne;
317 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
318 const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
319 USHORT nRangeCount = pDoc->GetPrintRangeCount( nCurTab );
320 for (USHORT i=0; i<nRangeCount; i++)
322 const ScRange* pPrintRange = pDoc->GetPrintRange( nCurTab, i );
323 if (pPrintRange)
325 if ( aStrRange.Len() )
326 aStrRange += sep;
327 pPrintRange->Format( aOne, SCR_ABS, pDoc, eConv );
328 aStrRange += aOne;
331 aEdPrintArea.SetText( aStrRange );
333 //-------------------------------
334 // Wiederholungszeile
335 //-------------------------------
336 lcl_GetRepeatRangeString(pRepeatRowRange, pDoc, true, aStrRange);
337 aEdRepeatRow.SetText( aStrRange );
339 //--------------------------------
340 // Wiederholungsspalte
341 //--------------------------------
342 lcl_GetRepeatRangeString(pRepeatColRange, pDoc, false, aStrRange);
343 aEdRepeatCol.SetText( aStrRange );
345 Impl_ModifyHdl( &aEdPrintArea );
346 Impl_ModifyHdl( &aEdRepeatRow );
347 Impl_ModifyHdl( &aEdRepeatCol );
348 if( pDoc->IsPrintEntireSheet( nCurTab ) )
349 aLbPrintArea.SelectEntryPos( SC_AREASDLG_PR_ENTIRE );
351 aEdPrintArea.SaveValue(); // fuer FillItemSet() merken:
352 aEdRepeatRow.SaveValue();
353 aEdRepeatCol.SaveValue();
357 //----------------------------------------------------------------------------
359 BOOL ScPrintAreasDlg::Impl_GetItem( Edit* pEd, SfxStringItem& rItem )
361 String aRangeStr = pEd->GetText();
362 BOOL bDataChanged = (pEd->GetSavedValue() != aRangeStr);
364 if ( (aRangeStr.Len() > 0) && &aEdPrintArea != pEd )
366 ScRange aRange;
367 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
368 lcl_CheckRepeatString(aRangeStr, pDoc, &aEdRepeatRow == pEd, &aRange);
369 aRange.Format(aRangeStr, SCR_ABS, pDoc, eConv);
372 rItem.SetValue( aRangeStr );
374 return bDataChanged;
378 //----------------------------------------------------------------------------
380 BOOL ScPrintAreasDlg::Impl_CheckRefStrings()
382 BOOL bOk = FALSE;
383 String aStrPrintArea = aEdPrintArea.GetText();
384 String aStrRepeatRow = aEdRepeatRow.GetText();
385 String aStrRepeatCol = aEdRepeatCol.GetText();
387 BOOL bPrintAreaOk = TRUE;
388 if ( aStrPrintArea.Len() )
390 const USHORT nValidAddr = SCA_VALID | SCA_VALID_ROW | SCA_VALID_COL;
391 const USHORT nValidRange = nValidAddr | SCA_VALID_ROW2 | SCA_VALID_COL2;
392 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
393 const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
394 // const sal_Unicode rsep = ScCompiler::GetNativeSymbol(ocRange).GetChar(0);
396 ScAddress aAddr;
397 ScRange aRange;
398 xub_StrLen nSepCount = aStrPrintArea.GetTokenCount(sep);
399 for ( xub_StrLen i = 0; i < nSepCount && bPrintAreaOk; ++i )
401 String aOne = aStrPrintArea.GetToken(i, sep);
402 USHORT nResult = aRange.Parse( aOne, pDoc, eConv );
403 if ((nResult & nValidRange) != nValidRange)
405 USHORT nAddrResult = aAddr.Parse( aOne, pDoc, eConv );
406 if ((nAddrResult & nValidAddr) != nValidAddr)
407 bPrintAreaOk = FALSE;
412 BOOL bRepeatRowOk = (aStrRepeatRow.Len() == 0);
413 if ( !bRepeatRowOk )
414 bRepeatRowOk = lcl_CheckRepeatString(aStrRepeatRow, pDoc, true, NULL);
416 BOOL bRepeatColOk = (aStrRepeatCol.Len() == 0);
417 if ( !bRepeatColOk )
418 bRepeatColOk = lcl_CheckRepeatString(aStrRepeatCol, pDoc, false, NULL);
420 // Fehlermeldungen
422 bOk = (bPrintAreaOk && bRepeatRowOk && bRepeatColOk);
424 if ( !bOk )
426 Edit* pEd = NULL;
428 if ( !bPrintAreaOk ) pEd = &aEdPrintArea;
429 else if ( !bRepeatRowOk ) pEd = &aEdRepeatRow;
430 else if ( !bRepeatColOk ) pEd = &aEdRepeatCol;
432 ERRORBOX( STR_INVALID_TABREF );
433 pEd->GrabFocus();
436 return bOk;
440 //----------------------------------------------------------------------------
442 void ScPrintAreasDlg::Impl_FillLists()
444 //------------------------------------------------------
445 // Selektion holen und String in PrintArea-ListBox merken
446 //------------------------------------------------------
447 ScRange aRange;
448 String aStrRange;
449 BOOL bSimple = TRUE;
451 if ( pViewData )
452 bSimple = (pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE);
454 formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
456 if ( bSimple )
457 aRange.Format( aStrRange, SCR_ABS, pDoc, eConv );
458 else
460 ScRangeListRef aList( new ScRangeList );
461 pViewData->GetMarkData().FillRangeListWithMarks( aList, FALSE );
462 aList->Format( aStrRange, SCR_ABS, pDoc, eConv );
465 aLbPrintArea.SetEntryData( SC_AREASDLG_PR_SELECT, new String( aStrRange ) );
467 //------------------------------------------------------
468 // Ranges holen und in ListBoxen merken
469 //------------------------------------------------------
470 ScRangeName* pRangeNames = pDoc->GetRangeName();
471 const USHORT nCount = pRangeNames ? pRangeNames->GetCount() : 0;
473 if ( nCount > 0 )
475 String aName;
476 String aSymbol;
477 // ScRange aRange;
478 ScRangeData* pData = NULL;
480 for ( USHORT i=0; i<nCount; i++ )
482 pData = (ScRangeData*)(pRangeNames->At( i ));
483 if ( pData )
485 if ( pData->HasType( RT_ABSAREA )
486 || pData->HasType( RT_REFAREA )
487 || pData->HasType( RT_ABSPOS ) )
489 pData->GetName( aName );
490 pData->GetSymbol( aSymbol );
491 if ( aRange.ParseAny( aSymbol, pDoc, eConv ) & SCA_VALID )
493 if ( pData->HasType( RT_PRINTAREA ) )
495 aRange.Format( aSymbol, SCR_ABS, pDoc, eConv );
496 aLbPrintArea.SetEntryData(
497 aLbPrintArea.InsertEntry( aName ),
498 new String( aSymbol ) );
501 if ( pData->HasType( RT_ROWHEADER ) )
503 lcl_GetRepeatRangeString(&aRange, pDoc, true, aSymbol);
504 aLbRepeatRow.SetEntryData(
505 aLbRepeatRow.InsertEntry( aName ),
506 new String( aSymbol ) );
509 if ( pData->HasType( RT_COLHEADER ) )
511 lcl_GetRepeatRangeString(&aRange, pDoc, false, aSymbol);
512 aLbRepeatCol.SetEntryData(
513 aLbRepeatCol.InsertEntry( aName ),
514 new String( aSymbol ) );
524 //----------------------------------------------------------------------------
525 // Handler:
526 //----------------------------------------------------------------------------
528 IMPL_LINK( ScPrintAreasDlg, Impl_BtnHdl, PushButton*, pBtn )
530 if ( &aBtnOk == pBtn )
532 if ( Impl_CheckRefStrings() )
534 BOOL bDataChanged = FALSE;
535 String aStr;
536 SfxStringItem aPrintArea( SID_CHANGE_PRINTAREA, aStr );
537 SfxStringItem aRepeatRow( FN_PARAM_2, aStr );
538 SfxStringItem aRepeatCol( FN_PARAM_3, aStr );
540 //-------------------------
541 // Druckbereich veraendert?
542 //-------------------------
544 // first try the list box, if "Entite sheet" is selected
545 BOOL bEntireSheet = (aLbPrintArea.GetSelectEntryPos() == SC_AREASDLG_PR_ENTIRE);
546 SfxBoolItem aEntireSheet( FN_PARAM_4, bEntireSheet );
548 bDataChanged = bEntireSheet != pDoc->IsPrintEntireSheet( nCurTab );
549 if( !bEntireSheet )
551 // if new list box selection is not "Entire sheet", get the edit field contents
552 bDataChanged |= Impl_GetItem( &aEdPrintArea, aPrintArea );
555 //-------------------------------
556 // Wiederholungszeile veraendert?
557 //-------------------------------
558 bDataChanged |= Impl_GetItem( &aEdRepeatRow, aRepeatRow );
560 //--------------------------------
561 // Wiederholungsspalte veraendert?
562 //--------------------------------
563 bDataChanged |= Impl_GetItem( &aEdRepeatCol, aRepeatCol );
565 if ( bDataChanged )
567 SetDispatcherLock( FALSE );
568 SwitchToDocument();
569 GetBindings().GetDispatcher()->Execute( SID_CHANGE_PRINTAREA,
570 SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
571 &aPrintArea, &aRepeatRow, &aRepeatCol, &aEntireSheet, 0L );
574 Close();
577 else if ( &aBtnCancel == pBtn )
578 Close();
580 return 0;
584 //----------------------------------------------------------------------------
586 IMPL_LINK( ScPrintAreasDlg, Impl_GetFocusHdl, Control*, pCtr )
588 if ( pCtr ==(Control *) &aEdPrintArea ||
589 pCtr ==(Control *) &aEdRepeatRow ||
590 pCtr ==(Control *) &aEdRepeatCol)
592 pRefInputEdit = (formula::RefEdit*) pCtr;
594 else if ( pCtr ==(Control *) &aLbPrintArea)
596 pRefInputEdit = &aEdPrintArea;
598 else if ( pCtr ==(Control *) &aLbRepeatRow)
600 pRefInputEdit = &aEdRepeatRow;
602 else if ( pCtr ==(Control *) &aLbRepeatCol)
604 pRefInputEdit = &aEdRepeatCol;
607 return 0;
611 //----------------------------------------------------------------------------
613 IMPL_LINK( ScPrintAreasDlg, Impl_SelectHdl, ListBox*, pLb )
615 USHORT nSelPos = pLb->GetSelectEntryPos();
616 Edit* pEd = NULL;
618 // list box positions of specific entries, default to "repeat row/column" list boxes
619 USHORT nAllSheetPos = SC_AREASDLG_RR_NONE;
620 USHORT nUserDefPos = SC_AREASDLG_RR_USER;
621 USHORT nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
623 // find edit field for list box, and list box positions
624 if( pLb == &aLbPrintArea )
626 pEd = &aEdPrintArea;
627 nAllSheetPos = SC_AREASDLG_PR_ENTIRE;
628 nUserDefPos = SC_AREASDLG_PR_USER;
629 nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
631 else if( pLb == &aLbRepeatCol )
632 pEd = &aEdRepeatCol;
633 else if( pLb == &aLbRepeatRow )
634 pEd = &aEdRepeatRow;
635 else
636 return 0;
638 // fill edit field according to list box selection
639 if( (nSelPos == 0) || (nSelPos == nAllSheetPos) )
640 pEd->SetText( EMPTY_STRING );
641 else if( nSelPos == nUserDefPos && !pLb->IsTravelSelect() && pEd->GetText().Len() == 0 )
642 pLb->SelectEntryPos( 0 );
643 else if( nSelPos >= nFirstCustomPos )
644 pEd->SetText( *static_cast< String* >( pLb->GetEntryData( nSelPos ) ) );
646 return 0;
650 //----------------------------------------------------------------------------
652 IMPL_LINK( ScPrintAreasDlg, Impl_ModifyHdl, formula::RefEdit*, pEd )
654 ListBox* pLb = NULL;
656 // list box positions of specific entries, default to "repeat row/column" list boxes
657 USHORT nUserDefPos = SC_AREASDLG_RR_USER;
658 USHORT nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
660 if( pEd == &aEdPrintArea )
662 pLb = &aLbPrintArea;
663 nUserDefPos = SC_AREASDLG_PR_USER;
664 nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
666 else if( pEd == &aEdRepeatCol )
667 pLb = &aLbRepeatCol;
668 else if( pEd == &aEdRepeatRow )
669 pLb = &aLbRepeatRow;
670 else
671 return 0;
673 // set list box selection according to edit field
674 USHORT nEntryCount = pLb->GetEntryCount();
675 String aStrEd( pEd->GetText() );
676 String aEdUpper = aStrEd;
677 aEdUpper.ToUpperAscii();
679 if ( (nEntryCount > nFirstCustomPos) && aStrEd.Len() > 0 )
681 BOOL bFound = FALSE;
682 String* pSymbol = NULL;
683 USHORT i;
685 for ( i=nFirstCustomPos; i<nEntryCount && !bFound; i++ )
687 pSymbol = (String*)pLb->GetEntryData( i );
688 bFound = ( (*pSymbol == aStrEd) || (*pSymbol == aEdUpper) );
691 pLb->SelectEntryPos( bFound ? i-1 : nUserDefPos );
693 else
694 pLb->SelectEntryPos( aStrEd.Len() ? nUserDefPos : 0 );
696 return 0;
700 //============================================================================
701 // globale Funktionen:
703 // ----------------------------------------------------------------------------
705 // TODO: It might make sense to move these functions to address.?xx. -kohei
707 bool lcl_CheckOne_OOO( const String& rStr, bool bIsRow, SCCOLROW& rVal )
709 // Zulaessige Syntax fuer rStr:
710 // Row: [$]1-MAXTAB
711 // Col: [$]A-IV
713 String aStr = rStr;
714 xub_StrLen nLen = aStr.Len();
715 SCCOLROW nNum = 0;
716 BOOL bStrOk = ( nLen > 0 ) && ( bIsRow ? ( nLen < 6 ) : ( nLen < 4 ) );
718 if ( bStrOk )
720 if ( '$' == aStr.GetChar(0) )
721 aStr.Erase( 0, 1 );
723 if ( bIsRow )
725 bStrOk = CharClass::isAsciiNumeric(aStr);
727 if ( bStrOk )
729 sal_Int32 n = aStr.ToInt32();
731 if ( ( bStrOk = (n > 0) && ( n <= MAXROWCOUNT ) ) != FALSE )
732 nNum = static_cast<SCCOLROW>(n - 1);
735 else
737 SCCOL nCol = 0;
738 bStrOk = ::AlphaToCol( nCol, aStr);
739 nNum = nCol;
743 if ( bStrOk )
744 rVal = nNum;
746 return bStrOk;
749 bool lcl_CheckOne_XL_A1( const String& rStr, bool bIsRow, SCCOLROW& rVal )
751 // XL A1 style is identical to OOO one for print range formats.
752 return lcl_CheckOne_OOO(rStr, bIsRow, rVal);
755 bool lcl_CheckOne_XL_R1C1( const String& rStr, bool bIsRow, SCCOLROW& rVal )
757 xub_StrLen nLen = rStr.Len();
758 if (nLen <= 1)
759 // There must be at least two characters.
760 return false;
762 const sal_Unicode preUpper = bIsRow ? 'R' : 'C';
763 const sal_Unicode preLower = bIsRow ? 'r' : 'c';
764 if (rStr.GetChar(0) != preUpper && rStr.GetChar(0) != preLower)
765 return false;
767 String aNumStr = rStr.Copy(1);
768 if (!CharClass::isAsciiNumeric(aNumStr))
769 return false;
771 sal_Int32 nNum = aNumStr.ToInt32();
773 if (nNum <= 0)
774 return false;
776 if ((bIsRow && nNum > MAXROWCOUNT) || (!bIsRow && nNum > MAXCOLCOUNT))
777 return false;
779 rVal = static_cast<SCCOLROW>(nNum-1);
780 return true;
783 bool lcl_CheckRepeatOne( const String& rStr, formula::FormulaGrammar::AddressConvention eConv, bool bIsRow, SCCOLROW& rVal )
785 switch (eConv)
787 case formula::FormulaGrammar::CONV_OOO:
788 return lcl_CheckOne_OOO(rStr, bIsRow, rVal);
789 case formula::FormulaGrammar::CONV_XL_A1:
790 return lcl_CheckOne_XL_A1(rStr, bIsRow, rVal);
791 case formula::FormulaGrammar::CONV_XL_R1C1:
792 return lcl_CheckOne_XL_R1C1(rStr, bIsRow, rVal);
793 default:
795 // added to avoid warnings
798 return false;
801 bool lcl_CheckRepeatString( const String& rStr, ScDocument* pDoc, bool bIsRow, ScRange* pRange )
803 // Row: [valid row] rsep [valid row]
804 // Col: [valid col] rsep [valid col]
806 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
807 const sal_Unicode rsep = ScCompiler::GetNativeSymbol(ocRange).GetChar(0);
809 if (pRange)
811 // initialize the range value.
812 pRange->aStart.SetCol(0);
813 pRange->aStart.SetRow(0);
814 pRange->aEnd.SetCol(0);
815 pRange->aEnd.SetRow(0);
818 String aBuf;
819 SCCOLROW nVal = 0;
820 xub_StrLen nLen = rStr.Len();
821 bool bEndPos = false;
822 for (xub_StrLen i = 0; i < nLen; ++i)
824 const sal_Unicode c = rStr.GetChar(i);
825 if (c == rsep)
827 if (bEndPos)
828 // We aren't supposed to have more than one range separator.
829 return false;
831 // range separator
832 if (aBuf.Len() == 0)
833 return false;
835 bool bRes = lcl_CheckRepeatOne(aBuf, eConv, bIsRow, nVal);
836 if (!bRes)
837 return false;
839 if (pRange)
841 if (bIsRow)
843 pRange->aStart.SetRow(static_cast<SCROW>(nVal));
844 pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
846 else
848 pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
849 pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
853 aBuf.Erase();
854 bEndPos = true;
856 else
857 aBuf.Append(c);
860 if (aBuf.Len() > 0)
862 bool bRes = lcl_CheckRepeatOne(aBuf, eConv, bIsRow, nVal);
863 if (!bRes)
864 return false;
866 if (pRange)
868 if (bIsRow)
870 if (!bEndPos)
871 pRange->aStart.SetRow(static_cast<SCROW>(nVal));
872 pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
874 else
876 if (!bEndPos)
877 pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
878 pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
883 return true;
886 // ----------------------------------------------------------------------------
888 void lcl_GetRepeatRangeString( const ScRange* pRange, ScDocument* pDoc, bool bIsRow, String& rStr )
890 rStr.Erase();
891 if (!pRange)
892 return;
894 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
895 const ScAddress& rStart = pRange->aStart;
896 const ScAddress& rEnd = pRange->aEnd;
898 const USHORT nFmt = bIsRow ? (SCA_VALID_ROW | SCA_ROW_ABSOLUTE) : (SCA_VALID_COL | SCA_COL_ABSOLUTE);
899 String aTmpStr;
900 rStart.Format(aTmpStr, nFmt, pDoc, eConv);
901 rStr += aTmpStr;
902 if ((bIsRow && rStart.Row() != rEnd.Row()) || (!bIsRow && rStart.Col() != rEnd.Col()))
904 rStr += ScCompiler::GetNativeSymbol(ocRange);
905 rEnd.Format(aTmpStr, nFmt, pDoc, eConv);
906 rStr += aTmpStr;