Révision 3161

tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/edition/EditionAnnotations.java (revision 3161)
1
package org.txm.annotation.kr.rcp.edition;
2

  
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.HashMap;
6
import java.util.List;
7
import java.util.TreeMap;
8

  
9
import org.txm.annotation.kr.core.Annotation;
10
import org.txm.annotation.kr.core.AnnotationManager;
11
import org.txm.annotation.kr.core.KRAnnotationEngine;
12
import org.txm.annotation.kr.core.repository.AnnotationType;
13
import org.txm.annotation.kr.core.repository.TypedValue;
14
import org.txm.concordance.core.functions.Concordance;
15
import org.txm.edition.rcp.editors.SynopticEditionEditor;
16
import org.txm.objects.Match;
17
import org.txm.objects.Match2P;
18
import org.txm.searchengine.cqp.CQPSearchEngine;
19
import org.txm.searchengine.cqp.corpus.CQPCorpus;
20
import org.txm.searchengine.cqp.corpus.query.MatchUtils;
21
import org.txm.utils.logger.Log;
22

  
23
/**
24
 * Annotation values to display in the current concordance shown lines
25
 * 
26
 * Call getStrings(conclines, from, to) 
27
 * 
28
 * @author mdecorde
29
 *
30
 */
31
public class EditionAnnotations {
32
	
33
	SynopticEditionEditor editor;
34
	
35
	private AnnotationType viewAnnotation;
36
	
37
	public EditionAnnotations(SynopticEditionEditor editor) {
38
		this.editor = editor;
39
	}
40
	
41
	private boolean overlapAnnotation;
42

  
43
	private HashMap<String, HashMap<String, String>> lines;
44

  
45
	public void setAnnotationOverlap(boolean overlap) {
46
		overlapAnnotation = overlap;
47
	}
48
	public boolean getAnnotationOverlap() {
49
		return overlapAnnotation;
50
	}
51
	
52
	public HashMap<String, HashMap<String, String>> computeStrings(String startID, String endID) throws Exception {
53

  
54
		CQPCorpus corpus = this.editor.getCorpus();
55
		
56
		int[] indexes = CQPSearchEngine.getCqiClient().str2Id(corpus.getProperty("id").getQualifiedName(), new String[] {startID, endID});
57
		int[] startEndPositions = CQPSearchEngine.getCqiClient().idList2Cpos(corpus.getProperty("id").getQualifiedName(), indexes);
58
		int[] allPositions = MatchUtils.toPositions(startEndPositions[1], startEndPositions[0]);
59
		String[] allWordIDS = CQPSearchEngine.getCqiClient().cpos2Str(corpus.getProperty("id").getQualifiedName(), allPositions);
60
		
61
		HashMap<Match, String> matches = new HashMap<Match, String>();
62
		for (int i = 0 ; i < allWordIDS.length ; i++) {
63
			matches.put(new Match2P(allPositions[i]), allWordIDS[i]);
64
		}
65
		ArrayList<Match> sorted_matches = new ArrayList<Match>(matches.keySet());
66
		Collections.sort(sorted_matches);
67
		
68
		List<Annotation> ann = getAnnotationForMatches(sorted_matches, overlapAnnotation);
69
		lines = new HashMap<String, HashMap<String, String>>();
70
		
71
		for (int i = 0 ; i < ann.size() ; i++) {
72
			Annotation a = ann.get(i);
73
			HashMap<String, String> aline = new HashMap<String, String>();
74
			TypedValue annotation = getAnnotationTypedValue(a);
75
			aline.put(annotation.getTypeID(), annotation.getId());
76
			lines.put(matches.get(sorted_matches.get(i)), aline);
77
		}
78
		
79
		return lines; // TODO find a way to add with lazy method
80
	}
81
	
82
	private String findAnnotationForString(Match match, List<Annotation> annots, boolean overlap) {
83
		String annotationValue = "";
84
		if (annots!=null) {
85
			if (!annots.isEmpty()) {
86
				for (Annotation annot : annots) {
87
					if (overlap) {
88
						if ((annot.getStart()<=match.getStart() && annot.getEnd()>=match.getEnd()) || (annot.getStart()>match.getStart() && annot.getEnd()<match.getEnd())
89
								) {
90
							annotationValue = annot.getValue(); 
91
							// use the first Annotation found, the one stored in the temporary HSQL database
92
							//should be modified to display a list of annotation values corresponding to the match positions (or wrapped if overlap is admitted)
93
						}
94
					} else {
95
						if (annot.getStart()==match.getStart() && annot.getEnd()==match.getEnd()) {
96
							annotationValue = annot.getValue(); 
97
							// use the first Annotation found, the one stored in the temporary HSQL database
98
						}
99
					}
100
				}
101
			}
102
		}
103
		return annotationValue;
104
	}
105
	
106
	public TypedValue getAnnotationTypedValue(Annotation annotation) { 
107

  
108
		TypedValue annotationValue = null;
109
		if (annotation!=null) {
110
			annotationValue = viewAnnotation.getTypedValue(annotation.getValue());
111
			if (annotationValue == null) { // the annotation is not stored in the KR type -> the annotation is surely built with the CQPAnnotationManager
112
				//System.out.println("WARNING: no annotation value found for value id="+annotation.getValue()+" - will be created.");
113
				annotationValue = new TypedValue(annotation.getValue(), annotation.getValue(), annotation.getType());
114
			}
115
		}
116
		
117
		return annotationValue;
118
	}
119

  
120
	/**
121
	 * 
122
	 * @return the current annotation type
123
	 */
124
	public AnnotationType getViewAnnotation() {
125
		return viewAnnotation;
126
	}
127

  
128

  
129
	private List<Annotation> prepareAnnotationsList(List<Match> matches, List<Annotation> annotations, boolean overlap){
130
		List<Annotation> annotsList = new ArrayList<Annotation>();
131

  
132
		int iMatch = 0;
133
		int iAnnotation = 0;
134
		int nMatch = matches.size();
135
		int nAnnotations = annotations.size();
136

  
137
		while (iMatch < nMatch && iAnnotation < nAnnotations) {
138
			if (overlap) {
139
				if (matches.get(iMatch).getEnd() < annotations.get(iAnnotation).getStart()) {
140
					iMatch++;
141
					annotsList.add(null); // nothing for this match
142
				} else if (annotations.get(iAnnotation).getEnd() < matches.get(iMatch).getStart()) {
143
					iAnnotation++;
144
				} else {
145
					annotsList.add(annotations.get(iAnnotation));
146
					iMatch++;
147
				}
148
			} else {
149
				if (matches.get(iMatch).getEnd() < annotations.get(iAnnotation).getStart()) {
150
					iMatch++;
151
					annotsList.add(null); // nothing for this match
152
				} else if (annotations.get(iAnnotation).getEnd() < matches.get(iMatch).getStart()) {
153
					iAnnotation++;
154
				} else if (annotations.get(iAnnotation).getStart() == matches.get(iMatch).getStart() && 
155
						annotations.get(iAnnotation).getEnd() == matches.get(iMatch).getEnd()) {
156
					annotsList.add(annotations.get(iAnnotation));
157
					iMatch++;
158
					iAnnotation++;
159
				} else {
160
					iAnnotation++;
161
				}
162
			}
163
		}
164

  
165
		while (annotsList.size() < matches.size() ) annotsList.add(null); // fill matches that were not process due to no more annotations
166

  
167
		return annotsList;
168
	}
169

  
170
	private HashMap<Match, Annotation> prepareAnnotationsMap(List<Match> matches, List<Annotation> annots, boolean overlap){
171
		HashMap<Match, Annotation> annotsList = new HashMap<Match, Annotation>();
172
		for (Match m : matches) {
173
			boolean hasAnnotations = false;
174
			if (annots!=null) {
175
				if (!annots.isEmpty()) {
176
					for (Annotation annot : annots) {
177
						if (overlap){
178
							if ((annot.getStart() <= m.getStart() && m.getStart() <= annot.getEnd() && m.getEnd() >= annot.getEnd()) || 
179
									(annot.getStart() <= m.getEnd() && m.getEnd() <= annot.getEnd() && m.getStart() <= annot.getStart()) 
180
									|| !(annot.getEnd() < m.getStart() || annot.getStart() > m.getEnd())){
181
								annotsList.put(m, annot);
182
								hasAnnotations = true;
183
							}
184
						} else {
185
							if (annot.getStart()==m.getStart() && annot.getEnd()==m.getEnd()) {
186
								annotsList.put(m, annot); 
187
								hasAnnotations = true;
188
							}
189
						}
190
					}
191
				}
192
			}
193
			if (!hasAnnotations) {
194
				annotsList.put(m, null);
195
			}
196
		}
197
		return annotsList;
198
	}
199

  
200
	public List<Annotation> getAnnotationForMatches(List<Match> subsetMatch, boolean overlapAnnotation) throws Exception {
201
		
202
		AnnotationManager am = KRAnnotationEngine.getAnnotationManager(editor.getCorpus());
203
		
204
		//List<Annotation> allAnnotations = null;
205
		List<Annotation> annotationsPerMatch = new ArrayList<Annotation>();
206
		if (viewAnnotation != null && am != null) {
207
			try {
208
				annotationsPerMatch = am.getAnnotationsForMatches(viewAnnotation, subsetMatch, overlapAnnotation);
209
				//System.out.println("annotationsPerMatch: "+annotationsPerMatch);
210
			} catch (Exception e) {
211
				System.out.println("Error while reading annotation "+viewAnnotation+" and with "+subsetMatch.size()+" matches");
212
				Log.printStackTrace(e);
213
			}
214
		}
215
		return annotationsPerMatch;
216
	}
217

  
218
	public void setViewAnnotation(AnnotationType type) {
219
		viewAnnotation = type;
220
	}
221
	
222
	/**
223
	 * 
224
	 * @param i the relative position of the HashMap<String, String> in the lines list
225
	 * 
226
	 * @return the HashMap<String, String> pointed by 'i'. May return null if i is wrong.
227
	 */
228
	public HashMap<String, String> getAnnotationsString(String line) {
229
		if (lines == null) return null;
230
		if (!lines.containsKey(line)) return null;
231
		return lines.get(line);
232
	}
233
}
0 234

  
tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/edition/WordAnnotationToolbar.java (revision 3161)
1
package org.txm.annotation.kr.rcp.edition;
2

  
3
import java.util.ArrayList;
4
import java.util.HashMap;
5
import java.util.List;
6
import java.util.Vector;
7
import java.util.logging.Level;
8

  
9
import org.eclipse.core.runtime.IProgressMonitor;
10
import org.eclipse.core.runtime.IStatus;
11
import org.eclipse.core.runtime.Status;
12
import org.eclipse.jface.dialogs.InputDialog;
13
import org.eclipse.jface.dialogs.MessageDialog;
14
import org.eclipse.jface.viewers.ArrayContentProvider;
15
import org.eclipse.jface.viewers.ComboViewer;
16
import org.eclipse.jface.viewers.ISelectionChangedListener;
17
import org.eclipse.jface.viewers.IStructuredSelection;
18
import org.eclipse.jface.viewers.SelectionChangedEvent;
19
import org.eclipse.jface.viewers.StructuredSelection;
20
import org.eclipse.jface.viewers.TableViewerColumn;
21
import org.eclipse.osgi.util.NLS;
22
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.events.KeyEvent;
24
import org.eclipse.swt.events.KeyListener;
25
import org.eclipse.swt.events.SelectionEvent;
26
import org.eclipse.swt.events.SelectionListener;
27
import org.eclipse.swt.events.TypedEvent;
28
import org.eclipse.swt.graphics.Font;
29
import org.eclipse.swt.layout.GridData;
30
import org.eclipse.swt.widgets.Button;
31
import org.eclipse.swt.widgets.Composite;
32
import org.eclipse.swt.widgets.Display;
33
import org.eclipse.swt.widgets.Label;
34
import org.eclipse.swt.widgets.Text;
35
import org.eclipse.ui.dialogs.ListDialog;
36
import org.txm.annotation.kr.core.Annotation;
37
import org.txm.annotation.kr.core.AnnotationManager;
38
import org.txm.annotation.kr.core.DatabasePersistenceManager;
39
import org.txm.annotation.kr.core.KRAnnotationEngine;
40
import org.txm.annotation.kr.core.repository.AnnotationEffect;
41
import org.txm.annotation.kr.core.repository.AnnotationType;
42
import org.txm.annotation.kr.core.repository.KnowledgeRepository;
43
import org.txm.annotation.kr.core.repository.KnowledgeRepositoryManager;
44
import org.txm.annotation.kr.core.repository.LocalKnowledgeRepository;
45
import org.txm.annotation.kr.core.repository.TypedValue;
46
import org.txm.annotation.kr.rcp.commands.InitializeKnowledgeRepository;
47
import org.txm.annotation.kr.rcp.commands.SaveAnnotations;
48
import org.txm.annotation.kr.rcp.concordance.ConcordanceAnnotations;
49
import org.txm.annotation.kr.rcp.messages.KRAnnotationUIMessages;
50
import org.txm.annotation.kr.rcp.views.knowledgerepositories.KRView;
51
import org.txm.annotation.rcp.editor.AnnotationArea;
52
import org.txm.annotation.rcp.editor.AnnotationExtension;
53
import org.txm.concordance.core.functions.Concordance;
54
import org.txm.concordance.rcp.messages.ConcordanceUIMessages;
55
import org.txm.core.messages.TXMCoreMessages;
56
import org.txm.core.results.TXMResult;
57
import org.txm.edition.rcp.editors.SynopticEditionEditor;
58
import org.txm.objects.Match;
59
import org.txm.objects.Match2P;
60
import org.txm.objects.Page;
61
import org.txm.rcp.IImageKeys;
62
import org.txm.rcp.editors.TXMEditor;
63
import org.txm.rcp.swt.GLComposite;
64
import org.txm.rcp.swt.dialog.ConfirmDialog;
65
import org.txm.rcp.swt.provider.SimpleLabelProvider;
66
import org.txm.rcp.utils.JobHandler;
67
import org.txm.searchengine.cqp.CQPSearchEngine;
68
import org.txm.searchengine.cqp.corpus.CQPCorpus;
69
import org.txm.searchengine.cqp.corpus.WordProperty;
70
import org.txm.utils.AsciiUtils;
71
import org.txm.utils.logger.Log;
72

  
73
public class WordAnnotationToolbar extends AnnotationArea {
74
	
75
	/**
76
	 * the limit number of annotation when a confirm dialog box is shown
77
	 */
78
	protected static final int NALERTAFFECTANNOTATIONS = 100;
79
	
80
	public static final String EMPTYTEXT = ""; //$NON-NLS-1$
81
	
82
	/** The annotation service */
83
	protected AnnotationManager annotManager;
84
	
85
	protected SynopticEditionEditor editor;
86
	
87
	/**
88
	 * The concordance annotations to show in the concordance column table
89
	 */
90
	private EditionAnnotations annotations = null;
91
	
92
	/**
93
	 * All available annotation types
94
	 */
95
	protected List<TypedValue> typeValuesList;
96
	
97
	protected ComboViewer annotationTypesCombo;
98
	
99
	protected Label equalLabel;
100
	
101
	protected Text annotationValuesText;
102
	
103
	protected Button affectAnnotationButton;
104
	
105
	protected Button deleteAnnotationButton;
106
	
107
	protected KnowledgeRepository currentKnowledgeRepository = null;
108
	
109
	protected Vector<AnnotationType> typesList = new Vector<>();
110
	
111
	protected AnnotationType tagAnnotationType; // the tag annotation type if annotation mode is simple
112
	
113
	protected TypedValue value_to_add;
114
	
115
	//protected Concordance concordance;
116
	
117
	private CQPCorpus corpus;
118
	
119
	private TableViewerColumn annotationColumnViewer;
120
	
121
	private Font annotationColummnFont;
122
	
123
	private Font defaultColummnFont;
124
	
125
	private Button addAnnotationTypeLink;
126
	
127
	private Button addTypedValueLink;
128
	
129
	@Override
130
	public String getName() {
131
		return KRAnnotationUIMessages.motsPropritsInfDfaut;
132
	}
133
	
134
	@Override
135
	public boolean allowMultipleAnnotations() {
136
		return true;
137
	}
138
	
139
	public WordAnnotationToolbar() {}
140
	
141
	protected AnnotationType getSelectedAnnotationType() {
142
		return annotations.getViewAnnotation();
143
	}
144
	
145
	public void updateAnnotationWidgetStates() {
146
		if (annotationArea == null) return; // :)
147
		
148
		if (getSelectedAnnotationType() != null) {
149
			annotationValuesText.setEnabled(true);
150
			affectAnnotationButton.setEnabled(true);
151
			deleteAnnotationButton.setEnabled(true);
152
		}
153
		else {
154
			annotationValuesText.setEnabled(false);
155
			affectAnnotationButton.setEnabled(false);
156
			deleteAnnotationButton.setEnabled(false);
157
		}
158
	}
159
	
160
	protected void affectAnnotationToSelection(String[] word_selection) {
161
		
162
		ArrayList<Match> matches = new ArrayList<>();
163

  
164
		try {
165
			int[] indexes = CQPSearchEngine.getCqiClient().str2Id(corpus.getProperty("id").getQualifiedName(), word_selection);
166
			int[] allPositions = CQPSearchEngine.getCqiClient().idList2Cpos(corpus.getProperty("id").getQualifiedName(), indexes);
167
			for (int p : allPositions) {
168
				matches.add(new Match2P(p));
169
			}
170
			affectAnnotationsToMatches(matches);
171
		}
172
		catch (Exception e) {
173
			e.printStackTrace();
174
		}
175
	}
176
	
177
	protected void affectAnnotationValues(final List<? extends Match> matches, final AnnotationType type, final String svalue, JobHandler job) {
178
		value_to_add = null; // reset
179
		if (matches == null || matches.size() == 0) {
180
			System.out.println("No line selected. Aborting."); //$NON-NLS-1$
181
			return;
182
		}
183
		if (type == null) return; // no type, no annotation
184
		
185
		job.syncExec(new Runnable() {
186
			
187
			@Override
188
			public void run() {
189
				if (matches.size() > NALERTAFFECTANNOTATIONS) {
190
					ConfirmDialog dialog = new ConfirmDialog(Display.getCurrent().getActiveShell(),
191
							"confirm_annotate",  //$NON-NLS-1$
192
							KRAnnotationUIMessages.confirmAnnotationAffectation,
193
							NLS.bind(KRAnnotationUIMessages.youAreAboutToAnnotateP0ElementsContinue, matches.size()));
194
					
195
					if (dialog.open() == ConfirmDialog.CANCEL) {
196
						System.out.println("Annotation aborted by user."); //$NON-NLS-1$
197
						matches.clear();
198
					}
199
				}
200
			}
201
		});
202
		
203
		// get value from combo text value
204
		Log.fine(NLS.bind(KRAnnotationUIMessages.lookingForTypedValueWithIdEqualsP0, svalue));
205
		final KnowledgeRepository kr = KnowledgeRepositoryManager.getKnowledgeRepository(type.getKnowledgeRepository());
206
		value_to_add = kr.getValue(type, svalue);
207
		
208
		
209
		if (value_to_add == null && kr instanceof LocalKnowledgeRepository) { // create or not the annotation is simple mode
210
			value_to_add = kr.addValue(svalue, svalue, type.getId());
211
		}
212
		
213
		if (value_to_add == null) {
214
			job.syncExec(new Runnable() {
215
				
216
				@Override
217
				public void run() {
218
					String mess = KRAnnotationUIMessages.bind(KRAnnotationUIMessages.noValueFoundWithTheP0Id, svalue);
219
					System.out.println(mess);
220
					MessageDialog.openError(Display.getCurrent().getActiveShell(), "Annotation canceled", mess); //$NON-NLS-1$
221
				}
222
			});
223
			return;
224
		}
225
		
226
		Log.info(TXMCoreMessages.bind(KRAnnotationUIMessages.AffectP0ToSelectionEqualsP1, value_to_add.getId(), value_to_add.getTypeID(), matches.size()));
227
		
228
		// finally we can 'try' to create the annotations \o/
229
		try {
230
			HashMap<Match, List<Annotation>> existingAnnots = annotManager.createAnnotations(type, value_to_add, matches, job);
231
			
232
			// did we had problems ?
233
			if (existingAnnots != null && existingAnnots.size() > 0) {
234
				String message = NLS.bind(KRAnnotationUIMessages.couldNotAnnotateTheValueP0OnCertainSequences, value_to_add.getStandardName());
235
				for (Match m : existingAnnots.keySet()) {
236
					message += NLS.bind(KRAnnotationUIMessages.theSequenceP0IsOverlappingWith, m);
237
					
238
					for (Annotation existingAnnot : existingAnnots.get(m)) {
239
						if (existingAnnot.getStart() < m.getStart()) {
240
							message += TXMCoreMessages.bind(KRAnnotationUIMessages.theEndOfAStructureP0AtP1P2, existingAnnot.getType(), existingAnnot.getStart(), existingAnnot.getEnd());
241
						}
242
						else {
243
							message += TXMCoreMessages.bind(KRAnnotationUIMessages.theStartOfAStructureP0AtP1P2, existingAnnot.getType(), existingAnnot.getStart(), existingAnnot.getEnd());
244
						}
245
					}
246
				}
247
				final String final_message = message;
248
				job.syncExec(new Runnable() {
249
					
250
					@Override
251
					public void run() {
252
						MessageDialog.openInformation(editor.getSite().getShell(), KRAnnotationUIMessages.aboutAnnotations, final_message);
253
					}
254
				});
255
			}
256
			// if (history != null && !history.get(type).contains(value_to_add))
257
			// history.get(type).add(value_to_add);
258
			
259
			if (Log.getLevel().intValue() < Level.INFO.intValue() && annotManager != null) {
260
				annotManager.checkData();
261
			}
262
			// concordance.reloadCurrentLines();
263
		}
264
		catch (Exception e1) {
265
			System.out.println(NLS.bind(KRAnnotationUIMessages.errorWhileAffectionAnnotationColonP0, e1));
266
			Log.printStackTrace(e1);
267
			return;
268
		}
269
		
270
		job.syncExec(new Runnable() {
271
			
272
			@Override
273
			public void run() {
274
				try {
275
					editor.refresh(false);
276
				}
277
				catch (Exception e) {
278
					// TODO Auto-generated catch block
279
					e.printStackTrace();
280
				}
281
			}
282
		});
283
	}
284
	
285
	protected void deleteAnnotationValues(String[] word_selection) {
286
		
287
		ArrayList<Match> matches = new ArrayList<>();
288
		try {
289
			int[] indexes = CQPSearchEngine.getCqiClient().str2Id(corpus.getProperty("id").getQualifiedName(), word_selection);
290
			int[] allPositions = CQPSearchEngine.getCqiClient().idList2Cpos(corpus.getProperty("id").getQualifiedName(), indexes);
291
			for (int p : allPositions) {
292
				matches.add(new Match2P(p));
293
			}
294
			deleteAnnotationValues(matches);
295
		}
296
		catch (Exception e) {
297
			e.printStackTrace();
298
		}
299
		
300
	}
301
	
302
	protected void deleteAnnotationValues(final List<Match> matches) {
303
		final AnnotationType type = getSelectedAnnotationType();
304
		
305
		JobHandler job = new JobHandler(KRAnnotationUIMessages.annotatingConcordanceSelection, true) {
306
			
307
			@Override
308
			protected IStatus run(IProgressMonitor monitor) {
309
				this.runInit(monitor);
310
				try {
311
					deleteAnnotationValues(matches, type, this);
312
				}
313
				catch (Exception e) {
314
					Log.severe(NLS.bind(KRAnnotationUIMessages.errorWhileAnnotatingConcordanceSelectionColonP0, e));
315
					Log.printStackTrace(e);
316
					return Status.CANCEL_STATUS;
317
				}
318
				catch (ThreadDeath td) {
319
					System.out.println(KRAnnotationUIMessages.annotationCanceledByUser);
320
					return Status.CANCEL_STATUS;
321
				}
322
				
323
				return Status.OK_STATUS;
324
			}
325
		};
326
		job.startJob(true);
327
	}
328
	
329
	protected void deleteAnnotationValues(List<Match> matches, AnnotationType type, JobHandler job) {
330
		
331
		if (matches.size() == 0) {
332
			System.out.println("No lines selected. Aborting."); //$NON-NLS-1$
333
			return;
334
		}
335
		
336
		if (type == null) {
337
			return;
338
		}
339
		
340
		try {
341
			if (annotManager != null && annotManager.deleteAnnotations(type, matches, job)) {
342
				if (Log.getLevel().intValue() < Level.INFO.intValue()) annotManager.checkData();
343
				
344
			}
345
			else {
346
				return;
347
			}
348
		}
349
		catch (Exception e1) {
350
			System.out.println(NLS.bind(KRAnnotationUIMessages.errorWhileDeletingAnnotationColonP0, e1));
351
			Log.printStackTrace(e1);
352
			return;
353
		}
354
		
355
		job.syncExec(new Runnable() {
356
			
357
			@Override
358
			public void run() {
359
				try {
360
					editor.refresh(false);
361
				}
362
				catch (Exception e) {
363
					// TODO Auto-generated catch block
364
					e.printStackTrace();
365
				}
366
			}
367
		});
368
	}
369
	
370
	protected void affectAnnotationsToMatches(final List<? extends Match> matches) {
371
		final AnnotationType type = getSelectedAnnotationType();
372
		final String svalue = annotationValuesText.getText();
373
		
374
		JobHandler job = new JobHandler(KRAnnotationUIMessages.annotatingConcordanceSelection, true) {
375
			
376
			@Override
377
			protected IStatus run(IProgressMonitor monitor) {
378
				this.runInit(monitor);
379
				try {
380
					affectAnnotationValues(matches, type, svalue, this);
381
				}
382
				catch (Exception e) {
383
					Log.severe(NLS.bind(KRAnnotationUIMessages.errorWhileAnnotatingConcordanceSelectionColonP0, e));
384
					Log.printStackTrace(e);
385
					return Status.CANCEL_STATUS;
386
				}
387
				catch (ThreadDeath td) {
388
					System.out.println(KRAnnotationUIMessages.annotationCanceledByUser);
389
					return Status.CANCEL_STATUS;
390
				}
391
				
392
				return Status.OK_STATUS;
393
			}
394
		};
395
		job.startJob(true);
396
	}
397
	
398
	@Override
399
	public boolean install(TXMEditor<? extends TXMResult> txmeditor, AnnotationExtension ext, Composite parent, int position) throws Exception {
400
		
401
		this.extension = ext;
402
		this.editor = (SynopticEditionEditor) txmeditor;
403
		this.corpus = editor.getCorpus();
404
		this.annotManager = KRAnnotationEngine.getAnnotationManager(corpus);
405
		this.annotations = new EditionAnnotations(this.editor);
406
		
407
		// TODO install browser listeners here
408
		
409
		List<KnowledgeRepository> krs = InitializeKnowledgeRepository.get(corpus.getMainCorpus());
410
		typesList.clear();
411
		Log.fine("Corpus KRs: " + krs); //$NON-NLS-1$
412
		
413
		currentKnowledgeRepository = KnowledgeRepositoryManager.getKnowledgeRepository(corpus.getMainCorpus().getName());
414
		if (currentKnowledgeRepository == null) {
415
			HashMap<String, HashMap<String, ?>> conf = new HashMap<>();
416
			HashMap<String, String> access = new HashMap<>();
417
			conf.put(KRAnnotationEngine.KNOWLEDGE_ACCESS, access);
418
			HashMap<String, HashMap<String, String>> fields = new HashMap<>();
419
			conf.put(KRAnnotationEngine.KNOWLEDGE_TYPES, fields);
420
			HashMap<String, HashMap<String, String>> strings = new HashMap<>();
421
			conf.put(KRAnnotationEngine.KNOWLEDGE_STRINGS, strings);
422
			
423
			access.put("mode", DatabasePersistenceManager.ACCESS_FILE); //$NON-NLS-1$
424
			access.put("version", "0"); //$NON-NLS-1$ //$NON-NLS-2$
425
			currentKnowledgeRepository = KnowledgeRepositoryManager.createKnowledgeRepository(corpus.getMainCorpus().getName(), conf);
426
			KnowledgeRepositoryManager.registerKnowledgeRepository(currentKnowledgeRepository);
427
			// KRAnnotationEngine.registerKnowledgeRepositoryName(corpus, corpus.getMainCorpus().getName());
428
		}
429
		
430
		List<WordProperty> wordProperties = corpus.getProperties();
431
		for (WordProperty p : wordProperties) {
432
			if (p.getName().equals("id")) continue; //$NON-NLS-1$
433
			AnnotationType type = currentKnowledgeRepository.getType(p.getName());
434
			if (type == null) {
435
				AnnotationType t = currentKnowledgeRepository.addType(p.getName(), p.getName());
436
				t.setEffect(AnnotationEffect.TOKEN);
437
			}
438
			else if (type != null) {
439
				type.setEffect(AnnotationEffect.TOKEN);
440
			}
441
		}
442
		
443
		Log.fine("KR: " + currentKnowledgeRepository); //$NON-NLS-1$
444
		List<AnnotationType> krtypes = currentKnowledgeRepository.getAllAnnotationTypes();
445
		for (AnnotationType type : krtypes) {
446
			if (type.getEffect().equals(AnnotationEffect.TOKEN)) {
447
				typesList.add(type);
448
			}
449
		}
450
		
451
		Log.fine(NLS.bind(KRAnnotationUIMessages.availableAnnotationTypesColonP0, typesList));
452
		
453
		annotationArea = new GLComposite(parent, SWT.NONE, KRAnnotationUIMessages.concordanceAnnotationArea);
454
		annotationArea.getLayout().numColumns = 12;
455
		annotationArea.getLayout().horizontalSpacing = 2;
456
		annotationArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
457
		
458
		GridData gdata = new GridData(SWT.CENTER, SWT.CENTER, false, false);
459
		gdata.widthHint = 90;
460
		
461
		new Label(annotationArea, SWT.NONE).setText(TXMCoreMessages.common_property);
462
		
463
		// Display combo with list of Annotation Type
464
		annotationTypesCombo = new ComboViewer(annotationArea, SWT.READ_ONLY);
465
		annotationTypesCombo.setContentProvider(new ArrayContentProvider());
466
		annotationTypesCombo.setLabelProvider(new SimpleLabelProvider() {
467
			
468
			@Override
469
			public String getColumnText(Object element, int columnIndex) {
470
				return ((AnnotationType) element).getName();
471
			}
472
			
473
			@Override
474
			public String getText(Object element) {
475
				return ((AnnotationType) element).getName();
476
			}
477
		});
478
		// annotationTypesCombo.getCombo().addKeyListener(new KeyListener() {
479
		//
480
		// @Override
481
		// public void keyReleased(KeyEvent e) {
482
		// if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
483
		// String name = annotationTypesCombo.getCombo().getText();
484
		// if (currentKnowledgeRepository.getType(name) == null) {
485
		// createNewType(e, name);
486
		// } else {
487
		// for (AnnotationType type : typesList) {
488
		// if (name.equals(type.getId())) {
489
		// StructuredSelection selection = new StructuredSelection(type);
490
		// annotationTypesCombo.setSelection(selection, true);
491
		// break;
492
		// }
493
		// }
494
		// }
495
		// }
496
		// }
497
		//
498
		// @Override
499
		// public void keyPressed(KeyEvent e) { }
500
		// });
501
		
502
		gdata = new GridData(SWT.CENTER, SWT.CENTER, false, false);
503
		gdata.widthHint = 200;
504
		
505
		annotationTypesCombo.getCombo().setLayoutData(gdata);
506
		annotationTypesCombo.setInput(typesList);
507
		annotationTypesCombo.getCombo().select(0);
508
		annotations.setViewAnnotation(typesList.get(0));
509
		// for (int i = 0 ; i < typesList.size(); i++) {
510
		// String name = typesList.get(i).getName();
511
		// if ("word".equals(name)) {
512
		// annotations.setViewAnnotation(typesList.get(i));
513
		// annotationColumn.setText(name);
514
		// }
515
		// }
516
		
517
		annotationTypesCombo.addSelectionChangedListener(new ISelectionChangedListener() {
518
			
519
			@Override
520
			public void selectionChanged(SelectionChangedEvent event) {
521
				onAnnotationTypeSelected(event);
522
			}
523
		});
524
		
525
		addAnnotationTypeLink = new Button(annotationArea, SWT.PUSH);
526
		addAnnotationTypeLink.setToolTipText(KRAnnotationUIMessages.addANewCategory);
527
		addAnnotationTypeLink.setImage(IImageKeys.getImage(IImageKeys.ACTION_ADD));
528
		addAnnotationTypeLink.setEnabled(true);
529
		addAnnotationTypeLink.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
530
		addAnnotationTypeLink.addSelectionListener(new SelectionListener() {
531
			
532
			@Override
533
			public void widgetSelected(SelectionEvent e) {
534
				if (currentKnowledgeRepository == null) return;
535
				if (!(currentKnowledgeRepository instanceof LocalKnowledgeRepository)) return;
536
				
537
				LocalKnowledgeRepository kr = (LocalKnowledgeRepository) currentKnowledgeRepository;
538
				
539
				InputDialog dialog = new InputDialog(e.widget.getDisplay().getActiveShell(), "New property", "Enter the new property name", "", null);
540
				if (dialog.open() == InputDialog.OK) {
541
					String name = dialog.getValue();
542
					if (name.trim().length() == 0) return;
543
					String id = AsciiUtils.buildId(name);
544
					AnnotationType existingType = kr.getType(id);
545
					if (existingType != null) {
546
						Log.warning(NLS.bind("The ''{0}'' annotation type already exists. Please use another name ({1}).", id, name));
547
						annotationTypesCombo.setSelection(new StructuredSelection(existingType));
548
						return;
549
					}
550
					AnnotationType type = kr.addType(name, id, "", AnnotationEffect.TOKEN); //$NON-NLS-1$
551
					typesList.add(type);
552
					
553
					if (annotationTypesCombo != null) annotationTypesCombo.refresh();
554
					if (typesList.size() == 1) {
555
						if (annotationTypesCombo != null) annotationTypesCombo.getCombo().select(typesList.size() - 1);
556
						
557
						annotations.setViewAnnotation(type);
558
						annotations.setAnnotationOverlap(true);
559
						try {
560
							editor.refresh(false);
561
						}
562
						catch (Exception e1) {
563
							// TODO Auto-generated catch block
564
							e1.printStackTrace();
565
						}
566
						annotationArea.layout(true);
567
						
568
					}
569
					else {
570
						if (typesList.size() > 1) {
571
							if (annotationTypesCombo != null) {
572
								annotationTypesCombo.setSelection(new StructuredSelection(typesList.get(typesList.size() - 1)));
573
							}
574
						}
575
					}
576
					annotations.setViewAnnotation(type);
577
					annotationTypesCombo.setSelection(new StructuredSelection(typesList.get(typesList.size() - 1)));
578
					annotationArea.layout(true);
579
					KRView.refresh();
580
					updateAnnotationWidgetStates();
581
				}
582
				else {
583
					System.out.println("Creation aborted."); //$NON-NLS-1$
584
				}
585
			}
586
			
587
			@Override
588
			public void widgetDefaultSelected(SelectionEvent e) {}
589
		});
590
		
591
		equalLabel = new Label(annotationArea, SWT.NONE);
592
		equalLabel.setText("="); //$NON-NLS-1$
593
		equalLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
594
		
595
		annotationValuesText = new Text(annotationArea, SWT.BORDER);
596
		annotationValuesText.setToolTipText(KRAnnotationUIMessages.enterAValueForAnId);
597
		GridData gdata2 = new GridData(SWT.FILL, SWT.CENTER, false, false);
598
		gdata2.widthHint = 200;
599
		annotationValuesText.setLayoutData(gdata2);
600
		annotationValuesText.addKeyListener(new KeyListener() {
601
			
602
			@Override
603
			public void keyReleased(KeyEvent e) {
604
				if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
605
					affectAnnotationToSelection(editor.getEditionPanel(0).getWordSelection());
606
				}
607
			}
608
			
609
			@Override
610
			public void keyPressed(KeyEvent e) {}
611
		});
612
		
613
		addTypedValueLink = new Button(annotationArea, SWT.PUSH);
614
		addTypedValueLink.setText("..."); //$NON-NLS-1$
615
		addTypedValueLink.setToolTipText(KRAnnotationUIMessages.selectAValueAmongTheList);
616
		addTypedValueLink.setEnabled(true);
617
		addTypedValueLink.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
618
		addTypedValueLink.addSelectionListener(new SelectionListener() {
619
			
620
			@Override
621
			public void widgetSelected(SelectionEvent e) {
622
				if (currentKnowledgeRepository == null) return;
623
				if (!(currentKnowledgeRepository instanceof LocalKnowledgeRepository)) return;
624
				
625
				AnnotationType type = getSelectedAnnotationType();
626
				if (type == null) return;
627
				
628
				LocalKnowledgeRepository kr = (LocalKnowledgeRepository) currentKnowledgeRepository;
629
				
630
				ListDialog dialog = new ListDialog(e.widget.getDisplay().getActiveShell());
631
				String title = currentKnowledgeRepository.getString(editor.getCorpus().getLang(), "ConcordancesEditor_100"); //$NON-NLS-1$
632
				if (title == null) title = KRAnnotationUIMessages.availableValuesForP0;
633
				dialog.setTitle(ConcordanceUIMessages.bind(title, type.getName()));// +"valeurs de "+type.getName());
634
				dialog.setContentProvider(new ArrayContentProvider());
635
				dialog.setLabelProvider(new SimpleLabelProvider() {
636
					
637
					@Override
638
					public String getColumnText(Object element, int columnIndex) {
639
						if (element instanceof TypedValue)
640
							return ((TypedValue) element).getId();
641
						return element.toString();
642
					}
643
				});
644
				List<TypedValue> values;
645
				try {
646
					values = kr.getValues(type);
647
				}
648
				catch (Exception e1) {
649
					e1.printStackTrace();
650
					return;
651
				}
652
				dialog.setInput(values);
653
				if (dialog.open() == InputDialog.OK) {
654
					TypedValue value = (TypedValue) dialog.getResult()[0];
655
					String name = value.getId();
656
					if (name.trim().length() == 0) return;
657
					
658
					annotationValuesText.setText(name);
659
				}
660
				else {
661
					
662
				}
663
			}
664
			
665
			@Override
666
			public void widgetDefaultSelected(SelectionEvent e) {}
667
		});
668
		
669
		new Label(annotationArea, SWT.NONE).setText(" ");
670
		
671
		affectAnnotationButton = new Button(annotationArea, SWT.PUSH);
672
		affectAnnotationButton.setText(KRAnnotationUIMessages.oK);
673
		affectAnnotationButton.setToolTipText(KRAnnotationUIMessages.proceedToAnnotation);
674
		affectAnnotationButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
675
		affectAnnotationButton.addSelectionListener(new SelectionListener() {
676
			
677
			@Override
678
			public void widgetSelected(SelectionEvent e) {
679
				affectAnnotationToSelection(editor.getEditionPanel(0).getWordSelection());
680
			}
681
			
682
			@Override
683
			public void widgetDefaultSelected(SelectionEvent e) {}
684
		});
685
		
686
		deleteAnnotationButton = new Button(annotationArea, SWT.PUSH);
687
		deleteAnnotationButton.setText(KRAnnotationUIMessages.delete);
688
		deleteAnnotationButton.setToolTipText(KRAnnotationUIMessages.delete);
689
		deleteAnnotationButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
690
		deleteAnnotationButton.addSelectionListener(new SelectionListener() {
691
			
692
			@Override
693
			public void widgetSelected(SelectionEvent e) {
694
				deleteAnnotationValues(editor.getEditionPanel(0).getWordSelection());
695
			}
696
			
697
			@Override
698
			public void widgetDefaultSelected(SelectionEvent e) {}
699
		});
700
		
701
		Button closeButton = new Button(annotationArea, SWT.PUSH);
702
		closeButton.setToolTipText(KRAnnotationUIMessages.closeTheToolbarWithoutSaving);
703
		closeButton.setImage(IImageKeys.getImage(IImageKeys.ACTION_DELETE));
704
		
705
		closeButton.addSelectionListener(new SelectionListener() {
706
			
707
			@Override
708
			public void widgetSelected(SelectionEvent e) {
709
				extension.closeArea(WordAnnotationToolbar.this, true);
710
			}
711
			
712
			@Override
713
			public void widgetDefaultSelected(SelectionEvent e) {}
714
		});
715
		
716
		updateAnnotationWidgetStates();
717
		editor.layout(true);
718
		ext.getSaveButton().setEnabled(true);
719
		return true;
720
	}
