1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 32 #include <hintids.hxx> 33 #ifndef _CMDID_H 34 #include <cmdid.h> 35 #endif 36 37 38 #include <svtools/textview.hxx> 39 #ifndef _SVX_SVXIDS_HRC 40 #include <svx/svxids.hrc> 41 #endif 42 #ifndef _SCRBAR_HXX //autogen 43 #include <vcl/scrbar.hxx> 44 #endif 45 #include <sfx2/dispatch.hxx> 46 #include <sfx2/app.hxx> 47 #include <svtools/htmltokn.h> 48 #include <svtools/txtattr.hxx> 49 #include <unotools/sourceviewconfig.hxx> 50 #include <svtools/colorcfg.hxx> 51 #include <editeng/flstitem.hxx> 52 #include <vcl/metric.hxx> 53 #include <svtools/ctrltool.hxx> 54 #include <tools/time.hxx> 55 #include <swmodule.hxx> 56 #ifndef _DOCSH_HXX 57 #include <docsh.hxx> 58 #endif 59 #ifndef _SRCVIEW_HXX 60 #include <srcview.hxx> 61 #endif 62 #ifndef _HELPID_H 63 #include <helpid.h> 64 #endif 65 #include <deque> 66 67 68 69 struct SwTextPortion 70 { 71 sal_uInt16 nLine; 72 sal_uInt16 nStart, nEnd; 73 svtools::ColorConfigEntry eType; 74 }; 75 76 #define MAX_SYNTAX_HIGHLIGHT 20 77 #define MAX_HIGHLIGHTTIME 200 78 #define SYNTAX_HIGHLIGHT_TIMEOUT 200 79 80 typedef std::deque<SwTextPortion> SwTextPortions; 81 82 83 static void lcl_Highlight(const String& rSource, SwTextPortions& aPortionList) 84 { 85 const sal_Unicode cOpenBracket = '<'; 86 const sal_Unicode cCloseBracket= '>'; 87 const sal_Unicode cSlash = '/'; 88 const sal_Unicode cExclamation = '!'; 89 const sal_Unicode cMinus = '-'; 90 const sal_Unicode cSpace = ' '; 91 const sal_Unicode cTab = 0x09; 92 const sal_Unicode cLF = 0x0a; 93 const sal_Unicode cCR = 0x0d; 94 95 96 const sal_uInt16 nStrLen = rSource.Len(); 97 sal_uInt16 nInsert = 0; // Number of inserted Portions 98 sal_uInt16 nActPos = 0; // Position, at the '<' was found 99 sal_uInt16 nOffset = 0; // Offset of nActPos for '<' 100 sal_uInt16 nPortStart = USHRT_MAX; // For the TextPortion 101 sal_uInt16 nPortEnd = 0; // 102 SwTextPortion aText; 103 while(nActPos < nStrLen) 104 { 105 svtools::ColorConfigEntry eFoundType = svtools::HTMLUNKNOWN; 106 if(rSource.GetChar(nActPos) == cOpenBracket && nActPos < nStrLen - 2 ) 107 { 108 // 'leere' Portion einfuegen 109 if(nPortEnd < nActPos - 1 ) 110 { 111 aText.nLine = 0; 112 // am Anfang nicht verschieben 113 aText.nStart = nPortEnd; 114 if(nInsert) 115 aText.nStart += 1; 116 aText.nEnd = nActPos - 1; 117 aText.eType = svtools::HTMLUNKNOWN; 118 aPortionList.push_back( aText ); 119 nInsert++; 120 } 121 sal_Unicode cFollowFirst = rSource.GetChar((xub_StrLen)(nActPos + 1)); 122 sal_Unicode cFollowNext = rSource.GetChar((xub_StrLen)(nActPos + 2)); 123 if(cExclamation == cFollowFirst) 124 { 125 // "<!" SGML oder Kommentar 126 if(cMinus == cFollowNext && 127 nActPos < nStrLen - 3 && cMinus == rSource.GetChar((xub_StrLen)(nActPos + 3))) 128 { 129 eFoundType = svtools::HTMLCOMMENT; 130 } 131 else 132 eFoundType = svtools::HTMLSGML; 133 nPortStart = nActPos; 134 nPortEnd = nActPos + 1; 135 } 136 else if(cSlash == cFollowFirst) 137 { 138 // "</" Slash ignorieren 139 nPortStart = nActPos; 140 nActPos++; 141 nOffset++; 142 } 143 if(svtools::HTMLUNKNOWN == eFoundType) 144 { 145 //jetzt koennte hier ein keyword folgen 146 sal_uInt16 nSrchPos = nActPos; 147 while(++nSrchPos < nStrLen - 1) 148 { 149 sal_Unicode cNext = rSource.GetChar(nSrchPos); 150 if( cNext == cSpace || 151 cNext == cTab || 152 cNext == cLF || 153 cNext == cCR) 154 break; 155 else if(cNext == cCloseBracket) 156 { 157 break; 158 } 159 } 160 if(nSrchPos > nActPos + 1) 161 { 162 //irgend ein String wurde gefunden 163 String sToken = rSource.Copy(nActPos + 1, nSrchPos - nActPos - 1 ); 164 sToken.ToUpperAscii(); 165 int nToken = ::GetHTMLToken(sToken); 166 if(nToken) 167 { 168 //Token gefunden 169 eFoundType = svtools::HTMLKEYWORD; 170 nPortEnd = nSrchPos; 171 nPortStart = nActPos; 172 } 173 else 174 { 175 //was war das denn? 176 #if OSL_DEBUG_LEVEL > 1 177 DBG_ERROR("Token nicht erkannt!"); 178 DBG_ERROR(ByteString(sToken, gsl_getSystemTextEncoding()).GetBuffer()); 179 #endif 180 } 181 182 } 183 } 184 // jetzt muss noch '>' gesucht werden 185 if(svtools::HTMLUNKNOWN != eFoundType) 186 { 187 sal_Bool bFound = sal_False; 188 for(sal_uInt16 i = nPortEnd; i < nStrLen; i++) 189 if(cCloseBracket == rSource.GetChar(i)) 190 { 191 bFound = sal_True; 192 nPortEnd = i; 193 break; 194 } 195 if(!bFound && (eFoundType == svtools::HTMLCOMMENT)) 196 { 197 // Kommentar ohne Ende in dieser Zeile 198 bFound = sal_True; 199 nPortEnd = nStrLen - 1; 200 } 201 202 if(bFound ||(eFoundType == svtools::HTMLCOMMENT)) 203 { 204 SwTextPortion aTextPortion; 205 aTextPortion.nLine = 0; 206 aTextPortion.nStart = nPortStart + 1; 207 aTextPortion.nEnd = nPortEnd; 208 aTextPortion.eType = eFoundType; 209 aPortionList.push_back( aTextPortion ); 210 nInsert++; 211 eFoundType = svtools::HTMLUNKNOWN; 212 } 213 214 } 215 } 216 nActPos++; 217 } 218 if(nInsert && nPortEnd < nActPos - 1) 219 { 220 aText.nLine = 0; 221 aText.nStart = nPortEnd + 1; 222 aText.nEnd = nActPos - 1; 223 aText.eType = svtools::HTMLUNKNOWN; 224 aPortionList.push_back( aText ); 225 nInsert++; 226 } 227 } 228 229 /*-------------------------------------------------------------------- 230 Beschreibung: 231 --------------------------------------------------------------------*/ 232 233 234 SwSrcEditWindow::SwSrcEditWindow( Window* pParent, SwSrcView* pParentView ) : 235 Window( pParent, WB_BORDER|WB_CLIPCHILDREN ), 236 237 pTextEngine(0), 238 239 pOutWin(0), 240 pHScrollbar(0), 241 pVScrollbar(0), 242 243 pSrcView(pParentView), 244 pSourceViewConfig(new utl::SourceViewConfig), 245 246 nCurTextWidth(0), 247 nStartLine(USHRT_MAX), 248 eSourceEncoding(gsl_getSystemTextEncoding()), 249 bDoSyntaxHighlight(sal_True), 250 bHighlighting(sal_False) 251 { 252 SetHelpId(HID_SOURCE_EDITWIN); 253 CreateTextEngine(); 254 pSourceViewConfig->AddListener(this); 255 } 256 /*-------------------------------------------------------------------- 257 Beschreibung: 258 --------------------------------------------------------------------*/ 259 SwSrcEditWindow::~SwSrcEditWindow() 260 { 261 pSourceViewConfig->RemoveListener(this); 262 delete pSourceViewConfig; 263 aSyntaxIdleTimer.Stop(); 264 if ( pTextEngine ) 265 { 266 EndListening( *pTextEngine ); 267 pTextEngine->RemoveView( pTextView ); 268 269 delete pHScrollbar; 270 delete pVScrollbar; 271 272 delete pTextView; 273 delete pTextEngine; 274 } 275 delete pOutWin; 276 } 277 278 /*-------------------------------------------------------------------- 279 Beschreibung: 280 --------------------------------------------------------------------*/ 281 282 void SwSrcEditWindow::DataChanged( const DataChangedEvent& rDCEvt ) 283 { 284 Window::DataChanged( rDCEvt ); 285 286 switch ( rDCEvt.GetType() ) 287 { 288 case DATACHANGED_SETTINGS: 289 // ScrollBars neu anordnen bzw. Resize ausloesen, da sich 290 // ScrollBar-Groesse geaendert haben kann. Dazu muss dann im 291 // Resize-Handler aber auch die Groesse der ScrollBars aus 292 // den Settings abgefragt werden. 293 if( rDCEvt.GetFlags() & SETTINGS_STYLE ) 294 Resize(); 295 break; 296 } 297 } 298 299 void SwSrcEditWindow::Resize() 300 { 301 // ScrollBars, etc. passiert in Adjust... 302 if ( pTextView ) 303 { 304 long nVisY = pTextView->GetStartDocPos().Y(); 305 pTextView->ShowCursor(); 306 Size aOutSz( GetOutputSizePixel() ); 307 long nMaxVisAreaStart = pTextView->GetTextEngine()->GetTextHeight() - aOutSz.Height(); 308 if ( nMaxVisAreaStart < 0 ) 309 nMaxVisAreaStart = 0; 310 if ( pTextView->GetStartDocPos().Y() > nMaxVisAreaStart ) 311 { 312 Point aStartDocPos( pTextView->GetStartDocPos() ); 313 aStartDocPos.Y() = nMaxVisAreaStart; 314 pTextView->SetStartDocPos( aStartDocPos ); 315 pTextView->ShowCursor(); 316 } 317 long nScrollStd = GetSettings().GetStyleSettings().GetScrollBarSize(); 318 Size aScrollSz(aOutSz.Width() - nScrollStd, nScrollStd ); 319 Point aScrollPos(0, aOutSz.Height() - nScrollStd); 320 321 pHScrollbar->SetPosSizePixel( aScrollPos, aScrollSz); 322 323 aScrollSz.Width() = aScrollSz.Height(); 324 aScrollSz.Height() = aOutSz.Height(); 325 aScrollPos = Point(aOutSz.Width() - nScrollStd, 0); 326 327 pVScrollbar->SetPosSizePixel( aScrollPos, aScrollSz); 328 aOutSz.Width() -= nScrollStd; 329 aOutSz.Height() -= nScrollStd; 330 pOutWin->SetOutputSizePixel(aOutSz); 331 InitScrollBars(); 332 333 // Zeile im ersten Resize setzen 334 if(USHRT_MAX != nStartLine) 335 { 336 if(nStartLine < pTextEngine->GetParagraphCount()) 337 { 338 TextSelection aSel(TextPaM( nStartLine, 0 ), TextPaM( nStartLine, 0x0 )); 339 pTextView->SetSelection(aSel); 340 pTextView->ShowCursor(); 341 } 342 nStartLine = USHRT_MAX; 343 } 344 345 if ( nVisY != pTextView->GetStartDocPos().Y() ) 346 Invalidate(); 347 } 348 349 } 350 351 /*-------------------------------------------------------------------- 352 Beschreibung: 353 --------------------------------------------------------------------*/ 354 355 void TextViewOutWin::DataChanged( const DataChangedEvent& rDCEvt ) 356 { 357 Window::DataChanged( rDCEvt ); 358 359 switch( rDCEvt.GetType() ) 360 { 361 case DATACHANGED_SETTINGS: 362 // den Settings abgefragt werden. 363 if( rDCEvt.GetFlags() & SETTINGS_STYLE ) 364 { 365 const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor(); 366 SetBackground( rCol ); 367 Font aFont( pTextView->GetTextEngine()->GetFont() ); 368 aFont.SetFillColor( rCol ); 369 pTextView->GetTextEngine()->SetFont( aFont ); 370 } 371 break; 372 } 373 } 374 375 void TextViewOutWin::MouseMove( const MouseEvent &rEvt ) 376 { 377 if ( pTextView ) 378 pTextView->MouseMove( rEvt ); 379 } 380 381 /*-------------------------------------------------------------------- 382 Beschreibung: 383 --------------------------------------------------------------------*/ 384 385 386 void TextViewOutWin::MouseButtonUp( const MouseEvent &rEvt ) 387 { 388 if ( pTextView ) 389 { 390 pTextView->MouseButtonUp( rEvt ); 391 SfxBindings& rBindings = ((SwSrcEditWindow*)GetParent())->GetSrcView()->GetViewFrame()->GetBindings(); 392 rBindings.Invalidate( SID_TABLE_CELL ); 393 rBindings.Invalidate( SID_CUT ); 394 rBindings.Invalidate( SID_COPY ); 395 } 396 } 397 398 /*-------------------------------------------------------------------- 399 Beschreibung: 400 --------------------------------------------------------------------*/ 401 402 403 void TextViewOutWin::MouseButtonDown( const MouseEvent &rEvt ) 404 { 405 GrabFocus(); 406 if ( pTextView ) 407 pTextView->MouseButtonDown( rEvt ); 408 } 409 410 /*-------------------------------------------------------------------- 411 Beschreibung: 412 --------------------------------------------------------------------*/ 413 414 415 void TextViewOutWin::Command( const CommandEvent& rCEvt ) 416 { 417 switch(rCEvt.GetCommand()) 418 { 419 case COMMAND_CONTEXTMENU: 420 ((SwSrcEditWindow*)GetParent())->GetSrcView()->GetViewFrame()-> 421 GetDispatcher()->ExecutePopup(); 422 break; 423 case COMMAND_WHEEL: 424 case COMMAND_STARTAUTOSCROLL: 425 case COMMAND_AUTOSCROLL: 426 { 427 const CommandWheelData* pWData = rCEvt.GetWheelData(); 428 if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() ) 429 { 430 ((SwSrcEditWindow*)GetParent())->HandleWheelCommand( rCEvt ); 431 } 432 } 433 break; 434 435 default: 436 if ( pTextView ) 437 pTextView->Command( rCEvt ); 438 else 439 Window::Command(rCEvt); 440 } 441 } 442 443 444 /*-------------------------------------------------------------------- 445 Beschreibung: 446 --------------------------------------------------------------------*/ 447 448 449 void TextViewOutWin::KeyInput( const KeyEvent& rKEvt ) 450 { 451 sal_Bool bDone = sal_False; 452 SwSrcEditWindow* pSrcEditWin = (SwSrcEditWindow*)GetParent(); 453 sal_Bool bChange = !pSrcEditWin->IsReadonly() || !TextEngine::DoesKeyChangeText( rKEvt ); 454 if(bChange) 455 bDone = pTextView->KeyInput( rKEvt ); 456 457 SfxBindings& rBindings = ((SwSrcEditWindow*)GetParent())->GetSrcView()->GetViewFrame()->GetBindings(); 458 if ( !bDone ) 459 { 460 if ( !SfxViewShell::Current()->KeyInput( rKEvt ) ) 461 Window::KeyInput( rKEvt ); 462 } 463 else 464 { 465 rBindings.Invalidate( SID_TABLE_CELL ); 466 if ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) 467 rBindings.Update( SID_BASICIDE_STAT_POS ); 468 if (pSrcEditWin->GetTextEngine()->IsModified() ) 469 { 470 rBindings.Invalidate( SID_SAVEDOC ); 471 rBindings.Invalidate( SID_DOC_MODIFIED ); 472 } 473 if( rKEvt.GetKeyCode().GetCode() == KEY_INSERT ) 474 rBindings.Invalidate( SID_ATTR_INSERT ); 475 } 476 477 rBindings.Invalidate( SID_CUT ); 478 rBindings.Invalidate( SID_COPY ); 479 480 SwDocShell* pDocShell = pSrcEditWin->GetSrcView()->GetDocShell(); 481 if(pSrcEditWin->GetTextEngine()->IsModified()) 482 { 483 pDocShell->SetModified(); 484 } 485 } 486 487 /*-------------------------------------------------------------------- 488 Beschreibung: 489 --------------------------------------------------------------------*/ 490 491 492 void TextViewOutWin::Paint( const Rectangle& rRect ) 493 { 494 pTextView->Paint( rRect ); 495 } 496 497 /*-------------------------------------------------------------------- 498 Beschreibung: 499 --------------------------------------------------------------------*/ 500 501 502 void SwSrcEditWindow::CreateTextEngine() 503 { 504 const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor(); 505 pOutWin = new TextViewOutWin(this, 0); 506 pOutWin->SetBackground(Wallpaper(rCol)); 507 pOutWin->SetPointer(Pointer(POINTER_TEXT)); 508 pOutWin->Show(); 509 510 //Scrollbars anlegen 511 pHScrollbar = new ScrollBar(this, WB_3DLOOK |WB_HSCROLL|WB_DRAG); 512 pHScrollbar->EnableRTL( false ); // #107300# --- RTL --- no mirroring for scrollbars 513 pHScrollbar->SetScrollHdl(LINK(this, SwSrcEditWindow, ScrollHdl)); 514 pHScrollbar->Show(); 515 516 pVScrollbar = new ScrollBar(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG); 517 pVScrollbar->EnableRTL( false ); // #107300# --- RTL --- no mirroring for scrollbars 518 pVScrollbar->SetScrollHdl(LINK(this, SwSrcEditWindow, ScrollHdl)); 519 pHScrollbar->EnableDrag(); 520 pVScrollbar->Show(); 521 522 pTextEngine = new ExtTextEngine; 523 pTextView = new ExtTextView( pTextEngine, pOutWin ); 524 pTextView->SetAutoIndentMode(sal_True); 525 pOutWin->SetTextView(pTextView); 526 527 pTextEngine->SetUpdateMode( sal_False ); 528 pTextEngine->InsertView( pTextView ); 529 530 Font aFont; 531 aFont.SetTransparent( sal_False ); 532 aFont.SetFillColor( rCol ); 533 SetPointFont( aFont ); 534 aFont = GetFont(); 535 aFont.SetFillColor( rCol ); 536 pOutWin->SetFont( aFont ); 537 pTextEngine->SetFont( aFont ); 538 539 aSyntaxIdleTimer.SetTimeout( SYNTAX_HIGHLIGHT_TIMEOUT ); 540 aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, SwSrcEditWindow, SyntaxTimerHdl ) ); 541 542 pTextEngine->EnableUndo( sal_True ); 543 pTextEngine->SetUpdateMode( sal_True ); 544 545 pTextView->ShowCursor( sal_True, sal_True ); 546 InitScrollBars(); 547 StartListening( *pTextEngine ); 548 549 SfxBindings& rBind = GetSrcView()->GetViewFrame()->GetBindings(); 550 rBind.Invalidate( SID_TABLE_CELL ); 551 // rBind.Invalidate( SID_ATTR_CHAR_FONTHEIGHT ); 552 } 553 554 /*-------------------------------------------------------------------- 555 Beschreibung: 556 --------------------------------------------------------------------*/ 557 558 /*-------------------------------------------------------------------- 559 Beschreibung: 560 --------------------------------------------------------------------*/ 561 562 563 void SwSrcEditWindow::SetScrollBarRanges() 564 { 565 // Extra-Methode, nicht InitScrollBars, da auch fuer TextEngine-Events. 566 567 pHScrollbar->SetRange( Range( 0, nCurTextWidth-1 ) ); 568 pVScrollbar->SetRange( Range(0, pTextEngine->GetTextHeight()-1) ); 569 } 570 571 /*-------------------------------------------------------------------- 572 Beschreibung: 573 --------------------------------------------------------------------*/ 574 575 576 void SwSrcEditWindow::InitScrollBars() 577 { 578 SetScrollBarRanges(); 579 580 Size aOutSz( pOutWin->GetOutputSizePixel() ); 581 pVScrollbar->SetVisibleSize( aOutSz.Height() ); 582 pVScrollbar->SetPageSize( aOutSz.Height() * 8 / 10 ); 583 pVScrollbar->SetLineSize( pOutWin->GetTextHeight() ); 584 pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() ); 585 pHScrollbar->SetVisibleSize( aOutSz.Width() ); 586 pHScrollbar->SetPageSize( aOutSz.Width() * 8 / 10 ); 587 pHScrollbar->SetLineSize( pOutWin->GetTextWidth( 'x' ) ); 588 pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() ); 589 590 } 591 592 /*-------------------------------------------------------------------- 593 Beschreibung: 594 --------------------------------------------------------------------*/ 595 596 597 IMPL_LINK(SwSrcEditWindow, ScrollHdl, ScrollBar*, pScroll) 598 { 599 if(pScroll == pVScrollbar) 600 { 601 long nDiff = pTextView->GetStartDocPos().Y() - pScroll->GetThumbPos(); 602 GetTextView()->Scroll( 0, nDiff ); 603 pTextView->ShowCursor( sal_False, sal_True ); 604 pScroll->SetThumbPos( pTextView->GetStartDocPos().Y() ); 605 } 606 else 607 { 608 long nDiff = pTextView->GetStartDocPos().X() - pScroll->GetThumbPos(); 609 GetTextView()->Scroll( nDiff, 0 ); 610 pTextView->ShowCursor( sal_False, sal_True ); 611 pScroll->SetThumbPos( pTextView->GetStartDocPos().X() ); 612 } 613 GetSrcView()->GetViewFrame()->GetBindings().Invalidate( SID_TABLE_CELL ); 614 return 0; 615 } 616 617 /*-----------------15.01.97 09.22------------------- 618 619 --------------------------------------------------*/ 620 621 IMPL_LINK( SwSrcEditWindow, SyntaxTimerHdl, Timer *, pTimer ) 622 { 623 Time aSyntaxCheckStart; 624 DBG_ASSERT( pTextView, "Noch keine View, aber Syntax-Highlight ?!" ); 625 // pTextEngine->SetUpdateMode( sal_False ); 626 627 bHighlighting = sal_True; 628 sal_uInt16 nLine; 629 sal_uInt16 nCount = 0; 630 // zuerst wird der Bereich um dem Cursor bearbeitet 631 TextSelection aSel = pTextView->GetSelection(); 632 sal_uInt16 nCur = (sal_uInt16)aSel.GetStart().GetPara(); 633 if(nCur > 40) 634 nCur -= 40; 635 else 636 nCur = 0; 637 if(aSyntaxLineTable.Count()) 638 for(sal_uInt16 i = 0; i < 80 && nCount < 40; i++, nCur++) 639 { 640 void * p = aSyntaxLineTable.Get(nCur); 641 if(p) 642 { 643 DoSyntaxHighlight( nCur ); 644 aSyntaxLineTable.Remove( nCur ); 645 nCount++; 646 if(!aSyntaxLineTable.Count()) 647 break; 648 if((Time().GetTime() - aSyntaxCheckStart.GetTime()) > MAX_HIGHLIGHTTIME ) 649 { 650 pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT ); 651 break; 652 } 653 } 654 } 655 656 // wenn dann noch etwas frei ist, wird von Beginn an weitergearbeitet 657 void* p = aSyntaxLineTable.First(); 658 while ( p && nCount < MAX_SYNTAX_HIGHLIGHT) 659 { 660 nLine = (sal_uInt16)aSyntaxLineTable.GetCurKey(); 661 DoSyntaxHighlight( nLine ); 662 sal_uInt16 nCurKey = (sal_uInt16)aSyntaxLineTable.GetCurKey(); 663 p = aSyntaxLineTable.Next(); 664 aSyntaxLineTable.Remove(nCurKey); 665 nCount ++; 666 if(Time().GetTime() - aSyntaxCheckStart.GetTime() > MAX_HIGHLIGHTTIME) 667 { 668 pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT ); 669 break; 670 } 671 } 672 // os: #43050# hier wird ein TextView-Problem umpopelt: 673 // waehrend des Highlightings funktionierte das Scrolling nicht 674 /* MT: Shouldn't be a oproblem any more, using IdeFormatter in Insert/RemoveAttrib now. 675 676 TextView* pTmp = pTextEngine->GetActiveView(); 677 pTextEngine->SetActiveView(0); 678 // pTextEngine->SetUpdateMode( sal_True ); 679 pTextEngine->SetActiveView(pTmp); 680 pTextView->ShowCursor(sal_False, sal_False); 681 */ 682 683 if(aSyntaxLineTable.Count() && !pTimer->IsActive()) 684 pTimer->Start(); 685 // SyntaxTimerHdl wird gerufen, wenn Text-Aenderung 686 // => gute Gelegenheit, Textbreite zu ermitteln! 687 long nPrevTextWidth = nCurTextWidth; 688 nCurTextWidth = pTextEngine->CalcTextWidth() + 25; // kleine Toleranz 689 if ( nCurTextWidth != nPrevTextWidth ) 690 SetScrollBarRanges(); 691 bHighlighting = sal_False; 692 693 return 0; 694 } 695 /*-----------------15.01.97 10.01------------------- 696 697 --------------------------------------------------*/ 698 699 void SwSrcEditWindow::DoSyntaxHighlight( sal_uInt16 nPara ) 700 { 701 // Durch das DelayedSyntaxHighlight kann es passieren, 702 // dass die Zeile nicht mehr existiert! 703 if ( nPara < pTextEngine->GetParagraphCount() ) 704 { 705 sal_Bool bTempModified = IsModified(); 706 pTextEngine->RemoveAttribs( nPara, (sal_Bool)sal_True ); 707 String aSource( pTextEngine->GetText( nPara ) ); 708 pTextEngine->SetUpdateMode( sal_False ); 709 ImpDoHighlight( aSource, nPara ); 710 // os: #43050# hier wird ein TextView-Problem umpopelt: 711 // waehrend des Highlightings funktionierte das Scrolling nicht 712 TextView* pTmp = pTextEngine->GetActiveView(); 713 pTmp->SetAutoScroll(sal_False); 714 pTextEngine->SetActiveView(0); 715 pTextEngine->SetUpdateMode( sal_True ); 716 pTextEngine->SetActiveView(pTmp); 717 // Bug 72887 show the cursor 718 pTmp->SetAutoScroll(sal_True); 719 pTmp->ShowCursor( sal_False/*pTmp->IsAutoScroll()*/ ); 720 721 if(!bTempModified) 722 ClearModifyFlag(); 723 } 724 } 725 726 /*-----------------15.01.97 09.49------------------- 727 728 --------------------------------------------------*/ 729 730 void SwSrcEditWindow::DoDelayedSyntaxHighlight( sal_uInt16 nPara ) 731 { 732 if ( !bHighlighting && bDoSyntaxHighlight ) 733 { 734 aSyntaxLineTable.Insert( nPara, (void*)(sal_uInt16)1 ); 735 aSyntaxIdleTimer.Start(); 736 } 737 } 738 739 /*-----------------15.01.97 11.32------------------- 740 741 --------------------------------------------------*/ 742 743 void SwSrcEditWindow::ImpDoHighlight( const String& rSource, sal_uInt16 nLineOff ) 744 { 745 SwTextPortions aPortionList; 746 lcl_Highlight(rSource, aPortionList); 747 748 size_t nCount = aPortionList.size(); 749 if ( !nCount ) 750 return; 751 752 SwTextPortion& rLast = aPortionList[nCount-1]; 753 if ( rLast.nStart > rLast.nEnd ) // Nur bis Bug von MD behoeben 754 { 755 nCount--; 756 aPortionList.pop_back(); 757 if ( !nCount ) 758 return; 759 } 760 761 // Evtl. Optimieren: 762 // Wenn haufig gleiche Farbe, dazwischen Blank ohne Farbe, 763 // ggf. zusammenfassen, oder zumindest das Blank, 764 // damit weniger Attribute 765 sal_Bool bOptimizeHighlight = sal_True; // war in der BasicIDE static 766 if ( bOptimizeHighlight ) 767 { 768 // Es muessen nur die Blanks und Tabs mit attributiert werden. 769 // Wenn zwei gleiche Attribute hintereinander eingestellt werden, 770 // optimiert das die TextEngine. 771 sal_uInt16 nLastEnd = 0; 772 773 #ifdef DBG_UTIL 774 sal_uInt16 nLine = aPortionList[0].nLine; 775 #endif 776 for ( size_t i = 0; i < nCount; i++ ) 777 { 778 SwTextPortion& r = aPortionList[i]; 779 DBG_ASSERT( r.nLine == nLine, "doch mehrere Zeilen ?" ); 780 if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoeben 781 continue; 782 783 if ( r.nStart > nLastEnd ) 784 { 785 // Kann ich mich drauf verlassen, dass alle ausser 786 // Blank und Tab gehighlightet wird ?! 787 r.nStart = nLastEnd; 788 } 789 nLastEnd = r.nEnd+1; 790 if ( ( i == (nCount-1) ) && ( r.nEnd < rSource.Len() ) ) 791 r.nEnd = rSource.Len(); 792 } 793 } 794 795 for ( size_t i = 0; i < aPortionList.size(); i++ ) 796 { 797 SwTextPortion& r = aPortionList[i]; 798 if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoeben 799 continue; 800 if(r.eType != svtools::HTMLSGML && 801 r.eType != svtools::HTMLCOMMENT && 802 r.eType != svtools::HTMLKEYWORD && 803 r.eType != svtools::HTMLUNKNOWN) 804 r.eType = svtools::HTMLUNKNOWN; 805 Color aColor((ColorData)SW_MOD()->GetColorConfig().GetColorValue((svtools::ColorConfigEntry)r.eType).nColor); 806 sal_uInt16 nLine = nLineOff+r.nLine; // 807 pTextEngine->SetAttrib( TextAttribFontColor( aColor ), nLine, r.nStart, r.nEnd+1, sal_True ); 808 } 809 } 810 811 /*-----------------30.06.97 09:12------------------- 812 813 --------------------------------------------------*/ 814 815 void SwSrcEditWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) 816 { 817 if ( rHint.ISA( TextHint ) ) 818 { 819 const TextHint& rTextHint = (const TextHint&)rHint; 820 if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED ) 821 { 822 pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() ); 823 pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() ); 824 } 825 else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED ) 826 { 827 if ( (long)pTextEngine->GetTextHeight() < pOutWin->GetOutputSizePixel().Height() ) 828 pTextView->Scroll( 0, pTextView->GetStartDocPos().Y() ); 829 pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() ); 830 SetScrollBarRanges(); 831 } 832 else if( ( rTextHint.GetId() == TEXT_HINT_PARAINSERTED ) || 833 ( rTextHint.GetId() == TEXT_HINT_PARACONTENTCHANGED ) ) 834 { 835 DoDelayedSyntaxHighlight( (sal_uInt16)rTextHint.GetValue() ); 836 } 837 } 838 } 839 840 void SwSrcEditWindow::ConfigurationChanged( utl::ConfigurationBroadcaster* pBrdCst, sal_uInt32 ) 841 { 842 if( pBrdCst == pSourceViewConfig) 843 SetFont(); 844 } 845 846 /*-----------------30.06.97 13:22------------------- 847 848 --------------------------------------------------*/ 849 850 void SwSrcEditWindow::Invalidate(sal_uInt16 ) 851 { 852 pOutWin->Invalidate(); 853 Window::Invalidate(); 854 855 } 856 857 void SwSrcEditWindow::Command( const CommandEvent& rCEvt ) 858 { 859 switch(rCEvt.GetCommand()) 860 { 861 case COMMAND_WHEEL: 862 case COMMAND_STARTAUTOSCROLL: 863 case COMMAND_AUTOSCROLL: 864 { 865 const CommandWheelData* pWData = rCEvt.GetWheelData(); 866 if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() ) 867 HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar ); 868 } 869 break; 870 default: 871 Window::Command(rCEvt); 872 } 873 } 874 875 void SwSrcEditWindow::HandleWheelCommand( const CommandEvent& rCEvt ) 876 { 877 pTextView->Command(rCEvt); 878 HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar ); 879 } 880 881 void SwSrcEditWindow::GetFocus() 882 { 883 pOutWin->GrabFocus(); 884 } 885 886 /*void SwSrcEditWindow::LoseFocus() 887 { 888 Window::LoseFocus(); 889 // pOutWin->LoseFocus(); 890 // rView.LostFocus(); 891 } */ 892 /* -----------------------------29.08.2002 13:21------------------------------ 893 894 ---------------------------------------------------------------------------*/ 895 sal_Bool lcl_GetLanguagesForEncoding(rtl_TextEncoding eEnc, LanguageType aLanguages[]) 896 { 897 switch(eEnc) 898 { 899 case RTL_TEXTENCODING_UTF7 : 900 case RTL_TEXTENCODING_UTF8 : 901 // don#t fill - all LANGUAGE_SYSTEM means unicode font has to be used 902 break; 903 904 905 case RTL_TEXTENCODING_ISO_8859_3: 906 case RTL_TEXTENCODING_ISO_8859_1 : 907 case RTL_TEXTENCODING_MS_1252 : 908 case RTL_TEXTENCODING_APPLE_ROMAN : 909 case RTL_TEXTENCODING_IBM_850 : 910 case RTL_TEXTENCODING_ISO_8859_14 : 911 case RTL_TEXTENCODING_ISO_8859_15 : 912 //fill with western languages 913 aLanguages[0] = LANGUAGE_GERMAN; 914 aLanguages[1] = LANGUAGE_FRENCH; 915 aLanguages[2] = LANGUAGE_ITALIAN; 916 aLanguages[3] = LANGUAGE_SPANISH; 917 break; 918 919 case RTL_TEXTENCODING_IBM_865 : 920 //scandinavian 921 aLanguages[0] = LANGUAGE_FINNISH; 922 aLanguages[1] = LANGUAGE_NORWEGIAN; 923 aLanguages[2] = LANGUAGE_SWEDISH; 924 aLanguages[3] = LANGUAGE_DANISH; 925 break; 926 927 case RTL_TEXTENCODING_ISO_8859_10 : 928 case RTL_TEXTENCODING_ISO_8859_13 : 929 case RTL_TEXTENCODING_ISO_8859_2 : 930 case RTL_TEXTENCODING_IBM_852 : 931 case RTL_TEXTENCODING_MS_1250 : 932 case RTL_TEXTENCODING_APPLE_CENTEURO : 933 aLanguages[0] = LANGUAGE_POLISH; 934 aLanguages[1] = LANGUAGE_CZECH; 935 aLanguages[2] = LANGUAGE_HUNGARIAN; 936 aLanguages[3] = LANGUAGE_SLOVAK; 937 break; 938 939 case RTL_TEXTENCODING_ISO_8859_4 : 940 case RTL_TEXTENCODING_IBM_775 : 941 case RTL_TEXTENCODING_MS_1257 : 942 aLanguages[0] = LANGUAGE_LATVIAN ; 943 aLanguages[1] = LANGUAGE_LITHUANIAN; 944 aLanguages[2] = LANGUAGE_ESTONIAN ; 945 break; 946 947 case RTL_TEXTENCODING_IBM_863 : aLanguages[0] = LANGUAGE_FRENCH_CANADIAN; break; 948 case RTL_TEXTENCODING_APPLE_FARSI : aLanguages[0] = LANGUAGE_FARSI; break; 949 case RTL_TEXTENCODING_APPLE_ROMANIAN:aLanguages[0] = LANGUAGE_ROMANIAN; break; 950 951 case RTL_TEXTENCODING_IBM_861 : 952 case RTL_TEXTENCODING_APPLE_ICELAND : 953 aLanguages[0] = LANGUAGE_ICELANDIC; 954 break; 955 956 case RTL_TEXTENCODING_APPLE_CROATIAN:aLanguages[0] = LANGUAGE_CROATIAN; break; 957 958 case RTL_TEXTENCODING_IBM_437 : 959 case RTL_TEXTENCODING_ASCII_US : aLanguages[0] = LANGUAGE_ENGLISH; break; 960 961 case RTL_TEXTENCODING_IBM_862 : 962 case RTL_TEXTENCODING_MS_1255 : 963 case RTL_TEXTENCODING_APPLE_HEBREW : 964 case RTL_TEXTENCODING_ISO_8859_8 : 965 aLanguages[0] = LANGUAGE_HEBREW; 966 break; 967 968 case RTL_TEXTENCODING_IBM_857 : 969 case RTL_TEXTENCODING_MS_1254 : 970 case RTL_TEXTENCODING_APPLE_TURKISH: 971 case RTL_TEXTENCODING_ISO_8859_9 : 972 aLanguages[0] = LANGUAGE_TURKISH; 973 break; 974 975 case RTL_TEXTENCODING_IBM_860 : 976 aLanguages[0] = LANGUAGE_PORTUGUESE; 977 break; 978 979 case RTL_TEXTENCODING_IBM_869 : 980 case RTL_TEXTENCODING_MS_1253 : 981 case RTL_TEXTENCODING_APPLE_GREEK : 982 case RTL_TEXTENCODING_ISO_8859_7 : 983 case RTL_TEXTENCODING_IBM_737 : 984 aLanguages[0] = LANGUAGE_GREEK; 985 break; 986 987 case RTL_TEXTENCODING_KOI8_R : 988 case RTL_TEXTENCODING_ISO_8859_5 : 989 case RTL_TEXTENCODING_IBM_855 : 990 case RTL_TEXTENCODING_MS_1251 : 991 case RTL_TEXTENCODING_IBM_866 : 992 case RTL_TEXTENCODING_APPLE_CYRILLIC : 993 aLanguages[0] = LANGUAGE_RUSSIAN; 994 break; 995 996 case RTL_TEXTENCODING_APPLE_UKRAINIAN: 997 case RTL_TEXTENCODING_KOI8_U: 998 aLanguages[0] = LANGUAGE_UKRAINIAN; 999 break; 1000 1001 case RTL_TEXTENCODING_IBM_864 : 1002 case RTL_TEXTENCODING_MS_1256 : 1003 case RTL_TEXTENCODING_ISO_8859_6 : 1004 case RTL_TEXTENCODING_APPLE_ARABIC : 1005 aLanguages[0] = LANGUAGE_ARABIC_SAUDI_ARABIA; 1006 break; 1007 1008 case RTL_TEXTENCODING_APPLE_CHINTRAD : 1009 case RTL_TEXTENCODING_MS_950 : 1010 case RTL_TEXTENCODING_GBT_12345 : 1011 case RTL_TEXTENCODING_BIG5 : 1012 case RTL_TEXTENCODING_EUC_TW : 1013 case RTL_TEXTENCODING_BIG5_HKSCS : 1014 aLanguages[0] = LANGUAGE_CHINESE_TRADITIONAL; 1015 break; 1016 1017 case RTL_TEXTENCODING_EUC_JP : 1018 case RTL_TEXTENCODING_ISO_2022_JP : 1019 case RTL_TEXTENCODING_JIS_X_0201 : 1020 case RTL_TEXTENCODING_JIS_X_0208 : 1021 case RTL_TEXTENCODING_JIS_X_0212 : 1022 case RTL_TEXTENCODING_APPLE_JAPANESE : 1023 case RTL_TEXTENCODING_MS_932 : 1024 case RTL_TEXTENCODING_SHIFT_JIS : 1025 aLanguages[0] = LANGUAGE_JAPANESE; 1026 break; 1027 1028 case RTL_TEXTENCODING_GB_2312 : 1029 case RTL_TEXTENCODING_MS_936 : 1030 case RTL_TEXTENCODING_GBK : 1031 case RTL_TEXTENCODING_GB_18030 : 1032 case RTL_TEXTENCODING_APPLE_CHINSIMP : 1033 case RTL_TEXTENCODING_EUC_CN : 1034 case RTL_TEXTENCODING_ISO_2022_CN : 1035 aLanguages[0] = LANGUAGE_CHINESE_SIMPLIFIED; 1036 break; 1037 1038 case RTL_TEXTENCODING_APPLE_KOREAN : 1039 case RTL_TEXTENCODING_MS_949 : 1040 case RTL_TEXTENCODING_EUC_KR : 1041 case RTL_TEXTENCODING_ISO_2022_KR : 1042 case RTL_TEXTENCODING_MS_1361 : 1043 aLanguages[0] = LANGUAGE_KOREAN; 1044 break; 1045 1046 case RTL_TEXTENCODING_APPLE_THAI : 1047 case RTL_TEXTENCODING_MS_874 : 1048 case RTL_TEXTENCODING_TIS_620 : 1049 aLanguages[0] = LANGUAGE_THAI; 1050 break; 1051 // case RTL_TEXTENCODING_SYMBOL : 1052 // case RTL_TEXTENCODING_DONTKNOW: : 1053 default: aLanguages[0] = Application::GetSettings().GetUILanguage(); 1054 } 1055 return aLanguages[0] != LANGUAGE_SYSTEM; 1056 } 1057 void SwSrcEditWindow::SetFont() 1058 { 1059 String sFontName = pSourceViewConfig->GetFontName(); 1060 if(!sFontName.Len()) 1061 { 1062 LanguageType aLanguages[5] = 1063 { 1064 LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM 1065 }; 1066 Font aFont; 1067 if(lcl_GetLanguagesForEncoding(eSourceEncoding, aLanguages)) 1068 { 1069 //TODO: check for multiple languages 1070 aFont = OutputDevice::GetDefaultFont(DEFAULTFONT_FIXED, aLanguages[0], 0, this); 1071 } 1072 else 1073 aFont = OutputDevice::GetDefaultFont(DEFAULTFONT_SANS_UNICODE, 1074 Application::GetSettings().GetLanguage(), 0, this); 1075 sFontName = aFont.GetName(); 1076 } 1077 const SvxFontListItem* pFontListItem = 1078 (const SvxFontListItem* )pSrcView->GetDocShell()->GetItem( SID_ATTR_CHAR_FONTLIST ); 1079 const FontList* pList = pFontListItem->GetFontList(); 1080 FontInfo aInfo = pList->Get(sFontName,WEIGHT_NORMAL, ITALIC_NONE); 1081 1082 const Font& rFont = GetTextEngine()->GetFont(); 1083 Font aFont(aInfo); 1084 Size aSize(rFont.GetSize()); 1085 //font height is stored in point and set in twip 1086 aSize.Height() = pSourceViewConfig->GetFontHeight() * 20; 1087 aFont.SetSize(pOutWin->LogicToPixel(aSize, MAP_TWIP)); 1088 GetTextEngine()->SetFont( aFont ); 1089 pOutWin->SetFont(aFont); 1090 } 1091 /* -----------------------------29.08.2002 13:47------------------------------ 1092 1093 ---------------------------------------------------------------------------*/ 1094 void SwSrcEditWindow::SetTextEncoding(rtl_TextEncoding eEncoding) 1095 { 1096 eSourceEncoding = eEncoding; 1097 SetFont(); 1098 } 1099 1100