initial contribution
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.wiki / src / net / sourceforge / phpeclipse / wiki / editor / WikiOccurrencesUpdater.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpeclipse.wiki.editor;
12
13 import java.util.Iterator;
14 import java.util.LinkedList;
15 import java.util.List;
16
17 import net.sourceforge.phpeclipse.wiki.editor.model.WikipediaText;
18
19 import org.eclipse.jface.viewers.IPostSelectionProvider;
20 import org.eclipse.jface.viewers.ISelection;
21 import org.eclipse.jface.viewers.ISelectionChangedListener;
22 import org.eclipse.jface.viewers.SelectionChangedEvent;
23
24 import org.eclipse.jface.text.BadLocationException;
25 import org.eclipse.jface.text.IDocument;
26 import org.eclipse.jface.text.ITextSelection;
27 import org.eclipse.jface.text.Position;
28 import org.eclipse.jface.text.source.Annotation;
29 import org.eclipse.jface.text.source.IAnnotationModel;
30 import org.eclipse.jface.text.source.ISourceViewer;
31
32
33
34 class WikiOccurrencesUpdater implements ISelectionChangedListener {
35         /**
36          * Annotation fType for recipe occurrences.
37          */
38         private static final String ANNOTATION_TYPE= "net.sourceforge.phpeclipse.wiki.editor.highlightannotation";
39         /**
40          * The editor we operate on.
41          */
42         private final WikiEditor fEditor;
43         /**
44          * The set of annotations added in the previous run, always replaced by a
45          * new run.
46          */
47         private final List fOldAnnotations= new LinkedList();
48         
49         /**
50          * Creates a new instance on editor <code>editor</code>.
51          * 
52          * @param editor the editor to mark occurrences on.
53          */
54         public WikiOccurrencesUpdater(WikiEditor editor) {
55                 ((IPostSelectionProvider) editor.getSelectionProvider()).addPostSelectionChangedListener(this);
56                 fEditor= editor;
57         }
58
59         /*
60          * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
61          */
62         public void selectionChanged(SelectionChangedEvent event) {
63                 update((ISourceViewer) event.getSource());
64         }
65
66         /**
67          * Updates the drawn annotations.
68          * 
69          * @param viewer the viewer to get the document and annotation model from
70          */
71         public void update(ISourceViewer viewer) {
72                 if (viewer==null) {  
73                   return;
74                 }
75 //              try {
76                         IDocument document= viewer.getDocument();
77                         IAnnotationModel model= viewer.getAnnotationModel();
78                         if (document == null || model == null)
79                                 return;
80                         
81                         removeOldAnnotations(model);
82
83 //                      String word= getWordAtSelection(fEditor.getSelectionProvider().getSelection(), document);
84 //                      if (isIngredient(word)) {
85 //                              createNewAnnotations(word, document, model);
86 //                      }
87                         
88 //              } catch (BadLocationException e) {
89 //                      // ignore
90 //              }
91         }
92
93         /**
94          * Removes the previous set of annotations from the annotation model.
95          * 
96          * @param model the annotation model
97          */
98         private void removeOldAnnotations(IAnnotationModel model) {
99                 for (Iterator it= fOldAnnotations.iterator(); it.hasNext();) {
100                         Annotation annotation= (Annotation) it.next();
101                         model.removeAnnotation(annotation);
102                 }
103                 fOldAnnotations.clear();
104         }
105
106         /**
107          * Returns the word at the current selection / caret position.
108          * 
109          * @param selection the selection
110          * @param document the document
111          * @return the currently selected text, or the word at the caret if the
112          *         selection has length 0
113          * @throws BadLocationException if accessing the document fails
114          */
115         private String getWordAtSelection(ISelection selection, IDocument document) throws BadLocationException {
116                 if (selection instanceof ITextSelection) {
117                         ITextSelection ts= (ITextSelection) selection;
118                         int offset= ts.getOffset();
119                         int end= offset + ts.getLength();
120                         
121                         // non-empty selections
122                         if (end != offset)
123                                 return ts.getText();
124                         
125                         while (offset > 0 && isIngredientChar(document.getChar(offset - 1)))
126                                 offset--;
127                         while (end < document.getLength() && isIngredientChar(document.getChar(end)))
128                                 end++;
129                         
130                         return document.get(offset, end - offset);
131                 }
132                 return "";
133         }
134
135         private boolean isIngredientChar(char c) {
136                 return !Character.isWhitespace(c) && c != ':' && c != ',' && c != '.';
137         }
138
139         /**
140          * Adds an annotation for every occurrence of
141          * <code>ingredient</code> in the document. Also stores the created 
142          * annotations in <code>fOldAnnotations</code>.
143          * 
144          * @param ingredient the word to look for
145          * @param document the document
146          * @param model the annotation model
147          */
148         private void createNewAnnotations(String ingredient, IDocument document, IAnnotationModel model) {
149                 String content= document.get();
150                 int idx= content.indexOf(ingredient);
151                 while (idx != -1) {
152                         Annotation annotation= new Annotation(ANNOTATION_TYPE, false, ingredient);
153                         Position position= new Position(idx, ingredient.length());
154                         
155                         model.addAnnotation(annotation, position);
156                         fOldAnnotations.add(annotation);
157                         
158                         idx= content.indexOf(ingredient, idx + 1);
159                 }
160         }
161         
162         public void dispose() {
163                 ((IPostSelectionProvider) fEditor.getSelectionProvider()).removePostSelectionChangedListener(this);
164         }
165 }