Index: tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/edition/EditionAnnotations.java
===================================================================
--- tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/edition/EditionAnnotations.java	(revision 0)
+++ tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/edition/EditionAnnotations.java	(revision 3161)
@@ -0,0 +1,233 @@
+package org.txm.annotation.kr.rcp.edition;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.txm.annotation.kr.core.Annotation;
+import org.txm.annotation.kr.core.AnnotationManager;
+import org.txm.annotation.kr.core.KRAnnotationEngine;
+import org.txm.annotation.kr.core.repository.AnnotationType;
+import org.txm.annotation.kr.core.repository.TypedValue;
+import org.txm.concordance.core.functions.Concordance;
+import org.txm.edition.rcp.editors.SynopticEditionEditor;
+import org.txm.objects.Match;
+import org.txm.objects.Match2P;
+import org.txm.searchengine.cqp.CQPSearchEngine;
+import org.txm.searchengine.cqp.corpus.CQPCorpus;
+import org.txm.searchengine.cqp.corpus.query.MatchUtils;
+import org.txm.utils.logger.Log;
+
+/**
+ * Annotation values to display in the current concordance shown lines
+ * 
+ * Call getStrings(conclines, from, to) 
+ * 
+ * @author mdecorde
+ *
+ */
+public class EditionAnnotations {
+	
+	SynopticEditionEditor editor;
+	
+	private AnnotationType viewAnnotation;
+	
+	public EditionAnnotations(SynopticEditionEditor editor) {
+		this.editor = editor;
+	}
+	
+	private boolean overlapAnnotation;
+
+	private HashMap<String, HashMap<String, String>> lines;
+
+	public void setAnnotationOverlap(boolean overlap) {
+		overlapAnnotation = overlap;
+	}
+	public boolean getAnnotationOverlap() {
+		return overlapAnnotation;
+	}
+	
+	public HashMap<String, HashMap<String, String>> computeStrings(String startID, String endID) throws Exception {
+
+		CQPCorpus corpus = this.editor.getCorpus();
+		
+		int[] indexes = CQPSearchEngine.getCqiClient().str2Id(corpus.getProperty("id").getQualifiedName(), new String[] {startID, endID});
+		int[] startEndPositions = CQPSearchEngine.getCqiClient().idList2Cpos(corpus.getProperty("id").getQualifiedName(), indexes);
+		int[] allPositions = MatchUtils.toPositions(startEndPositions[1], startEndPositions[0]);
+		String[] allWordIDS = CQPSearchEngine.getCqiClient().cpos2Str(corpus.getProperty("id").getQualifiedName(), allPositions);
+		
+		HashMap<Match, String> matches = new HashMap<Match, String>();
+		for (int i = 0 ; i < allWordIDS.length ; i++) {
+			matches.put(new Match2P(allPositions[i]), allWordIDS[i]);
+		}
+		ArrayList<Match> sorted_matches = new ArrayList<Match>(matches.keySet());
+		Collections.sort(sorted_matches);
+		
+		List<Annotation> ann = getAnnotationForMatches(sorted_matches, overlapAnnotation);
+		lines = new HashMap<String, HashMap<String, String>>();
+		
+		for (int i = 0 ; i < ann.size() ; i++) {
+			Annotation a = ann.get(i);
+			HashMap<String, String> aline = new HashMap<String, String>();
+			TypedValue annotation = getAnnotationTypedValue(a);
+			aline.put(annotation.getTypeID(), annotation.getId());
+			lines.put(matches.get(sorted_matches.get(i)), aline);
+		}
+		
+		return lines; // TODO find a way to add with lazy method
+	}
+	
+	private String findAnnotationForString(Match match, List<Annotation> annots, boolean overlap) {
+		String annotationValue = "";
+		if (annots!=null) {
+			if (!annots.isEmpty()) {
+				for (Annotation annot : annots) {
+					if (overlap) {
+						if ((annot.getStart()<=match.getStart() && annot.getEnd()>=match.getEnd()) || (annot.getStart()>match.getStart() && annot.getEnd()<match.getEnd())
+								) {
+							annotationValue = annot.getValue(); 
+							// use the first Annotation found, the one stored in the temporary HSQL database
+							//should be modified to display a list of annotation values corresponding to the match positions (or wrapped if overlap is admitted)
+						}
+					} else {
+						if (annot.getStart()==match.getStart() && annot.getEnd()==match.getEnd()) {
+							annotationValue = annot.getValue(); 
+							// use the first Annotation found, the one stored in the temporary HSQL database
+						}
+					}
+				}
+			}
+		}
+		return annotationValue;
+	}
+	
+	public TypedValue getAnnotationTypedValue(Annotation annotation) { 
+
+		TypedValue annotationValue = null;
+		if (annotation!=null) {
+			annotationValue = viewAnnotation.getTypedValue(annotation.getValue());
+			if (annotationValue == null) { // the annotation is not stored in the KR type -> the annotation is surely built with the CQPAnnotationManager
+				//System.out.println("WARNING: no annotation value found for value id="+annotation.getValue()+" - will be created.");
+				annotationValue = new TypedValue(annotation.getValue(), annotation.getValue(), annotation.getType());
+			}
+		}
+		
+		return annotationValue;
+	}
+
+	/**
+	 * 
+	 * @return the current annotation type
+	 */
+	public AnnotationType getViewAnnotation() {
+		return viewAnnotation;
+	}
+
+
+	private List<Annotation> prepareAnnotationsList(List<Match> matches, List<Annotation> annotations, boolean overlap){
+		List<Annotation> annotsList = new ArrayList<Annotation>();
+
+		int iMatch = 0;
+		int iAnnotation = 0;
+		int nMatch = matches.size();
+		int nAnnotations = annotations.size();
+
+		while (iMatch < nMatch && iAnnotation < nAnnotations) {
+			if (overlap) {
+				if (matches.get(iMatch).getEnd() < annotations.get(iAnnotation).getStart()) {
+					iMatch++;
+					annotsList.add(null); // nothing for this match
+				} else if (annotations.get(iAnnotation).getEnd() < matches.get(iMatch).getStart()) {
+					iAnnotation++;
+				} else {
+					annotsList.add(annotations.get(iAnnotation));
+					iMatch++;
+				}
+			} else {
+				if (matches.get(iMatch).getEnd() < annotations.get(iAnnotation).getStart()) {
+					iMatch++;
+					annotsList.add(null); // nothing for this match
+				} else if (annotations.get(iAnnotation).getEnd() < matches.get(iMatch).getStart()) {
+					iAnnotation++;
+				} else if (annotations.get(iAnnotation).getStart() == matches.get(iMatch).getStart() && 
+						annotations.get(iAnnotation).getEnd() == matches.get(iMatch).getEnd()) {
+					annotsList.add(annotations.get(iAnnotation));
+					iMatch++;
+					iAnnotation++;
+				} else {
+					iAnnotation++;
+				}
+			}
+		}
+
+		while (annotsList.size() < matches.size() ) annotsList.add(null); // fill matches that were not process due to no more annotations
+
+		return annotsList;
+	}
+
+	private HashMap<Match, Annotation> prepareAnnotationsMap(List<Match> matches, List<Annotation> annots, boolean overlap){
+		HashMap<Match, Annotation> annotsList = new HashMap<Match, Annotation>();
+		for (Match m : matches) {
+			boolean hasAnnotations = false;
+			if (annots!=null) {
+				if (!annots.isEmpty()) {
+					for (Annotation annot : annots) {
+						if (overlap){
+							if ((annot.getStart() <= m.getStart() && m.getStart() <= annot.getEnd() && m.getEnd() >= annot.getEnd()) || 
+									(annot.getStart() <= m.getEnd() && m.getEnd() <= annot.getEnd() && m.getStart() <= annot.getStart()) 
+									|| !(annot.getEnd() < m.getStart() || annot.getStart() > m.getEnd())){
+								annotsList.put(m, annot);
+								hasAnnotations = true;
+							}
+						} else {
+							if (annot.getStart()==m.getStart() && annot.getEnd()==m.getEnd()) {
+								annotsList.put(m, annot); 
+								hasAnnotations = true;
+							}
+						}
+					}
+				}
+			}
+			if (!hasAnnotations) {
+				annotsList.put(m, null);
+			}
+		}
+		return annotsList;
+	}
+
+	public List<Annotation> getAnnotationForMatches(List<Match> subsetMatch, boolean overlapAnnotation) throws Exception {
+		
+		AnnotationManager am = KRAnnotationEngine.getAnnotationManager(editor.getCorpus());
+		
+		//List<Annotation> allAnnotations = null;
+		List<Annotation> annotationsPerMatch = new ArrayList<Annotation>();
+		if (viewAnnotation != null && am != null) {
+			try {
+				annotationsPerMatch = am.getAnnotationsForMatches(viewAnnotation, subsetMatch, overlapAnnotation);
+				//System.out.println("annotationsPerMatch: "+annotationsPerMatch);
+			} catch (Exception e) {
+				System.out.println("Error while reading annotation "+viewAnnotation+" and with "+subsetMatch.size()+" matches");
+				Log.printStackTrace(e);
+			}
+		}
+		return annotationsPerMatch;
+	}
+
+	public void setViewAnnotation(AnnotationType type) {
+		viewAnnotation = type;
+	}
+	
+	/**
+	 * 
+	 * @param i the relative position of the HashMap<String, String> in the lines list
+	 * 
+	 * @return the HashMap<String, String> pointed by 'i'. May return null if i is wrong.
+	 */
+	public HashMap<String, String> getAnnotationsString(String line) {
+		if (lines == null) return null;
+		if (!lines.containsKey(line)) return null;
+		return lines.get(line);
+	}
+}