721
	
722
	protected void onAnnotationTypeSelected(SelectionChangedEvent event) {
723
		
724
		IStructuredSelection sel = (IStructuredSelection) annotationTypesCombo.getSelection();
725
		AnnotationType type = (AnnotationType) sel.getFirstElement();
726
		if (type == null) return;
727
		
728
		if (type.getSize() != AnnotationType.ValuesSize.LARGE) {
729
			try {
730
				KnowledgeRepository kr = KnowledgeRepositoryManager.getKnowledgeRepository(type.getKnowledgeRepository());
731
				typeValuesList = kr.getValues(type);
732
			}
733
			catch (Exception e) {
734
				// TODO Auto-generated catch block
735
				e.printStackTrace();
736
			}
737
		}
738
		
739
		annotations.setViewAnnotation(type);
740
		annotations.setAnnotationOverlap(true);
741
		try {
742
			editor.refresh(false);
743
		}
744
		catch (Exception e) {
745
			// TODO Auto-generated catch block
746
			e.printStackTrace();
747
		}
748
		
749
		updateAnnotationWidgetStates();
750
	}
751
	
752
	protected void createNewType(TypedEvent e, String typeName) {
753
		
754
		if (currentKnowledgeRepository == null) return;
755
		if (!(currentKnowledgeRepository instanceof LocalKnowledgeRepository)) return;
756
		
757
		LocalKnowledgeRepository kr = (LocalKnowledgeRepository) currentKnowledgeRepository;
758
		if (typeName == null) typeName = ""; //$NON-NLS-1$
759
		InputDialog dialog = new InputDialog(e.widget.getDisplay().getActiveShell(), KRAnnotationUIMessages.nouvelleProprit, KRAnnotationUIMessages.nomDeLaPropritPatternEqualsazaz09Plus, typeName,
760
				null);
761
		if (dialog.open() == InputDialog.OK) {
762
			String name = dialog.getValue();
763
			if (name.trim().length() == 0) return;
764
			String baseid = AsciiUtils.buildId(name);
765
			String id = AsciiUtils.buildId(name);
766
			int c = 1;
767
			while (kr.getType(id) != null) {
768
				id = baseid + "_" + (c++); //$NON-NLS-1$
769
			}
770
			AnnotationType type = kr.addType(name, id, "", AnnotationEffect.TOKEN); //$NON-NLS-1$
771
			typesList.add(type);
772
			annotationTypesCombo.refresh();
773
			StructuredSelection selection = new StructuredSelection(type);
774
			annotationTypesCombo.setSelection(selection, true);
775
			
776
			// if (annotationTypesCombo != null) annotationTypesCombo.refresh();
777
			// if (typesList.size() == 1) {
778
			// if (annotationTypesCombo != null) annotationTypesCombo.getCombo().select(0);
779
			// annotations.setViewAnnotation(type);
780
			// annotations.setAnnotationOverlap(true);
781
			// try {
782
			// editor.refresh(false);
783
			// } catch (Exception e1) {
784
			// // TODO Auto-generated catch block
785
			// e1.printStackTrace();
786
			// }
787
			// annotationArea.layout(true);
788
			// } else {
789
			// if (typesList.size() > 1) {
790
			// if (annotationTypesCombo != null) {
791
			// annotationTypesCombo.getCombo().select(typesList.size()-1);
792
			// }
793
			// }
794
			// }
795
			// KRView.refresh();
796
			// updateAnnotationWidgetStates();
797
			
798
			// onAnnotationTypeSelected(null);
799
		}
800
		else {
801
			System.out.println("Creation aborted."); //$NON-NLS-1$
802
		}
803
	}
