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
lcl_Highlight(const String & rSource,SwTextPortions & aPortionList)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
SwSrcEditWindow(Window * pParent,SwSrcView * pParentView)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 --------------------------------------------------------------------*/
~SwSrcEditWindow()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
DataChanged(const DataChangedEvent & rDCEvt)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
Resize()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
DataChanged(const DataChangedEvent & rDCEvt)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
MouseMove(const MouseEvent & rEvt)371 void TextViewOutWin::MouseMove( const MouseEvent &rEvt )
372 {
373 if ( pTextView )
374 pTextView->MouseMove( rEvt );
375 }
376
377 /*--------------------------------------------------------------------
378 Beschreibung:
379 --------------------------------------------------------------------*/
380
381
MouseButtonUp(const MouseEvent & rEvt)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
MouseButtonDown(const MouseEvent & rEvt)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
Command(const CommandEvent & rCEvt)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
KeyInput(const KeyEvent & rKEvt)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
Paint(const Rectangle & rRect)488 void TextViewOutWin::Paint( const Rectangle& rRect )
489 {
490 pTextView->Paint( rRect );
491 }
492
493 /*--------------------------------------------------------------------
494 Beschreibung:
495 --------------------------------------------------------------------*/
496
497
CreateTextEngine()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
SetScrollBarRanges()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
InitScrollBars()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
IMPL_LINK(SwSrcEditWindow,ScrollHdl,ScrollBar *,pScroll)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
IMPL_LINK(SwSrcEditWindow,SyntaxTimerHdl,Timer *,pTimer)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
DoSyntaxHighlight(sal_uInt16 nPara)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
DoDelayedSyntaxHighlight(sal_uInt16 nPara)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
ImpDoHighlight(const String & rSource,sal_uInt16 nLineOff)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
Notify(SfxBroadcaster &,const SfxHint & rHint)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
ConfigurationChanged(utl::ConfigurationBroadcaster * pBrdCst,sal_uInt32)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
Invalidate(sal_uInt16)846 void SwSrcEditWindow::Invalidate(sal_uInt16 )
847 {
848 pOutWin->Invalidate();
849 Window::Invalidate();
850
851 }
852
Command(const CommandEvent & rCEvt)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
HandleWheelCommand(const CommandEvent & rCEvt)871 void SwSrcEditWindow::HandleWheelCommand( const CommandEvent& rCEvt )
872 {
873 pTextView->Command(rCEvt);
874 HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar );
875 }
876
GetFocus()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 ---------------------------------------------------------------------------*/
lcl_GetLanguagesForEncoding(rtl_TextEncoding eEnc,LanguageType aLanguages[])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 }
SetFont()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 ---------------------------------------------------------------------------*/
SetTextEncoding(rtl_TextEncoding eEncoding)1090 void SwSrcEditWindow::SetTextEncoding(rtl_TextEncoding eEncoding)
1091 {
1092 eSourceEncoding = eEncoding;
1093 SetFont();
1094 }
1095
1096