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