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 pEditView->SetSelection( ESelection( 0, 0, EE_PARA_MAX, EE_INDEX_MAX ) ); 702 } 703 } 704 705 void SmEditWindow::InsertCommand(sal_uInt16 nCommand) 706 { 707 DBG_ASSERT( pEditView, "EditView missing" ); 708 if (pEditView) 709 { 710 //Anfang der Selektion merken und hinterher den Cursor daraufsetzen. Nur so 711 //macht das SelNextMark() Sinn. 712 ESelection aSelection = pEditView->GetSelection(); 713 aSelection.nEndPos = aSelection.nStartPos; 714 aSelection.nEndPara = aSelection.nStartPara; 715 716 DBG_ASSERT( pEditView, "NULL pointer" ); 717 String aText = String(SmResId(nCommand)); 718 pEditView->InsertText(aText); 719 720 if (HasMark(aText)) 721 { // set selection to next mark 722 pEditView->SetSelection(aSelection); 723 SelNextMark(); 724 } 725 else 726 { // set selection after inserted text 727 aSelection.nEndPos = aSelection.nEndPos + sal::static_int_cast< xub_StrLen >(aText.Len()); 728 aSelection.nStartPos = aSelection.nEndPos; 729 pEditView->SetSelection(aSelection); 730 } 731 732 aModifyTimer.Start(); 733 aCursorMoveTimer.Start(); 734 735 GrabFocus(); 736 } 737 } 738 739 void SmEditWindow::MarkError(const Point &rPos) 740 { 741 DBG_ASSERT( pEditView, "EditView missing" ); 742 if (pEditView) 743 { 744 const xub_StrLen nCol = sal::static_int_cast< xub_StrLen >(rPos.X()); 745 const sal_uInt16 nRow = sal::static_int_cast< sal_uInt16 >(rPos.Y() - 1); 746 747 pEditView->SetSelection(ESelection(nRow, nCol - 1, nRow, nCol)); 748 GrabFocus(); 749 } 750 } 751 752 void SmEditWindow::SelNextMark() 753 { 754 EditEngine *pEditEngine = GetEditEngine(); 755 DBG_ASSERT( pEditView, "NULL pointer" ); 756 DBG_ASSERT( pEditEngine, "NULL pointer" ); 757 if (pEditEngine && pEditView) 758 { 759 ESelection eSelection = pEditView->GetSelection(); 760 sal_uInt16 Pos = eSelection.nEndPos; 761 String aMark (C2S("<?>")); 762 String aText; 763 sal_uInt32 nCounts = pEditEngine->GetParagraphCount(); 764 765 while (eSelection.nEndPara < nCounts) 766 { 767 aText = pEditEngine->GetText( eSelection.nEndPara ); 768 Pos = aText.Search(aMark, Pos); 769 770 if (Pos != STRING_NOTFOUND) 771 { 772 pEditView->SetSelection(ESelection (eSelection.nEndPara, Pos, eSelection.nEndPara, Pos + 3)); 773 break; 774 } 775 776 Pos = 0; 777 eSelection.nEndPara++; 778 } 779 } 780 } 781 782 void SmEditWindow::SelPrevMark() 783 { 784 EditEngine *pEditEngine = GetEditEngine(); 785 DBG_ASSERT( pEditEngine, "NULL pointer" ); 786 DBG_ASSERT( pEditView, "NULL pointer" ); 787 if (pEditEngine && pEditView) 788 { 789 ESelection eSelection = pEditView->GetSelection(); 790 sal_uInt16 Pos = STRING_NOTFOUND; 791 xub_StrLen Max = eSelection.nStartPos; 792 String Text( pEditEngine->GetText( eSelection.nStartPara ) ); 793 String aMark (C2S("<?>")); 794 sal_uInt16 nCounts = pEditEngine->GetParagraphCount(); 795 796 do 797 { 798 sal_uInt16 Fnd = Text.Search(aMark, 0); 799 800 while ((Fnd < Max) && (Fnd != STRING_NOTFOUND)) 801 { 802 Pos = Fnd; 803 Fnd = Text.Search(aMark, Fnd + 1); 804 } 805 806 if (Pos == STRING_NOTFOUND) 807 { 808 eSelection.nStartPara--; 809 Text = pEditEngine->GetText( eSelection.nStartPara ); 810 Max = Text.Len(); 811 } 812 } 813 while ((eSelection.nStartPara < nCounts) && 814 (Pos == STRING_NOTFOUND)); 815 816 if (Pos != STRING_NOTFOUND) 817 { 818 pEditView->SetSelection(ESelection (eSelection.nStartPara, Pos, eSelection.nStartPara, Pos + 3)); 819 } 820 } 821 } 822 823 sal_Bool SmEditWindow::HasMark(const String& rText) const 824 // returns true iff 'rText' contains a mark 825 { 826 return rText.SearchAscii("<?>", 0) != STRING_NOTFOUND; 827 } 828 829 void SmEditWindow::MouseMove(const MouseEvent &rEvt) 830 { 831 if (pEditView) 832 pEditView->MouseMove(rEvt); 833 } 834 835 sal_Int8 SmEditWindow::AcceptDrop( const AcceptDropEvent& /*rEvt*/ ) 836 { 837 return pEditView ? /*pEditView->QueryDrop( rEvt )*/DND_ACTION_NONE: DND_ACTION_NONE; 838 } 839 840 sal_Int8 SmEditWindow::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ ) 841 { 842 return pEditView ? /*pEditView->Drop( rEvt )*/DND_ACTION_NONE : DND_ACTION_NONE; 843 } 844 845 ESelection SmEditWindow::GetSelection() const 846 { 847 // pointer may be 0 when reloading a document and the old view 848 // was already destroyed 849 //(DBG_ASSERT( pEditView, "NULL pointer" ); 850 ESelection eSel; 851 if (pEditView) 852 eSel = pEditView->GetSelection(); 853 return eSel; 854 } 855 856 void SmEditWindow::SetSelection(const ESelection &rSel) 857 { 858 DBG_ASSERT( pEditView, "NULL pointer" ); 859 if (pEditView) 860 pEditView->SetSelection(rSel); 861 InvalidateSlots(); 862 } 863 864 sal_Bool SmEditWindow::IsEmpty() const 865 { 866 EditEngine *pEditEngine = ((SmEditWindow *) this)->GetEditEngine(); 867 sal_Bool bEmpty = sal::static_int_cast< sal_Bool >( 868 pEditEngine ? pEditEngine->GetTextLen() == 0 : sal_False); 869 return bEmpty; 870 } 871 872 sal_Bool SmEditWindow::IsSelected() const 873 { 874 return pEditView ? pEditView->HasSelection() : sal_False; 875 } 876 877 878 void SmEditWindow::UpdateStatus( bool bSetDocModified ) 879 { 880 SmModule *pMod = SM_MOD(); 881 if (pMod && pMod->GetConfig()->IsAutoRedraw()) 882 Flush(); 883 if ( bSetDocModified ) 884 GetDoc()->SetModified( sal_True ); 885 } 886 887 void SmEditWindow::Cut() 888 { 889 DBG_ASSERT( pEditView, "EditView missing" ); 890 if (pEditView) 891 { 892 pEditView->Cut(); 893 UpdateStatus( sal_True ); 894 } 895 } 896 897 void SmEditWindow::Copy() 898 { 899 DBG_ASSERT( pEditView, "EditView missing" ); 900 if (pEditView) 901 pEditView->Copy(); 902 } 903 904 void SmEditWindow::Paste() 905 { 906 DBG_ASSERT( pEditView, "EditView missing" ); 907 if (pEditView) 908 { 909 pEditView->Paste(); 910 UpdateStatus( sal_True ); 911 } 912 } 913 914 void SmEditWindow::Delete() 915 { 916 DBG_ASSERT( pEditView, "EditView missing" ); 917 if (pEditView) 918 { 919 pEditView->DeleteSelected(); 920 UpdateStatus( sal_True ); 921 } 922 } 923 924 void SmEditWindow::InsertText(const String& Text) 925 { 926 DBG_ASSERT( pEditView, "EditView missing" ); 927 if (pEditView) 928 { 929 pEditView->InsertText(Text); 930 aModifyTimer.Start(); 931 aCursorMoveTimer.Start(); 932 } 933 } 934 935 void SmEditWindow::Flush() 936 { 937 EditEngine *pEditEngine = GetEditEngine(); 938 if (pEditEngine && pEditEngine->IsModified()) 939 { 940 pEditEngine->ClearModifyFlag(); 941 SmViewShell *pViewSh = rCmdBox.GetView(); 942 if (pViewSh) 943 { 944 pViewSh->GetViewFrame()->GetDispatcher()->Execute( 945 SID_TEXT, SFX_CALLMODE_STANDARD, 946 new SfxStringItem(SID_TEXT, GetText()), 0L); 947 } 948 } 949 950 if (aCursorMoveTimer.IsActive()) 951 { 952 aCursorMoveTimer.Stop(); 953 // ggf noch die (neue) FormulaCursor Position setzen 954 CursorMoveTimerHdl(&aCursorMoveTimer); 955 } 956 } 957 958 959 void SmEditWindow::DeleteEditView( SmViewShell & /*rView*/ ) 960 { 961 if (pEditView) 962 { 963 EditEngine *pEditEngine = pEditView->GetEditEngine(); 964 if (pEditEngine) 965 { 966 pEditEngine->SetStatusEventHdl( Link() ); 967 pEditEngine->RemoveView( pEditView ); 968 } 969 delete pEditView; 970 pEditView = 0; 971 } 972 } 973 974 975 uno::Reference< XAccessible > SmEditWindow::CreateAccessible() 976 { 977 if (!pAccessible) 978 { 979 pAccessible = new SmEditAccessible( this ); 980 xAccessible = pAccessible; 981 pAccessible->Init(); 982 } 983 return xAccessible; 984 } 985 986