804
	
805
	@Override
806
	public boolean save() {
807
		try {
808
			AnnotationManager am = KRAnnotationEngine.getAnnotationManager(WordAnnotationToolbar.this.corpus);
809
			if (am != null && am.hasChanges()) {
810
				// && MessageDialog.openConfirm(e.display.getActiveShell(), "Confirm annotation save", "Saving annotation will close this editor. Are you sure you want to save annotations right now
811
				// ?")
812
				JobHandler saveJob = SaveAnnotations.save(WordAnnotationToolbar.this.corpus.getMainCorpus());
813
				if (saveJob == null || saveJob.getResult() == Status.CANCEL_STATUS) {
814
					// update editor corpus
815
					System.out.println("Fail to save annotations of the corpus."); //$NON-NLS-1$
816
					return false;
817
				}
818
				else {
819
					return true; // something was saved
820
				}
821
			}
822
			else {
823
				return false;
824
			}
825
		}
826
		catch (Exception ex) {
827
			ex.printStackTrace();
828
			return false;
829
		}
830
	}
831
	
832
	@Override
833
	public boolean hasChanges() {
834
		AnnotationManager am;
835
		try {
836
			am = KRAnnotationEngine.getAnnotationManager(corpus);
837
			if (am != null && am.hasChanges()) {
838
				return am.hasChanges();
839
			}
840
			else {
841
				return false;
842
			}
843
		}
844
		catch (Exception e) {
845
			// TODO Auto-generated catch block
846
			e.printStackTrace();
847
			return false;
848
		}
849
	}
