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