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