xref: /trunk/main/sw/source/ui/docvw/srcedtw.cxx (revision 66b843ff8f1eedd2e69941f1ea52fa080f01ec28)
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