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