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