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 UpdateStatus(); 249 aModifyTimer.Stop(); 250 return 0; 251 } 252 253 254 IMPL_LINK(SmEditWindow, CursorMoveTimerHdl, Timer *, EMPTYARG /*pTimer*/) 255 // every once in a while check cursor position (selection) of edit 256 // window and if it has changed (try to) set the formula-cursor 257 // according to that. 258 { 259 ESelection aNewSelection (GetSelection()); 260 261 if (!aNewSelection.IsEqual(aOldSelection)) 262 { SmViewShell *pView = rCmdBox.GetView(); 263 264 if (pView) 265 { 266 // get row and column to look for 267 sal_uInt16 nRow, nCol; 268 SmGetLeftSelectionPart(aNewSelection, nRow, nCol); 269 nRow++; 270 nCol++; 271 272 pView->GetGraphicWindow().SetCursorPos(nRow, nCol); 273 274 aOldSelection = aNewSelection; 275 } 276 } 277 aCursorMoveTimer.Stop(); 278 279 return 0; 280 } 281 282 283 void SmEditWindow::Resize() 284 { 285 if (!pEditView) 286 CreateEditView(); 287 288 if (pEditView) 289 { 290 pEditView->SetOutputArea(AdjustScrollBars()); 291 pEditView->ShowCursor(); 292 293 DBG_ASSERT( pEditView->GetEditEngine(), "EditEngine missing" ); 294 const long nMaxVisAreaStart = pEditView->GetEditEngine()->GetTextHeight() - 295 pEditView->GetOutputArea().GetHeight(); 296 if (pEditView->GetVisArea().Top() > nMaxVisAreaStart) 297 { 298 Rectangle aVisArea(pEditView->GetVisArea() ); 299 aVisArea.Top() = (nMaxVisAreaStart > 0 ) ? nMaxVisAreaStart : 0; 300 aVisArea.SetSize(pEditView->GetOutputArea().GetSize()); 301 pEditView->SetVisArea(aVisArea); 302 pEditView->ShowCursor(); 303 } 304 InitScrollBars(); 305 } 306 Invalidate(); 307 } 308 309 void SmEditWindow::MouseButtonUp(const MouseEvent &rEvt) 310 { 311 if (pEditView) 312 pEditView->MouseButtonUp(rEvt); 313 else 314 Window::MouseButtonUp (rEvt); 315 316 // ggf FormulaCursor neu positionieren 317 CursorMoveTimerHdl(&aCursorMoveTimer); 318 InvalidateSlots(); 319 } 320 321 void SmEditWindow::MouseButtonDown(const MouseEvent &rEvt) 322 { 323 if (pEditView) 324 pEditView->MouseButtonDown(rEvt); 325 else 326 Window::MouseButtonDown (rEvt); 327 328 GrabFocus(); 329 } 330 331 void SmEditWindow::Command(const CommandEvent& rCEvt) 332 { 333 sal_Bool bForwardEvt = sal_True; 334 if (rCEvt.GetCommand() == COMMAND_CONTEXTMENU) 335 { 336 GetParent()->ToTop(); 337 338 Point aPoint = rCEvt.GetMousePosPixel(); 339 PopupMenu* pPopupMenu = new PopupMenu(SmResId(RID_COMMANDMENU)); 340 341 // added for replaceability of context menus #96085, #93782 342 Menu* pMenu = NULL; 343 ::com::sun::star::ui::ContextMenuExecuteEvent aEvent; 344 aEvent.SourceWindow = VCLUnoHelper::GetInterface( this ); 345 aEvent.ExecutePosition.X = aPoint.X(); 346 aEvent.ExecutePosition.Y = aPoint.Y(); 347 ::rtl::OUString sDummy; 348 if ( GetView()->TryContextMenuInterception( *pPopupMenu, sDummy, pMenu, aEvent ) ) 349 { 350 if ( pMenu ) 351 { 352 delete pPopupMenu; 353 pPopupMenu = (PopupMenu*) pMenu; 354 } 355 } 356 357 pPopupMenu->SetSelectHdl(LINK(this, SmEditWindow, MenuSelectHdl)); 358 359 pPopupMenu->Execute( this, aPoint ); 360 delete pPopupMenu; 361 bForwardEvt = sal_False; 362 } 363 else if (rCEvt.GetCommand() == COMMAND_WHEEL) 364 bForwardEvt = !HandleWheelCommands( rCEvt ); 365 366 if (bForwardEvt) 367 { 368 if (pEditView) 369 pEditView->Command( rCEvt ); 370 else 371 Window::Command (rCEvt); 372 } 373 } 374 375 376 sal_Bool SmEditWindow::HandleWheelCommands( const CommandEvent &rCEvt ) 377 { 378 sal_Bool bCommandHandled = sal_False; // true if the CommandEvent needs not 379 // to be passed on (because it has fully 380 // been taken care of). 381 382 const CommandWheelData* pWData = rCEvt.GetWheelData(); 383 if (pWData) 384 { 385 if (COMMAND_WHEEL_ZOOM == pWData->GetMode()) 386 bCommandHandled = sal_True; // no zooming in Command window 387 else 388 bCommandHandled = HandleScrollCommand( rCEvt, pHScrollBar, pVScrollBar); 389 } 390 391 return bCommandHandled; 392 } 393 394 395 IMPL_LINK_INLINE_START( SmEditWindow, MenuSelectHdl, Menu *, pMenu ) 396 { 397 SmViewShell *pViewSh = rCmdBox.GetView(); 398 if (pViewSh) 399 pViewSh->GetViewFrame()->GetDispatcher()->Execute( 400 SID_INSERTCOMMAND, SFX_CALLMODE_STANDARD, 401 new SfxInt16Item(SID_INSERTCOMMAND, pMenu->GetCurItemId()), 0L); 402 return 0; 403 } 404 IMPL_LINK_INLINE_END( SmEditWindow, MenuSelectHdl, Menu *, pMenu ) 405 406 void SmEditWindow::KeyInput(const KeyEvent& rKEvt) 407 { 408 if (rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE) 409 { 410 sal_Bool bCallBase = sal_True; 411 SfxViewShell* pViewShell = GetView(); 412 if ( pViewShell && pViewShell->ISA(SmViewShell) ) 413 { 414 // Terminate possible InPlace mode 415 bCallBase = !pViewShell->Escape(); 416 } 417 if ( bCallBase ) 418 Window::KeyInput( rKEvt ); 419 } 420 else 421 { 422 // Timer neu starten, um den Handler (auch bei laengeren Eingaben) 423 // moeglichst nur einmal am Ende aufzurufen. 424 aCursorMoveTimer.Start(); 425 426 DBG_ASSERT( pEditView, "EditView missing (NULL pointer)" ); 427 if (!pEditView) 428 CreateEditView(); 429 if ( !pEditView->PostKeyEvent(rKEvt) ) 430 { 431 SmViewShell *pView = GetView(); 432 if ( pView && !pView->KeyInput(rKEvt) ) 433 { 434 /* fuert bei F1 (Hilfe) zum Zerstoeren von this! */ 435 Flush(); 436 if ( aModifyTimer.IsActive() ) 437 aModifyTimer.Stop(); 438 Window::KeyInput(rKEvt); 439 } 440 else 441 { 442 //SFX hat evtl. Slot an der View gecallt und dabei (wg. Hack 443 //im SFX) den Focus auf die View gesetzt 444 SfxViewShell* pVShell = GetView(); 445 if ( pVShell && pVShell->ISA(SmViewShell) && 446 ((SmViewShell*)pVShell)->GetGraphicWindow().HasFocus() ) 447 { 448 GrabFocus(); 449 } 450 } 451 } 452 else 453 { 454 // have doc-shell modified only for formula input/change and not 455 // cursor travelling and such things... 456 SmDocShell *pDocShell = GetDoc(); 457 if (pDocShell) 458 pDocShell->SetModified( GetEditEngine()->IsModified() ); 459 460 aModifyTimer.Start(); 461 } 462 463 InvalidateSlots(); 464 } 465 } 466 467 void SmEditWindow::Paint(const Rectangle& rRect) 468 { 469 if (!pEditView) 470 CreateEditView(); 471 pEditView->Paint(rRect); 472 } 473 474 void SmEditWindow::CreateEditView() 475 { 476 EditEngine *pEditEngine = GetEditEngine(); 477 478 //! pEditEngine and pEditView may be 0. 479 //! For example when the program is used by the document-converter 480 if (!pEditView && pEditEngine) 481 { 482 pEditView = new EditView( pEditEngine, this ); 483 pEditEngine->InsertView( pEditView ); 484 485 if (!pVScrollBar) 486 pVScrollBar = new ScrollBar(this, WinBits(WB_VSCROLL)); 487 if (!pHScrollBar) 488 pHScrollBar = new ScrollBar(this, WinBits(WB_HSCROLL)); 489 if (!pScrollBox) 490 pScrollBox = new ScrollBarBox(this); 491 pVScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl)); 492 pHScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl)); 493 pVScrollBar->EnableDrag( sal_True ); 494 pHScrollBar->EnableDrag( sal_True ); 495 496 pEditView->SetOutputArea(AdjustScrollBars()); 497 498 ESelection eSelection; 499 500 pEditView->SetSelection(eSelection); 501 Update(); 502 pEditView->ShowCursor(sal_True, sal_True); 503 504 pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) ); 505 SetPointer(pEditView->GetPointer()); 506 507 SetScrollBarRanges(); 508 } 509 } 510 511 512 IMPL_LINK( SmEditWindow, EditStatusHdl, EditStatus *, EMPTYARG /*pStat*/ ) 513 { 514 if (!pEditView) 515 return 1; 516 else 517 { 518 Resize(); 519 return 0; 520 } 521 } 522 523 IMPL_LINK_INLINE_START( SmEditWindow, ScrollHdl, ScrollBar *, EMPTYARG /*pScrollBar*/ ) 524 { 525 DBG_ASSERT(pEditView, "EditView missing"); 526 if (pEditView) 527 { 528 pEditView->SetVisArea(Rectangle(Point(pHScrollBar->GetThumbPos(), 529 pVScrollBar->GetThumbPos()), 530 pEditView->GetVisArea().GetSize())); 531 pEditView->Invalidate(); 532 } 533 return 0; 534 } 535 IMPL_LINK_INLINE_END( SmEditWindow, ScrollHdl, ScrollBar *, pScrollBar ) 536 537 Rectangle SmEditWindow::AdjustScrollBars() 538 { 539 const Size aOut( GetOutputSizePixel() ); 540 Point aPoint; 541 Rectangle aRect( aPoint, aOut ); 542 543 if (pVScrollBar && pHScrollBar && pScrollBox) 544 { 545 const long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize(); 546 Point aPt( aRect.TopRight() ); aPt.X() -= nTmp -1L; 547 pVScrollBar->SetPosSizePixel( aPt, Size(nTmp, aOut.Height() - nTmp)); 548 549 aPt = aRect.BottomLeft(); aPt.Y() -= nTmp - 1L; 550 pHScrollBar->SetPosSizePixel( aPt, Size(aOut.Width() - nTmp, nTmp)); 551 552 aPt.X() = pHScrollBar->GetSizePixel().Width(); 553 aPt.Y() = pVScrollBar->GetSizePixel().Height(); 554 pScrollBox->SetPosSizePixel(aPt, Size(nTmp, nTmp )); 555 556 aRect.Right() = aPt.X() - 2; 557 aRect.Bottom() = aPt.Y() - 2; 558 } 559 return aRect; 560 } 561 562 void SmEditWindow::SetScrollBarRanges() 563 { 564 // Extra-Methode, nicht InitScrollBars, da auch fuer EditEngine-Events. 565 EditEngine *pEditEngine = GetEditEngine(); 566 if (pVScrollBar && pHScrollBar && pEditEngine && pEditView) 567 { 568 long nTmp = pEditEngine->GetTextHeight(); 569 pVScrollBar->SetRange(Range(0, nTmp)); 570 pVScrollBar->SetThumbPos(pEditView->GetVisArea().Top()); 571 572 nTmp = pEditEngine->GetPaperSize().Width(); 573 pHScrollBar->SetRange(Range(0,nTmp)); 574 pHScrollBar->SetThumbPos(pEditView->GetVisArea().Left()); 575 } 576 } 577 578 void SmEditWindow::InitScrollBars() 579 { 580 if (pVScrollBar && pHScrollBar && pScrollBox && pEditView) 581 { 582 const Size aOut( pEditView->GetOutputArea().GetSize() ); 583 pVScrollBar->SetVisibleSize(aOut.Height()); 584 pVScrollBar->SetPageSize(aOut.Height() * 8 / 10); 585 pVScrollBar->SetLineSize(aOut.Height() * 2 / 10); 586 587 pHScrollBar->SetVisibleSize(aOut.Width()); 588 pHScrollBar->SetPageSize(aOut.Width() * 8 / 10); 589 pHScrollBar->SetLineSize(SCROLL_LINE ); 590 591 SetScrollBarRanges(); 592 593 pVScrollBar->Show(); 594 pHScrollBar->Show(); 595 pScrollBox->Show(); 596 } 597 } 598 599 600 String SmEditWindow::GetText() const 601 { 602 String aText; 603 EditEngine *pEditEngine = const_cast< SmEditWindow* >(this)->GetEditEngine(); 604 DBG_ASSERT( pEditEngine, "EditEngine missing" ); 605 if (pEditEngine) 606 aText = pEditEngine->GetText( LINEEND_LF ); 607 return aText; 608 } 609 610 611 void SmEditWindow::SetText(const XubString& rText) 612 { 613 EditEngine *pEditEngine = GetEditEngine(); 614 DBG_ASSERT( pEditEngine, "EditEngine missing" ); 615 if (pEditEngine && !pEditEngine->IsModified()) 616 { 617 if (!pEditView) 618 CreateEditView(); 619 620 ESelection eSelection = pEditView->GetSelection(); 621 622 pEditEngine->SetText(rText); 623 pEditEngine->ClearModifyFlag(); 624 625 //! Hier die Timer neu zu starten verhindert, dass die Handler fuer andere 626 //! (im Augenblick nicht mehr aktive) Math Tasks aufgerufen werden. 627 aModifyTimer.Start(); 628 aCursorMoveTimer.Start(); 629 630 pEditView->SetSelection(eSelection); 631 } 632 } 633 634 635 void SmEditWindow::GetFocus() 636 { 637 Window::GetFocus(); 638 639 if (xAccessible.is()) 640 { 641 // Note: will implicitly send the AccessibleStateType::FOCUSED event 642 ::accessibility::AccessibleTextHelper *pHelper = pAccessible->GetTextHelper(); 643 if (pHelper) 644 pHelper->SetFocus( sal_True ); 645 } 646 647 if (!pEditView) 648 CreateEditView(); 649 EditEngine *pEditEngine = GetEditEngine(); 650 if (pEditEngine) 651 pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) ); 652 } 653 654 655 void SmEditWindow::LoseFocus() 656 { 657 EditEngine *pEditEngine = GetEditEngine(); 658 if (pEditEngine) 659 pEditEngine->SetStatusEventHdl( Link() ); 660 661 Window::LoseFocus(); 662 663 if (xAccessible.is()) 664 { 665 // Note: will implicitly send the AccessibleStateType::FOCUSED event 666 ::accessibility::AccessibleTextHelper *pHelper = pAccessible->GetTextHelper(); 667 if (pHelper) 668 pHelper->SetFocus( sal_False ); 669 } 670 } 671 672 673 sal_Bool SmEditWindow::IsAllSelected() const 674 { 675 sal_Bool bRes = sal_False; 676 EditEngine *pEditEngine = ((SmEditWindow *) this)->GetEditEngine(); 677 DBG_ASSERT( pEditView, "NULL pointer" ); 678 DBG_ASSERT( pEditEngine, "NULL pointer" ); 679 if (pEditEngine && pEditView) 680 { 681 ESelection eSelection( pEditView->GetSelection() ); 682 sal_Int32 nParaCnt = pEditEngine->GetParagraphCount(); 683 if (!(nParaCnt - 1)) 684 { 685 String Text( pEditEngine->GetText( LINEEND_LF ) ); 686 bRes = !eSelection.nStartPos && (eSelection.nEndPos == Text.Len () - 1); 687 } 688 else 689 { 690 bRes = !eSelection.nStartPara && (eSelection.nEndPara == nParaCnt - 1); 691 } 692 } 693 return bRes; 694 } 695 696 void SmEditWindow::SelectAll() 697 { 698 DBG_ASSERT( pEditView, "NULL pointer" ); 699 if (pEditView) 700 { 701 // 0xFFFF as last two parameters refers to the end of the text 702 pEditView->SetSelection( ESelection( 0, 0, 0xFFFF, 0xFFFF ) ); 703 } 704 } 705 706 void SmEditWindow::InsertCommand(sal_uInt16 nCommand) 707 { 708 DBG_ASSERT( pEditView, "EditView missing" ); 709 if (pEditView) 710 { 711 //Anfang der Selektion merken und hinterher den Cursor daraufsetzen. Nur so 712 //macht das SelNextMark() Sinn. 713 ESelection aSelection = pEditView->GetSelection(); 714 aSelection.nEndPos = aSelection.nStartPos; 715 aSelection.nEndPara = aSelection.nStartPara; 716 717 DBG_ASSERT( pEditView, "NULL pointer" ); 718 String aText = String(SmResId(nCommand)); 719 pEditView->InsertText(aText); 720 721 if (HasMark(aText)) 722 { // set selection to next mark 723 pEditView->SetSelection(aSelection); 724 SelNextMark(); 725 } 726 else 727 { // set selection after inserted text 728 aSelection.nEndPos = aSelection.nEndPos + sal::static_int_cast< xub_StrLen >(aText.Len()); 729 aSelection.nStartPos = aSelection.nEndPos; 730 pEditView->SetSelection(aSelection); 731 } 732 733 aModifyTimer.Start(); 734 aCursorMoveTimer.Start(); 735 736 GrabFocus(); 737 } 738 } 739 740 void SmEditWindow::MarkError(const Point &rPos) 741 { 742 DBG_ASSERT( pEditView, "EditView missing" ); 743 if (pEditView) 744 { 745 const xub_StrLen nCol = sal::static_int_cast< xub_StrLen >(rPos.X()); 746 const sal_uInt16 nRow = sal::static_int_cast< sal_uInt16 >(rPos.Y() - 1); 747 748 pEditView->SetSelection(ESelection(nRow, nCol - 1, nRow, nCol)); 749 GrabFocus(); 750 } 751 } 752 753 void SmEditWindow::SelNextMark() 754 { 755 EditEngine *pEditEngine = GetEditEngine(); 756 DBG_ASSERT( pEditView, "NULL pointer" ); 757 DBG_ASSERT( pEditEngine, "NULL pointer" ); 758 if (pEditEngine && pEditView) 759 { 760 ESelection eSelection = pEditView->GetSelection(); 761 sal_uInt16 Pos = eSelection.nEndPos; 762 String aMark (C2S("<?>")); 763 String aText; 764 sal_uInt16 nCounts = pEditEngine->GetParagraphCount(); 765 766 while (eSelection.nEndPara < nCounts) 767 { 768 aText = pEditEngine->GetText( eSelection.nEndPara ); 769 Pos = aText.Search(aMark, Pos); 770 771 if (Pos != STRING_NOTFOUND) 772 { 773 pEditView->SetSelection(ESelection (eSelection.nEndPara, Pos, eSelection.nEndPara, Pos + 3)); 774 break; 775 } 776 777 Pos = 0; 778 eSelection.nEndPara++; 779 } 780 } 781 } 782 783 void SmEditWindow::SelPrevMark() 784 { 785 EditEngine *pEditEngine = GetEditEngine(); 786 DBG_ASSERT( pEditEngine, "NULL pointer" ); 787 DBG_ASSERT( pEditView, "NULL pointer" ); 788 if (pEditEngine && pEditView) 789 { 790 ESelection eSelection = pEditView->GetSelection(); 791 sal_uInt16 Pos = STRING_NOTFOUND; 792 xub_StrLen Max = eSelection.nStartPos; 793 String Text( pEditEngine->GetText( eSelection.nStartPara ) ); 794 String aMark (C2S("<?>")); 795 sal_uInt16 nCounts = pEditEngine->GetParagraphCount(); 796 797 do 798 { 799 sal_uInt16 Fnd = Text.Search(aMark, 0); 800 801 while ((Fnd < Max) && (Fnd != STRING_NOTFOUND)) 802 { 803 Pos = Fnd; 804 Fnd = Text.Search(aMark, Fnd + 1); 805 } 806 807 if (Pos == STRING_NOTFOUND) 808 { 809 eSelection.nStartPara--; 810 Text = pEditEngine->GetText( eSelection.nStartPara ); 811 Max = Text.Len(); 812 } 813 } 814 while ((eSelection.nStartPara < nCounts) && 815 (Pos == STRING_NOTFOUND)); 816 817 if (Pos != STRING_NOTFOUND) 818 { 819 pEditView->SetSelection(ESelection (eSelection.nStartPara, Pos, eSelection.nStartPara, Pos + 3)); 820 } 821 } 822 } 823 824 sal_Bool SmEditWindow::HasMark(const String& rText) const 825 // returns true iff 'rText' contains a mark 826 { 827 return rText.SearchAscii("<?>", 0) != STRING_NOTFOUND; 828 } 829 830 void SmEditWindow::MouseMove(const MouseEvent &rEvt) 831 { 832 if (pEditView) 833 pEditView->MouseMove(rEvt); 834 } 835 836 sal_Int8 SmEditWindow::AcceptDrop( const AcceptDropEvent& /*rEvt*/ ) 837 { 838 return pEditView ? /*pEditView->QueryDrop( rEvt )*/DND_ACTION_NONE: DND_ACTION_NONE; 839 } 840 841 sal_Int8 SmEditWindow::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ ) 842 { 843 return pEditView ? /*pEditView->Drop( rEvt )*/DND_ACTION_NONE : DND_ACTION_NONE; 844 } 845 846 ESelection SmEditWindow::GetSelection() const 847 { 848 // pointer may be 0 when reloading a document and the old view 849 // was already destroyed 850 //(DBG_ASSERT( pEditView, "NULL pointer" ); 851 ESelection eSel; 852 if (pEditView) 853 eSel = pEditView->GetSelection(); 854 return eSel; 855 } 856 857 void SmEditWindow::SetSelection(const ESelection &rSel) 858 { 859 DBG_ASSERT( pEditView, "NULL pointer" ); 860 if (pEditView) 861 pEditView->SetSelection(rSel); 862 InvalidateSlots(); 863 } 864 865 sal_Bool SmEditWindow::IsEmpty() const 866 { 867 EditEngine *pEditEngine = ((SmEditWindow *) this)->GetEditEngine(); 868 sal_Bool bEmpty = sal::static_int_cast< sal_Bool >( 869 pEditEngine ? pEditEngine->GetTextLen() == 0 : sal_False); 870 return bEmpty; 871 } 872 873 sal_Bool SmEditWindow::IsSelected() const 874 { 875 return pEditView ? pEditView->HasSelection() : sal_False; 876 } 877 878 879 void SmEditWindow::UpdateStatus( bool bSetDocModified ) 880 { 881 SmModule *pMod = SM_MOD(); 882 if (pMod && pMod->GetConfig()->IsAutoRedraw()) 883 Flush(); 884 if ( bSetDocModified ) 885 GetDoc()->SetModified( sal_True ); 886 } 887 888 void SmEditWindow::Cut() 889 { 890 DBG_ASSERT( pEditView, "EditView missing" ); 891 if (pEditView) 892 { 893 pEditView->Cut(); 894 UpdateStatus( sal_True ); 895 } 896 } 897 898 void SmEditWindow::Copy() 899 { 900 DBG_ASSERT( pEditView, "EditView missing" ); 901 if (pEditView) 902 pEditView->Copy(); 903 } 904 905 void SmEditWindow::Paste() 906 { 907 DBG_ASSERT( pEditView, "EditView missing" ); 908 if (pEditView) 909 { 910 pEditView->Paste(); 911 UpdateStatus( sal_True ); 912 } 913 } 914 915 void SmEditWindow::Delete() 916 { 917 DBG_ASSERT( pEditView, "EditView missing" ); 918 if (pEditView) 919 { 920 pEditView->DeleteSelected(); 921 UpdateStatus( sal_True ); 922 } 923 } 924 925 void SmEditWindow::InsertText(const String& Text) 926 { 927 DBG_ASSERT( pEditView, "EditView missing" ); 928 if (pEditView) 929 { 930 pEditView->InsertText(Text); 931 aModifyTimer.Start(); 932 aCursorMoveTimer.Start(); 933 } 934 } 935 936 void SmEditWindow::Flush() 937 { 938 EditEngine *pEditEngine = GetEditEngine(); 939 if (pEditEngine && pEditEngine->IsModified()) 940 { 941 pEditEngine->ClearModifyFlag(); 942 SmViewShell *pViewSh = rCmdBox.GetView(); 943 if (pViewSh) 944 { 945 pViewSh->GetViewFrame()->GetDispatcher()->Execute( 946 SID_TEXT, SFX_CALLMODE_STANDARD, 947 new SfxStringItem(SID_TEXT, GetText()), 0L); 948 } 949 } 950 951 if (aCursorMoveTimer.IsActive()) 952 { 953 aCursorMoveTimer.Stop(); 954 // ggf noch die (neue) FormulaCursor Position setzen 955 CursorMoveTimerHdl(&aCursorMoveTimer); 956 } 957 } 958 959 960 void SmEditWindow::DeleteEditView( SmViewShell & /*rView*/ ) 961 { 962 if (pEditView) 963 { 964 EditEngine *pEditEngine = pEditView->GetEditEngine(); 965 if (pEditEngine) 966 { 967 pEditEngine->SetStatusEventHdl( Link() ); 968 pEditEngine->RemoveView( pEditView ); 969 } 970 delete pEditView; 971 pEditView = 0; 972 } 973 } 974 975 976 uno::Reference< XAccessible > SmEditWindow::CreateAccessible() 977 { 978 if (!pAccessible) 979 { 980 pAccessible = new SmEditAccessible( this ); 981 xAccessible = pAccessible; 982 pAccessible->Init(); 983 } 984 return xAccessible; 985 } 986 987