1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27
28
29 //----------------------------------------------------------------------------
30 #include <rangelst.hxx>
31
32 #include <sfx2/dispatch.hxx>
33 #include <svl/stritem.hxx>
34 #include <vcl/msgbox.hxx>
35 #include <unotools/charclass.hxx>
36 #include <stdlib.h>
37
38 #define _AREASDLG_CXX
39 #include "areasdlg.hxx"
40 #undef _AREASDLG_CXX
41
42 #include "scresid.hxx"
43 #include "rangenam.hxx"
44 #include "reffact.hxx"
45 #include "tabvwsh.hxx"
46 #include "docsh.hxx"
47 #include "globstr.hrc"
48 #include "pagedlg.hrc"
49 #include "compiler.hxx"
50
51 // STATIC DATA ---------------------------------------------------------------
52
53 // List box positions for print range (PR)
54 const sal_uInt16 SC_AREASDLG_PR_NONE = 0;
55 const sal_uInt16 SC_AREASDLG_PR_ENTIRE = 1;
56 const sal_uInt16 SC_AREASDLG_PR_USER = 2;
57 const sal_uInt16 SC_AREASDLG_PR_SELECT = 3;
58 const sal_uInt16 SC_AREASDLG_PR_OFFSET = 4;
59
60 // List box positions for repeat ranges (RR)
61 const sal_uInt16 SC_AREASDLG_RR_NONE = 0;
62 const sal_uInt16 SC_AREASDLG_RR_USER = 1;
63 const sal_uInt16 SC_AREASDLG_RR_OFFSET = 2;
64
65 //============================================================================
66
67 #define HDL(hdl) LINK( this, ScPrintAreasDlg, hdl )
68 #define ERRORBOX(nId) ErrorBox( this, WinBits(WB_OK|WB_DEF_OK), \
69 ScGlobal::GetRscString( nId ) ).Execute()
70 #define SWAP(x1,x2) { int n=x1; x1=x2; x2=n; }
71
72 // globale Funktionen (->am Ende der Datei):
73
74 bool lcl_CheckRepeatString( const String& rStr, ScDocument* pDoc, bool bIsRow, ScRange* pRange );
75 void lcl_GetRepeatRangeString( const ScRange* pRange, ScDocument* pDoc, bool bIsRow, String& rStr );
76
77 #if 0
78 static void printAddressFlags(sal_uInt16 nFlag)
79 {
80 if ((nFlag & SCA_COL_ABSOLUTE ) == SCA_COL_ABSOLUTE ) printf("SCA_COL_ABSOLUTE \n");
81 if ((nFlag & SCA_ROW_ABSOLUTE ) == SCA_ROW_ABSOLUTE ) printf("SCA_ROW_ABSOLUTE \n");
82 if ((nFlag & SCA_TAB_ABSOLUTE ) == SCA_TAB_ABSOLUTE ) printf("SCA_TAB_ABSOLUTE \n");
83 if ((nFlag & SCA_TAB_3D ) == SCA_TAB_3D ) printf("SCA_TAB_3D \n");
84 if ((nFlag & SCA_COL2_ABSOLUTE ) == SCA_COL2_ABSOLUTE ) printf("SCA_COL2_ABSOLUTE\n");
85 if ((nFlag & SCA_ROW2_ABSOLUTE ) == SCA_ROW2_ABSOLUTE ) printf("SCA_ROW2_ABSOLUTE\n");
86 if ((nFlag & SCA_TAB2_ABSOLUTE ) == SCA_TAB2_ABSOLUTE ) printf("SCA_TAB2_ABSOLUTE\n");
87 if ((nFlag & SCA_TAB2_3D ) == SCA_TAB2_3D ) printf("SCA_TAB2_3D \n");
88 if ((nFlag & SCA_VALID_ROW ) == SCA_VALID_ROW ) printf("SCA_VALID_ROW \n");
89 if ((nFlag & SCA_VALID_COL ) == SCA_VALID_COL ) printf("SCA_VALID_COL \n");
90 if ((nFlag & SCA_VALID_TAB ) == SCA_VALID_TAB ) printf("SCA_VALID_TAB \n");
91 if ((nFlag & SCA_FORCE_DOC ) == SCA_FORCE_DOC ) printf("SCA_FORCE_DOC \n");
92 if ((nFlag & SCA_VALID_ROW2 ) == SCA_VALID_ROW2 ) printf("SCA_VALID_ROW2 \n");
93 if ((nFlag & SCA_VALID_COL2 ) == SCA_VALID_COL2 ) printf("SCA_VALID_COL2 \n");
94 if ((nFlag & SCA_VALID_TAB2 ) == SCA_VALID_TAB2 ) printf("SCA_VALID_TAB2 \n");
95 if ((nFlag & SCA_VALID ) == SCA_VALID ) printf("SCA_VALID \n");
96 if ((nFlag & SCA_ABS ) == SCA_ABS ) printf("SCA_ABS \n");
97 if ((nFlag & SCR_ABS ) == SCR_ABS ) printf("SCR_ABS \n");
98 if ((nFlag & SCA_ABS_3D ) == SCA_ABS_3D ) printf("SCA_ABS_3D \n");
99 if ((nFlag & SCR_ABS_3D ) == SCR_ABS_3D ) printf("SCR_ABS_3D \n");
100 }
101 #endif
102
103 //============================================================================
104 // class ScPrintAreasDlg
105
106 //----------------------------------------------------------------------------
107
ScPrintAreasDlg(SfxBindings * pB,SfxChildWindow * pCW,Window * pParent)108 ScPrintAreasDlg::ScPrintAreasDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent )
109 : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_AREAS),
110 //
111 aFlPrintArea ( this, ScResId( FL_PRINTAREA ) ),
112 aLbPrintArea ( this, ScResId( LB_PRINTAREA ) ),
113 aEdPrintArea ( this, this, ScResId( ED_PRINTAREA ) ),
114 aRbPrintArea ( this, ScResId( RB_PRINTAREA ), &aEdPrintArea, this ),
115 //
116 aFlRepeatRow ( this, ScResId( FL_REPEATROW ) ),
117 aLbRepeatRow ( this, ScResId( LB_REPEATROW ) ),
118 aEdRepeatRow ( this, this, ScResId( ED_REPEATROW ) ),
119 aRbRepeatRow ( this, ScResId( RB_REPEATROW ), &aEdRepeatRow, this ),
120 //
121 aFlRepeatCol ( this, ScResId( FL_REPEATCOL ) ),
122 aLbRepeatCol ( this, ScResId( LB_REPEATCOL ) ),
123 aEdRepeatCol ( this, this, ScResId( ED_REPEATCOL ) ),
124 aRbRepeatCol ( this, ScResId( RB_REPEATCOL ), &aEdRepeatCol, this ),
125 //
126 aBtnOk ( this, ScResId( BTN_OK ) ),
127 aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
128 aBtnHelp ( this, ScResId( BTN_HELP ) ),
129 //
130 bDlgLostFocus ( sal_False ),
131 pRefInputEdit ( &aEdPrintArea ),
132 pDoc ( NULL ),
133 pViewData ( NULL ),
134 nCurTab ( 0 )
135 {
136 ScTabViewShell* pScViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
137 ScDocShell* pScDocSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() );
138
139 DBG_ASSERT( pScDocSh, "Current DocumentShell not found :-(" );
140
141 pDoc = pScDocSh->GetDocument();
142
143 if ( pScViewSh )
144 {
145 pViewData = pScViewSh->GetViewData();
146 nCurTab = pViewData->GetTabNo();
147 }
148
149 Impl_Reset();
150
151 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
152 //SFX_APPWINDOW->Enable();
153
154 FreeResource();
155 }
156
157
158 //----------------------------------------------------------------------------
159
~ScPrintAreasDlg()160 ScPrintAreasDlg::~ScPrintAreasDlg()
161 {
162 // Extra-Data an ListBox-Entries abraeumen
163 ListBox* pLb[3] = { &aLbPrintArea, &aLbRepeatRow, &aLbRepeatCol };
164
165 for ( sal_uInt16 i=0; i<3; i++ )
166 {
167 sal_uInt16 nCount = pLb[i]->GetEntryCount();
168 for ( sal_uInt16 j=0; j<nCount; j++ )
169 delete (String*)pLb[i]->GetEntryData(j);
170 }
171 }
172
173
174 //----------------------------------------------------------------------------
175
Close()176 sal_Bool ScPrintAreasDlg::Close()
177 {
178 return DoClose( ScPrintAreasDlgWrapper::GetChildWindowId() );
179 }
180
181
182 //----------------------------------------------------------------------------
183
IsTableLocked() const184 sal_Bool ScPrintAreasDlg::IsTableLocked() const
185 {
186 // Druckbereiche gelten pro Tabelle, darum macht es keinen Sinn,
187 // bei der Eingabe die Tabelle umzuschalten
188
189 return sal_True;
190 }
191
192
193 //----------------------------------------------------------------------------
194
SetReference(const ScRange & rRef,ScDocument *)195 void ScPrintAreasDlg::SetReference( const ScRange& rRef, ScDocument* /* pDoc */ )
196 {
197 if ( pRefInputEdit )
198 {
199 if ( rRef.aStart != rRef.aEnd )
200 RefInputStart( pRefInputEdit );
201
202 String aStr;
203 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
204
205 if ( &aEdPrintArea == pRefInputEdit )
206 {
207 rRef.Format( aStr, SCR_ABS, pDoc, eConv );
208
209 // aEdPrintArea.ReplaceSelected( aStr );
210
211 String aVal = aEdPrintArea.GetText();
212 Selection aSel = aEdPrintArea.GetSelection();
213 aSel.Justify();
214 aVal.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
215 aVal.Insert( aStr, (xub_StrLen)aSel.Min() );
216 Selection aNewSel( aSel.Min(), aSel.Min()+aStr.Len() );
217 aEdPrintArea.SetRefString( aVal );
218 aEdPrintArea.SetSelection( aNewSel );
219 }
220 else
221 {
222 sal_Bool bRow = ( &aEdRepeatRow == pRefInputEdit );
223 lcl_GetRepeatRangeString(&rRef, pDoc, bRow, aStr);
224 pRefInputEdit->SetRefString( aStr );
225 }
226 }
227
228 Impl_ModifyHdl( pRefInputEdit );
229 }
230
231
232 //----------------------------------------------------------------------------
233
AddRefEntry()234 void ScPrintAreasDlg::AddRefEntry()
235 {
236 if ( pRefInputEdit == &aEdPrintArea )
237 {
238 const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
239 String aVal = aEdPrintArea.GetText();
240 aVal += sep;
241 aEdPrintArea.SetText(aVal);
242
243 xub_StrLen nLen = aVal.Len();
244 aEdPrintArea.SetSelection( Selection( nLen, nLen ) );
245
246 Impl_ModifyHdl( &aEdPrintArea );
247 }
248 }
249
250
251 //----------------------------------------------------------------------------
252
Deactivate()253 void ScPrintAreasDlg::Deactivate()
254 {
255 bDlgLostFocus = sal_True;
256 }
257
258
259 //----------------------------------------------------------------------------
260
SetActive()261 void ScPrintAreasDlg::SetActive()
262 {
263 if ( bDlgLostFocus )
264 {
265 bDlgLostFocus = sal_False;
266
267 if ( pRefInputEdit )
268 {
269 pRefInputEdit->GrabFocus();
270 Impl_ModifyHdl( pRefInputEdit );
271 }
272 }
273 else
274 GrabFocus();
275
276 RefInputDone();
277 }
278
279
280 //----------------------------------------------------------------------------
281
Impl_Reset()282 void ScPrintAreasDlg::Impl_Reset()
283 {
284 String aStrRange;
285 const ScRange* pRepeatColRange = pDoc->GetRepeatColRange( nCurTab );
286 const ScRange* pRepeatRowRange = pDoc->GetRepeatRowRange( nCurTab );
287
288 aEdPrintArea.SetModifyHdl ( HDL(Impl_ModifyHdl) );
289 aEdRepeatRow.SetModifyHdl ( HDL(Impl_ModifyHdl) );
290 aEdRepeatCol.SetModifyHdl ( HDL(Impl_ModifyHdl) );
291 aEdPrintArea.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
292 aEdRepeatRow.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
293 aEdRepeatCol.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
294 aLbPrintArea.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
295 aLbRepeatRow.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
296 aLbRepeatCol.SetGetFocusHdl( HDL(Impl_GetFocusHdl) );
297 aLbPrintArea.SetSelectHdl ( HDL(Impl_SelectHdl) );
298 aLbRepeatRow.SetSelectHdl ( HDL(Impl_SelectHdl) );
299 aLbRepeatCol.SetSelectHdl ( HDL(Impl_SelectHdl) );
300 aBtnOk .SetClickHdl ( HDL(Impl_BtnHdl) );
301 aBtnCancel .SetClickHdl ( HDL(Impl_BtnHdl) );
302
303 Impl_FillLists();
304
305 //-------------------------
306 // Druckbereich
307 //-------------------------
308 aStrRange.Erase();
309 String aOne;
310 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
311 const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
312 sal_uInt16 nRangeCount = pDoc->GetPrintRangeCount( nCurTab );
313 for (sal_uInt16 i=0; i<nRangeCount; i++)
314 {
315 const ScRange* pPrintRange = pDoc->GetPrintRange( nCurTab, i );
316 if (pPrintRange)
317 {
318 if ( aStrRange.Len() )
319 aStrRange += sep;
320 pPrintRange->Format( aOne, SCR_ABS, pDoc, eConv );
321 aStrRange += aOne;
322 }
323 }
324 aEdPrintArea.SetText( aStrRange );
325
326 //-------------------------------
327 // Wiederholungszeile
328 //-------------------------------
329 lcl_GetRepeatRangeString(pRepeatRowRange, pDoc, true, aStrRange);
330 aEdRepeatRow.SetText( aStrRange );
331
332 //--------------------------------
333 // Wiederholungsspalte
334 //--------------------------------
335 lcl_GetRepeatRangeString(pRepeatColRange, pDoc, false, aStrRange);
336 aEdRepeatCol.SetText( aStrRange );
337
338 Impl_ModifyHdl( &aEdPrintArea );
339 Impl_ModifyHdl( &aEdRepeatRow );
340 Impl_ModifyHdl( &aEdRepeatCol );
341 if( pDoc->IsPrintEntireSheet( nCurTab ) )
342 aLbPrintArea.SelectEntryPos( SC_AREASDLG_PR_ENTIRE );
343
344 aEdPrintArea.SaveValue(); // fuer FillItemSet() merken:
345 aEdRepeatRow.SaveValue();
346 aEdRepeatCol.SaveValue();
347 }
348
349
350 //----------------------------------------------------------------------------
351
Impl_GetItem(Edit * pEd,SfxStringItem & rItem)352 sal_Bool ScPrintAreasDlg::Impl_GetItem( Edit* pEd, SfxStringItem& rItem )
353 {
354 String aRangeStr = pEd->GetText();
355 sal_Bool bDataChanged = (pEd->GetSavedValue() != aRangeStr);
356
357 if ( (aRangeStr.Len() > 0) && &aEdPrintArea != pEd )
358 {
359 ScRange aRange;
360 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
361 lcl_CheckRepeatString(aRangeStr, pDoc, &aEdRepeatRow == pEd, &aRange);
362 aRange.Format(aRangeStr, SCR_ABS, pDoc, eConv);
363 }
364
365 rItem.SetValue( aRangeStr );
366
367 return bDataChanged;
368 }
369
370
371 //----------------------------------------------------------------------------
372
Impl_CheckRefStrings()373 sal_Bool ScPrintAreasDlg::Impl_CheckRefStrings()
374 {
375 sal_Bool bOk = sal_False;
376 String aStrPrintArea = aEdPrintArea.GetText();
377 String aStrRepeatRow = aEdRepeatRow.GetText();
378 String aStrRepeatCol = aEdRepeatCol.GetText();
379
380 sal_Bool bPrintAreaOk = sal_True;
381 if ( aStrPrintArea.Len() )
382 {
383 const sal_uInt16 nValidAddr = SCA_VALID | SCA_VALID_ROW | SCA_VALID_COL;
384 const sal_uInt16 nValidRange = nValidAddr | SCA_VALID_ROW2 | SCA_VALID_COL2;
385 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
386 const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
387 // const sal_Unicode rsep = ScCompiler::GetNativeSymbol(ocRange).GetChar(0);
388
389 ScAddress aAddr;
390 ScRange aRange;
391 xub_StrLen nSepCount = aStrPrintArea.GetTokenCount(sep);
392 for ( xub_StrLen i = 0; i < nSepCount && bPrintAreaOk; ++i )
393 {
394 String aOne = aStrPrintArea.GetToken(i, sep);
395 sal_uInt16 nResult = aRange.Parse( aOne, pDoc, eConv );
396 if ((nResult & nValidRange) != nValidRange)
397 {
398 sal_uInt16 nAddrResult = aAddr.Parse( aOne, pDoc, eConv );
399 if ((nAddrResult & nValidAddr) != nValidAddr)
400 bPrintAreaOk = sal_False;
401 }
402 }
403 }
404
405 sal_Bool bRepeatRowOk = (aStrRepeatRow.Len() == 0);
406 if ( !bRepeatRowOk )
407 bRepeatRowOk = lcl_CheckRepeatString(aStrRepeatRow, pDoc, true, NULL);
408
409 sal_Bool bRepeatColOk = (aStrRepeatCol.Len() == 0);
410 if ( !bRepeatColOk )
411 bRepeatColOk = lcl_CheckRepeatString(aStrRepeatCol, pDoc, false, NULL);
412
413 // Fehlermeldungen
414
415 bOk = (bPrintAreaOk && bRepeatRowOk && bRepeatColOk);
416
417 if ( !bOk )
418 {
419 Edit* pEd = NULL;
420
421 if ( !bPrintAreaOk ) pEd = &aEdPrintArea;
422 else if ( !bRepeatRowOk ) pEd = &aEdRepeatRow;
423 else if ( !bRepeatColOk ) pEd = &aEdRepeatCol;
424
425 ERRORBOX( STR_INVALID_TABREF );
426 pEd->GrabFocus();
427 }
428
429 return bOk;
430 }
431
432
433 //----------------------------------------------------------------------------
434
Impl_FillLists()435 void ScPrintAreasDlg::Impl_FillLists()
436 {
437 //------------------------------------------------------
438 // Selektion holen und String in PrintArea-ListBox merken
439 //------------------------------------------------------
440 ScRange aRange;
441 String aStrRange;
442 sal_Bool bSimple = sal_True;
443
444 if ( pViewData )
445 bSimple = (pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE);
446
447 formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
448
449 if ( bSimple )
450 aRange.Format( aStrRange, SCR_ABS, pDoc, eConv );
451 else
452 {
453 ScRangeListRef aList( new ScRangeList );
454 pViewData->GetMarkData().FillRangeListWithMarks( aList, sal_False );
455 aList->Format( aStrRange, SCR_ABS, pDoc, eConv );
456 }
457
458 aLbPrintArea.SetEntryData( SC_AREASDLG_PR_SELECT, new String( aStrRange ) );
459
460 //------------------------------------------------------
461 // Ranges holen und in ListBoxen merken
462 //------------------------------------------------------
463 ScRangeName* pRangeNames = pDoc->GetRangeName();
464 const sal_uInt16 nCount = pRangeNames ? pRangeNames->GetCount() : 0;
465
466 if ( nCount > 0 )
467 {
468 String aName;
469 String aSymbol;
470 // ScRange aRange;
471 ScRangeData* pData = NULL;
472
473 for ( sal_uInt16 i=0; i<nCount; i++ )
474 {
475 pData = (ScRangeData*)(pRangeNames->At( i ));
476 if ( pData )
477 {
478 if ( pData->HasType( RT_ABSAREA )
479 || pData->HasType( RT_REFAREA )
480 || pData->HasType( RT_ABSPOS ) )
481 {
482 pData->GetName( aName );
483 pData->GetSymbol( aSymbol );
484 if ( aRange.ParseAny( aSymbol, pDoc, eConv ) & SCA_VALID )
485 {
486 if ( pData->HasType( RT_PRINTAREA ) )
487 {
488 aRange.Format( aSymbol, SCR_ABS, pDoc, eConv );
489 aLbPrintArea.SetEntryData(
490 aLbPrintArea.InsertEntry( aName ),
491 new String( aSymbol ) );
492 }
493
494 if ( pData->HasType( RT_ROWHEADER ) )
495 {
496 lcl_GetRepeatRangeString(&aRange, pDoc, true, aSymbol);
497 aLbRepeatRow.SetEntryData(
498 aLbRepeatRow.InsertEntry( aName ),
499 new String( aSymbol ) );
500 }
501
502 if ( pData->HasType( RT_COLHEADER ) )
503 {
504 lcl_GetRepeatRangeString(&aRange, pDoc, false, aSymbol);
505 aLbRepeatCol.SetEntryData(
506 aLbRepeatCol.InsertEntry( aName ),
507 new String( aSymbol ) );
508 }
509 }
510 }
511 }
512 }
513 }
514 }
515
516
517 //----------------------------------------------------------------------------
518 // Handler:
519 //----------------------------------------------------------------------------
520
IMPL_LINK(ScPrintAreasDlg,Impl_BtnHdl,PushButton *,pBtn)521 IMPL_LINK( ScPrintAreasDlg, Impl_BtnHdl, PushButton*, pBtn )
522 {
523 if ( &aBtnOk == pBtn )
524 {
525 if ( Impl_CheckRefStrings() )
526 {
527 sal_Bool bDataChanged = sal_False;
528 String aStr;
529 SfxStringItem aPrintArea( SID_CHANGE_PRINTAREA, aStr );
530 SfxStringItem aRepeatRow( FN_PARAM_2, aStr );
531 SfxStringItem aRepeatCol( FN_PARAM_3, aStr );
532
533 //-------------------------
534 // Druckbereich veraendert?
535 //-------------------------
536
537 // first try the list box, if "Entite sheet" is selected
538 sal_Bool bEntireSheet = (aLbPrintArea.GetSelectEntryPos() == SC_AREASDLG_PR_ENTIRE);
539 SfxBoolItem aEntireSheet( FN_PARAM_4, bEntireSheet );
540
541 bDataChanged = bEntireSheet != pDoc->IsPrintEntireSheet( nCurTab );
542 if( !bEntireSheet )
543 {
544 // if new list box selection is not "Entire sheet", get the edit field contents
545 bDataChanged |= Impl_GetItem( &aEdPrintArea, aPrintArea );
546 }
547
548 //-------------------------------
549 // Wiederholungszeile veraendert?
550 //-------------------------------
551 bDataChanged |= Impl_GetItem( &aEdRepeatRow, aRepeatRow );
552
553 //--------------------------------
554 // Wiederholungsspalte veraendert?
555 //--------------------------------
556 bDataChanged |= Impl_GetItem( &aEdRepeatCol, aRepeatCol );
557
558 if ( bDataChanged )
559 {
560 SetDispatcherLock( sal_False );
561 SwitchToDocument();
562 GetBindings().GetDispatcher()->Execute( SID_CHANGE_PRINTAREA,
563 SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
564 &aPrintArea, &aRepeatRow, &aRepeatCol, &aEntireSheet, 0L );
565 }
566
567 Close();
568 }
569 }
570 else if ( &aBtnCancel == pBtn )
571 Close();
572
573 return 0;
574 }
575
576
577 //----------------------------------------------------------------------------
578
IMPL_LINK(ScPrintAreasDlg,Impl_GetFocusHdl,Control *,pCtr)579 IMPL_LINK( ScPrintAreasDlg, Impl_GetFocusHdl, Control*, pCtr )
580 {
581 if ( pCtr ==(Control *) &aEdPrintArea ||
582 pCtr ==(Control *) &aEdRepeatRow ||
583 pCtr ==(Control *) &aEdRepeatCol)
584 {
585 pRefInputEdit = (formula::RefEdit*) pCtr;
586 }
587 else if ( pCtr ==(Control *) &aLbPrintArea)
588 {
589 pRefInputEdit = &aEdPrintArea;
590 }
591 else if ( pCtr ==(Control *) &aLbRepeatRow)
592 {
593 pRefInputEdit = &aEdRepeatRow;
594 }
595 else if ( pCtr ==(Control *) &aLbRepeatCol)
596 {
597 pRefInputEdit = &aEdRepeatCol;
598 }
599
600 return 0;
601 }
602
603
604 //----------------------------------------------------------------------------
605
IMPL_LINK(ScPrintAreasDlg,Impl_SelectHdl,ListBox *,pLb)606 IMPL_LINK( ScPrintAreasDlg, Impl_SelectHdl, ListBox*, pLb )
607 {
608 sal_uInt16 nSelPos = pLb->GetSelectEntryPos();
609 Edit* pEd = NULL;
610
611 // list box positions of specific entries, default to "repeat row/column" list boxes
612 sal_uInt16 nAllSheetPos = SC_AREASDLG_RR_NONE;
613 sal_uInt16 nUserDefPos = SC_AREASDLG_RR_USER;
614 sal_uInt16 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
615
616 // find edit field for list box, and list box positions
617 if( pLb == &aLbPrintArea )
618 {
619 pEd = &aEdPrintArea;
620 nAllSheetPos = SC_AREASDLG_PR_ENTIRE;
621 nUserDefPos = SC_AREASDLG_PR_USER;
622 nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
623 }
624 else if( pLb == &aLbRepeatCol )
625 pEd = &aEdRepeatCol;
626 else if( pLb == &aLbRepeatRow )
627 pEd = &aEdRepeatRow;
628 else
629 return 0;
630
631 // fill edit field according to list box selection
632 if( (nSelPos == 0) || (nSelPos == nAllSheetPos) )
633 pEd->SetText( EMPTY_STRING );
634 else if( nSelPos == nUserDefPos && !pLb->IsTravelSelect() && pEd->GetText().Len() == 0 )
635 pLb->SelectEntryPos( 0 );
636 else if( nSelPos >= nFirstCustomPos )
637 pEd->SetText( *static_cast< String* >( pLb->GetEntryData( nSelPos ) ) );
638
639 return 0;
640 }
641
642
643 //----------------------------------------------------------------------------
644
IMPL_LINK(ScPrintAreasDlg,Impl_ModifyHdl,formula::RefEdit *,pEd)645 IMPL_LINK( ScPrintAreasDlg, Impl_ModifyHdl, formula::RefEdit*, pEd )
646 {
647 ListBox* pLb = NULL;
648
649 // list box positions of specific entries, default to "repeat row/column" list boxes
650 sal_uInt16 nUserDefPos = SC_AREASDLG_RR_USER;
651 sal_uInt16 nFirstCustomPos = SC_AREASDLG_RR_OFFSET;
652
653 if( pEd == &aEdPrintArea )
654 {
655 pLb = &aLbPrintArea;
656 nUserDefPos = SC_AREASDLG_PR_USER;
657 nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following
658 }
659 else if( pEd == &aEdRepeatCol )
660 pLb = &aLbRepeatCol;
661 else if( pEd == &aEdRepeatRow )
662 pLb = &aLbRepeatRow;
663 else
664 return 0;
665
666 // set list box selection according to edit field
667 sal_uInt16 nEntryCount = pLb->GetEntryCount();
668 String aStrEd( pEd->GetText() );
669 String aEdUpper = aStrEd;
670 aEdUpper.ToUpperAscii();
671
672 if ( (nEntryCount > nFirstCustomPos) && aStrEd.Len() > 0 )
673 {
674 sal_Bool bFound = sal_False;
675 String* pSymbol = NULL;
676 sal_uInt16 i;
677
678 for ( i=nFirstCustomPos; i<nEntryCount && !bFound; i++ )
679 {
680 pSymbol = (String*)pLb->GetEntryData( i );
681 bFound = ( (*pSymbol == aStrEd) || (*pSymbol == aEdUpper) );
682 }
683
684 pLb->SelectEntryPos( bFound ? i-1 : nUserDefPos );
685 }
686 else
687 pLb->SelectEntryPos( aStrEd.Len() ? nUserDefPos : 0 );
688
689 return 0;
690 }
691
692
693 //============================================================================
694 // globale Funktionen:
695
696 // ----------------------------------------------------------------------------
697
698 // TODO: It might make sense to move these functions to address.?xx. -kohei
699
lcl_CheckOne_OOO(const String & rStr,bool bIsRow,SCCOLROW & rVal)700 bool lcl_CheckOne_OOO( const String& rStr, bool bIsRow, SCCOLROW& rVal )
701 {
702 // Zulaessige Syntax fuer rStr:
703 // Row: [$]1-MAXTAB
704 // Col: [$]A-IV
705
706 String aStr = rStr;
707 xub_StrLen nLen = aStr.Len();
708 SCCOLROW nNum = 0;
709 sal_Bool bStrOk = ( nLen > 0 ) && ( bIsRow ? ( nLen < 6 ) : ( nLen < 4 ) );
710
711 if ( bStrOk )
712 {
713 if ( '$' == aStr.GetChar(0) )
714 aStr.Erase( 0, 1 );
715
716 if ( bIsRow )
717 {
718 bStrOk = CharClass::isAsciiNumeric(aStr);
719
720 if ( bStrOk )
721 {
722 sal_Int32 n = aStr.ToInt32();
723
724 if ( ( bStrOk = (n > 0) && ( n <= MAXROWCOUNT ) ) != sal_False )
725 nNum = static_cast<SCCOLROW>(n - 1);
726 }
727 }
728 else
729 {
730 SCCOL nCol = 0;
731 bStrOk = ::AlphaToCol( nCol, aStr);
732 nNum = nCol;
733 }
734 }
735
736 if ( bStrOk )
737 rVal = nNum;
738
739 return bStrOk;
740 }
741
lcl_CheckOne_XL_A1(const String & rStr,bool bIsRow,SCCOLROW & rVal)742 bool lcl_CheckOne_XL_A1( const String& rStr, bool bIsRow, SCCOLROW& rVal )
743 {
744 // XL A1 style is identical to OOO one for print range formats.
745 return lcl_CheckOne_OOO(rStr, bIsRow, rVal);
746 }
747
lcl_CheckOne_XL_R1C1(const String & rStr,bool bIsRow,SCCOLROW & rVal)748 bool lcl_CheckOne_XL_R1C1( const String& rStr, bool bIsRow, SCCOLROW& rVal )
749 {
750 xub_StrLen nLen = rStr.Len();
751 if (nLen <= 1)
752 // There must be at least two characters.
753 return false;
754
755 const sal_Unicode preUpper = bIsRow ? 'R' : 'C';
756 const sal_Unicode preLower = bIsRow ? 'r' : 'c';
757 if (rStr.GetChar(0) != preUpper && rStr.GetChar(0) != preLower)
758 return false;
759
760 String aNumStr = rStr.Copy(1);
761 if (!CharClass::isAsciiNumeric(aNumStr))
762 return false;
763
764 sal_Int32 nNum = aNumStr.ToInt32();
765
766 if (nNum <= 0)
767 return false;
768
769 if ((bIsRow && nNum > MAXROWCOUNT) || (!bIsRow && nNum > MAXCOLCOUNT))
770 return false;
771
772 rVal = static_cast<SCCOLROW>(nNum-1);
773 return true;
774 }
775
lcl_CheckRepeatOne(const String & rStr,formula::FormulaGrammar::AddressConvention eConv,bool bIsRow,SCCOLROW & rVal)776 bool lcl_CheckRepeatOne( const String& rStr, formula::FormulaGrammar::AddressConvention eConv, bool bIsRow, SCCOLROW& rVal )
777 {
778 switch (eConv)
779 {
780 case formula::FormulaGrammar::CONV_OOO:
781 return lcl_CheckOne_OOO(rStr, bIsRow, rVal);
782 case formula::FormulaGrammar::CONV_XL_A1:
783 return lcl_CheckOne_XL_A1(rStr, bIsRow, rVal);
784 case formula::FormulaGrammar::CONV_XL_R1C1:
785 return lcl_CheckOne_XL_R1C1(rStr, bIsRow, rVal);
786 default:
787 {
788 // added to avoid warnings
789 }
790 }
791 return false;
792 }
793
lcl_CheckRepeatString(const String & rStr,ScDocument * pDoc,bool bIsRow,ScRange * pRange)794 bool lcl_CheckRepeatString( const String& rStr, ScDocument* pDoc, bool bIsRow, ScRange* pRange )
795 {
796 // Row: [valid row] rsep [valid row]
797 // Col: [valid col] rsep [valid col]
798
799 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
800 const sal_Unicode rsep = ScCompiler::GetNativeSymbol(ocRange).GetChar(0);
801
802 if (pRange)
803 {
804 // initialize the range value.
805 pRange->aStart.SetCol(0);
806 pRange->aStart.SetRow(0);
807 pRange->aEnd.SetCol(0);
808 pRange->aEnd.SetRow(0);
809 }
810
811 String aBuf;
812 SCCOLROW nVal = 0;
813 xub_StrLen nLen = rStr.Len();
814 bool bEndPos = false;
815 for (xub_StrLen i = 0; i < nLen; ++i)
816 {
817 const sal_Unicode c = rStr.GetChar(i);
818 if (c == rsep)
819 {
820 if (bEndPos)
821 // We aren't supposed to have more than one range separator.
822 return false;
823
824 // range separator
825 if (aBuf.Len() == 0)
826 return false;
827
828 bool bRes = lcl_CheckRepeatOne(aBuf, eConv, bIsRow, nVal);
829 if (!bRes)
830 return false;
831
832 if (pRange)
833 {
834 if (bIsRow)
835 {
836 pRange->aStart.SetRow(static_cast<SCROW>(nVal));
837 pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
838 }
839 else
840 {
841 pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
842 pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
843 }
844 }
845
846 aBuf.Erase();
847 bEndPos = true;
848 }
849 else
850 aBuf.Append(c);
851 }
852
853 if (aBuf.Len() > 0)
854 {
855 bool bRes = lcl_CheckRepeatOne(aBuf, eConv, bIsRow, nVal);
856 if (!bRes)
857 return false;
858
859 if (pRange)
860 {
861 if (bIsRow)
862 {
863 if (!bEndPos)
864 pRange->aStart.SetRow(static_cast<SCROW>(nVal));
865 pRange->aEnd.SetRow(static_cast<SCROW>(nVal));
866 }
867 else
868 {
869 if (!bEndPos)
870 pRange->aStart.SetCol(static_cast<SCCOL>(nVal));
871 pRange->aEnd.SetCol(static_cast<SCCOL>(nVal));
872 }
873 }
874 }
875
876 return true;
877 }
878
879 // ----------------------------------------------------------------------------
880
lcl_GetRepeatRangeString(const ScRange * pRange,ScDocument * pDoc,bool bIsRow,String & rStr)881 void lcl_GetRepeatRangeString( const ScRange* pRange, ScDocument* pDoc, bool bIsRow, String& rStr )
882 {
883 rStr.Erase();
884 if (!pRange)
885 return;
886
887 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
888 const ScAddress& rStart = pRange->aStart;
889 const ScAddress& rEnd = pRange->aEnd;
890
891 const sal_uInt16 nFmt = bIsRow ? (SCA_VALID_ROW | SCA_ROW_ABSOLUTE) : (SCA_VALID_COL | SCA_COL_ABSOLUTE);
892 String aTmpStr;
893 rStart.Format(aTmpStr, nFmt, pDoc, eConv);
894 rStr += aTmpStr;
895 if ((bIsRow && rStart.Row() != rEnd.Row()) || (!bIsRow && rStart.Col() != rEnd.Col()))
896 {
897 rStr += ScCompiler::GetNativeSymbol(ocRange);
898 rEnd.Format(aTmpStr, nFmt, pDoc, eConv);
899 rStr += aTmpStr;
900 }
901 }
902
903