Property changes on: tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/edition/EditionAnnotations.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/edition/WordAnnotationToolbar.java
===================================================================
--- tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/edition/WordAnnotationToolbar.java	(revision 0)
+++ tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/edition/WordAnnotationToolbar.java	(revision 3161)
@@ -0,0 +1,931 @@
+package org.txm.annotation.kr.rcp.edition;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Vector;
+import java.util.logging.Level;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.TypedEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.ListDialog;
+import org.txm.annotation.kr.core.Annotation;
+import org.txm.annotation.kr.core.AnnotationManager;
+import org.txm.annotation.kr.core.DatabasePersistenceManager;
+import org.txm.annotation.kr.core.KRAnnotationEngine;
+import org.txm.annotation.kr.core.repository.AnnotationEffect;
+import org.txm.annotation.kr.core.repository.AnnotationType;
+import org.txm.annotation.kr.core.repository.KnowledgeRepository;
+import org.txm.annotation.kr.core.repository.KnowledgeRepositoryManager;
+import org.txm.annotation.kr.core.repository.LocalKnowledgeRepository;
+import org.txm.annotation.kr.core.repository.TypedValue;
+import org.txm.annotation.kr.rcp.commands.InitializeKnowledgeRepository;
+import org.txm.annotation.kr.rcp.commands.SaveAnnotations;
+import org.txm.annotation.kr.rcp.concordance.ConcordanceAnnotations;
+import org.txm.annotation.kr.rcp.messages.KRAnnotationUIMessages;
+import org.txm.annotation.kr.rcp.views.knowledgerepositories.KRView;
+import org.txm.annotation.rcp.editor.AnnotationArea;
+import org.txm.annotation.rcp.editor.AnnotationExtension;
+import org.txm.concordance.core.functions.Concordance;
+import org.txm.concordance.rcp.messages.ConcordanceUIMessages;
+import org.txm.core.messages.TXMCoreMessages;
+import org.txm.core.results.TXMResult;
+import org.txm.edition.rcp.editors.SynopticEditionEditor;
+import org.txm.objects.Match;
+import org.txm.objects.Match2P;
+import org.txm.objects.Page;
+import org.txm.rcp.IImageKeys;
+import org.txm.rcp.editors.TXMEditor;
+import org.txm.rcp.swt.GLComposite;
+import org.txm.rcp.swt.dialog.ConfirmDialog;
+import org.txm.rcp.swt.provider.SimpleLabelProvider;
+import org.txm.rcp.utils.JobHandler;
+import org.txm.searchengine.cqp.CQPSearchEngine;
+import org.txm.searchengine.cqp.corpus.CQPCorpus;
+import org.txm.searchengine.cqp.corpus.WordProperty;
+import org.txm.utils.AsciiUtils;
+import org.txm.utils.logger.Log;
+
+public class WordAnnotationToolbar extends AnnotationArea {
+	
+	/**
+	 * the limit number of annotation when a confirm dialog box is shown
+	 */
+	protected static final int NALERTAFFECTANNOTATIONS = 100;
+	
+	public static final String EMPTYTEXT = ""; //$NON-NLS-1$
+	
+	/** The annotation service */
+	protected AnnotationManager annotManager;
+	
+	protected SynopticEditionEditor editor;
+	
+	/**
+	 * The concordance annotations to show in the concordance column table
+	 */
+	private EditionAnnotations annotations = null;
+	
+	/**
+	 * All available annotation types
+	 */
+	protected List<TypedValue> typeValuesList;
+	
+	protected ComboViewer annotationTypesCombo;
+	
+	protected Label equalLabel;
+	
+	protected Text annotationValuesText;
+	
+	protected Button affectAnnotationButton;
+	
+	protected Button deleteAnnotationButton;
+	
+	protected KnowledgeRepository currentKnowledgeRepository = null;
+	
+	protected Vector<AnnotationType> typesList = new Vector<>();
+	
+	protected AnnotationType tagAnnotationType; // the tag annotation type if annotation mode is simple
+	
+	protected TypedValue value_to_add;
+	
+	//protected Concordance concordance;
+	
+	private CQPCorpus corpus;
+	
+	private TableViewerColumn annotationColumnViewer;
+	
+	private Font annotationColummnFont;
+	
+	private Font defaultColummnFont;
+	
+	private Button addAnnotationTypeLink;
+	
+	private Button addTypedValueLink;
+	
+	@Override
+	public String getName() {
+		return KRAnnotationUIMessages.motsPropritsInfDfaut;
+	}
+	
+	@Override
+	public boolean allowMultipleAnnotations() {
+		return true;
+	}
+	
+	public WordAnnotationToolbar() {}
+	
+	protected AnnotationType getSelectedAnnotationType() {
+		return annotations.getViewAnnotation();
+	}
+	
+	public void updateAnnotationWidgetStates() {
+		if (annotationArea == null) return; // :)
+		
+		if (getSelectedAnnotationType() != null) {
+			annotationValuesText.setEnabled(true);
+			affectAnnotationButton.setEnabled(true);
+			deleteAnnotationButton.setEnabled(true);
+		}
+		else {
+			annotationValuesText.setEnabled(false);
+			affectAnnotationButton.setEnabled(false);
+			deleteAnnotationButton.setEnabled(false);
+		}
+	}
+	
+	protected void affectAnnotationToSelection(String[] word_selection) {
+		
+		ArrayList<Match> matches = new ArrayList<>();
+
+		try {
+			int[] indexes = CQPSearchEngine.getCqiClient().str2Id(corpus.getProperty("id").getQualifiedName(), word_selection);
+			int[] allPositions = CQPSearchEngine.getCqiClient().idList2Cpos(corpus.getProperty("id").getQualifiedName(), indexes);
+			for (int p : allPositions) {
+				matches.add(new Match2P(p));
+			}
+			affectAnnotationsToMatches(matches);
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+	
+	protected void affectAnnotationValues(final List<? extends Match> matches, final AnnotationType type, final String svalue, JobHandler job) {
+		value_to_add = null; // reset
+		if (matches == null || matches.size() == 0) {
+			System.out.println("No line selected. Aborting."); //$NON-NLS-1$
+			return;
+		}
+		if (type == null) return; // no type, no annotation
+		
+		job.syncExec(new Runnable() {
+			
+			@Override
+			public void run() {
+				if (matches.size() > NALERTAFFECTANNOTATIONS) {
+					ConfirmDialog dialog = new ConfirmDialog(Display.getCurrent().getActiveShell(),
+							"confirm_annotate",  //$NON-NLS-1$
+							KRAnnotationUIMessages.confirmAnnotationAffectation,
+							NLS.bind(KRAnnotationUIMessages.youAreAboutToAnnotateP0ElementsContinue, matches.size()));
+					
+					if (dialog.open() == ConfirmDialog.CANCEL) {
+						System.out.println("Annotation aborted by user."); //$NON-NLS-1$
+						matches.clear();
+					}
+				}
+			}
+		});
+		
+		// get value from combo text value
+		Log.fine(NLS.bind(KRAnnotationUIMessages.lookingForTypedValueWithIdEqualsP0, svalue));
+		final KnowledgeRepository kr = KnowledgeRepositoryManager.getKnowledgeRepository(type.getKnowledgeRepository());
+		value_to_add = kr.getValue(type, svalue);
+		
+		
+		if (value_to_add == null && kr instanceof LocalKnowledgeRepository) { // create or not the annotation is simple mode
+			value_to_add = kr.addValue(svalue, svalue, type.getId());
+		}
+		
+		if (value_to_add == null) {
+			job.syncExec(new Runnable() {
+				
+				@Override
+				public void run() {
+					String mess = KRAnnotationUIMessages.bind(KRAnnotationUIMessages.noValueFoundWithTheP0Id, svalue);
+					System.out.println(mess);
+					MessageDialog.openError(Display.getCurrent().getActiveShell(), "Annotation canceled", mess); //$NON-NLS-1$
+				}
+			});
+			return;
+		}
+		
+		Log.info(TXMCoreMessages.bind(KRAnnotationUIMessages.AffectP0ToSelectionEqualsP1, value_to_add.getId(), value_to_add.getTypeID(), matches.size()));
+		
+		// finally we can 'try' to create the annotations \o/
+		try {
+			HashMap<Match, List<Annotation>> existingAnnots = annotManager.createAnnotations(type, value_to_add, matches, job);
+			
+			// did we had problems ?
+			if (existingAnnots != null && existingAnnots.size() > 0) {
+				String message = NLS.bind(KRAnnotationUIMessages.couldNotAnnotateTheValueP0OnCertainSequences, value_to_add.getStandardName());
+				for (Match m : existingAnnots.keySet()) {
+					message += NLS.bind(KRAnnotationUIMessages.theSequenceP0IsOverlappingWith, m);
+					
+					for (Annotation existingAnnot : existingAnnots.get(m)) {
+						if (existingAnnot.getStart() < m.getStart()) {
+							message += TXMCoreMessages.bind(KRAnnotationUIMessages.theEndOfAStructureP0AtP1P2, existingAnnot.getType(), existingAnnot.getStart(), existingAnnot.getEnd());
+						}
+						else {
+							message += TXMCoreMessages.bind(KRAnnotationUIMessages.theStartOfAStructureP0AtP1P2, existingAnnot.getType(), existingAnnot.getStart(), existingAnnot.getEnd());
+						}
+					}
+				}
+				final String final_message = message;
+				job.syncExec(new Runnable() {
+					
+					@Override
+					public void run() {
+						MessageDialog.openInformation(editor.getSite().getShell(), KRAnnotationUIMessages.aboutAnnotations, final_message);
+					}
+				});
+			}
+			// if (history != null && !history.get(type).contains(value_to_add))
+			// history.get(type).add(value_to_add);
+			
+			if (Log.getLevel().intValue() < Level.INFO.intValue() && annotManager != null) {
+				annotManager.checkData();
+			}
+			// concordance.reloadCurrentLines();
+		}
+		catch (Exception e1) {
+			System.out.println(NLS.bind(KRAnnotationUIMessages.errorWhileAffectionAnnotationColonP0, e1));
+			Log.printStackTrace(e1);
+			return;
+		}
+		
+		job.syncExec(new Runnable() {
+			
+			@Override
+			public void run() {
+				try {
+					editor.refresh(false);
+				}
+				catch (Exception e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		});
+	}
+	
+	protected void deleteAnnotationValues(String[] word_selection) {
+		
+		ArrayList<Match> matches = new ArrayList<>();
+		try {
+			int[] indexes = CQPSearchEngine.getCqiClient().str2Id(corpus.getProperty("id").getQualifiedName(), word_selection);
+			int[] allPositions = CQPSearchEngine.getCqiClient().idList2Cpos(corpus.getProperty("id").getQualifiedName(), indexes);
+			for (int p : allPositions) {
+				matches.add(new Match2P(p));
+			}
+			deleteAnnotationValues(matches);
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+		}
+		
+	}
+	
+	protected void deleteAnnotationValues(final List<Match> matches) {
+		final AnnotationType type = getSelectedAnnotationType();
+		
+		JobHandler job = new JobHandler(KRAnnotationUIMessages.annotatingConcordanceSelection, true) {
+			
+			@Override
+			protected IStatus run(IProgressMonitor monitor) {
+				this.runInit(monitor);
+				try {
+					deleteAnnotationValues(matches, type, this);
+				}
+				catch (Exception e) {
+					Log.severe(NLS.bind(KRAnnotationUIMessages.errorWhileAnnotatingConcordanceSelectionColonP0, e));
+					Log.printStackTrace(e);
+					return Status.CANCEL_STATUS;
+				}
+				catch (ThreadDeath td) {
+					System.out.println(KRAnnotationUIMessages.annotationCanceledByUser);
+					return Status.CANCEL_STATUS;
+				}
+				
+				return Status.OK_STATUS;
+			}
+		};
+		job.startJob(true);
+	}
+	
+	protected void deleteAnnotationValues(List<Match> matches, AnnotationType type, JobHandler job) {
+		
+		if (matches.size() == 0) {
+			System.out.println("No lines selected. Aborting."); //$NON-NLS-1$
+			return;
+		}
+		
+		if (type == null) {
+			return;
+		}
+		
+		try {
+			if (annotManager != null && annotManager.deleteAnnotations(type, matches, job)) {
+				if (Log.getLevel().intValue() < Level.INFO.intValue()) annotManager.checkData();
+				
+			}
+			else {
+				return;
+			}
+		}
+		catch (Exception e1) {
+			System.out.println(NLS.bind(KRAnnotationUIMessages.errorWhileDeletingAnnotationColonP0, e1));
+			Log.printStackTrace(e1);
+			return;
+		}
+		
+		job.syncExec(new Runnable() {
+			
+			@Override
+			public void run() {
+				try {
+					editor.refresh(false);
+				}
+				catch (Exception e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		});
+	}
+	
+	protected void affectAnnotationsToMatches(final List<? extends Match> matches) {
+		final AnnotationType type = getSelectedAnnotationType();
+		final String svalue = annotationValuesText.getText();
+		
+		JobHandler job = new JobHandler(KRAnnotationUIMessages.annotatingConcordanceSelection, true) {
+			
+			@Override
+			protected IStatus run(IProgressMonitor monitor) {
+				this.runInit(monitor);
+				try {
+					affectAnnotationValues(matches, type, svalue, this);
+				}
+				catch (Exception e) {
+					Log.severe(NLS.bind(KRAnnotationUIMessages.errorWhileAnnotatingConcordanceSelectionColonP0, e));
+					Log.printStackTrace(e);
+					return Status.CANCEL_STATUS;
+				}
+				catch (ThreadDeath td) {
+					System.out.println(KRAnnotationUIMessages.annotationCanceledByUser);
+					return Status.CANCEL_STATUS;
+				}
+				
+				return Status.OK_STATUS;
+			}
+		};
+		job.startJob(true);
+	}
+	
+	@Override
+	public boolean install(TXMEditor<? extends TXMResult> txmeditor, AnnotationExtension ext, Composite parent, int position) throws Exception {
+		
+		this.extension = ext;
+		this.editor = (SynopticEditionEditor) txmeditor;
+		this.corpus = editor.getCorpus();
+		this.annotManager = KRAnnotationEngine.getAnnotationManager(corpus);
+		this.annotations = new EditionAnnotations(this.editor);
+		
+		// TODO install browser listeners here
+		
+		List<KnowledgeRepository> krs = InitializeKnowledgeRepository.get(corpus.getMainCorpus());
+		typesList.clear();
+		Log.fine("Corpus KRs: " + krs); //$NON-NLS-1$
+		
+		currentKnowledgeRepository = KnowledgeRepositoryManager.getKnowledgeRepository(corpus.getMainCorpus().getName());
+		if (currentKnowledgeRepository == null) {
+			HashMap<String, HashMap<String, ?>> conf = new HashMap<>();
+			HashMap<String, String> access = new HashMap<>();
+			conf.put(KRAnnotationEngine.KNOWLEDGE_ACCESS, access);
+			HashMap<String, HashMap<String, String>> fields = new HashMap<>();
+			conf.put(KRAnnotationEngine.KNOWLEDGE_TYPES, fields);
+			HashMap<String, HashMap<String, String>> strings = new HashMap<>();
+			conf.put(KRAnnotationEngine.KNOWLEDGE_STRINGS, strings);
+			
+			access.put("mode", DatabasePersistenceManager.ACCESS_FILE); //$NON-NLS-1$
+			access.put("version", "0"); //$NON-NLS-1$ //$NON-NLS-2$
+			currentKnowledgeRepository = KnowledgeRepositoryManager.createKnowledgeRepository(corpus.getMainCorpus().getName(), conf);
+			KnowledgeRepositoryManager.registerKnowledgeRepository(currentKnowledgeRepository);
+			// KRAnnotationEngine.registerKnowledgeRepositoryName(corpus, corpus.getMainCorpus().getName());
+		}
+		
+		List<WordProperty> wordProperties = corpus.getProperties();
+		for (WordProperty p : wordProperties) {
+			if (p.getName().equals("id")) continue; //$NON-NLS-1$
+			AnnotationType type = currentKnowledgeRepository.getType(p.getName());
+			if (type == null) {
+				AnnotationType t = currentKnowledgeRepository.addType(p.getName(), p.getName());
+				t.setEffect(AnnotationEffect.TOKEN);
+			}
+			else if (type != null) {
+				type.setEffect(AnnotationEffect.TOKEN);
+			}
+		}
+		
+		Log.fine("KR: " + currentKnowledgeRepository); //$NON-NLS-1$
+		List<AnnotationType> krtypes = currentKnowledgeRepository.getAllAnnotationTypes();
+		for (AnnotationType type : krtypes) {
+			if (type.getEffect().equals(AnnotationEffect.TOKEN)) {
+				typesList.add(type);
+			}
+		}
+		
+		Log.fine(NLS.bind(KRAnnotationUIMessages.availableAnnotationTypesColonP0, typesList));
+		
+		annotationArea = new GLComposite(parent, SWT.NONE, KRAnnotationUIMessages.concordanceAnnotationArea);
+		annotationArea.getLayout().numColumns = 12;
+		annotationArea.getLayout().horizontalSpacing = 2;
+		annotationArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+		
+		GridData gdata = new GridData(SWT.CENTER, SWT.CENTER, false, false);
+		gdata.widthHint = 90;
+		
+		new Label(annotationArea, SWT.NONE).setText(TXMCoreMessages.common_property);
+		
+		// Display combo with list of Annotation Type
+		annotationTypesCombo = new ComboViewer(annotationArea, SWT.READ_ONLY);
+		annotationTypesCombo.setContentProvider(new ArrayContentProvider());
+		annotationTypesCombo.setLabelProvider(new SimpleLabelProvider() {
+			
+			@Override
+			public String getColumnText(Object element, int columnIndex) {
+				return ((AnnotationType) element).getName();
+			}
+			
+			@Override
+			public String getText(Object element) {
+				return ((AnnotationType) element).getName();
+			}
+		});
+		// annotationTypesCombo.getCombo().addKeyListener(new KeyListener() {
+		//
+		// @Override
+		// public void keyReleased(KeyEvent e) {
+		// if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
+		// String name = annotationTypesCombo.getCombo().getText();
+		// if (currentKnowledgeRepository.getType(name) == null) {
+		// createNewType(e, name);
+		// } else {
+		// for (AnnotationType type : typesList) {
+		// if (name.equals(type.getId())) {
+		// StructuredSelection selection = new StructuredSelection(type);
+		// annotationTypesCombo.setSelection(selection, true);
+		// break;
+		// }
+		// }
+		// }
+		// }
+		// }
+		//
+		// @Override
+		// public void keyPressed(KeyEvent e) { }
+		// });
+		
+		gdata = new GridData(SWT.CENTER, SWT.CENTER, false, false);
+		gdata.widthHint = 200;
+		
+		annotationTypesCombo.getCombo().setLayoutData(gdata);
+		annotationTypesCombo.setInput(typesList);
+		annotationTypesCombo.getCombo().select(0);
+		annotations.setViewAnnotation(typesList.get(0));
+		// for (int i = 0 ; i < typesList.size(); i++) {
+		// String name = typesList.get(i).getName();
+		// if ("word".equals(name)) {
+		// annotations.setViewAnnotation(typesList.get(i));
+		// annotationColumn.setText(name);
+		// }
+		// }
+		
+		annotationTypesCombo.addSelectionChangedListener(new ISelectionChangedListener() {
+			
+			@Override
+			public void selectionChanged(SelectionChangedEvent event) {
+				onAnnotationTypeSelected(event);
+			}
+		});
+		
+		addAnnotationTypeLink = new Button(annotationArea, SWT.PUSH);
+		addAnnotationTypeLink.setToolTipText(KRAnnotationUIMessages.addANewCategory);
+		addAnnotationTypeLink.setImage(IImageKeys.getImage(IImageKeys.ACTION_ADD));
+		addAnnotationTypeLink.setEnabled(true);
+		addAnnotationTypeLink.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
+		addAnnotationTypeLink.addSelectionListener(new SelectionListener() {
+			
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (currentKnowledgeRepository == null) return;
+				if (!(currentKnowledgeRepository instanceof LocalKnowledgeRepository)) return;
+				
+				LocalKnowledgeRepository kr = (LocalKnowledgeRepository) currentKnowledgeRepository;
+				
+				InputDialog dialog = new InputDialog(e.widget.getDisplay().getActiveShell(), "New property", "Enter the new property name", "", null);
+				if (dialog.open() == InputDialog.OK) {
+					String name = dialog.getValue();
+					if (name.trim().length() == 0) return;
+					String id = AsciiUtils.buildId(name);
+					AnnotationType existingType = kr.getType(id);
+					if (existingType != null) {
+						Log.warning(NLS.bind("The ''{0}'' annotation type already exists. Please use another name ({1}).", id, name));
+						annotationTypesCombo.setSelection(new StructuredSelection(existingType));
+						return;
+					}
+					AnnotationType type = kr.addType(name, id, "", AnnotationEffect.TOKEN); //$NON-NLS-1$
+					typesList.add(type);
+					
+					if (annotationTypesCombo != null) annotationTypesCombo.refresh();
+					if (typesList.size() == 1) {
+						if (annotationTypesCombo != null) annotationTypesCombo.getCombo().select(typesList.size() - 1);
+						
+						annotations.setViewAnnotation(type);
+						annotations.setAnnotationOverlap(true);
+						try {
+							editor.refresh(false);
+						}
+						catch (Exception e1) {
+							// TODO Auto-generated catch block
+							e1.printStackTrace();
+						}
+						annotationArea.layout(true);
+						
+					}
+					else {
+						if (typesList.size() > 1) {
+							if (annotationTypesCombo != null) {
+								annotationTypesCombo.setSelection(new StructuredSelection(typesList.get(typesList.size() - 1)));
+							}
+						}
+					}
+					annotations.setViewAnnotation(type);
+					annotationTypesCombo.setSelection(new StructuredSelection(typesList.get(typesList.size() - 1)));
+					annotationArea.layout(true);
+					KRView.refresh();
+					updateAnnotationWidgetStates();
+				}
+				else {
+					System.out.println("Creation aborted."); //$NON-NLS-1$
+				}
+			}
+			
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		});
+		
+		equalLabel = new Label(annotationArea, SWT.NONE);
+		equalLabel.setText("="); //$NON-NLS-1$
+		equalLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
+		
+		annotationValuesText = new Text(annotationArea, SWT.BORDER);
+		annotationValuesText.setToolTipText(KRAnnotationUIMessages.enterAValueForAnId);
+		GridData gdata2 = new GridData(SWT.FILL, SWT.CENTER, false, false);
+		gdata2.widthHint = 200;
+		annotationValuesText.setLayoutData(gdata2);
+		annotationValuesText.addKeyListener(new KeyListener() {
+			
+			@Override
+			public void keyReleased(KeyEvent e) {
+				if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
+					affectAnnotationToSelection(editor.getEditionPanel(0).getWordSelection());
+				}
+			}
+			
+			@Override
+			public void keyPressed(KeyEvent e) {}
+		});
+		
+		addTypedValueLink = new Button(annotationArea, SWT.PUSH);
+		addTypedValueLink.setText("..."); //$NON-NLS-1$
+		addTypedValueLink.setToolTipText(KRAnnotationUIMessages.selectAValueAmongTheList);
+		addTypedValueLink.setEnabled(true);
+		addTypedValueLink.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
+		addTypedValueLink.addSelectionListener(new SelectionListener() {
+			
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (currentKnowledgeRepository == null) return;
+				if (!(currentKnowledgeRepository instanceof LocalKnowledgeRepository)) return;
+				
+				AnnotationType type = getSelectedAnnotationType();
+				if (type == null) return;
+				
+				LocalKnowledgeRepository kr = (LocalKnowledgeRepository) currentKnowledgeRepository;
+				
+				ListDialog dialog = new ListDialog(e.widget.getDisplay().getActiveShell());
+				String title = currentKnowledgeRepository.getString(editor.getCorpus().getLang(), "ConcordancesEditor_100"); //$NON-NLS-1$
+				if (title == null) title = KRAnnotationUIMessages.availableValuesForP0;
+				dialog.setTitle(ConcordanceUIMessages.bind(title, type.getName()));// +"valeurs de "+type.getName());
+				dialog.setContentProvider(new ArrayContentProvider());
+				dialog.setLabelProvider(new SimpleLabelProvider() {
+					
+					@Override
+					public String getColumnText(Object element, int columnIndex) {
+						if (element instanceof TypedValue)
+							return ((TypedValue) element).getId();
+						return element.toString();
+					}
+				});
+				List<TypedValue> values;
+				try {
+					values = kr.getValues(type);
+				}
+				catch (Exception e1) {
+					e1.printStackTrace();
+					return;
+				}
+				dialog.setInput(values);
+				if (dialog.open() == InputDialog.OK) {
+					TypedValue value = (TypedValue) dialog.getResult()[0];
+					String name = value.getId();
+					if (name.trim().length() == 0) return;
+					
+					annotationValuesText.setText(name);
+				}
+				else {
+					
+				}
+			}
+			
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		});
+		
+		new Label(annotationArea, SWT.NONE).setText(" ");
+		
+		affectAnnotationButton = new Button(annotationArea, SWT.PUSH);
+		affectAnnotationButton.setText(KRAnnotationUIMessages.oK);
+		affectAnnotationButton.setToolTipText(KRAnnotationUIMessages.proceedToAnnotation);
+		affectAnnotationButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
+		affectAnnotationButton.addSelectionListener(new SelectionListener() {
+			
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				affectAnnotationToSelection(editor.getEditionPanel(0).getWordSelection());
+			}
+			
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		});
+		
+		deleteAnnotationButton = new Button(annotationArea, SWT.PUSH);
+		deleteAnnotationButton.setText(KRAnnotationUIMessages.delete);
+		deleteAnnotationButton.setToolTipText(KRAnnotationUIMessages.delete);
+		deleteAnnotationButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
+		deleteAnnotationButton.addSelectionListener(new SelectionListener() {
+			
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				deleteAnnotationValues(editor.getEditionPanel(0).getWordSelection());
+			}
+			
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		});
+		
+		Button closeButton = new Button(annotationArea, SWT.PUSH);
+		closeButton.setToolTipText(KRAnnotationUIMessages.closeTheToolbarWithoutSaving);
+		closeButton.setImage(IImageKeys.getImage(IImageKeys.ACTION_DELETE));
+		
+		closeButton.addSelectionListener(new SelectionListener() {
+			
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				extension.closeArea(WordAnnotationToolbar.this, true);
+			}
+			
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		});
+		
+		updateAnnotationWidgetStates();
+		editor.layout(true);
+		ext.getSaveButton().setEnabled(true);
+		return true;
+	}
+	
+	protected void onAnnotationTypeSelected(SelectionChangedEvent event) {
+		
+		IStructuredSelection sel = (IStructuredSelection) annotationTypesCombo.getSelection();
+		AnnotationType type = (AnnotationType) sel.getFirstElement();
+		if (type == null) return;
+		
+		if (type.getSize() != AnnotationType.ValuesSize.LARGE) {
+			try {
+				KnowledgeRepository kr = KnowledgeRepositoryManager.getKnowledgeRepository(type.getKnowledgeRepository());
+				typeValuesList = kr.getValues(type);
+			}
+			catch (Exception e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		
+		annotations.setViewAnnotation(type);
+		annotations.setAnnotationOverlap(true);
+		try {
+			editor.refresh(false);
+		}
+		catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		updateAnnotationWidgetStates();
+	}
+	
+	protected void createNewType(TypedEvent e, String typeName) {
+		
+		if (currentKnowledgeRepository == null) return;
+		if (!(currentKnowledgeRepository instanceof LocalKnowledgeRepository)) return;
+		
+		LocalKnowledgeRepository kr = (LocalKnowledgeRepository) currentKnowledgeRepository;
+		if (typeName == null) typeName = ""; //$NON-NLS-1$
+		InputDialog dialog = new InputDialog(e.widget.getDisplay().getActiveShell(), KRAnnotationUIMessages.nouvelleProprit, KRAnnotationUIMessages.nomDeLaPropritPatternEqualsazaz09Plus, typeName,
+				null);
+		if (dialog.open() == InputDialog.OK) {
+			String name = dialog.getValue();
+			if (name.trim().length() == 0) return;
+			String baseid = AsciiUtils.buildId(name);
+			String id = AsciiUtils.buildId(name);
+			int c = 1;
+			while (kr.getType(id) != null) {
+				id = baseid + "_" + (c++); //$NON-NLS-1$
+			}
+			AnnotationType type = kr.addType(name, id, "", AnnotationEffect.TOKEN); //$NON-NLS-1$
+			typesList.add(type);
+			annotationTypesCombo.refresh();
+			StructuredSelection selection = new StructuredSelection(type);
+			annotationTypesCombo.setSelection(selection, true);
+			
+			// if (annotationTypesCombo != null) annotationTypesCombo.refresh();
+			// if (typesList.size() == 1) {
+			// if (annotationTypesCombo != null) annotationTypesCombo.getCombo().select(0);
+			// annotations.setViewAnnotation(type);
+			// annotations.setAnnotationOverlap(true);
+			// try {
+			// editor.refresh(false);
+			// } catch (Exception e1) {
+			// // TODO Auto-generated catch block
+			// e1.printStackTrace();
+			// }
+			// annotationArea.layout(true);
+			// } else {
+			// if (typesList.size() > 1) {
+			// if (annotationTypesCombo != null) {
+			// annotationTypesCombo.getCombo().select(typesList.size()-1);
+			// }
+			// }
+			// }
+			// KRView.refresh();
+			// updateAnnotationWidgetStates();
+			
+			// onAnnotationTypeSelected(null);
+		}
+		else {
+			System.out.println("Creation aborted."); //$NON-NLS-1$
+		}
+	}
+	
+	@Override
+	public boolean save() {
+		try {
+			AnnotationManager am = KRAnnotationEngine.getAnnotationManager(WordAnnotationToolbar.this.corpus);
+			if (am != null && am.hasChanges()) {
+				// && MessageDialog.openConfirm(e.display.getActiveShell(), "Confirm annotation save", "Saving annotation will close this editor. Are you sure you want to save annotations right now
+				// ?")
+				JobHandler saveJob = SaveAnnotations.save(WordAnnotationToolbar.this.corpus.getMainCorpus());
+				if (saveJob == null || saveJob.getResult() == Status.CANCEL_STATUS) {
+					// update editor corpus
+					System.out.println("Fail to save annotations of the corpus."); //$NON-NLS-1$
+					return false;
+				}
+				else {
+					return true; // something was saved
+				}
+			}
+			else {
+				return false;
+			}
+		}
+		catch (Exception ex) {
+			ex.printStackTrace();
+			return false;
+		}
+	}
+	
+	@Override
+	public boolean hasChanges() {
+		AnnotationManager am;
+		try {
+			am = KRAnnotationEngine.getAnnotationManager(corpus);
+			if (am != null && am.hasChanges()) {
+				return am.hasChanges();
+			}
+			else {
+				return false;
+			}
+		}
+		catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+			return false;
+		}
+	}
+	
+	@Override
+	public boolean notifyStartOfCompute() throws Exception {
+		if (annotationArea == null) return false;
+		if (annotationArea.isDisposed()) return false;
+		
+		AnnotationType type = getSelectedAnnotationType();
+		if (type != null) {
+			annotations.setViewAnnotation(type);
+			annotations.setAnnotationOverlap(true);
+		}
+		
+		return true;
+	}
+	
+	@Override
+	public boolean notifyEndOfCompute() throws Exception {
+		return true;
+	}
+	
+	@Override
+	public boolean isAnnotationEnable() {
+		return annotationArea != null;
+	}
+	
+	@Override
+	public void notifyStartOfRefresh() throws Exception {
+		if (annotationArea == null) return;
+		if (annotationArea.isDisposed()) return;
+		
+		Page currentPage = editor.getEditionPanel(0).getCurrentPage();
+		if (currentPage == null) return;
+		
+		String startID = currentPage.getWordId();
+		Page nextPage = currentPage.getEdition().getNextPage(currentPage);
+		String endID = nextPage.getWordId();
+		
+		annotations.computeStrings(startID, endID);
+		
+		updateAnnotationWidgetStates();
+		
+	}
+	
+	@Override
+	protected void _close() {
+		if (!annotationArea.isDisposed()) annotationArea.dispose();
+		extension.layout();
+	}
+	
+	@Override
+	public void notifyEndOfRefresh() throws Exception {
+		// TODO Auto-generated method stub
+	}
+	
+	@Override
+	public void notifyStartOfCreatePartControl() throws Exception {
+		// TODO Auto-generated method stub
+	}
+	
+	@Override
+	public Class<? extends TXMResult> getAnnotatedTXMResultClass() {
+		return org.txm.objects.Text.class;
+	}
+	
+	@Override
+	public boolean isDirty() {
+		if (annotManager != null) {
+			return annotManager.isDirty();
+		}
+		return false;
+	}
+	
+	@Override
+	public boolean discardChanges() {
+		return false;
+	}
+	
+	@Override
+	public boolean needToUpdateIndexes() {
+		return true;
+	}
+}

Property changes on: tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/edition/WordAnnotationToolbar.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

