Lines 11-20
Link Here
|
11 |
import java.util.HashMap; |
11 |
import java.util.HashMap; |
12 |
import java.util.Iterator; |
12 |
import java.util.Iterator; |
13 |
import java.util.Map; |
13 |
import java.util.Map; |
|
|
14 |
import java.util.regex.Matcher; |
15 |
import java.util.regex.Pattern; |
14 |
|
16 |
|
15 |
import org.eclipse.core.runtime.IAdaptable; |
17 |
import org.eclipse.core.runtime.IAdaptable; |
16 |
import org.eclipse.jface.preference.JFacePreferences; |
18 |
import org.eclipse.jface.preference.JFacePreferences; |
17 |
import org.eclipse.jface.resource.JFaceResources; |
19 |
import org.eclipse.jface.resource.JFaceResources; |
|
|
20 |
import org.eclipse.jface.text.BadLocationException; |
18 |
import org.eclipse.jface.text.IDocument; |
21 |
import org.eclipse.jface.text.IDocument; |
19 |
import org.eclipse.jface.text.IRegion; |
22 |
import org.eclipse.jface.text.IRegion; |
20 |
import org.eclipse.jface.text.TextAttribute; |
23 |
import org.eclipse.jface.text.TextAttribute; |
Lines 26-34
Link Here
|
26 |
import org.eclipse.jface.text.presentation.PresentationReconciler; |
29 |
import org.eclipse.jface.text.presentation.PresentationReconciler; |
27 |
import org.eclipse.jface.text.reconciler.IReconciler; |
30 |
import org.eclipse.jface.text.reconciler.IReconciler; |
28 |
import org.eclipse.jface.text.rules.DefaultDamagerRepairer; |
31 |
import org.eclipse.jface.text.rules.DefaultDamagerRepairer; |
|
|
32 |
import org.eclipse.jface.text.rules.ICharacterScanner; |
33 |
import org.eclipse.jface.text.rules.IPredicateRule; |
29 |
import org.eclipse.jface.text.rules.IRule; |
34 |
import org.eclipse.jface.text.rules.IRule; |
30 |
import org.eclipse.jface.text.rules.IToken; |
35 |
import org.eclipse.jface.text.rules.IToken; |
31 |
import org.eclipse.jface.text.rules.MultiLineRule; |
|
|
32 |
import org.eclipse.jface.text.rules.RuleBasedScanner; |
36 |
import org.eclipse.jface.text.rules.RuleBasedScanner; |
33 |
import org.eclipse.jface.text.rules.SingleLineRule; |
37 |
import org.eclipse.jface.text.rules.SingleLineRule; |
34 |
import org.eclipse.jface.text.rules.Token; |
38 |
import org.eclipse.jface.text.rules.Token; |
Lines 38-49
Link Here
|
38 |
import org.eclipse.mylyn.tasks.core.AbstractTask; |
42 |
import org.eclipse.mylyn.tasks.core.AbstractTask; |
39 |
import org.eclipse.mylyn.tasks.core.TaskList; |
43 |
import org.eclipse.mylyn.tasks.core.TaskList; |
40 |
import org.eclipse.mylyn.tasks.core.TaskRepository; |
44 |
import org.eclipse.mylyn.tasks.core.TaskRepository; |
|
|
45 |
import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi; |
41 |
import org.eclipse.mylyn.tasks.ui.TaskHyperlink; |
46 |
import org.eclipse.mylyn.tasks.ui.TaskHyperlink; |
42 |
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin; |
47 |
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin; |
|
|
48 |
import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi.HyperlinkRegularExpression; |
43 |
import org.eclipse.swt.SWT; |
49 |
import org.eclipse.swt.SWT; |
44 |
import org.eclipse.swt.custom.StyleRange; |
50 |
import org.eclipse.swt.custom.StyleRange; |
45 |
import org.eclipse.swt.graphics.Color; |
51 |
import org.eclipse.swt.graphics.Color; |
46 |
import org.eclipse.swt.widgets.Control; |
52 |
import org.eclipse.swt.widgets.Control; |
|
|
53 |
import org.eclipse.swt.widgets.Display; |
47 |
import org.eclipse.ui.editors.text.EditorsUI; |
54 |
import org.eclipse.ui.editors.text.EditorsUI; |
48 |
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration; |
55 |
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration; |
49 |
|
56 |
|
Lines 61-70
Link Here
|
61 |
private RepositoryTextScanner scanner = null; |
68 |
private RepositoryTextScanner scanner = null; |
62 |
|
69 |
|
63 |
private boolean spellcheck = false; |
70 |
private boolean spellcheck = false; |
|
|
71 |
|
72 |
private TaskRepository repository; |
64 |
|
73 |
|
65 |
public TaskTextViewerConfiguration(boolean spellchecking) { |
74 |
public TaskTextViewerConfiguration(boolean spellchecking, TaskRepository repository) { |
66 |
super(EditorsUI.getPreferenceStore()); |
75 |
super(EditorsUI.getPreferenceStore()); |
67 |
this.spellcheck = spellchecking; |
76 |
this.spellcheck = spellchecking; |
|
|
77 |
this.repository = repository; |
68 |
} |
78 |
} |
69 |
|
79 |
|
70 |
@Override |
80 |
@Override |
Lines 81-87
Link Here
|
81 |
|
91 |
|
82 |
private RepositoryTextScanner getDefaultScanner() { |
92 |
private RepositoryTextScanner getDefaultScanner() { |
83 |
if (scanner == null) { |
93 |
if (scanner == null) { |
84 |
scanner = new RepositoryTextScanner(); |
94 |
scanner = new RepositoryTextScanner(repository); |
85 |
} |
95 |
} |
86 |
return scanner; |
96 |
return scanner; |
87 |
} |
97 |
} |
Lines 199-204
Link Here
|
199 |
super.hideHyperlinks(); |
209 |
super.hideHyperlinks(); |
200 |
} |
210 |
} |
201 |
|
211 |
|
|
|
212 |
@Override |
202 |
public void uninstall() { |
213 |
public void uninstall() { |
203 |
// ignore |
214 |
// ignore |
204 |
super.uninstall(); |
215 |
super.uninstall(); |
Lines 206-238
Link Here
|
206 |
} |
217 |
} |
207 |
|
218 |
|
208 |
private static class RepositoryTextScanner extends RuleBasedScanner { |
219 |
private static class RepositoryTextScanner extends RuleBasedScanner { |
|
|
220 |
private int undefinedTokenLength; |
221 |
|
222 |
private int minundefinedTokenLength; |
223 |
|
224 |
private class TaskRule implements IPredicateRule { |
225 |
|
226 |
/** The token to be returned on success */ |
227 |
protected IToken fToken; |
228 |
|
229 |
private TaskRepository repository; |
230 |
|
231 |
protected IToken fTokenCompleted; |
232 |
|
233 |
protected IToken fTokenNotFound; |
234 |
|
235 |
private Pattern fPattern; |
236 |
|
237 |
private int taskNumberGroupNumber; |
238 |
|
239 |
public TaskRule(TaskRepository repository, String regexp, int taskNumberGroupNumber, IToken token, |
240 |
IToken tokenCompleted, IToken tokenNotFound) { |
241 |
this.repository = repository; |
242 |
fToken = token; |
243 |
fTokenCompleted = tokenCompleted; |
244 |
fTokenNotFound = tokenNotFound; |
245 |
this.taskNumberGroupNumber = taskNumberGroupNumber; |
246 |
fPattern = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE); |
247 |
} |
248 |
|
249 |
public IToken evaluate(ICharacterScanner scanner, boolean resume) { |
250 |
|
251 |
String text = ((RepositoryTextScanner) scanner).getLineTextFromPos(); |
252 |
if (text == null) { |
253 |
((RepositoryTextScanner) scanner).setUndefinedTokenLength(0); |
254 |
return Token.UNDEFINED; |
255 |
} |
256 |
Matcher m = fPattern.matcher(text); |
257 |
if (m.find()) { |
258 |
if (m.start() > 0) { |
259 |
((RepositoryTextScanner) scanner).setUndefinedTokenLength(m.start()); |
260 |
return Token.UNDEFINED; |
261 |
} |
262 |
String taskNumber = m.group(taskNumberGroupNumber); |
263 |
taskNumber = taskNumber.trim(); |
264 |
if (!taskNumber.equals("")) { |
265 |
((RepositoryTextScanner) scanner).addToOffset(m.end()); |
266 |
TaskList taskList = TasksUiPlugin.getTaskListManager().getTaskList(); |
267 |
String repositoryUrl = repository.getUrl(); |
268 |
|
269 |
AbstractTask task = taskList.getTask(repositoryUrl, taskNumber); |
270 |
if (task == null) { |
271 |
task = taskList.getTaskByKey(repositoryUrl, taskNumber); |
272 |
} |
273 |
if (task != null) { |
274 |
if (task.isCompleted()) { |
275 |
return fTokenCompleted; |
276 |
} else { |
277 |
return fToken; |
278 |
} |
279 |
} else { |
280 |
return fTokenNotFound; |
281 |
} |
282 |
} |
283 |
} |
284 |
|
285 |
((RepositoryTextScanner) scanner).setUndefinedTokenLength(text.length()); |
286 |
return Token.UNDEFINED; |
287 |
} |
288 |
|
289 |
public IToken getSuccessToken() { |
290 |
return fToken; |
291 |
} |
292 |
|
293 |
public IToken evaluate(ICharacterScanner scanner) { |
294 |
return evaluate(scanner, false); |
295 |
} |
296 |
} |
297 |
|
298 |
private class RegExprRule implements IPredicateRule { |
299 |
|
300 |
/** The token to be returned on success */ |
301 |
protected IToken fToken; |
302 |
|
303 |
private Pattern fPattern; |
304 |
|
305 |
public RegExprRule(String regExpr, IToken token) { |
306 |
fToken = token; |
307 |
fPattern = Pattern.compile(regExpr, Pattern.CASE_INSENSITIVE); |
308 |
} |
309 |
|
310 |
public IToken evaluate(ICharacterScanner scanner, boolean resume) { |
311 |
String text = ((RepositoryTextScanner) scanner).getLineTextFromPos(); |
312 |
if (text == null) { |
313 |
((RepositoryTextScanner) scanner).setUndefinedTokenLength(0); |
314 |
return Token.UNDEFINED; |
315 |
} |
316 |
Matcher m = fPattern.matcher(text); |
317 |
if (m.find()) { |
318 |
if (m.start() > 0) { |
319 |
((RepositoryTextScanner) scanner).setUndefinedTokenLength(m.start()); |
320 |
return Token.UNDEFINED; |
321 |
} |
322 |
((RepositoryTextScanner) scanner).addToOffset(m.end()); |
323 |
return fToken; |
324 |
} |
325 |
|
326 |
((RepositoryTextScanner) scanner).setUndefinedTokenLength(text.length()); |
327 |
return Token.UNDEFINED; |
328 |
} |
329 |
|
330 |
public IToken getSuccessToken() { |
331 |
return fToken; |
332 |
} |
333 |
|
334 |
public IToken evaluate(ICharacterScanner scanner) { |
335 |
return evaluate(scanner, false); |
336 |
} |
209 |
|
337 |
|
210 |
public RepositoryTextScanner() { |
338 |
} |
|
|
339 |
|
340 |
public RepositoryTextScanner(TaskRepository repository) { |
341 |
IToken urlToken = new Token(new TextAttribute(JFaceResources.getColorRegistry().get( |
342 |
JFacePreferences.ACTIVE_HYPERLINK_COLOR))); |
211 |
IToken bugToken = new Token(new TextAttribute(JFaceResources.getColorRegistry().get( |
343 |
IToken bugToken = new Token(new TextAttribute(JFaceResources.getColorRegistry().get( |
212 |
JFacePreferences.ACTIVE_HYPERLINK_COLOR))); |
344 |
JFacePreferences.ACTIVE_HYPERLINK_COLOR))); |
|
|
345 |
IToken bugTokenCompleted = new Token(new TextAttribute(JFaceResources.getColorRegistry().get( |
346 |
JFacePreferences.ACTIVE_HYPERLINK_COLOR), new Color(Display.getDefault(), 255, 255, 255), |
347 |
TextAttribute.STRIKETHROUGH)); |
348 |
IToken bugTokenNotFound = new Token(new TextAttribute(JFaceResources.getColorRegistry().get( |
349 |
JFacePreferences.HYPERLINK_COLOR), new Color(Display.getDefault(), 255, 255, 255), |
350 |
TextAttribute.STRIKETHROUGH)); |
213 |
IToken quoteToken = new Token(new TextAttribute(TaskListColorsAndFonts.COLOR_QUOTED_TEXT)); |
351 |
IToken quoteToken = new Token(new TextAttribute(TaskListColorsAndFonts.COLOR_QUOTED_TEXT)); |
214 |
IRule[] rules = new IRule[16]; |
352 |
|
215 |
rules[0] = (new SingleLineRule("http://", " ", bugToken)); |
353 |
AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(repository.getConnectorKind()); |
216 |
rules[1] = (new SingleLineRule("https://", " ", bugToken)); |
354 |
if (connectorUi != null) { |
217 |
rules[2] = (new SingleLineRule("bug#", " ", bugToken)); |
355 |
HyperlinkRegularExpression hyperlinkData = connectorUi.getHyperlinkRegularExpression(true); |
218 |
rules[3] = (new SingleLineRule("bug#", "", bugToken)); |
356 |
IRule[] rules = new IRule[4]; |
219 |
rules[4] = (new SingleLineRule("bug #", "", bugToken)); |
357 |
rules[1] = new RegExprRule("(http://){1}(\\S)*", urlToken); |
220 |
rules[5] = (new SingleLineRule("http://", "\n", bugToken)); |
358 |
rules[2] = new RegExprRule("(https://){1}(\\S)*", urlToken); |
221 |
rules[6] = (new SingleLineRule("https://", "\n", bugToken)); |
359 |
rules[3] = (new TaskRule(repository, hyperlinkData.getRegularExpressionString(), |
222 |
rules[7] = (new SingleLineRule("task#", " ", bugToken)); |
360 |
hyperlinkData.getRegularExpressionGroup(), bugToken, bugTokenCompleted, bugTokenNotFound)); |
223 |
rules[8] = (new MultiLineRule("task#", "\n", bugToken)); |
361 |
SingleLineRule quoteRule = new SingleLineRule(">", null, quoteToken, (char) 0, true); |
224 |
rules[9] = (new MultiLineRule("task# ", " ", bugToken)); |
362 |
quoteRule.setColumnConstraint(0); |
225 |
rules[10] = (new SingleLineRule("task #", "\n", bugToken)); |
363 |
rules[0] = quoteRule; |
226 |
rules[11] = (new SingleLineRule("*** This bug has been ", "***", bugToken)); |
364 |
setRules(rules); |
227 |
rules[12] = (new SingleLineRule("http://", "", bugToken)); |
365 |
} else { |
228 |
rules[13] = (new SingleLineRule("https://", "", bugToken)); |
366 |
IRule[] rules = new IRule[3]; |
229 |
rules[14] = (new MultiLineRule("task #", " ", bugToken)); |
367 |
rules[1] = new RegExprRule("(http://){1}(\\S)*", urlToken); |
230 |
SingleLineRule quoteRule = new SingleLineRule(">", null, quoteToken, (char) 0, true); |
368 |
rules[2] = new RegExprRule("(https://){1}(\\S)*", urlToken); |
231 |
quoteRule.setColumnConstraint(0); |
369 |
SingleLineRule quoteRule = new SingleLineRule(">", null, quoteToken, (char) 0, true); |
232 |
rules[15] = quoteRule; |
370 |
quoteRule.setColumnConstraint(0); |
233 |
setRules(rules); |
371 |
rules[0] = quoteRule; |
|
|
372 |
setRules(rules); |
373 |
} |
374 |
} |
375 |
|
376 |
public void addToOffset(int length) { |
377 |
fOffset += length; |
234 |
} |
378 |
} |
235 |
|
379 |
|
|
|
380 |
public String getLineTextFromPos() { |
381 |
try { |
382 |
int line = fDocument.getLineOfOffset(fOffset); |
383 |
int start = fDocument.getLineOffset(line); |
384 |
int length = fDocument.getLineLength(line); |
385 |
|
386 |
String erg = fDocument.get(fOffset, length - (fOffset - start)); |
387 |
return erg; |
388 |
} catch (BadLocationException ex) { |
389 |
} |
390 |
return null; |
391 |
} |
392 |
|
393 |
/* |
394 |
* @see ITokenScanner#nextToken() |
395 |
*/ |
396 |
public IToken nextToken() { |
397 |
|
398 |
fTokenOffset = fOffset; |
399 |
fColumn = UNDEFINED; |
400 |
|
401 |
if (fRules != null) { |
402 |
minundefinedTokenLength = -1; |
403 |
for (int i = 0; i < fRules.length; i++) { |
404 |
undefinedTokenLength = 0; |
405 |
IToken token = (fRules[i].evaluate(this)); |
406 |
if (!token.isUndefined()) { |
407 |
return token; |
408 |
} else { |
409 |
if (undefinedTokenLength > 0 |
410 |
&& (minundefinedTokenLength > undefinedTokenLength || minundefinedTokenLength == -1)) { |
411 |
minundefinedTokenLength = undefinedTokenLength; |
412 |
} |
413 |
} |
414 |
} |
415 |
if (minundefinedTokenLength > -1) { |
416 |
addToOffset(minundefinedTokenLength); |
417 |
return fDefaultReturnToken; |
418 |
} |
419 |
|
420 |
} |
421 |
|
422 |
if (read() == EOF) |
423 |
return Token.EOF; |
424 |
return fDefaultReturnToken; |
425 |
} |
426 |
|
427 |
public void setUndefinedTokenLength(int undefinedTokenLength) { |
428 |
this.undefinedTokenLength = undefinedTokenLength; |
429 |
} |
236 |
} |
430 |
} |
237 |
|
431 |
|
238 |
} |
432 |
} |