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_uInt16 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_uInt16 nLine; 625 sal_uInt16 nCount = 0; 626 // zuerst wird der Bereich um dem Cursor bearbeitet 627 TextSelection aSel = pTextView->GetSelection(); 628 sal_uInt16 nCur = (sal_uInt16)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_uInt16)aSyntaxLineTable.GetCurKey(); 657 DoSyntaxHighlight( nLine ); 658 sal_uInt16 nCurKey = (sal_uInt16)aSyntaxLineTable.GetCurKey(); 659 p = aSyntaxLineTable.Next(); 660 aSyntaxLineTable.Remove(nCurKey); 661 nCount ++; 662 if(Time().GetTime() - aSyntaxCheckStart.GetTime() > MAX_HIGHLIGHTTIME) 663 { 664 pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT ); 665 break; 666 } 667 } 668 // os: #43050# hier wird ein TextView-Problem umpopelt: 669 // waehrend des Highlightings funktionierte das Scrolling nicht 670 /* MT: Shouldn't be a oproblem any more, using IdeFormatter in Insert/RemoveAttrib now. 671 672 TextView* pTmp = pTextEngine->GetActiveView(); 673 pTextEngine->SetActiveView(0); 674 // pTextEngine->SetUpdateMode( sal_True ); 675 pTextEngine->SetActiveView(pTmp); 676 pTextView->ShowCursor(sal_False, sal_False); 677 */ 678 679 if(aSyntaxLineTable.Count() && !pTimer->IsActive()) 680 pTimer->Start(); 681 // SyntaxTimerHdl wird gerufen, wenn Text-Aenderung 682 // => gute Gelegenheit, Textbreite zu ermitteln! 683 long nPrevTextWidth = nCurTextWidth; 684 nCurTextWidth = pTextEngine->CalcTextWidth() + 25; // kleine Toleranz 685 if ( nCurTextWidth != nPrevTextWidth ) 686 SetScrollBarRanges(); 687 bHighlighting = sal_False; 688 689 return 0; 690 } 691 /*-----------------15.01.97 10.01------------------- 692 693 --------------------------------------------------*/ 694 695 void SwSrcEditWindow::DoSyntaxHighlight( sal_uInt16 nPara ) 696 { 697 // Durch das DelayedSyntaxHighlight kann es passieren, 698 // dass die Zeile nicht mehr existiert! 699 if ( nPara < pTextEngine->GetParagraphCount() ) 700 { 701 sal_Bool bTempModified = IsModified(); 702 pTextEngine->RemoveAttribs( nPara, (sal_Bool)sal_True ); 703 String aSource( pTextEngine->GetText( nPara ) ); 704 pTextEngine->SetUpdateMode( sal_False ); 705 ImpDoHighlight( aSource, nPara ); 706 // os: #43050# hier wird ein TextView-Problem umpopelt: 707 // waehrend des Highlightings funktionierte das Scrolling nicht 708 TextView* pTmp = pTextEngine->GetActiveView(); 709 pTmp->SetAutoScroll(sal_False); 710 pTextEngine->SetActiveView(0); 711 pTextEngine->SetUpdateMode( sal_True ); 712 pTextEngine->SetActiveView(pTmp); 713 // Bug 72887 show the cursor 714 pTmp->SetAutoScroll(sal_True); 715 pTmp->ShowCursor( sal_False/*pTmp->IsAutoScroll()*/ ); 716 717 if(!bTempModified) 718 ClearModifyFlag(); 719 } 720 } 721 722 /*-----------------15.01.97 09.49------------------- 723 724 --------------------------------------------------*/ 725 726 void SwSrcEditWindow::DoDelayedSyntaxHighlight( sal_uInt16 nPara ) 727 { 728 if ( !bHighlighting && bDoSyntaxHighlight ) 729 { 730 aSyntaxLineTable.Insert( nPara, (void*)(sal_uInt16)1 ); 731 aSyntaxIdleTimer.Start(); 732 } 733 } 734 735 /*-----------------15.01.97 11.32------------------- 736 737 --------------------------------------------------*/ 738 739 void SwSrcEditWindow::ImpDoHighlight( const String& rSource, sal_uInt16 nLineOff ) 740 { 741 SwTextPortions aPortionList; 742 lcl_Highlight(rSource, aPortionList); 743 744 size_t nCount = aPortionList.size(); 745 if ( !nCount ) 746 return; 747 748 SwTextPortion& rLast = aPortionList[nCount-1]; 749 if ( rLast.nStart > rLast.nEnd ) // Nur bis Bug von MD behoeben 750 { 751 nCount--; 752 aPortionList.pop_back(); 753 if ( !nCount ) 754 return; 755 } 756 757 // Evtl. Optimieren: 758 // Wenn haufig gleiche Farbe, dazwischen Blank ohne Farbe, 759 // ggf. zusammenfassen, oder zumindest das Blank, 760 // damit weniger Attribute 761 sal_Bool bOptimizeHighlight = sal_True; // war in der BasicIDE static 762 if ( bOptimizeHighlight ) 763 { 764 // Es muessen nur die Blanks und Tabs mit attributiert werden. 765 // Wenn zwei gleiche Attribute hintereinander eingestellt werden, 766 // optimiert das die TextEngine. 767 sal_uInt16 nLastEnd = 0; 768 769 #ifdef DBG_UTIL 770 sal_uInt16 nLine = aPortionList[0].nLine; 771 #endif 772 for ( size_t i = 0; i < nCount; i++ ) 773 { 774 SwTextPortion& r = aPortionList[i]; 775 DBG_ASSERT( r.nLine == nLine, "doch mehrere Zeilen ?" ); 776 if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoeben 777 continue; 778 779 if ( r.nStart > nLastEnd ) 780 { 781 // Kann ich mich drauf verlassen, dass alle ausser 782 // Blank und Tab gehighlightet wird ?! 783 r.nStart = nLastEnd; 784 } 785 nLastEnd = r.nEnd+1; 786 if ( ( i == (nCount-1) ) && ( r.nEnd < rSource.Len() ) ) 787 r.nEnd = rSource.Len(); 788 } 789 } 790 791 for ( size_t i = 0; i < aPortionList.size(); i++ ) 792 { 793 SwTextPortion& r = aPortionList[i]; 794 if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoeben 795 continue; 796 if(r.eType != svtools::HTMLSGML && 797 r.eType != svtools::HTMLCOMMENT && 798 r.eType != svtools::HTMLKEYWORD && 799 r.eType != svtools::HTMLUNKNOWN) 800 r.eType = svtools::HTMLUNKNOWN; 801 Color aColor((ColorData)SW_MOD()->GetColorConfig().GetColorValue((svtools::ColorConfigEntry)r.eType).nColor); 802 sal_uInt16 nLine = nLineOff+r.nLine; // 803 pTextEngine->SetAttrib( TextAttribFontColor( aColor ), nLine, r.nStart, r.nEnd+1, sal_True ); 804 } 805 } 806 807 /*-----------------30.06.97 09:12------------------- 808 809 --------------------------------------------------*/ 810 811 void SwSrcEditWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) 812 { 813 if ( rHint.ISA( TextHint ) ) 814 { 815 const TextHint& rTextHint = (const TextHint&)rHint; 816 if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED ) 817 { 818 pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() ); 819 pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() ); 820 } 821 else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED ) 822 { 823 if ( (long)pTextEngine->GetTextHeight() < pOutWin->GetOutputSizePixel().Height() ) 824 pTextView->Scroll( 0, pTextView->GetStartDocPos().Y() ); 825 pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() ); 826 SetScrollBarRanges(); 827 } 828 else if( ( rTextHint.GetId() == TEXT_HINT_PARAINSERTED ) || 829 ( rTextHint.GetId() == TEXT_HINT_PARACONTENTCHANGED ) ) 830 { 831 DoDelayedSyntaxHighlight( (sal_uInt16)rTextHint.GetValue() ); 832 } 833 } 834 } 835 836 void SwSrcEditWindow::ConfigurationChanged( utl::ConfigurationBroadcaster* pBrdCst, sal_uInt32 ) 837 { 838 if( pBrdCst == pSourceViewConfig) 839 SetFont(); 840 } 841 842 /*-----------------30.06.97 13:22------------------- 843 844 --------------------------------------------------*/ 845 846 void SwSrcEditWindow::Invalidate(sal_uInt16 ) 847 { 848 pOutWin->Invalidate(); 849 Window::Invalidate(); 850 851 } 852 853 void SwSrcEditWindow::Command( const CommandEvent& rCEvt ) 854 { 855 switch(rCEvt.GetCommand()) 856 { 857 case COMMAND_WHEEL: 858 case COMMAND_STARTAUTOSCROLL: 859 case COMMAND_AUTOSCROLL: 860 { 861 const CommandWheelData* pWData = rCEvt.GetWheelData(); 862 if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() ) 863 HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar ); 864 } 865 break; 866 default: 867 Window::Command(rCEvt); 868 } 869 } 870 871 void SwSrcEditWindow::HandleWheelCommand( const CommandEvent& rCEvt ) 872 { 873 pTextView->Command(rCEvt); 874 HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar ); 875 } 876 877 void SwSrcEditWindow::GetFocus() 878 { 879 pOutWin->GrabFocus(); 880 } 881 882 /*void SwSrcEditWindow::LoseFocus() 883 { 884 Window::LoseFocus(); 885 // pOutWin->LoseFocus(); 886 // rView.LostFocus(); 887 } */ 888 /* -----------------------------29.08.2002 13:21------------------------------ 889 890 ---------------------------------------------------------------------------*/ 891 sal_Bool lcl_GetLanguagesForEncoding(rtl_TextEncoding eEnc, LanguageType aLanguages[]) 892 { 893 switch(eEnc) 894 { 895 case RTL_TEXTENCODING_UTF7 : 896 case RTL_TEXTENCODING_UTF8 : 897 // don#t fill - all LANGUAGE_SYSTEM means unicode font has to be used 898 break; 899 900 901 case RTL_TEXTENCODING_ISO_8859_3: 902 case RTL_TEXTENCODING_ISO_8859_1 : 903 case RTL_TEXTENCODING_MS_1252 : 904 case RTL_TEXTENCODING_APPLE_ROMAN : 905 case RTL_TEXTENCODING_IBM_850 : 906 case RTL_TEXTENCODING_ISO_8859_14 : 907 case RTL_TEXTENCODING_ISO_8859_15 : 908 //fill with western languages 909 aLanguages[0] = LANGUAGE_GERMAN; 910 aLanguages[1] = LANGUAGE_FRENCH; 911 aLanguages[2] = LANGUAGE_ITALIAN; 912 aLanguages[3] = LANGUAGE_SPANISH; 913 break; 914 915 case RTL_TEXTENCODING_IBM_865 : 916 //scandinavian 917 aLanguages[0] = LANGUAGE_FINNISH; 918 aLanguages[1] = LANGUAGE_NORWEGIAN; 919 aLanguages[2] = LANGUAGE_SWEDISH; 920 aLanguages[3] = LANGUAGE_DANISH; 921 break; 922 923 case RTL_TEXTENCODING_ISO_8859_10 : 924 case RTL_TEXTENCODING_ISO_8859_13 : 925 case RTL_TEXTENCODING_ISO_8859_2 : 926 case RTL_TEXTENCODING_IBM_852 : 927 case RTL_TEXTENCODING_MS_1250 : 928 case RTL_TEXTENCODING_APPLE_CENTEURO : 929 aLanguages[0] = LANGUAGE_POLISH; 930 aLanguages[1] = LANGUAGE_CZECH; 931 aLanguages[2] = LANGUAGE_HUNGARIAN; 932 aLanguages[3] = LANGUAGE_SLOVAK; 933 break; 934 935 case RTL_TEXTENCODING_ISO_8859_4 : 936 case RTL_TEXTENCODING_IBM_775 : 937 case RTL_TEXTENCODING_MS_1257 : 938 aLanguages[0] = LANGUAGE_LATVIAN ; 939 aLanguages[1] = LANGUAGE_LITHUANIAN; 940 aLanguages[2] = LANGUAGE_ESTONIAN ; 941 break; 942 943 case RTL_TEXTENCODING_IBM_863 : aLanguages[0] = LANGUAGE_FRENCH_CANADIAN; break; 944 case RTL_TEXTENCODING_APPLE_FARSI : aLanguages[0] = LANGUAGE_FARSI; break; 945 case RTL_TEXTENCODING_APPLE_ROMANIAN:aLanguages[0] = LANGUAGE_ROMANIAN; break; 946 947 case RTL_TEXTENCODING_IBM_861 : 948 case RTL_TEXTENCODING_APPLE_ICELAND : 949 aLanguages[0] = LANGUAGE_ICELANDIC; 950 break; 951 952 case RTL_TEXTENCODING_APPLE_CROATIAN:aLanguages[0] = LANGUAGE_CROATIAN; break; 953 954 case RTL_TEXTENCODING_IBM_437 : 955 case RTL_TEXTENCODING_ASCII_US : aLanguages[0] = LANGUAGE_ENGLISH; break; 956 957 case RTL_TEXTENCODING_IBM_862 : 958 case RTL_TEXTENCODING_MS_1255 : 959 case RTL_TEXTENCODING_APPLE_HEBREW : 960 case RTL_TEXTENCODING_ISO_8859_8 : 961 aLanguages[0] = LANGUAGE_HEBREW; 962 break; 963 964 case RTL_TEXTENCODING_IBM_857 : 965 case RTL_TEXTENCODING_MS_1254 : 966 case RTL_TEXTENCODING_APPLE_TURKISH: 967 case RTL_TEXTENCODING_ISO_8859_9 : 968 aLanguages[0] = LANGUAGE_TURKISH; 969 break; 970 971 case RTL_TEXTENCODING_IBM_860 : 972 aLanguages[0] = LANGUAGE_PORTUGUESE; 973 break; 974 975 case RTL_TEXTENCODING_IBM_869 : 976 case RTL_TEXTENCODING_MS_1253 : 977 case RTL_TEXTENCODING_APPLE_GREEK : 978 case RTL_TEXTENCODING_ISO_8859_7 : 979 case RTL_TEXTENCODING_IBM_737 : 980 aLanguages[0] = LANGUAGE_GREEK; 981 break; 982 983 case RTL_TEXTENCODING_KOI8_R : 984 case RTL_TEXTENCODING_ISO_8859_5 : 985 case RTL_TEXTENCODING_IBM_855 : 986 case RTL_TEXTENCODING_MS_1251 : 987 case RTL_TEXTENCODING_IBM_866 : 988 case RTL_TEXTENCODING_APPLE_CYRILLIC : 989 aLanguages[0] = LANGUAGE_RUSSIAN; 990 break; 991 992 case RTL_TEXTENCODING_APPLE_UKRAINIAN: 993 case RTL_TEXTENCODING_KOI8_U: 994 aLanguages[0] = LANGUAGE_UKRAINIAN; 995 break; 996 997 case RTL_TEXTENCODING_IBM_864 : 998 case RTL_TEXTENCODING_MS_1256 : 999 case RTL_TEXTENCODING_ISO_8859_6 : 1000 case RTL_TEXTENCODING_APPLE_ARABIC : 1001 aLanguages[0] = LANGUAGE_ARABIC_SAUDI_ARABIA; 1002 break; 1003 1004 case RTL_TEXTENCODING_APPLE_CHINTRAD : 1005 case RTL_TEXTENCODING_MS_950 : 1006 case RTL_TEXTENCODING_GBT_12345 : 1007 case RTL_TEXTENCODING_BIG5 : 1008 case RTL_TEXTENCODING_EUC_TW : 1009 case RTL_TEXTENCODING_BIG5_HKSCS : 1010 aLanguages[0] = LANGUAGE_CHINESE_TRADITIONAL; 1011 break; 1012 1013 case RTL_TEXTENCODING_EUC_JP : 1014 case RTL_TEXTENCODING_ISO_2022_JP : 1015 case RTL_TEXTENCODING_JIS_X_0201 : 1016 case RTL_TEXTENCODING_JIS_X_0208 : 1017 case RTL_TEXTENCODING_JIS_X_0212 : 1018 case RTL_TEXTENCODING_APPLE_JAPANESE : 1019 case RTL_TEXTENCODING_MS_932 : 1020 case RTL_TEXTENCODING_SHIFT_JIS : 1021 aLanguages[0] = LANGUAGE_JAPANESE; 1022 break; 1023 1024 case RTL_TEXTENCODING_GB_2312 : 1025 case RTL_TEXTENCODING_MS_936 : 1026 case RTL_TEXTENCODING_GBK : 1027 case RTL_TEXTENCODING_GB_18030 : 1028 case RTL_TEXTENCODING_APPLE_CHINSIMP : 1029 case RTL_TEXTENCODING_EUC_CN : 1030 case RTL_TEXTENCODING_ISO_2022_CN : 1031 aLanguages[0] = LANGUAGE_CHINESE_SIMPLIFIED; 1032 break; 1033 1034 case RTL_TEXTENCODING_APPLE_KOREAN : 1035 case RTL_TEXTENCODING_MS_949 : 1036 case RTL_TEXTENCODING_EUC_KR : 1037 case RTL_TEXTENCODING_ISO_2022_KR : 1038 case RTL_TEXTENCODING_MS_1361 : 1039 aLanguages[0] = LANGUAGE_KOREAN; 1040 break; 1041 1042 case RTL_TEXTENCODING_APPLE_THAI : 1043 case RTL_TEXTENCODING_MS_874 : 1044 case RTL_TEXTENCODING_TIS_620 : 1045 aLanguages[0] = LANGUAGE_THAI; 1046 break; 1047 // case RTL_TEXTENCODING_SYMBOL : 1048 // case RTL_TEXTENCODING_DONTKNOW: : 1049 default: aLanguages[0] = Application::GetSettings().GetUILanguage(); 1050 } 1051 return aLanguages[0] != LANGUAGE_SYSTEM; 1052 } 1053 void SwSrcEditWindow::SetFont() 1054 { 1055 String sFontName = pSourceViewConfig->GetFontName(); 1056 if(!sFontName.Len()) 1057 { 1058 LanguageType aLanguages[5] = 1059 { 1060 LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM 1061 }; 1062 Font aFont; 1063 if(lcl_GetLanguagesForEncoding(eSourceEncoding, aLanguages)) 1064 { 1065 //TODO: check for multiple languages 1066 aFont = OutputDevice::GetDefaultFont(DEFAULTFONT_FIXED, aLanguages[0], 0, this); 1067 } 1068 else 1069 aFont = OutputDevice::GetDefaultFont(DEFAULTFONT_SANS_UNICODE, 1070 Application::GetSettings().GetLanguage(), 0, this); 1071 sFontName = aFont.GetName(); 1072 } 1073 const SvxFontListItem* pFontListItem = 1074 (const SvxFontListItem* )pSrcView->GetDocShell()->GetItem( SID_ATTR_CHAR_FONTLIST ); 1075 const FontList* pList = pFontListItem->GetFontList(); 1076 FontInfo aInfo = pList->Get(sFontName,WEIGHT_NORMAL, ITALIC_NONE); 1077 1078 const Font& rFont = GetTextEngine()->GetFont(); 1079 Font aFont(aInfo); 1080 Size aSize(rFont.GetSize()); 1081 //font height is stored in point and set in twip 1082 aSize.Height() = pSourceViewConfig->GetFontHeight() * 20; 1083 aFont.SetSize(pOutWin->LogicToPixel(aSize, MAP_TWIP)); 1084 GetTextEngine()->SetFont( aFont ); 1085 pOutWin->SetFont(aFont); 1086 } 1087 /* -----------------------------29.08.2002 13:47------------------------------ 1088 1089 ---------------------------------------------------------------------------*/ 1090 void SwSrcEditWindow::SetTextEncoding(rtl_TextEncoding eEncoding) 1091 { 1092 eSourceEncoding = eEncoding; 1093 SetFont(); 1094 } 1095 1096