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_starmath.hxx" 26 27 28 #include <com/sun/star/accessibility/XAccessible.hpp> 29 #include <com/sun/star/accessibility/AccessibleEventObject.hpp> 30 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 31 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 32 #include <toolkit/helper/vclunohelper.hxx> 33 34 35 #include "starmath.hrc" 36 #define ITEMID_FONT 1 37 #define ITEMID_FONTHEIGHT 2 38 #define ITEMID_LRSPACE 3 39 #define ITEMID_WEIGHT 4 40 41 42 #include <vcl/menu.hxx> 43 #include <editeng/editview.hxx> 44 #include <editeng/editeng.hxx> 45 #include <editeng/editstat.hxx> 46 #include <editeng/eeitem.hxx> 47 #include <sfx2/dispatch.hxx> 48 #include <svl/intitem.hxx> 49 #include <svl/itempool.hxx> 50 #include <svl/stritem.hxx> 51 #include <editeng/fhgtitem.hxx> 52 #include <editeng/wghtitem.hxx> 53 #include <editeng/lrspitem.hxx> 54 #include <svl/itemset.hxx> 55 #include <editeng/fontitem.hxx> 56 #include <sfx2/viewfrm.hxx> 57 58 #include "edit.hxx" 59 #include "view.hxx" 60 #include "document.hxx" 61 #include "config.hxx" 62 63 #define SCROLL_LINE 24 64 65 #define MINWIDTH 200 66 #define MINHEIGHT 200 67 #define MINSPLIT 40 68 #define SPLITTERWIDTH 2 69 70 71 using namespace com::sun::star::accessibility; 72 using namespace com::sun::star; 73 using namespace com::sun::star::uno; 74 75 //////////////////////////////////////// 76 77 78 void SmGetLeftSelectionPart(const ESelection aSel, 79 sal_uInt16 &nPara, sal_uInt16 &nPos) 80 // returns paragraph number and position of the selections left part 81 { 82 // compare start and end of selection and use the one that comes first 83 if ( aSel.nStartPara < aSel.nEndPara 84 || (aSel.nStartPara == aSel.nEndPara && aSel.nStartPos < aSel.nEndPos) ) 85 { nPara = aSel.nStartPara; 86 nPos = aSel.nStartPos; 87 } 88 else 89 { nPara = aSel.nEndPara; 90 nPos = aSel.nEndPos; 91 } 92 } 93 94 //////////////////////////////////////// 95 96 SmEditWindow::SmEditWindow( SmCmdBoxWindow &rMyCmdBoxWin ) : 97 Window (&rMyCmdBoxWin), 98 DropTargetHelper ( this ), 99 pAccessible (0), 100 rCmdBox (rMyCmdBoxWin), 101 pEditView (0), 102 pHScrollBar (0), 103 pVScrollBar (0), 104 pScrollBox (0) 105 { 106 SetHelpId(HID_SMA_COMMAND_WIN_EDIT); 107 SetMapMode(MAP_PIXEL); 108 109 // Even RTL languages don't use RTL for math 110 rCmdBox.GetEditWindow()->EnableRTL( sal_False ); 111 112 ApplyColorConfigValues( SM_MOD()->GetColorConfig() ); 113 114 // compare DataChanged 115 SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); 116 117 aModifyTimer.SetTimeoutHdl(LINK(this, SmEditWindow, ModifyTimerHdl)); 118 aModifyTimer.SetTimeout(500); 119 120 aCursorMoveTimer.SetTimeoutHdl(LINK(this, SmEditWindow, CursorMoveTimerHdl)); 121 aCursorMoveTimer.SetTimeout(500); 122 123 // if not called explicitly the this edit window within the 124 // command window will just show an empty gray panel. 125 Show(); 126 } 127 128 129 SmEditWindow::~SmEditWindow() 130 { 131 aCursorMoveTimer.Stop(); 132 aModifyTimer.Stop(); 133 134 135 // #112565# clean up of classes used for accessibility 136 // must be done before EditView (and thus EditEngine) is no longer 137 // available for those classes. 138 if (pAccessible) 139 pAccessible->ClearWin(); // make Accessible defunctional 140 // Note: memory for pAccessible will be freed when the reference 141 // xAccessible is released. 142 143 if (pEditView) 144 { 145 EditEngine *pEditEngine = pEditView->GetEditEngine(); 146 if (pEditEngine) 147 { 148 pEditEngine->SetStatusEventHdl( Link() ); 149 pEditEngine->RemoveView( pEditView ); 150 } 151 } 152 delete pEditView; 153 delete pHScrollBar; 154 delete pVScrollBar; 155 delete pScrollBox; 156 } 157 158 void SmEditWindow::InvalidateSlots() 159 { 160 SfxBindings& rBind = GetView()->GetViewFrame()->GetBindings(); 161 rBind.Invalidate(SID_COPY); 162 rBind.Invalidate(SID_CUT); 163 rBind.Invalidate(SID_DELETE); 164 } 165 166 SmViewShell * SmEditWindow::GetView() 167 { 168 return rCmdBox.GetView(); 169 } 170 171 172 SmDocShell * SmEditWindow::GetDoc() 173 { 174 SmViewShell *pView = rCmdBox.GetView(); 175 return pView ? pView->GetDoc() : 0; 176 } 177 178 179 EditEngine * SmEditWindow::GetEditEngine() 180 { 181 EditEngine *pEditEng = 0; 182 if (pEditView) 183 pEditEng = pEditView->GetEditEngine(); 184 else 185 { 186 SmDocShell *pDoc = GetDoc(); 187 if (pDoc) 188 pEditEng = &pDoc->GetEditEngine(); 189 } 190 return pEditEng; 191 } 192 193 194 SfxItemPool * SmEditWindow::GetEditEngineItemPool() 195 { 196 SmDocShell *pDoc = GetDoc(); 197 return pDoc ? &pDoc->GetEditEngineItemPool() : 0; 198 } 199 200 void SmEditWindow::ApplyColorConfigValues( const svtools::ColorConfig &rColorCfg ) 201 { 202 // Note: SetBackground still done in SmEditWindow::DataChanged 203 #if OSL_DEBUG_LEVEL > 1 204 // ColorData nVal = rColorCfg.GetColorValue(svtools::FONTCOLOR).nColor; 205 #endif 206 SetTextColor( rColorCfg.GetColorValue(svtools::FONTCOLOR).nColor ); 207 Invalidate(); 208 } 209 210 void SmEditWindow::DataChanged( const DataChangedEvent& ) 211 { 212 const StyleSettings aSettings( GetSettings().GetStyleSettings() ); 213 214 ApplyColorConfigValues( SM_MOD()->GetColorConfig() ); 215 SetBackground( aSettings.GetWindowColor() ); 216 217 // edit fields in other Applications use this font instead of 218 // the application font thus we use this one too 219 SetPointFont( aSettings.GetFieldFont() /*aSettings.GetAppFont()*/ ); 220 221 EditEngine *pEditEngine = GetEditEngine(); 222 SfxItemPool *pEditEngineItemPool = GetEditEngineItemPool(); 223 224 if (pEditEngine && pEditEngineItemPool) 225 { 226 //! 227 //! see also SmDocShell::GetEditEngine() ! 228 //! 229 230 pEditEngine->SetDefTab( sal_uInt16( GetTextWidth( C2S("XXXX") ) ) ); 231 232 SetEditEngineDefaultFonts( *pEditEngine, *pEditEngineItemPool ); 233 234 // forces new settings to be used 235 // unfortunately this resets the whole edit engine 236 // thus we need to save at least the text 237 String aTxt( pEditEngine->GetText( LINEEND_LF ) ); 238 pEditEngine->Clear(); //#77957 incorrect font size 239 pEditEngine->SetText( aTxt ); 240 } 241 242 AdjustScrollBars(); 243 Resize(); 244 } 245 246 IMPL_LINK( SmEditWindow, ModifyTimerHdl, Timer *, EMPTYARG /*pTimer*/ ) 247 { 248 SmModule *pp = SM_MOD(); 249 if (pp->GetConfig()->IsAutoRedraw()) 250 Flush(); 251 aModifyTimer.Stop(); 252 return 0; 253 } 254 255 256 IMPL_LINK(SmEditWindow, CursorMoveTimerHdl, Timer *, EMPTYARG /*pTimer*/) 257 // every once in a while check cursor position (selection) of edit 258 // window and if it has changed (try to) set the formula-cursor 259 // according to that. 260 { 261 ESelection aNewSelection (GetSelection()); 262 263 if (!aNewSelection.IsEqual(aOldSelection)) 264 { SmViewShell *pView = rCmdBox.GetView(); 265 266 if (pView) 267 { 268 // get row and column to look for 269 sal_uInt16 nRow, nCol; 270 SmGetLeftSelectionPart(aNewSelection, nRow, nCol); 271 nRow++; 272 nCol++; 273 274 pView->GetGraphicWindow().SetCursorPos(nRow, nCol); 275 276 aOldSelection = aNewSelection; 277 } 278 } 279 aCursorMoveTimer.Stop(); 280 281 return 0; 282 } 283 284 285 void SmEditWindow::Resize() 286 { 287 if (!pEditView) 288 CreateEditView(); 289 290 if (pEditView) 291 { 292 pEditView->SetOutputArea(AdjustScrollBars()); 293 pEditView->ShowCursor(); 294 295 DBG_ASSERT( pEditView->GetEditEngine(), "EditEngine missing" ); 296 const long nMaxVisAreaStart = pEditView->GetEditEngine()->GetTextHeight() - 297 pEditView->GetOutputArea().GetHeight(); 298 if (pEditView->GetVisArea().Top() > nMaxVisAreaStart) 299 { 300 Rectangle aVisArea(pEditView->GetVisArea() ); 301 aVisArea.Top() = (nMaxVisAreaStart > 0 ) ? nMaxVisAreaStart : 0; 302 aVisArea.SetSize(pEditView->GetOutputArea().GetSize()); 303 pEditView->SetVisArea(aVisArea); 304 pEditView->ShowCursor(); 305 } 306 InitScrollBars(); 307 } 308 Invalidate(); 309 } 310 311 void SmEditWindow::MouseButtonUp(const MouseEvent &rEvt) 312 { 313 if (pEditView) 314 pEditView->MouseButtonUp(rEvt); 315 else 316 Window::MouseButtonUp (rEvt); 317 318 // ggf FormulaCursor neu positionieren 319 CursorMoveTimerHdl(&aCursorMoveTimer); 320 InvalidateSlots(); 321 } 322 323 void SmEditWindow::MouseButtonDown(const MouseEvent &rEvt) 324 { 325 if (pEditView) 326 pEditView->MouseButtonDown(rEvt); 327 else 328 Window::MouseButtonDown (rEvt); 329 330 GrabFocus(); 331 } 332 333 void SmEditWindow::Command(const CommandEvent& rCEvt) 334 { 335 sal_Bool bForwardEvt = sal_True; 336 if (rCEvt.GetCommand() == COMMAND_CONTEXTMENU) 337 { 338 GetParent()->ToTop(); 339 340 Point aPoint = rCEvt.GetMousePosPixel(); 341 PopupMenu* pPopupMenu = new PopupMenu(SmResId(RID_COMMANDMENU)); 342 343 // added for replaceability of context menus #96085, #93782 344 Menu* pMenu = NULL; 345 ::com::sun::star::ui::ContextMenuExecuteEvent aEvent; 346 aEvent.SourceWindow = VCLUnoHelper::GetInterface( this ); 347 aEvent.ExecutePosition.X = aPoint.X(); 348 aEvent.ExecutePosition.Y = aPoint.Y(); 349 ::rtl::OUString sDummy; 350 if ( GetView()->TryContextMenuInterception( *pPopupMenu, sDummy, pMenu, aEvent ) ) 351 { 352 if ( pMenu ) 353 { 354 delete pPopupMenu; 355 pPopupMenu = (PopupMenu*) pMenu; 356 } 357 } 358 359 pPopupMenu->SetSelectHdl(LINK(this, SmEditWindow, MenuSelectHdl)); 360 361 pPopupMenu->Execute( this, aPoint ); 362 delete pPopupMenu; 363 bForwardEvt = sal_False; 364 } 365 else if (rCEvt.GetCommand() == COMMAND_WHEEL) 366 bForwardEvt = !HandleWheelCommands( rCEvt ); 367 368 if (bForwardEvt) 369 { 370 if (pEditView) 371 pEditView->Command( rCEvt ); 372 else 373 Window::Command (rCEvt); 374 } 375 } 376 377 378 sal_Bool SmEditWindow::HandleWheelCommands( const CommandEvent &rCEvt ) 379 { 380 sal_Bool bCommandHandled = sal_False; // true if the CommandEvent needs not 381 // to be passed on (because it has fully 382 // been taken care of). 383 384 const CommandWheelData* pWData = rCEvt.GetWheelData(); 385 if (pWData) 386 { 387 if (COMMAND_WHEEL_ZOOM == pWData->GetMode()) 388 bCommandHandled = sal_True; // no zooming in Command window 389 else 390 bCommandHandled = HandleScrollCommand( rCEvt, pHScrollBar, pVScrollBar); 391 } 392 393 return bCommandHandled; 394 } 395 396 397 IMPL_LINK_INLINE_START( SmEditWindow, MenuSelectHdl, Menu *, pMenu ) 398 { 399 SmViewShell *pViewSh = rCmdBox.GetView(); 400 if (pViewSh) 401 pViewSh->GetViewFrame()->GetDispatcher()->Execute( 402 SID_INSERTCOMMAND, SFX_CALLMODE_STANDARD, 403 new SfxInt16Item(SID_INSERTCOMMAND, pMenu->GetCurItemId()), 0L); 404 return 0; 405 } 406 IMPL_LINK_INLINE_END( SmEditWindow, MenuSelectHdl, Menu *, pMenu ) 407 408 void SmEditWindow::KeyInput(const KeyEvent& rKEvt) 409 { 410 if (rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE) 411 { 412 sal_Bool bCallBase = sal_True; 413 SfxViewShell* pViewShell = GetView(); 414 if ( pViewShell && pViewShell->ISA(SmViewShell) ) 415 { 416 // Terminate possible InPlace mode 417 bCallBase = !pViewShell->Escape(); 418 } 419 if ( bCallBase ) 420 Window::KeyInput( rKEvt ); 421 } 422 else 423 { 424 // Timer neu starten, um den Handler (auch bei laengeren Eingaben) 425 // moeglichst nur einmal am Ende aufzurufen. 426 aCursorMoveTimer.Start(); 427 428 DBG_ASSERT( pEditView, "EditView missing (NULL pointer)" ); 429 if (!pEditView) 430 CreateEditView(); 431 if ( !pEditView->PostKeyEvent(rKEvt) ) 432 { 433 SmViewShell *pView = GetView(); 434 if ( pView && !pView->KeyInput(rKEvt) ) 435 { 436 /* fuert bei F1 (Hilfe) zum Zerstoeren von this! */ 437 Flush(); 438 if ( aModifyTimer.IsActive() ) 439 aModifyTimer.Stop(); 440 Window::KeyInput(rKEvt); 441 } 442 else 443 { 444 //SFX hat evtl. Slot an der View gecallt und dabei (wg. Hack 445 //im SFX) den Focus auf die View gesetzt 446 SfxViewShell* pVShell = GetView(); 447 if ( pVShell && pVShell->ISA(SmViewShell) && 448 ((SmViewShell*)pVShell)->GetGraphicWindow().HasFocus() ) 449 { 450 GrabFocus(); 451 } 452 } 453 } 454 else 455 { 456 // have doc-shell modified only for formula input/change and not 457 // cursor travelling and such things... 458 SmDocShell *pDocShell = GetDoc(); 459 if (pDocShell) 460 pDocShell->SetModified( GetEditEngine()->IsModified() ); 461 462 aModifyTimer.Start(); 463 } 464 465 InvalidateSlots(); 466 } 467 } 468 469 void SmEditWindow::Paint(const Rectangle& rRect) 470 { 471 if (!pEditView) 472 CreateEditView(); 473 pEditView->Paint(rRect); 474 } 475 476 void SmEditWindow::CreateEditView() 477 { 478 EditEngine *pEditEngine = GetEditEngine(); 479 480 //! pEditEngine and pEditView may be 0. 481 //! For example when the program is used by the document-converter 482 if (!pEditView && pEditEngine) 483 { 484 pEditView = new EditView( pEditEngine, this ); 485 pEditEngine->InsertView( pEditView ); 486 487 if (!pVScrollBar) 488 pVScrollBar = new ScrollBar(this, WinBits(WB_VSCROLL)); 489 if (!pHScrollBar) 490 pHScrollBar = new ScrollBar(this, WinBits(WB_HSCROLL)); 491 if (!pScrollBox) 492 pScrollBox = new ScrollBarBox(this); 493 pVScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl)); 494 pHScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl)); 495 pVScrollBar->EnableDrag( sal_True ); 496 pHScrollBar->EnableDrag( sal_True ); 497 498 pEditView->SetOutputArea(AdjustScrollBars()); 499 500 ESelection eSelection; 501 502 pEditView->SetSelection(eSelection); 503 Update(); 504 pEditView->ShowCursor(sal_True, sal_True); 505 506 pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) ); 507 SetPointer(pEditView->GetPointer()); 508 509 SetScrollBarRanges(); 510 } 511 } 512 513 514 IMPL_LINK( SmEditWindow, EditStatusHdl, EditStatus *, EMPTYARG /*pStat*/ ) 515 { 516 if (!pEditView) 517 return 1; 518 else 519 { 520 Resize(); 521 return 0; 522 } 523 } 524 525 IMPL_LINK_INLINE_START( SmEditWindow, ScrollHdl, ScrollBar *, EMPTYARG /*pScrollBar*/ ) 526 { 527 DBG_ASSERT(pEditView, "EditView missing"); 528 if (pEditView) 529 { 530 pEditView->SetVisArea(Rectangle(Point(pHScrollBar->GetThumbPos(), 531 pVScrollBar->GetThumbPos()), 532 pEditView->GetVisArea().GetSize())); 533 pEditView->Invalidate(); 534 } 535 return 0; 536 } 537 IMPL_LINK_INLINE_END( SmEditWindow, ScrollHdl, ScrollBar *, pScrollBar ) 538 539 Rectangle SmEditWindow::AdjustScrollBars() 540 { 541 const Size aOut( GetOutputSizePixel() ); 542 Point aPoint; 543 Rectangle aRect( aPoint, aOut ); 544 545 if (pVScrollBar && pHScrollBar && pScrollBox) 546 { 547 const long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize(); 548 Point aPt( aRect.TopRight() ); aPt.X() -= nTmp -1L; 549 pVScrollBar->SetPosSizePixel( aPt, Size(nTmp, aOut.Height() - nTmp)); 550 551 aPt = aRect.BottomLeft(); aPt.Y() -= nTmp - 1L; 552 pHScrollBar->SetPosSizePixel( aPt, Size(aOut.Width() - nTmp, nTmp)); 553 554 aPt.X() = pHScrollBar->GetSizePixel().Width(); 555 aPt.Y() = pVScrollBar->GetSizePixel().Height(); 556 pScrollBox->SetPosSizePixel(aPt, Size(nTmp, nTmp )); 557 558 aRect.Right() = aPt.X() - 2; 559 aRect.Bottom() = aPt.Y() - 2; 560 } 561 return aRect; 562 } 563 564 void SmEditWindow::SetScrollBarRanges() 565 { 566 // Extra-Methode, nicht InitScrollBars, da auch fuer EditEngine-Events. 567 EditEngine *pEditEngine = GetEditEngine(); 568 if (pVScrollBar && pHScrollBar && pEditEngine && pEditView) 569 { 570 long nTmp = pEditEngine->GetTextHeight(); 571 pVScrollBar->SetRange(Range(0, nTmp)); 572 pVScrollBar->SetThumbPos(pEditView->GetVisArea().Top()); 573 574 nTmp = pEditEngine->GetPaperSize().Width(); 575 pHScrollBar->SetRange(Range(0,nTmp)); 576 pHScrollBar->SetThumbPos(pEditView->GetVisArea().Left()); 577 } 578 } 579 580 void SmEditWindow::InitScrollBars() 581 { 582 if (pVScrollBar && pHScrollBar && pScrollBox && pEditView) 583 { 584 const Size aOut( pEditView->GetOutputArea().GetSize() ); 585 pVScrollBar->SetVisibleSize(aOut.Height()); 586 pVScrollBar->SetPageSize(aOut.Height() * 8 / 10); 587 pVScrollBar->SetLineSize(aOut.Height() * 2 / 10); 588 589 pHScrollBar->SetVisibleSize(aOut.Width()); 590 pHScrollBar->SetPageSize(aOut.Width() * 8 / 10); 591 pHScrollBar->SetLineSize(SCROLL_LINE ); 592 593 SetScrollBarRanges(); 594 595 pVScrollBar->Show(); 596 pHScrollBar->Show(); 597 pScrollBox->Show(); 598 } 599 } 600 601 602 String SmEditWindow::GetText() const 603 { 604 String aText; 605 EditEngine *pEditEngine = const_cast< SmEditWindow* >(this)->GetEditEngine(); 606 DBG_ASSERT( pEditEngine, "EditEngine missing" ); 607 if (pEditEngine) 608 aText = pEditEngine->GetText( LINEEND_LF ); 609 return aText; 610 } 611 612 613 void SmEditWindow::SetText(const XubString& rText) 614 { 615 EditEngine *pEditEngine = GetEditEngine(); 616 DBG_ASSERT( pEditEngine, "EditEngine missing" ); 617 if (pEditEngine && !pEditEngine->IsModified()) 618 { 619 if (!pEditView) 620 CreateEditView(); 621 622 ESelection eSelection = pEditView->GetSelection(); 623 624 pEditEngine->SetText(rText); 625 pEditEngine->ClearModifyFlag(); 626 627 //! Hier die Timer neu zu starten verhindert, dass die Handler fuer andere 628 //! (im Augenblick nicht mehr aktive) Math Tasks aufgerufen werden. 629 aModifyTimer.Start(); 630 aCursorMoveTimer.Start(); 631 632 pEditView->SetSelection(eSelection); 633 } 634 } 635 636 637 void SmEditWindow::GetFocus() 638 { 639 Window::GetFocus(); 640 641 if (xAccessible.is()) 642 { 643 // Note: will implicitly send the AccessibleStateType::FOCUSED event 644 ::accessibility::AccessibleTextHelper *pHelper = pAccessible->GetTextHelper(); 645 if (pHelper) 646 pHelper->SetFocus( sal_True ); 647 } 648 649 if (!pEditView) 650 CreateEditView(); 651 EditEngine *pEditEngine = GetEditEngine(); 652 if (pEditEngine) 653 pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) ); 654 } 655 656 657 void SmEditWindow::LoseFocus() 658 { 659 EditEngine *pEditEngine = GetEditEngine(); 660 if (pEditEngine) 661 pEditEngine->SetStatusEventHdl( Link() ); 662 663 Window::LoseFocus(); 664 665 if (xAccessible.is()) 666 { 667 // Note: will implicitly send the AccessibleStateType::FOCUSED event 668 ::accessibility::AccessibleTextHelper *pHelper = pAccessible->GetTextHelper(); 669 if (pHelper) 670 pHelper->SetFocus( sal_False ); 671 } 672 } 673 674 675 sal_Bool SmEditWindow::IsAllSelected() const 676 { 677 sal_Bool bRes = sal_False; 678 EditEngine *pEditEngine = ((SmEditWindow *) this)->GetEditEngine(); 679 DBG_ASSERT( pEditView, "NULL pointer" ); 680 DBG_ASSERT( pEditEngine, "NULL pointer" ); 681 if (pEditEngine && pEditView) 682 { 683 ESelection eSelection( pEditView->GetSelection() ); 684 sal_Int32 nParaCnt = pEditEngine->GetParagraphCount(); 685 if (!(nParaCnt - 1)) 686 { 687 String Text( pEditEngine->GetText( LINEEND_LF ) ); 688 bRes = !eSelection.nStartPos && (eSelection.nEndPos == Text.Len () - 1); 689 } 690 else 691 { 692 bRes = !eSelection.nStartPara && (eSelection.nEndPara == nParaCnt - 1); 693 } 694 } 695 return bRes; 696 } 697 698 void SmEditWindow::SelectAll() 699 { 700 DBG_ASSERT( pEditView, "NULL pointer" ); 701 if (pEditView) 702 { 703 // 0xFFFF as last two parameters refers to the end of the text 704 pEditView->SetSelection( ESelection( 0, 0, 0xFFFF, 0xFFFF ) ); 705 } 706 } 707 708 void SmEditWindow::InsertCommand(sal_uInt16 nCommand) 709 { 710 DBG_ASSERT( pEditView, "EditView missing" ); 711 if (pEditView) 712 { 713 //Anfang der Selektion merken und hinterher den Cursor daraufsetzen. Nur so 714 //macht das SelNextMark() Sinn. 715 ESelection aSelection = pEditView->GetSelection(); 716 aSelection.nEndPos = aSelection.nStartPos; 717 aSelection.nEndPara = aSelection.nStartPara; 718 719 DBG_ASSERT( pEditView, "NULL pointer" ); 720 String aText = String(SmResId(nCommand)); 721 pEditView->InsertText(aText); 722 723 if (HasMark(aText)) 724 { // set selection to next mark 725 pEditView->SetSelection(aSelection); 726 SelNextMark(); 727 } 728 else 729 { // set selection after inserted text 730 aSelection.nEndPos = aSelection.nEndPos + sal::static_int_cast< xub_StrLen >(aText.Len()); 731 aSelection.nStartPos = aSelection.nEndPos; 732 pEditView->SetSelection(aSelection); 733 } 734 735 aModifyTimer.Start(); 736 aCursorMoveTimer.Start(); 737 738 GrabFocus(); 739 } 740 } 741 742 void SmEditWindow::MarkError(const Point &rPos) 743 { 744 DBG_ASSERT( pEditView, "EditView missing" ); 745 if (pEditView) 746 { 747 const xub_StrLen nCol = sal::static_int_cast< xub_StrLen >(rPos.X()); 748 const sal_uInt16 nRow = sal::static_int_cast< sal_uInt16 >(rPos.Y() - 1); 749 750 pEditView->SetSelection(ESelection(nRow, nCol - 1, nRow, nCol)); 751 GrabFocus(); 752 } 753 } 754 755 void SmEditWindow::SelNextMark() 756 { 757 EditEngine *pEditEngine = GetEditEngine(); 758 DBG_ASSERT( pEditView, "NULL pointer" ); 759 DBG_ASSERT( pEditEngine, "NULL pointer" ); 760 if (pEditEngine && pEditView) 761 { 762 ESelection eSelection = pEditView->GetSelection(); 763 sal_uInt16 Pos = eSelection.nEndPos; 764 String aMark (C2S("<?>")); 765 String aText; 766 sal_uInt16 nCounts = pEditEngine->GetParagraphCount(); 767 768 while (eSelection.nEndPara < nCounts) 769 { 770 aText = pEditEngine->GetText( eSelection.nEndPara ); 771 Pos = aText.Search(aMark, Pos); 772 773 if (Pos != STRING_NOTFOUND) 774 { 775 pEditView->SetSelection(ESelection (eSelection.nEndPara, Pos, eSelection.nEndPara, Pos + 3)); 776 break; 777 } 778 779 Pos = 0; 780 eSelection.nEndPara++; 781 } 782 } 783 } 784 785 void SmEditWindow::SelPrevMark() 786 { 787 EditEngine *pEditEngine = GetEditEngine(); 788 DBG_ASSERT( pEditEngine, "NULL pointer" ); 789 DBG_ASSERT( pEditView, "NULL pointer" ); 790 if (pEditEngine && pEditView) 791 { 792 ESelection eSelection = pEditView->GetSelection(); 793 sal_uInt16 Pos = STRING_NOTFOUND; 794 xub_StrLen Max = eSelection.nStartPos; 795 String Text( pEditEngine->GetText( eSelection.nStartPara ) ); 796 String aMark (C2S("<?>")); 797 sal_uInt16 nCounts = pEditEngine->GetParagraphCount(); 798 799 do 800 { 801 sal_uInt16 Fnd = Text.Search(aMark, 0); 802 803 while ((Fnd < Max) && (Fnd != STRING_NOTFOUND)) 804 { 805 Pos = Fnd; 806 Fnd = Text.Search(aMark, Fnd + 1); 807 } 808 809 if (Pos == STRING_NOTFOUND) 810 { 811 eSelection.nStartPara--; 812 Text = pEditEngine->GetText( eSelection.nStartPara ); 813 Max = Text.Len(); 814 } 815 } 816 while ((eSelection.nStartPara < nCounts) && 817 (Pos == STRING_NOTFOUND)); 818 819 if (Pos != STRING_NOTFOUND) 820 { 821 pEditView->SetSelection(ESelection (eSelection.nStartPara, Pos, eSelection.nStartPara, Pos + 3)); 822 } 823 } 824 } 825 826 sal_Bool SmEditWindow::HasMark(const String& rText) const 827 // returns true iff 'rText' contains a mark 828 { 829 return rText.SearchAscii("<?>", 0) != STRING_NOTFOUND; 830 } 831 832 void SmEditWindow::MouseMove(const MouseEvent &rEvt) 833 { 834 if (pEditView) 835 pEditView->MouseMove(rEvt); 836 } 837 838 sal_Int8 SmEditWindow::AcceptDrop( const AcceptDropEvent& /*rEvt*/ ) 839 { 840 return pEditView ? /*pEditView->QueryDrop( rEvt )*/DND_ACTION_NONE: DND_ACTION_NONE; 841 } 842 843 sal_Int8 SmEditWindow::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ ) 844 { 845 return pEditView ? /*pEditView->Drop( rEvt )*/DND_ACTION_NONE : DND_ACTION_NONE; 846 } 847 848 ESelection SmEditWindow::GetSelection() const 849 { 850 // pointer may be 0 when reloading a document and the old view 851 // was already destroyed 852 //(DBG_ASSERT( pEditView, "NULL pointer" ); 853 ESelection eSel; 854 if (pEditView) 855 eSel = pEditView->GetSelection(); 856 return eSel; 857 } 858 859 void SmEditWindow::SetSelection(const ESelection &rSel) 860 { 861 DBG_ASSERT( pEditView, "NULL pointer" ); 862 if (pEditView) 863 pEditView->SetSelection(rSel); 864 InvalidateSlots(); 865 } 866 867 sal_Bool SmEditWindow::IsEmpty() const 868 { 869 EditEngine *pEditEngine = ((SmEditWindow *) this)->GetEditEngine(); 870 sal_Bool bEmpty = sal::static_int_cast< sal_Bool >( 871 pEditEngine ? pEditEngine->GetTextLen() == 0 : sal_False); 872 return bEmpty; 873 } 874 875 sal_Bool SmEditWindow::IsSelected() const 876 { 877 return pEditView ? pEditView->HasSelection() : sal_False; 878 } 879 880 void SmEditWindow::Cut() 881 { 882 DBG_ASSERT( pEditView, "EditView missing" ); 883 if (pEditView) 884 { 885 pEditView->Cut(); 886 GetDoc()->SetModified( sal_True ); 887 } 888 } 889 890 void SmEditWindow::Copy() 891 { 892 DBG_ASSERT( pEditView, "EditView missing" ); 893 if (pEditView) 894 pEditView->Copy(); 895 } 896 897 void SmEditWindow::Paste() 898 { 899 DBG_ASSERT( pEditView, "EditView missing" ); 900 if (pEditView) 901 { 902 pEditView->Paste(); 903 GetDoc()->SetModified( sal_True ); 904 } 905 } 906 907 void SmEditWindow::Delete() 908 { 909 DBG_ASSERT( pEditView, "EditView missing" ); 910 if (pEditView) 911 { 912 pEditView->DeleteSelected(); 913 GetDoc()->SetModified( sal_True ); 914 } 915 } 916 917 void SmEditWindow::InsertText(const String& Text) 918 { 919 DBG_ASSERT( pEditView, "EditView missing" ); 920 if (pEditView) 921 { 922 pEditView->InsertText(Text); 923 aModifyTimer.Start(); 924 aCursorMoveTimer.Start(); 925 } 926 } 927 928 void SmEditWindow::Flush() 929 { 930 EditEngine *pEditEngine = GetEditEngine(); 931 if (pEditEngine && pEditEngine->IsModified()) 932 { 933 pEditEngine->ClearModifyFlag(); 934 SmViewShell *pViewSh = rCmdBox.GetView(); 935 if (pViewSh) 936 { 937 pViewSh->GetViewFrame()->GetDispatcher()->Execute( 938 SID_TEXT, SFX_CALLMODE_STANDARD, 939 new SfxStringItem(SID_TEXT, GetText()), 0L); 940 } 941 } 942 943 if (aCursorMoveTimer.IsActive()) 944 { 945 aCursorMoveTimer.Stop(); 946 // ggf noch die (neue) FormulaCursor Position setzen 947 CursorMoveTimerHdl(&aCursorMoveTimer); 948 } 949 } 950 951 952 void SmEditWindow::DeleteEditView( SmViewShell & /*rView*/ ) 953 { 954 if (pEditView) 955 { 956 EditEngine *pEditEngine = pEditView->GetEditEngine(); 957 if (pEditEngine) 958 { 959 pEditEngine->SetStatusEventHdl( Link() ); 960 pEditEngine->RemoveView( pEditView ); 961 } 962 delete pEditView; 963 pEditView = 0; 964 } 965 } 966 967 968 uno::Reference< XAccessible > SmEditWindow::CreateAccessible() 969 { 970 if (!pAccessible) 971 { 972 pAccessible = new SmEditAccessible( this ); 973 xAccessible = pAccessible; 974 pAccessible->Init(); 975 } 976 return xAccessible; 977 } 978 979