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