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_svtools.hxx"
26 
27 #include <svtools/svmedit.hxx>
28 #include <svtools/xtextedt.hxx>
29 #include <svtools/editsyntaxhighlighter.hxx>
30 #include <svtools/txtattr.hxx>
31 
32 
MultiLineEditSyntaxHighlight(Window * pParent,WinBits nWinStyle,HighlighterLanguage aLanguage)33 MultiLineEditSyntaxHighlight::MultiLineEditSyntaxHighlight( Window* pParent, WinBits nWinStyle,
34 	HighlighterLanguage aLanguage): MultiLineEdit(pParent,nWinStyle), mbDoBracketHilight(true)
35 {
36 	EnableUpdateData(300);
37 	aHighlighter.initialize( aLanguage );
38 }
39 
MultiLineEditSyntaxHighlight(Window * pParent,const ResId & rResId,HighlighterLanguage aLanguage)40 MultiLineEditSyntaxHighlight::MultiLineEditSyntaxHighlight( Window* pParent, const ResId& rResId ,
41 	HighlighterLanguage aLanguage): MultiLineEdit(pParent,rResId), mbDoBracketHilight(true)
42 {
43 	EnableUpdateData(300);
44 	aHighlighter.initialize( aLanguage );
45 }
46 
~MultiLineEditSyntaxHighlight()47 MultiLineEditSyntaxHighlight::~MultiLineEditSyntaxHighlight()
48 {
49 }
50 
EnableBracketHilight(bool aHilight)51 void MultiLineEditSyntaxHighlight::EnableBracketHilight(bool aHilight)
52 {
53 	mbDoBracketHilight = aHilight;
54 }
55 
IsBracketHilight()56 bool MultiLineEditSyntaxHighlight::IsBracketHilight()
57 {
58 	return mbDoBracketHilight;
59 }
60 
SetText(const String & rNewText)61 void MultiLineEditSyntaxHighlight::SetText(const String& rNewText)
62 {
63 	MultiLineEdit::SetText(rNewText);
64 	UpdateData();
65 }
66 
DoBracketHilight(sal_uInt16 aKey)67 void MultiLineEditSyntaxHighlight::DoBracketHilight(sal_uInt16 aKey)
68 {
69 	TextSelection aCurrentPos = GetTextView()->GetSelection();
70 	xub_StrLen aStartPos  = aCurrentPos.GetStart().GetIndex();
71 	sal_uLong nStartPara = aCurrentPos.GetStart().GetPara();
72 	sal_uInt16 aCount = 0;
73 	int aChar = -1;
74 
75 	switch (aKey)
76 	{
77 		case '\'':	// no break
78 		case '"':
79 		{
80 			aChar = aKey;
81 			break;
82 		}
83 		case '}' :
84 		{
85 			aChar = '{';
86 			break;
87 		}
88 		case ')':
89 		{
90 			aChar = '(';
91 			break;
92 		}
93 		case ']':
94 		{
95 			aChar = '[';
96 			break;
97 		}
98 	}
99 
100 	if (aChar != -1)
101 	{
102 		for (long aPara =nStartPara; aPara>=0;--aPara)
103 		{
104             if ( aStartPos == 0 )
105                 continue;
106 
107 			String aLine( GetTextEngine()->GetText( aPara ) );
108 			for (sal_uInt16 i = ((unsigned long)aPara==nStartPara) ? aStartPos-1 : (sal_uInt16)(aLine.Len()-1); i>0; --i)
109 			{
110 				if (aLine.GetChar(i)==aChar)
111 				{
112 					if (!aCount)
113 					{
114 						GetTextEngine()->SetAttrib( TextAttribFontWeight( WEIGHT_ULTRABOLD ), aPara, i, i+1, sal_True );
115 						GetTextEngine()->SetAttrib( TextAttribFontColor( Color(0,0,0) ), aPara, i, i+1, sal_True );
116 						GetTextEngine()->SetAttrib( TextAttribFontWeight( WEIGHT_ULTRABOLD ), nStartPara, aStartPos, aStartPos, sal_True );
117 						GetTextEngine()->SetAttrib( TextAttribFontColor( Color(0,0,0) ), nStartPara, aStartPos, aStartPos, sal_True );
118 						return;
119 					}
120 					else
121 						aCount--;
122 				}
123 				if (aLine.GetChar(i)==aKey)
124 					aCount++;
125 			}
126 		}
127 	}
128 }
129 
PreNotify(NotifyEvent & rNEvt)130 long MultiLineEditSyntaxHighlight::PreNotify( NotifyEvent& rNEvt )
131 {
132 	if ( mbDoBracketHilight && (rNEvt.GetType() == EVENT_KEYINPUT) )
133 		DoBracketHilight(rNEvt.GetKeyEvent()->GetCharCode());
134 
135 	return MultiLineEdit::PreNotify(rNEvt);
136 }
137 
GetColorValue(TokenTypes aToken)138 Color MultiLineEditSyntaxHighlight::GetColorValue(TokenTypes aToken)
139 {
140 	Color aColor;
141 	switch (aHighlighter.GetLanguage())
142 	{
143 		case HIGHLIGHT_SQL:
144 		{
145 			switch (aToken)
146 			{
147 				case TT_IDENTIFIER:	aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLIDENTIFIER).nColor; break;
148 				case TT_NUMBER:		aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLNUMBER).nColor; break;
149 				case TT_STRING:		aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLSTRING).nColor; break;
150 				case TT_OPERATOR:	aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLOPERATOR).nColor; break;
151 				case TT_KEYWORDS:	aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLKEYWORD).nColor; break;
152 				case TT_PARAMETER:  aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLPARAMETER).nColor; break;
153 				case TT_COMMENT:	aColor = (ColorData)m_aColorConfig.GetColorValue(svtools::SQLCOMMENT).nColor; break;
154 				default:			aColor = Color(0,0,0);
155 			}
156 			break;
157 		}
158 		case HIGHLIGHT_BASIC:
159 		{
160 			switch (aToken)
161 			{
162 				case TT_IDENTIFIER:	aColor = Color(255,0,0); break;
163 				case TT_COMMENT:	aColor = Color(0,0,45); break;
164 				case TT_NUMBER:		aColor = Color(204,102,204); break;
165 				case TT_STRING:		aColor = Color(0,255,45); break;
166 				case TT_OPERATOR:	aColor = Color(0,0,100); break;
167 				case TT_KEYWORDS:	aColor = Color(0,0,255); break;
168 				case TT_ERROR :		aColor = Color(0,255,255); break;
169 				default:			aColor = Color(0,0,0);
170 			}
171 			break;
172 		}
173 		default: aColor = Color(0,0,0);
174 
175 	}
176 	return aColor;
177 }
178 
UpdateData()179 void MultiLineEditSyntaxHighlight::UpdateData()
180 {
181 	// syntax highlighting
182 	// this must be possible improved by using notifychange correctly
183 	sal_Bool bTempModified = GetTextEngine()->IsModified();
184 	for (unsigned int nLine=0; nLine < GetTextEngine()->GetParagraphCount(); nLine++)
185 	{
186 		String aLine( GetTextEngine()->GetText( nLine ) );
187 		Range aChanges = aHighlighter.notifyChange( nLine, 0, &aLine, 1 );
188 
189 		GetTextEngine()->RemoveAttribs( nLine, sal_True );
190 		HighlightPortions aPortions;
191 		aHighlighter.getHighlightPortions( nLine, aLine, aPortions );
192 		for ( size_t i = 0; i < aPortions.size(); i++ )
193 		{
194 			HighlightPortion& r = aPortions[i];
195 			GetTextEngine()->SetAttrib( TextAttribFontColor( GetColorValue(r.tokenType) ), nLine, r.nBegin, r.nEnd, sal_True );
196 		}
197 	}
198 	GetTextView()->ShowCursor( false, true );
199 	GetTextEngine()->SetModified(bTempModified);
200 }
201