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