850
	
851
	@Override
852
	public boolean notifyStartOfCompute() throws Exception {
853
		if (annotationArea == null) return false;
854
		if (annotationArea.isDisposed()) return false;
855
		
856
		AnnotationType type = getSelectedAnnotationType();
857
		if (type != null) {
858
			annotations.setViewAnnotation(type);
859
			annotations.setAnnotationOverlap(true);
860
		}
861
		
862
		return true;
863
	}
864
	
865
	@Override
866
	public boolean notifyEndOfCompute() throws Exception {
867
		return true;
868
	}
869
	
870
	@Override
871
	public boolean isAnnotationEnable() {
872
		return annotationArea != null;
873
	}
874
	
875
	@Override
876
	public void notifyStartOfRefresh() throws Exception {
877
		if (annotationArea == null) return;
878
		if (annotationArea.isDisposed()) return;
879
		
880
		Page currentPage = editor.getEditionPanel(0).getCurrentPage();
881
		if (currentPage == null) return;
882
		
883
		String startID = currentPage.getWordId();
884
		Page nextPage = currentPage.getEdition().getNextPage(currentPage);
885
		String endID = nextPage.getWordId();
886
		
887
		annotations.computeStrings(startID, endID);
888
		
889
		updateAnnotationWidgetStates();
890
		
891
	}
892
	
893
	@Override
894
	protected void _close() {
895
		if (!annotationArea.isDisposed()) annotationArea.dispose();
896
		extension.layout();
897
	}
898
	
899
	@Override
900
	public void notifyEndOfRefresh() throws Exception {
901
		// TODO Auto-generated method stub
902
	}
903
	
904
	@Override
905
	public void notifyStartOfCreatePartControl() throws Exception {
906
		// TODO Auto-generated method stub
907
	}
908
	
909
	@Override
910
	public Class<? extends TXMResult> getAnnotatedTXMResultClass() {
911
		return org.txm.objects.Text.class;
912
	}
913
	
914
	@Override
915
	public boolean isDirty() {
916
		if (annotManager != null) {
917
			return annotManager.isDirty();
918
		}
919
		return false;
920
	}
921
	
922
	@Override
923
	public boolean discardChanges() {
924
		return false;
925
	}
926
	
927
	@Override
928
	public boolean needToUpdateIndexes() {
929
		return true;
930
	}
931
}
0 932

  

Formats disponibles : Unified diff