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