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 35 #include "rangelst.hxx" 36 #include <sfx2/app.hxx> 37 #include <sfx2/viewsh.hxx> 38 #include <vcl/wrkwin.hxx> 39 #include <vcl/mnemonic.hxx> 40 #include <tools/shl.hxx> 41 #include <svtools/taskbar.hxx> 42 #include <sfx2/bindings.hxx> 43 #include <sfx2/dispatch.hxx> 44 45 46 #define ANYREFDG_CXX 47 #include "anyrefdg.hxx" 48 #undef ANYREFDG_CXX 49 50 #include "sc.hrc" 51 #include "inputhdl.hxx" 52 #include "scmod.hxx" 53 #include "scresid.hxx" 54 #include "inputwin.hxx" 55 #include "tabvwsh.hxx" 56 #include "docsh.hxx" 57 #include "rfindlst.hxx" 58 #include "compiler.hxx" 59 #include "cell.hxx" 60 #include "global.hxx" 61 #include "inputopt.hxx" 62 #include "rangeutl.hxx" 63 64 65 ScFormulaReferenceHelper::ScFormulaReferenceHelper(IAnyRefDialog* _pDlg,SfxBindings* _pBindings) 66 : m_pDlg(_pDlg) 67 , pRefEdit (NULL) 68 , m_pWindow(NULL) 69 , m_pBindings(_pBindings) 70 , pAccel( NULL ) 71 , pHiddenMarks(NULL) 72 , nRefTab(0) 73 , bHighLightRef( sal_False ) 74 , bAccInserted( sal_False ) 75 { 76 ScInputOptions aInputOption=SC_MOD()->GetInputOptions(); 77 bEnableColorRef=aInputOption.GetRangeFinder(); 78 } 79 // ----------------------------------------------------------------------------- 80 ScFormulaReferenceHelper::~ScFormulaReferenceHelper() 81 { 82 if (bAccInserted) 83 Application::RemoveAccel( pAccel.get() ); 84 85 // common cleanup for ScAnyRefDlg and ScFormulaDlg is done here 86 87 HideReference(); 88 enableInput( sal_True ); 89 90 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl(); 91 if ( pInputHdl ) 92 pInputHdl->ResetDelayTimer(); // stop the timer for disabling the input line 93 } 94 // ----------------------------------------------------------------------------- 95 void ScFormulaReferenceHelper::enableInput( sal_Bool bEnable ) 96 { 97 TypeId aType(TYPE(ScDocShell)); 98 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType); 99 while( pDocShell ) 100 { 101 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell ); 102 while( pFrame ) 103 { 104 // #71577# enable everything except InPlace, including bean frames 105 if ( !pFrame->GetFrame().IsInPlace() ) 106 { 107 SfxViewShell* p = pFrame->GetViewShell(); 108 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); 109 if(pViewSh!=NULL) 110 { 111 Window *pWin=pViewSh->GetWindow(); 112 if(pWin) 113 { 114 Window *pParent=pWin->GetParent(); 115 if(pParent) 116 { 117 pParent->EnableInput(bEnable,sal_True /* sal_False */); 118 if(sal_True /*bChilds*/) 119 pViewSh->EnableRefInput(bEnable); 120 } 121 } 122 } 123 } 124 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell ); 125 } 126 127 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType); 128 } 129 } 130 // ----------------------------------------------------------------------------- 131 void ScFormulaReferenceHelper::ShowSimpleReference( const XubString& rStr ) 132 { 133 if( /*!pRefEdit &&*/ bEnableColorRef ) 134 { 135 bHighLightRef=sal_True; 136 ScViewData* pViewData=ScDocShell::GetViewData(); 137 if ( pViewData ) 138 { 139 ScDocument* pDoc=pViewData->GetDocument(); 140 ScTabViewShell* pTabViewShell=pViewData->GetViewShell(); 141 142 ScRangeList aRangeList; 143 144 pTabViewShell->DoneRefMode( sal_False ); 145 pTabViewShell->ClearHighlightRanges(); 146 147 if( ParseWithNames( aRangeList, rStr, pDoc ) ) 148 { 149 ScRange* pRangeEntry = aRangeList.First(); 150 151 sal_uInt16 nIndex=0; 152 while(pRangeEntry != NULL) 153 { 154 ColorData aColName = ScRangeFindList::GetColorName(nIndex++); 155 pTabViewShell->AddHighlightRange(*pRangeEntry, aColName); 156 157 pRangeEntry = aRangeList.Next(); 158 } 159 } 160 } 161 } 162 } 163 // ----------------------------------------------------------------------------- 164 bool ScFormulaReferenceHelper::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc ) 165 { 166 bool bError = false; 167 rRanges.RemoveAll(); 168 169 ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0); 170 ScRangeUtil aRangeUtil; 171 xub_StrLen nTokenCnt = rStr.GetTokenCount(); 172 for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken ) 173 { 174 ScRange aRange; 175 String aRangeStr( rStr.GetToken( nToken ) ); 176 177 sal_uInt16 nFlags = aRange.ParseAny( aRangeStr, pDoc, aDetails ); 178 if ( nFlags & SCA_VALID ) 179 { 180 if ( (nFlags & SCA_TAB_3D) == 0 ) 181 aRange.aStart.SetTab( nRefTab ); 182 if ( (nFlags & SCA_TAB2_3D) == 0 ) 183 aRange.aEnd.SetTab( aRange.aStart.Tab() ); 184 rRanges.Append( aRange ); 185 } 186 else if ( aRangeUtil.MakeRangeFromName( aRangeStr, pDoc, nRefTab, aRange, RUTL_NAMES, aDetails ) ) 187 rRanges.Append( aRange ); 188 else 189 bError = true; 190 } 191 192 return !bError; 193 } 194 // ----------------------------------------------------------------------------- 195 void ScFormulaReferenceHelper::ShowFormulaReference( const XubString& rStr ) 196 { 197 if( /*!pRefEdit &&*/ bEnableColorRef) 198 { 199 bHighLightRef=sal_True; 200 ScViewData* pViewData=ScDocShell::GetViewData(); 201 if ( pViewData && pRefComp.get() ) 202 { 203 ScTabViewShell* pTabViewShell=pViewData->GetViewShell(); 204 SCCOL nCol = pViewData->GetCurX(); 205 SCROW nRow = pViewData->GetCurY(); 206 SCTAB nTab = pViewData->GetTabNo(); 207 ScAddress aPos( nCol, nRow, nTab ); 208 209 ScTokenArray* pScTokA=pRefComp->CompileString(rStr); 210 //pRefComp->CompileTokenArray(); 211 212 if(pTabViewShell!=NULL && pScTokA!=NULL) 213 { 214 pTabViewShell->DoneRefMode( sal_False ); 215 pTabViewShell->ClearHighlightRanges(); 216 217 pScTokA->Reset(); 218 const ScToken* pToken = static_cast<const ScToken*>(pScTokA->GetNextReference()); 219 220 sal_uInt16 nIndex=0; 221 222 while(pToken!=NULL) 223 { 224 sal_Bool bDoubleRef=(pToken->GetType()==formula::svDoubleRef); 225 226 227 if(pToken->GetType()==formula::svSingleRef || bDoubleRef) 228 { 229 ScRange aRange; 230 if(bDoubleRef) 231 { 232 ScComplexRefData aRef( pToken->GetDoubleRef() ); 233 aRef.CalcAbsIfRel( aPos ); 234 aRange.aStart.Set( aRef.Ref1.nCol, aRef.Ref1.nRow, aRef.Ref1.nTab ); 235 aRange.aEnd.Set( aRef.Ref2.nCol, aRef.Ref2.nRow, aRef.Ref2.nTab ); 236 } 237 else 238 { 239 ScSingleRefData aRef( pToken->GetSingleRef() ); 240 aRef.CalcAbsIfRel( aPos ); 241 aRange.aStart.Set( aRef.nCol, aRef.nRow, aRef.nTab ); 242 aRange.aEnd = aRange.aStart; 243 } 244 ColorData aColName=ScRangeFindList::GetColorName(nIndex++); 245 pTabViewShell->AddHighlightRange(aRange, aColName); 246 } 247 248 pToken = static_cast<const ScToken*>(pScTokA->GetNextReference()); 249 } 250 } 251 if(pScTokA!=NULL) delete pScTokA; 252 } 253 } 254 } 255 // ----------------------------------------------------------------------------- 256 void ScFormulaReferenceHelper::HideReference( sal_Bool bDoneRefMode ) 257 { 258 ScViewData* pViewData=ScDocShell::GetViewData(); 259 260 if( pViewData && /*!pRefEdit &&*/ bHighLightRef && bEnableColorRef) 261 { 262 ScTabViewShell* pTabViewShell=pViewData->GetViewShell(); 263 264 if(pTabViewShell!=NULL) 265 { 266 // bDoneRefMode is sal_False when called from before SetReference. 267 // In that case, RefMode was just started and must not be ended now. 268 269 if ( bDoneRefMode ) 270 pTabViewShell->DoneRefMode( sal_False ); 271 pTabViewShell->ClearHighlightRanges(); 272 } 273 bHighLightRef=sal_False; 274 } 275 } 276 // ----------------------------------------------------------------------------- 277 void ScFormulaReferenceHelper::ShowReference( const XubString& rStr ) 278 { 279 if( /*!pRefEdit &&*/ bEnableColorRef ) 280 { 281 if( rStr.Search('(')!=STRING_NOTFOUND || 282 rStr.Search('+')!=STRING_NOTFOUND || 283 rStr.Search('*')!=STRING_NOTFOUND || 284 rStr.Search('-')!=STRING_NOTFOUND || 285 rStr.Search('/')!=STRING_NOTFOUND || 286 rStr.Search('&')!=STRING_NOTFOUND || 287 rStr.Search('<')!=STRING_NOTFOUND || 288 rStr.Search('>')!=STRING_NOTFOUND || 289 rStr.Search('=')!=STRING_NOTFOUND || 290 rStr.Search('^')!=STRING_NOTFOUND) 291 { 292 ShowFormulaReference(rStr); 293 } 294 else 295 { 296 ShowSimpleReference(rStr); 297 } 298 } 299 } 300 // ----------------------------------------------------------------------------- 301 void ScFormulaReferenceHelper::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton ) 302 { 303 if( !pRefEdit && pEdit ) 304 { 305 m_pDlg->RefInputStart( pEdit, pButton ); 306 // if( pRefEdit ) 307 // pRefEdit->SilentGrabFocus(); 308 } 309 310 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 311 if( pViewShell ) 312 { 313 pViewShell->ActiveGrabFocus(); 314 if( pRefEdit ) 315 { 316 const ScViewData* pViewData = pViewShell->GetViewData(); 317 ScDocument* pDoc = pViewData->GetDocument(); 318 ScRangeList aRangeList; 319 if( ParseWithNames( aRangeList, pRefEdit->GetText(), pDoc ) ) 320 { 321 const ScRange* pRange = aRangeList.GetObject( 0 ); 322 if( pRange ) 323 { 324 pViewShell->SetTabNo( pRange->aStart.Tab() ); 325 pViewShell->MoveCursorAbs( pRange->aStart.Col(), 326 pRange->aStart.Row(), SC_FOLLOW_JUMP, sal_False, sal_False ); 327 pViewShell->MoveCursorAbs( pRange->aEnd.Col(), 328 pRange->aEnd.Row(), SC_FOLLOW_JUMP, sal_True, sal_False ); 329 m_pDlg->SetReference( *pRange, pDoc ); 330 } 331 } 332 } 333 } 334 } 335 // ----------------------------------------------------------------------------- 336 void ScFormulaReferenceHelper::Init() 337 { 338 ScViewData* pViewData=ScDocShell::GetViewData(); //! use pScViewShell? 339 if ( pViewData ) 340 { 341 ScDocument* pDoc = pViewData->GetDocument(); 342 SCCOL nCol = pViewData->GetCurX(); 343 SCROW nRow = pViewData->GetCurY(); 344 SCTAB nTab = pViewData->GetTabNo(); 345 ScAddress aCursorPos( nCol, nRow, nTab ); 346 347 String rStrExp; 348 pRefCell.reset( new ScFormulaCell( pDoc, aCursorPos, rStrExp ) ); 349 pRefComp.reset( new ScCompiler( pDoc, aCursorPos) ); 350 pRefComp->SetGrammar( pDoc->GetGrammar() ); 351 pRefComp->SetCompileForFAP(sal_True); 352 353 nRefTab = nTab; 354 } // if ( pViewData ) 355 } 356 // ----------------------------------------------------------------------------- 357 IMPL_LINK( ScFormulaReferenceHelper, AccelSelectHdl, Accelerator *, pSelAccel ) 358 { 359 if ( !pSelAccel ) 360 return 0; 361 362 switch ( pSelAccel->GetCurKeyCode().GetCode() ) 363 { 364 case KEY_RETURN: 365 case KEY_ESCAPE: 366 if( pRefEdit ) 367 pRefEdit->GrabFocus(); 368 m_pDlg->RefInputDone( sal_True ); 369 break; 370 } 371 return sal_True; 372 } 373 //---------------------------------------------------------------------------- 374 void ScFormulaReferenceHelper::RefInputDone( sal_Bool bForced ) 375 { 376 //<!--Modified by PengYunQuan for Validity Cell Range Picker 377 //if (pRefEdit && (bForced || !pRefBtn)) 378 if ( CanInputDone( bForced ) )//if (pRefEdit && (bForced || !pRefBtn)) 379 //-->Modified by PengYunQuan for Validity Cell Range Picker 380 { 381 if (bAccInserted) // Accelerator wieder abschalten 382 { 383 Application::RemoveAccel( pAccel.get() ); 384 bAccInserted = sal_False; 385 } 386 387 // Fenstertitel anpassen 388 m_pWindow->SetText(sOldDialogText); 389 390 // Fenster wieder gross 391 m_pWindow->SetOutputSizePixel(aOldDialogSize); 392 393 // pEditCell an alte Position 394 pRefEdit->SetPosSizePixel(aOldEditPos, aOldEditSize); 395 396 // set button position and image 397 if( pRefBtn ) 398 { 399 pRefBtn->SetPosPixel( aOldButtonPos ); 400 pRefBtn->SetStartImage(); 401 } 402 403 // Alle anderen: Show(); 404 sal_uInt16 nChildren = m_pWindow->GetChildCount(); 405 for ( sal_uInt16 i = 0; i < nChildren; i++ ) 406 if (pHiddenMarks[i]) 407 { 408 m_pWindow->GetChild(i)->GetWindow( WINDOW_CLIENT )->Show(); 409 } 410 delete [] pHiddenMarks; 411 412 pRefEdit = NULL; 413 pRefBtn = NULL; 414 } 415 } 416 // ----------------------------------------------------------------------------- 417 void ScFormulaReferenceHelper::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton ) 418 { 419 if (!pRefEdit) 420 { 421 pRefEdit = pEdit; 422 pRefBtn = pButton; 423 424 // Neuen Fenstertitel basteln 425 String sNewDialogText; 426 sOldDialogText = m_pWindow->GetText(); 427 sNewDialogText = sOldDialogText; 428 sNewDialogText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " )); 429 430 // Alle Elemente ausser EditCell und Button verstecken 431 sal_uInt16 nChildren = m_pWindow->GetChildCount(); 432 pHiddenMarks = new sal_Bool [nChildren]; 433 for (sal_uInt16 i = 0; i < nChildren; i++) 434 { 435 pHiddenMarks[i] = sal_False; 436 Window* pWin = m_pWindow->GetChild(i); 437 pWin = pWin->GetWindow( WINDOW_CLIENT ); 438 if (pWin == (Window*)pRefEdit) 439 { 440 sNewDialogText += m_pWindow->GetChild(i-1)->GetWindow( WINDOW_CLIENT )->GetText(); 441 } 442 else if (pWin == (Window*)pRefBtn) 443 ; // do nothing 444 else if (pWin->IsVisible()) 445 { 446 pHiddenMarks[i] = sal_True; 447 pWin->Hide(); 448 } 449 } 450 451 // Alte Daten merken 452 aOldDialogSize = m_pWindow->GetOutputSizePixel(); 453 aOldEditPos = pRefEdit->GetPosPixel(); 454 aOldEditSize = pRefEdit->GetSizePixel(); 455 if (pRefBtn) 456 aOldButtonPos = pRefBtn->GetPosPixel(); 457 458 // Edit-Feld verschieben und anpassen 459 Size aNewDlgSize(aOldDialogSize.Width(), aOldEditSize.Height()); 460 Size aNewEditSize(aNewDlgSize); 461 long nOffset = 0; 462 if (pRefBtn) 463 { 464 aNewEditSize.Width() -= pRefBtn->GetSizePixel().Width(); 465 aNewEditSize.Width() -= aOldButtonPos.X() - (aOldEditPos.X()+aOldEditSize.Width()); 466 467 long nHeight = pRefBtn->GetSizePixel().Height(); 468 if ( nHeight > aOldEditSize.Height() ) 469 { 470 aNewDlgSize.Height() = nHeight; 471 nOffset = (nHeight-aOldEditSize.Height()) / 2; 472 } 473 aNewEditSize.Width() -= nOffset; 474 } 475 pRefEdit->SetPosSizePixel(Point(nOffset, nOffset), aNewEditSize); 476 477 // set button position and image 478 if( pRefBtn ) 479 { 480 pRefBtn->SetPosPixel( Point( aOldDialogSize.Width() - pRefBtn->GetSizePixel().Width(), 0 ) ); 481 pRefBtn->SetEndImage(); 482 } 483 484 // Fenster verkleinern 485 m_pWindow->SetOutputSizePixel(aNewDlgSize); 486 487 // Fenstertitel anpassen 488 m_pWindow->SetText( MnemonicGenerator::EraseAllMnemonicChars( sNewDialogText ) ); 489 490 // if ( pButton ) // ueber den Button: Enter und Escape abfangen 491 // { 492 if (!pAccel.get()) 493 { 494 pAccel.reset( new Accelerator ); 495 pAccel->InsertItem( 1, KeyCode( KEY_RETURN ) ); 496 pAccel->InsertItem( 2, KeyCode( KEY_ESCAPE ) ); 497 pAccel->SetSelectHdl( LINK( this, ScFormulaReferenceHelper, AccelSelectHdl ) ); 498 } 499 Application::InsertAccel( pAccel.get() ); 500 bAccInserted = sal_True; 501 // } 502 } 503 } 504 // ----------------------------------------------------------------------------- 505 void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton ) 506 { 507 if( pEdit ) 508 { 509 if( pRefEdit == pEdit ) // is this the active ref edit field? 510 { 511 pRefEdit->GrabFocus(); // before RefInputDone() 512 m_pDlg->RefInputDone( sal_True ); // finish ref input 513 } 514 else 515 { 516 m_pDlg->RefInputDone( sal_True ); // another active ref edit? 517 m_pDlg->RefInputStart( pEdit, pButton ); // start ref input 518 // pRefEdit might differ from pEdit after RefInputStart() (i.e. ScFormulaDlg) 519 if( pRefEdit ) 520 pRefEdit->GrabFocus(); 521 } 522 } 523 } 524 // ----------------------------------------------------------------------------- 525 sal_Bool ScFormulaReferenceHelper::DoClose( sal_uInt16 nId ) 526 { 527 SfxApplication* pSfxApp = SFX_APP(); 528 529 SetDispatcherLock( sal_False ); //! here and in dtor ? 530 531 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 532 if ( pViewFrm && pViewFrm->HasChildWindow(FID_INPUTLINE_STATUS) ) 533 { 534 // Die Eingabezeile wird per ToolBox::Disable disabled, muss darum auch 535 // per ToolBox::Enable wieder aktiviert werden (vor dem Enable des AppWindow), 536 // damit die Buttons auch wieder enabled gezeichnet werden. 537 SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_INPUTLINE_STATUS); 538 if (pChild) 539 { 540 ScInputWindow* pWin = (ScInputWindow*)pChild->GetWindow(); 541 pWin->Enable(); 542 } 543 } 544 545 // find parent view frame to close dialog 546 SfxViewFrame* pMyViewFrm = NULL; 547 if ( m_pBindings ) 548 { 549 SfxDispatcher* pMyDisp = m_pBindings->GetDispatcher(); 550 if (pMyDisp) 551 pMyViewFrm = pMyDisp->GetFrame(); 552 } 553 SC_MOD()->SetRefDialog( nId, sal_False, pMyViewFrm ); 554 555 pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) ); 556 557 ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell(); 558 if ( pScViewShell ) 559 pScViewShell->UpdateInputHandler(sal_True); 560 561 return sal_True; 562 } 563 void ScFormulaReferenceHelper::SetDispatcherLock( sal_Bool bLock ) 564 { 565 // lock / unlock only the dispatchers of Calc documents 566 567 TypeId aType(TYPE(ScDocShell)); 568 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType); 569 while( pDocShell ) 570 { 571 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell ); 572 while( pFrame ) 573 { 574 SfxDispatcher* pDisp = pFrame->GetDispatcher(); 575 if (pDisp) 576 pDisp->Lock( bLock ); 577 578 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell ); 579 } 580 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType); 581 } 582 583 // if a new view is created while the dialog is open, 584 // that view's dispatcher is locked when trying to create the dialog 585 // for that view (ScTabViewShell::CreateRefDialog) 586 } 587 // ----------------------------------------------------------------------------- 588 void ScFormulaReferenceHelper::ViewShellChanged(ScTabViewShell* /* pScViewShell */) 589 { 590 enableInput( sal_False ); 591 592 EnableSpreadsheets(); 593 } 594 void ScFormulaReferenceHelper::EnableSpreadsheets(sal_Bool bFlag, sal_Bool bChilds) 595 { 596 TypeId aType(TYPE(ScDocShell)); 597 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType); 598 while( pDocShell ) 599 { 600 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell ); 601 while( pFrame ) 602 { 603 // #71577# enable everything except InPlace, including bean frames 604 if ( !pFrame->GetFrame().IsInPlace() ) 605 { 606 SfxViewShell* p = pFrame->GetViewShell(); 607 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); 608 if(pViewSh!=NULL) 609 { 610 Window *pWin=pViewSh->GetWindow(); 611 if(pWin) 612 { 613 Window *pParent=pWin->GetParent(); 614 if(pParent) 615 { 616 pParent->EnableInput(bFlag,sal_False); 617 if(bChilds) 618 pViewSh->EnableRefInput(bFlag); 619 } 620 } 621 } 622 } 623 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell ); 624 } 625 626 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType); 627 } 628 } 629 630 //---------------------------------------------------------------------------- 631 632 633 634 void lcl_InvalidateWindows() 635 { 636 TypeId aType(TYPE(ScDocShell)); 637 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType); 638 while( pDocShell ) 639 { 640 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell ); 641 while( pFrame ) 642 { 643 // #71577# enable everything except InPlace, including bean frames 644 if ( !pFrame->GetFrame().IsInPlace() ) 645 { 646 SfxViewShell* p = pFrame->GetViewShell(); 647 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); 648 if(pViewSh!=NULL) 649 { 650 Window *pWin=pViewSh->GetWindow(); 651 if(pWin) 652 { 653 Window *pParent=pWin->GetParent(); 654 if(pParent) 655 pParent->Invalidate(); 656 } 657 } 658 } 659 pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell ); 660 } 661 662 pDocShell = (ScDocShell*)SfxObjectShell::GetNext(*pDocShell, &aType); 663 } 664 } 665 //---------------------------------------------------------------------------- 666 667 void lcl_HideAllReferences() 668 { 669 TypeId aScType = TYPE(ScTabViewShell); 670 SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType ); 671 while ( pSh ) 672 { 673 ((ScTabViewShell*)pSh)->ClearHighlightRanges(); 674 pSh = SfxViewShell::GetNext( *pSh, &aScType ); 675 } 676 } 677 678 //============================================================================ 679 //The class of ScAnyRefDlg is rewritten by PengYunQuan for Validity Cell Range Picker 680 // class ScRefHandler 681 //---------------------------------------------------------------------------- 682 683 ScRefHandler::ScRefHandler( Window &rWindow, SfxBindings* pB/*, SfxChildWindow* pCW, 684 Window* pParent, sal_uInt16 nResId*/, bool bBindRef ) 685 : //SfxModelessDialog ( pB, pCW, pParent, ScResId( nResId ) ), 686 m_rWindow( rWindow ), 687 m_bInRefMode( false ), 688 m_aHelper(this,pB), 689 pMyBindings( pB ), 690 pActiveWin(NULL) 691 { 692 m_aHelper.SetWindow(/*this*/&m_rWindow); 693 if(m_rWindow.GetHelpId().getLength()==0) //Hack, da im SfxModelessDialog die HelpId 694 m_rWindow.SetHelpId(m_rWindow.GetUniqueId()); //fuer einen ModelessDialog entfernt und 695 //in eine UniqueId gewandelt wird, machen 696 //wir das an dieser Stelle rueckgaengig. 697 aTimer.SetTimeout(200); 698 aTimer.SetTimeoutHdl(LINK( this, ScRefHandler, UpdateFocusHdl)); 699 700 if( bBindRef ) EnterRefMode(); 701 } 702 703 bool ScRefHandler::EnterRefMode() 704 { 705 if( m_bInRefMode ) return false; 706 707 SC_MOD()->InputEnterHandler(); 708 // ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell(); 709 710 ScTabViewShell* pScViewShell = NULL; 711 712 // title has to be from the view that opened the dialog, 713 // even if it's not the current view 714 715 SfxObjectShell* pParentDoc = NULL; 716 if ( pMyBindings ) 717 { 718 SfxDispatcher* pMyDisp = pMyBindings->GetDispatcher(); 719 if (pMyDisp) 720 { 721 SfxViewFrame* pMyViewFrm = pMyDisp->GetFrame(); 722 if (pMyViewFrm) 723 { 724 pScViewShell = PTR_CAST( ScTabViewShell, pMyViewFrm->GetViewShell() ); 725 if( pScViewShell ) 726 pScViewShell->UpdateInputHandler(sal_True); 727 pParentDoc = pMyViewFrm->GetObjectShell(); 728 } 729 } 730 } 731 if ( !pParentDoc && pScViewShell ) // use current only if above fails 732 pParentDoc = pScViewShell->GetObjectShell(); 733 if ( pParentDoc ) 734 aDocName = pParentDoc->GetTitle(); 735 736 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl(pScViewShell); 737 738 DBG_ASSERT( pInputHdl, "Missing input handler :-/" ); 739 740 if ( pInputHdl ) 741 pInputHdl->NotifyChange( NULL ); 742 743 m_aHelper.enableInput( sal_False ); 744 745 m_aHelper.EnableSpreadsheets(); 746 747 m_aHelper.Init(); 748 749 m_aHelper.SetDispatcherLock( sal_True ); 750 //@Test 751 //SFX_APPWINDOW->Disable(sal_True); //@BugID 54702 752 753 return m_bInRefMode = true; 754 } 755 756 //---------------------------------------------------------------------------- 757 758 ScRefHandler::~ScRefHandler() 759 { 760 LeaveRefMode(); 761 } 762 763 bool ScRefHandler::LeaveRefMode() 764 { 765 if( !m_bInRefMode ) return false; 766 767 lcl_HideAllReferences(); 768 769 if( Dialog *pDlg = dynamic_cast<Dialog*>( static_cast<Window*>(*this) ) ) 770 pDlg->SetModalInputMode(sal_False); 771 SetDispatcherLock( sal_False ); //! here and in DoClose ? 772 773 ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell(); 774 if( pScViewShell ) 775 pScViewShell->UpdateInputHandler(sal_True); 776 777 //SFX_APPWINDOW->Enable(sal_True,sal_True); 778 lcl_InvalidateWindows(); 779 780 m_bInRefMode = false; 781 return true; 782 } 783 784 //---------------------------------------------------------------------------- 785 786 //SfxBindings& ScRefHandler::GetBindings() 787 //{ 788 // //! SfxModelessDialog should allow access to pBindings pointer 789 // 790 // return *pMyBindings; 791 //} 792 793 //---------------------------------------------------------------------------- 794 795 void ScRefHandler::SwitchToDocument() 796 { 797 ScTabViewShell* pCurrent = ScTabViewShell::GetActiveViewShell(); 798 if (pCurrent) 799 { 800 SfxObjectShell* pObjSh = pCurrent->GetObjectShell(); 801 if ( pObjSh && pObjSh->GetTitle() == aDocName ) 802 { 803 // right document already visible -> nothing to do 804 return; 805 } 806 } 807 808 TypeId aScType = TYPE(ScTabViewShell); 809 SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType ); 810 while ( pSh ) 811 { 812 SfxObjectShell* pObjSh = pSh->GetObjectShell(); 813 if ( pObjSh && pObjSh->GetTitle() == aDocName ) 814 { 815 // switch to first TabViewShell for document 816 ((ScTabViewShell*)pSh)->SetActive(); 817 return; 818 } 819 pSh = SfxViewShell::GetNext( *pSh, &aScType ); 820 } 821 } 822 823 //---------------------------------------------------------------------------- 824 825 sal_Bool ScRefHandler::IsDocAllowed(SfxObjectShell* pDocSh) const // pDocSh may be 0 826 { 827 // default: allow only same document (overridden in function dialog) 828 String aCmpName; 829 if ( pDocSh ) 830 aCmpName = pDocSh->GetTitle(); 831 832 // if aDocName isn't initialized, allow 833 return ( aDocName.Len() == 0 || aDocName == aCmpName ); 834 } 835 836 //---------------------------------------------------------------------------- 837 838 sal_Bool __EXPORT ScRefHandler::IsRefInputMode() const 839 { 840 return m_rWindow.IsVisible(); // nur wer sichtbar ist kann auch Referenzen bekommen 841 } 842 843 //---------------------------------------------------------------------------- 844 845 sal_Bool __EXPORT ScRefHandler::DoClose( sal_uInt16 nId ) 846 { 847 m_aHelper.DoClose(nId); 848 return sal_True; 849 } 850 851 void ScRefHandler::SetDispatcherLock( sal_Bool bLock ) 852 { 853 m_aHelper.SetDispatcherLock( bLock ); 854 } 855 856 //---------------------------------------------------------------------------- 857 858 void ScRefHandler::ViewShellChanged(ScTabViewShell* pScViewShell ) 859 { 860 m_aHelper.ViewShellChanged(pScViewShell); 861 } 862 863 //---------------------------------------------------------------------------- 864 865 void ScRefHandler::AddRefEntry() 866 { 867 // wenn nicht ueberladen, gibt es keine Mehrfach-Referenzen 868 } 869 870 //---------------------------------------------------------------------------- 871 872 sal_Bool __EXPORT ScRefHandler::IsTableLocked() const 873 { 874 // per Default kann bei Referenzeingabe auch die Tabelle umgeschaltet werden 875 876 return sal_False; 877 } 878 879 //---------------------------------------------------------------------------- 880 // 881 // RefInputStart/Done: Zoom-In (AutoHide) auf einzelnes Feld 882 // (per Button oder Bewegung) 883 // 884 //---------------------------------------------------------------------------- 885 886 void ScRefHandler::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton ) 887 { 888 m_aHelper.RefInputStart( pEdit, pButton ); 889 } 890 891 892 void ScRefHandler::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton ) 893 { 894 m_aHelper.ToggleCollapsed( pEdit, pButton ); 895 } 896 897 //The two following function is commentted out by PengYunQuan for Validity Cell Range Picker 898 //long ScAnyRefDlg::PreNotify( NotifyEvent& rNEvt ) 899 //{ 900 // sal_uInt16 nSwitch=rNEvt.GetType(); 901 // if(nSwitch==EVENT_GETFOCUS) 902 // { 903 // pActiveWin=rNEvt.GetWindow(); 904 // } 905 // return SfxModelessDialog::PreNotify(rNEvt); 906 //} 907 // 908 //void ScAnyRefDlg::StateChanged( StateChangedType nStateChange ) 909 //{ 910 // SfxModelessDialog::StateChanged( nStateChange ); 911 // 912 // if(nStateChange == STATE_CHANGE_VISIBLE) 913 // { 914 // if(IsVisible()) 915 // { 916 // m_aHelper.enableInput( sal_False ); 917 // m_aHelper.EnableSpreadsheets(); 918 // m_aHelper.SetDispatcherLock( sal_True ); 919 // aTimer.Start(); 920 // } 921 // else 922 // { 923 // m_aHelper.enableInput( sal_True ); 924 // m_aHelper.SetDispatcherLock( sal_False ); //! here and in DoClose ? 925 // } 926 // } 927 //} 928 929 #if defined( _MSC_VER ) 930 #define INTRODUCE_TEMPLATE 931 #else 932 #define INTRODUCE_TEMPLATE template <> 933 #endif 934 935 #define IMPL_TWINDOW_PRENOTIFY( TWindow,bBindRef ) \ 936 INTRODUCE_TEMPLATE long ScRefHdlrImplBase<TWindow,bBindRef>::PreNotify( NotifyEvent& rNEvt )\ 937 {\ 938 if( bBindRef || m_bInRefMode )\ 939 {\ 940 sal_uInt16 nSwitch=rNEvt.GetType();\ 941 if(nSwitch==EVENT_GETFOCUS)\ 942 {\ 943 pActiveWin=rNEvt.GetWindow();\ 944 }\ 945 }\ 946 return TWindow::PreNotify(rNEvt);\ 947 } 948 949 #define IMPL_TWINDOW_STATECHANGED( TWindow,bBindRef ) \ 950 INTRODUCE_TEMPLATE void ScRefHdlrImplBase<TWindow,bBindRef>::StateChanged( StateChangedType nStateChange )\ 951 {\ 952 TWindow::StateChanged( nStateChange );\ 953 \ 954 if( !bBindRef && !m_bInRefMode ) return;\ 955 \ 956 if(nStateChange == STATE_CHANGE_VISIBLE)\ 957 {\ 958 if(m_rWindow.IsVisible())\ 959 {\ 960 m_aHelper.enableInput( sal_False );\ 961 m_aHelper.EnableSpreadsheets();\ 962 m_aHelper.SetDispatcherLock( sal_True );\ 963 aTimer.Start();\ 964 }\ 965 else\ 966 {\ 967 m_aHelper.enableInput( sal_True );\ 968 m_aHelper.SetDispatcherLock( sal_False ); /*//! here and in DoClose ?*/\ 969 }\ 970 }\ 971 } 972 973 IMPL_TWINDOW_PRENOTIFY( SfxModelessDialog, true ) 974 IMPL_TWINDOW_PRENOTIFY( SfxTabDialog, false ) 975 IMPL_TWINDOW_STATECHANGED( SfxModelessDialog, true ) 976 IMPL_TWINDOW_STATECHANGED( SfxTabDialog, false ) 977 978 IMPL_LINK( ScRefHandler, UpdateFocusHdl, Timer*, EMPTYARG ) 979 { 980 if (pActiveWin) 981 { 982 pActiveWin->GrabFocus(); 983 } 984 return 0; 985 } 986 // ----------------------------------------------------------------------------- 987 bool ScRefHandler::ParseWithNames( ScRangeList& rRanges, const String& rStr, ScDocument* pDoc ) 988 { 989 return m_aHelper.ParseWithNames( rRanges, rStr, pDoc ); 990 } 991 // ----------------------------------------------------------------------------- 992 void ScRefHandler::HideReference( sal_Bool bDoneRefMode ) 993 { 994 m_aHelper.HideReference( bDoneRefMode ); 995 } 996 // ----------------------------------------------------------------------------- 997 void ScRefHandler::ShowReference( const XubString& rStr ) 998 { 999 m_aHelper.ShowReference( rStr ); 1000 } 1001 // ----------------------------------------------------------------------------- 1002 void ScRefHandler::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton ) 1003 { 1004 m_aHelper.ReleaseFocus( pEdit,pButton ); 1005 } 1006 //---------------------------------------------------------------------------- 1007 void ScRefHandler::RefInputDone( sal_Bool bForced ) 1008 { 1009 m_aHelper.RefInputDone( bForced ); 1010 } 1011 1012