Index: tmp/org.txm.analec.rcp/.project
===================================================================
--- tmp/org.txm.analec.rcp/.project	(revision 0)
+++ tmp/org.txm.analec.rcp/.project	(revision 481)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.txm.analec.rcp</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.groovy.core.groovyNature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Property changes on: tmp/org.txm.analec.rcp/.project
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/DropDownButton.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/DropDownButton.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/DropDownButton.java	(revision 481)
@@ -0,0 +1,74 @@
+package org.txm.analec.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+public class DropDownButton extends Button {
+
+	public DropDownButton(ToolBar parent, int style) {
+		super(parent, style);
+		// TODO Auto-generated constructor stub
+	}
+	
+	public static void main (String [] args) {
+		final Display display = new Display ();
+		final Shell shell = new Shell (display);
+		final ToolBar toolBar = new ToolBar (shell, SWT.NONE);
+		Rectangle clientArea = shell.getClientArea ();
+		toolBar.setLocation(clientArea.x, clientArea.y);
+		final Menu menu = new Menu (shell, SWT.POP_UP);
+		for (int i=0 ; i < 8 ; i++) {
+			MenuItem item = new MenuItem (menu, SWT.PUSH);
+			item.setText ("Item " + i);
+			item.addSelectionListener(new SelectionListener() {
+				
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					System.out.println("item "+this);
+				}
+				
+				@Override
+				public void widgetDefaultSelected(SelectionEvent e) { }
+			});
+		}
+		
+		ToolItem b1 = new ToolItem(toolBar, SWT.PUSH);
+		b1.setText("push me");
+		
+		final ToolItem item = new ToolItem(toolBar, SWT.DROP_DOWN);
+		item.setText("default item");
+		item.addListener(SWT.Selection, new Listener() {
+			@Override
+			public void handleEvent(Event event) {
+				if (event.detail == SWT.ARROW) {
+					Rectangle rect = item.getBounds();
+					Point pt = new Point(rect.x, rect.y + rect.height);
+					pt = toolBar.toDisplay (pt);
+					menu.setLocation(pt.x, pt.y);
+					menu.setVisible(true);
+				}
+			}
+		});
+		
+		toolBar.pack();
+		shell.pack();
+		shell.open();
+		while (!shell.isDisposed()) {
+			if (!display.readAndDispatch()) display.sleep();
+		}
+		menu.dispose();
+		display.dispose();
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/DropDownButton.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/NavigationField.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/NavigationField.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/NavigationField.java	(revision 481)
@@ -0,0 +1,249 @@
+package org.txm.analec.widgets;
+
+import org.eclipse.jface.bindings.keys.KeyStroke;
+import org.eclipse.jface.fieldassist.TXMAutoCompleteField;
+import org.eclipse.jface.fieldassist.TextContentAdapter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseWheelListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowData;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.txm.rcp.IImageKeys;
+
+/**
+ * Mimic the List and Combo widget to manage big data volume
+ * 
+ * Don't forget to add a SelectionListener to the parent to manage the selection change
+ * 
+ * @author mdecorde
+ *
+ */
+public class NavigationField extends Composite {
+
+	protected String[] identifiants;
+
+	protected org.eclipse.swt.widgets.Text identifiantCombo;
+	protected Button identifiantComboButtonUp;
+	protected Button identifiantComboButtonDown;
+	protected TXMAutoCompleteField identifiantComboAutoCompleteField;
+
+	public NavigationField(Composite parent, int style) {
+		super(parent, style);
+
+		GridLayout layout = new GridLayout(2, false);
+		layout.horizontalSpacing = layout.marginBottom = layout.marginHeight = layout.marginLeft = layout.marginRight = layout.marginTop = layout.marginWidth = 0;
+		this.setLayout(layout);
+		
+		identifiantCombo = new org.eclipse.swt.widgets.Text(this, SWT.BORDER);
+		KeyStroke keys = KeyStroke.getInstance(SWT.CONTROL, SWT.SPACE);
+		identifiantComboAutoCompleteField = new TXMAutoCompleteField(identifiantCombo, new TextContentAdapter(), new String[0], keys);
+		Cursor cursor = new Cursor(identifiantCombo.getDisplay(), SWT.CURSOR_SIZENS);
+		identifiantCombo.setCursor(cursor);
+		identifiantCombo.setText("<identifiant>");
+
+		GridData gdata = new GridData(GridData.FILL, GridData.FILL, true, false);
+		gdata.minimumWidth = 100;
+		identifiantCombo.setLayoutData(gdata);
+		identifiantCombo.addKeyListener(new KeyListener() {
+			@Override
+			public void keyReleased(KeyEvent e) {
+				//System.out.println("e:"+e.keyCode);
+				if (identifiantComboAutoCompleteField.isOpen()) return; // ignore keys when content assist is opened
+
+				if (e.keyCode == SWT.ARROW_UP) {
+					selectPrevious();
+				} else if (e.keyCode == SWT.ARROW_DOWN) {
+					selectNext();
+				} else if (e.keyCode == SWT.PAGE_UP) {
+					select10Previous();
+				} else if (e.keyCode == SWT.PAGE_DOWN) {
+					select10Next();
+				}  else if (e.keyCode == SWT.END) {
+					selectLast();
+				} else if (e.keyCode == SWT.HOME) {
+					selectFirst();
+				} else if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
+					String id = identifiantCombo.getText().trim();
+					String prefix = type+"-";
+					if (id.startsWith(prefix)) {
+						id = id.substring(prefix.length());
+						//System.out.println("ID: "+id);
+						try {
+							Integer i = Integer.parseInt(id);
+							if (identifiants.length < i) {
+								System.out.println("Wrong unit ID: "+identifiantCombo.getText());
+								return;
+							}
+							setSelectionIndex(i);
+							notifySelectionChanged(null);
+						} catch(Exception ex) {
+							System.out.println("Wrong unit ID: "+identifiantCombo.getText());
+						}
+					}
+				}
+			}
+
+			@Override
+			public void keyPressed(KeyEvent e) { }
+		});
+		identifiantCombo.addMouseWheelListener(new MouseWheelListener() {
+			@Override
+			public void mouseScrolled(MouseEvent e) {
+				if (identifiantComboAutoCompleteField.isOpen()) return;
+
+				if (e.count > 0) {
+					selectPrevious();
+				} else {
+					selectNext();
+				}
+			}
+		});
+
+		Composite identifiantComboButtons = new Composite(this, SWT.NONE);
+		gdata = new GridData(GridData.FILL, GridData.FILL, false, false);
+		identifiantComboButtons.setLayoutData(gdata);
+		//identifiantComboButtons.setLayout(new GridLayout(1, true));
+		RowLayout fillLayout = new RowLayout(SWT.HORIZONTAL);
+		fillLayout.spacing = 0;
+		fillLayout.marginHeight = 0;
+		fillLayout.marginWidth = 0;
+		identifiantComboButtons.setLayout(fillLayout);
+		RowData rdata = new RowData();
+		//rdata.width = 20;
+		identifiantComboButtonUp = new Button(identifiantComboButtons, SWT.PUSH);
+		identifiantComboButtonUp.setImage(IImageKeys.getImage(IImageKeys.CTRLREVERSE));
+		identifiantComboButtonUp.setLayoutData(rdata);
+		identifiantComboButtonUp.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				selectPrevious();
+			}
+
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) { }
+		});
+		identifiantComboButtonDown = new Button(identifiantComboButtons, SWT.PUSH);
+		identifiantComboButtonDown.setImage(IImageKeys.getImage(IImageKeys.CTRLPLAY));
+		identifiantComboButtonDown.setLayoutData(rdata);
+		identifiantComboButtonDown.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				selectNext();
+			}
+
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) { }
+		});
+
+	}
+
+	protected void notifySelectionChanged(Object object) {
+		Event event = new Event();
+		event.data = identifiantComboIndex;
+		this.notifyListeners(SWT.Selection, event);
+	}
+
+	// This is a set of identifiantCombo control methods to replace the ComboViewer Jface widget
+	protected int identifiantComboIndex = 0;
+	protected int identifiantComboSize = 0;
+
+	private String type;
+	public void setSelectionIndex(int i) {
+		if (identifiantComboSize <= i) return;
+		if (i < 0) return;
+		identifiantComboIndex = i;
+		if (i == 0) {
+			this.identifiantCombo.setText("<identifiant>");
+		} else {
+			this.identifiantCombo.setText(type+"-"+(i));
+		}
+		Event e = new Event();
+		e.data = i;
+		this.notifyListeners(SWT.Selection, e);
+	}
+	public void setIdentifiants(String[] values, String type) {
+		this.identifiants = values;
+		this.type= type;
+		identifiantComboSize = values.length + 1; // + 1 because of <identifiants>
+		identifiantComboAutoCompleteField.setProposals(values);
+	}
+	public int getSelectionIndex() { return identifiantComboIndex;}
+	public int getIdentifiantSize() { return identifiantComboSize;}
+	public String getText() {
+		return identifiantCombo.getText();
+	}
+	public void setEnabled(boolean b) {
+		this.identifiantCombo.setEnabled(b);
+		this.identifiantComboButtonDown.setEnabled(b);
+		this.identifiantComboButtonUp.setEnabled(b);
+	}
+
+
+
+	public int selectNext() {
+		if (identifiantComboSize == 0) return 0;
+		
+		int i = getSelectionIndex();
+		i = (i+1)%identifiantComboSize;
+		setSelectionIndex(i);
+		return i;
+	}
+
+	public int selectPrevious() {
+		if (identifiantComboSize == 0) return 0;
+		
+		int i = getSelectionIndex();
+		i = (i-1)%identifiantComboSize;
+		if (i < 0) i = identifiantComboSize + i;
+		setSelectionIndex(i);
+		
+		return i;
+	}
+
+	public int selectFirst() {
+		if (identifiantComboSize == 0) return 0;
+		
+		int i = 1%identifiantComboSize;
+		setSelectionIndex(i);
+		return i;
+	}
+
+	public int select10Previous() {
+		if (identifiantComboSize == 0) return 0;
+		
+		int i = getSelectionIndex();
+		i = (i-10)%identifiantComboSize;
+		if (i < 0) i = identifiantComboSize + i;
+		setSelectionIndex(i);
+		return i;
+	}
+
+	public int select10Next() {
+		if (identifiantComboSize == 0) return 0;
+		
+		int i = getSelectionIndex();
+		i = (i+10)%identifiantComboSize;
+		setSelectionIndex(i);
+		return i;
+	}
+
+	public int selectLast() {
+		if (identifiantComboSize == 0) return 0;
+		
+		int i = (identifiantComboSize - 1);
+		if (i < 0) i = identifiantComboSize + i;
+		setSelectionIndex(i);
+		return i;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/NavigationField.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/TextItem.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/TextItem.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/TextItem.java	(revision 481)
@@ -0,0 +1,30 @@
+package org.txm.analec.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolBar;
+
+public class TextItem extends Item {
+
+	private ToolBar parent;
+	private Text field;
+
+	public TextItem (ToolBar parent, int style) {
+		super(parent, style);
+		this.parent = parent;
+	}
+	
+	public String getText() {
+		return field.getText();
+	}
+	
+	public void setText(String s) {
+		 field.setText(s);
+	}
+	
+	public void addSelectionListener(SelectionListener listener) {
+		 field.addSelectionListener(listener);
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/widgets/TextItem.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/AnalecCorpora.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/AnalecCorpora.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/AnalecCorpora.java	(revision 481)
@@ -0,0 +1,134 @@
+package org.txm.analec;
+
+import java.io.File;
+import java.util.HashMap;
+
+import org.txm.Toolbox;
+import org.txm.core.preferences.TBXPreferences;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersJava;
+import visuAnalec.vue.Vue;
+
+/**
+ * Manages Analec corpus : the corpus are associated with TXM MainCorpus names
+ * 
+ * @author mdecorde
+ *
+ */
+public class AnalecCorpora {
+	private static final HashMap<String, Corpus> corpora = new HashMap<String, Corpus>();
+	private static final HashMap<String, Vue> vues = new HashMap<String, Vue>();
+
+	/**
+	 * Create the ec file if needed, store a reference to the corpus if not already done.
+	 * 
+	 * @param name
+	 * @return the Corpus loaded and stored
+	 */
+	public static Corpus getCorpus(String name) {
+		File fichierCorpus = new File(Toolbox.getParam(TBXPreferences.USER_TXM_HOME), "corpora/"+name+"/analec/"+name+".ec");
+		//File fichierVue = new File(Toolbox.getParam(Toolbox.USER_TXM_HOME), "corpora/"+name+"/analec/"+name+".ecv");
+		Corpus corpus = null;
+		if (AnalecCorpora.corpora.containsKey(name)) {
+			corpus = AnalecCorpora.corpora.get(name);
+		} else {
+			corpus = new Corpus();
+			
+			if (fichierCorpus.exists()) {
+				if (!FichiersJava.ouvrirCorpus(corpus, fichierCorpus, false)) {
+					System.out.println("Fail to open corpus file: "+fichierCorpus);
+					return null;
+				}
+			} else {
+				fichierCorpus.getParentFile().mkdirs();
+				
+				if (!FichiersJava.enregistrerCorpus(corpus, fichierCorpus)) {
+					System.out.println("Fail to create corpus file: "+fichierCorpus);
+					return null;
+				}
+			}
+
+			AnalecCorpora.corpora.put(name, corpus);
+			
+			Vue vue = getVue(name);
+			
+//TODO: does not work :( 
+//			if (fichierVue.exists()) {
+//				if (!FichiersJava.ouvrirVue(vue, fichierVue)) {
+//					System.out.println("Warning: Fail to open corpus Vue file: "+fichierVue);
+//					//return null;
+//				}
+//			} else {
+//				if (!FichiersJava.enregistrerVue(vue, fichierVue)) {
+//					System.out.println("Warning: Fail to create corpus Vue file: "+fichierVue);
+//					//return null;
+//				}
+//			}
+		}
+		return corpus;
+	}
+	
+	public static boolean isAnnotationStructureReady(org.txm.searchengine.cqp.corpus.Corpus corpus) {
+		return isAnnotationStructureReady(corpus.getName());
+	}
+	
+	public static boolean isAnnotationStructureReady(String name) {
+		if (AnalecCorpora.corpora.containsKey(name)) {
+			return !AnalecCorpora.corpora.get(name).getStructure().isVide();
+		} else {
+			File fichierCorpus = new File(Toolbox.getParam(TBXPreferences.USER_TXM_HOME), "corpora/"+name+"/analec/"+name+".ec");
+			if (fichierCorpus.exists()) {
+				return !getCorpus(name).getStructure().isVide();
+			} else {
+				return false;
+			}
+		}
+	}
+
+	/**
+	 * need the corpus to be laoded
+	 * @param name
+	 * @return the corpus Vue
+	 */
+	public static Vue getVue(String name) {
+		if (!vues.containsKey(name)) {
+			if (!corpora.containsKey(name)) {
+				getCorpus(name);
+			}
+			Corpus corpus = getCorpus(name);
+			Vue vue = new Vue(corpus);
+			vue.retablirVueParDefaut();
+			vues.put(name, vue);
+		}
+		return vues.get(name);
+	}
+
+	public static boolean saveCorpus(String name) {
+		Corpus corpus = getCorpus(name);
+
+		File dir = new File(Toolbox.getParam(TBXPreferences.USER_TXM_HOME), "corpora/"+name+"/analec/");
+		dir.mkdir();
+		File fichierCorpus = new File(dir,name+".ec");
+		return FichiersJava.enregistrerCorpus(corpus, fichierCorpus);
+	}
+
+	public static Vue getVue(Corpus corpus) {
+		for (String name : corpora.keySet()) {
+			if (corpora.get(name) == corpus) return vues.get(name);
+		}
+		return null;
+	}
+
+	public static boolean saveCorpus(Corpus corpus) {
+		for (String name : corpora.keySet()) {
+			if (corpora.get(name) == corpus) return saveCorpus(name);
+		}
+		return false;
+	}
+
+	public static void removeCorpus(String name) {
+		if (!vues.containsKey(name)) {vues.remove(name);}
+		if (!corpora.containsKey(name)) {corpora.remove(name);}
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/AnalecCorpora.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/testers/IsCorpusAnnotated.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/testers/IsCorpusAnnotated.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/testers/IsCorpusAnnotated.java	(revision 481)
@@ -0,0 +1,39 @@
+package org.txm.analec.testers;
+
+import java.util.List;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.txm.analec.AnalecCorpora;
+import org.txm.searchengine.cqp.corpus.Corpus;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+public class IsCorpusAnnotated extends PropertyTester {
+
+	public static final String PROPERTY_NAMESPACE = "org.txm.analec.testers"; //$NON-NLS-1$
+	public static final String PROPERTY_CAN_SAVE = "canAnnotate";
+	
+	@Override
+	public boolean test(Object receiver, String property, Object[] args,
+			Object expectedValue) {
+
+		if (receiver instanceof List) {
+			@SuppressWarnings("unchecked")
+			List<Object> list = (List<Object>)receiver;
+			if (list.size() == 0) return false;
+			receiver = list.get(0);
+		}
+		
+		//System.out.println("test org.txm.analec.testers.canAnnotate with "+receiver.getClass());
+		if (receiver instanceof Corpus) {
+			return testCorpus((Corpus)receiver);
+		}
+		return false;
+	}
+
+	protected boolean testCorpus(Corpus c) {
+		MainCorpus mc = c.getMainCorpus();
+		boolean ret = AnalecCorpora.isAnnotationStructureReady(mc);
+		//System.out.println(" Corpus:"+c+" org.txm.analec.testers.canAnnotate: "+ret);
+		return ret;
+	}
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/testers/IsCorpusAnnotated.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/view/ElementPropertiesView.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/view/ElementPropertiesView.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/view/ElementPropertiesView.java	(revision 481)
@@ -0,0 +1,360 @@
+package org.txm.analec.view;
+
+import java.util.LinkedHashMap;
+
+import org.eclipse.jface.bindings.keys.KeyStroke;
+import org.eclipse.jface.fieldassist.ComboContentAdapter;
+import org.eclipse.jface.fieldassist.TXMAutoCompleteField;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+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.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowData;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+import org.txm.analec.AnalecCorpora;
+import org.txm.analec.toolbar.AnnotationToolbar;
+import org.txm.rcp.IImageKeys;
+import org.txm.utils.logger.Log;
+
+import visuAnalec.Message;
+import visuAnalec.Message.TypeMessage;
+import visuAnalec.donnees.Corpus;
+import visuAnalec.donnees.Corpus.CorpusListener;
+import visuAnalec.elements.Element;
+import visuAnalec.elements.Schema;
+import visuAnalec.elements.Unite;
+import visuAnalec.vue.Vue;
+
+public class ElementPropertiesView extends ViewPart {
+
+	public static final String ID = ElementPropertiesView.class.getName();
+
+	private LinkedHashMap<Combo, String> textWidgets = new LinkedHashMap<Combo, String>();
+	Element element;
+	AnnotationToolbar toolbar;
+
+	private ToolBar buttons;
+	private Composite fields;
+	private ToolItem firstButton;
+	private ToolItem previousButton;
+	private ToolItem nextButton;
+	private ToolItem lastButton;
+	RowData cData = new RowData();
+	private GridData lData;
+	private GridData tData;
+
+	private Corpus analecCorpus;
+	private Vue vue;
+	private CorpusListener corpusListener = new CorpusListener() {
+		@Override
+		public void traiterEvent(final Message e) {
+			Display.getDefault().syncExec(new Runnable() {
+				@Override
+				public void run() {
+					//System.out.println("EVENT: "+e);
+					if (ElementPropertiesView.this.element == null) return;
+					if (fields == null || fields.isDisposed()) return;
+					
+					if (e.getType() == TypeMessage.MODIF_STRUCTURE) {
+						needUpdate = true;
+						loadElement(analecCorpus, element, toolbar);
+					}
+				}
+			});
+			
+		}
+	};
+
+	private boolean needUpdate = false;
+
+//	private KeyListener allControlsKeyListener;
+
+	public static void closeView() {
+		try {
+			IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+			ElementPropertiesView view = (ElementPropertiesView) page.findView(ElementPropertiesView.ID);
+
+			// close Element View if opened
+			if (view != null) {
+				view = (ElementPropertiesView) page.showView(ElementPropertiesView.ID);
+				page.hideView(view);
+			}
+
+			return;
+		} catch (PartInitException e1) {
+			System.out.println("Part initialisation error: "+e1.getLocalizedMessage());
+			Log.printStackTrace(e1);
+		}
+		return;
+	}
+	public static ElementPropertiesView openView() {
+		// open Element View if not opened
+		try {
+			IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+			ElementPropertiesView view = (ElementPropertiesView) page.findView(ElementPropertiesView.ID);
+			if (view == null) {
+				view = (ElementPropertiesView) page.showView(ElementPropertiesView.ID);
+				if (view != null && !view.fields.isDisposed() && view.fields.getParent() != null) 
+					view.fields.getParent().layout(); // sometimes the part layout is broken
+			}
+			if (view == null) {
+				System.out.println("Error ElementPropertiesView view not found: "+ElementPropertiesView.ID);
+			}
+			return view;
+		} catch (PartInitException e1) {
+			System.out.println("Part initialisation error: "+e1.getLocalizedMessage());
+			Log.printStackTrace(e1);
+		}
+		return null;
+	}
+
+	@Override
+	public void createPartControl(Composite parent) {
+				
+		GridLayout layout = new GridLayout();
+		parent.setLayout(layout);
+		
+		//previous and next buttons
+		buttons = new ToolBar(parent, SWT.NONE);
+		GridData buttons_gdata = new GridData(GridData.FILL, GridData.CENTER, true, false);
+		buttons_gdata.horizontalSpan = 2;
+		buttons.setLayoutData(buttons_gdata);
+		firstButton = new ToolItem(buttons, SWT.PUSH);
+		firstButton.setImage(IImageKeys.getImage(IImageKeys.CTRLSTART));
+		firstButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (toolbar != null && !toolbar.isDisposed()) toolbar.selectFirst();
+			}
+			
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) { }
+		});
+		
+		previousButton = new ToolItem(buttons, SWT.PUSH);
+		previousButton.setImage(IImageKeys.getImage(IImageKeys.CTRLREVERSE));
+		previousButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (toolbar != null && !toolbar.isDisposed()) toolbar.selectPrevious();
+			}
+			
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) { }
+		});
+		nextButton = new ToolItem(buttons, SWT.PUSH);
+		nextButton.setImage(IImageKeys.getImage(IImageKeys.CTRLPLAY));
+		nextButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (toolbar != null && !toolbar.isDisposed()) toolbar.selectNext();
+			}
+			
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) { }
+		});
+		lastButton = new ToolItem(buttons, SWT.ARROW | SWT.END);
+		lastButton.setImage(IImageKeys.getImage(IImageKeys.CTRLEND));
+		lastButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (toolbar != null && !toolbar.isDisposed()) toolbar.selectLast();
+			}
+			
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) { }
+		});
+		
+//		allControlsKeyListener = new KeyListener() {
+//			@Override
+//			public void keyReleased(KeyEvent e) {
+//				if (((e.stateMask & SWT.CTRL) == SWT.CTRL)) {
+//					if (e.keyCode == SWT.ARROW_UP) {
+//						if (toolbar != null && !toolbar.isDisposed()) toolbar.selectPrevious();
+//						e.doit = false;
+//						
+//					} else if (e.keyCode == SWT.ARROW_DOWN) {
+//						if (toolbar != null && !toolbar.isDisposed()) toolbar.selectNext();
+//						e.doit = false;
+//					}
+//				}
+//			}
+//
+//			@Override
+//			public void keyPressed(KeyEvent e) { }
+//		};
+		
+		fields = new Composite(parent, SWT.NONE);
+		GridData fields_gdata = new GridData(GridData.FILL, GridData.FILL, true, true);
+		fields.setLayoutData(fields_gdata);
+		fields.setLayout(new RowLayout());
+		this.setPartName("Element");
+		
+		// GridDatas to use when a new field is added
+		cData.width = 250;
+		lData = new GridData(GridData.FILL, GridData.CENTER, false, false);
+		lData.minimumWidth = 75;
+		lData.widthHint = 75;
+		tData = new GridData(GridData.FILL, GridData.FILL, true, false);
+		tData.minimumWidth = 100;
+		tData.widthHint = 100;
+
+		parent.addDisposeListener(new DisposeListener() {
+			@Override
+			public void widgetDisposed(DisposeEvent e) {
+				try {
+					if (element != null) { // save previous unit changes
+						for (Combo t : textWidgets.keySet()) {
+							if (!t.isDisposed()) {
+								saveFieldValue(t);
+							}
+						}
+					}
+				} catch(Exception ex) { ex.printStackTrace();}
+			}
+		});
+	}
+
+	public void loadElement(Corpus analecCorpus, Element newElement, AnnotationToolbar toolbar) {
+
+		if (this.element != null) { // save previous unit changes
+			for (Combo t : textWidgets.keySet()) {
+				if (!t.isDisposed()) {
+					saveFieldValue(t);
+				}
+			}
+		}
+
+		if (this.analecCorpus != null) { // remove corpus listener from previous corpus
+			this.analecCorpus.removeEventListener(corpusListener);
+		}
+
+		this.analecCorpus = analecCorpus;
+		this.analecCorpus.addEventListener(corpusListener);
+		this.vue = AnalecCorpora.getVue(analecCorpus);
+
+		if (this.needUpdate  || this.element == null || (!this.element.getType().equals(newElement.getType()))) { // no need to rebuild the widgets
+			needUpdate = false;
+			clear(); // remove all previous widgets
+
+			String[][] props = vue.getChamps(newElement.getClass(), newElement.getType());
+			if (props.length > 0)
+				for (String p : props[0]) { // the first is the prop names
+
+					Composite c = new Composite(fields, SWT.NONE);
+					c.setLayoutData(cData);
+					c.setLayout(new GridLayout(2, true));
+					Label l = new Label(c, SWT.None);
+					l.setText(p);
+					l.setLayoutData(lData);
+
+					Combo t = new Combo(c, SWT.BORDER);
+					t.setLayoutData(tData);
+					textWidgets.put(t, p);
+					setItems(t, newElement);
+					t.addSelectionListener(new SelectionListener() {
+						@Override
+						public void widgetSelected(SelectionEvent e) {
+							if (!(e.widget instanceof Combo)) return;
+							
+//							System.out.println("w:"+e.widget+" selected.");
+							saveFieldValue((Combo)e.widget);
+						}
+
+						@Override
+						public void widgetDefaultSelected(SelectionEvent e) {}
+					});
+				//	t.addKeyListener(allControlsKeyListener);
+					t.addKeyListener(new KeyListener() {
+						@Override
+						public void keyReleased(KeyEvent e) {
+							if (!(e.widget instanceof Combo)) return;
+							if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
+//								System.out.println("w:"+e.widget+" key pressed2.");
+								
+								saveFieldValue((Combo)e.widget);
+							}
+						}
+
+						@Override
+						public void keyPressed(KeyEvent e) { }
+					});
+				}
+			fields.layout();
+			fields.getParent().layout();
+		}
+
+		Log.info("Refreshing unit properties view with: "+newElement);
+		this.toolbar = toolbar;
+		this.element = newElement;
+		for (Combo t : textWidgets.keySet()) {
+			if (newElement.getProps().get(textWidgets.get(t)) != null) {
+				t.setText(newElement.getProps().get(textWidgets.get(t)));
+			}
+		}
+		
+		if (newElement instanceof Unite) {
+			Unite unit = (Unite)newElement;
+			this.setPartName(unit.getType()+" from "+unit.getDeb()+" to "+unit.getFin());
+		} else if (newElement instanceof Schema) {
+			Schema schema = (Schema)newElement;
+			this.setPartName(schema.getType()+" size "+schema.getUnitesSousjacentes().length);
+		}
+	}
+
+	protected void saveFieldValue(Combo t) {
+		String newVal = t.getText().trim();
+		String v = ElementPropertiesView.this.vue.getValeurChamp(ElementPropertiesView.this.element, textWidgets.get(t));
+		if (!v.equals(newVal) && v != null) {
+			ElementPropertiesView.this.vue.setValeurChamp(ElementPropertiesView.this.element, textWidgets.get(t), newVal);
+			if (toolbar != null && !toolbar.isDisposed()) this.toolbar.getStartButton().fireIsDirty();
+		}
+	}
+	
+	private void setItems(Combo t, Element newElement) {
+		String[] items = vue.getValeursChamp(newElement.getClass(), newElement.getType(), textWidgets.get(t));
+		t.setItems(items);
+		KeyStroke keys = KeyStroke.getInstance(SWT.CONTROL, SWT.SPACE);
+		new TXMAutoCompleteField(t, new ComboContentAdapter(), items, keys);
+	}
+	public Element getCurrentElement() {
+		return element;
+	}
+
+	public Corpus getCurrentAnalecCorpus() {
+		return analecCorpus;
+	}
+
+	@Override
+	public void setFocus() {
+		for (Combo w : textWidgets.keySet()) {
+			w.setFocus();
+			return;
+		}
+	}
+
+	public void clear() {
+		Control[] children = fields.getChildren();
+		for (int i = 0 ; i < children.length ; i++) { 
+			children[i].dispose();
+		}
+		textWidgets.clear();
+		fields.layout();
+	}
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/view/ElementPropertiesView.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/view/ElementSearchView.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/view/ElementSearchView.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/view/ElementSearchView.java	(revision 481)
@@ -0,0 +1,389 @@
+package org.txm.analec.view;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+
+import org.eclipse.jface.bindings.keys.KeyStroke;
+import org.eclipse.jface.fieldassist.ComboContentAdapter;
+import org.eclipse.jface.fieldassist.TXMAutoCompleteField;
+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.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowData;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.CoolBar;
+import org.eclipse.swt.widgets.CoolItem;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Spinner;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+import org.txm.analec.AnalecCorpora;
+import org.txm.analec.toolbar.AnnotationToolbar;
+import org.txm.analec.widgets.TextItem;
+import org.txm.rcp.IImageKeys;
+import org.txm.utils.logger.Log;
+
+import visuAnalec.Message;
+import visuAnalec.Message.TypeMessage;
+import visuAnalec.donnees.Corpus;
+import visuAnalec.donnees.Corpus.CorpusListener;
+import visuAnalec.elements.Element;
+import visuAnalec.vue.Vue;
+
+public class ElementSearchView extends ViewPart {
+
+	public static final String ID = ElementSearchView.class.getName();
+
+	private LinkedHashMap<Combo, String> textWidgets = new LinkedHashMap<Combo, String>();
+	Element currentElement = null;
+	int currentIndex = -1;
+	ArrayList<Element> matchingElements = new ArrayList<Element>();
+	AnnotationToolbar toolbar;
+
+	private Composite buttons;
+	private Composite fields;
+	private Spinner text;
+	private Label label;
+	private Button resetButton;
+	private Button searchButton;
+	RowData cData = new RowData();
+	private GridData lData;
+	private GridData tData;
+
+	private Corpus analecCorpus;
+	private Class clazzSearched;
+	private String typeSearched;
+
+	private Vue vue;
+	private CorpusListener corpusListener = new CorpusListener() {
+		@Override
+		public void traiterEvent(final Message e) {
+			Display.getDefault().syncExec(new Runnable() {
+				@Override
+				public void run() {
+					//System.out.println("EVENT: "+e);
+					if (fields == null || fields.isDisposed()) return;
+
+					if (e.getType() == TypeMessage.MODIF_STRUCTURE) {
+						needUpdate = true;
+						loadType(analecCorpus, clazzSearched, typeSearched, toolbar);
+					}
+				}
+			});
+		}
+	};
+
+	private boolean needUpdate = false;
+
+	private SelectionListener selectionChangedListener;
+
+	public static void closeView() {
+		try {
+			IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+			ElementSearchView view = (ElementSearchView) page.findView(ElementSearchView.ID);
+
+			// close Element View if opened
+			if (view != null) {
+				view = (ElementSearchView) page.showView(ElementSearchView.ID);
+				page.hideView(view);
+			}
+
+			return;
+		} catch (PartInitException e1) {
+			System.out.println("Part initialisation error: "+e1.getLocalizedMessage());
+			Log.printStackTrace(e1);
+		}
+		return;
+	}
+	public static ElementSearchView openView() {
+		// open Element View if not opened
+		try {
+			IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+			ElementSearchView view = (ElementSearchView) page.findView(ElementSearchView.ID);
+			if (view == null) {
+				view = (ElementSearchView) page.showView(ElementSearchView.ID);
+				if (view != null && !view.fields.isDisposed() && view.fields.getParent() != null) 
+					view.fields.getParent().layout(); // sometimes the part layout is broken
+			}
+			if (view == null) {
+				System.out.println("Error ElementPropertiesView view not found: "+ElementSearchView.ID);
+			}
+			return view;
+		} catch (PartInitException e1) {
+			System.out.println("Part initialisation error: "+e1.getLocalizedMessage());
+			Log.printStackTrace(e1);
+		}
+		return null;
+	}
+
+	@Override
+	public void createPartControl(Composite parent) {
+
+		GridLayout layout = new GridLayout();
+		parent.setLayout(layout);
+
+		//previous and next buttons
+		buttons = new Composite(parent, SWT.NONE);
+		buttons.setLayout(new GridLayout(8, false));
+		GridData buttons_gdata = new GridData(GridData.FILL, GridData.CENTER, true, false);
+		buttons_gdata.horizontalSpan = 2;
+		buttons.setLayoutData(buttons_gdata);
+
+		text = new Spinner(buttons, SWT.BORDER);
+		text.setMinimum(1);
+		text.setIncrement(1);
+		text.setSelection(1);
+		selectionChangedListener = new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (toolbar == null || toolbar.isDisposed()) return; 
+				//System.out.println("SELECTED!!");
+				currentIndex = text.getSelection()-1;
+				currentElement = matchingElements.get(currentIndex);
+				toolbar.select(currentElement);
+				updateCurrentLabel();
+			}
+
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) { }
+		};
+		text.addSelectionListener(selectionChangedListener);
+		text.addKeyListener(new KeyListener() {
+			@Override
+			public void keyReleased(KeyEvent e) {
+				if (currentElement == null) return;
+
+				if (e.keyCode == SWT.HOME) {
+					text.setSelection(1);
+					selectionChangedListener.widgetSelected(null);
+				} else if (e.keyCode == SWT.END) {
+					text.setSelection(matchingElements.size());
+					selectionChangedListener.widgetSelected(null);
+				}
+			}
+
+			@Override
+			public void keyPressed(KeyEvent e) { }
+		});
+		GridData gdata = new GridData(GridData.FILL, GridData.FILL, false, false);
+		gdata.minimumWidth = 100;
+		gdata.widthHint = 100;
+		text.setLayoutData(gdata);
+		label = new Label(buttons, SWT.NONE);
+		label.setText(" / -");
+
+		resetButton = new Button(buttons, SWT.PUSH);
+		resetButton.setImage(IImageKeys.getImage(IImageKeys.ACTION_DELETE));
+		resetButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				for (Combo c : textWidgets.keySet()) c.setText("");
+			}
+
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) { }
+		});
+
+		searchButton = new Button(buttons, SWT.PUSH);
+		searchButton.setImage(IImageKeys.getImage(IImageKeys.ACTION_SEARCH));
+		searchButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				search();
+			}
+
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) { }
+		});
+
+		this.searchButton.setEnabled(false);
+		this.resetButton.setEnabled(false);
+
+		fields = new Composite(parent, SWT.NONE);
+		GridData fields_gdata = new GridData(GridData.FILL, GridData.FILL, true, true);
+		fields.setLayoutData(fields_gdata);
+		fields.setLayout(new RowLayout());
+		this.setPartName("Element");
+
+		// GridDatas to use when a new field is added
+		cData.width = 250;
+		lData = new GridData(GridData.FILL, GridData.CENTER, false, false);
+		lData.minimumWidth = 75;
+		lData.widthHint = 75;
+		tData = new GridData(GridData.FILL, GridData.FILL, true, false);
+		tData.minimumWidth = 100;
+		tData.widthHint = 100;
+
+		updateCurrentLabel();
+	}
+
+	protected void updateCurrentLabel() {
+		if (currentIndex >= 0) {
+			this.setPartName(""+(currentIndex+1)+" / "+matchingElements.size()+" "+typeSearched);
+			text.setSelection((currentIndex+1));
+			text.setMaximum(matchingElements.size());
+			label.setText(" / "+matchingElements.size());
+			text.setEnabled(true);
+		} else {
+			if (typeSearched != null) this.setPartName(typeSearched);
+			text.setSelection(1);
+			text.setEnabled(false);
+			label.setText(" / -");
+		}
+	}
+
+	public void loadType(Corpus analecCorpus, Class clazz, String type, AnnotationToolbar toolbar) {
+		if (toolbar == null || toolbar.isDisposed()) return;
+		
+		this.searchButton.setEnabled(true);
+		this.resetButton.setEnabled(true);
+
+		if (this.analecCorpus != null) { // remove corpus listener from previous corpus
+			this.analecCorpus.removeEventListener(corpusListener);
+		}
+
+		this.analecCorpus = analecCorpus;
+		this.analecCorpus.addEventListener(corpusListener);
+		this.vue = AnalecCorpora.getVue(analecCorpus);
+
+		if (this.needUpdate  || type.equals(type)) { // no need to rebuild the widgets
+			needUpdate = false;
+			clear(); // remove all previous widgets
+
+			String[][] props = vue.getChamps(clazz, type);
+			if (props.length > 0)
+				for (String p : props[0]) { // the first is the prop names
+
+					Composite c = new Composite(fields, SWT.NONE);
+					c.setLayoutData(cData);
+					c.setLayout(new GridLayout(2, true));
+					Label l = new Label(c, SWT.None);
+					l.setText(p);
+					l.setLayoutData(lData);
+
+					Combo t = new Combo(c, SWT.BORDER);
+					t.setLayoutData(tData);
+					textWidgets.put(t, p);
+					setItems(t, clazz, type, p);
+					t.addKeyListener(new KeyListener() {
+						@Override
+						public void keyReleased(KeyEvent e) {
+							if (!(e.widget instanceof Combo)) return;
+							if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
+								search();
+							}
+						}
+
+						@Override
+						public void keyPressed(KeyEvent e) { }
+					});
+				}
+			fields.layout();
+			fields.getParent().layout();
+		}
+
+		this.toolbar = toolbar;
+		this.clazzSearched = clazz;
+		this.typeSearched = type;
+
+		this.setPartName(typeSearched);
+	}
+
+	/**
+	 * start a new search
+	 */
+	public void search() {
+		if (toolbar == null || toolbar.isDisposed()) return;
+		
+		ArrayList<? extends Element> elements = analecCorpus.getElements(clazzSearched, typeSearched);
+		matchingElements.clear();
+		for (Element e : elements) {
+			boolean insert = true;
+			for (Combo w : textWidgets.keySet()) {
+				if (w.getText().trim().length() > 0 
+						&& !e.getProp(textWidgets.get(w)).matches(w.getText())) {
+					insert = false;
+					continue;
+				}
+			}
+			if (insert) matchingElements.add(e);
+		}
+
+		if (matchingElements.size() > 0) {
+			
+			// sort elements
+			Collections.sort(matchingElements, new Comparator<Element>() {
+				@Override
+				public int compare(Element o1, Element o2) {
+					if (o1 == null) return 1;
+					else if (o2 == null) return -1;
+					else if (o1.getUnite0().getDeb() < o2.getUnite0().getDeb()) {
+						return -1;
+					} else if (o1.getUnite0().getDeb() > o2.getUnite0().getDeb()) {
+						return 1;
+					} else if (o1.getUnite0().getFin() < o2.getUnite0().getFin()) {
+						return -1;
+					} else if (o1.getUnite0().getFin() > o2.getUnite0().getFin()) {
+						return 1;
+					}
+					return 0;
+				}
+			});
+			
+			currentElement = matchingElements.get(0);
+			currentIndex = 0;
+			toolbar.select(currentElement);
+			updateCurrentLabel();
+		} else {
+			currentElement = null;
+			currentIndex = -1;
+			updateCurrentLabel();
+		}
+	}
+
+	private void setItems(Combo t, Class clazz, String type, String prop) {
+		String[] items = vue.getValeursChamp(clazz, type, prop);
+		t.setItems(items);
+		KeyStroke keys = KeyStroke.getInstance(SWT.CONTROL, SWT.SPACE);
+		new TXMAutoCompleteField(t, new ComboContentAdapter(), items, keys);
+	}
+
+	public Corpus getCurrentAnalecCorpus() {
+		return analecCorpus;
+	}
+
+	@Override
+	public void setFocus() {
+		for (Combo w : textWidgets.keySet()) {
+			w.setFocus();
+			return;
+		}
+	}
+
+	public void clear() {
+		Control[] children = fields.getChildren();
+		for (int i = 0 ; i < children.length ; i++) { 
+			children[i].dispose();
+		}
+		textWidgets.clear();
+		fields.layout();
+	}
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/view/ElementSearchView.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/toolbarbutton/StartButton.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/toolbarbutton/StartButton.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/toolbarbutton/StartButton.java	(revision 481)
@@ -0,0 +1,353 @@
+package org.txm.analec.toolbarbutton;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.RowData;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.ToolItem;
+import org.txm.analec.AnalecCorpora;
+import org.txm.analec.toolbar.AnnotationToolbar;
+import org.txm.analec.toolbar.SchemaToolbar;
+import org.txm.analec.toolbar.UnitToolbar;
+import org.txm.analec.view.ElementPropertiesView;
+import org.txm.analec.view.ElementSearchView;
+import org.txm.rcp.synoptic.editor.SynopticEditionEditor;
+import org.txm.rcp.synoptic.editor.ext.ToolbarButton;
+import org.txm.rcp.IImageKeys;
+import org.txm.rcp.swt.dialog.ConfirmDialog;
+import org.txm.rcp.utils.JobHandler;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.Message;
+import visuAnalec.Message.TypeMessage;
+import visuAnalec.donnees.Corpus;
+import visuAnalec.donnees.Corpus.CorpusListener;
+import visuAnalec.vue.Vue;
+
+public class StartButton extends ToolbarButton {
+
+	private Corpus analecCorpus;
+	protected Button b;
+	protected Button drop_b;
+	private MainCorpus corpus;
+	
+	// listen to corpus structure modification -> enable/disable the button
+	// and to new annotations -> set the star modifier to the Corpus view
+	protected CorpusListener corpusListener = new CorpusListener() {
+		@Override
+		public void traiterEvent(final Message e) {
+			if (corpus == null) return;
+
+			//System.out.println("StartButton.corpusListener.traiterEvent: "+e);
+			if (b !=null && !b.isDisposed()) {
+
+				b.getDisplay().syncExec(new Runnable() {
+					@Override
+					public void run() {
+						if (e.getType() == TypeMessage.MODIF_STRUCTURE) {
+							boolean ready = AnalecCorpora.isAnnotationStructureReady(corpus);
+							StartButton.this.setEnabled(ready);
+							//if (!ready && utoolbar != null && !utoolbar.isDisposed()) utoolbar.clearHighlight();
+						}
+
+						if (e.getType() == TypeMessage.MODIF_ELEMENT) {
+							StartButton.this.setEnabled(AnalecCorpora.isAnnotationStructureReady(corpus));
+							if (!corpus.isModified()) {
+								corpus.setIsModified(true); // to show the * in corpora view
+								updateCorporaView(corpus);
+							}
+
+						} else if (e.getType() == TypeMessage.CORPUS_SAVED) {
+							b.setEnabled(false);
+							if (corpus.isModified()) {
+								corpus.setIsModified(false); // to remove the * in corpora view
+								updateCorporaView(corpus);
+							}
+						}
+					}
+				});
+
+				if (utoolbar != null && !utoolbar.isDisposed()) {
+
+				}
+			}
+		}
+	};
+	private String name;
+	protected boolean open = false;
+	protected Composite toolbar;
+	protected AnnotationToolbar utoolbar;
+	private Vue vue;
+
+	public Composite getToolbarButton(Composite toolbar, SynopticEditionEditor syneditor) {
+		this.editor = syneditor;
+		this.toolbar = toolbar;
+		corpus = editor.getCorpus().getMainCorpus();
+		name = corpus.getName();
+		analecCorpus = AnalecCorpora.getCorpus(name);
+		vue = AnalecCorpora.getVue(name);
+		analecCorpus.addEventListener(corpusListener);
+
+		Composite allstuff = new Composite(toolbar, SWT.NONE);
+		RowLayout fillLayout = new RowLayout();
+		allstuff.setLayout(fillLayout);
+		fillLayout.spacing = 0;
+		fillLayout.marginHeight = 0;
+		fillLayout.marginWidth = 0;
+		b = new Button(allstuff, SWT.PUSH);
+		b.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (open) {
+					onEndAnnotation();
+				} else {
+					setButtonToSaveMode();
+					openUnitToolbar();
+				}
+			}
+		});
+		
+		drop_b = new Button(allstuff, SWT.ARROW | SWT.DOWN);
+		
+		RowData rdata = new RowData();
+		rdata.width = 20;
+		drop_b.setLayoutData(rdata);
+		drop_b.addSelectionListener(new SelectionListener() {
+
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				Menu menu = new Menu(e.display.getActiveShell(), SWT.POP_UP);
+
+                MenuItem item1 = new MenuItem(menu, SWT.PUSH);
+                item1.setText("Units");
+                item1.addSelectionListener(new SelectionListener() {
+					
+					@Override
+					public void widgetSelected(SelectionEvent e) {
+						if (open) {
+							openUnitToolbar();
+						} else {
+							setButtonToSaveMode();
+							openUnitToolbar();
+						}
+					}
+					
+					@Override
+					public void widgetDefaultSelected(SelectionEvent e) {}
+				});
+                MenuItem item2 = new MenuItem(menu, SWT.PUSH);
+                item2.setText("Schemas");
+                item2.addSelectionListener(new SelectionListener() {
+					
+					@Override
+					public void widgetSelected(SelectionEvent e) {
+						if (open) {
+							openSchemaToolbar();
+						} else {
+							setButtonToSaveMode();
+							openSchemaToolbar();
+						}
+					}
+					
+					@Override
+					public void widgetDefaultSelected(SelectionEvent e) {}
+				});
+                Point loc = drop_b.getLocation();
+                Rectangle rect = drop_b.getBounds();
+
+                Point mLoc = new Point(loc.x-1, loc.y+rect.height);
+
+                menu.setLocation(e.display.getActiveShell().getDisplay().map(drop_b.getParent(), null, mLoc));
+
+                menu.setVisible(true);
+			}
+
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) { }
+		});
+		
+		endAnnotation(); // initial enable set
+		
+		return allstuff;
+	}
+
+	protected void onEndAnnotation() {
+		if (analecCorpus.isModifie()) {
+			System.out.println("Saving analec annotations...");
+			JobHandler job = new JobHandler("Saving analec annotations...", true) {
+				@Override
+				protected IStatus run(IProgressMonitor monitor) {
+					if (!AnalecCorpora.saveCorpus(name)) {
+						System.out.println("Error: corpus not saved.");
+						return Status.CANCEL_STATUS;
+					} else {
+						editor.fireIsDirty();
+						System.out.println("Done.");
+						this.syncExec(new Runnable() {
+							@Override
+							public void run() {
+								open = false;
+								endAnnotation();
+								ElementPropertiesView.closeView();
+								ElementSearchView.closeView();
+							}
+						});
+						return Status.OK_STATUS;
+					}
+				}
+			};
+			job.schedule();
+		}
+	}
+
+	public boolean onClose() {
+		
+//		if (utoolbar != null && utoolbar.getAnalecCorpus().isModifie()) {
+//			ConfirmDialog dialog = new ConfirmDialog(Display.getCurrent().getActiveShell(), "org.txm.analec.close", "Save changes in "+corpus, "There are annotations to save in the "+corpus+" corpus.\nSave them ?");
+//			int ret = dialog.open();
+//			if (ret == ConfirmDialog.OK) {
+//				if (!AnalecCorpora.saveCorpus(utoolbar.getAnalecCorpus())) {
+//					System.out.println("Error while saving corpus.");
+//					return false;
+//				} else {
+//					corpus.setIsModified(false);
+//					updateCorporaView(corpus);
+//				}
+//			}
+//		}
+		
+		ElementPropertiesView.closeView();
+		ElementSearchView.closeView();
+		analecCorpus.removeEventListener(corpusListener);
+
+		return true;
+	}
+
+	private void openUnitToolbar() {
+		if (utoolbar instanceof UnitToolbar) return;
+		if (utoolbar != null) {
+			closeToolbar();
+		}
+		
+		if (analecCorpus.getStructure().isVide()) {
+			System.out.println("You need to import an annotation structure before starting to annotate. Select the edition main corpus ("+name+"), then call the Analec > Import Structure command");
+			return;
+		}
+
+		b.setToolTipText("Save and close annotation tools: "+analecCorpus.isModifie());
+		b.setEnabled(analecCorpus.isModifie()); // enable if corpus is not saved
+		drop_b.setEnabled(true); // enable if corpus is not saved
+		b.setImage(IImageKeys.getImage(IImageKeys.PENCIL_SAVE));
+		open = true;
+
+		Composite toolbarsArea = editor.getUpperToolbarArea();
+		utoolbar = new UnitToolbar(toolbarsArea, StartButton.this, SWT.NONE, editor, analecCorpus, vue);
+
+		editor.getEditionPanel(0).getBrowser().addMouseListener(utoolbar.getEditorClickListener());
+		editor.getEditionPanel(0).getBrowser().getMenu().addMenuListener(utoolbar.getMenuListener());
+		editor.getEditionPanel(0).getBrowser().addKeyListener(utoolbar.getEditorKeyListener());
+	}
+	
+	private void setButtonToSaveMode() {
+		if (analecCorpus.getStructure().isVide()) {
+			System.out.println("You need to import an annotation structure before starting to annotate. Select the edition main corpus ("+name+"), then call the Analec > Import Structure command");
+			return;
+		}
+
+		b.setToolTipText("Save and close annotation tools: "+analecCorpus.isModifie());
+		b.setEnabled(analecCorpus.isModifie()); // enable if corpus is not saved
+		drop_b.setEnabled(true); // enable if corpus is not saved
+		b.setImage(IImageKeys.getImage(IImageKeys.PENCIL_SAVE));
+		open = true;
+	}
+	
+	private void setButtonToStartMode() {
+		if (b != null) {
+			b.setEnabled(AnalecCorpora.isAnnotationStructureReady(editor.getCorpus()));
+			b.setToolTipText("Start Analec annotation");
+			b.setImage(IImageKeys.getImage(IImageKeys.PENCIL));
+		}
+		if (drop_b != null) {
+			drop_b.setEnabled(AnalecCorpora.isAnnotationStructureReady(editor.getCorpus()));
+		}
+	}
+	
+	private void openSchemaToolbar() {
+		if (utoolbar instanceof SchemaToolbar) return;
+		if (utoolbar != null) {
+			closeToolbar();
+		}
+		
+		Composite toolbarsArea = editor.getUpperToolbarArea();
+		utoolbar = new SchemaToolbar(toolbarsArea, StartButton.this, SWT.NONE, editor, analecCorpus, vue);
+
+		editor.getEditionPanel(0).getBrowser().addMouseListener(utoolbar.getEditorClickListener());
+		editor.getEditionPanel(0).getBrowser().getMenu().addMenuListener(utoolbar.getMenuListener());
+		editor.getEditionPanel(0).getBrowser().addKeyListener(utoolbar.getEditorKeyListener());
+	}
+
+	private void endAnnotation() {
+		setButtonToStartMode();
+		closeToolbar();
+	}
+
+	private void closeToolbar() {
+		editor.getUpperToolbarArea().getParent().layout(true);
+		if (utoolbar != null) {
+			utoolbar.clearHighlight();
+			utoolbar.dispose();
+			
+			editor.getEditionPanel(0).getBrowser().removeMouseListener(utoolbar.getEditorClickListener());
+			editor.getEditionPanel(0).getBrowser().getMenu().removeMenuListener(utoolbar.getMenuListener());
+			editor.getEditionPanel(0).getBrowser().removeKeyListener(utoolbar.getEditorKeyListener());
+			editor.getUpperToolbarArea().getParent().layout(true);
+			utoolbar = null;
+		}
+	}
+
+	public void setEnabled(boolean state) {
+		if (b != null) b.setEnabled(state);
+		
+		if (open && drop_b != null) drop_b.setEnabled(true);
+		if (!open && drop_b != null) drop_b.setEnabled(state);
+	}
+
+	public void updateCorporaView(final MainCorpus corpus) {
+		CorporaView.refreshObject(corpus);
+	}
+
+	@Override
+	public void save() {
+		if (isDirty() && toolbar != null && !toolbar.isDisposed()) {
+			AnalecCorpora.saveCorpus(analecCorpus);
+		}
+	}
+
+	@Override
+	public boolean isDirty() {
+		return corpus.isModified();
+	}
+	
+	public void fireIsDirty() {
+		editor.fireIsDirty();
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/toolbarbutton/StartButton.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/DoInstallStep.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/DoInstallStep.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/DoInstallStep.java	(revision 481)
@@ -0,0 +1,57 @@
+package org.txm.analec.commands;
+
+import java.io.File;
+
+import org.osgi.framework.Version;
+import org.txm.PostInstallationStep;
+import org.txm.Toolbox;
+import org.txm.analec.preferences.AnalecPreferences;
+import org.txm.core.preferences.TBXPreferences;
+import org.txm.core.preferences.TXMPreferences;
+import org.txm.rcp.TxmPreferences;
+import org.txm.utils.BundleUtils;
+import org.txm.utils.logger.Log;
+
+/**
+ * Copy macros from bundle to TXM macro directory
+ * 
+ * @author mdecorde
+ *
+ */
+public class DoInstallStep  extends PostInstallationStep {
+
+	/** The ID. */
+	public static String ID = "org.txm.analec.commands.DoInstallStep"; //$NON-NLS-1$
+	public static final String VERSION = "org.txm.analec.version";
+
+	public DoInstallStep() {
+		name = "Analec";
+	}
+	
+	public void install() {
+		
+		Log.info("Analec.DoInstallStep.install()");
+		String saved = TXMPreferences.getString(AnalecPreferences.VERSION, AnalecPreferences.PREFERENCES_NODE);
+		Version currentVersion = BundleUtils.getBundleVersion("AnalecRCP");
+		
+		if (saved != null && saved.length() > 0) {
+			Version savedVersion = new Version(saved);
+			if (currentVersion.compareTo(savedVersion) <= 0) {
+				Log.info("No post-installation of Analec to do");
+				//System.out.println("No post-installation of Analec to do");
+				return; // nothing to do
+			}
+		}
+		System.out.println("Post-installing Analec version="+currentVersion);
+		
+		File macroDirectory = new File(TXMPreferences.getString(TBXPreferences.USER_TXM_HOME, TBXPreferences.PREFERENCES_NODE), "scripts/macro/org/txm/macro");
+		if (!BundleUtils.copyFiles("AnalecRCP", "src", "org/txm/macro/", "analec", macroDirectory)) {
+			System.out.println("Error while coping Analec org/txm/macro/analec in "+macroDirectory.getAbsolutePath());
+			return;
+		}
+		
+		Log.warning("Analec post-installation done.");
+		TXMPreferences.put(AnalecPreferences.PREFERENCES_NODE, AnalecPreferences.VERSION, currentVersion.toString());
+		return;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/DoInstallStep.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/EditStructure.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/EditStructure.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/EditStructure.java	(revision 481)
@@ -0,0 +1,65 @@
+package org.txm.analec.commands;
+
+import java.awt.Dimension;
+import java.awt.Point;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.VisuMain;
+import visuAnalec.donnees.Corpus;
+import visuAnalec.donnees.VisuStructure;
+import visuAnalec.util.GMessages;
+
+public class EditStructure  extends AbstractHandler {
+
+	/** The ID. */
+	public static String ID = "org.txm.analec.commands.LoadAnnotationStructure"; //$NON-NLS-1$
+	Corpus corpus;
+	/** The selection. */
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+
+		Object first = CorporaView.getSelection();
+		if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+			System.out.println("Selection is not a corpus: "+first);
+			return null;
+		}
+		
+		MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+		corpus = AnalecCorpora.getCorpus(mainCorpus.getName());
+
+		//System.out.println("Editing structure for corpus="+corpus);
+
+		javax.swing.SwingUtilities.invokeLater(new Runnable() {
+			public void run() {
+				try {
+					//System.out.println("Show editor...");
+					//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+					VisuStructure visuStructure = VisuStructure.newVisuStructure(null, corpus);
+					visuStructure.setExtendedState(VisuMain.NORMAL);
+					
+					Point locFenetre = new Point(50, 50);
+					Dimension dimFenetre = new Dimension(500, 500);
+					visuStructure.setLocation(locFenetre);
+					visuStructure.setSize(dimFenetre);
+					
+					visuStructure.setVisible(true);
+					visuStructure.agencer();
+				} catch (Throwable ex) {
+					GMessages.erreurFatale(ex);
+				}
+			}
+		});
+
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/EditStructure.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportTEICorpus.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportTEICorpus.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportTEICorpus.java	(revision 481)
@@ -0,0 +1,171 @@
+package org.txm.analec.commands;
+
+import java.io.File;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.kohsuke.args4j.Option;
+import org.txm.Toolbox;
+import org.txm.analec.AnalecAnnotationReIndexer;
+import org.txm.analec.AnalecCorpora;
+import org.txm.core.preferences.TBXPreferences;
+import org.txm.objects.BaseParameters;
+import org.txm.rcp.commands.ExecuteImportScript;
+import org.txm.rcp.swt.widget.parameters.ParametersDialog;
+import org.txm.rcp.utils.JobHandler;
+import org.txm.searchengine.cqp.corpus.CorpusManager;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+import org.txm.utils.AsciiUtils;
+import org.txm.utils.DeleteDir;
+import org.txm.utils.io.IOUtils;
+import org.txm.utils.logger.Log;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersTEI;
+
+public class ImportTEICorpus  extends AbstractHandler {
+
+	@Option(name="xmlFile",usage="an example file", widget="File", required=true, def="text.xml")
+	File xmlFile;
+
+	private String name;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		try {
+			// Open the parameters input dialog box
+			if (!ParametersDialog.open(this)) return null;
+
+			// END OF PARAMETERS
+			if (!(xmlFile.exists())) {
+				System.out.println("The AA AAM and AC files must exists.");
+				return null;
+			}
+
+			name = xmlFile.getName();
+			int idx = name.indexOf(".");
+			name = name.substring(0, idx);
+			name = AsciiUtils.buildId(name);
+
+			File srcDir = new File(xmlFile.getParentFile(), name);
+			System.out.println("Creating source directory: $srcDir");
+			DeleteDir.deleteDirectory(srcDir);
+			srcDir.mkdir();
+
+			if (!srcDir.exists()) {
+				System.out.println("Could not create the source directory $srcDir");
+				return null;
+			}
+
+			// write the TXT file WITH paragraphs
+			File txtFile = new File(srcDir, name+".txt");
+			Corpus tmpAnalecCorpus = new Corpus(); // need a temporary corpus
+			System.out.println("Importing TEI data from: "+xmlFile);
+			if (!FichiersTEI.convertir(xmlFile, new File("/tmp"), tmpAnalecCorpus)) {
+				System.out.println("Error while importing TEI data.");
+				return null;
+			}
+			
+			final String texte = tmpAnalecCorpus.getTexte();
+		    int debParag = 0;
+		    Integer[] finPars = tmpAnalecCorpus.getFinParagraphes();
+		    StringBuffer newTexte = new StringBuffer(texte.length() + finPars.length);
+		    for (int i = 0 ; i < finPars.length ; i++) {
+		    	newTexte.append(texte.substring(debParag, finPars[i])).append("\n");
+		    	debParag = finPars[i];
+		    }
+			
+			IOUtils.write(txtFile, newTexte.toString());
+			
+			if (!txtFile.exists()) {
+				System.out.println("Could not create the TXT source file $txtFile");
+				return null;
+			}
+
+			File paramFile = new File(srcDir, "import.xml");
+			BaseParameters.createEmptyParams(paramFile, name.toUpperCase());
+
+			final BaseParameters params = new BaseParameters(paramFile);
+			params.load();
+			params.rootDir = srcDir.getAbsolutePath(); // fix
+			params.saveToElement();
+
+			if (!params.save()) {
+				System.out.println("ERROR: could not save import configuration: "+ params.paramFile);
+				return null;
+			}
+
+			String txmhome = Toolbox.getParam(TBXPreferences.USER_TXM_HOME);
+			File scriptsdir = new File(txmhome, "scripts/import");
+			File script = new File(scriptsdir, "txtLoader.groovy");
+			if (!script.exists()) {
+				System.out.println("Error: no script found for import name ${importName}: $script");
+				return null;
+			}
+
+			JobHandler job = ExecuteImportScript.executeScript(script.getAbsolutePath(), params);
+			if (job == null) { // job is scheduled in ExecuteImportScript.executeScript
+				System.out.println("Error during import");
+				return null;
+			}
+
+//			System.out.println("Waiting for import to finish...");
+//			job.join();
+//			System.out.println("Waiting for import done.");
+			
+			JobHandler job2 = new JobHandler("Finalize Analec corpus import") {
+				
+				@Override
+				protected IStatus run(IProgressMonitor monitor) {
+					try {
+					MainCorpus corpus = CorpusManager.getCorpusManager().getCorpus(name.toUpperCase());
+					File analecDirectory = new File(corpus.getBaseDirectory(), "analec");
+					analecDirectory.mkdirs();
+					Corpus analecCorpus = AnalecCorpora.getCorpus(name.toUpperCase());
+					analecCorpus.clearAll(); // remove all : annotations, structure
+					
+					System.out.println("Importing TEI model from: "+xmlFile);
+					if (!FichiersTEI.convertir(xmlFile, analecDirectory, analecCorpus)) {
+						System.out.println("Error while importing TEI model.");
+						return null;
+					}
+				
+					System.out.println("Reindexing annotations with TXM words.");
+					
+					AnalecCorpora.removeCorpus(corpus.getName()); // remove old corpus if any
+					
+					AnalecAnnotationReIndexer aari = new AnalecAnnotationReIndexer(corpus, analecCorpus);
+					if (!aari.process()) {
+						System.out.println("error while re-indexing Analec annotations.");
+						return null;
+					}
+					
+					System.out.println("Saving annotations.");
+					AnalecCorpora.saveCorpus(analecCorpus);
+					AnalecCorpora.getVue(analecCorpus).retablirVueParDefaut();
+					System.out.println("Done.");
+					
+					return Status.OK_STATUS;
+					} catch (Exception e) {
+						System.out.println("Error while finalizing corpus import: "+e);
+						Log.printStackTrace(e);
+						return Status.CANCEL_STATUS;
+					}
+				}
+			};
+			job2.startJob(true); // wait for the TXT import job to finish
+			return null;
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportTEICorpus.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadStructureFromGlozz.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadStructureFromGlozz.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadStructureFromGlozz.java	(revision 481)
@@ -0,0 +1,61 @@
+package org.txm.analec.commands;
+
+import java.io.File;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.kohsuke.args4j.Option;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.swt.widget.parameters.ParametersDialog;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersGlozz;
+
+public class LoadStructureFromGlozz  extends AbstractHandler {
+
+	@Option(name="aamfile",usage="an example file", widget="File", required=true, def="model.aam")
+	File aamfile;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		
+		Object first = CorporaView.getSelection();
+		if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+			System.out.println("Selection is not a main corpus: "+first);
+			return null;
+		}
+		
+		MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+		Corpus corpus = AnalecCorpora.getCorpus(mainCorpus.getName());
+		
+//		if (VisuStructure.isOpen()) {
+//			System.out.println("Structure de corpus en cours d'édition. Abandon.");
+//			return null;
+//		}
+		
+		System.out.println("Importing Glozz model for corpus="+corpus);
+
+		if (!ParametersDialog.open(this)) return null;
+
+		// END OF PARAMETERS
+		if (!(aamfile.exists() && aamfile.exists() && aamfile.exists())) {
+			System.out.println("The AAM file must exists.");
+			return null;
+		}
+		
+		File fichierModele = aamfile;
+		if (!FichiersGlozz.importerModeleGlozz(corpus, fichierModele)) {
+			System.out.println("Fail to load structure from Glozz model.");
+			return null;
+		}
+		
+		System.out.println("Done.");
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadStructureFromGlozz.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveCorpus.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveCorpus.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveCorpus.java	(revision 481)
@@ -0,0 +1,56 @@
+package org.txm.analec.commands;
+
+import java.io.File;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersJava;
+
+public class SaveCorpus  extends AbstractHandler {
+
+	/** The ID. */
+	public static String ID = "org.txm.analec.commands.LoadAnnotationStructure"; //$NON-NLS-1$
+	Corpus corpus;
+	/** The selection. */
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+
+		Object first = CorporaView.getSelection();
+		if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+			System.out.println("Selection is not a main corpus: "+first);
+			return null;
+		}
+		
+		final MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+		File binaryCorpusDirectory = mainCorpus.getBaseDirectory();
+		File fichierCorpus = new File(binaryCorpusDirectory, "/analec/"+mainCorpus.getName()+".ec");
+		corpus = AnalecCorpora.getCorpus(mainCorpus.getName());
+		System.out.println("Saving structure for corpus="+corpus+" in "+fichierCorpus);
+
+		if (!FichiersJava.enregistrerCorpus(corpus, fichierCorpus)) {
+			System.out.println("Erreur lors de la sauvegarde du corpus.");
+			return null;
+		}
+		
+		mainCorpus.setIsModified(false);
+		HandlerUtil.getActiveShell(event).getDisplay().syncExec(new Runnable() {
+			@Override
+			public void run() {
+				CorporaView.refreshObject(mainCorpus);
+			}
+		});
+
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveCorpus.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveStructureAsGlozzModel.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveStructureAsGlozzModel.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveStructureAsGlozzModel.java	(revision 481)
@@ -0,0 +1,46 @@
+package org.txm.analec.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersGlozz;
+
+public class SaveStructureAsGlozzModel  extends AbstractHandler {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+
+		Object first = CorporaView.getSelection();
+		if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+			System.out.println("Selection is not a main corpus: "+first);
+			return null;
+		}
+		
+		MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+		
+		Corpus corpus = AnalecCorpora.getCorpus(mainCorpus.getName());
+
+//		if (VisuStructure.isOpen()) {
+//			System.out.println("Structure de corpus en cours d'édition. Abandon.");
+//			return null;
+//		}
+		
+		System.out.println("Saving structure as Glozz model for corpus="+corpus);
+
+		if (!FichiersGlozz.exporterModeleGlozz(corpus.getStructure())) {
+			System.out.println("Erreur lors de la sauvegarde de la structure.");
+			return null;
+		}
+
+		System.out.println("Done.");
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveStructureAsGlozzModel.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadCorpus.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadCorpus.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadCorpus.java	(revision 481)
@@ -0,0 +1,61 @@
+package org.txm.analec.commands;
+
+import java.io.File;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.kohsuke.args4j.Option;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.swt.widget.parameters.ParametersDialog;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersJava;
+
+public class LoadCorpus  extends AbstractHandler {
+
+	/** The ID. */
+	public static String ID = "org.txm.analec.commands.LoadAnnotationStructure"; //$NON-NLS-1$
+
+	@Option(name="ecfile",usage="an example file", widget="File", required=true, def="text.ec")
+	File ecfile;
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		
+		Object first = CorporaView.getSelection();
+		if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+			System.out.println("Selection is not a main corpus: "+first);
+			return null;
+		}
+		
+		MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+		Corpus corpus = AnalecCorpora.getCorpus(mainCorpus.getName());
+		
+		File fichierCorpus = null;
+		System.out.println("Loading corpus from file...");
+		
+		if (!ParametersDialog.open(this)) return null;
+
+		// END OF PARAMETERS
+		if (!(ecfile.exists())) {
+			System.out.println("The EC files must exists.");
+			return null;
+		}
+		fichierCorpus = ecfile;
+		System.out.println("Loading corpus from file="+fichierCorpus);
+		if (!FichiersJava.ouvrirCorpus(corpus, fichierCorpus, false)) {
+			System.out.println("Fail to laod structure.");
+			return null;
+		}
+		
+		System.out.println("Done: ");
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadCorpus.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportGlozzCorpus.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportGlozzCorpus.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportGlozzCorpus.java	(revision 481)
@@ -0,0 +1,244 @@
+package org.txm.analec.commands;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.Arrays;
+
+import org.apache.commons.io.FilenameUtils;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.kohsuke.args4j.Option;
+import org.txm.Toolbox;
+import org.txm.analec.AnalecAnnotationReIndexer;
+import org.txm.analec.AnalecCorpora;
+import org.txm.core.preferences.TBXPreferences;
+import org.txm.objects.BaseParameters;
+import org.txm.rcp.commands.ExecuteImportScript;
+import org.txm.rcp.swt.widget.parameters.ParametersDialog;
+import org.txm.rcp.utils.JobHandler;
+import org.txm.searchengine.cqp.corpus.CorpusManager;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+import org.txm.utils.AsciiUtils;
+import org.txm.utils.DeleteDir;
+import org.txm.utils.io.IOUtils;
+import org.txm.utils.logger.Log;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersGlozz;
+import visuAnalec.fichiers.FichiersJava;
+
+public class ImportGlozzCorpus  extends AbstractHandler {
+
+
+
+//	@Option(name="aafile",usage="an example file", widget="File", required=true, def="text.aa")
+//	File aafile;
+
+//	@Option(name="acfile",usage="an example file", widget="File", required=true, def="annotations.ac")
+//	File acfile
+	
+	@Option(name="glozzDirectory",usage="A folder containing the Glozz files: aa ac and aam", widget="Folder", required=true, def="glozz")
+	File glozzDirectory;
+	
+	@Option(name="aamfile",usage="The aam file to use", widget="File", required=true, def="model.aam")
+	File aamfile;
+	private String name;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		try {
+			// Open the parameters input dialog box
+			if (!ParametersDialog.open(this)) return null;
+
+			// END OF PARAMETERS
+			if (!glozzDirectory.exists()) {
+				System.out.println("The glozzDirectory directory must exists.");
+				return null;
+			}
+
+			name = glozzDirectory.getName();
+			name = AsciiUtils.buildId(name);
+
+			final File srcDir = new File(glozzDirectory, name);
+			System.out.println("Creating source directory: $srcDir");
+			DeleteDir.deleteDirectory(srcDir);
+			srcDir.mkdir();
+
+			final File ecDir = new File(glozzDirectory, "ec");
+			System.out.println("Creating ec directory: $ecDir");
+			DeleteDir.deleteDirectory(ecDir);
+			ecDir.mkdir();
+
+			
+			if (!srcDir.exists()) {
+				System.out.println("Could not create the source directory $srcDir");
+				return null;
+			}
+			
+			if (!ecDir.exists()) {
+				System.out.println("Could not create the ec directory $ecDir");
+				return null;
+			}
+
+			// write the TXT file WITH paragraphs
+			File[] aaFiles = glozzDirectory.listFiles(new FilenameFilter() {
+				@Override
+				public boolean accept(File dir, String name) {
+					return name.endsWith(".aa");
+				}
+			});
+			File[] acFiles = glozzDirectory.listFiles(new FilenameFilter() {
+				@Override
+				public boolean accept(File dir, String name) {
+					return name.endsWith(".ac");
+				}
+			});
+
+			if (aaFiles == null || aaFiles.length == 0) {
+				System.out.println("No .aa files found in "+glozzDirectory);
+				return false;
+			}
+			if (acFiles == null || acFiles.length == 0) {
+				System.out.println("No .ac files found in "+glozzDirectory);
+				return false;
+			}
+			if (aaFiles.length != acFiles.length) {
+				System.out.println("No .aa files found in "+glozzDirectory);
+				return false;
+			}
+			
+			System.out.println("Importing Glozz data from: "+glozzDirectory);
+			Arrays.sort(acFiles);
+			Arrays.sort(aaFiles);
+			for (int i = 0 ; i < aaFiles.length ; i++) {
+				File acFile = acFiles[i];
+				File aaFile = aaFiles[i];
+				String name = acFile.getName();
+				int idx = name.indexOf(".");
+				if (idx > 0) name = name.substring(0, idx);
+				
+				File txtFile = new File(srcDir, name+".txt");
+				File ecFile = new File(ecDir, name+".ec");
+				Corpus tmpAnalecCorpus = new Corpus(); // need a temporary corpus
+				
+				if (!FichiersGlozz.importerGlozz(tmpAnalecCorpus, acFile, aaFile)) {
+					System.out.println("Error while importing Glozz data.");
+					return null;
+				}
+				
+				final String texte = tmpAnalecCorpus.getTexte();
+			    int debParag = 0;
+			    Integer[] finPars = tmpAnalecCorpus.getFinParagraphes();
+			    StringBuffer newTexte = new StringBuffer(texte.length() + finPars.length);
+			    for (int iParagraph = 0 ; iParagraph < finPars.length ; iParagraph++) {
+			    	newTexte.append(texte.substring(debParag, finPars[iParagraph])).append("\n");
+			    	debParag = finPars[iParagraph];
+			    }
+				
+				IOUtils.write(txtFile, newTexte.toString()); // write the TXT file for TXM TXT import module
+				FichiersJava.enregistrerCorpus(tmpAnalecCorpus, ecFile); // write for later
+				
+				if (!txtFile.exists()) {
+					System.out.println("Could not create the TXT source file $txtFile");
+					return null;
+				}
+			}
+			
+			File paramFile = new File(srcDir, "import.xml");
+			BaseParameters.createEmptyParams(paramFile, name.toUpperCase());
+
+			final BaseParameters params = new BaseParameters(paramFile);
+			params.load();
+			params.rootDir = srcDir.getAbsolutePath(); // fix
+			params.saveToElement();
+
+			if (!params.save()) {
+				System.out.println("ERROR: could not save import configuration: "+ params.paramFile);
+				return null;
+			}
+
+			String txmhome = Toolbox.getParam(TBXPreferences.USER_TXM_HOME);
+			File scriptsdir = new File(txmhome, "scripts/import");
+			File script = new File(scriptsdir, "txtLoader.groovy");
+			if (!script.exists()) {
+				System.out.println("Error: no script found for import name ${importName}: $script");
+				return null;
+			}
+
+			JobHandler job = ExecuteImportScript.executeScript(script.getAbsolutePath(), params);
+			if (job == null) { // job is scheduled in ExecuteImportScript.executeScript
+				System.out.println("Error during import");
+				return null;
+			}
+
+//			System.out.println("Waiting for import to finish...");
+//			job.join();
+//			System.out.println("Waiting for import done.");
+			
+			JobHandler job2 = new JobHandler("Finalize Analec corpus import") {
+				
+				@Override
+				protected IStatus run(IProgressMonitor monitor) {
+					try {
+					Corpus analecCorpus = AnalecCorpora.getCorpus(name.toUpperCase());
+					analecCorpus.clearAll(); // remove all : annotations, structure
+					File[] ecFiles = ecDir.listFiles();
+					Arrays.sort(ecFiles);
+					for (File ecFile : ecFiles) {
+						FichiersJava.concatener(ecFile, analecCorpus);
+					}
+					
+					System.out.println("Importing Glozz model from: "+aamfile);
+					if (!FichiersGlozz.importerModeleGlozz(analecCorpus, aamfile)) {
+						System.out.println("Error while importing Glozz model.");
+						return null;
+					}
+//					
+//					System.out.println("Importing Glozz corpus from: "+acfile+" and "+aafile);
+//					if (!FichiersGlozz.importerGlozz(analecCorpus, acfile, aafile)) {
+//						System.out.println("Error while importing Glozz corpus.");
+//						return null;
+//					}
+					
+					System.out.println("Reindexing annotations with TXM words.");
+					MainCorpus corpus = CorpusManager.getCorpusManager().getCorpus(name.toUpperCase());
+					AnalecCorpora.removeCorpus(corpus.getName()); // remove old corpus if any
+					
+					AnalecAnnotationReIndexer aari = new AnalecAnnotationReIndexer(corpus, analecCorpus);
+					if (!aari.process()) {
+						System.out.println("error while re-indexing Analec annotations.");
+						return null;
+					}
+					
+					System.out.println("Saving annotations.");
+					AnalecCorpora.saveCorpus(analecCorpus);
+					AnalecCorpora.getVue(analecCorpus).retablirVueParDefaut();
+					System.out.println("Done.");
+					analecCorpus.setTexte(""); // free memory
+					DeleteDir.deleteDirectory(ecDir); // cleaning
+					DeleteDir.deleteDirectory(srcDir); // cleaning
+					
+					return Status.OK_STATUS;
+					} catch (Exception e) {
+						System.out.println("ERROR while finalizing corpus import: "+e.getLocalizedMessage());
+						Log.printStackTrace(e);
+						return Status.CANCEL_STATUS;
+					}
+				}
+			};
+			job2.startJob(true); // wait for the TXT import job to finish
+			return null;
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportGlozzCorpus.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportGlozzAnnotations.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportGlozzAnnotations.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportGlozzAnnotations.java	(revision 481)
@@ -0,0 +1,90 @@
+package org.txm.analec.commands;
+
+import java.io.File;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.kohsuke.args4j.Option;
+import org.txm.analec.AnalecAnnotationReIndexer;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.swt.widget.parameters.ParametersDialog;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.CorpusManager;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersGlozz;
+
+public class ImportGlozzAnnotations  extends AbstractHandler {
+
+
+
+	@Option(name="aafile",usage="an example file", widget="File", required=true, def="text.aa")
+	File aafile;
+
+	@Option(name="aamfile",usage="an example file", widget="File", required=true, def="model.aam")
+	File aamfile;
+
+	@Option(name="acfile",usage="an example file", widget="File", required=true, def="annotations.ac")
+	File acfile;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		try {
+			// Open the parameters input dialog box
+			if (!ParametersDialog.open(this)) return null;
+
+			// END OF PARAMETERS
+			if (!(aafile.exists() && aafile.exists() && aafile.exists())) {
+				System.out.println("The AA AAM and AC files must exists.");
+				return null;
+			}
+
+			Object first = CorporaView.getSelection();
+			if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+				System.out.println("Selection is not a main corpus: "+first);
+				return null;
+			}
+			
+			MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+			Corpus analecCorpus = AnalecCorpora.getCorpus(mainCorpus.getName());
+			analecCorpus.clearAll(); // remove all : annotations, structure
+			
+			System.out.println("Importing Glozz model from: "+aamfile);
+			if (!FichiersGlozz.importerModeleGlozz(analecCorpus, aamfile)) {
+				System.out.println("error while importing Glozz model.");
+				return null;
+			}
+			
+			System.out.println("Importing Glozz corpus from: "+acfile+" and "+aafile);
+			if (!FichiersGlozz.importerGlozz(analecCorpus, acfile, aafile)) {
+				System.out.println("error while importing Glozz corpus.");
+				return null;
+			}
+			
+			System.out.println("Reindexing annotations with TXM words");
+			AnalecAnnotationReIndexer aari = new AnalecAnnotationReIndexer(mainCorpus, analecCorpus);
+			if (!aari.process()) {
+				System.out.println("error while re-indexing Analec annotations.");
+				return null;
+			}
+			
+			System.out.println("Saving annotations.");
+			AnalecCorpora.saveCorpus(analecCorpus);
+			
+			System.out.println("Done.");
+			return null;
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ImportGlozzAnnotations.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveVue.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveVue.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveVue.java	(revision 481)
@@ -0,0 +1,48 @@
+package org.txm.analec.commands;
+
+import java.io.File;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersJava;
+
+public class SaveVue  extends AbstractHandler {
+
+	/** The ID. */
+	public static String ID = "org.txm.analec.commands.LoadAnnotationStructure"; //$NON-NLS-1$
+	Corpus corpus;
+	/** The selection. */
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+
+		Object first = CorporaView.getSelection();
+		if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+			System.out.println("Selection is not a main corpus: "+first);
+			return null;
+		}
+		
+		MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+		corpus = AnalecCorpora.getCorpus(mainCorpus.getName());
+
+		File binaryCorpusDirectory = mainCorpus.getBaseDirectory();
+		File fichierVue = new File(binaryCorpusDirectory, "/analec/"+mainCorpus.getName()+".ecv");
+		System.out.println("Saving vue for corpus="+corpus+" in "+fichierVue);
+
+		if (!FichiersJava.enregistrerCorpus(corpus, fichierVue)) {
+			System.out.println("Erreur lors de la sauvegarde de la vue.");
+			return null;
+		}
+
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveVue.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ExportTEICorpus.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ExportTEICorpus.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ExportTEICorpus.java	(revision 481)
@@ -0,0 +1,55 @@
+package org.txm.analec.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.swt.widget.parameters.ParametersDialog;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersTEI;
+
+public class ExportTEICorpus  extends AbstractHandler {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		try {
+			// Open the parameters input dialog box
+			if (!ParametersDialog.open(this)) return null;
+
+			Object first = CorporaView.getSelection();
+			if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+				System.out.println("Selection is not a main corpus: "+first);
+				return null;
+			}
+			
+			MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+			
+			String name = mainCorpus.getName();
+			
+			Corpus analecCorpus = AnalecCorpora.getCorpus(name.toUpperCase());
+			analecCorpus.clearAll(); // remove all : annotations, structure
+			
+			if (!FichiersTEI.exporterCorpusTEI(analecCorpus)) {
+				System.out.println("Error while exporting corpus to XML-Analec.");
+				return null;
+			}
+
+			System.out.println("Done.");
+			
+			return null;
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ExportTEICorpus.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadVue.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadVue.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadVue.java	(revision 481)
@@ -0,0 +1,44 @@
+package org.txm.analec.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.fichiers.FichiersJava;
+import visuAnalec.vue.Vue;
+
+public class LoadVue  extends AbstractHandler {
+
+	/** The ID. */
+	public static String ID = "org.txm.analec.commands.LoadAnnotationStructure"; //$NON-NLS-1$
+
+	/** The selection. */
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		
+		Object first = CorporaView.getSelection();
+		if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+			System.out.println("Selection is not a main corpus: "+first);
+			return null;
+		}
+		
+		MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+		
+		System.out.println("Loading vue for corpus="+mainCorpus.getName());
+		Vue vue = AnalecCorpora.getVue(mainCorpus.getName());
+		if (!FichiersJava.ouvrirVue(vue)) {
+			System.out.println("Fail to load structure.");
+			return null;
+		}
+		
+		System.out.println("Done: ");
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadVue.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveStructure.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveStructure.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveStructure.java	(revision 481)
@@ -0,0 +1,52 @@
+package org.txm.analec.commands;
+
+import java.io.File;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersJava;
+
+public class SaveStructure  extends AbstractHandler {
+
+	/** The ID. */
+	public static String ID = "org.txm.analec.commands.LoadAnnotationStructure"; //$NON-NLS-1$
+	/** The selection. */
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+
+		Object first = CorporaView.getSelection();
+		if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+			System.out.println("Selection is not a main corpus: "+first);
+			return null;
+		}
+		
+		MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+		Corpus corpus = AnalecCorpora.getCorpus(mainCorpus.getName());
+
+//		if (VisuStructure.isOpen()) {
+//			System.out.println("Structure de corpus en cours d'édition. Abandon.");
+//			return null;
+//		}
+		
+		File binaryCorpusDirectory = mainCorpus.getBaseDirectory();
+		File fichierStructure = new File(binaryCorpusDirectory, "/analec/"+mainCorpus.getName()+".ecs");
+		System.out.println("Saving structure for corpus="+corpus+" in "+fichierStructure);
+
+		if (!FichiersJava.enregistrerStructure(corpus, fichierStructure)) {
+			System.out.println("Erreur lors de la sauvegarde de la structure.");
+			return null;
+		}
+
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/SaveStructure.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadStructure.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadStructure.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadStructure.java	(revision 481)
@@ -0,0 +1,47 @@
+package org.txm.analec.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersJava;
+
+public class LoadStructure  extends AbstractHandler {
+
+	/** The ID. */
+	public static String ID = "org.txm.analec.commands.LoadAnnotationStructure"; //$NON-NLS-1$
+
+	/** The selection. */
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		
+		Object first = CorporaView.getSelection();
+		if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+			System.out.println("Selection is not a main corpus: "+first);
+			return null;
+		}
+		
+		MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+		Corpus corpus = AnalecCorpora.getCorpus(mainCorpus.getName());
+//		if (VisuStructure.isOpen()) {
+//			System.out.println("Structure de corpus en cours d'édition. Abandon.");
+//			return null;
+//		}
+		
+		System.out.println("Loading structure for corpus="+corpus);
+		if (!FichiersJava.ouvrirStructure(corpus)) {
+			System.out.println("Fail to laod structure.");
+			return null;
+		}
+		System.out.println("Done: ");
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/LoadStructure.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ExportGlozzCorpus.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ExportGlozzCorpus.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ExportGlozzCorpus.java	(revision 481)
@@ -0,0 +1,56 @@
+package org.txm.analec.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.txm.analec.AnalecCorpora;
+import org.txm.rcp.swt.widget.parameters.ParametersDialog;
+import org.txm.rcp.views.corpora.CorporaView;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.fichiers.FichiersGlozz;
+import visuAnalec.fichiers.FichiersTEI;
+
+public class ExportGlozzCorpus  extends AbstractHandler {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		try {
+			// Open the parameters input dialog box
+			if (!ParametersDialog.open(this)) return null;
+
+			Object first = CorporaView.getSelection();
+			if (!(first instanceof org.txm.searchengine.cqp.corpus.Corpus)) {
+				System.out.println("Selection is not a main corpus: "+first);
+				return null;
+			}
+			
+			MainCorpus mainCorpus = ((org.txm.searchengine.cqp.corpus.Corpus)first).getMainCorpus();
+			
+			String name = mainCorpus.getName();
+			
+			Corpus analecCorpus = AnalecCorpora.getCorpus(name.toUpperCase());
+			analecCorpus.clearAll(); // remove all : annotations, structure
+			
+			if (!FichiersGlozz.exporterGlozz(analecCorpus)) {
+				System.out.println("Error while exporting corpus to XML-Glozz.");
+				return null;
+			}
+
+			System.out.println("Done.");
+			
+			return null;
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/commands/ExportGlozzCorpus.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/preferences/AnalecPreferencePage.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/preferences/AnalecPreferencePage.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/preferences/AnalecPreferencePage.java	(revision 481)
@@ -0,0 +1,69 @@
+package org.txm.analec.preferences;
+
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.ColorFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.RadioGroupFieldEditor;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.preferences.ScopedPreferenceStore;
+import org.txm.rcp.Application;
+
+public class AnalecPreferencePage  extends FieldEditorPreferencePage
+implements IWorkbenchPreferencePage {
+	public static final String ANALEC_LIMIT_CORRECTION_SCHEME = "analec_limit_correction_scheme";
+	private BooleanFieldEditor analec_limit_scheme_field;
+	
+//	public static final String SELECTED_UNIT_COLOR = "selected_unit_color";
+//	private ColorFieldEditor selected_unit_color;
+//	public static final String HIGHLIGHTED_UNIT_COLOR = "hightlighted_unit_color";
+//	private ColorFieldEditor hightlighted_unit_color;
+	
+	ScopedPreferenceStore preferences;
+	public static final String COLOR_PALETTE = "color_palette";
+	private RadioGroupFieldEditor color_palette;
+
+	public AnalecPreferencePage() {
+		super();
+		
+		preferences = new ScopedPreferenceStore(org.eclipse.core.runtime.preferences.InstanceScope.INSTANCE,
+				Application.PLUGIN_ID);
+		setPreferenceStore(preferences);
+	}
+
+	/**
+	 * Creates the field editors. Field editors are abstractions of the common
+	 * GUI blocks needed to manipulate various types of preferences. Each field
+	 * editor knows how to save and restore itself.
+	 */
+	@Override
+	public void createFieldEditors() {
+		analec_limit_scheme_field = new BooleanFieldEditor(
+				ANALEC_LIMIT_CORRECTION_SCHEME, "Use Analec scheme to fix unit limits",
+				getFieldEditorParent());
+		addField(analec_limit_scheme_field);
+		
+//		hightlighted_unit_color = new ColorFieldEditor(
+//				HIGHLIGHTED_UNIT_COLOR, "Highlighted units background color",
+//				getFieldEditorParent());
+//		addField(hightlighted_unit_color);
+//		
+//		
+//		selected_unit_color = new ColorFieldEditor(
+//				SELECTED_UNIT_COLOR, "Selected units background color",
+//				getFieldEditorParent());
+//		addField(selected_unit_color);
+		
+		String[][] values = {{"green","green"}, {"yellow","yellow"}};
+		color_palette = new RadioGroupFieldEditor(COLOR_PALETTE, "Unit highlight color palette", 2, values, getFieldEditorParent());
+		addField(color_palette);
+		
+		preferences = new ScopedPreferenceStore(org.eclipse.core.runtime.preferences.InstanceScope.INSTANCE,
+				Application.PLUGIN_ID);
+		setPreferenceStore(preferences);
+		setTitle("Analec");
+	}
+	
+	@Override
+	public void init(IWorkbench workbench) { }
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/preferences/AnalecPreferencePage.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/preferences/AnalecPreferences.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/preferences/AnalecPreferences.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/preferences/AnalecPreferences.java	(revision 481)
@@ -0,0 +1,20 @@
+package org.txm.analec.preferences;
+
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.service.prefs.Preferences;
+import org.txm.core.preferences.TXMPreferences;
+
+public class AnalecPreferences extends TXMPreferences{
+	
+	public static final String PREFERENCES_NODE = FrameworkUtil.getBundle(AnalecPreferences.class).getSymbolicName();
+	public static final String VERSION = "analec.version"; //$NON-NLS-1$
+	public static final String COLOR_PALETTE = "color_palette";
+	
+	@Override
+	public void initializeDefaultPreferences() {
+		Preferences preferences = DefaultScope.INSTANCE.getNode(PREFERENCES_NODE);
+		preferences.put(VERSION, "");
+		preferences.put(COLOR_PALETTE, "green");
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/preferences/AnalecPreferences.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/AnnotationToolbar.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/AnnotationToolbar.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/AnnotationToolbar.java	(revision 481)
@@ -0,0 +1,49 @@
+package org.txm.analec.toolbar;
+
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MenuListener;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.widgets.Composite;
+import org.txm.analec.toolbarbutton.StartButton;
+import org.txm.rcp.synoptic.editor.EditionPanel.RGBA;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.elements.Element;
+
+public abstract class AnnotationToolbar extends Composite {
+	
+	//see https://groupes.renater.fr/wiki/txm-info/public/specs_charte_graphique
+	public static final RGBA blue = new RGBA(152, 159, 201, 0.7f);
+	public static final RGBA green = new RGBA(122, 153, 0, 0.7f);
+	public static final RGBA lightgreen = new RGBA(206, 240, 83, 0.5f);
+	public static final RGBA yellow = new RGBA(255,255,96, 1f);
+	public static final RGBA lightblue = new RGBA(183, 191, 237, 0.7f);
+	public static final RGBA lightyellow = new RGBA(255,255,176, 0.5f);
+	
+	protected Corpus analecCorpus;
+	protected StartButton button;
+	
+	public AnnotationToolbar(Composite parent, StartButton button, int style) {
+		super(parent, style);
+		this.button = button;
+	}
+	
+	public abstract void selectFirst();
+	public abstract void selectPrevious();
+	public abstract void select10Previous();
+	public abstract void select10Next();
+	public abstract void selectNext();
+	public abstract void selectLast();
+	public abstract void select(Element currentElement);
+
+	public Corpus getAnalecCorpus() {
+		return analecCorpus;
+	}
+	
+	public abstract MenuListener getMenuListener();
+	public abstract MouseListener getEditorClickListener();
+	public abstract KeyListener getEditorKeyListener();
+	public abstract void clearHighlight();
+	
+	public StartButton getStartButton() { return button;};
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/AnnotationToolbar.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/UnitToolbar.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/UnitToolbar.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/UnitToolbar.java	(revision 481)
@@ -0,0 +1,1219 @@
+package org.txm.analec.toolbar;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DragDetectListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.MenuListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.txm.Toolbox;
+import org.txm.analec.preferences.AnalecPreferencePage;
+import org.txm.analec.preferences.AnalecPreferences;
+import org.txm.analec.toolbarbutton.StartButton;
+import org.txm.analec.view.ElementPropertiesView;
+import org.txm.analec.view.ElementSearchView;
+import org.txm.analec.widgets.NavigationField;
+import org.txm.core.preferences.TXMPreferences;
+import org.txm.objects.Edition;
+import org.txm.objects.Page;
+import org.txm.objects.Text;
+import org.txm.rcp.synoptic.editor.EditionPanel;
+import org.txm.rcp.synoptic.editor.EditionPanel.RGBA;
+import org.txm.rcp.synoptic.editor.SynopticEditionEditor;
+import org.txm.rcp.IImageKeys;
+import org.txm.rcp.TxmPreferences;
+import org.txm.rcp.swt.dialog.ConfirmDialog;
+import org.txm.searchengine.cqp.AbstractCqiClient;
+import org.txm.searchengine.cqp.CQPEngine;
+import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
+import org.txm.searchengine.cqp.clientExceptions.UnexpectedAnswerException;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+import org.txm.searchengine.cqp.corpus.Property;
+import org.txm.searchengine.cqp.corpus.QueryResult;
+import org.txm.searchengine.cqp.corpus.query.Match;
+import org.txm.searchengine.cqp.corpus.query.Query;
+import org.txm.searchengine.cqp.serverException.CqiServerError;
+import org.txm.utils.logger.Log;
+
+import visuAnalec.Message;
+import visuAnalec.Message.TypeMessage;
+import visuAnalec.donnees.Corpus;
+import visuAnalec.donnees.Corpus.CorpusListener;
+import visuAnalec.donnees.Structure;
+import visuAnalec.elements.Element;
+import visuAnalec.elements.Unite;
+import visuAnalec.vue.Vue;
+
+public class UnitToolbar extends AnnotationToolbar implements CorpusListener {
+
+	//boolean AnalecUnitLimitCorrectionScheme = TxmPreferences.getBoolean(AnalecPreferencePage.ANALEC_LIMIT_CORRECTION_SCHEME); // use Analec scheme to fix unit limits or TXM's
+
+	public RGBA highlighted_unit_color = new RGBA(183, 191, 237, 0.7f);
+	public RGBA selected_unit_color = new RGBA(255, 255, 0, 0.5f);
+
+	private Button createButton;
+	private Button deleteButton;
+	private Button editButton;
+	SynopticEditionEditor editor;
+
+	private KeyListener editorKeyListener;
+	private MouseListener editorMouseListener;
+	private int fixingAnnotationLimits = 0;
+	private NavigationField navigationField;
+	private Label l;
+	private MenuListener menuListener;
+	private List<String> previousSelectedTypeUnitIDS;
+
+	private List<String> previousSelectedUnitIDS;
+	protected boolean startFixingUnitLimit;
+	private Combo typeCombo;
+	private Unite[] unites;
+	private String[] typesUnitesAVoir;
+	private Vue vue;
+	private MainCorpus maincorpus;
+	private int maxCorpusPosition;
+
+	private DragDetectListener dragDetectListener;
+
+	private Button searchButton;
+
+	private Button drop_b;
+	private Button editLeftButton;
+	private Button editRightButton;
+
+	public UnitToolbar(Composite toolbarsArea, StartButton button, int style, SynopticEditionEditor syneditor, Corpus analecCorpus, Vue vue) {
+		super(toolbarsArea, button, style);
+
+
+		String color_palette = TXMPreferences.getString(AnalecPreferences.COLOR_PALETTE, AnalecPreferences.PREFERENCES_NODE);
+		if ("green".equals(color_palette)) {
+			this.highlighted_unit_color = AnnotationToolbar.lightgreen;
+			this.selected_unit_color = AnnotationToolbar.green;
+		} else if ("yellow".equals(color_palette)) {
+			this.highlighted_unit_color = AnnotationToolbar.lightyellow;
+			this.selected_unit_color = AnnotationToolbar.yellow;
+		} else { // custom palette
+			//		String highlighted_unit_color_pref = TxmPreferences.get(AnalecPreferencePage.HIGHLIGHTED_UNIT_COLOR, "255,255,176");
+			//		String selected_unit_color_pref = TxmPreferences.get(AnalecPreferencePage.SELECTED_UNIT_COLOR, "255,255,96");
+			//		this.highlighted_unit_color = new RGBA(highlighted_unit_color_pref, 0.7f);
+			//		this.selected_unit_color = new RGBA(selected_unit_color_pref, 1f);
+
+		}
+
+		this.button = button;
+		this.editor = syneditor;
+		this.maincorpus = UnitToolbar.this.editor.getCorpus().getMainCorpus();
+		try {
+			maxCorpusPosition = maincorpus.getSize();
+		} catch (Exception e) {
+			System.out.println("** Could not retrieve "+maincorpus+" size: "+e.getLocalizedMessage());
+			Log.printStackTrace(e);
+		}
+		this.analecCorpus = analecCorpus;
+		analecCorpus.addEventListener(this);
+		this.vue = vue;
+		this.setLayout(new GridLayout(10, false));
+		this.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
+
+		l = new Label(this, SWT.NONE);
+		l.setText("Unité :");
+
+		typeCombo = new Combo(this, SWT.NONE|SWT.READ_ONLY);
+		typeCombo.setToolTipText("<type d'unité>");
+		GridData gdata = new GridData(GridData.FILL, GridData.FILL, false, false);
+		gdata.minimumWidth = 100;
+		gdata.widthHint = 100;
+		typeCombo.setLayoutData(gdata);
+		typeCombo.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				onTypecomboSelected(e);
+			}
+		});
+
+		searchButton = new Button(this, SWT.PUSH);
+		searchButton.setImage(IImageKeys.getImage(IImageKeys.ACTION_SEARCH));
+		searchButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false));
+		searchButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (typeCombo.getSelectionIndex() > 0) {
+					ElementSearchView view = ElementSearchView.openView();
+					view.loadType(UnitToolbar.this.analecCorpus, Unite.class, typeCombo.getText(), UnitToolbar.this);
+				}
+			}
+		});
+
+		navigationField = new NavigationField(this, SWT.NONE);
+		gdata = new GridData(GridData.FILL, GridData.FILL, true, false);
+		navigationField.setLayoutData(gdata);
+		navigationField.addListener(SWT.Selection, new Listener() {
+			@Override
+			public void handleEvent(Event event) {
+				onIdentifiantComboSelected(null);
+			}
+		});
+
+		createButton = new Button(this, SWT.PUSH);
+		createButton.setText("Créer");
+		createButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				onCreateButtonSelected(e);
+			}
+		});
+		deleteButton = new Button(this, SWT.PUSH);
+		deleteButton.setImage(IImageKeys.getImage(IImageKeys.ACTION_DELETE));
+		deleteButton.setToolTipText("Supprimer");
+		deleteButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				onDeleteComboSelected(e);
+			}
+		});
+
+		l = new Label(this, SWT.NONE);
+		l.setText("Limites :");
+
+		editLeftButton = new Button(this, SWT.TOGGLE);
+		editLeftButton.setText("<[");
+		editLeftButton.setToolTipText("Corriger la limite gauche");
+		editLeftButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				onEditButtonSelected(e,1);
+			}
+		});
+
+		editButton = new Button(this, SWT.TOGGLE);
+		editButton.setText("[]");
+		editButton.setToolTipText("Corriger avec une nouvelle sélection");
+		editButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				onEditButtonSelected(e);
+			}
+		});
+
+		editRightButton = new Button(this, SWT.TOGGLE);
+		editRightButton.setText("]>");
+		editRightButton.setToolTipText("Corriger la limite droite");
+		editRightButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				onEditButtonSelected(e,2);
+			}
+		});
+
+		//		drop_b = new Button(this, SWT.PUSH);
+		//		//drop_b.setText("▾");
+		////		gdata = new GridData(GridData.FILL, GridData.FILL, false, false);
+		////		gdata.minimumWidth = gdata.widthHint = 20;
+		////		//drop_b.setLayoutData(gdata);
+		//		//drop_b.addSelectionListener(new SelectionListener() {
+		//
+		//			@Override
+		//			public void widgetSelected(SelectionEvent e) {
+		//				Menu menu = new Menu(e.display.getActiveShell(), SWT.POP_UP);
+		//
+		//                MenuItem item1 = new MenuItem(menu, SWT.PUSH);
+		//                item1.setText("<[");
+		//                item1.addSelectionListener(new SelectionListener() {
+		//					@Override
+		//					public void widgetSelected(SelectionEvent e) {
+		//						onEditButtonSelected(e,1);
+		//					}
+		//					@Override
+		//					public void widgetDefaultSelected(SelectionEvent e) {}
+		//				});
+		//                MenuItem item2 = new MenuItem(menu, SWT.PUSH);
+		//                item2.setText("]>");
+		//                item2.addSelectionListener(new SelectionListener() {
+		//					@Override
+		//					public void widgetSelected(SelectionEvent e) {
+		//						onEditButtonSelected(e,2);
+		//					}
+		//					@Override
+		//					public void widgetDefaultSelected(SelectionEvent e) {}
+		//				});
+		////                MenuItem item3 = new MenuItem(menu, SWT.PUSH);
+		////                item3.setText("Fix limits with Analec scheme");
+		////                item3.addSelectionListener(new SelectionListener() {
+		////					@Override
+		////					public void widgetSelected(SelectionEvent e) {
+		////						onEditButtonSelected(e,3);
+		////					}
+		////					@Override
+		////					public void widgetDefaultSelected(SelectionEvent e) {}
+		////				});
+		//               
+		//                Point loc = //drop_b.getLocation();
+		//                Rectangle rect = //drop_b.getBounds();
+		//
+		//                Point mLoc = new Point(loc.x-1, loc.y+rect.height);
+		//                menu.setLocation(e.display.getActiveShell().getDisplay().map(//drop_b.getParent(), null, mLoc));
+		//                menu.setVisible(true);
+		//			}
+		//
+		//			@Override
+		//			public void widgetDefaultSelected(SelectionEvent e) { }
+		//		});
+
+		toolbarsArea.layout();
+		toolbarsArea.getParent().layout(true);
+		editor.getEditionArea().layout();
+
+		reloadUnits(); // reloads types
+		reloadIdentifiants();
+
+		editor.updateWordStyles();
+
+		createButton.setEnabled(false);
+		deleteButton.setEnabled(false);
+		editButton.setEnabled(false);
+		editLeftButton.setEnabled(false);
+		editRightButton.setEnabled(false);
+		//drop_b.setEnabled(false);
+		if (typesUnitesAVoir.length > 0) {
+			typeCombo.select(1);
+			onTypecomboSelected(null);
+
+			testIfAwordSpanIsSelected();
+		}
+
+		ElementPropertiesView.openView();
+	}
+
+	public void clearHighlight() {
+		if (previousSelectedUnitIDS != null) {
+			editor.removeHighlightWordsById(selected_unit_color, previousSelectedUnitIDS);
+			editor.removeFontWeightWordsById(previousSelectedUnitIDS);
+			previousSelectedUnitIDS = null; // release memory
+		}
+		if (previousSelectedTypeUnitIDS != null) {
+			editor.removeHighlightWordsById(highlighted_unit_color, previousSelectedTypeUnitIDS);
+			previousSelectedTypeUnitIDS = null; // release memory
+		}
+		editor.updateWordStyles();
+
+		createButton.setEnabled(false);
+		deleteButton.setEnabled(false);
+		editButton.setEnabled(false);
+		//drop_b.setEnabled(false);
+	}
+
+	public void dispose() {
+		try {
+			analecCorpus.removeEventListener(this);
+		} catch(Exception e) { }
+		super.dispose();
+
+	}
+
+	public MouseListener getEditorClickListener() {
+		if (editorMouseListener != null) return editorMouseListener;
+		editorMouseListener = new MouseListener() {
+
+			boolean dblClick = false;
+			boolean debug = false;
+			private int t,x,y;
+
+			@Override
+			public void mouseDoubleClick(MouseEvent e) {
+				if (debug) System.out.println("DOUBLE CLICK");
+				dblClick= true;
+
+				EditionPanel panel = editor.getEditionPanel(0);
+				if (panel == null) return;
+				String[] ids = panel.getWordSelection(); // may be null
+				//System.out.println("word id="+id);
+				//				if (id != null) {
+				//					org.txm.searchengine.cqp.corpus.Corpus c = UnitToolbar.this.editor.getCorpus();
+				//					try {
+				//						if (debug)  System.out.println(" HIGHLIGHTING ANNOT IF ANY AT "+id);
+				//						tryHighlightingWord(id,c );
+				//					} catch (Exception ex) {
+				//						ex.printStackTrace();
+				//					}
+				//				}
+
+				if (ids != null && typeCombo.getSelectionIndex() > 0 && typeCombo.getEnabled())
+					createButton.setEnabled(true); // there is a text selection in the browser
+			}
+
+			@Override
+			public void mouseDown(MouseEvent e) {
+				if (debug) System.out.println("MOUSE DOWN");
+				dblClick = false;
+				t = e.time;
+				x = e.x;
+				y = e.y;
+			}
+
+			@Override
+			public void mouseUp(MouseEvent e) {
+				if (dblClick) { // doucle click raised by mouseDoubleClick
+					dblClick = false;
+					return; // stop right now ! :-o
+				}
+				if (debug) System.out.println("MOUSE UP");
+				EditionPanel panel = editor.getEditionPanel(0);
+				if (panel == null) return;
+
+				if (typeCombo.getSelectionIndex() <= 0) {
+					createButton.setEnabled(false);
+					deleteButton.setEnabled(false);
+					editLeftButton.setEnabled(false);
+					editButton.setEnabled(false);
+					editRightButton.setEnabled(false);
+					//drop_b.setEnabled(false);
+					return; // nothing to do with annotations
+				}
+
+				// filter click that are not a left simple click (no drag)
+				//System.out.println("click count="+e.count+" button="+e.button+" time="+e.time+" diff="+(e.time-t)+" dist="+(Math.abs(e.x - x) + Math.abs(e.y - y)));
+				if (e.count > 1) {
+					if (debug) System.out.println(" DOUBLE CLICK");
+					//System.out.println("not a simple click");
+					return;
+				}
+
+				int dist = Math.abs(e.x - x) + Math.abs(e.y - y);
+				int deltat = (e.time-t);
+				//System.out.println("deltat ="+deltat);
+				if (dist != 0 && (deltat > 120 || dist > 4)) {
+					//System.out.println(" DRAG dist="+dist+" deltat="+deltat);
+
+					String[] ids = panel.getWordSelection(); // may be null
+
+					if (fixingAnnotationLimits== 3) { // fixing limit with a mouse drag an drop 
+						if (debug)  System.out.println(" EDITING ANNOTATION POSITION mode="+fixingAnnotationLimits);
+						onFixingAnnotationLimits(ids);
+						return;
+					} else {
+
+						testIfAwordSpanIsSelected(ids);				
+
+						//panel.getBrowser().forceFocus();
+						// extend selection to word boundaries
+						//					String id = panel.getWordSelection(); // may be null
+						//					if (id != null) {
+						//						panel.expandSelectionTo(id);
+						//					}
+						return;
+					}
+				}
+				if (e.button != 1) {
+					if (debug) System.out.println(" NO LEFT");
+					//System.out.println("not a left click");
+					return;
+				}
+				if ((e.time-t) > 200) {
+					if (debug) System.out.println(" LONG");
+					//System.out.println("not a short click");
+					return;
+				}
+
+				String[] ids = panel.getWordSelection(); // may be null
+
+				if (fixingAnnotationLimits > 0) {
+					if (debug)  System.out.println(" EDITING ANNOTATION POSITION mode="+fixingAnnotationLimits);
+					onFixingAnnotationLimits(ids);
+					return;
+				}
+
+				if (ids == null) { // clear selection
+					if (debug)  System.out.println(" NO WORD SELECTION");
+					navigationField.setSelectionIndex(0); // clear selection
+					return;
+				}
+
+				org.txm.searchengine.cqp.corpus.Corpus c = UnitToolbar.this.editor.getCorpus();
+
+				try {
+					if (debug)  System.out.println(" HIGHLIGHTING ANNOT IF ANY AT "+ids[0]);
+					tryHighlightingWord(ids[0],c );
+				} catch (Exception ex) {
+					ex.printStackTrace();
+				}
+			}
+		};
+		return editorMouseListener;
+	}
+
+	protected void testIfAwordSpanIsSelected() {
+		EditionPanel panel = editor.getEditionPanel(0);
+		if (panel == null) return;
+		String[] ids = panel.getWordSelection(); // may be null
+		testIfAwordSpanIsSelected(ids);
+	}
+
+	protected void testIfAwordSpanIsSelected(String[] ids) {
+		if (ids != null && typeCombo.getItemCount() > 1  && typeCombo.getEnabled() ) {
+			//System.out.println("ids:"+Arrays.toString(ids));
+			if (navigationField.getSelectionIndex() > 0) {
+				deleteButton.setEnabled(true);
+				editLeftButton.setEnabled(true);
+				editButton.setEnabled(true);
+				editRightButton.setEnabled(true);
+				//drop_b.setEnabled(true);
+			}
+
+			createButton.setEnabled(ids != null);
+		}	
+	}
+
+
+
+	protected void onFixingAnnotationLimits(String[] ids) {
+
+		if (ids == null || ids.length == 0) { System.out.println("You must select a word. Try again!");return; }
+
+		boolean uniteFixed = false;
+		int i = navigationField.getSelectionIndex();
+		if (i > 0) {
+			Unite unite = unites[i-1];
+
+			try {
+				uniteFixed = updateUniteLimits(unite, ids, fixingAnnotationLimits);
+			} catch (CqiClientException e1) {
+				System.out.println("An error occured when updating unit limits with id="+ids[0]);
+				Log.printStackTrace(e1);
+			}
+
+			editButton.setSelection(false);
+			editLeftButton.setSelection(false);
+			editRightButton.setSelection(false);
+			fixingAnnotationLimits = 0;
+			typeCombo.setEnabled(true);
+			searchButton.setEnabled(true);
+			navigationField.setEnabled(true);
+			createButton.setEnabled(true);
+			deleteButton.setEnabled(true);
+
+			if (uniteFixed) {
+				//button.setEnabled(analecCorpus.isModifie());
+				reloadIdentifiants();
+				highlightType();
+				//highlightUnite(unite, true);
+				navigationField.setSelectionIndex(i);
+				//updateUniteView(unite); // start-end may have changed
+				return;
+			}
+		}
+	}
+
+
+
+	public KeyListener getEditorKeyListener() {
+		if (editorKeyListener != null) return editorKeyListener;
+		editorKeyListener = new KeyListener() {
+
+			@Override
+			public void keyPressed(KeyEvent e) { }
+
+			@Override
+			public void keyReleased(KeyEvent e) {
+				//System.out.println("Key: "+e.keyCode);	
+				//				if (((e.stateMask & SWT.SHIFT) == SWT.SHIFT) && ((e.stateMask & SWT.CTRL) == SWT.CTRL)) {
+				//					if (e.keyCode == SWT.ARROW_RIGHT) {
+				//						int i = navigationField.getSelectionIndex();
+				//						if (i > 0) {
+				//							Unite u = unites[i-1];
+				//							if (u.getFin() < maxCorpusPosition) {
+				//								u.setDeb(u.getDeb()+1);
+				//								u.setFin(u.getFin()+1);
+				//								highlightUnite(u);
+				//							}
+				//						}
+				//					} else if (e.keyCode == SWT.ARROW_LEFT) {
+				//						int i = navigationField.getSelectionIndex();
+				//						if (i > 0) {
+				//							Unite u = unites[i-1];
+				//							if (u.getDeb() > 0) {
+				//								u.setDeb(u.getDeb()-1);
+				//								u.setFin(u.getFin()-1);
+				//								highlightUnite(u);
+				//							}
+				//						}
+				//					}
+				//				} else 
+				if (((e.stateMask & SWT.CTRL) == SWT.CTRL)) {
+					if (e.keyCode == SWT.SPACE) { 
+						int i = navigationField.getSelectionIndex();
+						if (i > 0) {
+							onEditButtonSelected(null);
+						}
+					} else if (e.keyCode == SWT.ARROW_UP) {
+						selectPrevious();
+					} else if (e.keyCode == SWT.ARROW_DOWN) {
+						selectNext();
+					} else if (e.keyCode == SWT.PAGE_UP) {
+						select10Previous();
+					} else if (e.keyCode == SWT.PAGE_DOWN) {
+						select10Next();
+					} else if (e.keyCode == SWT.END) {
+						selectLast();
+					} else if (e.keyCode == SWT.HOME) {
+						selectFirst();
+					}
+					//				} else if (((e.stateMask & SWT.SHIFT) == SWT.SHIFT)) {
+					//					if (e.keyCode == SWT.ARROW_RIGHT) {
+					//						int i = navigationField.getSelectionIndex();
+					//						if (i > 0) {
+					//							Unite u = unites[i-1];
+					//							if (u.getFin() < maxCorpusPosition) {
+					//								u.setFin(u.getFin()+1);
+					//								highlightUnite(u);
+					//							}
+					//						}
+					//					} else if (e.keyCode == SWT.ARROW_LEFT) {
+					//						int i = navigationField.getSelectionIndex();
+					//						if (i > 0) {
+					//							Unite u = unites[i-1];
+					//							if (u.getDeb() > 0) {
+					//								u.setDeb(u.getDeb()-1);
+					//								highlightUnite(u);
+					//							}
+					//						}
+					//					}
+				} else {
+					if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { 
+						onCreateButtonSelected(null);
+					} else if (e.keyCode == SWT.DEL) { 
+						int i = navigationField.getSelectionIndex();
+						if (i > 0) {
+							onDeleteComboSelected(null);
+						}
+					}
+				}
+			}
+		};
+		return editorKeyListener;
+	}
+
+	public MenuListener getMenuListener() {
+
+		if (menuListener != null) return menuListener;
+
+		this.menuListener = new MenuListener() {
+
+			HashSet<MenuItem> entries = new HashSet<MenuItem>();
+
+			@Override
+			public void menuHidden(MenuEvent e) { }
+
+			@Override
+			public void menuShown(MenuEvent e) {
+
+				EditionPanel panel = editor.getEditionPanel(0);
+				if (panel == null) return;
+				Menu menu = panel.getBrowser().getMenu();
+
+				for (MenuItem item : entries) item.dispose(); 
+
+				String[] ids = panel.getWordSelection();
+				//System.out.println("Word under mouse: "+id);
+				if (ids != null && ids.length > 0) {
+					int[] startend = getSelectionStartEndWordPositions(); // get the word start end positions
+					ArrayList<Unite> unitEntries = new ArrayList<Unite>(); // stores units  covering the word
+					ArrayList<Integer> noEntries = new ArrayList<Integer>(); // stores units  covering the word
+					int i = 1;
+					for (Unite unit : unites) {
+						if (unit.getDeb() > startend[0]) break; // don't go further
+						if (unit.getFin() < startend[0]) continue;
+						unitEntries.add(unit);
+						noEntries.add(i);
+						i++;
+					}
+
+					if (unitEntries.size() > 0) {
+						MenuItem item = new MenuItem(menu, SWT.SEPARATOR);
+						entries.add(item);
+					}
+
+					for (i = 0 ; i < unitEntries.size() ; i++) {
+						final Unite unit = unitEntries.get(i);
+						final Integer unitNo = Arrays.binarySearch(unites, unit)+1;
+
+						MenuItem item = new MenuItem(menu, SWT.NONE);
+						AbstractCqiClient CQI = CQPEngine.getCqiClient();
+						try {
+							if (unit.getDeb() == unit.getFin()) {
+								String[] firstWords = CQI.cpos2Str(maincorpus.getWordProperty().getQualifiedName(), new int[]{unit.getDeb()});
+								item.setText("Select "+unit.getType()+"-"+unitNo+ ":"+firstWords[0]);
+							} else {
+								String[] firstWords = CQI.cpos2Str(maincorpus.getWordProperty().getQualifiedName(), new int[]{unit.getDeb(), unit.getDeb()+1});
+								item.setText("Select "+unit.getType()+"-"+unitNo+ "="+firstWords[0]+" "+firstWords[1]+"...");
+							}
+						} catch (Exception e1) {
+							e1.printStackTrace();
+						}
+						item.addSelectionListener(new SelectionListener() {
+							@Override
+							public void widgetDefaultSelected(SelectionEvent e) { }
+							@Override
+							public void widgetSelected(SelectionEvent e) {
+								selectUniteInIdentifants(unit);
+							}
+						});
+						entries.add(item);
+					}
+				}
+			}
+		};
+
+		return menuListener;
+	}
+
+	public String uniteToWords(Unite unit) {
+		AbstractCqiClient CQI = CQPEngine.getCqiClient();
+		String[] firstWords = null;
+		try {
+			if (unit.getDeb() == unit.getFin()) {
+				firstWords = CQI.cpos2Str(maincorpus.getWordProperty().getQualifiedName(), new int[]{unit.getDeb()});
+			} else {
+				firstWords = CQI.cpos2Str(maincorpus.getWordProperty().getQualifiedName(), new int[]{unit.getDeb(), unit.getDeb()+1});
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return StringUtils.join(firstWords, " ");
+	}
+
+	protected int[] getSelectionStartEndWordPositions() {
+		EditionPanel panel = UnitToolbar.this.editor.getEditionPanel(0);
+		String text_name = panel.getEdition().getText().getName();
+		String[] sel = panel.getWordSelection();
+		if (sel == null) {
+			Log.info("No selection found. Aborting.");
+			return null;
+		}
+		//System.out.println("Selection="+sel);
+		try {
+			return getStartEndWordPositions(maincorpus, sel, text_name);
+		} catch (CqiClientException e1) {
+			e1.printStackTrace();
+		}
+		return null;
+	}
+
+	protected int[] getStartEndWordPositions(MainCorpus c, String[] ids, String text_name) throws CqiClientException {
+		//System.out.println("IDS="+Arrays.toString(ids));
+		Query query = new Query("[_.text_id=\""+text_name+"\" & id=\""+StringUtils.join(ids, "|")+"\"]");
+		QueryResult result = c.query(query, "TMP", false);
+		List<Match> matches = result.getMatches();
+		int start, end;
+		//		try {
+		//			int[] indexes = Toolbox.getCqiClient().str2Id(c.getProperty("id").getQualifiedName(), ids);
+		//			int[] positions = Toolbox.getCqiClient().id2Cpos(c.getProperty("id").getQualifiedName(), indexes);
+		//		
+		//		} catch (Exception e) {
+		//			
+		//		}
+		if (matches.size() == 0) {
+			System.out.println("Error: QueryResult matches size is "+matches.size()+" query was "+query);
+			return null;
+		} else {
+			start = matches.get(0).getStart();
+			end = matches.get(matches.size()-1).getStart();
+		}
+		result.drop();
+		return new int[]{start, end};
+	}
+
+	protected void highlightType() {
+		if (unites == null) return;
+
+		int n2 = 0;
+		for (int i = 0 ; i < unites.length ; i++) {
+			for (int p = unites[i].getDeb() ; p <= unites[i].getFin() ; p++) {
+				n2++;
+			}
+		}
+		int allpositions[] = new int[n2];
+		n2 = 0;
+		for (int i = 0 ; i < unites.length ; i++) {
+			for (int p = unites[i].getDeb() ; p <= unites[i].getFin() ; p++) {
+				allpositions[n2++] = p;
+			}
+		}
+
+		try {
+			if (previousSelectedTypeUnitIDS != null) {
+				editor.removeHighlightWordsById(highlighted_unit_color, previousSelectedTypeUnitIDS);
+				editor.removeFontWeightWordsById(previousSelectedTypeUnitIDS);
+				previousSelectedTypeUnitIDS = null; // release memory
+			}
+			String ids2[] = CQPEngine.getCqiClient().cpos2Str(maincorpus.getProperty("id").getQualifiedName(), allpositions);
+			previousSelectedTypeUnitIDS = Arrays.asList(ids2);
+
+			editor.addHighlightWordsById(highlighted_unit_color, previousSelectedTypeUnitIDS);
+			editor.updateWordStyles();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Highlight a unit and don't focus it
+	 * 
+	 * @param unite
+	 */
+	private void highlightUnite(Unite unite) {
+		highlightUnite(unite, true);
+	}
+
+	/**
+	 * Highlight a unit and don't focus it
+	 * 
+	 * @param unite
+	 * @param focus if set the edition will focus ONE TIME on the unit
+	 */
+	private void highlightUnite(Unite unite, boolean focus) {
+		int start = unite.getDeb();
+		int end = unite.getFin();
+	//	System.out.println("HU: start="+start+" end="+end+" -> "+(end-start+1));
+		int len = end-start+1;
+		if (len < 0) {
+			System.out.println("Error: can not highlight unit="+unite+": start > end.");
+			return;
+		}
+		int positions [] = new int[len]; // build the positions array for CQP
+		int n = 0;
+		for (int p = start ; p <= end ; p++) {
+			positions[n++] = p;
+		}
+
+		try {
+			if (previousSelectedUnitIDS != null) { // remove previous highlighted words
+				editor.removeHighlightWordsById(selected_unit_color, previousSelectedUnitIDS);
+				editor.removeFontWeightWordsById(previousSelectedUnitIDS);
+				previousSelectedUnitIDS = null; // release memory
+			}
+
+			String ids[] = CQPEngine.getCqiClient().cpos2Str(maincorpus.getProperty("id").getQualifiedName(), positions);
+			//System.out.println("Highlight words with ids="+Arrays.toString(ids));
+
+			positions = new int[]{positions[0]};
+			Property text_id = maincorpus.getStructuralUnit("text").getProperty("id");
+			int[] text_strucs = CQPEngine.getCqiClient().cpos2Struc(text_id.getQualifiedName(), positions);
+			String[] text_ids = CQPEngine.getCqiClient().struc2Str(text_id.getQualifiedName(), text_strucs);
+
+			String firstWordId = ids[0];
+			String firstWordTextId = text_ids[0];
+
+			EditionPanel panel = editor.getEditionPanel(0);
+			Edition e = panel.getEdition();
+			org.txm.objects.Corpus corpus = e.getText().getCorpus();
+			//System.out.println("firstWordTextId="+firstWordTextId);
+			Text newText = corpus.getText(firstWordTextId); // get the new text
+			//System.out.println("positions="+Arrays.toString(positions));
+			//System.out.println("firstWordId="+firstWordId);
+			//System.out.println("firstWordTextId="+firstWordTextId);
+			//System.out.println("newText="+newText+" e="+e);
+			Edition newEdition = newText.getEdition(e.getName()); // get the edition of the new text
+			Page p = newEdition.getPageForWordId(firstWordId); // find out the page containing the word
+			//System.out.println("page="+p+" current page="+panel.getCurrentPage());
+			
+			previousSelectedUnitIDS = Arrays.asList(ids);
+			editor.addHighlightWordsById(selected_unit_color, previousSelectedUnitIDS);
+			editor.addFontWeightWordsById(EditionPanel.WEIGHT_BOLD, previousSelectedUnitIDS);
+
+			if (previousSelectedUnitIDS.size() > 0 && focus) editor.setFocusedWordID(previousSelectedUnitIDS.get(0));
+			//System.out.println("Word page= "+p+" current="+panel.getCurrentPage());
+			if (panel.getCurrentText() != newText) { // text changed
+				//System.out.println("TEXT CHANGED");
+				editor.setText(newText, false); // don't refresh right now
+				editor.goToPage(p.getName());
+			} else if (panel.getCurrentPage() != p) { // do we need to change page ?
+				//System.out.println("PAGE CHANGED");
+				editor.goToPage(p.getName());
+			} else { // just reload the page to highlight words
+				//System.out.println("NO CHANGE");
+				editor.updateWordStyles();
+			}
+		} catch (Exception e1) {
+			e1.printStackTrace();
+		}
+	}
+
+	protected void onCreateButtonSelected(SelectionEvent e) {
+		//System.out.println("onCreateButtonSelected");
+		int[] startend = getSelectionStartEndWordPositions();
+		if (startend != null) {
+			Log.info("Creating unit with start="+startend[0]+" end="+startend[1]);
+			Unite unite = UnitToolbar.this.vue.getCorpus().addUniteSaisie(typeCombo.getText(), startend[0], startend[1]);
+			Structure structure =  UnitToolbar.this.analecCorpus.getStructure();
+			for (String prop : unite.getProps().keySet())
+				unite.getProps().put(prop, structure.getValeurParDefaut(unite.getClass(), unite.getType(), prop));
+
+			reloadIdentifiants();
+			selectUniteInIdentifants(unite);
+			highlightUnite(unite, true);
+			int i = typeCombo.getSelectionIndex();
+			if (i > 0) {
+				highlightType();
+			}
+			deleteButton.setEnabled(true);
+			editLeftButton.setEnabled(true);
+			editButton.setEnabled(true);
+			editRightButton.setEnabled(true);
+			//drop_b.setEnabled(true);
+			updateUniteView(unite);
+			editor.fireIsDirty();
+		}
+	}
+
+	protected void onDeleteComboSelected(SelectionEvent e) {
+		int i = navigationField.getSelectionIndex();
+		if (i <= 0) return;
+		//System.out.println("Delete unite at i="+i);
+		Unite unite = unites[i-1];
+
+		String id = navigationField.getText();
+
+		ConfirmDialog dialog = new ConfirmDialog(Display.getCurrent().getActiveShell(), "org.txm.analec.delete", "Delete unit "+id, "Do you really want to delete unit "+id+" ?");
+		if (dialog.open() == ConfirmDialog.CANCEL) return;
+
+		//System.out.println("unite "+unite.toString());
+		UnitToolbar.this.vue.getCorpus().supUnite(unite);
+		reloadIdentifiants();
+
+		i = typeCombo.getSelectionIndex();
+		if (i > 0) {
+			highlightType();
+		}
+		editor.fireIsDirty();
+	}
+
+	protected void onEditButtonSelected(SelectionEvent e) {
+		onEditButtonSelected(e, 3);
+	}
+
+	protected void onEditButtonSelected(SelectionEvent e, int mode) {
+		if (mode == 0) { // select unit, select words, click the edit button -> deprecated
+			int i = navigationField.getSelectionIndex();
+			if (i == -1) return;
+			//System.out.println("Delete unite at i="+i);
+			Unite unite = unites[i-1];
+			int[] startend = getSelectionStartEndWordPositions();
+			if (startend != null) {
+				analecCorpus.modifBornesUnite(unite, startend[0], startend[1]);
+				reloadIdentifiants();
+				highlightUnite(unite, false);
+				updateUniteView(unite);
+			}
+		} else {
+			if (fixingAnnotationLimits > 0) { 
+				System.out.println("Aborting annotation limit update");
+
+				typeCombo.setEnabled(true);
+				searchButton.setEnabled(true);
+				navigationField.setEnabled(true);
+				createButton.setEnabled(true);
+				deleteButton.setEnabled(true);
+				fixingAnnotationLimits = 0;
+			} else {
+				typeCombo.setEnabled(false);
+				searchButton.setEnabled(false);
+				navigationField.setEnabled(false);
+				createButton.setEnabled(false);
+				deleteButton.setEnabled(false);
+				fixingAnnotationLimits = mode;
+			}
+		}
+		editor.fireIsDirty();
+	}
+
+	/**
+	 * called when the NavigationField changed its selection
+	 * @param e
+	 */
+	public void onIdentifiantComboSelected(SelectionEvent e) {
+		Log.info("Identifiants SelectionListener: "+navigationField.getSelectionIndex());
+		int i = navigationField.getSelectionIndex();
+		if (i <= 0) {
+			if (previousSelectedUnitIDS != null) {
+				editor.removeHighlightWordsById(selected_unit_color, previousSelectedUnitIDS);
+				editor.removeFontWeightWordsById(previousSelectedUnitIDS);
+				previousSelectedUnitIDS = null; // release memory
+			}
+			highlightType();
+			createButton.setEnabled(false);
+			deleteButton.setEnabled(false);
+			editLeftButton.setEnabled(false);
+			editButton.setEnabled(false);
+			editRightButton.setEnabled(false);
+			//drop_b.setEnabled(false);
+			//navigationField.setSelectionIndex(i);
+		} else {
+			createButton.setEnabled(false);
+			deleteButton.setEnabled(true);
+			editLeftButton.setEnabled(true);
+			editButton.setEnabled(true);
+			editRightButton.setEnabled(true);
+			//drop_b.setEnabled(true);
+			//System.out.println("i="+i);
+			Unite unite = unites[i-1];
+			//System.out.println("unite="+unite);
+			//System.out.println("unite str="+uniteToWords(unite));
+			highlightUnite(unite, true);
+
+			updateUniteView(unite);
+			deleteButton.setEnabled(true);
+			editLeftButton.setEnabled(true);
+			editButton.setEnabled(true);
+			editRightButton.setEnabled(true);
+			//drop_b.setEnabled(true);
+		}
+	}
+
+	protected void onTypecomboSelected(SelectionEvent e) {
+		Log.info("Types SelectionListener: "+typeCombo.getSelectionIndex());
+		reloadIdentifiants();
+
+		if (typeCombo.getSelectionIndex() > 0) {
+			//String type = unitesAVoir[typeCombo.getSelectionIndex()-1];
+			highlightType();
+			searchButton.setEnabled(true);
+		} else {
+			clearHighlight();
+			searchButton.setEnabled(false);
+		}
+
+		createButton.setEnabled(false);
+		deleteButton.setEnabled(false);
+		editButton.setEnabled(false);
+		//drop_b.setEnabled(false);
+	}
+
+	/**
+	 * reload the identifiants combo
+	 * 
+	 * @param unite the unite to select, may be null
+	 */
+	public void reloadIdentifiants() {
+		Log.info("Reloading identifiants combo values.");
+		String type0 = typeCombo.getText();
+		unites = vue.getUnitesAVoir(type0);
+		String[] identifiants = vue.getIdUnites(type0, unites);
+		navigationField.setIdentifiants(identifiants, type0);
+
+		//		String[] items = new String[identifiants.length +1];
+		//		System.arraycopy(identifiants, 0, items, 1, identifiants.length);
+		//		//System.out.println("Identifiants: "+Arrays.toString(identifiants));
+		//		items[0] = "< identifiant >";
+		//		identifiantCombo.setItems(items);
+		navigationField.setSelectionIndex(0);
+		//identifiantCombo.layout();
+	}
+	//		reloadNumbers();
+
+	public void reloadUnits() {
+
+		typesUnitesAVoir = vue.getTypesUnitesAVoir();
+		String[] items = new String[typesUnitesAVoir.length +1];
+		System.arraycopy(typesUnitesAVoir, 0, items, 1, typesUnitesAVoir.length);
+		items[0] = "< type d'unité >";
+		typeCombo.setItems(items);
+		if (items.length > 0) {
+			typeCombo.select(0);
+		}
+		typeCombo.layout();
+
+		onTypecomboSelected(null);
+	}
+
+	protected void selectUniteInIdentifants(Unite unite) {
+		for (int i = 0 ; i < unites.length ; i++) {
+			//System.out.println("VS "+unites[i]);
+			if (unites[i] == unite) {
+				navigationField.setSelectionIndex(i+1);
+				return; // no need to go further
+			}
+		}
+	}
+
+	public void setEnable(boolean enable) {
+		l.setEnabled(enable);
+		typeCombo.setEnabled(enable);
+		searchButton.setEnabled(enable);
+		navigationField.setEnabled(enable);
+		createButton.setEnabled(enable);
+		deleteButton.setEnabled(enable);
+		editButton.setEnabled(enable);
+		editLeftButton.setEnabled(enable);
+		editRightButton.setEnabled(enable);
+		//drop_b.setEnabled(enable);
+	}
+
+	@Override
+	public void traiterEvent(Message e) {
+		if (this.isDisposed()) return;
+
+		if (e.getType().equals(TypeMessage.MODIF_STRUCTURE)) {
+			//System.out.println("UnitToolbar.traiterEvent: Update toolbar ");
+			UnitToolbar.this.getDisplay().syncExec(new Runnable() {
+				@Override
+				public void run() {
+					setEnable(!analecCorpus.isVide());
+					//reloadUnits();
+				}
+			});
+		} else if (e.getType().equals(TypeMessage.MODIF_ELEMENT)) {
+			//System.out.println("UnitToolbar.traiterEvent: Update toolbar ");
+			UnitToolbar.this.getDisplay().syncExec(new Runnable() {
+				@Override
+				public void run() {
+					//reloadUnits();
+				}
+			});
+		}
+	}
+
+	protected void tryHighlightingWord(String id, org.txm.searchengine.cqp.corpus.Corpus c) throws CqiClientException {
+		EditionPanel panel = editor.getEditionPanel(0);
+		if (panel == null) return;
+		if (id != null) {
+
+		}
+		QueryResult r = c.query(new Query("[_.text_id=\""+panel.getEdition().getText().getName()+"\" & id=\""+id+"\"]"), "TMP", false);
+		List<Match> matches = r.getMatches();
+		if (matches.size() == 0) {
+			System.out.println("Error no word found for id="+id);
+			return;
+		}
+		int start = matches.get(0).getStart();
+		//System.out.println("start="+start);
+		r.drop();
+		int i = 0;
+		ArrayList<Integer> matching_units = new ArrayList<Integer>();
+		for (Unite u : unites) {
+			if (u.getDeb() <= start &&  start <= u.getFin()) {
+				matching_units.add(i);
+			} else if (u.getDeb() > start) { // no need to search further
+				continue;
+			}
+			i++;
+		}
+
+		if (matching_units.size() > 0) {
+			// get index in matching_units of the current unit if any
+			int iUnite = matching_units.indexOf(navigationField.getSelectionIndex()-1);
+
+			if (iUnite == -1) iUnite = 0; // current unit is not present, take the first in matching_units
+			else iUnite = (iUnite+1)%matching_units.size(); // take the next unit in matching_units
+
+			iUnite = matching_units.get(iUnite); // get the real unit position in 'unites'
+			navigationField.setSelectionIndex(iUnite+1); // call onIndentifiantComboChanged(...)
+
+			return;
+		}
+
+		panel.expandSelectionTo(id);
+		navigationField.setSelectionIndex(0);
+	}
+
+	protected boolean updateUniteLimits(Unite unite, String[] ids, int mode) throws CqiClientException {
+
+		EditionPanel panel = UnitToolbar.this.editor.getEditionPanel(0);
+		String text_name = panel.getEdition().getText().getName();
+
+		int[] startend = getStartEndWordPositions(maincorpus, ids, text_name);
+		if (startend == null) return false;
+
+		int pos = startend[0];
+		Log.warning("Updating annotation limits: "+unite.getDeb()+" -> "+unite.getFin()+" with word id="+ids+" with pos="+pos);
+
+		if (mode == 1) { // left
+			analecCorpus.modifBornesUnite(unite, pos, unite.getFin());
+		} else if (mode == 2) { // right
+			analecCorpus.modifBornesUnite(unite, unite.getDeb(), pos);
+		} else if (mode == 3) { // choose using distance
+			analecCorpus.modifBornesUnite(unite, startend[0], startend[1]);
+		}
+
+		return true;
+	}
+
+	protected void updateUniteView(Unite unite) {
+		ElementPropertiesView view = ElementPropertiesView.openView();
+		if (view != null) view.loadElement(UnitToolbar.this.analecCorpus, unite, this);
+	}
+
+	public void selectNext() {
+		int i = navigationField.selectNext();
+	}
+
+	public void selectPrevious() {
+		int i = navigationField.selectPrevious();
+	}
+
+	@Override
+	public void selectFirst() {
+		int i = navigationField.selectFirst();
+	}
+
+	@Override
+	public void select10Previous() {
+		int i = navigationField.select10Previous();
+	}
+
+	@Override
+	public void select10Next() {
+		int i = navigationField.select10Next();
+	}
+
+	@Override
+	public void selectLast() {
+		int i = navigationField.selectLast();
+	}
+
+	@Override
+	public void select(Element currentElement) {
+		if (currentElement.getClass() == Unite.class) {
+			int i = Arrays.binarySearch(unites, currentElement);
+			if (i >= 0) navigationField.setSelectionIndex(i+1);
+		}
+	}
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/UnitToolbar.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/SchemaToolbar.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/SchemaToolbar.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/SchemaToolbar.java	(revision 481)
@@ -0,0 +1,956 @@
+package org.txm.analec.toolbar;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.MenuListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.txm.analec.toolbarbutton.StartButton;
+import org.txm.analec.view.ElementPropertiesView;
+import org.txm.analec.view.ElementSearchView;
+import org.txm.analec.widgets.NavigationField;
+import org.txm.objects.Edition;
+import org.txm.objects.Page;
+import org.txm.objects.Text;
+import org.txm.rcp.IImageKeys;
+import org.txm.rcp.swt.dialog.ConfirmDialog;
+import org.txm.rcp.synoptic.editor.EditionPanel;
+import org.txm.rcp.synoptic.editor.SynopticEditionEditor;
+import org.txm.searchengine.cqp.CQPEngine;
+import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
+import org.txm.searchengine.cqp.corpus.Property;
+import org.txm.searchengine.cqp.corpus.QueryResult;
+import org.txm.searchengine.cqp.corpus.query.Match;
+import org.txm.searchengine.cqp.corpus.query.Query;
+import org.txm.utils.logger.Log;
+
+import visuAnalec.Message;
+import visuAnalec.Message.TypeMessage;
+import visuAnalec.donnees.Corpus;
+import visuAnalec.donnees.Corpus.CorpusListener;
+import visuAnalec.elements.Element;
+import visuAnalec.elements.Schema;
+import visuAnalec.elements.Unite;
+import visuAnalec.vue.Vue;
+
+public class SchemaToolbar extends AnnotationToolbar implements CorpusListener {
+
+	//	private Button createButton;
+	private Button deleteButton;
+	//	private Button editButton;
+	SynopticEditionEditor editor;
+	private KeyListener editorKeyListener;
+	private MouseListener editorMouseListener;
+	private Label l;
+	private MenuListener menuListener;
+	private List<String> previousSelectedTypeUnitIDS;
+
+	private List<String> previousSelectedUnitIDS;
+	protected boolean startFixingUnitLimit;
+
+	private Schema[] schemas;
+	private Unite[] unites;
+	private String[] schemasAVoir;
+	private Vue vue;
+	private Combo typeCombo;
+	private Button searchButton;
+	private NavigationField navigationField;
+	//	private Combo unitTypeCombo;
+	private NavigationField subNavigationField;
+
+	public SchemaToolbar(Composite toolbarsArea, StartButton button, int style, SynopticEditionEditor syneditor, Corpus analecCorpus, Vue vue) {
+		super(toolbarsArea, button, style);
+		this.editor = syneditor;
+		this.analecCorpus = analecCorpus;
+		analecCorpus.addEventListener(this);
+		this.vue = vue;
+		this.setLayout(new GridLayout(7, false));
+		this.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
+
+		l = new Label(this, SWT.NONE);
+		l.setText("Schéma : ");
+
+		typeCombo = new Combo(this, SWT.NONE|SWT.READ_ONLY);
+		typeCombo.setToolTipText("<type de schémas>");
+		GridData gdata = new GridData(GridData.FILL, GridData.FILL, false, false);
+		gdata.minimumWidth = 100;
+		gdata.widthHint = 100;
+		typeCombo.setLayoutData(gdata);
+		typeCombo.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				onTypeComboSelected(e);
+			}
+		});
+		
+		searchButton = new Button(this, SWT.PUSH);
+		searchButton.setImage(IImageKeys.getImage(IImageKeys.ACTION_SEARCH));
+		searchButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false));
+		searchButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (typeCombo.getSelectionIndex() > 0) {
+					ElementSearchView view = ElementSearchView.openView();
+					view.loadType(SchemaToolbar.this.analecCorpus, Schema.class, typeCombo.getText(), SchemaToolbar.this);
+				}
+			}
+		});
+
+		navigationField = new NavigationField(this, SWT.NONE);
+		gdata = new GridData(GridData.FILL, GridData.FILL, true, false);
+		navigationField.setLayoutData(gdata);
+		navigationField.addListener(SWT.Selection, new Listener() {
+			@Override
+			public void handleEvent(Event event) {
+				onIdentifiantComboSelected(null);
+			}
+		});
+
+		//		l = new Label(this, SWT.NONE);
+		//		l.setText("Unités : ");
+		//		
+		//		unitTypeCombo = new Combo(this, SWT.NONE|SWT.READ_ONLY);
+		//		unitTypeCombo.setToolTipText("<type de schémas>");
+		//		gdata = new GridData(GridData.FILL, GridData.FILL, false, false);
+		//		gdata.minimumWidth = 100;
+		//		gdata.widthHint = 100;
+		//		unitTypeCombo.setLayoutData(gdata);
+		//		unitTypeCombo.addSelectionListener(new SelectionListener() {
+		//			@Override
+		//			public void widgetDefaultSelected(SelectionEvent e) {}
+		//
+		//			@Override
+		//			public void widgetSelected(SelectionEvent e) {
+		//				onUnitTypeComboSelected(e);
+		//			}
+		//		});
+		//		
+		subNavigationField = new NavigationField(this, SWT.NONE);
+		gdata = new GridData(GridData.FILL, GridData.FILL, true, false);
+		subNavigationField.setLayoutData(gdata);
+		subNavigationField.addListener(SWT.Selection, new Listener() {
+			@Override
+			public void handleEvent(Event event) {
+				onUnitComboSelected(null);
+			}
+		});
+		//		createButton = new Button(this, SWT.PUSH);
+		//		createButton.setText("Créer");
+		//		createButton.addSelectionListener(new SelectionListener() {
+		//			@Override
+		//			public void widgetDefaultSelected(SelectionEvent e) {}
+		//
+		//			@Override
+		//			public void widgetSelected(SelectionEvent e) {
+		//				onCreateButtonSelected(e);
+		//			}
+		//		});
+		deleteButton = new Button(this, SWT.PUSH);
+		deleteButton.setText("Supprimer");
+		deleteButton.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				onDeleteComboSelected(e);
+			}
+		});
+		//		editButton = new Button(this, SWT.TOGGLE);
+		//		editButton.setText("Rectifier une borne");
+		//		editButton.addSelectionListener(new SelectionListener() {
+		//			@Override
+		//			public void widgetDefaultSelected(SelectionEvent e) {}
+		//			@Override
+		//			public void widgetSelected(SelectionEvent e) {
+		//				onEditButtonSelected(e);
+		//			}
+		//		});
+		toolbarsArea.layout();
+		toolbarsArea.getParent().layout(true);
+		editor.getEditionArea().layout();
+
+		reloadTypeSchemas(); // reloads ids also
+		reloadIdentifiants();
+
+		editor.updateWordStyles();
+
+		//		createButton.setEnabled(false);
+		deleteButton.setEnabled(false);
+		//		editButton.setEnabled(false);
+
+		ElementPropertiesView.openView();
+	}
+
+	public void clearHighlight() {
+		if (previousSelectedUnitIDS != null) {
+			editor.removeHighlightWordsById(green, previousSelectedUnitIDS);
+			previousSelectedUnitIDS = null; // release memory
+		}
+		if (previousSelectedTypeUnitIDS != null) {
+			editor.removeHighlightWordsById(lightgreen, previousSelectedTypeUnitIDS);
+			previousSelectedTypeUnitIDS = null; // release memory
+		}
+		editor.updateWordStyles();
+
+		//		createButton.setEnabled(false);
+		deleteButton.setEnabled(false);
+		//		editButton.setEnabled(false);
+	}
+
+	public void dispose() {
+		try {
+			analecCorpus.removeEventListener(this);
+		} catch(Exception e) { }
+		super.dispose();
+
+	}
+
+
+	public MouseListener getEditorClickListener() {
+		if (editorMouseListener != null) return editorMouseListener;
+		editorMouseListener = new MouseListener() {
+
+			boolean dblClick = false;
+			boolean debug = false;
+			private int t,x,y;
+
+			@Override
+			public void mouseDoubleClick(MouseEvent e) {
+				if (debug) System.out.println("DOUBLE CLICK");
+				dblClick= true;
+
+				EditionPanel panel = editor.getEditionPanel(0);
+				if (panel == null) return;
+				String[] ids = panel.getWordSelection(); // may be null
+				//System.out.println("word id="+id);
+				//				if (id != null) {
+				//					org.txm.searchengine.cqp.corpus.Corpus c = SchemaToolbar.this.editor.getCorpus();
+				//					try {
+				//						if (debug)  System.out.println(" HIGHLIGHTING ANNOT IF ANY AT "+id);
+				//						tryHighlightingWord(id,c );
+				//					} catch (Exception ex) {
+				//						ex.printStackTrace();
+				//					}
+				//				}
+
+				//				if (id != null && typeCombo.getSelectionIndex() > 0 && typeCombo.getEnabled())
+				//					createButton.setEnabled(true); // there is a text selection in the browser
+			}
+
+			@Override
+			public void mouseDown(MouseEvent e) {
+				if (debug) System.out.println("MOUSE DOWN");
+				dblClick = false;
+				t = e.time;
+				x = e.x;
+				y = e.y;
+			}
+
+			@Override
+			public void mouseUp(MouseEvent e) {
+				if (dblClick) { // doucle click raised by mouseDoubleClick
+					dblClick = false;
+					return; // stop right now ! :-o
+				}
+				if (debug) System.out.println("MOUSE UP");
+				EditionPanel panel = editor.getEditionPanel(0);
+				if (panel == null) return;
+
+				if (typeCombo.getSelectionIndex() <= 0) {
+					//					createButton.setEnabled(false);
+					deleteButton.setEnabled(false);
+					//					editButton.setEnabled(false);
+					return; // nothing to do with annotations
+				}
+
+				// filter click that are not a left simple click (no drag)
+				//System.out.println("click count="+e.count+" button="+e.button+" time="+e.time+" diff="+(e.time-t)+" dist="+(Math.abs(e.x - x) + Math.abs(e.y - y)));
+				if (e.count > 1) {
+					if (debug) System.out.println(" DOUBLE CLICK");
+					//System.out.println("not a simple click");
+					return;
+				}
+
+				if (Math.abs(e.x - x) + Math.abs(e.y - y) > 7) {
+					if (debug) System.out.println(" DRAG");
+
+					String[] ids = panel.getWordSelection(); // may be null
+					if (ids != null && ids.length > 0 && typeCombo.getItemCount() > 1  && typeCombo.getEnabled() ) {
+
+						if (navigationField.getSelectionIndex() > 0 && ids[0] != null) {
+							deleteButton.setEnabled(true);
+							//							editButton.setEnabled(true);
+						}
+						//						
+						//						createButton.setEnabled(id != null);
+					}
+					//panel.getBrowser().forceFocus();
+					// extend selection to word boundaries
+					//					String id = panel.getWordSelection(); // may be null
+					//					if (id != null) {
+					//						panel.expandSelectionTo(id);
+					//					}
+					return;
+				}
+				if (e.button != 1) {
+					if (debug) System.out.println(" NO LEFT");
+					//System.out.println("not a left click");
+					return;
+				}
+				if ((e.time-t) > 150) {
+					if (debug) System.out.println(" LONG");
+					//System.out.println("not a short click");
+					return;
+				}
+
+				String[] ids = panel.getWordSelection(); // may be null
+
+				if (ids == null) { // clear selection
+					if (debug)  System.out.println(" NO WORD SELECTION");
+					//					navigationField.setSelectionIndex(0); // clear selection
+					//					onIdentifiantComboSelected(null);
+					return;
+				}
+
+				org.txm.searchengine.cqp.corpus.Corpus c = SchemaToolbar.this.editor.getCorpus();
+
+				try {
+					if (debug)  System.out.println(" HIGHLIGHTING ANNOT IF ANY AT "+ids[0]);
+					tryHighlightingWord(ids[0],c );
+				} catch (Exception ex) {
+					ex.printStackTrace();
+				}
+			}
+		};
+		return editorMouseListener;
+	}
+
+	public KeyListener getEditorKeyListener() {
+		if (editorKeyListener != null) return editorKeyListener;
+		editorKeyListener = new KeyListener() {
+
+			@Override
+			public void keyPressed(KeyEvent e) { }
+
+			@Override
+			public void keyReleased(KeyEvent e) {
+				//System.out.println("Key: "+e.keyCode);	
+				if (((e.stateMask & SWT.CTRL) == SWT.CTRL)) {
+					if (e.keyCode == SWT.ARROW_UP) {
+						selectPrevious();
+					} else if (e.keyCode == SWT.ARROW_DOWN) {
+						selectNext();
+					}
+				} else {
+					//					if (e.keyCode == SWT.SPACE) { 
+					//						int i = navigationField.getSelectionIndex();
+					//						if (i > 0) {
+					//							onEditButtonSelected(null);
+					//						}
+					//					} else if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { 
+					//						onCreateButtonSelected(null);
+					//					} else if (e.keyCode == SWT.DEL) { 
+					//						int i = navigationField.getSelectionIndex();
+					//						if (i > 0) {
+					//							onDeleteComboSelected(null);
+					//						}
+					//					}
+				}
+			}
+		};
+		return editorKeyListener;
+	}
+
+	public MenuListener getMenuListener() {
+
+		if (menuListener != null) return menuListener;
+
+		this.menuListener = new MenuListener() {
+
+			HashSet<MenuItem> entries = new HashSet<MenuItem>();
+
+			@Override
+			public void menuHidden(MenuEvent e) { }
+
+			@Override
+			public void menuShown(MenuEvent e) {
+
+				EditionPanel panel = editor.getEditionPanel(0);
+				if (panel == null) return;
+				Menu menu = panel.getBrowser().getMenu();
+
+				for (MenuItem item : entries) item.dispose(); 
+
+				int[] startend = getSelectionStartEndWordPositions(); 
+				//System.out.println("Word under mouse: "+id);
+				if (startend != null && startend.length == 2) {
+					// get the word start end positions
+					ArrayList<Unite> unitEntries = new ArrayList<Unite>(); // stores units  covering the word
+					ArrayList<Integer> noEntries = new ArrayList<Integer>(); // stores units  covering the word
+					int i = 1;
+					Unite[] unites = schemas[navigationField.getSelectionIndex()].getUnitesSousjacentes();
+					for (Unite unit : unites) {
+						if (unit.getDeb() > startend[0]) break; // don't go further
+						if (unit.getFin() < startend[0]) continue;
+						unitEntries.add(unit);
+						noEntries.add(i);
+						i++;
+					}
+
+					if (unitEntries.size() > 0) {
+						MenuItem item = new MenuItem(menu, SWT.SEPARATOR);
+						entries.add(item);
+					}
+
+					for (i = 0 ; i < unitEntries.size() ; i++) {
+						final Unite unit = unitEntries.get(i);
+						final Integer unitNo = Arrays.binarySearch(unites, unit)+1;
+
+						MenuItem item = new MenuItem(menu, SWT.NONE);
+						item.setText("Select "+unit.getType()+"-"+unitNo);
+						item.addSelectionListener(new SelectionListener() {
+							@Override
+							public void widgetDefaultSelected(SelectionEvent e) { }
+							@Override
+							public void widgetSelected(SelectionEvent e) {
+								highlightUnite(unit);
+								updatePropertiesView(unit);
+							}
+						});
+						entries.add(item);
+					}
+				}
+			}
+		};
+
+		return menuListener;
+	}
+
+	protected int[] getSelectionStartEndWordPositions() {
+		EditionPanel panel = SchemaToolbar.this.editor.getEditionPanel(0);
+		String text_name = panel.getEdition().getText().getName();
+		String[] sel = panel.getWordSelection();
+		if (sel == null) {
+			Log.info("No selection found. Aborting.");
+			return null;
+		}
+		//System.out.println("Selection="+sel);
+		org.txm.searchengine.cqp.corpus.Corpus c = SchemaToolbar.this.editor.getCorpus();
+		try {
+			return getStartEndWordPositions(c, sel, text_name);
+		} catch (CqiClientException e1) {
+			e1.printStackTrace();
+		}
+		return null;
+	}
+
+	protected int[] getStartEndWordPositions(org.txm.searchengine.cqp.corpus.Corpus c, String[] ids, String text_name) throws CqiClientException {
+		//System.out.println("IDS="+Arrays.toString(ids));
+		Query query = new Query("[_.text_id=\""+text_name+"\" & id=\""+StringUtils.join(ids, "|")+"\"]");
+		QueryResult result = c.query(query, "TMP", false);
+		List<Match> matches = result.getMatches();
+		int start, end;
+		//		try {
+		//			int[] indexes = Toolbox.getCqiClient().str2Id(c.getProperty("id").getQualifiedName(), ids);
+		//			int[] positions = Toolbox.getCqiClient().id2Cpos(c.getProperty("id").getQualifiedName(), indexes);
+		//		
+		//		} catch (Exception e) {
+		//			
+		//		}
+		if (matches.size() == 0) {
+			System.out.println("Error: QueryResult matches size is "+matches.size()+" query was "+query);
+			return null;
+		} else {
+			start = matches.get(0).getStart();
+			end = matches.get(matches.size()-1).getStart();
+		}
+		result.drop();
+		return new int[]{start, end};
+	}
+
+	protected void highlightType() {
+		if (schemas == null) return;
+		if (schemas.length == 0) return;
+
+		for (Schema schema : schemas) {
+			hightlightSchema(schema, false);
+		}
+	}
+
+	protected void highlightSchema(Schema schema) {
+		hightlightSchema(schema, true);
+	}
+
+	protected void hightlightSchema(Schema schema, boolean hightlightFirstUnit) {
+		Unite[] unites = schema.getUnitesSousjacentes();
+
+		if (unites == null) return;
+		if (unites.length == 0) return;
+
+		int n2 = 0;
+		for (int i = 0 ; i < unites.length ; i++) {
+			for (int p = unites[i].getDeb() ; p <= unites[i].getFin() ; p++) {
+				n2++;
+			}
+		}
+		int allpositions[] = new int[n2];
+		n2 = 0;
+		for (int i = 0 ; i < unites.length ; i++) {
+			for (int p = unites[i].getDeb() ; p <= unites[i].getFin() ; p++) {
+				allpositions[n2++] = p;
+			}
+		}
+
+		org.txm.searchengine.cqp.corpus.Corpus c = SchemaToolbar.this.editor.getCorpus();
+		try {
+			if (previousSelectedTypeUnitIDS != null) {
+				editor.removeHighlightWordsById(lightgreen, previousSelectedTypeUnitIDS);
+				previousSelectedTypeUnitIDS = null; // release memory
+			}
+			String ids2[] = CQPEngine.getCqiClient().cpos2Str(c.getProperty("id").getQualifiedName(), allpositions);
+			previousSelectedTypeUnitIDS = Arrays.asList(ids2);
+
+			editor.addHighlightWordsById(lightgreen, previousSelectedTypeUnitIDS);
+			editor.updateWordStyles();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		if (hightlightFirstUnit) highlightUnite(unites[0]);
+	}
+
+	private void highlightUnite(Unite unite) {
+		int start = unite.getDeb();
+		int end = unite.getFin();
+		int positions [] = new int[end-start+1];
+		int n = 0;
+		for (int p = start ; p <= end ; p++) {
+			positions[n++] = p;
+		}
+		org.txm.searchengine.cqp.corpus.Corpus c = SchemaToolbar.this.editor.getCorpus();
+
+		try {
+			if (previousSelectedUnitIDS != null) {
+				editor.removeHighlightWordsById(green, previousSelectedUnitIDS);
+				previousSelectedUnitIDS = null; // release memory
+			}
+
+			String ids[] = CQPEngine.getCqiClient().cpos2Str(c.getProperty("id").getQualifiedName(), positions);
+			//System.out.println("Highlight words with ids="+Arrays.toString(ids));
+
+			positions = new int[]{positions[0]};
+			Property text_id = c.getStructuralUnit("text").getProperty("id");
+			int[] text_strucs = CQPEngine.getCqiClient().cpos2Struc(text_id.getQualifiedName(), positions);
+			String[] text_ids = CQPEngine.getCqiClient().struc2Str(text_id.getQualifiedName(), text_strucs);
+
+			String firstWordId = ids[0];
+			String firstWordTextId = text_ids[0];
+
+			EditionPanel panel = editor.getEditionPanel(0);
+			Edition e = panel.getEdition();
+			org.txm.objects.Corpus corpus = e.getText().getCorpus();
+			Text newText = corpus.getText(firstWordTextId); // get the new text
+			Edition newEdition = newText.getEdition(e.getName()); // get the edition of the new text
+			Page p = newEdition.getPageForWordId(firstWordId); // find out the page containing the word
+
+			previousSelectedUnitIDS = Arrays.asList(ids);
+			editor.addHighlightWordsById(green, previousSelectedUnitIDS);
+
+			//if (previousSelectedUnitIDS.size() > 0)	editor.setFocusedWordID(previousSelectedUnitIDS.get(0));
+			//System.out.println("Word page= "+p+" current="+panel.getCurrentPage());
+			if (panel.getCurrentText() != newText) { // text changed
+				//System.out.println("TEXT CHANGED");
+				editor.setText(newText, false); // don't refresh right now
+				editor.goToPage(p.getName());
+			} else if (panel.getCurrentPage() != p) { // do we need to change page ?
+				//System.out.println("PAGE CHANGED");
+				editor.goToPage(p.getName());
+			} else { // just reload the page to highlight words
+				//System.out.println("NO CHANGE");
+				editor.updateWordStyles();
+			}
+		} catch (Exception e1) {
+			e1.printStackTrace();
+		}
+	}
+
+	//	protected void onCreateButtonSelected(SelectionEvent e) {
+	//		//System.out.println("onCreateButtonSelected");
+	//		int[] startend = getSelectionStartEndWordPositions();
+	//		if (startend != null) {
+	//			Log.info("Creating unit with start="+startend[0]+" end="+startend[1]);
+	//			Unite unite = SchemaToolbar.this.vue.getCorpus().addUniteSaisie(typeCombo.getText(), startend[0], startend[1]);
+	//			Structure structure =  SchemaToolbar.this.analecCorpus.getStructure();
+	//			for (String prop : unite.getProps().keySet())
+	//				unite.getProps().put(prop, structure.getValeurParDefaut(unite.getClass(), unite.getType(), prop));
+	//
+	//			reloadIdentifiants();
+	//			selectUniteInIdentifants(unite);
+	//			highlightUnite(unite);
+	//
+	//			int i = typeCombo.getSelectionIndex();
+	//			if (i > 0) {
+	//				highlightType();
+	//			}
+	//			deleteButton.setEnabled(true);
+	//			editButton.setEnabled(true);
+	//			updateUniteView(unite);
+	//		}
+	//	}
+	//
+	protected void onDeleteComboSelected(SelectionEvent e) {
+		int i = navigationField.getSelectionIndex();
+		if (i <= 0) return;
+		//System.out.println("Delete unite at i="+i);
+		Schema schema = schemas[i-1];
+
+		String id = navigationField.getText();
+
+		ConfirmDialog dialog = new ConfirmDialog(Display.getCurrent().getActiveShell(), "org.txm.analec.delete", "Delete unit "+id, "Do you really want to delete unit "+id+" ?");
+		if (dialog.open() == ConfirmDialog.CANCEL) return;
+
+		//System.out.println("unite "+unite.toString());
+		SchemaToolbar.this.vue.getCorpus().supSchema(schema);
+		reloadIdentifiants();
+		onIdentifiantComboSelected(e);
+
+		i = typeCombo.getSelectionIndex();
+		if (i > 0) {
+			highlightType();
+		}
+	}
+	//
+	//	protected void onEditButtonSelected(SelectionEvent e) {
+	//		if (fixingAnnotationLimits) {
+	//			System.out.println("Aborting annotation limit update");
+	//
+	//			typeCombo.setEnabled(true);
+	//			identifiantCombo.setEnabled(true);
+	//			createButton.setEnabled(true);
+	//			deleteButton.setEnabled(true);
+	//		} else {
+	//			typeCombo.setEnabled(false);
+	//			identifiantCombo.setEnabled(false);
+	//			createButton.setEnabled(false);
+	//			deleteButton.setEnabled(false);
+	//		}
+	//		fixingAnnotationLimits = !fixingAnnotationLimits;
+	//
+	//		//TODO: choose between the 2 fix scenarios
+	//		/*
+	//		int i = navigationField.getSelectionIndex();
+	//		if (i == -1) return;
+	//		//System.out.println("Delete unite at i="+i);
+	//		Unite unite = unites[i+1];
+	//		int[] startend = getSelectionStartEndWordPositions();
+	//		if (startend != null) {
+	//			//System.out.println("Reset unit with start="+startend[0]+" end="+startend[1]);
+	//			unite.setDeb(startend[0]);
+	//			unite.setFin(startend[1]);
+	//			highlightUnite(unite);
+	//			UniteView view = openUniteView();
+	//			if (view != null) view.update();
+	//		}
+	//		 */
+	//	}
+
+	protected void onUnitComboSelected(Object object) {
+		int iSchema = navigationField.getSelectionIndex();
+		if (iSchema > 0) {
+			int iUnite = subNavigationField.getSelectionIndex();
+			if (iUnite > 0) {
+				Schema schema = schemas[iSchema];
+				Unite unite = unites[iUnite];
+			}
+		}
+	}
+
+	protected void onIdentifiantComboSelected(SelectionEvent e) {
+		Log.info("Identifiants SelectionListener: "+navigationField.getSelectionIndex());
+		int i = navigationField.getSelectionIndex();
+		if (i <= 0) {
+			if (previousSelectedUnitIDS != null) {
+				editor.removeHighlightWordsById(green, previousSelectedUnitIDS);
+				previousSelectedUnitIDS = null; // release memory
+			}
+			highlightType();
+			//			createButton.setEnabled(false);
+			deleteButton.setEnabled(false);
+			//			editButton.setEnabled(false);
+		} else {
+			//			createButton.setEnabled(false);
+			deleteButton.setEnabled(true);
+			//			editButton.setEnabled(true);
+			Schema schema = schemas[navigationField.getSelectionIndex()-1];
+			highlightSchema(schema);
+
+
+
+			updatePropertiesView(schema);
+			deleteButton.setEnabled(true);
+			//			editButton.setEnabled(true);
+		}
+	}
+
+	protected void onTypeComboSelected(SelectionEvent e) {
+		Log.info("Types SelectionListener: "+typeCombo.getSelectionIndex());
+		reloadIdentifiants();
+		if (typeCombo.getSelectionIndex() > 0) {
+			//String type = unitesAVoir[typeCombo.getSelectionIndex()-1];
+			highlightType();
+			searchButton.setEnabled(true);
+		} else {
+			clearHighlight();
+			searchButton.setEnabled(false);
+		}
+
+		//		createButton.setEnabled(false);
+		deleteButton.setEnabled(false);
+		//		editButton.setEnabled(false);
+	}
+
+	/**
+	 * reload the identifiants combo
+	 * 
+	 * @param unite the unite to select, may be null
+	 */
+	public void reloadIdentifiants() {
+		Log.info("Reloading identifiants combo values.");
+		String type0 = typeCombo.getText();
+		schemas = vue.getSchemasAVoir(type0);
+		String[] identifiants = vue.getIdSchemas(type0, schemas);
+		navigationField.setIdentifiants(identifiants, type0);
+
+		//		String[] items = new String[identifiants.length +1];
+		//		System.arraycopy(identifiants, 0, items, 1, identifiants.length);
+		//		//System.out.println("Identifiants: "+Arrays.toString(identifiants));
+		//		items[0] = "< identifiant >";
+		//		identifiantCombo.setItems(items);
+		navigationField.setSelectionIndex(0);
+		//identifiantCombo.layout();
+	}
+
+	/**
+	 * reload the identifiants combo
+	 * 
+	 * @param unite the unite to select, may be null
+	 */
+	public void reloadUnites() {
+		Log.info("Reloading unites combo values.");
+		int iSchema = navigationField.getSelectionIndex();
+		if (iSchema <= 0) {
+			subNavigationField.setIdentifiants(new String[0], "");
+			unites = null;
+			return;
+		} else {
+			Schema schema = schemas[iSchema];
+			unites = schema.getUnitesSousjacentes();
+			String[] identifiants = new String[unites.length];
+			for (int i = 0 ; i < unites.length ; i++) {
+				identifiants[i] = vue.getIdElement(unites[i]);
+			}
+			subNavigationField.setIdentifiants(identifiants, "");
+
+			//		String[] items = new String[identifiants.length +1];
+			//		System.arraycopy(identifiants, 0, items, 1, identifiants.length);
+			//		//System.out.println("Identifiants: "+Arrays.toString(identifiants));
+			//		items[0] = "< identifiant >";
+			//		identifiantCombo.setItems(items);
+			subNavigationField.setSelectionIndex(0);
+			//identifiantCombo.layout();
+		}
+	}
+
+	public void reloadTypeSchemas() {
+
+		schemasAVoir = vue.getTypesSchemasAVoir();
+		String[] items = new String[schemasAVoir.length +1];
+		System.arraycopy(schemasAVoir, 0, items, 1, schemasAVoir.length);
+		items[0] = "<type de schéma>";
+		typeCombo.setItems(items);
+		if (items.length > 0) {
+			typeCombo.select(0);
+		}
+		typeCombo.layout();
+
+		onTypeComboSelected(null);
+	}
+
+	protected void selectSchemaInIdentifants(Schema schema) {
+		for (int i = 0 ; i < schemas.length ; i++) {
+			//System.out.println("VS "+unites[i]);
+			if (schemas[i] == schema) {
+				navigationField.setSelectionIndex(i+1);
+				return; // no need to go further
+			}
+		}
+	}
+
+	public void setEnable(boolean enable) {
+		l.setEnabled(enable);
+		typeCombo.setEnabled(enable);
+		//		createButton.setEnabled(enable);
+		deleteButton.setEnabled(enable);
+		//		editButton.setEnabled(enable);
+		navigationField.setEnabled(enable);
+	}
+
+	@Override
+	public void traiterEvent(Message e) {
+		if (this.isDisposed()) return;
+
+		if (e.getType().equals(TypeMessage.MODIF_STRUCTURE)) {
+			//System.out.println("SchemaToolbar.traiterEvent: Update toolbar ");
+			SchemaToolbar.this.getDisplay().syncExec(new Runnable() {
+				@Override
+				public void run() {
+					setEnable(!analecCorpus.isVide());
+					//reloadUnits();
+				}
+			});
+		} else if (e.getType().equals(TypeMessage.MODIF_ELEMENT)) {
+			//System.out.println("SchemaToolbar.traiterEvent: Update toolbar ");
+			SchemaToolbar.this.getDisplay().syncExec(new Runnable() {
+				@Override
+				public void run() {
+					//reloadUnits();
+				}
+			});
+		}
+	}
+
+	protected void tryHighlightingWord(String id, org.txm.searchengine.cqp.corpus.Corpus c) throws CqiClientException {
+		EditionPanel panel = editor.getEditionPanel(0);
+		if (panel == null) return;
+		if (id != null) {
+
+		}
+		QueryResult r = c.query(new Query("[_.text_id=\""+panel.getEdition().getText().getName()+"\" & id=\""+id+"\"]"), "TMP", false);
+		List<Match> matches = r.getMatches();
+		if (matches.size() == 0) {
+			System.out.println("Error no word found for id="+id);
+			return;
+		}
+		int start = matches.get(0).getStart();
+		//System.out.println("start="+start);
+		r.drop();
+		int i = 0;
+		Unite[] unites = schemas[navigationField.getSelectionIndex()].getUnitesSousjacentes();
+		for (Unite u : unites) {
+			if (u.getDeb() <= start &&  start <= u.getFin()) {
+				highlightUnite(u);
+				//			navigationField.setSelectionIndex(i+1);
+				updatePropertiesView(u);
+
+				//				createButton.setEnabled(false);
+				deleteButton.setEnabled(true);
+				//				editButton.setEnabled(true);
+
+				//panel.getBrowser().forceFocus();
+				return;
+			} else if (u.getFin() < start) { // no need to search further
+
+			}
+			i++;
+		}
+
+		panel.expandSelectionTo(id);
+		//	navigationField.setSelectionIndex(0);
+		onIdentifiantComboSelected(null);
+	}
+
+	protected boolean updateUniteLimits(Unite unite, String id) throws CqiClientException {
+
+		String[] ids = {id};
+		org.txm.searchengine.cqp.corpus.Corpus c = SchemaToolbar.this.editor.getCorpus();
+		EditionPanel panel = SchemaToolbar.this.editor.getEditionPanel(0);
+		String text_name = panel.getEdition().getText().getName();
+
+		int[] startend = getStartEndWordPositions(c, ids, text_name);
+		if (startend == null) return false;
+
+		int pos = startend[0];
+		Log.warning("Updating annotation limits: "+unite.getDeb()+" -> "+unite.getFin()+" with word id="+id+" with pos="+pos);
+		if ((pos == unite.getDeb() || pos == unite.getFin()) && (unite.getFin() - unite.getDeb()) == 1) {
+			analecCorpus.modifBornesUnite(unite, pos, pos);
+		} else if (pos <= unite.getDeb()) {
+			analecCorpus.modifBornesUnite(unite, pos, unite.getFin());
+		} else if (pos >= unite.getFin()) {
+			analecCorpus.modifBornesUnite(unite, unite.getDeb(), pos);
+		} else if ((pos - unite.getDeb()) < (unite.getFin() - pos)) {
+			analecCorpus.modifBornesUnite(unite, pos, unite.getFin());
+		} else {
+			analecCorpus.modifBornesUnite(unite, unite.getDeb(), pos);
+		}
+
+		return true;
+	}
+
+	protected void updatePropertiesView(Element element) {
+		ElementPropertiesView view = ElementPropertiesView.openView();
+		if (view != null) view.loadElement(SchemaToolbar.this.analecCorpus, element, this);
+	}
+
+	public void selectNext() {
+		int i = navigationField.selectNext();
+	}
+
+	public void selectPrevious() {
+		int i = navigationField.selectPrevious();
+	}
+
+	@Override
+	public void selectFirst() {
+		int i = navigationField.selectFirst();
+	}
+
+	@Override
+	public void select10Previous() {
+		int i = navigationField.select10Previous();
+	}
+
+	@Override
+	public void select10Next() {
+		int i = navigationField.select10Next();
+	}
+
+	@Override
+	public void selectLast() {
+		int i = navigationField.selectLast();
+	}
+
+	@Override
+	public void select(Element currentElement) {
+		if (currentElement.getClass() == Schema.class) {
+			int i = Arrays.binarySearch(schemas, currentElement);
+			if (i >= 0) navigationField.setSelectionIndex(i+1);
+		}
+	}
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/toolbar/SchemaToolbar.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/analec/AnalecAnnotationReIndexer.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/analec/AnalecAnnotationReIndexer.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/analec/AnalecAnnotationReIndexer.java	(revision 481)
@@ -0,0 +1,145 @@
+package org.txm.analec;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.txm.Toolbox;
+import org.txm.searchengine.cqp.AbstractCqiClient;
+import org.txm.searchengine.cqp.CQPEngine;
+import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
+import org.txm.searchengine.cqp.corpus.MainCorpus;
+import org.txm.searchengine.cqp.corpus.Property;
+import org.txm.searchengine.cqp.serverException.CqiServerError;
+
+import visuAnalec.donnees.Corpus;
+import visuAnalec.elements.Unite;
+
+public class AnalecAnnotationReIndexer {
+	MainCorpus corpus;
+	Corpus analecCorpus;
+	File aafile;
+	public boolean debug = false;
+
+	public AnalecAnnotationReIndexer(MainCorpus corpus, Corpus analecCorpus) {
+		this.corpus = corpus;
+		this.analecCorpus = analecCorpus;
+	}
+
+	public boolean process() throws CqiClientException, IOException, CqiServerError {
+
+		int corpusSize = corpus.getSize();
+
+		String text = analecCorpus.getTexte();
+		int isearch = 0; // the current search start position
+
+		AbstractCqiClient CQI = CQPEngine.getCqiClient();
+		Property word = corpus.getProperty("word");
+
+		int positions[] = new int[corpusSize];
+		for (int i = 0 ; i < corpusSize ; i++) positions[i] = i;
+		
+		int positionsCorrespondances[] = new int[corpusSize];
+		String strs[] = CQI.cpos2Str(word.getQualifiedName(), positions);
+
+		for (int i = 0 ; i < corpusSize ; i++) {
+			int idx = text.indexOf(strs[i], isearch);
+			if (idx < 0) {
+				System.out.println("Error: cannot find word='"+strs[i]+"' (word with position in CQP corpus="+positions[i]+") in text with current carret="+isearch+". Aborting.");
+				
+				System.out.println("Current text slice is (-20, +20 characters): ");
+				System.out.println("* before: "+text.substring(Math.max(0, isearch-20), Math.min(isearch+20, isearch)));
+				System.out.println("* after: "+text.substring(isearch, Math.min(isearch+20, text.length()-1)));
+				
+				return false;
+			}
+			positionsCorrespondances[i] = idx;
+			isearch = idx + strs[i].length();
+		}
+		
+		if (debug) System.out.println(Arrays.toString(positions));
+		if (debug) System.out.println(Arrays.toString(positionsCorrespondances));
+
+		isearch = 0;
+		ArrayList<Unite> unites = analecCorpus.getToutesUnites();
+		if (debug) System.out.println("units not-sorted: ");
+		if (debug) printUnits(unites);
+		Collections.sort(unites, new Comparator<Unite>() {
+			@Override
+			public int compare(Unite o1, Unite o2) {
+				return o1.getDeb() - o2.getDeb();
+			}
+		});
+		if (debug) System.out.println("units sorted: ");
+		if (debug) printUnits(unites);
+		
+		int iunite = 0;
+		for (Unite unite : unites) {
+			if (debug) System.out.println("Updating ");
+			if (debug) printUnite(unite);
+			int start = unite.getDeb();
+			int end = unite.getFin();
+			
+			boolean startFound = false;
+			boolean endFound = false;
+			int i = 0; // or not : unites are sorted by start position, we don't need to browse all words \o/
+			for (; i < positionsCorrespondances.length ; i++) {
+				if (startFound && endFound) break; // no need to go further
+				if (debug) System.out.println("i="+i+" positionsCorrespondances[i]="+positionsCorrespondances[i]);
+				if (!startFound && start < positionsCorrespondances[i]) {
+					unite.setDeb(i-1);
+					startFound = true;
+				}
+				if (!endFound && end <= positionsCorrespondances[i]) {
+					unite.setFin(i-1);
+					endFound = true;
+				}
+			}
+			
+			if (!endFound && i == positionsCorrespondances.length) {
+				unite.setFin(i-1);
+				endFound = true;
+			}
+			if (!startFound && i == positionsCorrespondances.length) {
+				unite.setDeb(i-1);
+				startFound = true;
+			}
+			
+			if (!(startFound && endFound)) {
+				String s = "Error: cannot find words positions for unite of type="+unite.getType()+" and unit carret positions=["+start+", "+end+"]. Aborting";
+				System.out.println(s);
+				
+				System.out.println("5 last found units are: ");
+				for (int j = 4 ; j >= 0 ; j--) {
+					if (iunite-j >= 0) {
+						printUnite(unites.get(iunite-j));
+					}
+				}
+				return false;
+			}
+			//if (i > 0) i--; // restart at previous word
+			iunite++;
+		}
+		if (debug) System.out.println("units updated: ");
+		if (debug) printUnits(unites);
+		return true;
+	}
+	
+	public static void printUnite(Unite unite) {
+		System.out.print(unite.getType()+ "["+unite.getDeb()+", "+unite.getFin()+"]");
+	}
+	
+	public static void printUnits(List<Unite> units) {
+		int i = 0;
+		for (Unite u : units) {
+			if (i > 0) System.out.print(", ");
+			printUnite(u);
+			i++;
+		}
+		System.out.println();
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/analec/AnalecAnnotationReIndexer.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/PremierMaillonMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/PremierMaillonMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/PremierMaillonMacro.groovy	(revision 481)
@@ -0,0 +1,84 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+
+import groovy.transform.Field
+
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+
+import visuAnalec.donnees.Structure;
+import visuAnalec.elements.Unite;
+import visuAnalec.vue.Vue
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="unit_type",usage="", widget="String", required=true, def="Maillon")
+String unit_type
+@Field @Option(name="reset",usage="", widget="Boolean", required=true, def="true")
+boolean reset
+
+if (!ParametersDialog.open(this)) return;
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+Structure structure = analecCorpus.getStructure()
+if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
+	println "Error: corpus structure does not contains unit with name=$unit_type"
+	return
+}
+def props = structure.getUniteProperties(unit_type)
+
+String NEW = "NEW"
+String REF = "REF"
+String YES = "YES"
+String NO = "NO"
+if (!props.contains(NEW)) { // update the structure if needed
+	analecCorpus.ajouterProp(Unite.class, unit_type, NEW);
+	analecCorpus.ajouterVal(Unite.class, unit_type, NEW, "YES");
+	analecCorpus.ajouterVal(Unite.class, unit_type, NEW, "NO");
+}
+
+if (!props.contains(REF)) { // check the unit_type units have the REF property
+	println "Error: $unit_type units have no proprerty named 'REF'"
+	return
+}
+
+int nIgnored = 0; // number of units ignored
+int nYes = 0 // number of "YES" unit set
+int nNo = 0 // number of "NO" unit set
+
+def allRefs = new HashSet<String>() // store the references already seen, allow to set the 'NEW' property to 'YES' or 'NO'
+def units = analecCorpus.getUnites(unit_type)
+units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
+for (Unite unit : units) {
+	def prop = unit.getProp(NEW);
+	def ref = unit.getProp(REF);
+	if (reset || prop == null || prop.length() == 0) {
+		if (allRefs.contains(ref)) {
+			unit.getProps().put(NEW, NO)
+			nNo++
+		} else { // this is the first MENTION of the CHAINE
+			allRefs << ref
+			unit.getProps().put(NEW, YES)
+			nYes++
+		}
+	} else {
+		// nothing to do "NEW" already exists
+		nIgnored++
+	}
+}
+
+println "nIgnored=$nIgnored"
+println "nYes=$nYes"
+println "nNo=$nNo"
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CoefficientStabiliteMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CoefficientStabiliteMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CoefficientStabiliteMacro.groovy	(revision 481)
@@ -0,0 +1,159 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.*
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+import org.apache.commons.lang.StringUtils;
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="schema_type",usage="", widget="String", required=true, def="Coréférence")
+String schema_type
+
+@Field @Option(name="minimum_schema_size", usage="", widget="Integer", required=true, def="3")
+int minimum_schema_size
+
+@Field @Option(name="schema_property_name",usage="", widget="String", required=false, def="")
+String schema_property_name
+
+@Field @Option(name="schema_display_property_name",usage="", widget="String", required=false, def="Nom du référent")
+String schema_display_property_name
+
+@Field @Option(name="schema_property_value",usage="", widget="String", required=false, def=".*")
+String schema_property_value
+
+@Field @Option(name="unit_type",usage="", widget="String", required=false, def="Maillon")
+String unit_type
+
+@Field @Option(name="unit_property_name", usage="", widget="String", required=false, def="Catégorie")
+String unit_property_name
+
+@Field @Option(name="unit_property_value", usage="", widget="String", required=false, def="GN Défini|GN Démonstratif|Nom Propre")
+String unit_property_value
+
+@Field @Option(name="word_property", usage="", widget="StringArray", metaVar="word	lemma	frlemma	frolemma	#forme#", required=false, def="word")
+String word_property
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// Open the parameters input dialog box
+if (!ParametersDialog.open(this)) return;
+// END OF PARAMETERS
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName())
+
+// check Schema parameters
+if (!analecCorpus.getStructure().getSchemas().contains(schema_type)) {
+	println "No schema with name=$schema_type"
+	return;
+} else {
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getSchemaProperties(schema_type);
+		if (!props.contains(schema_property_name)) {
+			println "Schema $schema_type has no property named $schema_property_name"
+			return;
+		}
+	}
+}
+
+// check unit parameters
+if (!analecCorpus.getStructure().getUnites().contains(unit_type)) {
+	println "No unit with name=$unit_type"
+	return;
+} else {
+	if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getUniteProperties(unit_type);
+		if (!props.contains(unit_property_name)) {
+			println "Unit $unit_type has no property named $unit_property_name"
+			return;
+		}
+	}
+}
+
+def CQI = Toolbox.getCqiClient()
+
+def prop = corpus.getProperty(word_property)
+
+def schemas = analecCorpus.getSchemas(schema_type)
+allFormesSet = new HashSet();
+nUnitesGrandTotal = 0;
+def coefs = []
+int n = 1
+for (def schema : schemas) {
+	def formesSet = new HashSet(); // contient toutes les formes du CR courant
+	nUnitesTotal = 0;
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		if (!schema.getProp(schema_property_name).matches(schema_property_value)) {
+			// ignoring this schema
+			continue
+		}
+	}
+	
+	def units = schema.getUnitesSousjacentesNonTriees()
+	def nUnites = units.size();
+	
+	if (nUnites < minimum_schema_size) continue;
+
+	for (def unit : units) {
+	
+		if (unit_type.length() > 0) {
+			if (!unit.getType().equals(unit_type)) {
+				continue
+			}
+		}
+		
+		if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+			if (!unit.getProp(unit_property_name).matches(unit_property_value)) {
+				// ignoring this schema
+				continue
+			}
+		}
+		
+		String forme =  null;
+		if (prop == null) { // word_property is the analec unit property to use
+			forme = unit.getProp(word_property)
+		} else {
+			int[] pos = null;
+			if (unit.getDeb() == unit.getFin()) pos = [unit.getDeb()]
+			else pos = unit.getDeb()..unit.getFin()
+				
+			forme = StringUtils.join(CQI.cpos2Str(prop.getQualifiedName(), pos), " ") // ids is enough
+		}
+		
+		formesSet.add(forme)
+		
+		nUnitesTotal++
+	}
+	if (formesSet.size() == 0) {
+		coef = -1
+	} else {
+		coef = (nUnitesTotal/formesSet.size())
+	}
+	coefs << coef
+	nUnitesGrandTotal += nUnitesTotal;
+	allFormesSet.addAll(formesSet)
+	
+	if (schema_display_property_name != null) {
+		print schema.getProp(schema_display_property_name)
+	} else {
+		print schema_type+"-"+n+" : "
+	}
+	
+	println " ($nUnites units) : $nUnitesTotal selected units / ${formesSet.size()} forms = $coef"
+	n++
+}
+
+return ["result":coefs, "data":["nUnitesTotal":nUnitesGrandTotal, "allFormesSet":allFormesSet], "coef":(nUnitesGrandTotal/allFormesSet.size())]
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/ConcordanceToUnitMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/ConcordanceToUnitMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/ConcordanceToUnitMacro.groovy	(revision 481)
@@ -0,0 +1,92 @@
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+
+import groovy.transform.Field
+
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.concordance.core.functions.*
+import org.txm.concordance.rcp.editors.ConcordanceEditor;
+
+// BEGINNING OF PARAMETERS
+
+@Field @Option(name="unit_type", usage="The unit type to create", widget="String", required=true, def="MENTION")
+def unit_type
+
+@Field @Option(name="create_only_if_new", usage="Create the unit if not already annotated", widget="Boolean", required=true, def="true")
+def create_only_if_new
+
+@Field @Option(name="type", usage="type", widget="String", required=true, def="true")
+def type
+
+@Field @Option(name="value", usage="default value", widget="String", required=true, def="true")
+def value
+
+// END OF PARAMETERS
+
+// get a Concordance from 1) current Concordance editor or 2) CorporaView selection
+Concordance concordance
+if (editor instanceof ConcordanceEditor) {
+	concordance = editor.getConcordance()
+} else if (corpusViewSelection instanceof Concordance) {
+	concordance = corpusViewSelection
+} else {
+	println "You must select a concordance or open a concordance result to run this macro."
+	return false
+}
+
+if (concordance == null) {
+	println "You must compute a concordance before."
+	return
+}
+
+// check the analec corpus is ready
+def corpus = concordance.getCorpus();
+String name = corpus.getMainCorpus().getName()
+if (!AnalecCorpora.isAnnotationStructureReady(name)) {
+	println "Annotation structure is not ready."
+	return
+}
+
+// Open the parameters input dialog box
+if (!ParametersDialog.open(this)) return
+
+// check the corpus structure has the unit_type provided
+def analecCorpus = AnalecCorpora.getCorpus(name)
+if (!analecCorpus.getStructure().getUnites().contains(unit_type)) {
+	println "The corpus structure does not contains unit with type=$unit_type"
+	return;
+}
+
+// browse lines and check 
+def units = analecCorpus.getUnites(unit_type)
+def lines = concordance.getLines()
+int iUnit = 0
+int n = 0
+for (int iLine = 0 ; iLine < lines.size() ; iLine++) { 
+	def line = lines[iLine]
+	def m = line.getMatch()
+	if (create_only_if_new && iUnit < units.size()) { // test only if create_only_if_new == true
+		def unit = null
+		while (iUnit < units.size() && units[iUnit].getDeb() < m.getStart()) {
+			
+		
+		if (iUnit < units.size()) {
+			unit = units[iUnit++]
+			if (unit.getDeb() == m.getStart() && unit.getFin() == m.getEnd()) { // skip and print the line
+				println "skiping line: "+line.getViewRef().toString()+" "+line.keywordToString()
+				// line.getViewRef().toString()
+				// line.leftContextToString()
+				// line.keywordToString()
+				// line.rightContextToString()
+				continue
+			}
+		}
+		}
+	}
+	n++
+	analecCorpus.addUniteSaisie(unit_type, m.getStart(), m.getEnd(), [type:value])
+}
+println "$n $unit_type created."
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/AjoutDefinitudeMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/AjoutDefinitudeMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/AjoutDefinitudeMacro.groovy	(revision 481)
@@ -0,0 +1,110 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.apache.commons.lang.StringUtils;
+import org.kohsuke.args4j.*
+
+import groovy.transform.Field
+
+import org.txm.Toolbox;
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.AbstractCqiClient;
+import org.txm.searchengine.cqp.corpus.*
+
+import visuAnalec.Message.StructureEvent;
+import visuAnalec.Message.TypeModifStructure;
+import visuAnalec.donnees.Structure;
+import visuAnalec.elements.Unite;
+import visuAnalec.vue.Vue
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="unit_type",usage="", widget="String", required=true, def="Maillon")
+String unit_type
+@Field @Option(name="reset",usage="", widget="Boolean", required=true, def="true")
+boolean reset
+
+if (!ParametersDialog.open(this)) return;
+
+MainCorpus corpus = corpusViewSelection
+AbstractCqiClient CQI = Toolbox.getCqiClient();
+def word = corpus.getWordProperty()
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+Structure structure = analecCorpus.getStructure()
+if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
+	println "Error: corpus structure does not contains unit with name=$unit_type"
+	return
+}
+def props = structure.getUniteProperties(unit_type)
+
+String DEFINITUDE = "DEFINITUDE"
+if (!props.contains(DEFINITUDE)) { // update the structure if needed
+	analecCorpus.ajouterProp(Unite.class, unit_type, DEFINITUDE);
+	analecCorpus.ajouterVal(Unite.class, unit_type, DEFINITUDE, "DEFINI");
+	analecCorpus.ajouterVal(Unite.class, unit_type, DEFINITUDE, "INDEFINI");
+	analecCorpus.ajouterVal(Unite.class, unit_type, DEFINITUDE, "DEMONSTRATIF");
+	analecCorpus.ajouterVal(Unite.class, unit_type, DEFINITUDE, "AMBIGU");
+	analecCorpus.ajouterVal(Unite.class, unit_type, DEFINITUDE, "NONE");
+}
+
+int nIgnored = 0 // number of ignored units
+int nModified = 0 // number of modified units
+int nDefini = 0 // number of "DEFINI" units
+int nIndefini = 0 // number of "InDEFINI" units
+int nDemonstratif = 0 // number of "DEMONSTRATIF" units
+int nAmbigu = 0 // number of "AMBIGU" units
+int nNone = 0 // number of "NONE" units
+
+def units = analecCorpus.getUnites(unit_type)
+units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
+for (Unite unit : units) { // process all units
+	
+	def prop = unit.getProp(DEFINITUDE);
+	
+	int[] pos = null
+	if (unit.getDeb() == unit.getFin()) pos = [unit.getDeb()]
+	else pos = (unit.getDeb()..unit.getFin())
+	def form = StringUtils.join(CQI.cpos2Str(word.getQualifiedName(), pos), " ")
+	
+	if (reset || prop == null || prop.length() == 0 || prop.equals("NONE")) {
+		// petits ajouts à faire ? : |(ses\s.+)|(Ses\s.+)|(son\s.+)|(Son\s.+)|(sa\s.+)|(Sa\s.+)|(leurs?\s.+)|(Leurs?\s.+)|(tous\s.+)|(Tous\s.+)|(toutes\s.+)|(Toutes\s.+)
+		if (form =~ /^(le\s.+)|(Les\s.+)|(Le\s.+)|(la\s.+)|(La\s.+)|(l'.+)|(L'.+)|(les\s.+)|(au\s.+)|(Au\s.+)|(aux\s.+)|(Aux\s.+)|(du\s.+)|(Du\s.+)/) {
+			unit.getProps().put(DEFINITUDE, "DEFINI")
+			nDefini++
+		} else if (form =~ /^(un\s.+)|(une\s.+)|(Un\s.+)|(Une\s.+)|(Chaque\s.+)|(chaque\s.+)|(Certains\s.+)|(Certaines\s.+)|(certains\s.+)|(certaines\s.+)|(aucun\s.+)|(aucune\s.+)|(Aucun\s.+)|(Aucunes\s.+)|(Autre\s.+)|(Autre\s.+)|(autres\s.+)|(autre\s.+)|(quelque\s.+)|(quelques\s.+)|(Quelque\s.+)|(Quelques\s.+)/) {
+			unit.getProps().put(DEFINITUDE, "INDEFINI")
+			nIndefini++
+		} else if (form =~ /^(ce\s.+)|(cette\s.+)|(Cette\s.+)|(cet\s.+)|(ces\s.+)|(Ce\s.+)|(Cet\s.+)|(Ces\s.+)/) {
+			unit.getProps().put(DEFINITUDE, "DEMONSTRATIF")
+			nDemonstratif++
+		} else if (form =~ /^(des\s.+)|(de\s.+)|(Des\s.+)|(De\s.+)/) {
+			unit.getProps().put(DEFINITUDE, "AMBIGU")
+			nAmbigu++
+		} else {
+			unit.getProps().put(DEFINITUDE, "NONE")
+			nNone++;
+		}
+		nModified++
+		
+	} else {
+		// nothing to do
+		nIgnored++
+	}
+}
+
+println "nIgnored=$nIgnored"
+println "nModified=$nModified"
+println " nDefini=$nDefini"
+println " nIndefini=$nIndefini"
+println " nDemonstratif=$nDemonstratif"
+println " nAmbigu=$nAmbigu"
+println " nNone=$nNone"
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/SchemaTypesMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/SchemaTypesMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/SchemaTypesMacro.groovy	(revision 481)
@@ -0,0 +1,28 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+
+def schemas = analecCorpus.getTousSchemas()
+def set = new HashMap()
+for (def s : schemas.collect { it.getType() }) {
+	if (!set.containsKey(s)) set[s] = 0;
+	set[s] = set[s] +1
+}
+println "Schemas types: "+set.sort() { it -> set[it]}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CreationRelationsMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CreationRelationsMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CreationRelationsMacro.groovy	(revision 481)
@@ -0,0 +1,74 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+
+import groovy.transform.Field
+
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+
+import visuAnalec.donnees.Structure;
+import visuAnalec.elements.Relation;
+import visuAnalec.elements.Schema
+import visuAnalec.elements.Unite;
+import visuAnalec.vue.Vue
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
+		String unit_type
+@Field @Option(name="schema_type",usage="", widget="String", required=true, def="CHAINE")
+		String schema_type
+if (!ParametersDialog.open(this)) return;
+
+int nCreated = 0 // count the number of created RELATION
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName()); // analec corpus has the same name has the TXM corpus
+Structure structure = analecCorpus.getStructure()
+if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
+	println "Error: corpus structure does not contains unit with name=$unit_type"
+	return
+}
+if (!structure.getSchemas().contains(schema_type)) { // check if the structure contains the unit_type units
+	println "Error: corpus structure does not contains schema with name=$schema_type"
+	return
+}
+if (!structure.getRelations().contains("ANAPHORE")) { // update the structure if needed
+	println "Creating the 'ANAPHORE' relation in the structure"
+	structure.ajouterType(Relation.class, "ANAPHORE")
+	analecCorpus.ajouterProp(Relation.class, "ANAPHORE", "TYPE")
+	analecCorpus.ajouterVal(Relation.class, "ANAPHORE", "TYPE", "COREFERENTE")
+	analecCorpus.ajouterVal(Relation.class, "ANAPHORE", "TYPE", "ASSOCIATIVE")
+}
+if (analecCorpus.getRelations("ANAPHORE").size() > 0) {
+	println "Error: This macro can't update existing Relations"
+	return
+}
+
+for (Schema schema : analecCorpus.getSchemas(schema_type)) { // parse all CHAINE
+	def units = []
+	for (Unite unit : schema.getUnitesSousjacentes()) { // keep only the 'unit_type' units
+		if (unit.type.equals(unit_type)) units << unit
+	}
+	units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() } // sort them
+	
+	for (int i = 0 ; i < units.size() - 1 ; i++) { // build RELATIONS and don't process the last unit
+		println "creating "+units[i+1]+", "+units[i]
+		Relation relation = new Relation("ANAPHORE", units[i+1], units[i])
+		relation.getProps().put("TYPE", "COREFERENTE")
+		analecCorpus.addRelationLue(relation)  // add the new relation
+		nCreated++;
+	}
+}
+
+println "nCreated=$nCreated"
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/NombreDeChainesMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/NombreDeChainesMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/NombreDeChainesMacro.groovy	(revision 481)
@@ -0,0 +1,116 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="schema_type",usage="", widget="String", required=true, def="Coréférence")
+String schema_type
+
+@Field @Option(name="minimum_schema_size",usage="", widget="Integer", required=true, def="3")
+int minimum_schema_size
+
+@Field @Option(name="schema_property_name",usage="", widget="String", required=false, def="")
+String schema_property_name
+
+@Field @Option(name="schema_property_value",usage="", widget="String", required=false, def=".*")
+String schema_property_value
+
+@Field @Option(name="unit_type",usage="", widget="String", required=false, def="Maillon")
+String unit_type
+
+@Field @Option(name="unit_property_name", usage="", widget="String", required=false, def="")
+String unit_property_name
+
+@Field @Option(name="unit_property_value", usage="", widget="String", required=false, def=".*")
+String unit_property_value
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// Open the parameters input dialog box
+if (!ParametersDialog.open(this)) return;
+// END OF PARAMETERS
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName())
+
+// check Schema parameters
+if (!analecCorpus.getStructure().getSchemas().contains(schema_type)) {
+	println "No schema with name=$schema_type"
+	return;
+} else {
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getSchemaProperties(schema_type);
+		if (!props.contains(schema_property_name)) {
+			println "Schema $schema_type has no property named $schema_property_name"
+			return;
+		}
+	}
+}
+
+// check unit parameters
+if (!analecCorpus.getStructure().getUnites().contains(unit_type)) {
+	println "No unit with name=$unit_type"
+	return;
+} else {
+	if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getUniteProperties(unit_type);
+		if (!props.contains(unit_property_name)) {
+			println "Unit $unit_type has no property named $unit_property_name"
+			return;
+		}
+	}
+}
+
+def schemas = analecCorpus.getSchemas(schema_type)
+
+int nSchemas = 0;
+for (def schema : schemas) {
+
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		if (!schema.getProp(schema_property_name).matches(schema_property_value)) {
+			// ignoring this schema
+			continue
+		}
+	}
+	
+	int nUnites = 0;
+	for (def unit : schema.getUnitesSousjacentesNonTriees()) {
+	if (unit_type.length() > 0) {
+			if (!unit.getType().equals(unit_type)) {
+				continue
+			}
+		}
+		
+		if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+			if (!unit.getProp(unit_property_name).matches(unit_property_value)) {
+				// ignoring this schema
+				continue
+			}
+		}
+	
+		nUnites++
+	}
+	
+	if (nUnites < minimum_schema_size) continue;
+
+	nSchemas++;
+}
+
+println "nombre de chaînes de référence d'un texte : $nSchemas"
+
+["result":nSchemas, "data":schemas]
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/DistanceInterMaillonnaireMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/DistanceInterMaillonnaireMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/DistanceInterMaillonnaireMacro.groovy	(revision 481)
@@ -0,0 +1,124 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.*
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+import org.apache.commons.lang.StringUtils;
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="schema_type",usage="", widget="String", required=true, def="Coréférence")
+String schema_type
+
+@Field @Option(name="minimum_schema_size", usage="", widget="Integer", required=true, def="3")
+int minimum_schema_size
+
+@Field @Option(name="schema_property_name",usage="", widget="String", required=false, def="")
+String schema_property_name
+
+@Field @Option(name="schema_property_value",usage="", widget="String", required=false, def=".*")
+String schema_property_value
+
+@Field @Option(name="unit_type",usage="", widget="String", required=false, def="Maillon")
+String unit_type
+
+@Field @Option(name="unit_property_name", usage="", widget="String", required=false, def="")
+String unit_property_name
+
+@Field @Option(name="unit_property_value", usage="", widget="String", required=false, def=".*")
+String unit_property_value
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+if (!ParametersDialog.open(this)) return;
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName())
+
+// check Schema parameters
+if (!analecCorpus.getStructure().getSchemas().contains(schema_type)) {
+	println "No schema with name=$schema_type"
+	return;
+} else {
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getSchemaProperties(schema_type);
+		if (!props.contains(schema_property_name)) {
+			println "Schema $schema_type has no property named $schema_property_name"
+			return;
+		}
+	}
+}
+
+// check unit parameters
+if (!analecCorpus.getStructure().getUnites().contains(unit_type)) {
+	println "No unit with name=$unit_type"
+	return;
+} else {
+	if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getUniteProperties(unit_type);
+		if (!props.contains(unit_property_name)) {
+			println "Unit $unit_type has no property named $unit_property_name"
+			return;
+		}
+	}
+}
+
+def schemas = analecCorpus.getSchemas(schema_type)
+def distances = 0;
+def nDistances = 0
+for (def schema : schemas) {
+
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		if (!schema.getProp(schema_property_name).matches(schema_property_value)) {
+			// ignoring this schema
+			continue
+		}
+	}
+	
+	def allUnites = schema.getUnitesSousjacentesNonTriees()
+	int nUnites = allUnites.size()
+	if (nUnites < minimum_schema_size) continue;
+
+	def units = []
+	for (def unit : allUnites) {
+	
+		if (unit_type.length() > 0) {
+			if (!unit.getType().equals(unit_type)) {
+				continue
+			}
+		}
+		
+		if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+			if (!unit.getProp(unit_property_name).matches(unit_property_value)) {
+				// ignoring this schema
+				continue
+			}
+		}
+		
+		units << unit
+	}
+	
+	units.sort() { u1, u2 -> u1.getDeb() <=> u2.getDeb()}
+		
+	for (int i = 0 ; i < units.size() -1 ; i++) {
+		distances +=  units[i+1].getDeb() - units[i].getFin() 
+		nDistances++
+	}
+}
+
+coef = (distances / nDistances)
+println "distance moyenne inter-mayonnaise : $distances / $nDistances = $coef"
+
+return ["result":coef, "data":["distances":distances, "nDistances":nDistances]]
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/NatureDuPremierMaillonMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/NatureDuPremierMaillonMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/NatureDuPremierMaillonMacro.groovy	(revision 481)
@@ -0,0 +1,156 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.*
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+import org.apache.commons.lang.StringUtils;
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="schema_type",usage="", widget="String", required=true, def="Coréférence")
+String schema_type
+
+@Field @Option(name="minimum_schema_size", usage="", widget="Integer", required=true, def="3")
+int minimum_schema_size
+
+@Field @Option(name="schema_property_name",usage="", widget="String", required=false, def="")
+String schema_property_name
+
+@Field @Option(name="schema_property_value",usage="", widget="String", required=false, def=".*")
+String schema_property_value
+
+@Field @Option(name="unit_type",usage="", widget="String", required=false, def="Maillon")
+String unit_type
+
+@Field @Option(name="unit_property_name", usage="", widget="String", required=false, def="")
+String unit_property_name
+
+@Field @Option(name="unit_property_value", usage="", widget="String", required=false, def=".*")
+String unit_property_value
+
+@Field @Option(name="word_property", usage="", widget="StringArray", metaVar="Catégorie	pos	fropos	frpos", required=false, def="Catégorie")
+String word_property
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// Open the parameters input dialog box
+if (!ParametersDialog.open(this)) return;
+// END OF PARAMETERS
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName())
+
+if (!analecCorpus.getStructure().getSchemas().contains(schema_type)) {
+	println "No schema with name=$schema_type"
+	return;
+} else {
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getSchemaProperties(schema_type);
+		if (!props.contains(schema_property_name)) {
+			println "Schema $schema_type has no property named $schema_property_name"
+			return;
+		}
+	}
+}
+
+if (!analecCorpus.getStructure().getUnites().contains(unit_type)) {
+	println "No unit with name=$unit_type"
+	return;
+} else {
+	if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getUniteProperties(unit_type);
+		if (!props.contains(unit_property_name)) {
+			println "Unit $unit_type has no property named $unit_property_name"
+			return;
+		}
+	}
+}
+
+def CQI = Toolbox.getCqiClient()
+
+def prop = corpus.getProperty(word_property)
+
+def schemas = analecCorpus.getSchemas(schema_type)
+def freqs = [:]
+
+def distances = 0;
+def nDistances = 0
+for (def schema : schemas) {
+
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		if (!schema.getProp(schema_property_name).matches(schema_property_value)) {
+			// ignoring this schema
+			continue
+		}
+	}
+	
+	def allUnites = schema.getUnitesSousjacentesNonTriees()
+	int nUnites = allUnites.size()
+	if (nUnites < minimum_schema_size) continue;
+
+	def units = []
+	for (def unit : allUnites) {
+	
+		if (unit_type.length() > 0) {
+			if (!unit.getType().equals(unit_type)) {
+				continue
+			}
+		}
+		
+		if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+			if (!unit.getProp(unit_property_name).matches(unit_property_value)) {
+				// ignoring this schema
+				continue
+			}
+		}
+		
+		units << unit
+	}
+	
+	units.sort() { u1, u2 ->
+		return u1.getDeb() - u2.getDeb()
+	}
+	if (units.size() == 0) continue;
+	
+	def unit = units[0]
+	
+	String forme =  null;
+	if (prop == null) { // word_property is the analec unit property to use
+		forme = unit.getProp(word_property)
+	} else {
+		int[] pos = null;
+		if (unit.getDeb() == unit.getFin()) pos = [unit.getDeb()]
+		else pos = unit.getDeb()..unit.getFin()
+			
+		forme = StringUtils.join(CQI.cpos2Str(prop.getQualifiedName(), pos), " ") // ids is enough
+	}
+	
+	if (!freqs.containsKey(forme)) freqs[forme] = 0;
+	
+	freqs[forme] = freqs[forme] + 1;
+}
+
+println "index des natures de premier maillon :"
+int max = 0;
+def result = "";
+for (def forme : freqs.keySet().sort() {it -> -freqs[it]}) {
+	println "$forme\t"+freqs[forme]
+	if (max < freqs[forme]) {
+		max = freqs[forme]
+		result = "$forme: "+freqs[forme]
+	}
+}
+
+["result": result, "data": freqs]
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/LongueurMoyenneMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/LongueurMoyenneMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/LongueurMoyenneMacro.groovy	(revision 481)
@@ -0,0 +1,173 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+
+import groovy.transform.Field
+
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+import org.txm.statsengine.r.core.RWorkspace;
+import org.txm.Toolbox
+import org.txm.rcpapplication.commands.*
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="schema_type",usage="", widget="String", required=true, def="Coréférence")
+String schema_type
+
+@Field @Option(name="minimum_schema_size",usage="", widget="Integer", required=true, def="3")
+int minimum_schema_size
+
+@Field @Option(name="schema_property_name",usage="", widget="String", required=false, def="")
+String schema_property_name
+
+@Field @Option(name="schema_property_value",usage="", widget="String", required=false, def=".*")
+String schema_property_value
+
+@Field @Option(name="unit_type",usage="", widget="String", required=false, def="Maillon")
+String unit_type
+
+@Field @Option(name="unit_property_name", usage="", widget="String", required=false, def="")
+String unit_property_name
+
+@Field @Option(name="unit_property_value", usage="", widget="String", required=false, def=".*")
+String unit_property_value
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+if (!ParametersDialog.open(this)) return;
+// END OF PARAMETERS
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName())
+
+// check Schema parameters
+if (!analecCorpus.getStructure().getSchemas().contains(schema_type)) {
+	println "No schema with name=$schema_type"
+	return;
+} else {
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getSchemaProperties(schema_type);
+		if (!props.contains(schema_property_name)) {
+			println "Schema $schema_type has no property named $schema_property_name"
+			return;
+		}
+	}
+}
+
+// check unit parameters
+if (!analecCorpus.getStructure().getUnites().contains(unit_type)) {
+	println "No unit with name=$unit_type"
+	return;
+} else {
+	if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getUniteProperties(unit_type);
+		if (!props.contains(unit_property_name)) {
+			println "Unit $unit_type has no property named $unit_property_name"
+			return;
+		}
+	}
+}
+
+def schemas = analecCorpus.getSchemas(schema_type)
+
+int nSchemas = 0;
+
+def lens = [:]
+for (def schema : schemas) {
+
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		if (!schema.getProp(schema_property_name).matches(schema_property_value)) {
+			// ignoring this schema
+			continue
+		}
+	}
+	
+	int nUnites = 0;
+	for (def unit : schema.getUnitesSousjacentesNonTriees()) {
+		if (unit_type.length() > 0) {
+			if (!unit.getType().equals(unit_type)) {
+				continue
+			}
+		}
+		
+		if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+			if (!unit.getProp(unit_property_name).matches(unit_property_value)) {
+				// ignoring this schema
+				continue
+			}
+		}
+	
+		nUnites++
+	}
+	
+	if (nUnites < minimum_schema_size) continue;
+	
+	if (!lens.containsKey(nUnites)) lens[nUnites] = 0;
+	
+	lens[nUnites] = lens[nUnites] + 1;
+	nSchemas++;
+}
+
+//println "nSchemas=$nSchemas"
+def freqs = lens.keySet();
+freqs.sort();
+int t = 0;
+int n = 0;
+//println "Fréquences ("+freqs.size()+")"
+for (def f : freqs) {
+	t += f * lens[f]
+	n += lens[f]
+}
+
+coef = (t/n)
+def slens = lens.sort { a, b -> -a.value <=> -b.value ?: -a.key <=> -b.key }
+def flens = []
+slens.each { key, value -> value.times { flens << key } }
+def nbins = flens.size()*2
+
+def cfreq = 0
+println "longueur moyenne des chaînes de référence : $t/$n = "+coef
+println "index hiérarchique des longueurs de chaînes :\nlen\tfreq\tcfreq"
+slens.each { println it.key+"	"+it.value+"	"+(cfreq+=it.value) }
+
+def slens2 = slens.sort { a, b -> -a.key <=> -b.key }
+
+def r = RWorkspace.getRWorkspaceInstance()
+
+r.addVectorToWorkspace("len", slens2.keySet() as int[])
+r.addVectorToWorkspace("freq", slens2.values() as int[])
+r.addVectorToWorkspace("flen", flens as int[])
+
+def corpusName = corpus.getName()
+
+def file = File.createTempFile("txm", ".svg", new File(Toolbox.getParam(Toolbox.USER_TXM_HOME), "results"))
+println "SVG file: "+file.getAbsolutePath()
+/// BEGINNING OF R SCRIPT
+def script ="""
+hist(flen, xaxt='n', col="gray", xlab="Length", breaks=$nbins, main="$corpusName Longueur des chaînes ($nbins bins)")
+axis(side=1, at=len)
+"""
+/// END OF R SCRIPT
+
+// execute R script
+r.plot(file, script)
+
+//display the SVG results graphic
+monitor.syncExec(new Runnable() {
+	@Override
+	public void run() { OpenSVGGraph.OpenSVGFile(file.getAbsolutePath(), corpusName+" Longueur des chaînes") }
+})
+
+return ["result":coef, "data":lens]
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitTypesNotInSchemaMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitTypesNotInSchemaMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitTypesNotInSchemaMacro.groovy	(revision 481)
@@ -0,0 +1,42 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="schema_type",usage="", widget="String", required=true, def="Coréférence")
+String schema_type
+if (!ParametersDialog.open(this)) return;
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+
+def unitesInSchema = new HashSet()
+for (def schema : analecCorpus.getSchemas(schema_type)) {
+	unitesInSchema.addAll(schema.getUnitesSousjacentes())
+}
+println "unites: "+analecCorpus.getToutesUnites().size()
+println "unites in schema: "+unitesInSchema.size()
+
+def set = new HashMap()
+for (def u : analecCorpus.getToutesUnites()) {
+	if (unitesInSchema.contains(u)) continue;
+	
+	if (!set.containsKey(u.getType())) set[u.getType()] = 0;
+	set[u.getType()] = set[u.getType()] +1
+}
+
+println "unites not in schema: "+set.sort() { it -> set[it]}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/Frpos2CategorieMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/Frpos2CategorieMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/Frpos2CategorieMacro.groovy	(revision 481)
@@ -0,0 +1,252 @@
+// @author Bruno Oberlé (2017-04-01 21:50)
+
+/*
+Définit la catégorie grammaticale du maillon d'après le champ `frpos'
+(tagset de TreeTagger).  Le script est adapté de
+http://svn.code.sf.net/p/txm/code/trunk/plugins/Analec/AnalecRCP/src/org/txm/macro/analec/Fropos2CategorieMacro.groovy.
+
+Voici la liste des catégories grammaticales retenues (manuel d'annotation de
+Democrat):
+- GN: Groupe Nominal (le petit chat, le chat, le même, ce chat etc.)
+- POSS: Possessif (mon, ton son, ma, ta, sa, mes, tes, ses, notre, votre,
+  leur, nos, vos, leurs)
+- PR: Pronom (moi, toi, lui, elle, nous, vous, eux, elles, le tien, le mien,
+  moi-même etc.)
+- PR_CL_O: Pronom Clitique Objet (me, te, le, la, les, lui, leur, y, en)
+- PR_CL_R: Pronom Clitique Réfléchi
+- PR_CL_S: Pronom Clitique Sujet (je, tu, il, elle, on, nous, vous, ils,
+  elles)
+- PR_REL: Pronom Relatif (qui, que, quoi, dont, où, lequel, quiconque etc.)
+- PR_WH: Pronom Interrogatif (qui, que, quoi, lequel etc.)
+
+Le script ne peut pas désambiguïser les pronoms clitiques de même forme
+(`nous' est-il un sujet, un objet ou un réfléchi?).  Dans ce cas, le script
+opte pour le sujet (ou pour l'objet si l'ambiguïté n'est que entre objet et
+réfléchi).
+
+Quand il n'y a aucune information disponible (erreurs de l'étiqueteur), la
+valeur est UNDEFINED.
+
+L'algorithme est décrit ici:
+https://groupes.renater.fr/wiki/democrat/prive/txm_annotation_exploitation
+
+*/
+
+package org.txm.macro.analec
+
+import org.apache.commons.lang.*
+import org.kohsuke.args4j.*
+import groovy.transform.*
+import org.txm.*
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.*
+import org.txm.searchengine.cqp.corpus.*
+import visuAnalec.Message.*
+import visuAnalec.donnees.*
+import visuAnalec.elements.*
+import visuAnalec.vue.*
+
+def testClitic(def position, def frpos) {
+
+   // je me sers de la forme, parce qu'il est difficile de savoir quel est le
+   // lemme de "elle" ("il"?), de "te" ("tu"?) ou encore de "leur"
+   def form = CQI.cpos2Str(word.getQualifiedName(), position)[0].toLowerCase()
+   if (     form == "je" || form == "j'"
+         || form == "tu" || form == "t'"
+         || form == "il"
+         || form == "elle"
+         || form == "on"
+         || form == "vous"
+         || form == "nous"
+         || form == "ils"
+         || form == "elles" ) {
+      return "PR_CL_S"
+   } else if (form == "me" || form == "m'"
+           || form == "te"
+           || form == "le" || form == "l'"
+           || form == "la"
+           || form == "lui"
+           || form == "leur"
+           || form == "les" ) {
+      return "PR_CL_O"
+   } else if (form == "se" || form == "s'") {
+      return "PR_CL_R"
+   }
+   return null
+
+}
+
+def testPhrase(def positions, def Mention) {
+
+   // on doit regarder ce qui apparaît en premier:
+   // - ce peut être un nom, comme dans `le petit chat que j'ai adopté'
+   // - ce peut être un pronom relatif, comme dans `(le livre) dans lequel
+   // j'ai lu cette histoire...'
+   // NOTE: dans Democrat, on n'annote pas, bizarrement, la relative dans le
+   // maillon, donc, dans un GN on n'a jamais de relatif inclus.  On aura donc
+   // toujours `[le petit chat] [que] [j']ai adopté'.  Mais tout le monde
+   // n'annote pas de la sorte...
+   for (def i=0; i<Mention.length; i++) {
+         def mention = Mention[i]
+         //def form = CQI.cpos2Str(word.getQualifiedName(), positions[i])[0]
+         if (mention == "NOM" || mention == "NAM") {
+            return "GN"
+         } else if (mention == "PRO:REL") {
+            return "PR_REL"
+         }
+    }
+
+    return null
+
+}
+
+def testWhPronoun(position, mention) {
+   def form = CQI.cpos2Str(word.getQualifiedName(), position)[0]
+   if (mention == "PRO" && (form == "qui" || form == "que" || form == "lequel")) {
+      return "PR_WH"
+   }
+   return null
+
+}
+
+def testRules(def positions, def Mention) {
+	def catégorie = null
+
+   // a possessive (mon, ma...)
+   if (Mention.length == 1 && Mention.contains("DET:POS"))
+      catégorie = "POSS"
+
+   // a clitic (subject: je, tu...; object: me, te; reflexive: se)
+   if (!catégorie && Mention.length == 1 && Mention.contains("PRO:PER"))
+      catégorie = testClitic(positions[0], Mention[0])
+
+   // an interrogative pronoun
+   if (!catégorie && Mention.length == 1)
+      catégorie = testWhPronoun(positions[0], Mention[0])
+
+   // a noun phrase or a relative pronoun
+   if (!catégorie)
+      catégorie = testPhrase(positions, Mention)
+
+   // some other kind of pronouns
+   if (!catégorie
+         && (   Mention.contains("PRO")
+             || Mention.contains("PRO:POSS")
+             || Mention.contains("PRO:IND")
+             || Mention.contains("PRO:DEM")
+             || Mention.contains("PRO:PER") )
+         && !Mention.contains("NOM")
+         && !Mention.contains("NAM") )
+      catégorie = "PRO"
+
+// Fin des règles, aucune n'a matchée. On stocke le pattern  qu'on affichera à la fin.
+   if (!catégorie) {
+      catégorie = "UNDEFINED" // clear the field
+		def forms = CQI.cpos2Str(word.getQualifiedName(), positions)
+		if (!errors.containsKey(Mention)) errors[Mention] = new HashSet()
+		errors[Mention] << forms
+	}
+	
+	return catégorie
+}
+
+//
+// FIN DE LA DÉFINITION DES RÈGLES
+//
+
+// CORPS DU SCRIPT
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="unit_type", usage="", widget="String", required=true, def="MENTION")
+def unit_type
+@Field @Option(name="pos_property_name", usage="", widget="String", required=true, def="pos")
+def pos_property_name
+@Field @Option(name="reset", usage="", widget="Boolean", required=true, def="true")
+def reset
+if (!ParametersDialog.open(this)) return
+
+corpus = corpusViewSelection
+CQI = Toolbox.getCqiClient()
+word = corpus.getWordProperty()
+posProperty = corpus.getProperty(pos_property_name)
+if (posProperty == null) {
+	println "Error: CQP corpus does not contains the word property with name=$pos_property_name"
+	return
+}
+analecCorpus = AnalecCorpora.getCorpus(corpus.getName())
+vue = AnalecCorpora.getVue(corpus.getName())
+structure = analecCorpus.getStructure()
+if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
+	println "Error: corpus structure does not contains unit with name=$unit_type"
+	return
+}
+
+CATEGORIE = "CATEGORIE"
+// Si la structure d'annotation ne contient pas CATEGORIE, on la crée avec ses valeurs
+if (!structure.getUniteProperties(unit_type).contains(CATEGORIE)) { 
+
+// FIXME: dans le script original (see also
+// http://forge.cbp.ens-lyon.fr/redmine/issues/2065), on utilise
+// analecCorpus.ajouterProp/Val, mais cela ne marche pas dans ma version de
+// TXM-Analec --> je retourne donc à structure.ajouterProp/Val
+
+// la propriété
+	structure.ajouterProp(Unite.class, unit_type, CATEGORIE)
+// les valeurs
+	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN")
+	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "POSS")
+	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO")
+	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PR_CL_O")
+	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PR_CL_S")
+	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PR_CL_R")
+	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PR_REL")
+	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PR_WH")
+//...
+}
+
+def nModified = 0
+def nIgnored = 0
+
+errors = new HashMap()
+def units = analecCorpus.getUnites(unit_type)
+units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
+for (Unite unit : units) { // process all units
+	
+	def prop = unit.getProp(CATEGORIE)
+	if (!reset && prop != null && prop.length() > 0) continue // l'unité a déjà une CATEGORIE
+	
+	int[] positions = null
+	if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
+	else positions = (unit.getDeb()..unit.getFin())
+	
+	def Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
+	def cat = testRules(positions, Mention)
+
+	if (cat != null) {
+		// following line in the original script but doesn't work for me:
+      // vue.setValeurChamp(unit, CATEGORIE, cat)
+      unit.getProps().put(CATEGORIE, cat)
+		nModified++
+	} else {
+		nIgnored++
+	}
+}
+
+println "Result:"
+println "- $nModified units of type $unit_type have been modified."
+println "- $nIgnored units of type $unit_type have not been modified.\n"
+
+if (errors.size() > 0) {
+	println "Some rules should be added to this macro to process the following remaining 'FROPOS / words' values:"
+	errors.keySet().each { println "fropos="+it+"\twords="+errors[it].join(" | ") }
+}
+
+// udpate the view (also see also
+// http://forge.cbp.ens-lyon.fr/redmine/issues/2065)
+AnalecCorpora.getVue(analecCorpus).retablirVueParDefaut()
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CreationChainesMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CreationChainesMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CreationChainesMacro.groovy	(revision 481)
@@ -0,0 +1,118 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+import visuAnalec.donnees.Structure;
+import visuAnalec.elements.Schema
+import visuAnalec.elements.Unite;
+import visuAnalec.vue.Vue
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
+String unit_type
+if (!ParametersDialog.open(this)) return;
+
+int nCreated = 0 // count the number of created CHAINE
+int nUpdated = 0 // count the number of updated CHAINE
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName()); // analec corpus has the same name has the TXM corpus
+Structure structure = analecCorpus.getStructure()
+if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
+	println "Error: corpus structure does not contains unit with name=$unit_type"
+	return
+}
+if (!structure.getSchemas().contains("CHAINE")) { // update the structure if needed
+	println "Creating the 'CHAINE' schema in the structure"
+	analecCorpus.ajouterType(Schema.class, "CHAINE")
+	analecCorpus.ajouterProp(Schema.class, "CHAINE", "REF")
+	analecCorpus.ajouterProp(Schema.class, "CHAINE", "GENRE")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "GENRE", "INDETERMINABLE")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "GENRE", "FEMININ")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "GENRE", "MASCULIN")
+	analecCorpus.ajouterProp(Schema.class, "CHAINE", "NOMBRE")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "NOMBRE", "GROUPE_FLOU")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "NOMBRE", "GROUPE_STRICT")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "NOMBRE", "SINGULIER")
+	analecCorpus.ajouterProp(Schema.class, "CHAINE", "NB MAILLONS")
+	analecCorpus.ajouterProp(Schema.class, "CHAINE", "TYPE REFERENT")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "TYPE REFERENT", "UNKNOWN")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "TYPE REFERENT", "CONCRET_OBJECT")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "TYPE REFERENT", "ABSTRACT_OBJECT")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "TYPE REFERENT", "TIME")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "TYPE REFERENT", "PRODUCT")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "TYPE REFERENT", "AMOUNT")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "TYPE REFERENT", "EVENT")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "TYPE REFERENT", "GPE")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "TYPE REFERENT", "ORG")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "TYPE REFERENT", "PERSON")
+	analecCorpus.ajouterVal(Schema.class, "CHAINE", "TYPE REFERENT", "LIEU")
+}
+
+def props = structure.getUniteProperties(unit_type)
+String REF = "REF"
+if (!props.contains(REF)) { // check the unit_type units have the REF property
+	println "Error: $unit_type units have no proprerty named 'REF'"
+	return
+}
+
+// parse the units to build CHAINES
+def chaines = [:]
+def units = analecCorpus.getUnites(unit_type)
+units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
+for (Unite unit : units) {
+	def ref = unit.getProp(REF)
+	if (!chaines.containsKey(ref)) {
+		chaines[ref] = []
+	}
+	chaines[ref] << unit
+}
+
+// update the already existing CHAINES schemas
+for (Schema schema : analecCorpus.getSchemas("CHAINE")) {
+	String ref = schema.getProp(REF)
+	if (chaines.containsKey(ref)) { // the CHAINE exists 
+		// maj des unités de la chaine existante
+		int size_before = schema.getContenu().size()
+		for (def unit : chaines[ref]) schema.ajouter(unit) // insert the new units in the hashset
+		
+		// Update the CHAINE size
+		schema.props.put("NB MAILLONS", Integer.toString(schema.contenu.size())) 
+		
+		// remove the inserted CHAINE from 'chaines'
+		chaines.remove(ref)
+		if (size_before < schema.getContenu().size()) // if the size changed, then the CHAIEN have been updated
+			nUpdated++
+	}
+}
+
+// create the remaining CHAINES schemas
+for (def ref : chaines.keySet()) { // process the remaining CHAINE of 'chaines'
+	nCreated++;
+	Schema schema = new Schema()
+	schema.type = "CHAINE"
+	schema.props.put("REF", ref) 
+	schema.props.put("GENRE", "") // set default values
+	schema.props.put("NOMBRE", "") // set default values
+	schema.props.put("NB MAILLONS", Integer.toString(chaines[ref].size())) 
+	schema.props.put("TYPE REFERENT", "") // set default values
+	
+	for (def unit : chaines[ref]) schema.ajouter(unit) // insert the new units in the hashset
+	
+	analecCorpus.addSchemaLu(schema)  // add the new schema
+}
+
+println "nUpdated=$nUpdated"
+println "nCreated=$nCreated"
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/RelationsMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/RelationsMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/RelationsMacro.groovy	(revision 481)
@@ -0,0 +1,62 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.tools.ant.types.resources.selectors.InstanceOf;
+import org.kohsuke.args4j.*
+
+import groovy.transform.Field
+
+import org.txm.Toolbox;
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.AbstractCqiClient;
+import org.txm.searchengine.cqp.corpus.*
+
+import visuAnalec.donnees.Structure;
+import visuAnalec.elements.Relation
+import visuAnalec.elements.Unite;
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="relation_type",usage="", widget="String", required=true, def="ANAPHORE")
+String relation_type
+
+if (!ParametersDialog.open(this)) return;
+
+MainCorpus corpus = corpusViewSelection
+AbstractCqiClient CQI = Toolbox.getCqiClient();
+def word = corpus.getWordProperty()
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+
+int n = 1;
+def relations = analecCorpus.getRelations(relation_type)
+for (Relation relation : relations) {
+	def unit1 = relation.getElt1();
+	def unit2 = relation.getElt2();
+	def props = relation.getProps()
+	if (unit1 instanceof Unite && unit2 instanceof Unite) {
+		int[] pos1 = null
+		if (unit1.getDeb() == unit1.getFin()) pos1 = [unit1.getDeb()]
+		else pos1 = (unit1.getDeb()..unit1.getFin())
+		def form1 = StringUtils.join(CQI.cpos2Str(word.getQualifiedName(), pos1), " ")
+		
+		int[] pos2 = null
+		if (unit2.getDeb() == unit2.getFin()) pos2 = [unit2.getDeb()]
+		else pos2 = (unit2.getDeb()..unit2.getFin())
+		def form2 = StringUtils.join(CQI.cpos2Str(word.getQualifiedName(), pos2), " ")
+		
+		println "$n - $props : $form1 -> $form2"
+	} else {
+		println "$n - $props"
+	}
+	n++
+}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/ResetAnnotationsMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/ResetAnnotationsMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/ResetAnnotationsMacro.groovy	(revision 481)
@@ -0,0 +1,52 @@
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+import visuAnalec.elements.*
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+@Field @Option(name="I_AM_SURE_IWANT_TO_RESET_THE_ANNOTATIONS", usage="an example boolean", widget="Boolean", required=false, def="false")
+def I_AM_SURE_IWANT_TO_RESET_THE_ANNOTATIONS
+
+// Open the parameters input dialog box
+if (!ParametersDialog.open(this)) return;
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+def structure = analecCorpus.getStructure()
+
+Class[] classes = [Unite.class, Relation.class, Schema.class]
+println "Removing unites..."
+for (String type : structure.getTypes(Unite.class)) {
+	for (Unite unite : analecCorpus.getUnites(type).toArray(new Unite[0])) {
+		analecCorpus.supUnite(unite)
+	}
+//	fireMessage(new StructureEvent(analecCorpus, TypeModifStructure.SUPPR_TYPE, Unite.class, type));
+}
+
+println "Removing relations..."
+for (String type : structure.getTypes(Relation.class)) {
+	for (Relation relation : analecCorpus.getRelations(type).toArray(new Relation[0])) {
+		analecCorpus.supRelation(relation)
+	}
+//	fireMessage(new StructureEvent(analecCorpus, TypeModifStructure.SUPPR_TYPE, Relation.class, type));
+}
+
+println "Removing schemas..."
+for (String type : structure.getTypes(Schema.class)) {
+	for (Schema schema : analecCorpus.getSchemas(type).toArray(new Schema[0])) {
+		analecCorpus.supSchema(schema)
+	}
+//	fireMessage(new StructureEvent(analecCorpus, TypeModifStructure.SUPPR_TYPE, Schema.class, type));
+}
+
+println "Done. Save the corpus to finish the reset."
+
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/DensiteReferentielleMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/DensiteReferentielleMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/DensiteReferentielleMacro.groovy	(revision 481)
@@ -0,0 +1,74 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+@Field @Option(name="unit_type",usage="", widget="String", required=false, def="Maillon")
+String unit_type
+
+@Field @Option(name="unit_property_name", usage="", widget="String", required=false, def="")
+String unit_property_name
+
+@Field @Option(name="unit_property_value", usage="", widget="String", required=false, def=".*")
+String unit_property_value
+
+if (!ParametersDialog.open(this)) return;
+// END OF PARAMETERS
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+
+// check unit parameters
+if (!analecCorpus.getStructure().getUnites().contains(unit_type)) {
+	println "No unit with name=$unit_type"
+	return;
+} else {
+	if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getUniteProperties(unit_type);
+		if (!props.contains(unit_property_name)) {
+			println "Unit $unit_type has no property named $unit_property_name"
+			return;
+		}
+	}
+}
+
+int nMots = corpus.getSize();
+
+int nUnites = 0;
+	for (def unit : analecCorpus.getToutesUnites()) {
+		if (unit_type.length() > 0) {
+			if (!unit.getType().equals(unit_type)) {
+				continue
+			}
+		}
+		
+		if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+			if (!unit.getProp(unit_property_name).matches(unit_property_value)) {
+				// ignoring this schema
+				continue
+			}
+		}
+	
+		nUnites++
+	}
+
+coef = (nUnites /nMots)
+println "densité référentielle : nUnites/nMots = $nUnites/$nMots = $coef = ${coef*100}%"
+if (nUnites >= nMots) {
+	println "WARNING: possible encoding error. Number of units ($nUnites) is greater than number of words ($nMots)"
+}
+return ["result":coef, "data":["nUnites":nUnites, "nMots":nMots]]
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitsMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitsMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitsMacro.groovy	(revision 481)
@@ -0,0 +1,47 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.apache.commons.lang.StringUtils;
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.Toolbox;
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.AbstractCqiClient;
+import org.txm.searchengine.cqp.corpus.*
+import visuAnalec.donnees.Structure;
+import visuAnalec.elements.Unite;
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
+String unit_type
+
+if (!ParametersDialog.open(this)) return;
+
+MainCorpus corpus = corpusViewSelection
+AbstractCqiClient CQI = Toolbox.getCqiClient();
+def word = corpus.getWordProperty()
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+
+int n = 1;
+def units = analecCorpus.getUnites(unit_type)
+units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
+for (Unite unit : units) {
+	int[] pos = null
+	if (unit.getDeb() == unit.getFin()) pos = [unit.getDeb()]
+	else pos = (unit.getDeb()..unit.getFin())
+	def form = StringUtils.join(CQI.cpos2Str(word.getQualifiedName(), pos), " ")
+	
+	def props = unit.getProps().sort();
+	println "$n - ${unit.getDeb()} -> ${unit.getFin()} - $props : $form"
+	n++
+}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitTypesMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitTypesMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitTypesMacro.groovy	(revision 481)
@@ -0,0 +1,48 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="schema_type",usage="", widget="String", required=true, def="Coréférence")
+String schema_type
+
+if (!ParametersDialog.open(this)) return;
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+def map = new HashMap()
+def unitesInSchema = []
+def n = 0
+for (def schema : analecCorpus.getSchemas(schema_type)) {
+	def unites = schema.getUnitesSousjacentes()
+	unitesInSchema.addAll(unites)
+	n += unites.size()
+}
+
+def counts = unitesInSchema.countBy() { it };
+for (def c : counts.keySet()) {
+	if (counts[c] > 1) println "ERROR UNIT IN MULTIPLE SCHEMA["+c.getDeb()+", "+c.getFin()+"]="+c.getProps()+" in "+c.getSchemas().collect() {it.getProps()}
+}
+
+def set = new HashSet()
+set.addAll(unitesInSchema)
+for (def s : set.collect { it.getType() }) {
+	if (!map.containsKey(s)) map[s] = 0;
+	map[s] = map[s] +1
+}
+
+println "Unites types: "+map.sort() { it -> map[it]}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CheckAnnotationStructureValuesMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CheckAnnotationStructureValuesMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CheckAnnotationStructureValuesMacro.groovy	(revision 481)
@@ -0,0 +1,69 @@
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+import visuAnalec.elements.*
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+@Field @Option(name="unit_type",usage="", widget="String", required=false, def="Maillon")
+String unit_type
+
+@Field @Option(name="unit_property_name", usage="", widget="String", required=false, def="REF")
+String unit_property_name
+
+@Field @Option(name="pruneUnusedValues", usage="", widget="Boolean", required=false, def="false")
+boolean pruneUnusedValues
+
+// Open the parameters input dialog box
+if (!ParametersDialog.open(this)) return;
+
+// END OF PARAMETERS
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+def structure = analecCorpus.getStructure()
+
+def unit_types = structure.getTypes(Unite.class);
+if (!unit_types.contains(unit_type)) {
+	println "Missing unit type: $unit_type"
+	return
+}
+
+def props = analecCorpus.getStructure().getUniteProperties(unit_type);
+if (!props.contains(unit_property_name)) {
+	println "No properties '$unit_property_name' in '$unit_type' unit."
+	return
+}
+
+def prop  = unit_property_name
+	
+def tmpvalues = new HashSet()
+tmpvalues.addAll(structure.getValeursProp(Unite.class, unit_type, prop));
+println "Values stored in the structure: $tmpvalues"
+	
+def used_values = new HashSet();
+def unites = analecCorpus.getUnites(unit_type);
+for (Unite unite : unites) {
+	used_values.add(unite.getProp(prop))
+}
+	
+tmpvalues.removeAll(used_values);
+if (tmpvalues.size() > 0) {
+	println "The following "+tmpvalues.size()+" value(s) are not used: $tmpvalues"
+	if (pruneUnusedValues) {
+		println "Pruning the values..."
+		for (String val : tmpvalues) {
+			structure.supprimerVal(Unite.class, unit_type, unit_property_name, val);
+		}
+	} 
+} else {
+	println "All the values are used."
+}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CategorieGrammaticaleMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CategorieGrammaticaleMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CategorieGrammaticaleMacro.groovy	(revision 481)
@@ -0,0 +1,169 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.*
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+import org.apache.commons.lang.StringUtils;
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="schema_type",usage="", widget="String", required=true, def="Coréférence")
+String schema_type
+
+@Field @Option(name="minimum_schema_size", usage="", widget="Integer", required=true, def="3")
+int minimum_schema_size
+
+@Field @Option(name="schema_property_name",usage="", widget="String", required=false, def="")
+String schema_property_name
+
+@Field @Option(name="schema_property_value",usage="", widget="String", required=false, def=".*")
+String schema_property_value
+
+@Field @Option(name="schema_display_property_name",usage="", widget="String", required=false, def="Nom du référent")
+String schema_display_property_name
+
+@Field @Option(name="unit_type",usage="", widget="String", required=false, def="Maillon")
+String unit_type
+
+@Field @Option(name="unit_property_name", usage="", widget="String", required=false, def="")
+String unit_property_name
+
+@Field @Option(name="unit_property_value", usage="", widget="String", required=false, def=".*")
+String unit_property_value
+
+@Field @Option(name="word_property", usage="", widget="StringArray", metaVar="Catégorie	CATEGORIE	pos	fropos	frpos	word	lemma	frlemma	frolemma	#forme#", required=false, def="Catégorie")
+
+String word_property
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// Open the parameters input dialog box
+if (!ParametersDialog.open(this)) return;
+// END OF PARAMETERS
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName())
+
+if (!analecCorpus.getStructure().getSchemas().contains(schema_type)) {
+	println "No schema with name=$schema_type"
+	return;
+} else {
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getSchemaProperties(schema_type);
+		if (!props.contains(schema_property_name)) {
+			println "Schema $schema_type has no property named $schema_property_name"
+			return;
+		}
+	}
+}
+
+if (!analecCorpus.getStructure().getUnites().contains(unit_type)) {
+	println "No unit with name=$unit_type"
+	return;
+} else {
+	if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getUniteProperties(unit_type);
+		if (!props.contains(unit_property_name)) {
+			println "Unit $unit_type has no property named $unit_property_name"
+			return;
+		}
+	}
+}
+
+def CQI = Toolbox.getCqiClient()
+
+def prop = corpus.getProperty(word_property)
+if (prop == null) {
+	analecCorpus.getStructure()
+}
+def schemas = analecCorpus.getSchemas(schema_type)
+def allFreqs = [:]
+def n = 0
+for (def schema : schemas) {
+	n++
+	
+	def freqs = [:]
+	
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		if (!schema.getProp(schema_property_name).matches(schema_property_value)) {
+			// ignoring this schema
+			continue
+		}
+	}
+	
+	def allUnites = schema.getUnitesSousjacentesNonTriees()
+	int nUnites = allUnites.size()
+	if (nUnites < minimum_schema_size) continue;
+
+	def units = []
+	for (def unit : allUnites) { // no need to sort units
+	
+		if (unit_type.length() > 0) {
+			if (!unit.getType().equals(unit_type)) {
+				continue
+			}
+		}
+		
+		if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+			if (!unit.getProp(unit_property_name).matches(unit_property_value)) {
+				// ignoring this schema
+				continue
+			}
+		}
+		
+		String forme =  null;
+		if (prop == null) { // word_property is the analec unit property to use
+			forme = unit.getProp(word_property)
+		} else {
+			int[] pos = null;
+			if (unit.getDeb() == unit.getFin()) pos = [unit.getDeb()]
+			else pos = unit.getDeb()..unit.getFin()
+				
+			forme = StringUtils.join(CQI.cpos2Str(prop.getQualifiedName(), pos), " ") // ids is enough
+		}
+		
+		if (!freqs.containsKey(forme)) freqs[forme] = 0;
+		freqs[forme] = freqs[forme] + 1;
+		
+		if (!allFreqs.containsKey(forme)) allFreqs[forme] = 0;
+		allFreqs[forme] = allFreqs[forme] + 1;
+	}
+	
+	if (schema_display_property_name != null) {
+		println "index des natures de $unit_type de '"+schema.getProp(schema_display_property_name)+"' : "
+	} else {
+		println "index des natures de $schema_type - $n : "
+	}
+	
+	int max = 0;
+	def result = "";
+	for (def forme : freqs.sort() { a, b -> -a.value <=> -b.value ?: a.key <=> b.key }) {
+		println forme.key+"\t"+forme.value
+	}
+}
+
+int max = 0;
+def result = "";
+
+println "index des natures de $schema_type : "
+for (def forme : allFreqs.sort() { a, b -> -a.value <=> -b.value ?: a.key <=> b.key }) {
+	println forme.key+"\t"+forme.value
+	if (max < forme.value) {
+		max = forme.value
+		result = "$forme: "+forme.value
+	}
+}
+
+return ["result":result, "data":allFreqs]
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/ChainesMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/ChainesMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/ChainesMacro.groovy	(revision 481)
@@ -0,0 +1,182 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+import org.txm.Toolbox
+import org.txm.rcpapplication.commands.*
+import org.apache.commons.lang.StringUtils
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="schema_type",usage="", widget="String", required=true, def="Coréférence")
+String schema_type
+
+@Field @Option(name="minimum_schema_size",usage="", widget="Integer", required=true, def="3")
+int minimum_schema_size
+
+@Field @Option(name="schema_property_name",usage="", widget="String", required=false, def="")
+String schema_property_name
+
+@Field @Option(name="schema_property_value",usage="", widget="String", required=false, def=".*")
+String schema_property_value
+
+@Field @Option(name="unit_type",usage="", widget="String", required=false, def="Maillon")
+String unit_type
+
+@Field @Option(name="unit_property_name", usage="", widget="String", required=false, def="")
+String unit_property_name
+
+@Field @Option(name="unit_property_value", usage="", widget="String", required=false, def=".*")
+String unit_property_value
+
+@Field @Option(name="word_property", usage="", widget="StringArray", metaVar="word	lemma	frlemma	frolemma	#forme#	id", required=false, def="word")
+String word_property
+
+@Field @Option(name="separator", usage="", widget="String", required=true, def=", ")
+String separator
+
+@Field @Option(name="buildCQL", usage="générer la requête des unités", widget="Boolean", required=true, def='false')
+def buildCQL
+
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpus view selection is not a Corpus"
+	return;
+}
+
+if (!ParametersDialog.open(this)) return;
+// END OF PARAMETERS
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName())
+
+// check Schema parameters
+if (!analecCorpus.getStructure().getSchemas().contains(schema_type)) {
+	println "No schema with name=$schema_type"
+	return;
+} else {
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getSchemaProperties(schema_type);
+		if (!props.contains(schema_property_name)) {
+			println "Schema $schema_type has no property named $schema_property_name"
+			return;
+		}
+	}
+}
+
+// check unit parameters
+if (!analecCorpus.getStructure().getUnites().contains(unit_type)) {
+	println "No unit with name=$unit_type"
+	return;
+} else {
+	if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+		// test property existance
+		def props = analecCorpus.getStructure().getUniteProperties(unit_type);
+		if (!props.contains(unit_property_name)) {
+			println "Unit $unit_type has no property named $unit_property_name"
+			return;
+		}
+	}
+}
+
+def CQI = Toolbox.getCqiClient()
+
+if (buildCQL) {
+	word_prop = corpus.getProperty("id")
+} else {
+	word_prop = corpus.getProperty(word_property)
+}
+
+def schemas = analecCorpus.getSchemas(schema_type)
+schemas.sort() {it.getProps()}
+def nSchemas = 0
+
+def lens = [:]
+for (def schema : schemas) {
+
+	if (schema_property_name.length() > 0 && schema_property_value.length() > 0) {
+		if (!schema.getProp(schema_property_name).matches(schema_property_value)) {
+			// ignoring this schema
+			continue
+		}
+	}
+	
+	def nUnites = 0
+	for (def unit : schema.getUnitesSousjacentes()) {
+		if (unit_type.length() > 0) {
+			if (!unit.getType().equals(unit_type)) {
+				continue
+			}
+		}
+		
+		if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+			if (!unit.getProp(unit_property_name).matches(unit_property_value)) {
+				// ignoring this schema
+				continue
+			}
+		}
+
+		nUnites++
+	}
+
+	if (nUnites < minimum_schema_size) continue
+
+	print schema.getProps().toString()+ ": "
+	def first = true
+	for (def unit : schema.getUnitesSousjacentes()) {
+		if (unit_type.length() > 0) {
+			if (!unit.getType().equals(unit_type)) {
+				continue
+			}
+		}
+		
+		if (unit_property_name.length() > 0 && unit_property_value.length() > 0) {
+			if (!unit.getProp(unit_property_name).matches(unit_property_value)) {
+				// ignoring this schema
+				continue
+			}
+		}
+
+		String forme =  null;
+
+		if (buildCQL) {
+			int[] pos = null
+			if (unit.getDeb() == unit.getFin()) pos = [unit.getDeb()]
+			else pos = (unit.getDeb()..unit.getFin())
+			def first2= true
+			q = ""
+			pos.each {
+				if (first2) { first2 = false } else { q = q+" " }
+				int[] pos2 = [it]
+				q = q+"["+word_prop+"=\""+CQI.cpos2Str(word_prop.getQualifiedName(), pos2)[0]+"\"]"
+			}
+			if (first) { first = false } else { print "|" }
+			print "("+q+")"
+		} else {
+			if (word_prop == null) { // word_property is the analec unit property to use
+			forme = unit.getProp(word_property)
+			} else {
+			int[] pos = null
+			if (unit.getDeb() == unit.getFin()) pos = [unit.getDeb()]
+			else pos = (unit.getDeb()..unit.getFin())
+				
+			forme = StringUtils.join(CQI.cpos2Str(word_prop.getQualifiedName(), pos), " ") // ids is enough
+			}
+
+			if (first) { first = false } else { print separator }
+			print forme
+		}
+	}
+	println ""
+
+	nSchemas++
+}
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CompUnitPropertiesMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CompUnitPropertiesMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/CompUnitPropertiesMacro.groovy	(revision 481)
@@ -0,0 +1,62 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.apache.commons.lang.StringUtils;
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.Toolbox;
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.AbstractCqiClient;
+import org.txm.searchengine.cqp.corpus.*
+import visuAnalec.donnees.Structure;
+import visuAnalec.elements.Unite;
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
+String unit_type
+
+@Field @Option(name="unit_property_name1", usage="", widget="String", required=false, def="CATEGORIE")
+String unit_property_name1
+
+@Field @Option(name="unit_property_name2", usage="", widget="String", required=false, def="CATEGORIE_ORIG")
+String unit_property_name2
+
+if (!ParametersDialog.open(this)) return;
+
+int n = 1;
+int nDiff = 0;
+MainCorpus corpus = corpusViewSelection
+AbstractCqiClient CQI = Toolbox.getCqiClient();
+def word = corpus.getWordProperty()
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+
+def units = analecCorpus.getUnites(unit_type)
+units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
+for (Unite unit : units) {
+	int[] pos = null
+	if (unit.getDeb() == unit.getFin()) pos = [unit.getDeb()]
+	else pos = (unit.getDeb()..unit.getFin())
+	def form = StringUtils.join(CQI.cpos2Str(word.getQualifiedName(), pos), " ")
+	def props = unit.getProps()
+	def v1 = props.get(unit_property_name1);
+	def v2 = props.get(unit_property_name2);
+	
+	if (v1 != v2) {
+		println "$n - ${unit.getDeb()} -> ${unit.getFin()} - $props : $form"
+		nDiff++
+	}
+	n++
+}
+
+if (nDiff == 0) println "$unit_property_name1 and $unit_property_name2 have the same values."
+else println "$unit_property_name1 and $unit_property_name2 have $nDiff/$n different values."
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitTypesInSchemaMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitTypesInSchemaMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/UnitTypesInSchemaMacro.groovy	(revision 481)
@@ -0,0 +1,48 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="schema_type",usage="", widget="String", required=true, def="Coréférence")
+String schema_type
+
+if (!ParametersDialog.open(this)) return;
+
+MainCorpus corpus = corpusViewSelection
+def analecCorpus = AnalecCorpora.getCorpus(corpus.getName());
+def map = new HashMap()
+def unitesInSchema = []
+def n = 0
+for (def schema : analecCorpus.getSchemas(schema_type)) {
+	def unites = schema.getUnitesSousjacentes()
+	unitesInSchema.addAll(unites)
+	n += unites.size()
+}
+
+def counts = unitesInSchema.countBy() { it };
+for (def c : counts.keySet()) {
+	if (counts[c] > 1) println "ERROR UNIT IN MULTIPLE SCHEMA["+c.getDeb()+", "+c.getFin()+"]="+c.getProps()+" in "+c.getSchemas().collect() {it.getProps()}
+}
+
+def set = new HashSet()
+set.addAll(unitesInSchema)
+for (def s : set.collect { it.getType() }) {
+	if (!map.containsKey(s)) map[s] = 0;
+	map[s] = map[s] +1
+}
+
+println "Unites types: "+map.sort() { it -> map[it]}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/AllMesuresMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/AllMesuresMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/AllMesuresMacro.groovy	(revision 481)
@@ -0,0 +1,158 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.analec
+
+import org.kohsuke.args4j.*
+import groovy.transform.Field
+import org.txm.*
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.corpus.*
+import org.apache.commons.lang.StringUtils;
+
+// BEGINNING OF PARAMETERS
+
+@Field @Option(name="tsvFile",usage="", widget="FileSave", required=true, def="result.tsv")
+File tsvFile
+@Field @Option(name="default_schema_type",usage="", widget="String", required=true, def="Coréférence")
+String default_schema_type
+@Field @Option(name="default_minimum_schema_size", usage="", widget="Integer", required=true, def="3")
+int default_minimum_schema_size
+@Field @Option(name="default_schema_property_name",usage="", widget="String", required=false, def="")
+String default_schema_property_name
+@Field @Option(name="default_schema_property_value",usage="", widget="String", required=false, def=".*")
+String default_schema_property_value
+@Field @Option(name="schema_display_property_name",usage="", widget="String", required=false, def="Nom du référent")
+String schema_display_property_name
+@Field @Option(name="default_unit_type",usage="", widget="String", required=false, def="Maillon")
+String default_unit_type
+@Field @Option(name="default_unit_property_name", usage="", widget="String", required=false, def="")
+String default_unit_property_name
+@Field @Option(name="default_unit_property_value", usage="", widget="String", required=false, def=".*")
+String default_unit_property_value
+@Field @Option(name="default_word_property", usage="", widget="StringArray", metaVar="word	lemma	frlemma	frolemma #forme#", required=false, def="word")
+String default_word_property
+@Field @Option(name="default_pos_property", usage="", widget="StringArray", metaVar="Catégorie	pos	fropos	frpos", required=false, def="Catégorie")
+String default_pos_property
+
+if (!ParametersDialog.open(this)) return;
+// END OF PARAMETERS
+
+println "Corpora selections: "+corpusViewSelections
+
+table = [] // contains all table lines
+mesures = []
+
+for (def corpus : corpusViewSelections) { // for each corpus selected in the corpora view
+	if (!(corpus instanceof MainCorpus)) continue; // check if the corpus is a maincorpus
+	def line = [] ; table << line // create and add a new table line
+	line << corpus.getName() // add the corpus name in the first column
+	
+	println "*** Computing mesures for $corpus" // each macro return a "result" and a "data"
+
+	params = [
+		"unit_type":default_unit_type,
+		"unit_property_name":"",
+		"unit_property_value":"",
+	]
+	returnedValue = execMesure(DensiteReferentielleMacro, line, corpus, params)
+	line << returnedValue["result"]
+	
+	params = [
+		"schema_type":default_schema_type,
+		"minimum_schema_size":default_minimum_schema_size,
+		"schema_property_name":"",
+		"schema_property_value":"",
+		"unit_type":default_unit_type,
+		"unit_property_name":"",
+		"unit_property_value":"",
+	]
+	returnedValue = execMesure(LongueurMoyenneMacro, line, corpus, params)
+	line << returnedValue["result"]
+	
+	params = [
+		"schema_type":default_schema_type,
+		"minimum_schema_size":default_minimum_schema_size,
+		"schema_property_name":"",
+		"schema_property_value":"",
+		"unit_type":default_unit_type,
+		"unit_property_name":"",
+		"unit_property_value":"",
+	]
+	returnedValue = execMesure(NombreDeChainesMacro, line, corpus, params)
+	line << returnedValue["result"]
+	
+	params = [
+		"schema_type":default_schema_type,
+		"minimum_schema_size":default_minimum_schema_size,
+		"schema_property_name":"",
+		"schema_property_value":"",
+		"schema_display_property_name":schema_display_property_name,
+		"unit_type":default_unit_type,
+		"unit_property_name":"Catégorie",
+		"unit_property_value":"GN Défini|GN Démonstratif|Nom Propre",
+		"word_property":default_word_property,
+	]
+	returnedValue = execMesure(CoefficientStabiliteMacro, line, corpus, params)
+	line << returnedValue["result"]
+	
+	params = [
+		"schema_type":default_schema_type,
+		"minimum_schema_size":default_minimum_schema_size,
+		"schema_property_name":"",
+		"schema_property_value":"",
+		"unit_type":default_unit_type,
+		"unit_property_name":"",
+		"unit_property_value":"",
+	]
+	returnedValue = execMesure(DistanceInterMaillonnaireMacro, line, corpus, params)
+	line << returnedValue["result"]
+
+	params = [
+		"schema_type":default_schema_type,
+		"minimum_schema_size":default_minimum_schema_size,
+		"schema_property_name":"",
+		"schema_property_value":"",
+		"unit_type":default_unit_type,
+		"unit_property_name":"",
+		"unit_property_value":"",
+		"word_property":default_pos_property,
+	]
+	returnedValue = execMesure(NatureDuPremierMaillonMacro, line, corpus, params)
+	line << returnedValue["data"]
+	
+	params = [
+		"schema_type":default_schema_type,
+		"minimum_schema_size":default_minimum_schema_size,
+		"schema_property_name":"",
+		"schema_property_value":"",
+		"schema_display_property_name":schema_display_property_name,
+		"unit_type":default_unit_type,
+		"unit_property_name":"",
+		"unit_property_value":"",
+		"word_property":default_pos_property,
+	]
+	returnedValue = execMesure(CategorieGrammaticaleMacro, line, corpus, params)
+	line << returnedValue["data"]
+}
+
+// WRITE RESULTS IN THE TSV FILE
+tsvFile.withWriter("UTF-8") { writer ->
+	writer.println "\t"+mesures.join("\t")
+	table.each { line -> writer.println line.join("\t")	}
+}
+
+println "Done. Results are saved in ${tsvFile.getAbsolutePath()} file."
+
+// UTILITY FUNCTIONS
+def execMesure(def mesure, def line, def corpus, def params) {
+	def m = mesure.getSimpleName().substring(0, mesure.getSimpleName().indexOf("Macro"))
+	mesures << m
+	println "***** ${mesures.size()}- $m with parameters: $params"
+	def r = gse.run(mesure, ["args":params, "corpusViewSelection":corpus, "monitor":monitor])
+	if (r == null) throw new Exception("Null result");
+	return r;
+}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/analec/Fropos2CategorieMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/analec/Fropos2CategorieMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/analec/Fropos2CategorieMacro.groovy	(revision 481)
@@ -0,0 +1,145 @@
+package org.txm.macro.analec
+
+import org.apache.commons.lang.*
+import org.kohsuke.args4j.*
+import groovy.transform.*
+import org.txm.*
+import org.txm.rcpapplication.swt.widget.parameters.*
+import org.txm.analec.*
+import org.txm.searchengine.cqp.*
+import org.txm.searchengine.cqp.corpus.*
+import visuAnalec.Message.*
+import visuAnalec.donnees.*
+import visuAnalec.elements.*
+import visuAnalec.vue.*
+
+def testRules(def positions, def Mention) {
+	def catégorie = null
+
+// DÉFINITION DES RÈGLES
+// elles sont testées les unes après les autres. 
+// Dès qu'une règle est appliquée les suivantes sont ignorées.
+
+// Règles de type CONTIENT
+
+	     if (Mention.contains("NOMpro")) catégorie = "Nom Propre"
+	else if (Mention.contains("DETpos")) catégorie = "Dét Possessif"
+//  ...
+
+// Règles de type COMMENCE ET NE CONTIENT PAS	
+
+	else if (Mention.first() == "DETpos" && !Mention.contains("NOMpro")) catégorie = "GN Possessif"
+	else if (Mention.first() == "DETdem" && !Mention.contains("NOMpro")) catégorie = "GN Démonstratif"
+//  ...
+
+// Règles de type CONTIENT PLUSIEURS	
+
+	else if (Mention.contains("PROadv") || Mention.contains("ADVgen.PROadv")) catégorie = "Pronom Adverbial"
+//  ...
+
+// Règles de type CONTIENT ET NE CONTIENT PAS
+
+	else if (
+			 ( Mention.contains("DETdef") || Mention.contains("PRE.DETdef") )
+			  &&
+			  !Mention.contains("PROpos") && !Mention.contains("NOMpro") && !Mention.contains("PROcar")
+			) catégorie = "GN Défini"
+//  ...	
+
+// Fin des règles, aucune n'a matchée. On stocke le pattern  qu'on affichera à la fin.
+	else {
+		def forms = CQI.cpos2Str(word.getQualifiedName(), positions)
+		if (!errors.containsKey(Mention)) errors[Mention] = new HashSet()
+		errors[Mention] << forms
+	}
+	
+	return catégorie
+}
+
+//
+// FIN DE LA DÉFINITION DES RÈGLES
+//
+
+// CORPS DU SCRIPT
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a Corpus"
+	return
+}
+
+// BEGINNING OF PARAMETERS
+@Field @Option(name="unit_type", usage="", widget="String", required=true, def="MENTION")
+def unit_type
+@Field @Option(name="pos_property_name", usage="", widget="String", required=true, def="pos")
+def pos_property_name
+@Field @Option(name="reset", usage="", widget="Boolean", required=true, def="true")
+def reset
+if (!ParametersDialog.open(this)) return
+
+corpus = corpusViewSelection
+CQI = Toolbox.getCqiClient()
+word = corpus.getWordProperty()
+posProperty = corpus.getProperty(pos_property_name)
+if (posProperty == null) {
+	println "Error: CQP corpus does not contains the word property with name=$pos_property_name"
+	return
+}
+analecCorpus = AnalecCorpora.getCorpus(corpus.getName())
+vue = AnalecCorpora.getVue(corpus.getName())
+structure = analecCorpus.getStructure()
+if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
+	println "Error: corpus structure does not contains unit with name=$unit_type"
+	return
+}
+
+CATEGORIE = "CATEGORIE"
+// Si la structure d'annotation ne contient pas CATEGORIE, on la crée avec ses valeurs
+if (!structure.getUniteProperties(unit_type).contains(CATEGORIE)) { 
+// la propriété
+	analecCorpus.ajouterProp(Unite.class, unit_type, CATEGORIE)
+// les valeurs
+	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Nom Propre")
+	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Impersonnel")
+	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Interrogatif")
+	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Pronom cardinal")
+	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Démonstratif")
+	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Indéfini")
+	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom ordinal")
+	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Relatif")
+//...
+}
+
+def nModified = 0
+def nIgnored = 0
+
+errors = new HashMap()
+def units = analecCorpus.getUnites(unit_type)
+units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
+for (Unite unit : units) { // process all units
+	
+	def prop = unit.getProp(CATEGORIE)
+	if (!reset && prop != null && prop.length() > 0) continue // l'unité a déjà une CATEGORIE
+	
+	int[] positions = null
+	if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
+	else positions = (unit.getDeb()..unit.getFin())
+	
+	def Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
+	def cat = testRules(positions, Mention)
+	
+	if (cat != null) {
+		vue.setValeurChamp(unit, CATEGORIE, cat)
+		nModified++
+	} else {
+		nIgnored++
+	}
+}
+
+println "Result:"
+println "- $nModified units of type $unit_type have been modified."
+println "- $nIgnored units of type $unit_type have not been modified.\n"
+
+if (errors.size() > 0) {
+	println "Some rules should be added to this macro to process the following remaining 'FROPOS / words' values:"
+	errors.keySet().each { println "fropos="+it+"\twords="+errors[it].join(" | ") }
+}
Index: tmp/org.txm.analec.rcp/src/org/eclipse/jface/fieldassist/TXMAutoCompleteField.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/eclipse/jface/fieldassist/TXMAutoCompleteField.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/eclipse/jface/fieldassist/TXMAutoCompleteField.java	(revision 481)
@@ -0,0 +1,111 @@
+package org.eclipse.jface.fieldassist;
+
+import org.eclipse.jface.bindings.keys.KeyStroke;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * AutoCompleteField is a class which attempts to auto-complete a user's
+ * keystrokes by activating a popup that filters a list of proposals according
+ * to the content typed by the user.
+ * 
+ * @see ContentProposalAdapter
+ * @see SimpleContentProposalProvider
+ * 
+ * @since 3.3
+ */
+public class TXMAutoCompleteField {
+
+	private SimpleContentProposalProvider proposalProvider;
+	private TXMContentProposalAdapter adapter;
+	boolean open = false;
+
+	public boolean isOpen() { return adapter.isProposalPopupOpen();};
+	
+	/**
+	 * Construct an AutoComplete field on the specified control, whose
+	 * completions are characterized by the specified array of Strings.
+	 * 
+	 * @param control
+	 *            the control for which autocomplete is desired. May not be
+	 *            <code>null</code>.
+	 * @param controlContentAdapter
+	 *            the <code>IControlContentAdapter</code> used to obtain and
+	 *            update the control's contents. May not be <code>null</code>.
+	 * @param proposals
+	 *            the array of Strings representing valid content proposals for
+	 *            the field.
+	 */
+	public TXMAutoCompleteField(Control control,
+			IControlContentAdapter controlContentAdapter, String[] proposals, KeyStroke keyStroke) {
+		this(control, controlContentAdapter, proposals, keyStroke, null);
+	}
+	
+	/**
+	 * Construct an AutoComplete field on the specified control, whose
+	 * completions are characterized by the specified array of Strings.
+	 * 
+	 * @param control
+	 *            the control for which autocomplete is desired. May not be
+	 *            <code>null</code>.
+	 * @param controlContentAdapter
+	 *            the <code>IControlContentAdapter</code> used to obtain and
+	 *            update the control's contents. May not be <code>null</code>.
+	 * @param proposals
+	 *            the array of Strings representing valid content proposals for
+	 *            the field.
+	 */
+	public TXMAutoCompleteField(Control control,
+			IControlContentAdapter controlContentAdapter, String[] proposals, KeyStroke keyStroke, char[] autoActivationCharacters) {
+		proposalProvider = new SimpleContentProposalProvider(proposals);
+		proposalProvider.setFiltering(true);
+		adapter = new TXMContentProposalAdapter(control, controlContentAdapter,
+				proposalProvider, keyStroke, autoActivationCharacters);
+		adapter.setPropagateKeys(true);
+		adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
+		adapter.addContentProposalListener(new IContentProposalListener2() {
+			@Override
+			public void proposalPopupOpened(ContentProposalAdapter adapter) {
+				open = true;
+			}
+			
+			@Override
+			public void proposalPopupClosed(ContentProposalAdapter adapter) {
+				open = false;
+			}
+		});
+	}
+	
+	/**
+	 * Construct an AutoComplete field on the specified control, whose
+	 * completions are characterized by the specified array of Strings.
+	 * 
+	 * @param control
+	 *            the control for which autocomplete is desired. May not be
+	 *            <code>null</code>.
+	 * @param controlContentAdapter
+	 *            the <code>IControlContentAdapter</code> used to obtain and
+	 *            update the control's contents. May not be <code>null</code>.
+	 * @param proposals
+	 *            the array of Strings representing valid content proposals for
+	 *            the field.
+	 */
+	public TXMAutoCompleteField(Control control,
+			IControlContentAdapter controlContentAdapter, String[] proposals) {
+		this(control, controlContentAdapter, proposals, null, null);
+	}
+
+	/**
+	 * Set the Strings to be used as content proposals.
+	 * 
+	 * @param proposals
+	 *            the array of Strings to be used as proposals.
+	 */
+	public void setProposals(String[] proposals) {
+		proposalProvider.setProposals(proposals);
+	}
+
+	public void open() {
+		if (open) adapter.close();
+		else adapter.open();
+	}
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src/org/eclipse/jface/fieldassist/TXMAutoCompleteField.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/eclipse/jface/fieldassist/TXMContentProposalAdapter.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/eclipse/jface/fieldassist/TXMContentProposalAdapter.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/eclipse/jface/fieldassist/TXMContentProposalAdapter.java	(revision 481)
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Hannes Erven <hannes@erven.at> - Bug 293841 - [FieldAssist] NumLock keyDown event should not close the proposal popup [with patch]
+ *******************************************************************************/
+package org.eclipse.jface.fieldassist;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.jface.bindings.keys.KeyStroke;
+import org.eclipse.jface.dialogs.PopupDialog;
+import org.eclipse.jface.preference.JFacePreferences;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.Util;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * ContentProposalAdapter can be used to attach content proposal behavior to a
+ * control. This behavior includes obtaining proposals, opening a popup dialog,
+ * managing the content of the control relative to the selections in the popup,
+ * and optionally opening up a secondary popup to further describe proposals.
+ * <p>
+ * A number of configurable options are provided to determine how the control
+ * content is altered when a proposal is chosen, how the content proposal popup
+ * is activated, and whether any filtering should be done on the proposals as
+ * the user types characters.
+ * <p>
+ * This class provides some overridable methods to allow clients to manually
+ * control the popup. However, most of the implementation remains private.
+ * 
+ * @since 3.2
+ */
+public class TXMContentProposalAdapter extends ContentProposalAdapter {
+	public TXMContentProposalAdapter(Control control, IControlContentAdapter controlContentAdapter, IContentProposalProvider proposalProvider, KeyStroke keyStroke, char[] autoActivationCharacters) {
+		super(control, controlContentAdapter, proposalProvider, keyStroke, autoActivationCharacters);
+		// TODO Auto-generated constructor stub
+	}
+	
+	public void open() {
+		super.openProposalPopup();
+	}
+	
+	public void close() {
+		super.closeProposalPopup();
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/eclipse/jface/fieldassist/TXMContentProposalAdapter.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/analecrcp/Activator.java
===================================================================
--- tmp/org.txm.analec.rcp/src/analecrcp/Activator.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/analecrcp/Activator.java	(revision 481)
@@ -0,0 +1,50 @@
+package analecrcp;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "AnalecRCP"; //$NON-NLS-1$
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+}

Property changes on: tmp/org.txm.analec.rcp/src/analecrcp/Activator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesSchemas.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesSchemas.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesSchemas.java	(revision 481)
@@ -0,0 +1,524 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.Message.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.texte.PanneauAffTexte.*;
+import visuAnalec.texte.PanneauTexte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class PanneauCommandesSchemas extends PanneauCommandes implements ActionListener {
+  private PanneauChamps panneauChamps;
+  private TypeComboBox saisieTypeSchemas;
+  private ElementComboBox saisieSchema;
+  private TypeComboBox saisieTypeElt;
+  private ElementComboBox saisieElt;
+  private JButton creeSchema;
+  private JButton supprimeSchema;
+  private JButton ajouteElement;
+  private JButton oteElement;
+  private JButton creeUniteElt;
+  private int[] bornesSelectTexte;
+  /*
+  
+   * CREATION PAR LE PANNEAU EDITEUR
+   */
+  PanneauCommandesSchemas(Vue vue, PanneauAffTexte pTexte, PanneauChamps pChamps) {
+    super(vue, pTexte);
+    JToolBar barre1 = new JToolBar();
+    barre1.setPreferredSize(new Dimension(0, 22));
+//    barre1.setBackground(PanneauTexte.getCouleurFond1());
+    barre1.setAlignmentX(0.0f);
+    //    barre1.setFloatable(false);
+    add(barre1);
+    JToolBar barre2 = new JToolBar();
+    barre2.setPreferredSize(new Dimension(0, 22));
+//    barre2.setBackground(PanneauTexte.getCouleurFond2());
+    barre2.setAlignmentX(0.0f);
+//     barre2.setFloatable(false);
+    add(barre2);
+    panneauChamps = pChamps;
+    saisieTypeSchemas = new TypeComboBox(Schema.class);
+    saisieTypeSchemas.addActionListener(this);
+    saisieSchema = new ElementComboBox();
+    saisieSchema.addActionListener(this);
+    saisieTypeElt = new TypeComboBox(Element.class);
+    saisieTypeElt.addActionListener(this);
+    saisieElt = new ElementComboBox();
+    saisieElt.addActionListener(this);
+    creeSchema = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerSchema();
+      }
+    });
+    supprimeSchema = new JButton(new GAction("Supprimer") {
+      public void executer() {
+        supprimerSchema();
+      }
+    });
+    ajouteElement = new JButton(new GAction("Ajouter") {
+      public void executer() {
+        ajouterElement();
+      }
+    });
+    oteElement = new JButton(new GAction("Oter") {
+      public void executer() {
+        oterElement();
+      }
+    });
+    creeUniteElt = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerUniteElt();
+      }
+    });
+    barre1.addSeparator();
+    barre1.add(new TitreBarre("Schéma : ", PanneauTexte.getCouleurFond1()));
+    barre1.addSeparator();
+    barre1.add(saisieTypeSchemas);
+    barre1.add(saisieSchema);
+    barre1.addSeparator();
+    barre1.add(creeSchema);
+    barre1.addSeparator();
+    barre1.add(supprimeSchema);
+    barre2.addSeparator();
+    barre2.add(new TitreBarre("Elément : ", PanneauTexte.getCouleurFond2()));
+    barre2.addSeparator();
+    barre2.add(saisieTypeElt);
+    barre2.add(saisieElt);
+    barre2.addSeparator();
+    barre2.add(ajouteElement);
+    barre2.add(oteElement);
+    barre2.add(creeUniteElt);
+  }
+
+  /*
+   * COMMANDES UTILISEES PAR LE PANNEAU EDITEUR
+   */
+  public void reinitialiser() {
+    // typiquement, appelé par le panneau éditeur à la suite d'une modif de vue ou de structure
+    saisieTypeSchemas.removeActionListener(this);
+    saisieTypeSchemas.setModele(vue.getTypesSchemasAVoir());
+    saisieTypeSchemas.effSelection();
+    saisieTypeSchemas.addActionListener(this);
+    saisieTypeElt.removeActionListener(this);
+    saisieTypeElt.setModele(vue.getTypes(Unite.class), vue.getTypes(Relation.class), vue.getTypes(Schema.class));
+    saisieTypeElt.effSelection();
+    saisieTypeElt.addActionListener(this);
+    initSaisieSchema();
+    initSaisieElt();
+    etatSelectRien();
+    revalidate();
+    repaint();
+  }
+  public void reafficher() {
+    // potentiellement appelé par le panneau éditeur ?
+    // appelé aussi par  traiterElementEvent
+    if (saisieSchema.pasdeSelection()) {
+      initSaisieSchema();
+      if (saisieElt.pasdeSelection()) {
+        initSaisieElt();
+        etatSelectRien();
+      } else {
+        Element eltCourant = saisieElt.getSelection();
+        initSaisieElt(eltCourant);
+        etatSelectElt(eltCourant);
+      }
+    } else {
+      Schema schCourant = (Schema) saisieSchema.getSelection();
+      initSaisieSchema(schCourant);
+      if (saisieElt.pasdeSelection()) {
+        initSaisieElt();
+        etatSelectSchema(schCourant);
+      } else {
+        Element eltCourant = saisieElt.getSelection();
+        initSaisieElt(eltCourant);
+        etatSelectSchemaElt(schCourant, eltCourant);
+      }
+    }
+  }
+   public void elementSuivant(int sens) {
+    if (sens>0) saisieSchema.gotoSuivant();
+    else saisieSchema.gotoPrecedent();
+  }
+ public Element elementSelectionne() {
+    if (saisieSchema.pasdeSelection()) return null;
+    return saisieSchema.getSelection();
+  }
+  public void editerElement(Element elt) {
+    // appelé par le panneauEditeur : elt est forcément un schéma
+    if (elt.getClass() != Schema.class) throw new UnsupportedOperationException("Erreur : classe incorrecte");
+    editerSchema((Schema) elt);
+  }
+  public void traiterElementEvent(ElementEvent evt) {
+    switch (evt.getModif()) {
+      case AJOUT_SCHEMA:
+      case MODIF_SCHEMA:
+        Schema sch = (Schema) evt.getElement();
+        editerSchema(sch);
+        return;
+      case SUP_SCHEMA:
+        if (evt.getElement() == saisieSchema.getSelection()) {
+          initSaisieSchema();
+          initSaisieElt();
+          etatSelectRien();
+        } else {
+          reafficher();
+        }
+        return;
+      case AJOUT_UNITE:
+        if (saisieTypeElt.getClasseSelection() == Unite.class ||
+                evt.getElement().getType().equals(saisieTypeElt.getTypeSelection())) {
+          initSaisieElt(evt.getElement());
+        }
+        reafficher();
+        return;
+      case SUP_UNITE:
+      case SUP_RELATION:
+      case BORNES_UNITE:
+      case AJOUT_RELATION:
+      case MODIF_VALEUR:
+        reafficher();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas " + evt.getModif() + " oublié dans un switch");
+    }
+  }
+  public void editerSchema(Schema sch) {
+    // appelé  par traiterElementEvent, 
+    // et aussi directement par le panneau éditeur quand il est sollicité par d'autres fenêtres
+    if (!sch.getType().equals(saisieTypeSchemas.getTypeSelection())) {
+      saisieTypeSchemas.removeActionListener(this);
+      saisieTypeSchemas.setSelection(sch.getType());
+      saisieTypeSchemas.addActionListener(this);
+    }
+    initSaisieSchema(sch);
+    saisieSchema.setSelection(sch);
+  }
+  public void editerSchemaElement(Schema sch, Element elt) {
+    // appelé  par le panneau éditeur  sollicité par VisuChaines 
+    if (!sch.getType().equals(saisieTypeSchemas.getTypeSelection())) {
+      saisieTypeSchemas.removeActionListener(this);
+      saisieTypeSchemas.setSelection(sch.getType());
+      saisieTypeSchemas.addActionListener(this);
+    }
+    initSaisieSchema(sch);
+    forceElt(elt);
+  }
+ public void editerElementTypeSchema(Element elt, String typesch) {
+    // appelé  par le panneau éditeur  sollicité par VisuChaines 
+    if (!typesch.equals(saisieTypeSchemas.getTypeSelection())) {
+      saisieTypeSchemas.removeActionListener(this);
+      saisieTypeSchemas.setSelection(typesch);
+      saisieTypeSchemas.addActionListener(this);
+    }
+    initSaisieSchema();
+    forceElt(elt);
+  }
+  public ArrayList<ElementMarque> trouverElementsVises(Unite uniteVisee, TypeMarquage marqueUniteVisee,
+          boolean avecId) {
+    ArrayList<ElementMarque> eltsMarques = new ArrayList<ElementMarque>();
+    ArrayList<Element> eltsVises;
+    Element eltVise;
+    switch (marqueUniteVisee) {
+      case FOND1:
+        eltsVises = Element.trouverElementsParUniteSousjacente(saisieSchema.getElements(), uniteVisee);
+        for (Element elt : eltsVises) eltsMarques.add(new ElementMarque(
+                  elt, marqueUniteVisee, avecId ? saisieSchema.getIdElement(elt) : null));
+        return eltsMarques;
+      case FOND1_2:
+      case FOND2:
+        eltsVises = Element.trouverElementsParUniteSousjacente(saisieElt.getElements(), uniteVisee);
+        for (Element elt : eltsVises) eltsMarques.add(new ElementMarque(
+                  elt, marqueUniteVisee, avecId ? saisieElt.getIdElement(elt) : null));
+        return eltsMarques;
+      case SELECT1:
+        eltVise = saisieSchema.getSelection();
+        eltsMarques.add(new ElementMarque(
+                  eltVise, marqueUniteVisee, avecId ? saisieSchema.getIdElement(eltVise) : null));
+        return eltsMarques;
+      case SELECT1_2:
+      case SELECT2:
+        eltVise = saisieElt.getSelection();
+        eltsMarques.add(new ElementMarque(
+                eltVise, marqueUniteVisee, avecId ? saisieElt.getIdElement(eltVise) : null));
+        return eltsMarques;       
+      default:
+        throw new UnsupportedOperationException("Marquage non prévu : " + marqueUniteVisee);
+
+    }
+  }
+  /*
+   * ACTIONS DE L'UTILISATEUR : CHANGEMENTS D'ETAT
+   */
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource() == saisieTypeSchemas) {
+        initSaisieSchema();
+        if (saisieElt.pasdeSelection()) etatSelectRien();
+        else etatSelectElt(saisieElt.getSelection());
+        return;
+      }
+      if (evt.getSource() == saisieTypeElt) {
+        initSaisieElt();
+        if (saisieSchema.pasdeSelection()) etatSelectRien();
+        else etatSelectSchema((Schema) saisieSchema.getSelection());
+        return;
+      }
+      if (evt.getSource() == saisieSchema) {
+        if (saisieSchema.pasdeSelection()) {
+          if (saisieElt.pasdeSelection()) etatSelectRien();
+          else etatSelectElt(saisieElt.getSelection());
+        } else {
+          if (saisieElt.pasdeSelection()) etatSelectSchema((Schema) saisieSchema.getSelection());
+          else etatSelectSchemaElt((Schema) saisieSchema.getSelection(), saisieElt.getSelection());
+        }
+        return;
+      }
+      if (evt.getSource() == saisieElt) {
+        if (saisieElt.pasdeSelection()) {
+          if (saisieSchema.pasdeSelection()) etatSelectRien();
+          else etatSelectSchema((Schema) saisieSchema.getSelection());
+        } else {
+          if (saisieSchema.pasdeSelection()) etatSelectElt(saisieElt.getSelection());
+          else etatSelectSchemaElt((Schema) saisieSchema.getSelection(), saisieElt.getSelection());
+        }
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : " + evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  @Override
+  public void traiterSourisEvent(SourisEvent evt) {
+    switch (evt.getTypeEvent()) {
+      case SELECT_RIEN:
+        saisieElt.removeActionListener(this);
+        saisieElt.effSelection();
+        saisieElt.addActionListener(this);
+        saisieSchema.effSelection();
+        return;
+      case SELECT_ELEMENT:
+        switch (evt.getMarquageElementVise()) {
+          case SELECT1:
+            forceElt(evt.getElementVise());
+            return;
+          case SELECT2:
+          case SELECT1_2:
+            saisieSchema.effSelection();
+            return;
+          case FOND1:
+            saisieSchema.setSelection(evt.getElementVise());
+            return;
+          case FOND2:
+          case FOND1_2:
+            saisieElt.setSelection(evt.getElementVise());
+            return;
+          default:
+            throw new UnsupportedOperationException("Marquage non prévu : " + evt.getTypeEvent());
+        }
+      case SELECT_TEXTE:
+        saisieElt.removeActionListener(this);
+        saisieElt.effSelection();
+        saisieElt.addActionListener(this);
+        saisieSchema.removeActionListener(this);
+        saisieSchema.effSelection();
+        saisieSchema.addActionListener(this);
+        bornesSelectTexte = evt.getBornesSelectionTexte();
+        etatSelectTexte();
+        return;
+    }
+    throw new UnsupportedOperationException("Evénement non prévu : " + evt.getTypeEvent());
+  }
+
+  /*
+   * ACTIONS DE L'UTILISATEUR : BOUTONS
+   */
+  private void creerSchema() {
+    vue.getCorpus().addSchemaSaisi(saisieTypeSchemas.getTypeSelection(), saisieElt.getSelection());
+  }
+  private void creerUniteElt() {
+    if (vue.getCorpus().checkPresenceUnite(saisieTypeElt.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1]) &&
+            !GMessages.confirmationAction("Dupliquer cette unité  ?")) return;
+    vue.getCorpus().addUniteSaisie(saisieTypeElt.getTypeSelection(),  bornesSelectTexte[0], bornesSelectTexte[1]);
+  }
+  private void supprimerSchema() {
+    if (!GMessages.confirmationAction("Supprimer le schéma sélectionné ?")) return;
+    vue.getCorpus().supSchema((Schema) saisieSchema.getSelection());
+  }
+  private void ajouterElement() {
+    vue.getCorpus().ajouterElementSchemaSaisi(saisieElt.getSelection(), (Schema) saisieSchema.getSelection());
+  }
+  private void oterElement() {
+    vue.getCorpus().oterElementSchema(saisieElt.getSelection(), (Schema) saisieSchema.getSelection());
+  }
+
+  /* 
+   * GESTION INTERNE
+   */
+  private void etatSelectRien() { // ni Sch ni Elt n'ont été saisis
+    if (saisieTypeElt.pasdeSelection()) {
+      if (saisieTypeSchemas.pasdeSelection()) panneauTexte.pasDeMarquage();
+      else panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieSchema.getElements()), TypeMarquage.FOND1);
+    } else {
+      if (saisieTypeSchemas.pasdeSelection()) panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieElt.getElements()), TypeMarquage.FOND2);
+      else panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieSchema.getElements()), TypeMarquage.FOND1,
+                Element.getUnitesSousjacentes(saisieElt.getElements()), TypeMarquage.FOND2);
+    }
+    panneauChamps.effacer();
+    creeSchema.setEnabled(false);
+    supprimeSchema.setEnabled(false);
+    ajouteElement.setEnabled(false);
+    oteElement.setEnabled(false);
+    creeUniteElt.setEnabled(false);
+  }
+  private void etatSelectTexte() { // du texte a été sélectionné
+    if (saisieTypeElt.pasdeSelection()) {
+      if (saisieTypeSchemas.pasdeSelection()) panneauTexte.pasDeMarquage();
+      else panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieSchema.getElements()), TypeMarquage.FOND1);
+    } else {
+      if (saisieTypeSchemas.pasdeSelection()) panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieElt.getElements()), TypeMarquage.FOND2);
+      else panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieSchema.getElements()), TypeMarquage.FOND1,
+                Element.getUnitesSousjacentes(saisieElt.getElements()), TypeMarquage.FOND2);
+    }
+    panneauChamps.effacer();
+    creeSchema.setEnabled(false);
+    supprimeSchema.setEnabled(false);
+    ajouteElement.setEnabled(false);
+    oteElement.setEnabled(false);
+    if (!saisieTypeElt.pasdeSelection() && saisieTypeElt.getClasseSelection() == Unite.class)
+      creeUniteElt.setEnabled(true);
+  }
+  private void etatSelectElt(Element elt) {  // seul Elt a été choisi 
+    if (saisieTypeSchemas.pasdeSelection()) panneauTexte.saisir(elt.getUnite0(),
+              elt.getUnitesSousjacentes(), TypeMarquage.SELECT2);
+    else panneauTexte.saisir(elt.getUnite0(), elt.getUnitesSousjacentes(), TypeMarquage.SELECT2,
+              Element.getUnitesSousjacentes(saisieSchema.getElements()), TypeMarquage.FOND1);
+    panneauChamps.afficher(elt);
+    if (!saisieTypeSchemas.pasdeSelection()) {
+      creeSchema.setEnabled(true);
+      Boutons.setDefaut(creeSchema, true);
+    }
+    supprimeSchema.setEnabled(false);
+    ajouteElement.setEnabled(false);
+    oteElement.setEnabled(false);
+    creeUniteElt.setEnabled(false);
+  }
+  private void etatSelectSchema(Schema sch) { // seul Sch a été choisi
+    if (saisieTypeElt.pasdeSelection()) panneauTexte.saisir(sch.getUnite0(),
+              sch.getUnitesSousjacentes(), TypeMarquage.SELECT1);
+    else panneauTexte.saisir(sch.getUnite0(),
+              sch.getUnitesSousjacentes(), TypeMarquage.SELECT1,
+              Element.getUnitesSousjacentes(filtreSch(saisieElt.getElements(), (Schema[])saisieSchema.getElements())),
+              TypeMarquage.FOND1_2,
+              Element.getUnitesSousjacentes(saisieElt.getElements()), TypeMarquage.FOND2);
+    panneauChamps.afficher(sch);
+    creeSchema.setEnabled(false);
+    supprimeSchema.setEnabled(true);
+    ajouteElement.setEnabled(false);
+    oteElement.setEnabled(false);
+    creeUniteElt.setEnabled(false);
+  }
+  private void etatSelectSchemaElt(Schema sch, Element elt) {
+    if (sch.contient(elt)) etatSelectSchemaEltInterne(sch, elt);
+    else etatSelectSchemaEltExterne(sch, elt);
+  }
+  private void etatSelectSchemaEltInterne(Schema sch, Element elt) {
+    panneauTexte.saisir(elt.getUnite0(),
+            elt.getUnitesSousjacentes(), TypeMarquage.SELECT1_2,
+            sch.getUnitesSousjacentes(), TypeMarquage.SELECT1);
+    panneauChamps.afficher(elt);
+    creeSchema.setEnabled(false);
+    ajouteElement.setEnabled(false);
+    if (sch.getContenu().size() > 1) {
+      oteElement.setEnabled(true);
+      supprimeSchema.setEnabled(false);
+    } else {
+      oteElement.setEnabled(false);
+      supprimeSchema.setEnabled(true);
+    }
+    creeUniteElt.setEnabled(false);
+  }
+  private void etatSelectSchemaEltExterne(Schema sch, Element elt) {
+    panneauTexte.saisir(elt.getUnite0(),
+            sch.getUnitesSousjacentes(), TypeMarquage.SELECT1,
+            elt.getUnitesSousjacentes(), TypeMarquage.SELECT2);
+    panneauChamps.afficher(sch);
+    creeSchema.setEnabled(false);
+    supprimeSchema.setEnabled(false);
+    ajouteElement.setEnabled(true);
+    oteElement.setEnabled(false);
+    creeUniteElt.setEnabled(false);
+  }
+  private void forceElt(Element elt) {
+    if (saisieTypeElt.getClasseSelection() != elt.getClass() || !elt.getType().equals(saisieTypeElt.getTypeSelection())) {
+      saisieTypeElt.removeActionListener(this);
+      saisieTypeElt.setSelection(elt.getClass(), elt.getType());
+      saisieTypeElt.addActionListener(this);
+      initSaisieElt();
+    }
+    saisieElt.setSelection(elt);
+  }
+  private Element[] filtreSch(Element[] elts, Schema[] schs) {
+    ArrayList<Element> elts1 = new ArrayList<Element>();
+    for (Element elt : elts) for(Schema sch: schs) if(sch.getContenu().contains(elt)) {
+      elts1.add(elt);
+      break;
+    }
+    return elts1.toArray(new Element[0]);
+  }
+  private void initSaisieSchema(Schema sch) {
+    saisieSchema.removeActionListener(this);
+    if (saisieTypeSchemas.pasdeSelection()) saisieSchema.setModeleVide();
+    else {
+      String type0 = saisieTypeSchemas.getTypeSelection();
+      Schema[] schemas = vue.getSchemasAVoir(type0);
+      saisieSchema.setModele(schemas, vue.getIdSchemas(type0, schemas));
+    }
+    if (sch == null) saisieSchema.effSelection();
+    else saisieSchema.setSelection(sch);
+    saisieSchema.addActionListener(this);
+    saisieSchema.revalidate();
+  }
+  private void initSaisieSchema() {
+    initSaisieSchema(null);
+  }
+  private void initSaisieElt(Element elt) {
+    saisieElt.removeActionListener(this);
+    if (saisieTypeElt.pasdeSelection()) saisieElt.setModeleVide();
+    else {
+      Class<? extends Element> classe = saisieTypeElt.getClasseSelection();
+      String type = saisieTypeElt.getTypeSelection();
+      saisieElt.setModele(vue.getElements(classe, type), vue.getIdElements(classe, type));
+    }
+    if (elt == null) saisieElt.effSelection();
+    else saisieElt.setSelection(elt);
+    saisieElt.addActionListener(this);
+    saisieElt.revalidate();
+  }
+  private void initSaisieElt() {
+    initSaisieElt(null);
+  }
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesSchemas.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/GBarres.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/GBarres.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/GBarres.java	(revision 481)
@@ -0,0 +1,101 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.statistiques;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.plaf.*;
+import visuAnalec.util.GMessages;
+
+
+/**
+ *
+ * @author Bernard
+ */
+public class GBarres extends JComponent implements TableModelListener {
+
+  ModeleStatsFrequences modele;
+  BarresPainter painter;
+
+  GBarres(ModeleStatsFrequences modele) {
+    super();
+    setUI(painter = new BarresPainter());
+    this.modele = modele;
+//    System.out.println("---\nCréation : " + getPreferredSize() + " -> " + getSize());
+
+
+  }
+
+  public void tableChanged(TableModelEvent evt) {
+    try {
+      ArrayList<Float> longueurs = new ArrayList<Float>();
+      ArrayList<String> noms = new ArrayList<String>();
+      for (int i = 0; i < modele.getRowCount() - 1; i++) {
+        if ((Integer) modele.getValueAt(i, 1) > 0) {
+          longueurs.add((Float) modele.getValueAt(i, 2));
+          noms.add((String) modele.getValueAt(i, 0));
+        }
+      }
+//    System.out.println(noms + "\n" + getPreferredSize() + " -> " + getSize());
+      painter.setLongueursBarres(longueurs.toArray(new Float[0]));
+      painter.setNomsBarres(noms.toArray(new String[0]));
+      repaint();
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+}
+class BarresPainter extends ComponentUI {
+
+  private String[] nomsBarres = new String[0];
+  private Float[] longueursBarres = new Float[0];
+  static BarresPainter barresUI = new BarresPainter();
+  private Color[] couleurs = new Color[]{Color.BLUE, Color.CYAN, Color.GREEN, Color.MAGENTA,
+    Color.RED, Color.YELLOW, Color.LIGHT_GRAY, Color.ORANGE, Color.PINK
+  };
+  private int margeX = 5;
+  private int interligneY = 5;
+
+  void setLongueursBarres(Float[] longueurs) {
+    longueursBarres = longueurs;
+  }
+
+  void setNomsBarres(String[] noms) {
+    nomsBarres = noms;
+  }
+
+  @Override
+  public void paint(Graphics g, JComponent c) {
+    Dimension dim = c.getSize();
+//    System.out.println(dim);
+    int hauteurMin = g.getFontMetrics().getHeight() + 2;
+    int nbBarres = nomsBarres.length;
+    g.setColor(Color.BLACK);
+    g.drawLine(margeX, interligneY, margeX, 2 * interligneY + (hauteurMin + interligneY) * nbBarres);
+    int largeurMaxTexte = 0;
+    for (int i = 0; i < nbBarres; i++) {
+      largeurMaxTexte = Math.max(largeurMaxTexte,
+              SwingUtilities.computeStringWidth(g.getFontMetrics(), nomsBarres[i]));
+    }
+    for (int i = 0; i < nbBarres; i++) {
+      int y = interligneY + (hauteurMin + interligneY) * i;
+      int longueur = Math.round((dim.width - largeurMaxTexte) * longueursBarres[i] / 100);
+      g.setColor(Color.LIGHT_GRAY); // couleurs[i % couleurs.length]);
+      g.fillRect(margeX, y, longueur, hauteurMin);
+      g.setColor(Color.BLACK);
+      g.drawRect(margeX, y, longueur, hauteurMin);
+      g.drawString(nomsBarres[i], 2 * margeX + longueur, y + hauteurMin);
+    }
+  }
+
+  public static ComponentUI createUI(JComponent c) {
+    return barresUI;
+  }
+}
+
+

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/GBarres.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsFrequences.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsFrequences.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsFrequences.java	(revision 481)
@@ -0,0 +1,90 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+//import donnees.*;
+import java.util.*;
+import javax.swing.table.*;
+import visuAnalec.elements.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class ModeleStatsFrequences extends AbstractTableModel {
+  private String[] nomsValeurs;
+  private int[] nbOcc;
+  private String[] nomsColonnes;
+  private int totalOcc;
+ public ModeleStatsFrequences() {
+    super();
+    initialise();
+  }
+private void initialise() {
+    nomsValeurs = new String[0];
+    nbOcc = new int[]{0};
+    nomsColonnes = new String[]{"", "Nb d'occurrences", "Fréquence (%)"};
+    totalOcc = 0;
+  }
+  public int getRowCount() {
+    return nomsValeurs.length + 2;
+  }
+  public int getColumnCount() {
+    return 3;
+  }
+  @Override
+  public String getColumnName(int col) {
+    return nomsColonnes[col];
+  }
+  public Object getValueAt(int row, int col) {
+    switch (col) {
+      case 0:
+        return row == nomsValeurs.length + 1 ? "TOTAL" : row == nomsValeurs.length ? "<aucune valeur>" : nomsValeurs[row];
+      case 1:
+        return row == nomsValeurs.length + 1 ? totalOcc : nbOcc[row];
+      case 2:
+        return row == nomsValeurs.length + 1 ? 100.0f : Math.round(nbOcc[row] * 10000.0f / totalOcc) / 100.0f;
+      default:
+        return null;
+    }
+  }
+  Element[] getListeElementsRowsSelected(int[] rows, Vue vue, Class<? extends Element> classe, String type,
+          String champCible, String champFiltre, String[] valeursChampFiltre) {
+    if (rows.length == 0 || classe==null) return (new Unite[0]);
+    ArrayList<String> vals = new ArrayList<String>();
+    for (int row : rows) {
+      if (row == nomsValeurs.length + 1) {
+        return vue.getDoubleSelectionOccurrences(classe, type, null, vals.toArray(new String[0]), 
+                champFiltre, valeursChampFiltre);
+      }
+      vals.add(row == nomsValeurs.length ? "" : nomsValeurs[row]);
+    }
+    return vue.getDoubleSelectionOccurrences(classe, type, champCible, vals.toArray(new String[0]), 
+            champFiltre, valeursChampFiltre);
+  }
+  private void setModeleVide() {
+    initialise();
+    fireTableDataChanged();
+  }
+  void setModele(Vue vue, Class<? extends Element> classe, String type, String champCible,
+          String champFiltre, String[] valeursChampFiltre) {
+    if (classe==null || champCible == null || vue.getNbElementsAVoir(classe, type) == 0) {
+      setModeleVide();
+      return;
+    }
+    nomsValeurs = vue.getValeursChamp(classe, type, champCible);
+    nbOcc = new int[nomsValeurs.length + 1];
+    HashMap<String, Integer> compte =
+            vue.compterOccurrencesFiltrees(classe, type, champCible, champFiltre, valeursChampFiltre);
+    totalOcc = 0;
+    for (int row = 0; row < nomsValeurs.length + 1; row++) {
+      nbOcc[row] = compte.get(row == nomsValeurs.length ? "" : nomsValeurs[row]);
+      totalOcc += nbOcc[row];
+    }
+    fireTableDataChanged();
+  }
+}
+

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsFrequences.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsGeometrie.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsGeometrie.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsGeometrie.java	(revision 481)
@@ -0,0 +1,188 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+/**
+ *
+ * @author Bernard
+ */
+import JamaPlus.*;
+import java.awt.*;
+import java.util.*;
+import java.util.ArrayList;
+import visuAnalec.elements.*;
+import visuAnalec.vue.*;
+
+public class ModeleStatsGeometrie {
+  public enum TypeEventDonneesGraphe {
+    NEW_DONNEES,
+    MODIF_DONNEES,
+    CLEAR_DONNEES,
+    NEW_COORDS,
+    NEW_COULEURS,
+    NEW_SELECT_PTS
+  }
+
+  public interface DonneesGrapheListener extends EventListener {
+    void traiterEvent(DonneesGrapheEvent e);
+  }
+
+  public class DonneesGrapheEvent extends EventObject {
+    private TypeEventDonneesGraphe type;
+    DonneesGrapheEvent(Object source, TypeEventDonneesGraphe type) {
+      super(source);
+      this.type = type;
+    }
+    public TypeEventDonneesGraphe getType() {
+      return type;
+    }
+  }
+  private ArrayList<DonneesGrapheListener> listeCorrespondants = new ArrayList<DonneesGrapheListener>();
+  void addEventListener(DonneesGrapheListener correspondant) {
+    listeCorrespondants.add(correspondant);
+  }
+  void removeEventListener(DonneesGrapheListener correspondant) {
+    listeCorrespondants.remove(correspondant);
+  }
+  private void fireDonneesGrapheEvent(DonneesGrapheEvent evt) {
+    for (Object corresp : listeCorrespondants.toArray()) {
+      ((DonneesGrapheListener) corresp).traiterEvent(evt);
+    }
+  }
+  private Vue vue;
+  private Class<? extends Element> classe;
+  private String type;
+  private String[] champsPertinents;
+  private Element[] elementsRetenus;
+  private Matrix Pts;
+  private Color[] couleursPts;
+  private ArrayList<Integer> nosPtsChoisis;
+  public Class<? extends Element> getClasseElements() {
+    return classe;
+  }
+  public String getTypeElements() {
+    return type;
+  }
+  public Matrix getPts() {
+    return Pts;
+  }
+  public Color[] getCouleurs() {
+    return couleursPts;
+  }
+  public boolean[] getEtatsChoixtPts() {
+    boolean[] etats = new boolean[elementsRetenus.length];
+    for (int no : nosPtsChoisis) {
+      etats[no] = true;
+    }
+    return etats;
+  }
+  public ArrayList<ArrayList<String>> getTexteIdElements(ArrayList<Integer> nos) {
+    ArrayList<ArrayList<String>> textesIds = new ArrayList<ArrayList<String>>();
+    ArrayList<String> textes = new ArrayList<String>();
+    ArrayList<String> ids = new ArrayList<String>();
+    for (int i = 0; i<nos.size(); i++) {
+      Element elt = elementsRetenus[nos.get(i)];
+      textes.add(vue.getTexteUnite(elt.getUnite0()));
+      ids.add(vue.getIdElement(elt));
+    }
+    textesIds.add(textes);
+    textesIds.add(ids);
+    return textesIds;
+  }
+  public Element[] getListeElementsChoisis() {
+    Element[] liste = new Element[nosPtsChoisis.size()];
+    for (int i = 0; i<liste.length; i++) {
+      liste[i] = elementsRetenus[nosPtsChoisis.get(i)];
+    }
+    Arrays.sort(liste);
+    return liste;
+  }
+//  public Unite getDerniereUniteChoisie() {
+//    if (nosPtsChoisis.isEmpty()) {
+//      return null;
+//    }
+//    return unitesSelectionnees[nosPtsChoisis.get(nosPtsChoisis.size() - 1)];
+//  }
+  void initialise(Vue vue, Class<? extends Element> classe, String type) {
+    this.vue = vue;
+    this.type = type;
+    this.classe = classe;
+    if (classe==null) {
+      champsPertinents = new String[0];
+      elementsRetenus = new Element[0];
+      Pts = null;
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.CLEAR_DONNEES));
+      return;
+    }
+    champsPertinents = vue.getNomsChamps(classe, type);
+    elementsRetenus = vue.getElementsAVoir(classe, type);
+    if (calculerCoord()) {
+      nosPtsChoisis = new ArrayList<Integer>();
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.NEW_DONNEES));
+    } else {
+      Pts = null;
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.CLEAR_DONNEES));
+    }
+  }
+  void majChampsSelect(String[] champsSelect) {
+    champsPertinents = champsSelect;
+    if (champsSelect.length>0&&calculerCoord()) {
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.NEW_COORDS));
+    } else {
+      Pts = null;
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.CLEAR_DONNEES));
+    }
+  }
+  void majChampAffiche(String champAffiche, HashMap<String, Color> couleurValeur) {
+    couleursPts = new Color[elementsRetenus.length];
+    for (int i = 0; i<elementsRetenus.length; i++) {
+      couleursPts[i] = couleurValeur.get(vue.getValeurChamp(elementsRetenus[i], champAffiche));
+    }
+    fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.NEW_COULEURS));
+  }
+  boolean calculerCoord() {
+//    Matrix mat = vue.getMatrice(classe, type, champsPertinents, elementsRetenus);
+    SparseMatrix mat = vue.getMatriceCreuse(classe, type, champsPertinents, elementsRetenus);
+    Matrix CP = mat.afc().getCP();
+    if (CP==null) return false;
+    if (CP.getColumnDimension()<2) {
+      Pts = new Matrix(elementsRetenus.length, 2);
+      if (CP.getColumnDimension()==1)
+        Pts.setMatrix(0, elementsRetenus.length-1, 0, 0, CP);
+    } else {
+      Pts = CP.getMatrix(0, elementsRetenus.length-1, 0, 1);
+    }
+    return true;
+  }
+  void setPtsChoisis(ArrayList<Integer> nos) {
+    nosPtsChoisis = nos;
+    fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.NEW_SELECT_PTS));
+  }
+  void majPtsChoisis(ArrayList<Integer> nos) {
+    for (Integer no : nos) {
+      if (nosPtsChoisis.contains(no)) {
+        nosPtsChoisis.remove(no);
+      } else {
+        nosPtsChoisis.add(no);
+      }
+    }
+    fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.NEW_SELECT_PTS));
+  }
+  void supPtsChoisis() {
+    ArrayList<Element> EltsSelects = new ArrayList<Element>(
+            Arrays.asList(elementsRetenus));
+    for (Integer no : nosPtsChoisis) {
+      EltsSelects.remove(elementsRetenus[no]);
+    }
+    elementsRetenus = EltsSelects.toArray(new Element[0]);
+    if (calculerCoord()) {
+      nosPtsChoisis = new ArrayList<Integer>();
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.MODIF_DONNEES));
+    } else {
+      Pts = null;
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.CLEAR_DONNEES));
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsGeometrie.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsFrequences.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsFrequences.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsFrequences.java	(revision 481)
@@ -0,0 +1,281 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+import visuAnalec.texte.PanneauOccurrences;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import visuAnalec.*;
+import visuAnalec.Message.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.elements.*;
+import visuAnalec.fichiers.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class VisuStatsFrequences extends JFrame
+        implements VueListener, ActionListener, ListSelectionListener {
+  private Vue vue;
+  private ModeleStatsFrequences donneesFrequences = new ModeleStatsFrequences();
+  private Class<? extends Element> classe;
+  private String type;
+  private String champEtudie;
+  private String champFiltre;
+  private String[] valeursChampFiltre;
+  private TypeComboBox saisieTypeElements;
+  private JComboBox saisieChampEtudie = new JComboBox();
+  private JComboBox saisieChampFiltre = new JComboBox();
+  private JList saisieValeursChampFiltre = new JList();
+  private JTable tableau;
+  private PanneauOccurrences panneauOccurrences;
+  public VisuStatsFrequences(Container fenetre, Vue vue, PanneauEditeur pEditeur) {
+    super("Fréquences");
+    Point pos = new Point(fenetre.getX()+20, fenetre.getY()+50);
+    Dimension dim = new Dimension(fenetre.getWidth(), fenetre.getHeight()-30);
+    setLocation(pos);
+    setSize(dim);
+    this.vue = vue;
+    vue.addEventListener(this);
+
+    // Panneau des commandes
+    Box panneauCommandes = Box.createVerticalBox();
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieType = new JPanel(new FlowLayout());
+    pSaisieType.setBorder(new TitledBorder("Eléments"));
+    saisieTypeElements = new TypeComboBox(Element.class);
+    saisieTypeElements.setModele(vue.getTypesUnitesAVoir(), vue.getTypesRelationsAVoir(),
+            vue.getTypesSchemasAVoir());
+    saisieTypeElements.setEditable(false);
+    saisieTypeElements.setMaximumRowCount(saisieTypeElements.getModel().getSize());
+    saisieTypeElements.addActionListener(this);
+    pSaisieType.add(saisieTypeElements, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieType);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieChamp = new JPanel(new FlowLayout());
+    pSaisieChamp.setBorder(new TitledBorder("Champ à analyser"));
+    saisieChampEtudie.setEditable(false);
+    saisieChampEtudie.addActionListener(this);
+    pSaisieChamp.add(saisieChampEtudie, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieChamp);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieFiltre = new JPanel(new BorderLayout());
+    pSaisieFiltre.setBorder(new TitledBorder("Filtre"));
+    saisieChampFiltre.setEditable(false);
+    saisieChampFiltre.addActionListener(this);
+    pSaisieFiltre.add(saisieChampFiltre, BorderLayout.NORTH);
+    saisieValeursChampFiltre.addListSelectionListener(this);
+    pSaisieFiltre.add(new JScrollPane(saisieValeursChampFiltre), BorderLayout.CENTER);
+    panneauCommandes.add(pSaisieFiltre);
+    panneauCommandes.add(Box.createVerticalGlue());
+    // Panneau du tableau de résultats
+    JPanel panneauAfficheTableau = new JPanel(new BorderLayout());
+    panneauAfficheTableau.setBorder(new TitledBorder("Résultats"));
+    tableau = new JTable(donneesFrequences);
+    tableau.getSelectionModel().addListSelectionListener(this);
+    JScrollPane scrollTableau = new JScrollPane(tableau);
+    panneauAfficheTableau.add(scrollTableau, BorderLayout.CENTER);
+    JPanel pExporterFrequences = new JPanel(new FlowLayout());
+    JButton exporterFrequences = new JButton(new GAction("Exporter le tableau") {
+      public void executer() {
+        FichiersTableur.exporterTable(donneesFrequences);
+      }
+    });
+    pExporterFrequences.add(exporterFrequences, CENTER_ALIGNMENT);
+    panneauAfficheTableau.add(pExporterFrequences, BorderLayout.SOUTH);
+//    panneauAfficheTableau.setPreferredSize(new Dimension(
+//            Math.round((dim.width - panneauCommandes.getPreferredSize().width) / 2),
+//            panneauCommandes.getPreferredSize().height));
+    // Panneau de l'affichage graphique
+    GBarres panneauAfficheBarres = new GBarres(donneesFrequences);
+    JScrollPane scrollPanneauBarres = new JScrollPane(panneauAfficheBarres);
+    scrollPanneauBarres.setBorder(new TitledBorder("Graphique"));
+    scrollPanneauBarres.setPreferredSize(scrollTableau.getPreferredSize());
+    donneesFrequences.addTableModelListener(panneauAfficheBarres);
+    // Panneau de visualisation des occurrences
+    panneauOccurrences = new PanneauOccurrences(vue, pEditeur);
+    JScrollPane scrollPanneauOccurrences = new JScrollPane(panneauOccurrences);
+    scrollPanneauOccurrences.setBorder(
+            new TitledBorder("Visualisation des occurrences"));
+    JButton exporterConcordances = new JButton(
+            new GAction("Exporter les concordances") {
+              public void executer() {
+                FichiersTableur.exporterTable(panneauOccurrences.getModeleTableur());
+              }
+            });
+    JPanel pExporterConcordances = new JPanel(new FlowLayout());
+    pExporterConcordances.add(exporterConcordances, CENTER_ALIGNMENT);
+    // cadre global de la fenêtre
+    JPanel haut = new JPanel(new BorderLayout());
+    haut.add(panneauCommandes, BorderLayout.WEST);
+    haut.add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panneauAfficheTableau, panneauAfficheBarres),
+            BorderLayout.CENTER);
+    JPanel bas = new JPanel(new BorderLayout());
+    bas.add(scrollPanneauOccurrences, BorderLayout.CENTER);
+    bas.add(pExporterConcordances, BorderLayout.SOUTH);
+    JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, haut, bas);
+    setContentPane(split);
+    setVisible(true);
+    split.setDividerLocation(2./3);
+    // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+    // Initialisation
+    saisieTypeElements.effSelection();
+    afficherOccurrences();
+  }
+  private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+  }
+  private void initSaisieChampEtudie() {
+    saisieChampEtudie.removeActionListener(this);
+    saisieChampEtudie.removeAllItems();
+    if (classe!=null) for (String ch : vue.getNomsChamps(classe, type))
+        saisieChampEtudie.addItem(ch);
+    saisieChampEtudie.setSelectedIndex(-1);
+    champEtudie = null;
+    saisieChampEtudie.addActionListener(this);
+  }
+  private void initSaisieChampFiltre() {
+    saisieChampFiltre.removeActionListener(this);
+    saisieChampFiltre.removeAllItems();
+    saisieChampFiltre.addItem("<pas de filtre>");
+    if (classe!=null) for (String ch : vue.getNomsChamps(classe, type))
+        saisieChampFiltre.addItem(ch);
+    saisieChampFiltre.setSelectedIndex(0);
+    champFiltre = null;
+    saisieChampFiltre.addActionListener(this);
+  }
+  private void initSaisieValeursChampFiltre() {
+    saisieValeursChampFiltre.removeListSelectionListener(this);
+    if (champFiltre==null) {
+      saisieValeursChampFiltre.setListData(new String[0]);
+    } else {
+      saisieValeursChampFiltre.setListData(vue.getValeursChamp(classe, type, champFiltre));
+    }
+    saisieValeursChampFiltre.setSelectedIndex(-1);
+    saisieValeursChampFiltre.addListSelectionListener(this);
+  }
+  void afficherOccurrences() {
+    panneauOccurrences.init(classe, type, donneesFrequences.getListeElementsRowsSelected(tableau.getSelectedRows(), vue, classe,
+            type, champEtudie, champFiltre, valeursChampFiltre));
+  }
+  void changerDonnees() {
+    Object[] vals = saisieValeursChampFiltre.getSelectedValues();
+    valeursChampFiltre = new String[vals.length];
+    for (int i = 0; i<vals.length; i++) {
+      valeursChampFiltre[i] = (String) vals[i];
+    }
+    donneesFrequences.setModele(vue, classe, type, champEtudie, champFiltre, valeursChampFiltre);
+  }
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case CORPUS_SAVED:
+          fermerFenetre();
+          return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre stat présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        afficherOccurrences();
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        switch (((StructureEvent) evt).getModif()) {
+          case AJOUT_VALEUR:
+          case RENOM_VALEUR:
+          case FUSION_VALEUR:
+          case SUPPR_VALEUR:
+          case VALEUR_PAR_DEFAUT:
+          case AJOUT_FORME_UNITE:
+            changerDonnees();
+            return;
+          case AJOUT_TYPE:  // à affiner : trop brutal
+          case AJOUT_TYPE_ET_ELEMENTS:
+          case RENOM_TYPE:
+          case FUSION_TYPE:
+          case SUPPR_TYPE:
+          case AJOUT_PROP:
+          case RENOM_PROP:
+          case FUSION_PROP:
+          case SUPPR_PROP:
+            fermerFenetre();
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+        }
+      case MODIF_ELEMENT:
+        ElementEvent evtE = (ElementEvent) evt;
+        if (evtE.getModif()!=TypeModifElement.BORNES_UNITE) changerDonnees();
+        else afficherOccurrences();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource().equals(saisieTypeElements)) {
+        classe = saisieTypeElements.getClasseSelection();
+        type = saisieTypeElements.getTypeSelection();
+        initSaisieChampEtudie();
+        initSaisieChampFiltre();
+        changerDonnees();
+        return;
+      }
+      if (evt.getSource().equals(saisieChampEtudie)) {
+        champEtudie = (String) saisieChampEtudie.getSelectedItem();
+        changerDonnees();
+        return;
+      }
+      if (evt.getSource().equals(saisieChampFiltre)) {
+        int ind = saisieChampFiltre.getSelectedIndex();
+        if (ind==0) champFiltre = null;
+        else champFiltre = (String) saisieChampFiltre.getSelectedItem();
+        initSaisieValeursChampFiltre();
+        changerDonnees();
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  public void valueChanged(ListSelectionEvent evt) {
+    try {
+      if (evt.getValueIsAdjusting()) return;
+      if (evt.getSource().equals(saisieValeursChampFiltre)) {
+        changerDonnees();
+        return;
+      }
+      if (evt.getSource().equals(tableau.getSelectionModel())) {
+        afficherOccurrences();
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.toString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsFrequences.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsGeometrie.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsGeometrie.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsGeometrie.java	(revision 481)
@@ -0,0 +1,367 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.table.*;
+import visuAnalec.*;
+import visuAnalec.Message.*;
+import visuAnalec.elements.*;
+import visuAnalec.fichiers.*;
+import visuAnalec.statistiques.ModeleStatsGeometrie.*;
+import visuAnalec.texte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class VisuStatsGeometrie extends JFrame implements VueListener, ActionListener, DonneesGrapheListener {
+  private Vue vue;
+  private ModeleStatsGeometrie donneesGraphe = new ModeleStatsGeometrie();
+  private GPlanAFC panneauAfficheGraphe;
+  private Class<? extends Element> classe;
+  private String type;
+  private String[] listeChampsSelectionnes;
+  private String champAffiche;
+  private TypeComboBox saisieTypeElements;
+  private JList saisieChampsSelectionnes = new JList();
+  private JComboBox saisieChampAffiche = new JComboBox();
+  private JList legendeChampAffiche = new JList();
+  private PanneauOccurrences panneauOccurrences;
+  public VisuStatsGeometrie(Container fenetre, Vue vue, PanneauEditeur pEditeur) {
+    super("Représentations géométriques");
+    Point pos = new Point(fenetre.getX()+20, fenetre.getY()+20);
+    Dimension dim = new Dimension(fenetre.getWidth(), fenetre.getHeight());
+    setLocation(pos);
+    setSize(dim);
+    this.vue = vue;
+    vue.addEventListener(this);
+
+    // Panneau des commandes
+    Box panneauCommandes = Box.createVerticalBox();
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieType = new JPanel(new FlowLayout());
+    pSaisieType.setBorder(new TitledBorder("Eléments"));
+    saisieTypeElements = new TypeComboBox(Element.class);
+    saisieTypeElements.setModele(vue.getTypesUnitesAVoir(), vue.getTypesRelationsAVoir(),
+            vue.getTypesSchemasAVoir());
+    saisieTypeElements.setEditable(false);
+    saisieTypeElements.addActionListener(this);
+    pSaisieType.add(saisieTypeElements, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieType);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieSelection = new JPanel(new FlowLayout());
+    pSaisieSelection.setBorder(new TitledBorder("Champs pertinents"));
+    pSaisieSelection.add(saisieChampsSelectionnes, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieSelection);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pAfficherGraphe = new JPanel(new FlowLayout());
+    JButton afficherGraphe = new JButton(new GAction("Mettre à jour le graphe") {
+      public void executer() {
+        Object[] valSelect = saisieChampsSelectionnes.getSelectedValues();
+        String[] chs = new String[valSelect.length];
+        for (int i = 0; i<valSelect.length; i++) {
+          chs[i] = (String) valSelect[i];
+        }
+        donneesGraphe.majChampsSelect(chs);
+      }
+    });
+    pAfficherGraphe.add(afficherGraphe, CENTER_ALIGNMENT);
+    panneauCommandes.add(pAfficherGraphe);
+    panneauCommandes.add(Box.createVerticalGlue());
+
+    // Panneau du graphe
+    JPanel panneauAfficheGraphique = new JPanel(new BorderLayout());
+    panneauAfficheGraphique.setBorder(new TitledBorder("Graphique"));
+    panneauAfficheGraphique.setPreferredSize(new Dimension(
+            Math.round((getWidth()-panneauCommandes.getPreferredSize().width)/2),
+            panneauCommandes.getPreferredSize().height));
+    panneauAfficheGraphe = new GPlanAFC(donneesGraphe);
+    JScrollPane scroll1 = new JScrollPane(panneauAfficheGraphe);
+    panneauAfficheGraphique.add(scroll1, BorderLayout.CENTER);
+    JPanel pExporterGraphique = new JPanel(new FlowLayout());
+    JButton exporterGraphiqueSVG = new JButton(
+            new GAction("<html> Exporter le graphique<br>en format xml (.svg)") {
+              public void executer() {
+                FichiersGraphique.exporterGraphiqueSVG(panneauAfficheGraphe);
+              }
+            });
+    JButton exporterGraphiqueEMF = new JButton(
+            new GAction("<html> Exporter le graphique<br>vers MS-Office (.emf)") {
+              public void executer() {
+                FichiersGraphique.exporterGraphiqueEMF(panneauAfficheGraphe);
+              }
+            });
+    //  exporterGraphiqueEMF.setText("<htlm> Exporter le graphique<br>vers MS-Office (.emf)");
+    pExporterGraphique.add(exporterGraphiqueSVG, CENTER_ALIGNMENT);
+    pExporterGraphique.add(exporterGraphiqueEMF, CENTER_ALIGNMENT);
+    panneauAfficheGraphique.add(pExporterGraphique, BorderLayout.SOUTH);
+
+    // Panneau champ affiché 
+    Box panneauChampAffiche = Box.createVerticalBox();
+    panneauChampAffiche.add(Box.createVerticalGlue());
+    JPanel pChampAffiche = new JPanel(new BorderLayout());
+    pChampAffiche.setBorder(new TitledBorder("Champ à afficher"));
+    saisieChampAffiche.setEditable(false);
+    saisieChampAffiche.addActionListener(this);
+    pChampAffiche.add(saisieChampAffiche, BorderLayout.NORTH);
+    legendeChampAffiche.setCellRenderer(new LegendeCellRenderer());
+    pChampAffiche.add(legendeChampAffiche, BorderLayout.CENTER);
+    panneauChampAffiche.add(pChampAffiche);
+
+    // Panneau valeurs typiques 
+    JPanel panneauValTypiques = new JPanel(new BorderLayout());
+    panneauValTypiques.setBorder(new TitledBorder("Valeurs typiques"));
+    JLabel affNbElements = new JLabel("", JLabel.CENTER);
+    panneauValTypiques.add(affNbElements, BorderLayout.NORTH);
+    ModeleValTypiques donneesValTypiques =
+            new ModeleValTypiques(vue, donneesGraphe, affNbElements);
+    donneesGraphe.addEventListener(donneesValTypiques);
+    JTable tableauValTypiques = new JTable(donneesValTypiques);
+    JScrollPane scrollChampAffiche = new JScrollPane(tableauValTypiques);
+    panneauValTypiques.add(scrollChampAffiche, BorderLayout.CENTER);
+
+    // Panneau de visualisation des occurrences
+    panneauOccurrences = new PanneauOccurrences(vue, pEditeur);
+    JScrollPane scrollPanneauOccurrences = new JScrollPane(panneauOccurrences);
+    scrollPanneauOccurrences.setBorder(new TitledBorder("Visualisation des occurrences"));
+      JButton exporterConcordances = new JButton(
+            new GAction("Exporter les concordances") {
+      public void executer() {
+       FichiersTableur.exporterTable(panneauOccurrences.getModeleTableur());
+      }
+    });
+    JPanel pExporterConcordances = new JPanel(new FlowLayout());
+    pExporterConcordances.add(exporterConcordances, CENTER_ALIGNMENT); 
+
+    donneesGraphe.addEventListener(this);  // pour lancer afficheOccurrences
+
+    // cadre global de la fenêtre
+    JSplitPane split1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+            panneauChampAffiche, panneauValTypiques);
+    JSplitPane split2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+            panneauAfficheGraphique, split1);
+    JSplitPane split3 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+            panneauCommandes, split2);
+    JPanel bas = new JPanel(new BorderLayout());
+    bas.add(scrollPanneauOccurrences, BorderLayout.CENTER);
+    bas.add(pExporterConcordances, BorderLayout.SOUTH);
+    JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
+            split3, bas);
+    getContentPane().add(split);
+    setVisible(true);
+    split3.setDividerLocation(0.15);
+    split2.setDividerLocation(0.4);
+    split1.setDividerLocation(0.3);
+    split.setDividerLocation(2./3);
+
+    // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+
+    // Initialisation
+    saisieTypeElements.effSelection();
+  }
+  private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+  }
+  void initSaisieChampsSelectionnes() {
+    if (classe==null) {
+      listeChampsSelectionnes = new String[0];
+      saisieChampsSelectionnes.setListData(listeChampsSelectionnes);
+    } else {
+      listeChampsSelectionnes = vue.getNomsChamps(classe, type);
+      saisieChampsSelectionnes.setListData(listeChampsSelectionnes);
+      saisieChampsSelectionnes.addSelectionInterval(0, listeChampsSelectionnes.length-1);
+    }
+  }
+  void initSaisieChampAffiche() {
+    saisieChampAffiche.removeAllItems();
+    if (classe!=null) {
+      for (String ch : vue.getNomsChamps(classe, type)) {
+        saisieChampAffiche.addItem(ch);
+      }
+    }
+    saisieChampAffiche.setSelectedIndex(-1);
+    champAffiche = null;
+    initLegendeChampAffiche();
+  }
+  void initLegendeChampAffiche() {
+    legendeChampAffiche.setListData(new LegendeLabel[0]);
+    HashMap<String, Color> couleurValeur = new HashMap<String, Color>();
+    couleurValeur.put("", GVisu.getCouleurSansValeur());
+    donneesGraphe.majChampAffiche(champAffiche, couleurValeur);
+  }
+  void majCouleursChampAffiche() {
+    String[] vals = classe==null ? new String[0] : vue.getValeursChamp(classe, type, champAffiche);
+    HashMap<String, Color> couleurValeur = new HashMap<String, Color>();
+    LegendeLabel[] legende = new LegendeLabel[vals.length+1];
+    for (int i = 0; i<vals.length; i++) {
+      legende[i] = new LegendeLabel(vals[i], GVisu.getCouleur(i));
+      couleurValeur.put(vals[i], GVisu.getCouleur(i));
+    }
+    legende[vals.length] = new LegendeLabel("<aucune valeur>", GVisu.getCouleurSansValeur());
+    couleurValeur.put("", GVisu.getCouleurSansValeur());
+    legendeChampAffiche.setListData(legende);
+    donneesGraphe.majChampAffiche(champAffiche, couleurValeur);
+  }
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case CORPUS_SAVED:
+          fermerFenetre();
+          return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre stat présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        fermerFenetre();
+        return;
+      case MODIF_ELEMENT:
+        ElementEvent evtE = (ElementEvent) evt;
+        if (evtE.getModif()!=TypeModifElement.BORNES_UNITE) {
+          fermerFenetre();
+        }
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource().equals(saisieTypeElements)) {
+        classe = saisieTypeElements.getClasseSelection();
+        type = saisieTypeElements.getTypeSelection();
+        donneesGraphe.initialise(vue, classe, type);
+        initSaisieChampsSelectionnes();
+        initSaisieChampAffiche();
+        return;
+      }
+      if (evt.getSource().equals(saisieChampAffiche)) {
+        champAffiche = (String) saisieChampAffiche.getSelectedItem();
+        majCouleursChampAffiche();
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "
+              +evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  public void traiterEvent(DonneesGrapheEvent evt) {
+    switch (evt.getType()) {
+      case NEW_DONNEES:
+      case CLEAR_DONNEES:
+        panneauOccurrences.initVide();
+        return;
+      case MODIF_DONNEES:
+        panneauOccurrences.initVide();
+        majCouleursChampAffiche();
+        return;
+      case NEW_SELECT_PTS:
+        panneauOccurrences.init(classe, type,
+                donneesGraphe.getListeElementsChoisis());
+        return;
+      case NEW_COORDS:
+      case NEW_COULEURS:
+        return;
+      default:
+        throw new UnsupportedOperationException("cas "+evt.getType()
+                +" non traité dans un switch");
+    }
+  }
+
+  static class ModeleValTypiques extends AbstractTableModel
+          implements DonneesGrapheListener {
+    String[] nomsColonnes;
+    Vue.TripletValTypique[] triplets;
+    ModeleStatsGeometrie donnees;
+    Vue vue;
+    JLabel affNbElts;
+    public ModeleValTypiques(Vue vue, ModeleStatsGeometrie donnees, JLabel affNbElts) {
+      super();
+      this.donnees = donnees;
+      this.vue = vue;
+      this.affNbElts = affNbElts;
+      initialise();
+    }
+    private void initialise() {
+      nomsColonnes = new String[]{"Champ", "Valeur", "Pourcentage"};
+      setModeleVide();
+    }
+    private void setModeleVide() {
+      triplets = new Vue.TripletValTypique[0];
+      affNbElts.setText("Pas d'élément sélectionné");
+      fireTableDataChanged();
+    }
+    private void setModele(Class<? extends Element> classe, String type, Element[] elts) {
+      triplets = vue.getValTypiques(classe, type, elts);
+      affNbElts.setText(elts.length==1 ? "Un seul élément sélectionné"
+              : elts.length+" éléments sélectionnés");
+      fireTableDataChanged();
+    }
+    public int getRowCount() {
+      return triplets.length;
+    }
+    public int getColumnCount() {
+      return 3;
+    }
+    @Override
+    public String getColumnName(int col) {
+      return nomsColonnes[col];
+    }
+    public Object getValueAt(int row, int col) {
+      switch (col) {
+        case 0:
+          return triplets[row].champ;
+        case 1:
+          return triplets[row].valeur;
+        case 2:
+          return Math.round(triplets[row].pourcentage*10000)/100.0f;
+        default:
+          return null;
+      }
+    }
+    public void traiterEvent(DonneesGrapheEvent evt) {
+      switch (evt.getType()) {
+        case NEW_DONNEES:
+        case CLEAR_DONNEES:
+        case MODIF_DONNEES:
+          setModeleVide();
+          return;
+        case NEW_SELECT_PTS:
+          setModele(donnees.getClasseElements(), donnees.getTypeElements(),
+                  donnees.getListeElementsChoisis());
+          return;
+        case NEW_COORDS:
+        case NEW_COULEURS:
+          return;
+        default:
+          throw new UnsupportedOperationException("cas "+evt.getType()+" non traité dans un switch");
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsGeometrie.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsCorrelations.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsCorrelations.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsCorrelations.java	(revision 481)
@@ -0,0 +1,146 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import visuAnalec.elements.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class ModeleStatsCorrelations extends AbstractTableModel {
+  private String[] valeursChamp2;
+  private String[] valeursChamp1;
+  private int[][] nbOcc;
+  private int[] totauxChamp1;
+  private int[] totauxChamp2;
+  private int totalTotaux;
+  public ModeleStatsCorrelations() {
+    super();
+    initialise();
+  }
+  private void initialise() {
+    valeursChamp2 = new String[0];
+    valeursChamp1 = new String[0];
+    nbOcc = new int[1][1];
+    totauxChamp1 = new int[1];
+    totauxChamp2 = new int[1];
+    totalTotaux = 0;
+  }
+  public int getRowCount() {
+    return valeursChamp2.length + 2;
+  }
+  public int getColumnCount() {
+    return valeursChamp1.length + 3;
+  }
+  @Override
+  public String getColumnName(int col) {
+    return col == 0 ? "" : col == valeursChamp1.length + 2 ? "TOTAL" : col == valeursChamp1.length + 1 ? "<aucune valeur>" : valeursChamp1[col - 1];
+  }
+  public Object getValueAt(int row, int col) {
+    if (col == 0) {
+      return row == valeursChamp2.length + 1 ? "TOTAL" : row == valeursChamp2.length ? "<aucune valeur>" : valeursChamp2[row];
+    } else if (col == valeursChamp1.length + 2) {
+      return row == valeursChamp2.length + 1 ? totalTotaux : totauxChamp1[row];
+    } else {
+      return row == valeursChamp2.length + 1 ? totauxChamp2[col - 1] : nbOcc[row][col - 1];
+    }
+  }
+  Element[] getListeElementsSelected(Integer[] rows, Integer[] cols, Vue vue, Class<? extends Element> classe, 
+          String type, String champ1, String champ2) {
+    HashSet<Element> liste = new HashSet<Element>();
+    for (int i = 0; i < rows.length; i++) {
+      if(cols[i]==0) continue;
+      if (rows[i] == valeursChamp2.length + 1) {
+        if (cols[i] == valeursChamp1.length + 2) {
+          return vue.getElementsAVoir(classe, type);
+        } else {
+          String[] val1 = cols[i] == valeursChamp1.length + 1 ? new String[]{""} : new String[]{valeursChamp1[cols[i] - 1]};
+          liste.addAll(Arrays.asList(vue.getDoubleSelectionOccurrences(classe, type,champ1, val1, null, null)));
+        }
+      } else {
+        String[] val2 = rows[i] == valeursChamp2.length ? new String[]{""} : new String[]{valeursChamp2[rows[i]]};
+        if (cols[i] == valeursChamp1.length + 2) {
+          liste.addAll(Arrays.asList(vue.getDoubleSelectionOccurrences(classe, type, champ2, val2, null, null)));
+        } else {
+          String[] val1 = cols[i] == valeursChamp1.length + 1 ? new String[]{""} : new String[]{valeursChamp1[cols[i] - 1]};
+          liste.addAll(Arrays.asList(vue.getDoubleSelectionOccurrences(classe, type, champ2, val2, champ1, val1)));
+
+        }
+      }
+    }
+    Element[] tab = liste.toArray(new Element[0]);
+    Arrays.sort(tab);
+    return tab;
+  }
+  void setModele(Vue vue, Class<? extends Element> classe, String type, String champ1, String champ2) {
+    if (classe == null) {
+      setModeleVide();
+      return;
+    }
+    valeursChamp1 = champ1 == null ? new String[0] : vue.getValeursChamp(classe, type, champ1);
+    valeursChamp2 = champ2 == null ? new String[0] : vue.getValeursChamp(classe, type, champ2);
+    nbOcc = new int[valeursChamp2.length + 1][valeursChamp1.length + 1];
+    totauxChamp1 = new int[valeursChamp2.length + 1];
+    totauxChamp2 = new int[valeursChamp1.length + 1];
+    HashMap<String, HashMap<String, Integer>> compte =
+            vue.compterOccurrencesCorrelees(classe, type, champ1, champ2);
+    totalTotaux = 0;
+    for (int col = 0; col < valeursChamp1.length + 1; col++) {
+      HashMap<String, Integer> hm = compte.get(col == valeursChamp1.length ? "" : valeursChamp1[col]);
+      for (int row = 0; row < valeursChamp2.length + 1; row++) {
+        nbOcc[row][col] = hm.get(row == valeursChamp2.length ? "" : valeursChamp2[row]);
+        totauxChamp2[col] += nbOcc[row][col];
+        totauxChamp1[row] += nbOcc[row][col];
+        totalTotaux += nbOcc[row][col];
+      }
+    }
+    fireTableStructureChanged();
+  }
+  private void setModeleVide() {
+    initialise();
+    fireTableDataChanged();
+  }
+}
+
+class CorrelationsRenderer extends DefaultTableCellRenderer {
+  ModeleStatsCorrelations donnees;
+  static Color GRIS_CLAIR = new Color(0.95f, 0.95f, 0.95f);
+  static Color BLEU_CLAIR = new Color(0.9f, 0.9f, 1.0f);
+  public CorrelationsRenderer(ModeleStatsCorrelations donnees) {
+    this.donnees = donnees;
+  }
+  @Override
+  public Component getTableCellRendererComponent(JTable table, Object value,
+          boolean isSelected, boolean hasFocus, int row, int col) {
+    int colTotal = donnees.getColumnCount() - 1;
+    int rowTotal = donnees.getRowCount() - 1;
+    int totalTotaux = (Integer) donnees.getValueAt(rowTotal, colTotal);
+    setBackground(Color.WHITE);
+    setHorizontalTextPosition(JLabel.CENTER);
+    if (col == colTotal || row == rowTotal) {
+      setBackground(BLEU_CLAIR);
+    } else if (col == 0) {
+      setBackground(GRIS_CLAIR);
+      setHorizontalTextPosition(JLabel.LEFT);
+    } else if (totalTotaux > 0) {
+      int c = (Integer) donnees.getValueAt(row, col);
+      float m = ((Integer) donnees.getValueAt(row, colTotal)) * ((Integer) donnees.getValueAt(rowTotal, col)) /
+              totalTotaux * 1.0f;
+      if (c / m > 1.0f) {
+        float corr = Math.min(c / m - 1.0f, 2.0f) * 0.4f;
+        setBackground(new Color(1.0f, 1.0f - corr, 1.0f - corr));
+      }
+    }
+    return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
+  }
+}
+
+

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/ModeleStatsCorrelations.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsCorrelations.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsCorrelations.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsCorrelations.java	(revision 481)
@@ -0,0 +1,254 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import visuAnalec.*;
+import visuAnalec.Message.*;
+import visuAnalec.elements.*;
+import visuAnalec.fichiers.*;
+import visuAnalec.texte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class VisuStatsCorrelations extends JFrame
+        implements VueListener, ActionListener, ListSelectionListener {
+  private Vue vue;
+  private ModeleStatsCorrelations donneesCorrelations = new ModeleStatsCorrelations();
+  private Class<? extends Element> classe;
+  private String type;
+  private String champ1;
+  private String champ2;
+  private TypeComboBox saisieTypeElements;
+  private JComboBox saisieChamp1 = new JComboBox();
+  private JComboBox saisieChamp2 = new JComboBox();
+  private JTable tableau;
+  private PanneauOccurrences panneauOccurrences;
+  public VisuStatsCorrelations(Container fenetre, Vue vue, PanneauEditeur pEditeur) {
+    super("Corrélations");
+    Point pos = new Point(fenetre.getX()+20, fenetre.getY()+50);
+    Dimension dim = new Dimension(fenetre.getWidth(), fenetre.getHeight()-30);
+    setLocation(pos);
+    setSize(dim);
+    this.vue = vue;
+    vue.addEventListener(this);
+    // Panneau des commandes
+    Box panneauCommandes = Box.createVerticalBox();
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieType = new JPanel(new FlowLayout());
+    pSaisieType.setBorder(new TitledBorder("Eléments"));
+    saisieTypeElements = new TypeComboBox(Element.class);
+    saisieTypeElements.setModele(vue.getTypesUnitesAVoir(), vue.getTypesRelationsAVoir(),
+            vue.getTypesSchemasAVoir());
+    saisieTypeElements.setMaximumRowCount(saisieTypeElements.getModel().getSize());
+    saisieTypeElements.setEditable(false);
+    saisieTypeElements.addActionListener(this);
+    pSaisieType.add(saisieTypeElements, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieType);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieChamp1 = new JPanel(new FlowLayout());
+    pSaisieChamp1.setBorder(new TitledBorder("Champ 1 (horizontal)"));
+    saisieChamp1.setEditable(false);
+    saisieChamp1.addActionListener(this);
+    pSaisieChamp1.add(saisieChamp1, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieChamp1);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieChamp2 = new JPanel(new FlowLayout());
+    pSaisieChamp2.setBorder(new TitledBorder("Champ 2 (vertical)"));
+    saisieChamp2.setEditable(false);
+    saisieChamp2.addActionListener(this);
+    pSaisieChamp2.add(saisieChamp2, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieChamp2);
+    panneauCommandes.add(Box.createVerticalGlue());
+    // Panneau du tableau de résultats
+    JPanel panneauAfficheTableau = new JPanel(new BorderLayout());
+    panneauAfficheTableau.setBorder(new TitledBorder("Résultats"));
+    tableau = new JTable(donneesCorrelations);
+    tableau.setDefaultRenderer(Number.class, new CorrelationsRenderer(donneesCorrelations));
+    tableau.setDefaultRenderer(Object.class, new CorrelationsRenderer(donneesCorrelations));
+    tableau.setName("tableauCorrelations");
+    tableau.setCellSelectionEnabled(true);
+    tableau.setRowHeight(40);
+    tableau.getTableHeader().setPreferredSize(new Dimension(tableau.getPreferredSize().width, 40));
+    tableau.getSelectionModel().addListSelectionListener(this);
+    JScrollPane scroll1 = new JScrollPane(tableau);
+    panneauAfficheTableau.add(scroll1, BorderLayout.CENTER);
+    JPanel pExporterCorrelations = new JPanel(new FlowLayout());
+    JButton exporterCorrelations = new JButton(new GAction("Exporter le tableau") {
+      public void executer() {
+        FichiersTableur.exporterTable(donneesCorrelations);
+      }
+    });
+    pExporterCorrelations.add(exporterCorrelations, CENTER_ALIGNMENT);
+    panneauAfficheTableau.add(pExporterCorrelations, BorderLayout.SOUTH);
+    panneauAfficheTableau.setPreferredSize(new Dimension(
+            getWidth()-panneauCommandes.getPreferredSize().width,
+            panneauCommandes.getPreferredSize().height));
+    // Panneau de visualisation des occurrences
+    panneauOccurrences = new PanneauOccurrences(vue, pEditeur);
+    JScrollPane scrollPanneauOccurrences = new JScrollPane(panneauOccurrences);
+    scrollPanneauOccurrences.setBorder(new TitledBorder("Visualisation des occurrences"));
+    JButton exporterConcordances = new JButton(
+            new GAction("Exporter les concordances") {
+              public void executer() {
+                FichiersTableur.exporterTable(panneauOccurrences.getModeleTableur());
+              }
+            });
+    JPanel pExporterConcordances = new JPanel(new FlowLayout());
+    pExporterConcordances.add(exporterConcordances, CENTER_ALIGNMENT);
+    // cadre global de la fenêtre
+    JPanel bas = new JPanel(new BorderLayout());
+    bas.add(scrollPanneauOccurrences, BorderLayout.CENTER);
+    bas.add(pExporterConcordances, BorderLayout.SOUTH);
+    JSplitPane haut = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+            panneauCommandes, panneauAfficheTableau);
+    JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, haut, bas);
+    getContentPane().add(split);
+    setVisible(true);
+    split.setDividerLocation(2./3);
+    // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+    // Initialisation
+    saisieTypeElements.effSelection();
+    afficherOccurrences();
+  }
+  private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+  }
+  private void initSaisieChamps() {
+    for (JComboBox saisieChamp : new JComboBox[]{saisieChamp1, saisieChamp2}) {
+      saisieChamp.removeActionListener(this);
+      saisieChamp.removeAllItems();
+      if (classe!=null) for (String ch : vue.getNomsChamps(classe, type))
+          saisieChamp.addItem(ch);
+      saisieChamp.setSelectedIndex(-1);
+      saisieChamp.addActionListener(this);
+    }
+    champ1 = champ2 = null;
+  }
+  void afficherOccurrences() {
+    ArrayList<Integer> rows = new ArrayList<Integer>();
+    ArrayList<Integer> cols = new ArrayList<Integer>();
+    for (int row : tableau.getSelectedRows()) {
+      for (int col : tableau.getSelectedColumns()) {
+        if (tableau.isCellSelected(row, col)) {
+          rows.add(row);
+          cols.add(col);
+        }
+      }
+    }
+    panneauOccurrences.init(classe, type,
+            donneesCorrelations.getListeElementsSelected(rows.toArray(new Integer[0]),
+            cols.toArray(new Integer[0]), vue, classe, type, champ1, champ2));
+  }
+  void changerDonnees() {
+    donneesCorrelations.setModele(vue, classe, type, champ1, champ2);
+  }
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case CORPUS_SAVED:
+          fermerFenetre();
+          return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre stat présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        afficherOccurrences();
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        switch (((StructureEvent) evt).getModif()) {
+          case AJOUT_VALEUR:
+          case RENOM_VALEUR:
+          case FUSION_VALEUR:
+          case SUPPR_VALEUR:
+          case AJOUT_FORME_UNITE:
+          case VALEUR_PAR_DEFAUT:
+            changerDonnees();
+            return;
+          case AJOUT_TYPE:  // à affiner : trop brutal
+          case AJOUT_TYPE_ET_ELEMENTS:
+          case RENOM_TYPE:
+          case FUSION_TYPE:
+          case SUPPR_TYPE:
+          case AJOUT_PROP:
+          case RENOM_PROP:
+          case FUSION_PROP:
+          case SUPPR_PROP:
+            fermerFenetre();
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+        }
+      case MODIF_ELEMENT:
+        ElementEvent evtE = (ElementEvent) evt;
+        if (evtE.getModif()!=TypeModifElement.BORNES_UNITE) changerDonnees();
+        else afficherOccurrences();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource().equals(saisieTypeElements)) {
+        classe = saisieTypeElements.getClasseSelection();
+        type = saisieTypeElements.getTypeSelection();
+        initSaisieChamps();
+        changerDonnees();
+        return;
+      }
+      if (evt.getSource().equals(saisieChamp1)) {
+        champ1 = (String) saisieChamp1.getSelectedItem();
+        changerDonnees();
+        return;
+      }
+      if (evt.getSource().equals(saisieChamp2)) {
+        champ2 = (String) saisieChamp2.getSelectedItem();
+        changerDonnees();
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.toString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  public void valueChanged(ListSelectionEvent evt) {
+    try {
+      if (evt.getValueIsAdjusting())
+        return;
+      if (evt.getSource().equals(tableau.getSelectionModel())) {
+        afficherOccurrences();
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.toString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/VisuStatsCorrelations.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/GPlanAFC.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/GPlanAFC.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/GPlanAFC.java	(revision 481)
@@ -0,0 +1,420 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+import JamaPlus.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.geom.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.plaf.*;
+import visuAnalec.elements.*;
+import visuAnalec.fichiers.FichiersGraphique.*;
+import visuAnalec.statistiques.ModeleStatsGeometrie.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class GPlanAFC extends JComponent
+        implements DonneesGrapheListener, MouseListener, GraphiqueExport {
+
+  private static class Ellipse {
+
+    double xcentre, ycentre;
+    double grandAxe, petitAxe;
+    double xrotation, yrotation;
+
+    private Ellipse(double xc, double yc, double ga, double pa, double xr, double yr) {
+      xcentre = xc;
+      ycentre = yc;
+      petitAxe = pa;
+      grandAxe = ga;
+      xrotation = xr;
+      yrotation = yr;
+    }
+  }
+  private final static int marge = 20;
+  private final static int delta = 1;
+  private final static int bord = marge - delta;
+  private final static int rayon = 3;
+  private final static int epaisseurSelection = 3;
+  private final static double epsilon = 0.0001;
+  private final static BasicStroke ligneEpaisse = new BasicStroke(epaisseurSelection);
+  private final static BasicStroke ligneFine = new BasicStroke();
+  private final static int dimExport = 500;
+  private double xRange, yRange, xMin, yMin;
+  private double[] xPts, yPts;
+  private int nbPts;
+  private Color[] couleurs;
+  private boolean[] etatPts;
+  private Rectangle[] rects;
+  private Ellipse ellipse;
+  private ModeleStatsGeometrie donnees;
+  private JPopupMenu menu;
+  private double echelleExport;  // pour exporter le graphique
+
+  GPlanAFC(ModeleStatsGeometrie donnees) {
+    super();
+    this.donnees = donnees;
+    donnees.addEventListener(this);
+    addMouseListener(this);
+    menu = new JPopupMenu();
+    menu.add(new GAction("Tout déselectionner") {
+
+      public void executer() {
+        deselectionnerTout();
+      }
+    });
+    menu.add(new GAction("Entourer la sélection") {
+
+      public void executer() {
+        entourerSelection();
+      }
+    });
+    menu.add(new GAction("Supprimer les points") {
+
+      public void executer() {
+        supprimerPts();
+      }
+    });
+    ToolTipManager.sharedInstance().registerComponent(this);
+  }
+
+  @Override
+  public JToolTip createToolTip() {
+    JToolTip jt = new JToolTip();
+//    jt.setBackground(JAUNE_TRES_CLAIR);
+    return jt;
+  }
+
+  public void traiterEvent(DonneesGrapheEvent evt) {
+    switch (evt.getType()) {
+      case NEW_DONNEES:
+      case MODIF_DONNEES:
+        setPts(donnees.getPts());
+        couleurs = new Color[donnees.getPts().getRowDimension()];
+        Arrays.fill(couleurs, GVisu.getCouleurSansValeur());
+        etatPts = donnees.getEtatsChoixtPts();
+        clearEllipse();
+        repaint();
+        return;
+      case NEW_COORDS:
+        setPts(donnees.getPts());
+        repaint();
+        return;
+      case CLEAR_DONNEES:
+        clearPts();
+        repaint();
+        return;
+      case NEW_COULEURS:
+        couleurs = donnees.getCouleurs();
+        repaint();
+        return;
+      case NEW_SELECT_PTS:
+        etatPts = donnees.getEtatsChoixtPts();
+        repaint();
+        return;
+      default:
+        throw new UnsupportedOperationException("cas " + evt.getType() + " non traité");
+    }
+  }
+
+  public void mouseClicked(MouseEvent e) {
+    try {
+      ArrayList<Integer> nos = getPts(getMousePosition());
+      if (!nos.isEmpty() && e.getButton() == MouseEvent.BUTTON1) {
+        clearEllipse();
+        donnees.majPtsChoisis(nos);
+      }
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  public void mousePressed(MouseEvent e) {
+    try {
+      if (e.isPopupTrigger()) {
+        showPopup(e);
+      }
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  public void mouseReleased(MouseEvent e) {
+    try {
+      if (e.isPopupTrigger()) {
+        showPopup(e);
+      }
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  private void showPopup(MouseEvent e) {
+    menu.show(e.getComponent(), e.getX(), e.getY());
+  }
+
+  public void mouseEntered(MouseEvent e) {
+  }
+
+  public void mouseExited(MouseEvent e) {
+  }
+
+  @Override
+  public String getToolTipText() {
+    Point pt = getMousePosition();
+    if (pt == null) return "";
+    ArrayList<Integer> nopts = getPts(pt);
+    if (nopts.isEmpty()) return "";
+    ArrayList<ArrayList<String>> textesEtIds = donnees.getTexteIdElements(nopts);
+    return GVisu.styleIdTooltip(textesEtIds.get(0), textesEtIds.get(1));
+  }
+
+  private void deselectionnerTout() {
+    donnees.setPtsChoisis(new ArrayList<Integer>());
+    clearEllipse();
+  }
+
+  private void entourerSelection() {
+    ArrayList<Integer> nos = setEllipse(donnees.getPts(), donnees.getEtatsChoixtPts());
+    donnees.setPtsChoisis(nos);
+  }
+
+  private void supprimerPts() {
+    int nb = Tableaux.compterValeursVraies(donnees.getEtatsChoixtPts());
+    if (nb == 0) return;
+    if (!GMessages.confirmationAction("Supprimer " + nb
+            + " élément(s) de la représentation ?")) return;
+    donnees.supPtsChoisis();
+  }
+
+  private void setPts(Matrix Pts) {
+    nbPts = Pts.getRowDimension();
+    if (nbPts == 0) {
+      clearPts();
+      return;
+    }
+    xMin = Pts.minColumn(0);
+    yMin = Pts.minColumn(1);
+    xRange = Pts.maxColumn(0) - xMin;
+    yRange = Pts.maxColumn(1) - yMin;
+    xPts = new double[nbPts];
+    yPts = new double[nbPts];
+    rects = new Rectangle[nbPts];
+    for (int i = 0; i < nbPts; i++) {
+      xPts[i] = Pts.get(i, 0) - xMin;
+      yPts[i] = Pts.get(i, 1) - yMin;
+    }
+    ellipse = null;
+  }
+
+  private void clearPts() {
+    nbPts = 0;
+    xRange = 0;
+    yRange = 0;
+    xPts = new double[0];
+    yPts = new double[0];
+    rects = new Rectangle[0];
+    ellipse = null;
+  }
+
+  private void setEtatPts(boolean[] etats) {
+    etatPts = etats;
+  }
+
+  private void setCouleurs(Color[] couleurs) {
+    this.couleurs = couleurs;
+  }
+
+  private ArrayList<Integer> setEllipse(Matrix Pts, boolean[] aentourer) {
+    ArrayList<Integer> listenos = new ArrayList<Integer>();
+    for (int i = 0; i < aentourer.length; i++) if (aentourer[i])
+        listenos.add(i);
+    if (listenos.isEmpty()) return listenos;
+    Matrix PtsEntoures = getPtsUniqueCoord(Pts, listenos);
+    SingularValueDecomposition svd = new SingularValueDecomposition(PtsEntoures.columnCovariance());
+    Matrix C = PtsEntoures.columnMean();
+    double xcentre = C.get(0, 0);
+    double ycentre = C.get(0, 1);
+    Matrix U = svd.getU();
+    double xrotation = U.get(0, 0);
+    double yrotation = U.get(0, 1);
+    double[] s = svd.getSingularValues();
+    Matrix OPts = Pts.firstLineMinus(C).times(U);
+    double[] d2Pts = new double[nbPts];
+    double maxd2Pts = 0;
+    if (s[1] > epsilon) {  // cas général
+      for (int i = 0; i < nbPts; i++) {
+        d2Pts[i] = (OPts.get(i, 0) * OPts.get(i, 0)) / s[0]
+                + (OPts.get(i, 1) * OPts.get(i, 1)) / s[1];
+        if (aentourer[i]) maxd2Pts = Math.max(maxd2Pts, d2Pts[i]);
+      }
+      listenos.clear();
+      for (int i = 0; i < nbPts; i++) if (d2Pts[i] <= maxd2Pts) listenos.add(i);
+    } else if (s[0] > epsilon) { // tous les points sont alignés
+      for (int i = 0; i < nbPts; i++) {
+        d2Pts[i] = (OPts.get(i, 0) * OPts.get(i, 0)) / s[0];
+        if (aentourer[i]) maxd2Pts = Math.max(maxd2Pts, d2Pts[i]);
+      }
+      listenos.clear();
+      for (int i = 0; i < nbPts; i++)
+        if (Math.abs(OPts.get(i, 1)) < epsilon && d2Pts[i] <= maxd2Pts)
+          listenos.add(i);
+    }  // si tous les points sont confondus : on garde listenos et max2Pts=0
+    double r = Math.sqrt(maxd2Pts);
+    double grandaxe = r * Math.sqrt(s[0]);
+    double petitaxe = r * Math.sqrt(s[1]);
+    ellipse = new Ellipse(xcentre - xMin, ycentre - yMin,
+            grandaxe, petitaxe, xrotation, yrotation);
+    return listenos;
+  }
+
+  private void clearEllipse() {
+    ellipse = null;
+  }
+
+  private ArrayList<Integer> getPts(Point pt) {
+    ArrayList<Integer> nos = new ArrayList<Integer>();
+    for (int no = 0; no < nbPts; no++) {
+      if (rects[no].contains(pt)) {
+        nos.add(no);
+      }
+    }
+    return nos;
+  }
+
+  private static Matrix getPtsUniqueCoord(Matrix Pts, ArrayList<Integer> nos) {
+    ArrayList<Integer> noselects = new ArrayList<Integer>();
+    double dx, dy;
+    for (int i : nos) {
+      boolean unique = true;
+      for (int i1 : noselects) {
+        dx = Pts.get(i, 0) - Pts.get(i1, 0);
+        dy = Pts.get(i, 1) - Pts.get(i1, 1);
+        if (dx * dx + dy * dy < epsilon) {
+          unique = false;
+          break;
+        }
+      }
+      if (unique) noselects.add(i);
+    }
+    int[] nosels = new int[noselects.size()];
+    for (int i = 0; i < nosels.length; i++) nosels[i] = noselects.get(i);
+    return Pts.getMatrix(nosels, 0, 1);
+  }
+
+  @Override
+  public void paintComponent(Graphics g0) {
+    if (nbPts == 0) return;
+    Graphics2D g = (Graphics2D) g0;
+    double echelle;
+    int x0, y0, xrg, yrg, x, y;
+    Dimension dim = getSize();
+    if (xRange == 0 && yRange == 0) {
+      x0 = (int) Math.round((dim.width) / 2.0);
+      xrg = 0;
+      y0 = (int) Math.round((dim.height) / 2.0);
+      yrg = 0;
+      echelle = 0;
+    } else if (xRange == 0) {   // impossible en fait : xRange >= yRange
+      x0 = (int) Math.round((dim.width) / 2.0);
+      xrg = 0;
+      y0 = marge;
+      echelle = (dim.height - 2 * marge) / yRange;
+      yrg = (int) Math.round(yRange * echelle);
+    } else if (yRange == 0) {
+      echelle = (dim.width - 2 * marge) / xRange;
+      xrg = (int) Math.round(xRange * echelle);
+      x0 = marge;
+      yrg = 0;
+      y0 = (int) Math.round((dim.height) / 2.0);
+    } else {
+      double echx = (dim.width - 2 * marge) / xRange;
+      double echy = (dim.height - 2 * marge) / yRange;
+      if (echx < echy) {
+        echelle = echx;
+        xrg = (int) Math.round(xRange * echelle);
+        yrg = (int) Math.round(yRange * echelle);
+        x0 = marge;
+        y0 = (int) Math.round((dim.height - yrg) / 2.0);
+      } else {
+        echelle = echy;
+        xrg = (int) Math.round(xRange * echelle);
+        yrg = (int) Math.round(yRange * echelle);
+        x0 = (int) Math.round((dim.width - xrg) / 2.0);
+        y0 = marge;
+      }
+    }
+    g.drawRect(x0 - bord, y0 - bord, xrg + 2 * bord, yrg + 2 * bord);
+    for (int i = 0; i < nbPts; i++) {
+      x = x0 + (int) Math.round(echelle * xPts[i]);
+      y = y0 + (int) Math.round(echelle * yPts[i]);
+      g.setColor(couleurs[i]);
+      rects[i] = new Rectangle(x - rayon, y - rayon, 2 * rayon, 2 * rayon);
+      g.fillOval(x - rayon - 1, y - rayon - 1, 2 * rayon + 2, 2 * rayon + 2);
+      g.setStroke(etatPts[i] ? ligneEpaisse : ligneFine);
+      g.setColor(Color.BLACK);
+      int epais = etatPts[i] ? epaisseurSelection - 1 : 0;
+      g.drawOval(x - (rayon + epais), y - (rayon + epais), 2 * (rayon + epais), 2 * (rayon + epais));
+    }
+    if (ellipse == null) return;
+    double xc = x0 + ellipse.xcentre * echelle;
+    double yc = y0 + ellipse.ycentre * echelle;
+    double ga = ellipse.grandAxe * echelle + rayon + epaisseurSelection - 1;
+    double pa = ellipse.petitAxe * echelle + rayon + epaisseurSelection - 1;
+    Ellipse2D.Double ell = new Ellipse2D.Double(xc - ga, yc - pa, 2 * ga, 2 * pa);
+    g.setStroke(ligneFine);
+    g.draw(AffineTransform.getRotateInstance(ellipse.xrotation, ellipse.yrotation, xc, yc).
+            createTransformedShape(ell));
+  }
+
+  public Dimension initExport() {
+    if (nbPts == 0) return new Dimension(dimExport, dimExport);
+    if (xRange == 0 && yRange == 0) {
+      echelleExport = 0;
+      return new Dimension(2 * marge, 2 * marge);
+    } else if (xRange == 0) { // impossible, en fait
+      echelleExport = dimExport / yRange;
+      return new Dimension(2 * marge, dimExport + 2 * marge);
+    } else if (yRange == 0) {
+      echelleExport = dimExport / xRange;
+      return new Dimension(dimExport + 2 * marge, 2 * marge);
+    } else {
+      echelleExport = dimExport / xRange;
+      return new Dimension(dimExport + 2 * marge,
+              ((int) Math.round(yRange * echelleExport)) + 2 * marge);
+    }
+  }
+
+  public Rectangle getCadre() {
+    if (nbPts == 0) return null;
+    if (xRange == 0 && yRange == 0)
+      return new Rectangle(delta, delta, 2 * bord, 2 * bord);
+    else if (xRange == 0)
+      return new Rectangle(delta, delta, 2 * bord, dimExport + 2 * bord);
+    else if (yRange == 0)
+      return new Rectangle(delta, delta, dimExport + 2 * bord, 2 * bord);
+    else
+      return new Rectangle(delta, delta, dimExport + 2 * bord,
+              ((int) Math.round(yRange * echelleExport)) + 2 * bord);
+  }
+
+  public CercleColore[] getCerclesColores() {
+    CercleColore[] cercles = new CercleColore[nbPts];
+    for (int i = 0; i < nbPts; i++) {
+      cercles[i] = new CercleColore();
+      cercles[i].cx = marge + (int) Math.round(echelleExport * xPts[i]);
+      cercles[i].cy = marge + (int) Math.round(echelleExport * yPts[i]);
+      cercles[i].couleur = couleurs[i];
+      cercles[i].r = rayon;
+    }
+    return cercles;
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/statistiques/GPlanAFC.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/PanneauChamps.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/PanneauChamps.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/PanneauChamps.java	(revision 481)
@@ -0,0 +1,148 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.vue.*;
+
+import ca.odell.glazedlists.swing.AutoCompleteSupport;
+import ca.odell.glazedlists.GlazedLists;
+
+/**
+ *
+ * @author Bernard, cplancq
+ */
+public class PanneauChamps extends JPanel {
+  ArrayList<GChamp> champs = new ArrayList<GChamp>();
+  private Vue vue;
+  private Element element = null;
+  private Class<? extends Element> classe = null;
+  private String type = null;
+  private JPanel cadre;
+  public PanneauChamps(PanneauEditeur pEdit, Vue vue) {
+    super(new BorderLayout());
+    setBorder(new TitledBorder("Champs"));
+    cadre = new JPanel(new GridLayout(0, 1));
+    JScrollPane scroll = new JScrollPane(cadre);
+    add(scroll, BorderLayout.CENTER);
+    this.vue = vue;
+  }
+  void reafficher() {
+    if (element == null) return;
+    type = null;
+    afficher(element);
+  }
+  void afficher(Element elt) {
+    this.element = elt;
+    if (elt.getClass() != classe || !elt.getType().equals(type)) {
+      type = elt.getType();
+      classe = elt.getClass();
+      afficherTouslesChamps();
+    }
+    ((TitledBorder) getBorder()).setTitle("Champs " + GVisu.getNomDeLaClasse(elt) + " :  \"" +
+            vue.getIdElement(elt) + "\"");
+    for (GChamp gc : champs) {
+      gc.afficher(elt);
+    }
+    revalidate();
+    repaint();
+  }
+  void effacer() {
+    cadre.removeAll();
+    type = null;
+    element = null;
+    ((TitledBorder) getBorder()).setTitle("Champs");
+    revalidate();
+    repaint();
+  }
+  private void afficherTouslesChamps() {
+    cadre.removeAll();
+    champs.clear();
+
+    int niveau = 0;
+    for (String[] champsniveau : vue.getChamps(classe, type)) {
+      JPanel panneauniveau = new JPanel();
+ //     panneauniveau.setBorder(new TitledBorder("Niveau " + ++niveau));
+      for (String champ : champsniveau) {
+        GChamp gc = new GChamp(vue, classe, type, champ);
+        champs.add(gc);
+        panneauniveau.add(gc);
+      }
+      cadre.add(panneauniveau);
+    }
+  }
+
+  private static class GChamp extends JPanel implements ActionListener {
+    JComboBox afficheValeurChamp;
+    Vue vue;
+    Class<? extends Element> classe;
+    String type;
+    String champ;
+    Element element = null;
+    GChamp(Vue vue, Class<? extends Element> classe, String type, String champ) {
+      super();
+      this.vue = vue;
+      this.classe = classe;
+      this.type = type;
+      this.champ = champ;
+      Box groupe = Box.createVerticalBox();
+      Box titre = Box.createHorizontalBox();
+      titre.add(Box.createHorizontalGlue());
+      JLabel label = new JLabel(champ, JLabel.CENTER);
+ //     label.setPreferredSize(new Dimension(50, 10));
+      titre.add(label);
+      titre.add(Box.createHorizontalGlue());
+      groupe.add(titre);
+      groupe.add(Box.createVerticalStrut(2));
+      afficheValeurChamp = new JComboBox(vue.getValeursChamp(classe, type, champ));
+      /*
+      * CP: JComboBox avec autocompletion. Dépend de la lib glazedlists
+      * (http://www.glazedlists.com/), (https://github.com/glazedlists/glazedlists)
+      */
+      AutoCompleteSupport support = AutoCompleteSupport.install(afficheValeurChamp, GlazedLists.eventListOf(vue.getValeursChamp(classe, type, champ)));
+      support.setCorrectsCase(false);
+      afficheValeurChamp.setEditable(vue.isChampModifiable(classe, type, champ));
+      afficheValeurChamp.addActionListener(this);
+      groupe.add(afficheValeurChamp);
+      add(groupe);
+    }
+    void afficher(Element elt) {
+      this.element = elt;
+      afficheValeurChamp.removeActionListener(this);
+      String val = vue.getValeurChamp(elt, champ);
+      if (val.isEmpty()) afficheValeurChamp.setSelectedIndex(-1);
+      else afficheValeurChamp.setSelectedItem(val);
+      afficheValeurChamp.addActionListener(this);
+    }
+    public void actionPerformed(ActionEvent evt) {
+      try {
+        if (!afficheValeurChamp.isEditable()) {
+          JOptionPane.showMessageDialog(getTopLevelAncestor(), "Champ non modifiable pour ce type d'éléments",
+                  "Modification impossible", JOptionPane.ERROR_MESSAGE);
+          afficher(element);
+          return;
+        }
+        String newval = ((String) afficheValeurChamp.getSelectedItem());
+        if (newval == null) newval = "";
+        else newval = newval.trim();
+        
+        if (!vue.setValeurChamp(element, champ, newval)) {
+          JOptionPane.showMessageDialog(getTopLevelAncestor(), "Champ non défini pour cet élément",
+                  "Saisie de valeur de champ impossible", JOptionPane.ERROR_MESSAGE);
+          afficher(element);
+        }
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/PanneauChamps.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/Message.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/Message.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/Message.java	(revision 481)
@@ -0,0 +1,149 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.util.*;
+import visuAnalec.elements.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class Message extends EventObject {
+  public enum TypeMessage {
+    CLEAR_CORPUS,
+    NEW_CORPUS,
+    MODIF_TEXTE,
+    MODIF_ELEMENT,
+    MODIF_STRUCTURE,
+    MODIF_VUE,
+    CORPUS_SAVED // corpus annotation and structure are saved
+  }
+
+  public enum TypeModifElement {
+    AJOUT_UNITE,
+    SUP_UNITE,
+    BORNES_UNITE,
+    AJOUT_RELATION,
+    SUP_RELATION,
+    AJOUT_SCHEMA,
+    MODIF_SCHEMA,
+    SUP_SCHEMA,
+    MODIF_VALEUR,
+  }
+
+  public enum TypeModifStructure {
+    AJOUT_TYPE_ET_ELEMENTS,
+    AJOUT_TYPE,
+    AJOUT_PROP,
+    AJOUT_FORME_UNITE,
+    AJOUT_VALEUR,
+    RENOM_TYPE,
+    RENOM_PROP,
+    RENOM_VALEUR,
+    FUSION_TYPE,
+    FUSION_PROP,
+    FUSION_VALEUR,
+    SUPPR_TYPE,
+    SUPPR_PROP,
+    SUPPR_VALEUR,
+    VALEUR_PAR_DEFAUT,
+  }
+
+  public enum TypeModifVue {
+    EXTRACTION,
+    NEW_VUE,
+    VUE_DEFAUT,
+  }
+  TypeMessage type;
+  public Message(Object source, TypeMessage type) {
+    super(source);
+    this.type = type;
+  }
+  public TypeMessage getType() {
+    return type;
+  }
+
+  public static class VueEvent extends Message {
+    private TypeModifVue modif;
+    private Unite unite;
+    private String[] args;
+    public VueEvent(Object source, TypeModifVue modif, String... args) {
+      super(source, TypeMessage.MODIF_VUE);
+      this.modif = modif;
+      this.args = args;
+    }
+    public VueEvent(Object source, TypeModifVue modif, Unite unite, String... args) {
+      super(source, TypeMessage.MODIF_VUE);
+      this.unite = unite;
+      this.modif = modif;
+      this.args = args;
+    }
+    public TypeModifVue getModif() {
+      return modif;
+    }
+    public Unite getUnite() {
+      return unite;
+    }
+    public String getArg() {
+      return args[0];
+    }
+    public String getArg(int i) {
+      return args[i];
+    }
+  }
+
+  public static class ElementEvent extends Message {
+    private TypeModifElement modif;
+    private Element element;
+    private String[] args;
+    public ElementEvent(Object source, TypeModifElement modif, Element element, String... args) {
+      super(source, TypeMessage.MODIF_ELEMENT);
+      this.modif = modif;
+      this.element = element;
+      this.args = args;
+    }
+    public TypeModifElement getModif() {
+      return modif;
+    }
+    public Element getElement() {
+      return element;
+    }
+    public String getArg() {
+      return args[0];
+    }
+    public String getArg(int i) {
+      return args[i];
+    }
+  }
+
+  public static class StructureEvent extends Message {
+    private TypeModifStructure modif;
+    private Class<? extends Element> classe;
+    private String[] args;
+    public StructureEvent(Object source, TypeModifStructure modif, Class<? extends Element> classe, String... args) {
+      super(source, TypeMessage.MODIF_STRUCTURE);
+      this.modif = modif;
+      this.classe = classe;
+      this.args = args;
+    }
+    public TypeModifStructure getModif() {
+      return modif;
+    }
+    public Class<? extends Element> getClasse() {
+      return classe;
+    }
+    public String getArg() {
+      return args[0];
+    }
+    public String getArg(int i) {
+      return args[i];
+    }
+  }
+}
+
+
+
+

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/Message.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesUnites.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesUnites.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesUnites.java	(revision 481)
@@ -0,0 +1,276 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.Message.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.texte.PanneauAffTexte.*;
+import visuAnalec.texte.PanneauTexte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class PanneauCommandesUnites extends PanneauCommandes implements ActionListener {
+  private PanneauChamps panneauChamps;
+  public TypeComboBox saisieTypeUnites;
+  private ElementComboBox saisieUnite;
+  private JButton creeUnite;
+  private JButton supprimeUnite;
+  private JButton rectifieBorne;
+  private int[] bornesSelectTexte;
+
+  /*
+   * CREATION PAR LE PANNEAU EDITEUR
+   */
+  PanneauCommandesUnites(Vue vue, PanneauAffTexte pTexte, PanneauChamps pChamps) {
+    super(vue, pTexte);
+    JToolBar barre1 = new JToolBar("Gestion des unités");
+    barre1.setPreferredSize(new Dimension(0, 22));
+//    barre1.setBackground(PanneauTexte.getCouleurFond1());
+    barre1.setAlignmentX(0.0f);
+    add(barre1);
+    panneauChamps = pChamps;
+    saisieTypeUnites = new TypeComboBox(Unite.class);
+    saisieTypeUnites.addActionListener(this);
+    saisieUnite = new ElementComboBox();
+    saisieUnite.addActionListener(this);
+    creeUnite = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerUnite();
+      }
+    });
+    supprimeUnite = new JButton(new GAction("Supprimer") {
+      public void executer() {
+        supprimerUnite();
+      }
+    });
+    rectifieBorne = new JButton(new GAction("Rectifier une borne") {
+      public void executer() {
+        modifierBorne();
+      }
+    });
+    barre1.addSeparator();
+    barre1.add(new TitreBarre("Unité : ", PanneauTexte.getCouleurFond1()));
+    barre1.addSeparator();
+    barre1.add(saisieTypeUnites);
+    barre1.add(saisieUnite);
+    barre1.addSeparator();
+    barre1.add(creeUnite);
+    barre1.addSeparator();
+    barre1.add(supprimeUnite);
+    barre1.addSeparator();
+    barre1.add(rectifieBorne);
+  }
+
+  /*
+   * COMMANDES UTILISEES PAR LE PANNEAU EDITEUR
+   */
+  public void reinitialiser() {
+    // typiquement, appelé par le panneau éditeur à la suite d'une modif de vue ou de structure
+    saisieTypeUnites.removeActionListener(this);
+    saisieTypeUnites.setModele(vue.getTypesUnitesAVoir());
+    saisieTypeUnites.effSelection();
+    saisieTypeUnites.addActionListener(this);
+    supprimeUnite.setEnabled(false);
+    rectifieBorne.setEnabled(false);
+    initSaisieUnite();
+    etatSelectRien();
+    revalidate();
+    repaint();
+  }
+  public void reafficher() {
+    // potentiellement appelé par le panneau éditeur ?
+    // appelé aussi par  traiterElementEvent
+    if (saisieUnite.pasdeSelection()) {
+      initSaisieUnite();
+      etatSelectRien();
+    } else {
+      Unite uniteCourante = (Unite) saisieUnite.getSelection();
+      initSaisieUnite(uniteCourante);
+      etatSelectUnite(uniteCourante);
+    }
+  }
+  public void elementSuivant(int sens) {
+    if (sens>0) saisieUnite.gotoSuivant();
+    else saisieUnite.gotoPrecedent();
+  }
+  public Element elementSelectionne() {
+    if (saisieUnite.pasdeSelection()) return null;
+    return saisieUnite.getSelection();
+  }
+  public void editerElement(Element elt) {
+    // appelé par le panneauEditeur : elt est forcément une unité
+    if (elt.getClass()!=Unite.class)
+      throw new UnsupportedOperationException("Erreur : classe incorrecte");
+    editerUnite((Unite) elt);
+  }
+  public ArrayList<ElementMarque> trouverElementsVises(Unite uniteVisee, TypeMarquage marqueUniteVisee,
+          boolean avecId) {
+    ArrayList<ElementMarque> eltsMarques = new ArrayList<ElementMarque>();
+    eltsMarques.add(new ElementMarque(uniteVisee, marqueUniteVisee,
+            avecId ? saisieUnite.getIdElement(uniteVisee) : null));
+    return eltsMarques;
+  }
+  public void traiterElementEvent(ElementEvent evt) {
+    // relayé par le panneau éditeur 
+    switch (evt.getModif()) {
+      case AJOUT_UNITE:
+        Unite unite = (Unite) evt.getElement();
+        editerUnite(unite);
+        return;
+      case SUP_UNITE:
+        if (evt.getElement()==saisieUnite.getSelection()) {
+          initSaisieUnite();
+          etatSelectRien();
+        } else {
+          reafficher();
+        }
+        return;
+      case BORNES_UNITE:
+        return;  // traité directement par le panneau Texte : à revoir ?
+      case AJOUT_RELATION:
+      case AJOUT_SCHEMA:
+      case SUP_RELATION:
+      case MODIF_SCHEMA:
+      case SUP_SCHEMA:
+      case MODIF_VALEUR:
+        reafficher();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getModif()+" oublié dans un switch");
+    }
+  }
+  void editerUnite(Unite unite) {
+    // appelé  par traiterElementEvent, 
+    // et aussi directement par le panneau éditeur quand il est sollicité par d'autres fenêtres
+    if (!unite.getType().equals(saisieTypeUnites.getTypeSelection())) {
+      saisieTypeUnites.removeActionListener(this);
+      saisieTypeUnites.setSelection(unite.getType());
+      saisieTypeUnites.addActionListener(this);
+    }
+    initSaisieUnite(unite);
+    etatSelectUnite(unite);
+  }
+  /*
+   * ACTIONS DE L'UTILISATEUR : CHANGEMENTS D'ETAT
+   */
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource()==saisieTypeUnites) {
+        initSaisieUnite();
+        if (bornesSelectTexte==null) etatSelectRien();
+        else {
+          panneauTexte.getCaret().setSelectionVisible(true);
+          etatSelectTexte();
+        }
+        return;
+      }
+      if (evt.getSource()==saisieUnite) {
+        if (saisieUnite.pasdeSelection()) etatSelectRien();
+        else etatSelectUnite((Unite) saisieUnite.getSelection());
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  @Override
+  public void traiterSourisEvent(SourisEvent evt) {
+    switch (evt.getTypeEvent()) {
+      case SELECT_RIEN:
+        saisieUnite.effSelection();
+        bornesSelectTexte = null;
+        return;
+      case SELECT_TEXTE:
+        saisieUnite.removeActionListener(this);
+        saisieUnite.effSelection();
+        saisieUnite.addActionListener(this);
+        bornesSelectTexte = evt.getBornesSelectionTexte();
+        etatSelectTexte();
+        return;
+      case SELECT_ELEMENT:
+        saisieUnite.setSelection(evt.getElementVise());
+        bornesSelectTexte = null;
+        return;
+    }
+    throw new UnsupportedOperationException("Evénement non prévu : "+evt.getTypeEvent());
+  }
+  /*
+   * ACTIONS DE L'UTILISATEUR : BOUTONS
+   */
+  private void creerUnite() {
+    if (vue.getCorpus().checkPresenceUnite(saisieTypeUnites.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1])
+            &&!GMessages.confirmationAction("Dupliquer cette unité  ?")) return;
+    vue.getCorpus().addUniteSaisie(saisieTypeUnites.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1]);
+  }
+  private void supprimerUnite() {
+    if (!GMessages.confirmationAction("Supprimer l'unité sélectionnée ?"))
+      return;
+    vue.getCorpus().supUnite((Unite) saisieUnite.getSelection());
+  }
+  private void modifierBorne() {
+    panneauTexte.rectifierBorneUnite((Unite) saisieUnite.getSelection());
+  }
+  /* 
+   * GESTION INTERNE
+   */
+  private void etatSelectUnite(Unite unite) {  // une unité est sélectionnée
+    panneauTexte.saisir(unite, new Unite[]{unite}, TypeMarquage.SELECT1);
+    //           (Unite[]) saisieUnite.getElements(), TypeMarquage.FOND1);
+    panneauChamps.afficher(unite);
+    creeUnite.setEnabled(false);
+    supprimeUnite.setEnabled(true);
+    rectifieBorne.setEnabled(true);
+  }
+  private void etatSelectRien() {  // rien n'est sélectionné
+    if (saisieTypeUnites.pasdeSelection()) panneauTexte.pasDeMarquage();
+    else
+      panneauTexte.saisir(null, (Unite[]) saisieUnite.getElements(), TypeMarquage.FOND1);
+    panneauChamps.effacer();
+    creeUnite.setEnabled(false);
+    supprimeUnite.setEnabled(false);
+    rectifieBorne.setEnabled(false);
+  }
+  private void etatSelectTexte() {    // du texte est sélectionné
+    panneauTexte.pasDeMarquage();
+//    if (saisieTypeUnites.pasdeSelection()) panneauTexte.pasDeMarquage();
+//    else panneauTexte.saisir(null, (Unite[]) saisieUnite.getElements(), TypeMarquage.FOND1);
+    panneauChamps.effacer();
+    if (!saisieTypeUnites.pasdeSelection()) {
+      creeUnite.setEnabled(true);
+//      Boutons.setDefaut(creeUnite, true);
+    }
+    supprimeUnite.setEnabled(false);
+    rectifieBorne.setEnabled(false);
+  }
+  private void initSaisieUnite(Unite unit) {
+    saisieUnite.removeActionListener(this);
+    if (saisieTypeUnites.pasdeSelection()) saisieUnite.setModeleVide();
+    else {
+      String type0 = saisieTypeUnites.getTypeSelection();
+      Unite[] unites = vue.getUnitesAVoir(type0);
+      saisieUnite.setModele(unites, vue.getIdUnites(type0, unites));
+    }
+    if (unit==null) saisieUnite.effSelection();
+    else saisieUnite.setSelection(unit);
+    saisieUnite.addActionListener(this);
+    saisieUnite.revalidate();
+  }
+  private void initSaisieUnite() {
+    initSaisieUnite(null);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesUnites.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/PanneauEditeur.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/PanneauEditeur.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/PanneauEditeur.java	(revision 481)
@@ -0,0 +1,355 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.text.Document;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+import visuAnalec.Message.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.texte.PanneauTexte.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class PanneauEditeur extends JPanel implements VueListener {
+  private enum Commandes {
+    GESTION_UNITES,
+    GESTION_RELATIONS,
+    GESTION_SCHEMAS,
+    MODIF_TEXTE;
+    private static Commandes getCommande(Class<? extends Element> classe) {
+      if (classe==Unite.class) return GESTION_UNITES;
+      if (classe==Relation.class) return GESTION_RELATIONS;
+      if (classe==Schema.class) return GESTION_SCHEMAS;
+      throw new UnsupportedOperationException("sous-classe non traitée");
+    }
+  }
+  private Vue vue;
+  private PanneauAffTexte panneauTexte;
+  private JPanel panneauOccurrences;
+  private PanneauChamps panneauChamps;
+  private Commandes commandes = null;
+  private HashMap<Commandes, PanneauCommandes> panneauxCommandes =
+          new HashMap<Commandes, PanneauCommandes>();
+  private HashMap<Commandes, String> titresPanneauxCommandes =
+          new HashMap<Commandes, String>();
+  private JDialog fenetreModifTexte;
+  private PanneauModifTexte panneauModifTexte;
+  private PanneauCommandesModifTexte panneauCommandesModifTexte;
+  private String recherche = "";
+  private Element elementCourant;
+
+  public static class ElementMarque {
+    public Element elt;
+    public String id;
+    public TypeMarquage marque;
+    public ElementMarque(Element elt, TypeMarquage marque, String id) {
+      this.elt = elt;
+      this.id = id;
+      this.marque = marque;
+    }
+  }
+
+  public static abstract class PanneauCommandes extends Box {
+    protected Vue vue;
+    protected PanneauAffTexte panneauTexte;
+    PanneauCommandes(Vue vue, PanneauAffTexte panneauTexte) {
+      super(BoxLayout.Y_AXIS);
+      this.vue = vue;
+      this.panneauTexte = panneauTexte;
+    }
+    public Vue getVue() {
+      return vue;
+    }
+    abstract public void reafficher();        // quand la vue n'a pas changé
+    abstract public void reinitialiser();     // quand la vue a changé
+    abstract public void elementSuivant(int sens);
+    abstract public Element elementSelectionne();
+    abstract public void editerElement(Element elt);
+    abstract public void traiterElementEvent(ElementEvent evt);
+    abstract public void traiterSourisEvent(PanneauAffTexte.SourisEvent evt);   // appelée par le panneau AffTexte
+    abstract public ArrayList<ElementMarque> trouverElementsVises(Unite uniteVisee,
+            TypeMarquage marqueUniteVisee, boolean avecId);  // appelée par le panneau AffTexte
+  }
+  public PanneauEditeur(Vue vue) {
+    super(new BorderLayout());
+    this.vue = vue;
+    vue.addEventListener(this);
+    setBorder(new TitledBorder(""));
+    panneauOccurrences = new JPanel(new BorderLayout());
+    panneauTexte = new PanneauAffTexte(vue.getCorpus());
+    panneauOccurrences.add(new JScrollPane(panneauTexte), BorderLayout.CENTER);
+    panneauChamps = new PanneauChamps(this, vue);
+    add(new JSplitPane(JSplitPane.VERTICAL_SPLIT, panneauOccurrences, panneauChamps), BorderLayout.CENTER);
+    // Les différents panneaux de commandes 
+    panneauxCommandes.put(Commandes.GESTION_UNITES,
+            new PanneauCommandesUnites(vue, panneauTexte, panneauChamps));
+    titresPanneauxCommandes.put(Commandes.GESTION_UNITES, "Gestion des unités");
+    panneauxCommandes.put(Commandes.GESTION_RELATIONS,
+            new PanneauCommandesRelations(vue, panneauTexte, panneauChamps));
+    titresPanneauxCommandes.put(Commandes.GESTION_RELATIONS, "Gestion des relations");
+    panneauxCommandes.put(Commandes.GESTION_SCHEMAS,
+            new PanneauCommandesSchemas(vue, panneauTexte, panneauChamps));
+    titresPanneauxCommandes.put(Commandes.GESTION_SCHEMAS, "Gestion des schémas");
+    new GActionClavier(this, "suivant", "F1", "control DOWN") {
+      public void executer() {
+        elementSuivant(1);
+      }
+    };
+    new GActionClavier(this, "précédent", "F2", "control UP") {
+      public void executer() {
+        elementSuivant(-1);
+      }
+    };
+    new GActionClavier(this, "copier", "F3", "control M") {
+      public void executer() {
+        copierElement();
+      }
+    };
+    new GActionClavier(this, "coller", "F4", "control R") {
+      public void executer() {
+        collerElement();
+      }
+    };
+    // La fenêtre modale pour éditer le texte
+    fenetreModifTexte = new JDialog((VisuMain) getTopLevelAncestor(), true);
+    fenetreModifTexte.setUndecorated(true);
+    fenetreModifTexte.getContentPane().setLayout(new BorderLayout());
+    panneauModifTexte = new PanneauModifTexte(vue.getCorpus());
+    fenetreModifTexte.getContentPane().add(new JScrollPane(panneauModifTexte), BorderLayout.CENTER);
+    panneauCommandesModifTexte = new visuAnalec.texte.PanneauCommandesModifTexte(this, vue, panneauModifTexte);
+    panneauModifTexte.setCommandesModifTexte(panneauCommandesModifTexte);
+    fenetreModifTexte.getContentPane().add(panneauCommandesModifTexte, BorderLayout.SOUTH);
+    fenetreModifTexte.setVisible(false);
+    // Panneau initial : gestion des unités
+    changerPanneauCommandes(Commandes.GESTION_UNITES);
+    reinitCommandes();
+
+  }
+  void agencerPanneaux() {
+    JSplitPane split = (JSplitPane) panneauOccurrences.getParent();
+    split.setDividerLocation(2./3);
+    revalidate();
+    repaint();
+  }
+  private void changerPanneauCommandes(Commandes newCommandes) {
+    if (commandes!=null)
+      panneauOccurrences.remove(panneauxCommandes.get(commandes));
+    commandes = newCommandes;
+    panneauOccurrences.add(panneauxCommandes.get(commandes), BorderLayout.NORTH);
+    ((TitledBorder) getBorder()).setTitle(titresPanneauxCommandes.get(commandes));
+    panneauTexte.setCommandes(panneauxCommandes.get(commandes));
+    revalidate();
+    repaint();
+  }
+  private void reinitCommandes() {
+    panneauxCommandes.get(commandes).reinitialiser();
+  }
+  private void elementSuivant(int sens) {
+    panneauxCommandes.get(commandes).elementSuivant(sens);
+  }
+  private void copierElement() {
+    Element elt = panneauxCommandes.get(commandes).elementSelectionne();
+    if (elt!=null) elementCourant = elt;
+  }
+  private void collerElement() {
+    if (elementCourant==null) return;
+    Element elt = panneauxCommandes.get(commandes).elementSelectionne();
+    if (elt==null) return;
+    vue.copierValeurs(elementCourant, elt);
+  }
+  private void reinitCommandes(Element elt) {
+    panneauxCommandes.get(commandes).reinitialiser();
+    panneauxCommandes.get(commandes).editerElement(elt);
+  }
+  private void reaffCommandes() {
+    panneauxCommandes.get(commandes).reafficher();
+  }
+  private void initNewCorpus() {
+    panneauTexte.setTexteVisu();
+    panneauTexte.initAscenseur();
+    colorierTexte();
+    changerPanneauCommandes(Commandes.GESTION_UNITES);
+    reinitCommandes();
+  }
+  private void colorierTexte() {
+    panneauTexte.setAttributsStandard(vue.getStyleTexte());
+    panneauTexte.colorierUnites(vue.getUnitesAColorier());
+  }
+  void initRechercherTexte() {
+    recherche = (String) JOptionPane.showInputDialog(this, "Recherche dans le texte",
+            "Rechercher", JOptionPane.PLAIN_MESSAGE, null, null, recherche);
+    if (recherche==null) recherche = "";
+    if (recherche.isEmpty()) return;
+    panneauTexte.rechercherTexte(recherche);
+  }
+  void rechercherSuivantTexte() {
+    if (recherche.isEmpty()) return;
+    panneauTexte.rechercherTexte(recherche);
+
+  }
+  void initModifierTexte() {
+    ((TitledBorder) getBorder()).setTitle("Modification du texte");
+    repaint();
+    fenetreModifTexte.setSize(panneauOccurrences.getSize());
+    fenetreModifTexte.setLocationRelativeTo(panneauOccurrences);
+    panneauChamps.effacer();
+    panneauModifTexte.init();
+    fenetreModifTexte.setModal(false);
+    fenetreModifTexte.setVisible(true);
+    panneauModifTexte.ajusterAscenseur(panneauTexte);
+    fenetreModifTexte.setVisible(false);
+    fenetreModifTexte.setModal(true);
+    fenetreModifTexte.setVisible(true);
+  }
+  public void finModifTexte() {
+    fenetreModifTexte.setVisible(false);
+    panneauTexte.ajusterAscenseur(panneauModifTexte);
+    if (commandes==null) {
+      changerPanneauCommandes(Commandes.GESTION_UNITES);
+      reinitCommandes();
+    } else {
+      ((TitledBorder) getBorder()).setTitle(titresPanneauxCommandes.get(commandes));
+      reaffCommandes();
+    }
+    repaint();
+  }
+  public void saisirStyleTexte(Vue vue) {
+    VisuStyleTexte.newVisuStyleTexte(this, vue.getStyleTexte());
+  }
+  public void changerStyleTexte(SimpleAttributeSet att) {
+    vue.setStyleTexte(att);
+    panneauTexte.setAttributsStandard(att);
+    panneauModifTexte.setAttributsStandard(att);
+    reaffCommandes();
+  }
+  public Document getTexteFormate() {
+    return panneauTexte.getDocument();
+  }
+  public void editerElement(Element elt) {
+    // typiquement, appelée de l'extérieur par d'autres fenêtres
+    changerPanneauCommandes(Commandes.getCommande(elt.getClass()));
+    reinitCommandes(elt);
+    ((VisuMain) getTopLevelAncestor()).premierPlan();
+  }
+  public void editerUniteChaine(Unite unit, Schema chaine) {
+    // appelée de l'extérieur notamment par visuChaines)
+    changerPanneauCommandes(Commandes.GESTION_SCHEMAS);
+    reinitCommandes();
+    ((PanneauCommandesSchemas) panneauxCommandes.get(commandes)).editerSchemaElement(chaine, unit);
+    ((VisuMain) getTopLevelAncestor()).premierPlan();
+  }
+  public void editerUniteTypeChaine(Unite unit, String typechaine) {
+    // appelée de l'extérieur notamment par visuChaines)
+    changerPanneauCommandes(Commandes.GESTION_SCHEMAS);
+    reinitCommandes();
+    ((PanneauCommandesSchemas) panneauxCommandes.get(commandes)).editerElementTypeSchema(unit, typechaine);
+    ((VisuMain) getTopLevelAncestor()).premierPlan();
+  }
+  void initGestionUnites() {
+    if (vue.getTypesUnitesAVoir().length==0) {
+      JOptionPane.showMessageDialog(getTopLevelAncestor(), "Aucun type d'unités n'est défini dans la vue actuelle",
+              "Saisie d'unités impossible", JOptionPane.ERROR_MESSAGE);
+      return;
+    }
+    changerPanneauCommandes(Commandes.GESTION_UNITES);
+    reinitCommandes();
+  }
+  void initGestionRelations() {
+    if (vue.getTypesRelationsAVoir().length==0) {
+      JOptionPane.showMessageDialog(getTopLevelAncestor(), "Aucun type de relation n'est défini dans la vue actuelle",
+              "Saisie de relations impossible", JOptionPane.ERROR_MESSAGE);
+      return;
+    }
+    changerPanneauCommandes(Commandes.GESTION_RELATIONS);
+    reinitCommandes();
+  }
+  void initGestionSchemas() {
+    if (vue.getTypesSchemasAVoir().length==0) {
+      JOptionPane.showMessageDialog(getTopLevelAncestor(), "Aucun type de schéma n'est défini dans la vue actuelle",
+              "Saisie de schéma impossible", JOptionPane.ERROR_MESSAGE);
+      return;
+    }
+    changerPanneauCommandes(Commandes.GESTION_SCHEMAS);
+    reinitCommandes();
+  }
+  public void traiterVueEvent(VueEvent evt) {
+    switch (evt.getModif()) {
+      case EXTRACTION:
+      case NEW_VUE:
+      case VUE_DEFAUT:
+        colorierTexte();
+        reinitCommandes();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getModif()+" oublié dans un switch");
+    }
+  }
+  public void traiterStructureEvent(StructureEvent evt) {
+    switch (evt.getModif()) {
+      case SUPPR_TYPE:
+      case FUSION_TYPE:
+      case RENOM_TYPE:
+      case AJOUT_TYPE:
+      case AJOUT_TYPE_ET_ELEMENTS:
+        colorierTexte();
+        reinitCommandes();
+        return;
+      case VALEUR_PAR_DEFAUT:
+      case AJOUT_FORME_UNITE:
+      case FUSION_PROP:
+      case RENOM_PROP:
+      case SUPPR_PROP:
+      case AJOUT_PROP:
+      case FUSION_VALEUR:
+      case RENOM_VALEUR:
+      case SUPPR_VALEUR:
+      case AJOUT_VALEUR:
+        colorierTexte();
+        panneauChamps.reafficher();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getModif()+" oublié dans un switch");
+    }
+  }
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        initNewCorpus();
+        return;
+      case NEW_CORPUS:
+        initNewCorpus();
+        return;
+      case CORPUS_SAVED:
+          return;
+      case MODIF_TEXTE:
+        panneauTexte.setTexteVisu();
+        return;
+      case MODIF_VUE:
+        traiterVueEvent((VueEvent) evt);
+        return;
+      case MODIF_STRUCTURE:
+        traiterStructureEvent((StructureEvent) evt);
+        return;
+      case MODIF_ELEMENT:
+        colorierTexte();
+        panneauxCommandes.get(commandes).traiterElementEvent((ElementEvent) evt);
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/PanneauEditeur.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauCommandesModifTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauCommandesModifTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauCommandesModifTexte.java	(revision 481)
@@ -0,0 +1,58 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.texte;
+
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.Message.*;
+import visuAnalec.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class PanneauCommandesModifTexte extends Box  {
+  Vue vue;
+  PanneauModifTexte panneauTexte;
+  PanneauEditeur panneauEditeur;
+ public PanneauCommandesModifTexte( PanneauEditeur pEditeur, Vue vue, PanneauModifTexte pTexte) {
+    super(BoxLayout.X_AXIS);
+    this.panneauEditeur = pEditeur;
+    this.vue = vue;
+    this.panneauTexte = pTexte;
+        add(Box.createHorizontalGlue());
+    add( new JButton(new GAction("Valider") {
+      public void executer() {
+        validerModifTexte();
+        panneauEditeur.finModifTexte();
+      }
+    }));
+    add(Box.createHorizontalGlue());
+    add( new JButton(new GAction("Annuler") {
+      public void executer() {
+        panneauEditeur.finModifTexte();
+    }
+    }));
+    add(Box.createHorizontalGlue());
+  }
+ void validerModifTexte() {
+   int nbSupprimes = panneauTexte.preparerValiderModifTexte();
+  if (nbSupprimes > 0) {
+      int rep = JOptionPane.showOptionDialog(getTopLevelAncestor(),
+              "Les modifications du texte vont entraîner la suppression " +
+              (nbSupprimes == 1 ? "d'une unité" : "de " + nbSupprimes + " unités"), "Suppression d'unités",
+              JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+              null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+      if (rep == 1) return;
+    }
+    panneauTexte.validerModifTexte();
+  }
+ }

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauCommandesModifTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauAffChainesTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauAffChainesTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauAffChainesTexte.java	(revision 481)
@@ -0,0 +1,77 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import java.awt.event.*;
+import java.util.*;
+import visuAnalec.chaines.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class PanneauAffChainesTexte extends PanneauTexte {
+  private ListenerSourisTexte sourisListener;
+  private VisuChaines visuChaines;
+  private Marquage marquage;
+  public PanneauAffChainesTexte(Corpus corpus, VisuChaines visuChaines) {
+    super(corpus);
+    setEditable(false);
+    this.visuChaines = visuChaines;
+    setSourisListener(visuChaines);
+    marquage = new Marquage(this);
+  }
+  protected void setSourisListener(VisuChaines vChaines) {
+    sourisListener = new ListenerSourisTexte(this, vChaines);
+    addMouseListener(sourisListener);
+  }
+  public void pasDeMarquage() {
+    marquerUnites(marquage, new TypeMarquage[0], null);
+  }
+  public void montrerUnite(Unite unit, TypeMarquage typeSelectUnite) {
+    TypeMarquage[] typesMarq = new TypeMarquage[]{typeSelectUnite};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(typeSelectUnite, new Unite[]{unit});
+    marquerUnites(marquage, typesMarq, unites);
+    placerAscenseur(unit);
+  }
+  public void montrerUnite(Unite unit, TypeMarquage typeSelectUnite, Unite[] unitsChaine,
+          TypeMarquage typeSelectChaine) {
+    TypeMarquage[] typesMarq = new TypeMarquage[]{typeSelectUnite, typeSelectChaine};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(typeSelectUnite, new Unite[]{unit});
+    unites.put(typeSelectChaine, unitsChaine);
+    marquerUnites(marquage, typesMarq, unites);
+    placerAscenseur(unit);
+  }
+  public void colorerUnites(Unite[] units, TypeMarquage typeColorChaines) {
+    TypeMarquage[] typesMarq = new TypeMarquage[]{typeColorChaines};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(typeColorChaines, units);
+    marquerUnites(marquage, typesMarq, unites);
+  }
+
+  protected static class ListenerSourisTexte extends MouseAdapter {
+    private PanneauAffChainesTexte panneauTexte;
+    private VisuChaines visuChaines;
+    public ListenerSourisTexte(PanneauAffChainesTexte pTexte, VisuChaines vChaines) {
+      this.panneauTexte = pTexte;
+      this.visuChaines = vChaines;
+    }
+    @Override
+    public void mouseClicked(MouseEvent e) {
+ try {
+   Unite uniteVisee = panneauTexte.getUniteVisee(panneauTexte.marquage, e.getPoint());
+      if (uniteVisee == null){  /*visuChaines.traiterAffTexteClicVide();*/}
+      else  if (e.getClickCount() == 2){/* visuChaines.traiterAffTexteDoubleClic(uniteVisee);*/}
+     } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+   }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauAffChainesTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauAffTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauAffTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauAffTexte.java	(revision 481)
@@ -0,0 +1,318 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.PanneauAffTexte.ListenerSourisTexte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import static visuAnalec.texte.PanneauAffTexte.SourisEvent.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class PanneauAffTexte extends PanneauTexte {
+  private PanneauCommandes panneauCommandes;
+  private ListenerSourisTexte sourisListener;
+  protected Marquage marquage = new Marquage(this);
+  public PanneauAffTexte(Corpus corpus) {
+    super(corpus);
+    coloriage = new Coloriage(this);
+    setEditable(false);
+    setSourisListener();
+  }
+  @Override
+  public String getToolTipText() {
+    Point pt = getMousePosition();
+    if (pt == null) return "";
+    Unite[] unitesVisees = getUnitesVisees(marquage, pt);
+    if (unitesVisees.length == 0) return "";
+    ArrayList<String> textes = new ArrayList<String>();
+    ArrayList<String> idsElementsVises = new ArrayList<String>();
+    for (Unite unit : unitesVisees) {
+      String texte = getTexteUnite(unit);
+      for (ElementMarque eltMarque : panneauCommandes.trouverElementsVises(unit,
+              marquage.getMarquage(unit), true)) {
+        idsElementsVises.add(eltMarque.id);
+        textes.add(texte);
+      }
+    }
+    return GVisu.styleIdTooltip(textes, idsElementsVises);
+  }
+  protected void setSourisListener() {
+    sourisListener = new ListenerSourisTexte(this);
+    addMouseListener(sourisListener);
+  }
+  public void setCommandes(PanneauCommandes panneauCommandes) {
+    this.panneauCommandes = panneauCommandes;
+    sourisListener.setCommandes(panneauCommandes);
+  }
+  private void deselecterUnite(Unite unite) {  // utilisé uniquement pour rectifier une borne
+    int debUnite = indexToPosition(unite.getDeb());
+    int finUnite = indexToPosition(unite.getFin());
+    doc.setCharacterAttributes(debUnite, finUnite - debUnite, AttributsStandard, true);
+  }
+  private void selecterUnite(Unite unite) {   // utilisé uniquement pour rectifier une borne
+    int debUnite = indexToPosition(unite.getDeb());
+    int finUnite = indexToPosition(unite.getFin());
+    doc.setCharacterAttributes(debUnite, finUnite - debUnite, SELECTION_1, true);
+  }
+  public void pasDeMarquage() {
+    marquerUnites(marquage, new TypeMarquage[0], null);
+    sourisListener.setEtat(EtatClic.SAISIE);
+  }
+  public void saisir(Unite amontrer, Unite[] lUnites, TypeMarquage type) {
+    TypeMarquage[] typesMarq = {type};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(type, lUnites);
+    marquerUnites(marquage, typesMarq, unites);
+    if (amontrer != null) placerAscenseur(amontrer);
+    sourisListener.setEtat(EtatClic.SAISIE);
+  }
+  public void saisir(Unite amontrer, Unite[] lUnites1, TypeMarquage type1, Unite[] lUnites2, TypeMarquage type2) {
+    TypeMarquage[] typesMarq = {type1, type2};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(type1, lUnites1);
+    unites.put(type2, lUnites2);
+    marquerUnites(marquage, typesMarq, unites);
+    if (amontrer != null) placerAscenseur(amontrer);
+    sourisListener.setEtat(EtatClic.SAISIE);
+  }
+  public void saisir(Unite amontrer, Unite[] lUnites1, TypeMarquage type1,
+          Unite[] lUnites2, TypeMarquage type2, Unite[] lUnites3, TypeMarquage type3) {
+    TypeMarquage[] typesMarq = {type1, type2, type3};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(type1, lUnites1);
+    unites.put(type2, lUnites2);
+    unites.put(type3, lUnites3);
+    marquerUnites(marquage, typesMarq, unites);
+    if (amontrer != null) placerAscenseur(amontrer);
+    sourisListener.setEtat(EtatClic.SAISIE);
+  }
+  public void saisir(Unite amontrer, Unite[] lUnites1, TypeMarquage type1, Unite[] lUnites2, TypeMarquage type2,
+          Unite[] lUnites3, TypeMarquage type3, Unite[] lUnites4, TypeMarquage type4) {
+    TypeMarquage[] typesMarq = {type1, type2, type3, type4};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(type1, lUnites1);
+    unites.put(type2, lUnites2);
+    unites.put(type3, lUnites3);
+    unites.put(type4, lUnites4);
+    marquerUnites(marquage, typesMarq, unites);
+    if (amontrer != null) placerAscenseur(amontrer);
+    sourisListener.setEtat(EtatClic.SAISIE);
+  }
+  public void rectifierBorneUnite(Unite unite) {
+    sourisListener.etatChtBornes(unite);
+  }
+  void changerBornes(Unite unite, int borneGauche, int borneDroite) {
+    corpus.modifBornesUnite(unite, borneGauche, borneDroite);
+  }
+
+  public static class SourisEvent {
+    public enum TypeEvent {
+      SELECT_TEXTE, SELECT_RIEN, SELECT_ELEMENT
+    }
+    private TypeEvent type;
+    private Element elementVise;
+    private TypeMarquage marquageElementVise;
+    private int[] bornesSelectionTexte;
+    protected SourisEvent(TypeEvent type) {
+      this(type, null, null, null);
+    }
+    protected SourisEvent(TypeEvent type, Element elt, TypeMarquage marque) {
+      this(type, elt, marque, null);
+    }
+    protected SourisEvent(TypeEvent type, int[] bornes) {
+      this(type, null, null, bornes);
+    }
+    protected SourisEvent(TypeEvent type, Element elt, TypeMarquage marque, int[] bornes) {
+      this.type = type;
+      marquageElementVise = marque;
+      bornesSelectionTexte = bornes;
+      elementVise = elt;
+    }
+    public TypeEvent getTypeEvent() {
+      return type;
+    }
+    public TypeMarquage getMarquageElementVise() {
+      return marquageElementVise;
+    }
+    public int[] getBornesSelectionTexte() {
+      return bornesSelectionTexte;
+    }
+    public Element getElementVise() {
+      return elementVise;
+    }
+  }
+
+  protected static class ListenerSourisTexte extends MouseAdapter {
+    enum EtatClic {
+      INACTIF,
+      SAISIE,
+      BORNES,
+    }
+    private EtatClic etatClic;
+    private Unite uniteABorner;
+    private PanneauAffTexte panneauTexte;
+    private PanneauCommandes panneauCommandes;
+    private JPopupMenuUnites popupMenuUnites;
+    public ListenerSourisTexte(PanneauAffTexte pTexte) {
+      panneauTexte = pTexte;
+      popupMenuUnites = new JPopupMenuUnites(pTexte);
+    }
+    void setCommandes(PanneauCommandes commandes) {
+      panneauCommandes = commandes;
+      popupMenuUnites.setCommandes(commandes);
+    }
+    void setEtat(EtatClic etat) {
+      this.etatClic = etat;
+    }
+    void etatChtBornes(Unite uniteABorner) {
+      etatClic = EtatClic.BORNES;
+      this.uniteABorner = uniteABorner;
+      int deb = panneauTexte.indexToPosition(uniteABorner.getDeb());
+      int fin = panneauTexte.indexToPosition(uniteABorner.getFin());
+      panneauTexte.doc.setCharacterAttributes(deb, fin - deb, BORNAGE, true);
+    }
+    @Override
+    public void mousePressed(MouseEvent e) {
+      if (e.isPopupTrigger()) mousePopup(e);
+    }
+    @Override
+    public void mouseReleased(MouseEvent e) {
+      try {
+        if (e.isPopupTrigger()) {
+          mousePopup(e);
+          return;
+        }
+        switch (etatClic) {
+          case INACTIF:
+          case BORNES:
+            return;
+          case SAISIE:
+            if (panneauTexte.getSelectedText() != null) panneauCommandes.traiterSourisEvent(new SourisEvent(
+                      TypeEvent.SELECT_TEXTE, panneauTexte.getIndSelection()));
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas non prévu d'étatClic");
+        }
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+    @Override
+    public void mouseClicked(MouseEvent e) {
+      try {
+        if (e.getButton() != MouseEvent.BUTTON1) return;
+        if (e.getClickCount() > 1) return;
+        switch (etatClic) {
+          case INACTIF:  // peut-être inutile ??
+            return;
+          case SAISIE:
+            Unite uniteVisee = panneauTexte.getUniteVisee(panneauTexte.marquage, e.getPoint());
+            if (uniteVisee == null) {
+              panneauCommandes.traiterSourisEvent(new SourisEvent(TypeEvent.SELECT_RIEN));
+              return;
+            }
+            ElementMarque eltM = panneauCommandes.trouverElementsVises(uniteVisee,
+                    panneauTexte.marquage.getMarquage(uniteVisee), false).get(0);
+            panneauCommandes.traiterSourisEvent(new SourisEvent(TypeEvent.SELECT_ELEMENT,
+                    eltM.elt, eltM.marque));
+            return;
+          case BORNES: // à revoir
+            int olddeb = uniteABorner.getDeb();
+            int oldfin = uniteABorner.getFin();
+            int newdeb = olddeb;
+            int newfin = oldfin;
+            int newborne = panneauTexte.positionToIndex(panneauTexte.viewToModel(e.getPoint()));
+            if (2 * newborne < olddeb + oldfin) newdeb = newborne;
+            else newfin = newborne;
+            panneauTexte.deselecterUnite(uniteABorner);
+            panneauTexte.changerBornes(uniteABorner, newdeb, newfin);
+            panneauTexte.selecterUnite(uniteABorner);
+            etatClic = EtatClic.SAISIE;
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas non prévu d'état d'AffTexte");
+        }
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+    public void mousePopup(MouseEvent e) {
+      Unite[] unitesVisees = panneauTexte.getUnitesVisees(panneauTexte.marquage, e.getPoint());
+      if (unitesVisees.length > 0) {
+        popupMenuUnites.reinitialiser(unitesVisees);
+        popupMenuUnites.show(e.getComponent(), e.getX(), e.getY());
+      }
+    }
+  }
+
+  private static class JPopupMenuUnites extends JPopupMenu {
+    private PanneauAffTexte panneauTexte;
+    private PanneauCommandes panneauCommandes;
+    private ArrayList<ElementMarque> elementsMarques = new ArrayList<ElementMarque>();
+    private Element[] elementsVises;
+    private String[] idsElementsVises;
+    private TypeMarquage[] marquesElementsVises;
+    public JPopupMenuUnites(PanneauAffTexte panneauTexte) {
+      super();
+      this.panneauTexte = panneauTexte;
+    }
+    void setCommandes(PanneauCommandes commandes) {
+      panneauCommandes = commandes;
+    }
+    void reinitialiser(Unite[] unitesVisees) {
+      removeAll();
+      elementsMarques.clear();
+      elementsVises = new Element[unitesVisees.length];
+      idsElementsVises = new String[unitesVisees.length];
+      marquesElementsVises = new TypeMarquage[unitesVisees.length];
+      int no = 0;
+      ArrayList<ElementMarque> eltsMARajouter = new ArrayList<ElementMarque>();
+      ArrayList<String> descrsARajouter = new ArrayList<String>();
+      for (Unite unit : unitesVisees) {
+        String texte = panneauTexte.getTexteUnite(unit);
+        ArrayList<TypeMarquage> typesM = panneauTexte.marquage.getMarquages(unit);
+        for (ElementMarque eltM : panneauCommandes.trouverElementsVises(unit, typesM.get(0), true)) {
+          elementsMarques.add(eltM);
+          String descr = GVisu.styleIdPopup(texte, eltM.id);
+          add(new ActionSelectionUnites(descr, no++));
+        }
+        for (TypeMarquage typeM : typesM.subList(1, typesM.size()))
+          for (ElementMarque eltM : panneauCommandes.trouverElementsVises(unit, typeM, true)) {
+            eltsMARajouter.add(eltM);
+            descrsARajouter.add(GVisu.styleIdPopup(texte, eltM.id));
+          }
+      }
+      for (int i = 0; i < eltsMARajouter.size(); i++) {
+        elementsMarques.add(eltsMARajouter.get(i));
+        add(new ActionSelectionUnites(descrsARajouter.get(i), no++));
+      }
+    }
+
+    private class ActionSelectionUnites extends GAction {
+      int no;
+      private ActionSelectionUnites(String descr, int no) {
+        super(descr);
+        this.no = no;
+      }
+      public void executer() {
+        panneauCommandes.traiterSourisEvent(new SourisEvent(TypeEvent.SELECT_ELEMENT,
+                elementsMarques.get(no).elt, elementsMarques.get(no).marque));
+      }
+    }
+  }
+}
+
+      
+

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauAffTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauModifTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauModifTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauModifTexte.java	(revision 481)
@@ -0,0 +1,170 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import java.util.*;
+import javax.swing.event.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class PanneauModifTexte extends PanneauTexte implements DocumentListener {
+  protected static class BorneUnite implements Comparable {
+    public Unite unite;
+    public int pos;
+    public BorneUnite(Unite unite, int pos) {
+      this.unite = unite;
+      this.pos = pos;
+    }
+    public int compareTo(Object obj) {
+      if (obj.getClass() != BorneUnite.class) {
+        throw new ClassCastException("Comparaison impossible : " + obj.toString() +
+                " n'est pas une instance de BorneUnite");
+      }
+      int comp = Integer.signum(pos - (((BorneUnite) obj).pos));
+      if (comp == 0) {
+        comp = -Integer.signum(unite.getFin() - unite.getDeb() - ((BorneUnite) obj).unite.getFin() +
+                ((BorneUnite) obj).unite.getDeb());
+      }
+      return comp;
+    }
+  }
+  private PanneauCommandesModifTexte panneauCommandes;
+  private BorneUnite[] bornesGauches;
+  private BorneUnite[] bornesDroites;
+  public PanneauModifTexte(Corpus corpus) {
+    super(corpus);
+    setEditable(true);
+  }
+  public void setCommandesModifTexte(PanneauCommandesModifTexte panneauCommandes) {
+    this.panneauCommandes = panneauCommandes;
+  }
+  void setBornesModifTexte() {
+    ArrayList<Unite> units = corpus.getToutesUnites();
+    bornesGauches = new BorneUnite[units.size()];
+    bornesDroites = new BorneUnite[units.size()];
+    for (int i = 0; i < units.size(); i++) {
+      Unite unite = units.get(i);
+      bornesGauches[i] = new BorneUnite(unite, unite.getDeb());
+      bornesDroites[i] = new BorneUnite(unite, unite.getFin());
+    }
+    Arrays.sort(bornesGauches);
+    Arrays.sort(bornesDroites);
+
+  }
+  public void init() {
+    doc.removeDocumentListener(this);
+    setTexteVisu();
+    setEditable(true);
+    doc.setParagraphAttributes(0, getText().length(), AttributsStandard, true);
+    doc.setCharacterAttributes(0, getText().length(), AttributsStandard, true);
+    setBornesModifTexte();
+    doc.addDocumentListener(this);
+  }
+  public int preparerValiderModifTexte() {
+    Comparator<BorneUnite> comp = new Comparator<BorneUnite>() {
+      public int compare(BorneUnite b1, BorneUnite b2) {
+        return b1.unite.compareTo(b2.unite);
+      }
+    };
+    Arrays.sort(bornesGauches, comp);
+    Arrays.sort(bornesDroites, comp);
+    int nbSupprimes = 0;
+    for (int i = 0; i < bornesGauches.length; i++) {
+      if (bornesGauches[i].pos == bornesDroites[i].pos) {
+        nbSupprimes++;
+      }
+    }
+    return nbSupprimes;
+  }
+  public void validerModifTexte() {
+    for (int i = 0; i < bornesGauches.length; i++) {
+      Unite unite = bornesGauches[i].unite;
+      if (bornesGauches[i].pos == unite.getDeb() && bornesDroites[i].pos == unite.getFin()) {
+        continue;
+      }
+      if (bornesGauches[i].pos == bornesDroites[i].pos) {
+        corpus.supUnite(unite);
+      } else {
+        corpus.modifBornesUnite(unite, bornesGauches[i].pos, bornesDroites[i].pos);
+      }
+    }
+    setEditable(false);
+    setTexteCorpus();  // Corpus enverra l'événement MODIF_TEXTE à tous les panneaux occurrence
+  }
+  public void insertUpdate(DocumentEvent evt) {
+    try {
+      String texte = getText();
+      int debutInsertion = positionToIndex(evt.getOffset());
+      int lengthInsertion = evt.getLength();
+      int iIns = 0;
+      while (iIns < posNewLines.size() && posNewLines.get(iIns) < evt.getOffset()) {
+        iIns++;
+      }
+      for (int ind = iIns; ind < posNewLines.size(); ind++) {
+        posNewLines.set(ind, posNewLines.get(ind) + evt.getLength());
+      }
+      for (int pos = evt.getOffset(); pos < evt.getOffset() + evt.getLength(); pos++) {
+        if (texte.charAt(pos) == '\n') {
+          lengthInsertion--;
+          posNewLines.add(iIns++, pos);
+        }
+      }
+      shiftDroitBornes(bornesGauches, debutInsertion, lengthInsertion);
+      shiftDroitBornes(bornesDroites, debutInsertion, lengthInsertion);
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  public void removeUpdate(DocumentEvent evt) {
+    try {
+      int debutSuppression = positionToIndex(evt.getOffset());
+      int lengthSuppression = evt.getLength();
+      int iSup = 0;
+      while (iSup < posNewLines.size() && posNewLines.get(iSup) < evt.getOffset()) {
+        iSup++;
+      }
+      while (iSup < posNewLines.size() && posNewLines.get(iSup) < evt.getOffset() + evt.getLength()) {
+        posNewLines.remove(iSup);
+        lengthSuppression--;
+      }
+      for (int ind = iSup; ind < posNewLines.size(); ind++) {
+        posNewLines.set(ind, posNewLines.get(ind) - evt.getLength());
+      }
+      shiftGaucheBornes(bornesGauches, debutSuppression, lengthSuppression);
+      shiftGaucheBornes(bornesDroites, debutSuppression, lengthSuppression);
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  public void changedUpdate(DocumentEvent evt) {
+    // rien à faire
+  }
+  void shiftDroitBornes(BorneUnite[] bornes, int deb, int shift) {
+    for (int i = bornes.length - 1; i >= 0; i--) {
+      if (bornes[i].pos < deb) {
+        return;
+      }
+      bornes[i].pos += shift;
+    }
+  }
+  void shiftGaucheBornes(BorneUnite[] bornes, int deb, int shift) {
+    for (int i = bornes.length - 1; i >= 0; i--) {
+      if (bornes[i].pos <= deb) {
+        return;
+      }
+      if (bornes[i].pos < deb + shift) {
+        bornes[i].pos = deb;
+      } else {
+        bornes[i].pos -= shift;
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauModifTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauTexte.java	(revision 481)
@@ -0,0 +1,542 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import java.awt.*;
+import java.util.*;
+import java.util.ArrayList;
+import javax.swing.*;
+import javax.swing.text.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class PanneauTexte extends JTextPane {
+  final private static Color ROUGE = new Color(0x800000);
+  final private static Color BLEU = new Color(0x000080);
+  final private static Color JAUNE_CLAIR = new Color(0xffffb0);
+  final private static Color JAUNE_TRES_CLAIR = new Color(0xffffe0);
+  final private static Color JAUNE_FONCE = new Color(0xffff60);
+  final private static Color VERT_CLAIR = new Color(0xd8f0ff);
+  final private static Color VERT_FONCE = new Color(0xb0d0ff);
+  final private static Color VIOLET_CLAIR = new Color(0xffd8e0);
+  final private static Color VIOLET_FONCE = new Color(0xffb0c0);
+  final public static SimpleAttributeSet STANDARD_DEFAUT = creerStyleStandardDefaut();
+  final protected static AttributeSet COLORATION_1 = creerCouleurFond(JAUNE_CLAIR);
+  final protected static AttributeSet COLORATION_1_MULTI = creerCouleurFond(JAUNE_FONCE);
+  final protected static AttributeSet COLORATION_2 = creerCouleurFond(VERT_CLAIR);
+  final protected static AttributeSet COLORATION_2_MULTI = creerCouleurFond(VERT_FONCE);
+  final protected static AttributeSet COLORATION_3 = creerCouleurFond(VIOLET_CLAIR);
+  final protected static AttributeSet COLORATION_3_MULTI = creerCouleurFond(VIOLET_FONCE);
+  final protected static AttributeSet SELECTION_1_1 = ajouterCouleurCar(COLORATION_1, BLEU);
+  final protected static AttributeSet SELECTION_1_1_MULTI = ajouterCouleurCar(COLORATION_1_MULTI,
+          BLEU);
+  final protected static AttributeSet SELECTION_1_2 = ajouterCouleurCar(COLORATION_1, ROUGE);
+  final protected static AttributeSet SELECTION_1_2_MULTI = ajouterCouleurCar(COLORATION_1_MULTI,
+          ROUGE);
+  final protected static AttributeSet SELECTION_1 = ajouterCouleurCar(COLORATION_1, ROUGE);
+  final protected static AttributeSet SELECTION_1_MULTI = ajouterCouleurCar(COLORATION_1_MULTI,
+          ROUGE);
+  final protected static AttributeSet SELECTION_2 = ajouterCouleurCar(COLORATION_2, BLEU);
+  final protected static AttributeSet SELECTION_2_MULTI = ajouterCouleurCar(COLORATION_2_MULTI,
+          BLEU);
+  final protected static AttributeSet SELECTION_3 = ajouterCouleurCar(COLORATION_3, ROUGE);
+  final protected static AttributeSet SELECTION_3_MULTI = ajouterCouleurCar(COLORATION_3_MULTI,
+          ROUGE);
+  final protected static AttributeSet BORNAGE = ajouterCouleurCar(COLORATION_1, null);
+  final private static HashMap<Integer, String> NOM_ALIGNEMENT = creerTableauNomsAlignement();
+
+  private static SimpleAttributeSet creerStyleStandardDefaut() {
+    String police;
+    if (Arrays.binarySearch(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(),
+            "Times New Roman")>=0) police = "Times New Roman";
+    else police = "Serif";
+    SimpleAttributeSet att = new SimpleAttributeSet();
+    StyleConstants.setFontFamily(att, police);
+    StyleConstants.setForeground(att, Color.BLACK);
+    StyleConstants.setBackground(att, Color.WHITE);
+    StyleConstants.setFontSize(att, 14);
+    StyleConstants.setBold(att, false);
+    StyleConstants.setItalic(att, false);
+    StyleConstants.setUnderline(att, false);
+    StyleConstants.setAlignment(att, StyleConstants.ALIGN_JUSTIFIED);
+    StyleConstants.setFirstLineIndent(att, 20f);
+    StyleConstants.setSpaceAbove(att, 4f);
+    StyleConstants.setSpaceBelow(att, 0f);
+    StyleConstants.setLeftIndent(att, 10f);
+    StyleConstants.setRightIndent(att, 10f);
+    StyleConstants.setLineSpacing(att, 0.1f);
+    return att;
+  }
+
+  private static HashMap<Integer, String> creerTableauNomsAlignement() {
+    HashMap<Integer, String> tab = new HashMap<Integer, String>();
+    tab.put(StyleConstants.ALIGN_CENTER, "Centré");
+    tab.put(StyleConstants.ALIGN_JUSTIFIED, "Justifié");
+    tab.put(StyleConstants.ALIGN_LEFT, "Gauche");
+    tab.put(StyleConstants.ALIGN_RIGHT, "Droite");
+    return tab;
+  }
+
+  public static String nomAlignement(int code) {
+    return NOM_ALIGNEMENT.get(code);
+  }
+
+  public static String[] nomsAlignement() {
+    String[] noms = NOM_ALIGNEMENT.values().toArray(new String[0]);
+    Arrays.sort(noms);
+    return noms;
+  }
+
+  public static int codeAlignement(String nom) {
+    for (int code : NOM_ALIGNEMENT.keySet()) if (nomAlignement(code).equals(nom))
+        return code;
+    return StyleConstants.ALIGN_JUSTIFIED;
+  }
+
+  private static SimpleAttributeSet creerCouleurFond(Color c) {
+    SimpleAttributeSet att = new SimpleAttributeSet();
+    StyleConstants.setBackground(att, c);
+    return att;
+  }
+
+  private static SimpleAttributeSet ajouterCouleurCar(AttributeSet att0, Color c) {
+    SimpleAttributeSet att = new SimpleAttributeSet(att0);
+    StyleConstants.setBold(att, true);
+    if (c!=null) StyleConstants.setForeground(att, c);
+    return att;
+  }
+
+  public static Color getCouleurFond1() {
+    return StyleConstants.getBackground(COLORATION_1);
+  }
+
+  public static Color getCouleurFond2() {
+    return StyleConstants.getBackground(COLORATION_2);
+  }
+
+  public static Color getCouleurFond3() {
+    return StyleConstants.getBackground(COLORATION_3);
+  }
+
+  public enum TypeMarquage {
+    FOND1(5, COLORATION_1, COLORATION_1_MULTI),
+    FOND1_2(5, COLORATION_1, COLORATION_1_MULTI),
+    FOND2(6, COLORATION_2, COLORATION_2_MULTI),
+    FOND3(7, COLORATION_3, COLORATION_3_MULTI),
+    SELECT1(2, SELECTION_1, SELECTION_1_MULTI),
+    SELECT1_2(1, SELECTION_1_1, SELECTION_1_1_MULTI),
+    SELECT1_3(2, SELECTION_1_2, SELECTION_1_2_MULTI),
+    SELECT2(3, SELECTION_2, SELECTION_2_MULTI),
+    SELECT3(4, SELECTION_3, SELECTION_3_MULTI);
+    protected AttributeSet attribut;
+    protected AttributeSet attributMulti;
+    protected int niveau;
+
+    TypeMarquage(int niv, AttributeSet att, AttributeSet attMulti) {
+      attribut = att;
+      attributMulti = attMulti;
+      niveau = niv;
+    }
+  }
+
+  public static class UniteColoree {
+    public Unite unite;
+    public AttributeSet att;
+
+    public UniteColoree(Unite unite, AttributeSet att) {
+      this.att = att;
+      this.unite = unite;
+    }
+  }
+
+  protected static class Coloriage {
+    private int[][] intervalles;
+    private AttributeSet[] attributIntervalles;
+    private PanneauTexte panneauTexte;
+
+    protected Coloriage(PanneauTexte pTexte) {
+      panneauTexte = pTexte;
+      intervalles = new int[0][];
+      attributIntervalles = new AttributeSet[0];
+    }
+
+    private void creerColoriage(UniteColoree[] unitsCol) {
+      ArrayList<int[]> intervlles = new ArrayList<int[]>();
+      ArrayList<AttributeSet> attIntervalle = new ArrayList<AttributeSet>();
+      for (UniteColoree unitCol : unitsCol) {
+        int deb = panneauTexte.indexToPosition(unitCol.unite.getDeb());
+        int fin = panneauTexte.indexToPosition(unitCol.unite.getFin());
+        intervlles.add(new int[]{deb, fin-deb});
+        attIntervalle.add(unitCol.att);
+      }
+      intervalles = intervlles.toArray(new int[0][]);
+      attributIntervalles = attIntervalle.toArray(new AttributeSet[0]);
+    }
+  }
+
+  protected static class Marquage {
+    private int[][] intervalles;
+    private Unite[][] unitesIntervalles;
+    private AttributeSet[] attributIntervalles;
+    private HashMap<Unite, ArrayList<TypeMarquage>> typesMarquage =
+            new HashMap<Unite, ArrayList<TypeMarquage>>();
+    private PanneauTexte panneauTexte;
+
+    protected Marquage(PanneauTexte pTexte) {
+      panneauTexte = pTexte;
+    }
+    // Ordre de masquage décroissant : si une unité est présente dans plusieurs types de marquage, 
+    // seule sa première mention sera prise en compte (grâce au HashMap typesMarquage)
+
+    void creerMarquage(TypeMarquage[] typesMarq, EnumMap<TypeMarquage, Unite[]> unites) {
+      HashMap<Integer, HashSet<Unite>> debs = new HashMap<Integer, HashSet<Unite>>();
+      HashMap<Integer, HashSet<Unite>> fins = new HashMap<Integer, HashSet<Unite>>();
+      HashSet<Integer> bornes = new HashSet<Integer>();
+      HashMap<Unite, Boolean> multis = new HashMap<Unite, Boolean>();
+      typesMarquage.clear();
+      for (TypeMarquage typeM : typesMarq)
+        for (Unite unit : unites.get(typeM)) {
+          if (!typesMarquage.containsKey(unit)) {
+            typesMarquage.put(unit, new ArrayList<TypeMarquage>());
+            typesMarquage.get(unit).add(typeM);
+            multis.put(unit, false);
+          } else {
+            ArrayList<TypeMarquage> types = typesMarquage.get(unit);
+            if (!types.get(types.size()-1).equals(typeM)) types.add(typeM);
+            else if (types.size()==1) multis.put(unit, true);
+          }
+          int deb = panneauTexte.indexToPosition(unit.getDeb());
+          int fin = panneauTexte.indexToPosition(unit.getFin());
+          bornes.add(deb);
+          bornes.add(fin);
+          if (!debs.containsKey(deb)) debs.put(deb, new HashSet<Unite>());
+          debs.get(deb).add(unit);
+          if (!fins.containsKey(fin)) fins.put(fin, new HashSet<Unite>());
+          fins.get(fin).add(unit);
+        }
+      Integer[] brnes = bornes.toArray(new Integer[0]);
+      Arrays.sort(brnes);
+      ArrayList<Unite> units = new ArrayList<Unite>();
+      ArrayList<int[]> intervlles = new ArrayList<int[]>();
+      ArrayList<Unite[]> unitsIntervalle = new ArrayList<Unite[]>();
+      ArrayList<AttributeSet> attIntervalle = new ArrayList<AttributeSet>();
+      int deb = 0;  // début d'un intervalle
+      int lg = 0;   // longueur d'un intervalle
+      for (int borne : brnes) {
+        if (!units.isEmpty()) {
+          lg = borne-deb;
+          intervlles.add(new int[]{deb, lg});
+          unitsIntervalle.add(ordonnerUnites(units));
+          attIntervalle.add(choisirAttribut(units, multis));
+        }
+        if (debs.containsKey(borne)) for (Unite unit : debs.get(borne))
+            units.add(unit);
+        if (fins.containsKey(borne)) for (Unite unit : fins.get(borne))
+            units.remove(unit);
+        if (!units.isEmpty()) deb = borne;
+      }
+      intervalles = intervlles.toArray(new int[0][]);
+      unitesIntervalles = unitsIntervalle.toArray(new Unite[0][]);
+      attributIntervalles = attIntervalle.toArray(new AttributeSet[0]);
+    }
+
+    private Unite[] ordonnerUnites(ArrayList<Unite> units) {
+      Unite[] unites = new Unite[units.size()];
+      unites[0] = units.get(0);
+      for (int i = 1; i<unites.length; i++) {
+        if (units.get(i).getFin()-units.get(i).getDeb()>=unites[0].getFin()-unites[0].getDeb())
+          unites[i] = units.get(i);
+        else {
+          unites[i] = unites[0];
+          unites[0] = units.get(i);
+        }
+      }
+      return unites;
+    }
+
+    private AttributeSet choisirAttribut(ArrayList<Unite> units, HashMap<Unite, Boolean> multis) {
+      AttributeSet att;
+      if (units.size()==1) {
+        att = multis.get(units.get(0)) ? typesMarquage.get(units.get(0)).get(0).attributMulti : typesMarquage.get(units.get(0)).get(0).attribut;
+      } else {
+        att = typesMarquage.get(units.get(0)).get(0).attributMulti;
+        int niv = typesMarquage.get(units.get(0)).get(0).niveau;
+        for (int i = 1; i<units.size(); i++) {
+          if (typesMarquage.get(units.get(i)).get(0).niveau<niv) {
+            att = typesMarquage.get(units.get(i)).get(0).attributMulti;
+            niv = typesMarquage.get(units.get(i)).get(0).niveau;
+          }
+        }
+      }
+      return att;
+    }
+
+    public Unite[] getUnitesVisees(int pos) {   // peut être améliorée par une recherche dichotomique
+      for (int i = 0; i<intervalles.length; i++) {
+        int[] interv = intervalles[i];
+        if (pos<interv[0]) return new Unite[0];
+        if (pos<interv[0]+interv[1]) return unitesIntervalles[i];
+      }
+      return new Unite[0];
+    }
+
+    public Unite getUniteVisee(int pos) {   // peut être améliorée par une recherche dichotomique
+      Unite[] units = getUnitesVisees(pos);
+      if (units.length==0) return null;
+      return units[0];
+    }
+
+    public TypeMarquage getMarquage(Unite unit) {
+      return typesMarquage.get(unit).get(0);
+    }
+
+    public ArrayList<TypeMarquage> getMarquages(Unite unit) {
+      return typesMarquage.get(unit);
+    }
+  }
+  // Champs de la classe PanneauTexte
+  protected SimpleAttributeSet AttributsStandard;
+  final static String CAR_FIN_PARAGRAPHE = "[\u00b6] ";
+  protected Corpus corpus;
+  protected StyledDocument doc;
+  protected Coloriage coloriage = null;
+  protected ArrayList<Integer> posNewLines = new ArrayList<Integer>();
+
+  public PanneauTexte(Corpus corpus) {
+    super();
+    this.corpus = corpus;
+    AttributsStandard = new SimpleAttributeSet(STANDARD_DEFAUT);
+    doc = getStyledDocument();
+    setText("");
+    ToolTipManager.sharedInstance().registerComponent(this);
+  }
+
+  @Override
+  public JToolTip createToolTip() {
+    JToolTip jt = new JToolTip();
+    jt.setBackground(JAUNE_TRES_CLAIR);
+    return jt;
+  }
+
+  public SimpleAttributeSet getAttributsStandard() {
+    return AttributsStandard;
+  }
+
+  public void setAttributsStandard(SimpleAttributeSet att) {
+    AttributsStandard = att;
+  }
+
+//  private int debParag;
+//  public void setTexteVisu() {
+//    final String texte = corpus.getTexte();
+//    posNewLines.clear();
+//    debParag = 0;
+//    final Integer[] finPars = corpus.getFinParagraphes();
+//    final StringBuffer newTexte = new StringBuffer(texte.length()+finPars.length);
+//    final GMessages.GProgression progression =
+//            new GMessages.GProgression(finPars.length, "paragraphes");
+//    Thread traitement = new Thread() {
+//      @Override
+//      public void run() {
+//        for (int i = 0; i<finPars.length; i++) {
+//          //           if(progression.isCanceled()) break;
+//          newTexte.append(texte.substring(debParag, finPars[i])).append("\n");
+//          posNewLines.add(newTexte.length()-1);
+//          debParag = finPars[i];
+//         progression.setNbTraites(i+1);
+//         }
+//        setText(new String(newTexte));
+//        revalidate();
+//        repaint();
+//      }
+//    };
+//    traitement.start();
+//  }
+//
+  public void setTexteVisu() {
+    final String texte = corpus.getTexte();
+    posNewLines.clear();
+    int debParag = 0;
+    Integer[] finPars = corpus.getFinParagraphes();
+    StringBuffer newTexte = new StringBuffer(texte.length()+finPars.length);
+    for (int i = 0; i<finPars.length; i++) {
+      //           if(progression.isCanceled()) break;
+      newTexte.append(texte.substring(debParag, finPars[i])).append("\n");
+      posNewLines.add(newTexte.length()-1);
+      debParag = finPars[i];
+    }
+    setText(new String(newTexte));
+    revalidate();
+    repaint();
+  }
+
+  private int getYHautAff() {
+    return ((JViewport) getParent()).getViewPosition().y;
+  }
+
+  private void setYHautAff(int y) {
+    ((JViewport) getParent()).setViewPosition(new Point(0, y));
+  }
+
+  public void initAscenseur() {
+    setYHautAff(0);
+    setCaretPosition(0);
+  }
+
+  public void ajusterAscenseur(PanneauTexte panneau) {
+    setYHautAff(panneau.getYHautAff());
+    setCurseur(panneau.getCaretPosition());
+  }
+
+  public void setCurseur(int pos) {
+    int ymax = getYHautAff()+((JViewport) getParent()).getViewSize().height;
+    pos = Math.max(pos, viewToModel(new Point(0, getYHautAff())));
+    pos = Math.min(pos, viewToModel(new Point(0, ymax)));
+    setCaretPosition(pos);
+  }
+
+  protected void placerAscenseur(Unite unite) {
+    int posdeb = indexToPosition(unite.getDeb());
+    placerAscenseur(posdeb, indexToPosition(unite.getFin()));
+    setCaretPosition(posdeb);
+  }
+
+  protected void placerAscenseur(int posdeb, int posfin) {
+    try {
+      Rectangle rectdeb = modelToView(posdeb);
+      Rectangle rectfin = modelToView(posfin);
+      int hligne = rectdeb.height;
+      int yhaut = rectdeb.y;
+      int ybas = rectfin.y+hligne;
+      int y0 = getYHautAff();
+      int h = ((JViewport) getParent()).getExtentSize().height;
+      if (yhaut<y0||ybas>y0+h) {
+        setYHautAff(Math.max(0, modelToView(posdeb).y-h/3));
+      }
+    } catch (BadLocationException ex) {
+      System.out.println("Erreur dans placerAscenseur : "+ex.getLocalizedMessage());
+      System.exit(1);
+    }
+  }
+
+  public int[] getIndSelection() {
+    int deb = getSelectionStart();
+    int fin = getSelectionEnd();
+    if (deb==fin) return null;
+    return new int[]{positionToIndex(deb), positionToIndex(fin)};
+  }
+
+  protected int indexToPosition(int ind) {
+    int nbnl = 0;
+    for (int finParag : corpus.getFinParagraphes()) {
+      if (ind<finParag) {
+        break;
+      }
+      nbnl++;
+    }
+    return ind+nbnl;
+  }
+
+  protected int positionToIndex(int pos) {
+    int nbnl = 0;
+    for (int posnl : posNewLines) {
+      if (pos<=posnl) {
+        break;
+      }
+      nbnl++;
+    }
+    return pos-nbnl;
+  }
+
+  public void colorierUnites(UniteColoree[] unitsCol) {
+    coloriage.creerColoriage(unitsCol);
+  }
+  // Ordre de masquage décroissant : si une unité est présente dans plusieurs types de marquage, 
+  // seule sa première mention sera prise en compte 
+
+  protected void marquerUnites(Marquage marquage, TypeMarquage[] typesMarq, EnumMap<TypeMarquage, Unite[]> unites) {
+    doc.setCharacterAttributes(0, getText().length(), AttributsStandard, true);
+    doc.setParagraphAttributes(0, getText().length(), AttributsStandard, true);
+    if (coloriage!=null&&typesMarq.length==0)
+      for (int i = 0; i<coloriage.intervalles.length; i++)
+        doc.setCharacterAttributes(
+                coloriage.intervalles[i][0], coloriage.intervalles[i][1], coloriage.attributIntervalles[i], false);
+    marquage.creerMarquage(typesMarq, unites);
+    for (int i = 0; i<marquage.intervalles.length; i++)
+      doc.setCharacterAttributes(
+              marquage.intervalles[i][0], marquage.intervalles[i][1], marquage.attributIntervalles[i], false);
+  }
+
+  protected Unite getUniteVisee(Marquage marquage, Point pt) {
+    return marquage.getUniteVisee(viewToModel(pt));
+  }
+
+  protected Unite[] getUnitesVisees(Marquage marquage, Point pt) {
+    return marquage.getUnitesVisees(viewToModel(pt));
+  }
+
+//  public static int[] calculerNoParagraphe(Unite[] unites, Integer[] finPar) {
+//    // les unites sont triées
+//    // les numéros de paragraphe commencent à 1 
+//    int[] nosPar = new int[unites.length];
+//    int nopar = 0;
+//    for (int i = 0; i<unites.length; i++) {
+//      while (unites[i].getDeb()>finPar[nopar]) nopar++;
+//      nosPar[i] = nopar+1;
+//    }
+//    return nosPar;
+//  }
+//
+  public static String insereCarFinParagraphe(String texte, Integer[] finPar, int offset) {
+    for (int ind : finPar) {
+      ind -= offset;
+      if (ind<=0) continue;
+      if (ind>=texte.length()) break;
+      texte = texte.substring(0, ind)+PanneauTexte.CAR_FIN_PARAGRAPHE+texte.substring(ind);
+      offset -= CAR_FIN_PARAGRAPHE.length();
+    }
+    return texte;
+  }
+
+  public String getTexteUnite(Unite unit) {  // utilisé pour les tooltips et les popups : à revoir
+    int deb = unit.getDeb();
+    int fin = unit.getFin();
+    return insereCarFinParagraphe(corpus.getTexte().substring(deb, fin), corpus.getFinParagraphes(), deb);
+  }
+
+  protected void setTexteCorpus() {
+    String newTexte = "";
+    ArrayList<Integer> newFinParag = new ArrayList<Integer>();
+    String texte = getText();
+    if (posNewLines.isEmpty()||posNewLines.get(posNewLines.size()-1)!=texte.length()-1) {
+      posNewLines.add(texte.length());
+    }
+    int debParag = 0;
+    for (int posnl : posNewLines) {
+      newTexte += texte.substring(debParag, posnl);
+      newFinParag.add(newTexte.length());
+      debParag = posnl+1;
+    }
+    corpus.modifTexte(newTexte, newFinParag);
+  }
+
+  public void rechercherTexte(String chaine) {
+    getCaret().setSelectionVisible(true);
+    String texte = getText();
+    int pos = texte.indexOf(chaine, getCaretPosition());
+    if (pos<0) pos = texte.indexOf(chaine);
+    if (pos>=0) {
+      placerAscenseur(pos, pos+chaine.length());
+      setCaretPosition(pos);
+      moveCaretPosition(pos+chaine.length());
+    } else moveCaretPosition(getCaretPosition());
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/texte/VisuStyleTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/texte/VisuStyleTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/texte/VisuStyleTexte.java	(revision 481)
@@ -0,0 +1,213 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.text.*;
+import visuAnalec.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu;
+import visuAnalec.util.GVisu.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class VisuStyleTexte extends JFrame {
+  private static VisuStyleTexte instance = null;
+  private PanneauEditeur pEditeur;
+  private SimpleAttributeSet att;
+  JComboBox saisieTaille;
+  JComboBox saisiePolice;
+  JCheckBox saisieGras;
+  JCheckBox saisieItalique;
+  JCheckBox saisieSouligne;
+  CouleurComboBox saisieCouleur;
+  CouleurComboBox saisieFond;
+  JComboBox saisieInterligne;
+  JComboBox saisieEspaceAvant;
+  JComboBox saisieEspaceApres;
+  JComboBox saisieAlignement;
+  JComboBox saisieIndentGauche;
+  JComboBox saisieIndentDroite;
+  JComboBox saisieIndentPrem;
+  public static void newVisuStyleTexte(PanneauEditeur pEditeur, SimpleAttributeSet att) {
+    if (instance != null) instance.dispose();
+    instance = new VisuStyleTexte(pEditeur, att);
+
+  }
+  private VisuStyleTexte(PanneauEditeur pEditeur, SimpleAttributeSet att) {
+    super("Gestion du style du texte");
+    Container fen = pEditeur.getTopLevelAncestor();
+    Point pos = new Point(fen.getX() + 200, fen.getY() + 50);
+    setLocation(pos);
+    this.pEditeur = pEditeur;
+    this.att = att;
+    JPanel pStyleCaracteres = new JPanel(new GridLayout(0, 2, 2, 4));
+    pStyleCaracteres.setBorder(new TitledBorder("Caractères"));
+    pStyleCaracteres.add(new JLabel("Police", JLabel.TRAILING));
+    String[] polices = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
+    saisiePolice = new JComboBox(polices);
+    saisiePolice.setPrototypeDisplayValue("Times New Roman");
+    saisiePolice.setEditable(false);
+    saisiePolice.setSelectedItem(StyleConstants.getFontFamily(att));
+    saisiePolice.setMaximumSize(new Dimension(40, 100));
+    pStyleCaracteres.add(saisiePolice);
+    pStyleCaracteres.add(new JLabel("Taille (pts)", JLabel.TRAILING));
+    saisieTaille = new JComboBox(new String[]{"4", "8", "10", "12", "14", "16", "20"});
+    saisieTaille.setEditable(true);
+    saisieTaille.setSelectedItem(Integer.toString(StyleConstants.getFontSize(att)));
+    pStyleCaracteres.add(saisieTaille);
+    pStyleCaracteres.add(new JLabel("Couleur", JLabel.TRAILING));
+    saisieCouleur = new CouleurComboBox(GVisu.getCouleursEtNoirEtBlanc());
+    saisieCouleur.setEditable(true);
+    saisieCouleur.setSelectedItem(StyleConstants.getForeground(att));
+    pStyleCaracteres.add(saisieCouleur);
+    pStyleCaracteres.add(new JLabel("Surbrillance", JLabel.TRAILING));
+    saisieFond = new CouleurComboBox(GVisu.getCouleursEtNoirEtBlanc());
+    saisieFond.setEditable(true);
+    saisieFond.setSelectedItem(StyleConstants.getBackground(att));
+    pStyleCaracteres.add(saisieFond);
+    pStyleCaracteres.add(new JLabel("Caractères gras", JLabel.TRAILING));
+    saisieGras = new JCheckBox("", StyleConstants.isBold(att));
+    pStyleCaracteres.add(saisieGras);
+    pStyleCaracteres.add(new JLabel("italiques", JLabel.TRAILING));
+    saisieItalique = new JCheckBox("", StyleConstants.isItalic(att));
+   pStyleCaracteres.add(saisieItalique);
+    pStyleCaracteres.add(new JLabel("soulignés", JLabel.TRAILING));
+    saisieSouligne = new JCheckBox("", StyleConstants.isUnderline(att));
+    saisieSouligne.setHorizontalTextPosition(SwingConstants.LEADING);
+    pStyleCaracteres.add(saisieSouligne);
+    JPanel pStyleParagraphes = new JPanel(new GridLayout(0,2,2,4));
+    pStyleParagraphes.setBorder(new TitledBorder("Paragraphes"));
+    pStyleParagraphes.add(new JLabel("Alignement", JLabel.TRAILING));
+    saisieAlignement = new JComboBox(PanneauTexte.nomsAlignement());
+    saisieAlignement.setEditable(false);
+    saisieAlignement.setSelectedItem(PanneauTexte.nomAlignement(StyleConstants.getAlignment(att)));
+    pStyleParagraphes.add(saisieAlignement);
+    pStyleParagraphes.add(new JLabel("Interligne (pts)", JLabel.TRAILING));
+    saisieInterligne = new JComboBox(new String[]{"-0.2", "0", "0.2", "0.5", "1.0", "1.5", "2"});
+    saisieInterligne.setEditable(true);
+    saisieInterligne.setSelectedItem(Float.toString(StyleConstants.getLineSpacing(att)));
+    pStyleParagraphes.add(saisieInterligne);
+    pStyleParagraphes.add(new JLabel("Espacement avant (pts)", JLabel.TRAILING));
+    saisieEspaceAvant = new JComboBox(new String[]{"0.0", "2.0", "5.0", "10.0", "15.0", "20.0"});
+    saisieEspaceAvant.setEditable(true);
+    saisieEspaceAvant.setSelectedItem(Float.toString(StyleConstants.getSpaceAbove(att)));
+    pStyleParagraphes.add(saisieEspaceAvant);
+    pStyleParagraphes.add(new JLabel("après (pts)", JLabel.TRAILING));
+    saisieEspaceApres = new JComboBox(new String[]{"0.0", "2.0", "5.0", "10.0", "15.0", "20.0"});
+    saisieEspaceApres.setEditable(true);
+    saisieEspaceApres.setSelectedItem(Float.toString(StyleConstants.getSpaceBelow(att)));
+    pStyleParagraphes.add(saisieEspaceApres);
+    pStyleParagraphes.add(new JLabel("Retrait gauche (pts)", JLabel.TRAILING));
+    saisieIndentGauche = new JComboBox(new String[]{"0.0", "2.0", "5.0", "10.0", "15.0", "20.0"});
+    saisieIndentGauche.setEditable(true);
+    saisieIndentGauche.setSelectedItem(Float.toString(StyleConstants.getLeftIndent(att)));
+    pStyleParagraphes.add(saisieIndentGauche);
+    pStyleParagraphes.add(new JLabel("droit (pts)", JLabel.TRAILING));
+    saisieIndentDroite = new JComboBox(new String[]{"0.0", "2.0", "5.0", "10.0", "15.0", "20.0"});
+    saisieIndentDroite.setEditable(true);
+    saisieIndentDroite.setSelectedItem(Float.toString(StyleConstants.getRightIndent(att)));
+    pStyleParagraphes.add(saisieIndentDroite);
+    pStyleParagraphes.add(new JLabel("1ère ligne (pts)", JLabel.TRAILING));
+    saisieIndentPrem = new JComboBox(new String[]{"0.0", "2.0", "5.0", "10.0", "15.0", "20.0"});
+    saisieIndentPrem.setEditable(true);
+    saisieIndentPrem.setSelectedItem(Float.toString(StyleConstants.getFirstLineIndent(att)));
+    pStyleParagraphes.add(saisieIndentPrem);
+   Box pSaisieItems = Box.createHorizontalBox();
+   pSaisieItems.add(pStyleCaracteres);
+    pSaisieItems.add(Box.createHorizontalGlue());
+    pSaisieItems.add(pStyleParagraphes);
+   JPanel  pCommandesValidation = new JPanel(new FlowLayout(FlowLayout.CENTER));
+    JButton valideModifs = new JButton(
+            new GAction("Valider") {
+              public void executer() {
+                validerModifs();
+              }
+              ;
+            });
+    JButton annuleModifs = new JButton(
+            new GAction("Annuler") {
+              public void executer() {
+                dispose();
+              }
+              ;
+            });
+    pCommandesValidation.add(valideModifs);
+    pCommandesValidation.add(annuleModifs);
+    // cadre global de la fenêtre
+    JPanel cadre = new JPanel(new BorderLayout());
+    cadre.add(pStyleCaracteres, BorderLayout.WEST);
+   cadre.add(pStyleParagraphes, BorderLayout.EAST);
+    cadre.add(pCommandesValidation, BorderLayout.SOUTH);
+    setContentPane(cadre);
+    pack();
+    setVisible(true);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+      }
+    });
+  }
+  private void validerModifs() {
+    int entierSaisi;
+    float decimalSaisi;
+    StyleConstants.setFontFamily(att, (String) saisiePolice.getSelectedItem());
+    StyleConstants.setForeground(att, (Color) saisieCouleur.getSelectedItem());
+    StyleConstants.setBackground(att, (Color) saisieFond.getSelectedItem());
+    try {
+      entierSaisi = Integer.parseInt((String) saisieTaille.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      entierSaisi = StyleConstants.getFontSize(att);
+    }
+    StyleConstants.setFontSize(att, entierSaisi);
+    StyleConstants.setBold(att, (boolean) saisieGras.isSelected());
+    StyleConstants.setItalic(att, (boolean) saisieItalique.isSelected());
+    StyleConstants.setUnderline(att, (boolean) saisieSouligne.isSelected());
+    StyleConstants.setAlignment(att, PanneauTexte.codeAlignement((String) saisieAlignement.getSelectedItem()));
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieEspaceAvant.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = StyleConstants.getSpaceAbove(att);
+    }
+    StyleConstants.setSpaceAbove(att, decimalSaisi);
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieEspaceApres.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = StyleConstants.getSpaceBelow(att);
+    }
+    StyleConstants.setSpaceBelow(att, decimalSaisi);
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieIndentGauche.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = StyleConstants.getLeftIndent(att);
+    }
+    StyleConstants.setLeftIndent(att, decimalSaisi);
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieIndentDroite.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = StyleConstants.getRightIndent(att);
+    }
+    StyleConstants.setRightIndent(att, decimalSaisi);
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieIndentPrem.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = StyleConstants.getFirstLineIndent(att);
+    }
+    StyleConstants.setFirstLineIndent(att, decimalSaisi);
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieInterligne.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = (Float) StyleConstants.getLineSpacing(att);
+    }
+    StyleConstants.setLineSpacing(att, decimalSaisi);
+    pEditeur.changerStyleTexte(att);
+    dispose();
+  }
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/texte/VisuStyleTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauOccurrences.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauOccurrences.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauOccurrences.java	(revision 481)
@@ -0,0 +1,172 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import visuAnalec.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class PanneauOccurrences extends JTable implements ListSelectionListener {
+  ModeleTableauOcc modele;
+  ModeleTableur modeleTableur;
+  Vue vue;
+  PanneauEditeur pEditeur;
+  Element[] listElt;
+  final static int EMPAN = 80;  // paramètre à saisir (un jour)
+  public PanneauOccurrences(Vue vue, PanneauEditeur pEditeur) {
+    super();
+    modele = new ModeleTableauOcc();
+    setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+    setModel(modele);
+    modeleTableur = new ModeleTableur();
+    getSelectionModel().addListSelectionListener(this);
+    this.vue = vue;
+    this.pEditeur = pEditeur;
+  }
+  public TableModel getModeleTableur() {
+    return modeleTableur;
+  }
+  public void initVide() {
+    listElt = new Element[0];
+    getTableHeader().setVisible(false);
+    modele.clear();
+    modeleTableur.clear();
+  }
+  public void init(Class<? extends Element> classe, String type, Element[] listElt) {
+    this.listElt = listElt;
+    if (listElt.length==0) {
+      initVide();
+      return;
+    }
+    getTableHeader().setVisible(true);
+    String[] ids = vue.getIdListeElements(classe, type, listElt);
+    String[][] concordances = vue.getCorpus().getConcordances(listElt, EMPAN);
+    String[] champs = vue.getNomsChamps(classe, type);
+    String[][] valeurs = vue.getValeursChampsListeElements(champs, listElt);
+    modele.setModele(ids, concordances);
+    modeleTableur.setModele(ids, concordances, champs, valeurs);
+    getColumnModel().getColumn(0).setPreferredWidth(150);
+    getColumnModel().getColumn(1).setMinWidth(1200);
+  }
+  @Override
+  public void valueChanged(ListSelectionEvent evt) {
+    try {
+      if (evt.getValueIsAdjusting()) return;
+      if (evt.getSource().equals(getSelectionModel())) {
+        int row = getSelectedRow();
+        if (row>=0) pEditeur.editerElement(listElt[row]);
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.toString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  private static class ModeleTableauOcc extends AbstractTableModel {
+    final static String STYLE_HTML = "<html>";
+    final static String STYLE_DEB_SELECT =
+            "<span style=\"font-weight:bold; background-color:#FFFF80\">";
+    final static String STYLE_FIN_SELECT = "</span>";
+    String[] ids;
+    String[] extraits;
+    public ModeleTableauOcc() {
+      super();
+      clear();
+    }
+    public int getRowCount() {
+      return ids.length;
+    }
+    public int getColumnCount() {
+      return 2;
+    }
+    @Override
+    public String getColumnName(int columnIndex) {
+      return columnIndex==0 ? "Identifiants" : "Occurrences";
+    }
+    public Object getValueAt(int rowIndex, int columnIndex) {
+      return columnIndex==0 ? ids[rowIndex] : extraits[rowIndex];
+
+    }
+    private void clear() {
+      ids = new String[0];
+    }
+    private void setModele(String[] ids, String[][] concordances) {
+      this.ids = ids;
+      extraits = new String[ids.length];
+      for (int i = 0; i<ids.length; i++)
+        extraits[i] = formerExtrait(concordances[i]);
+      fireTableDataChanged();
+    }
+    private String formerExtrait(String[] concordance) {
+      return STYLE_HTML+concordance[0]+STYLE_DEB_SELECT+concordance[1]
+              +STYLE_FIN_SELECT+concordance[2];
+    }
+  }
+
+  private static class ModeleTableur extends AbstractTableModel {
+    String[] ids;
+    String[][] concordances;
+    String[] champs;
+    String[][] valeurs;
+    public ModeleTableur() {
+      super();
+      clear();
+    }
+    public int getRowCount() {
+      return ids.length;
+    }
+    public int getColumnCount() {
+      return 4+champs.length;
+    }
+    @Override
+    public String getColumnName(int columnIndex) {
+      switch (columnIndex) {
+        case 0:
+          return "Identifiants";
+        case 1:
+          return "Contexte gauche";
+        case 2:
+          return "Elément";
+        case 3:
+          return "Contexte droit";
+        default:
+          return champs[columnIndex-4];
+      }
+    }
+    public Object getValueAt(int rowIndex, int columnIndex) {
+      switch (columnIndex) {
+        case 0:
+          return ids[rowIndex];
+        case 1:
+        case 2:
+        case 3:
+          return concordances[rowIndex][columnIndex-1];
+        default:
+          return valeurs[rowIndex][columnIndex-4];
+      }
+
+    }
+    private void clear() {
+      champs = ids = new String[0];
+    }
+    private void setModele(String[] ids, String[][] concordances,
+            String[] champs, String[][] valeurs) {
+      this.ids = ids;
+      this.concordances = concordances;
+      this.champs = champs;
+      this.valeurs = valeurs;
+      fireTableDataChanged();
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/texte/PanneauOccurrences.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ModeleStatChaine.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ModeleStatChaine.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ModeleStatChaine.java	(revision 481)
@@ -0,0 +1,224 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.chaines;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import javax.swing.table.*;
+import visuAnalec.elements.Schema;
+import visuAnalec.elements.Unite;
+import visuAnalec.vue.Vue;
+/**
+ *
+ * @author Marc
+ */
+public class ModeleStatChaine extends AbstractTableModel{
+
+    private Object[][] donnees;
+    private String[] entetes= new String[]{"Trigramme","Nombre d'occurences","Fréquence","Position moyenne"};
+    	@Override
+	public int getColumnCount() {
+		return entetes.length;
+        }
+        @Override
+	public String getColumnName(int columnIndex) {
+		return entetes[columnIndex];
+	}
+        public ModeleStatChaine(Object[][] donnees,String[] titres){
+            this.donnees = donnees;
+            this.entetes= titres;
+        }
+        public ModeleStatChaine(){
+            this.donnees = new Object[0][0];
+            this.entetes = new String[0];
+        }
+        public int getRowCount() {
+		return donnees.length;
+	}
+
+	@Override
+	public Object getValueAt(int rowIndex, int columnIndex) {
+		return donnees[rowIndex][columnIndex];
+	}
+        @Override
+        public Class getColumnClass(int columnIndex){
+            switch(columnIndex){
+                    case 0:
+                            return String.class;
+                    default:
+                            return Float.class;
+            }
+        }
+        
+        public HashMap<Object,HashMap<Object,Float>> conversionNbOccurencesToFrequence(
+                HashMap<Object,HashMap<Object,Float>> donnees){
+            float sommepartielle;
+            for(Object val : donnees.keySet()){
+                sommepartielle = 0.0f;
+                for(Object val1 : donnees.get(val).keySet()){
+                    sommepartielle = sommepartielle + (donnees.get(val)).get(val1);
+                }
+                for(Object val1 : donnees.get(val).keySet()){
+                    (donnees.get(val)).put(val1,(sommepartielle!=0.0f ?
+                            (donnees.get(val)).get(val1)*10000.0f/sommepartielle/100.0f : 0.0f));
+                }
+            }
+            return donnees;
+        }
+        
+        public void getTableau(HashMap<Object,HashMap<Object,Float>> donnees,int nbcolonnes,String observation){
+            Object[][] resultat = new Object[donnees.size()][nbcolonnes+2];
+            String[] titre = new String[nbcolonnes+2];
+            int i = 0;
+            HashMap<Object,Integer> idcolonnes = new HashMap();
+            donnees = conversionNbOccurencesToFrequence(donnees);
+            titre[0]=observation;
+            //on choisit les colonnes des valeurs
+            //grossier
+            for(Object val : donnees.keySet()){
+                i = 0;
+                for(Object val1 : donnees.get(val).keySet()){
+                    titre[i+1] = val1.toString();
+                    idcolonnes.put(val1,i+1);
+                    i = i + 1;
+                }
+            }
+            i=0;
+            for(Object val : donnees.keySet()){
+                //on écrit l'objet surlequel porte l'observation
+                resultat[i][0]=val;
+                for(Object val1 : donnees.get(val).keySet()){
+                    resultat[i][idcolonnes.get(val1)] = (donnees.get(val)).get(val1);
+                }
+                i = i + 1;
+            }
+            this.entetes = titre;
+            this.donnees = resultat;
+            
+        }
+        
+        //@require : typeChampLigne n'a aucune case nulle, typeUnite et typeChaine sont non-null
+        // typeChampColonne est défini 
+        //génère un modèle pour un tableau en comptant le nombre d'occurrence de la valeur du champ en tête de
+        //colonne par par valeur du ou des champs en tête de ligne
+        public static ModeleStatChaine calculateStatCoref(String nomChampChaine ,
+                String nomChampUnite, Collection<String> valeurChaineCachees,
+                String typeChampColonne, String[] typeChampLigne, Vue vue, ModeleChaines donneesChaine,
+                ArrayList paragrapheCaches, String typeChaine, String typeUnite, String[] valNbElements){
+            HashMap<Object,HashMap<Object,Float>> retour = new HashMap();
+            Unite[] listeUnites = donneesChaine.getUnites();
+            int[] noparag = (vue.getCorpus()).calculerNoParagraphe(listeUnites);
+            
+            //on créé une ligne par défaut
+            HashMap defaultLine = new HashMap();
+        switch (typeChampColonne) {
+            case "Chaine":
+                //un champ de la chaine ne peut pas être nul
+                for(String val : vue.getValeursChamp(Schema.class, typeChaine, nomChampChaine)){
+                    defaultLine.put(val, 0.0f);
+                }
+                defaultLine.put("Aucune valeur",0.0f);
+                break;
+            case "Unite":
+                for(String val : (nomChampUnite == null ? valNbElements
+                        : vue.getValeursChamp(Unite.class, typeUnite, nomChampUnite))){
+                    defaultLine.put(val, 0.0f);
+                }
+                defaultLine.put("Aucune valeur",0.0f);
+                break;
+            default:
+                for(int val : noparag){
+                    defaultLine.put("  Paragraphe " + val, 0.0f);
+                }
+                break;
+        }
+            
+            
+            int numeroUnite = 0;
+            for(Unite unit : listeUnites){
+                Schema chaine = donneesChaine.getchainesUnitesNonFiltrees().get(unit);
+                
+                //on filtre les unités
+                String propUnite = ( nomChampUnite==null ? valNbElements
+                                    [donneesChaine.calculerValNbElements(
+                                            donneesChaine.getChainonUnites().get(unit).nbEltsChaine)]
+                                    : vue.getValeurChamp(unit, nomChampUnite));
+                
+                String propChaine = chaine==null ? null : (vue.getValeurChamp(chaine, nomChampChaine)) ;
+                
+                if(!paragrapheCaches.contains(noparag[numeroUnite]) && chaine!=null &&
+                        !(nomChampUnite==null ? donneesChaine.isMasqueeValNbElements(donneesChaine.
+                        calculerValNbElements(donneesChaine.getChainonUnites().get(unit).nbEltsChaine))
+                        : donneesChaine.isMasqueeValChamp(nomChampUnite, propUnite)) && 
+                        !valeurChaineCachees.contains(propChaine)){
+                    
+                    //on calcule la clé de la ligne sous forme de chaine de caractère
+                    String key1 = new String();
+                    for(int i = 0;i<typeChampLigne.length;i++){
+                        switch (typeChampLigne[i]) {
+                            case "Chaine": 
+                                key1 = key1 + "  " + (propChaine == null || propChaine.equals("")
+                                        ? "Aucune valeur" : propChaine);
+                                break;
+                            case "Unite":
+                                key1 = key1 + "  " + (propUnite == null || propUnite.equals("") ? 
+                                        "Aucune valeur" : propUnite);
+                                break;
+                            default:
+                                key1 = key1 + "  Paragraphe " + noparag[numeroUnite];
+                                break;
+                        }
+                    }
+                    //on cherche la clé de la colonne et on initialise les valeurs
+                    String key2 = new String();
+                    switch (typeChampColonne) {
+                        case "Chaine":
+                            key2 = key2 + (propChaine == null || propChaine.equals("")
+                                    ? "Aucune valeur" : propChaine);
+                            break;
+                        case "Unite": 
+                            key2 = key2 + (propUnite == null || propUnite.equals("")
+                                    ? "Aucune valeur" : propUnite);
+                            break;
+                        default:
+                            key2 = key2 + "  Paragraphe " + noparag[numeroUnite];
+                            break;
+                    }
+                    //on ajoute l'unité dans la table correspondante
+                    HashMap<Object,Float> ligne = (retour.containsKey(key1) ? retour.get(key1) :
+                            (HashMap<Object,Float>) defaultLine.clone());
+                    ligne.put(key2 , ligne.get(key2) + 1);
+                    retour.put(key1, ligne);   
+                }
+                numeroUnite++;
+            }
+            
+            String titreLigne = new String();
+            for(String type : typeChampLigne){
+                switch (type) {
+                    case "Chaine":
+                        titreLigne = titreLigne + "  Valeur Champ Chaine";
+                        break;
+                    case "Unite":
+                        titreLigne = titreLigne + "  Valeur Champ Unite";
+                        break;
+                    default:
+                        titreLigne = titreLigne + "  Numero Paragraphe";
+                        break;
+                }
+            }
+            ModeleStatChaine modele = new ModeleStatChaine();
+            modele.getTableau(retour,defaultLine.size(),titreLigne);
+            return modele;
+        }
+        
+    
+
+        
+        
+
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ModeleStatChaine.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/NgrammesPanel.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/NgrammesPanel.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/NgrammesPanel.java	(revision 481)
@@ -0,0 +1,526 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.chaines;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.HashMap;
+import java.util.HashSet;
+import javax.swing.Box;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+import visuAnalec.Message;
+import visuAnalec.elements.Schema;
+import visuAnalec.elements.Unite;
+import visuAnalec.util.GMessages;
+import visuAnalec.util.GVisu;
+import visuAnalec.vue.Vue;
+
+/**
+ *
+ * @author marc
+ * panneau affichage des statistiques des n-grams
+ */
+public class NgrammesPanel extends JPanel implements Vue.VueListener, ActionListener {
+
+private JList legendechampstatistique;
+private JPopupMenu popupChampstat = new JPopupMenu();
+private JPopupMenu popupChamptrigramme = new JPopupMenu();
+private JCheckBox digrammeXX = new JCheckBox();
+private JCheckBox trigrammeXOX = new JCheckBox();
+private JCheckBox trigrammeXOY = new JCheckBox();
+private JCheckBox trigrammeXXX = new JCheckBox();
+private JCheckBox trigrammeXYZ = new JCheckBox();
+private final GVisu.Val0ComboBox typeChamp;
+private final GVisu.Val0ComboBox champstatistique;
+private final GVisu.Val0ComboBox saisiechampchaine;
+private final JCheckBox activeparagraphe;
+private final JCheckBox activeglissant;
+private final JCheckBox activesingleton;
+private final Box commandesstat;
+private String[] valsAfficheesstat;
+private NgrammesModel ngrammesModel;
+private HashSet valsAfficheesautrestat=new HashSet();
+private Vue vue;
+private String typeChaines;
+private String typeUnites;
+private JTable resultatstatistique;
+private ModeleChaines donneesChaines;
+private final String[] statpossibles = new String[]{"Digramme","Trigramme"};
+
+public NgrammesPanel(Vue vue){    
+    this.vue=vue;
+    vue.addEventListener(this);
+    
+    legendechampstatistique = new JList();
+    legendechampstatistique.addMouseListener(new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+        check(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInitStat(legendechampstatistique.locationToIndex(e.getPoint()));
+          popupChampstat.show(legendechampstatistique, e.getX(), e.getY());
+        }
+      }
+    });
+    typeChamp = new GVisu.Val0ComboBox("Rien");
+    typeChamp.addActionListener(this);
+    champstatistique = new GVisu.Val0ComboBox("Rien");
+    champstatistique.addActionListener(this);  
+    saisiechampchaine = new GVisu.Val0ComboBox("Rien");
+    saisiechampchaine.addActionListener(this);  
+    activeparagraphe = new JCheckBox("activer les paragraphes (chiffre 0)");
+    activeglissant = new JCheckBox("activer le mode glissant");
+    activesingleton = new JCheckBox("activer l'affichage des singletons");
+    commandesstat = Box.createVerticalBox();
+    commandesstat.add(Box.createVerticalGlue());
+    commandesstat.add(activeparagraphe);
+    commandesstat.add(Box.createVerticalGlue());
+    commandesstat.add(activeglissant);
+    commandesstat.add(Box.createVerticalGlue());
+    commandesstat.add(activesingleton);    
+    commandesstat.add(Box.createVerticalGlue());
+    commandesstat.add(new JLabel("Choisisser une statistique : "));
+    commandesstat.add(champstatistique);
+    commandesstat.add(Box.createVerticalGlue());
+    commandesstat.add(new JLabel("Choisisser un type de champ: "));
+    commandesstat.add(typeChamp);    
+    commandesstat.add(Box.createVerticalGlue());
+    commandesstat.add(new JLabel("Choisisser un champ de la chaine : "));
+    commandesstat.add(saisiechampchaine);
+    commandesstat.add(Box.createVerticalGlue());
+    commandesstat.add(legendechampstatistique);  
+    commandesstat.add(Box.createVerticalGlue());
+    digrammeXX = new JCheckBox("Compter les digrammes de type XX");
+    commandesstat.add(digrammeXX); 
+    commandesstat.add(Box.createVerticalGlue());
+    trigrammeXOX = new JCheckBox("Compter les digrammes de type X0X");
+    commandesstat.add(trigrammeXOX);     
+    commandesstat.add(Box.createVerticalGlue());
+    trigrammeXOY = new JCheckBox("Compter les digrammes de type X0Y");
+    commandesstat.add(trigrammeXOY); 
+    commandesstat.add(Box.createVerticalGlue());
+    trigrammeXYZ = new JCheckBox("Compter les digrammes de type XYZ");
+    commandesstat.add(trigrammeXYZ); 
+    commandesstat.add(Box.createVerticalGlue());
+    trigrammeXXX = new JCheckBox("Compter les digrammes de type XXX");
+    commandesstat.add(trigrammeXXX); 
+    JScrollPane scrollstat = new JScrollPane(commandesstat);
+    this.donneesChaines = null;
+        
+    Box resultatstat = Box.createVerticalBox();
+    resultatstat.add(Box.createVerticalGlue());
+    resultatstat.add(new JLabel("Statistique : "));
+    resultatstat.add(Box.createVerticalGlue());
+    
+    DefaultTableModel initModel = new DefaultTableModel(new Object[0][0],
+    new String[]{"Ngramme","Nombre d'occurences","Fréquence","Position moyenne"}){
+               Class[] types = new Class [] {
+                java.lang.String.class, java.lang.Integer.class,java.lang.Float.class,java.lang.Float.class
+            };
+
+            public Class getColumnClass(int columnIndex) {
+                return types [columnIndex];
+            }
+
+            };
+    
+    resultatstatistique = new JTable(initModel);
+    resultatstatistique.addMouseListener(new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+        check(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInitTrigramme(resultatstatistique.rowAtPoint(e.getPoint()));
+          popupChamptrigramme.show(resultatstatistique, e.getX(), e.getY());
+        }
+      }
+    });
+    JScrollPane jsp =new JScrollPane(resultatstatistique);
+    resultatstat.add(resultatstatistique.getTableHeader());
+    resultatstat.add(jsp);
+    typeChamp.setAlignmentX(0);
+    champstatistique.setAlignmentX(0);
+    saisiechampchaine.setAlignmentX(0);
+    legendechampstatistique.setAlignmentX(0); 
+    JScrollPane scrollstatresultat = new JScrollPane(resultatstat);
+    JSplitPane split1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,  scrollstat,scrollstatresultat);
+    add(split1);
+    split1.setDividerLocation(1./4);
+    
+}
+
+public void setDonneesChaines(ModeleChaines donneesChaines){
+    this.donneesChaines=donneesChaines;
+}
+
+public void setVue(Vue vue){
+    this.vue= vue;
+}
+
+public void setTypeChaines(String typeChaines){
+    this.typeChaines=typeChaines;
+}
+
+public void setTypeUnites(String typeUnites){
+    this.typeUnites=typeUnites;
+}
+
+public void update(){
+    if(this.donneesChaines!=null && this.vue!=null && this.typeChaines!=null && this.typeUnites!=null){
+        initstat();
+    }
+    else{
+        init();
+    }
+}
+
+public void importerAffichage(HashMap choix){
+        typeChamp.removeActionListener(this);
+        saisiechampchaine.removeActionListener(this);
+        champstatistique.removeActionListener(this);
+        activeparagraphe.setSelected(choix.get("activeparagraphe").equals("vrai"));
+        activeglissant.setSelected(choix.get("activeglissant").equals("vrai"));
+        activesingleton.setSelected(choix.get("activesingleton").equals("vrai"));
+        digrammeXX.setSelected(choix.get("digrammeXX").equals("vrai"));
+        trigrammeXOX.setSelected(choix.get("trigrammeXOX").equals("vrai"));
+        trigrammeXOY.setSelected(choix.get("trigrammeXOY").equals("vrai"));
+        trigrammeXXX.setSelected(choix.get("trigrammeXXX").equals("vrai"));
+        trigrammeXYZ.setSelected(choix.get("trigrammeXYZ").equals("vrai"));
+        if(choix.get("typeChamp")!=null){
+          typeChamp.setSelectedItem(choix.get("typeChamp"));
+          if(!typeChamp.pasdeSelection()){
+            switch(typeChamp.getSelection()){
+                case "Chaine" :
+                    saisiechampchaine.removeActionListener(this);
+                    saisiechampchaine.setModele(vue.getNomsChamps(Schema.class, typeChaines));
+                    saisiechampchaine.addActionListener(this);                       
+                    break;
+                case "Unité" :
+                    saisiechampchaine.removeActionListener(this);
+                    saisiechampchaine.setModele(vue.getNomsChamps(Unite.class, typeUnites));
+                    saisiechampchaine.addActionListener(this);                        
+                    break;
+                default :
+                    saisiechampchaine.removeActionListener(this);
+                    saisiechampchaine.setModeleVide();
+                    saisiechampchaine.addActionListener(this);                      
+                    break;
+            }
+          }
+          else{
+                saisiechampchaine.removeActionListener(this);
+                saisiechampchaine.setModeleVide();
+                saisiechampchaine.addActionListener(this);                 
+          }
+        }
+        else{
+          typeChamp.effSelection();
+        }
+        
+        if(choix.get("saisiechampchaine")!=null){
+          saisiechampchaine.setSelectedItem(choix.get("saisiechampchaine"));
+        }
+        else{
+          saisiechampchaine.effSelection();
+        }
+        if(choix.get("champstatistique")!=null){
+        champstatistique.setSelectedItem(choix.get("champstatistique"));
+        }
+        else{
+          champstatistique.effSelection();
+        }
+        typeChamp.addActionListener(this);
+        saisiechampchaine.addActionListener(this);
+        champstatistique.addActionListener(this);
+        this.valsAfficheesautrestat = (HashSet) choix.get("valsAfficheesautrestat");
+        this.valsAfficheesstat = (String[]) choix.get("valsAfficheesstat");
+    
+}
+
+public HashMap exporterAffichage(){
+    HashMap choix = new HashMap();
+      choix.put("activeparagraphe",activeparagraphe.isSelected() ? "vrai" : "faux");
+      choix.put("activeglissant",activeglissant.isSelected() ? "vrai" : "faux");
+      choix.put("activesingleton",activesingleton.isSelected() ? "vrai" : "faux");
+      choix.put("digrammeXX",digrammeXX.isSelected() ? "vrai" : "faux");
+      choix.put("trigrammeXOX",trigrammeXOX.isSelected() ? "vrai" : "faux");
+      choix.put("trigrammeXOY",trigrammeXOY.isSelected() ? "vrai" : "faux");
+      choix.put("trigrammeXXX",trigrammeXXX.isSelected() ? "vrai" : "faux");
+      choix.put("trigrammeXYZ",trigrammeXYZ.isSelected() ? "vrai" : "faux");
+      choix.put("typeChamp",typeChamp.pasdeSelection() ? null : typeChamp.getSelection());
+      choix.put("saisiechampchaine",saisiechampchaine.pasdeSelection() ? null : saisiechampchaine.getSelection());
+      choix.put("champstatistique",champstatistique.pasdeSelection() ? null : champstatistique.getSelection());
+      choix.put("valsAfficheesautrestat",valsAfficheesautrestat);
+      choix.put("valsAfficheesstat",valsAfficheesstat);
+    return choix;
+    
+}
+
+private void popupChampInitStat(final int index) {
+    popupChampstat.removeAll();
+    if (saisiechampchaine.pasdeSelection()) {
+    } else if (index>=valsAfficheesstat.length - valsAfficheesautrestat.size()) {
+      popupChampstat.add(new GMessages.GAction("Afficher toutes les autres valeurs") {
+        @Override
+        public void executer() {
+          eclaterautres();
+        }
+      });
+    } else {
+      popupChampstat.add(new GMessages.GAction("Ajouter à la valeur autre") {
+        @Override
+        public void executer() {
+          ajouteraautres(legendechampstatistique.getModel().getElementAt(index));
+        }
+      });
+    }
+  }
+
+private void popupChampInitTrigramme(final int index) {
+    popupChamptrigramme.removeAll();
+    if (!champstatistique.pasdeSelection() && !saisiechampchaine.pasdeSelection()) {
+        String valeur = resultatstatistique.getValueAt(index, 0).toString();
+        if(!valeur.equals("x0x") && !valeur.equals("xx") &&!valeur.equals("x0y") &&!valeur.equals("xyz") &&
+                !valeur.equals("xxx")){
+            String[] affichage;
+            switch(champstatistique.getSelection()){
+                case "Digramme" :
+                    affichage = ngrammesModel.infoSuivant(valeur);
+                    break;
+                case "Trigramme" :
+                    affichage = ngrammesModel.infoSuivant(valeur);
+                    break;
+                default :
+                    affichage = new String[0];
+                    break;
+            }
+            for(int i = 0; i < affichage.length;i++){
+                popupChamptrigramme.add(new JLabel(affichage[i]));
+            }
+        }
+    } 
+  }
+//permet d'ajouter à la catégorie "autre" la valeur d'un champ
+  private void ajouteraautres (Object valeur){
+
+        this.valsAfficheesautrestat.add(valeur.toString().substring(4));
+
+    initstat();
+  }
+  private void eclaterautres(){
+    this.valsAfficheesautrestat.clear();
+    initstat();
+  }
+  
+  public HashMap<String,Character> LegendeStat(String[] valsAfficheesstat,HashSet valsAfficheesautre){
+      HashMap<String,Character> retour = new HashMap<String,Character>();
+      int compte = 0;
+      for(String unit : valsAfficheesstat){
+          if(!valsAfficheesautre.contains(unit) ){
+          compte = compte + 1;
+          retour.put(unit,GVisu.intToChar(compte));
+          }
+      }
+      retour.put("autre", GVisu.intToChar(compte+1));
+      retour.put("singleton", GVisu.intToChar(compte+2));
+     return retour;
+  }
+  
+
+  public void AfficherLegendeStat(HashMap<String,Character> donnee){
+  String[] legendes = new String[donnee.size()];
+  for(String unit : donnee.keySet()){
+    legendes[GVisu.CharToInt(donnee.get(unit)) - 1]= "" + donnee.get(unit) +"   "+ unit;
+  }
+  legendechampstatistique.setListData(legendes);
+  }
+  
+  public void initstat(){
+      if(!champstatistique.pasdeSelection() && !saisiechampchaine.pasdeSelection() && !typeChamp.pasdeSelection()){
+            switch(typeChamp.getSelection()){
+                case "Chaine" :
+                    this.valsAfficheesstat = vue.getValeursChamp(Schema.class,typeChaines,
+                            saisiechampchaine.getSelection());              
+                    break;
+                case "Unité" :
+                    this.valsAfficheesstat = vue.getValeursChamp(Unite.class,typeUnites,
+                            saisiechampchaine.getSelection());                      
+                    break;
+            }
+        HashMap<String,Character> legende = LegendeStat(this.valsAfficheesstat,this.valsAfficheesautrestat);
+        AfficherLegendeStat(legende);
+        this.ngrammesModel=new NgrammesModel();
+        int nbLettre;
+        if( "Trigramme".equals(champstatistique.getSelection())){
+            nbLettre = 3;
+        }
+        else if("Digramme".equals(champstatistique.getSelection())){
+            nbLettre = 2;
+        }
+        else{
+            nbLettre = 1;
+        }
+        //on calcule le modèle des ngrammes
+        this.ngrammesModel.ngrammeUpdate(nbLettre, legende,saisiechampchaine.getSelection(),vue,
+                activeglissant.isSelected(), donneesChaines,activesingleton.isSelected(), 
+                typeChamp.getSelection(),activeparagraphe.isSelected());
+        boolean[] ligneSup;
+        if( "Trigramme".equals(champstatistique.getSelection())){
+            ligneSup = new boolean[4];
+            ligneSup[0]=trigrammeXOX.isSelected();
+            ligneSup[1]=trigrammeXOY.isSelected();
+            ligneSup[2]=trigrammeXYZ.isSelected();
+            ligneSup[3]=trigrammeXXX.isSelected();
+        }
+        else if("Digramme".equals(champstatistique.getSelection())){
+            ligneSup = new boolean[1];
+            ligneSup[0]=digrammeXX.isSelected();
+        }
+        else{
+            ligneSup = new boolean[0];
+        }
+        ((DefaultTableModel) resultatstatistique.getModel()).setDataVector(
+                this.ngrammesModel.gettableau(ligneSup),new String[]{champstatistique.getSelection()
+                        ,"Nombre d'occurences","Fréquence","Position moyenne"});
+        resultatstatistique.setAutoCreateRowSorter(true);
+          
+      }
+  }
+  
+  @Override
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource().equals(saisiechampchaine)) {
+        this.valsAfficheesautrestat.clear();
+        initstat();
+        return;
+      }
+      if (evt.getSource().equals(champstatistique)) {
+          this.valsAfficheesautrestat.clear();
+          initstat();
+        return;
+      }
+      if (evt.getSource().equals(typeChamp)) {
+          if(!typeChamp.pasdeSelection()){
+            switch(typeChamp.getSelection()){
+                case "Chaine" :
+                    saisiechampchaine.removeActionListener(this);
+                    saisiechampchaine.setModele(vue.getNomsChamps(Schema.class, typeChaines));
+                    saisiechampchaine.addActionListener(this);                       
+                    break;
+                case "Unité" :
+                    saisiechampchaine.removeActionListener(this);
+                    saisiechampchaine.setModele(vue.getNomsChamps(Unite.class, typeUnites));
+                    saisiechampchaine.addActionListener(this);                        
+                    break;
+                default :
+                    saisiechampchaine.removeActionListener(this);
+                    saisiechampchaine.setModeleVide();
+                    saisiechampchaine.addActionListener(this);                      
+                    break;
+            }
+          }
+          else{
+                saisiechampchaine.removeActionListener(this);
+                saisiechampchaine.setModeleVide();
+                saisiechampchaine.addActionListener(this);                 
+          }
+        return;
+      } 
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  @Override
+  public void traiterEvent(Message evt) { // très grossier : à améliorer
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre chaines présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        return;
+      case MODIF_VUE:
+        return;
+      case MODIF_STRUCTURE:
+        return;
+      case MODIF_ELEMENT:
+//        ElementEvent evtE = (ElementEvent) evt;
+//        if (evtE.getModif() != TypeModifElement.BORNES_UNITE) fermerFenetre();
+        return;
+      case CORPUS_SAVED:
+          return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  
+  public void init(){
+      
+    typeChamp.removeActionListener(this);
+    typeChamp.setModele(new String[]{"Chaine","Unité"});
+    typeChamp.setSelectedIndex(0);
+    typeChamp.addActionListener(this);      
+    saisiechampchaine.removeActionListener(this);
+    //saisiechampchaine.setModele(vue.getNomsChamps(Schema.class, typeChaines));
+    saisiechampchaine.setModeleVide();
+    saisiechampchaine.addActionListener(this);    
+    champstatistique.removeActionListener(this);
+    champstatistique.setModele(statpossibles);
+    champstatistique.addActionListener(this);    
+    if(vue!=null && donneesChaines!=null){
+        initstat();
+    }
+      
+  }
+  
+  public void initVide(){
+    saisiechampchaine.setModeleVide();
+    champstatistique.setModeleVide();
+    typeChamp.setModeleVide();
+      
+  }
+  
+  public Object[][] donneesCSV(){
+        Object[][] donneesCSV = new Object[resultatstatistique.getRowCount()+1][resultatstatistique.getColumnCount()];
+        for(int i = 0 ; i < resultatstatistique.getRowCount();i++){
+             for(int j = 0 ; j < resultatstatistique.getColumnCount();j++){
+                donneesCSV[i+1][j]=resultatstatistique.getValueAt(i, j);
+             }
+        }
+        for(int j = 0 ; j < resultatstatistique.getColumnCount();j++){
+                donneesCSV[0][j]=resultatstatistique.getColumnName(j);
+        }
+        return donneesCSV;
+  }
+
+
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/NgrammesPanel.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/NgrammesModel.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/NgrammesModel.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/NgrammesModel.java	(revision 481)
@@ -0,0 +1,354 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.chaines;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import visuAnalec.elements.Schema;
+import visuAnalec.elements.Unite;
+import visuAnalec.vue.Vue;
+
+/**
+ *
+ * @author marc
+ */
+public class NgrammesModel {
+       public class ngramme{
+            private HashSet<Unite[]> unites;
+            private ArrayList<String> suivant;
+            private float frequence;
+            private float posmoyenne;
+            public HashSet<Unite[]> getUnites(){
+                return unites;
+            }
+            public int getnboccurences(){
+                return unites.size();
+            }
+            public float getfrequence(){
+                return frequence;
+            }
+            public float getposmoyenne(){
+                return posmoyenne;
+            }
+            public void setposmoyenne(){
+                float somme = 0.0f;
+                for(Unite[] unit : unites){
+                    somme = somme + unit[0].getDeb();
+                }
+                this.posmoyenne= somme / unites.size();
+            }
+            public void setfrequence(HashMap<String,ngramme> total){
+                int somme = 0;
+                for(String code : total.keySet()){
+                    somme = somme + total.get(code).getnboccurences();
+                }
+                this.frequence = this.unites.size() * 10000.0f / somme / 100.0f;
+            }
+            public void addUnites(Unite[] donnees){
+                this.unites.add(donnees);
+            }
+            public void addSuivant(String suivant){
+                this.suivant.add(suivant);
+            }
+            public ngramme(){
+                this.unites = new HashSet();
+                this.frequence = 0.0f;
+                this.posmoyenne = 0.0f;
+                this.suivant = new ArrayList();
+            }
+            public ngramme(HashSet<Unite[]> unites,ArrayList<String> suivant){
+                this.frequence = 0.0f;
+                this.unites = unites;
+                this.suivant = suivant;
+                setposmoyenne();
+            }
+       }
+       private HashMap<String,ngramme> collection;
+       public NgrammesModel(){
+           this.collection = new HashMap();
+       }
+       public NgrammesModel(HashMap<String,ngramme> collection){
+           this.collection = collection;
+       }
+       public void setallfrequence(){
+           for(String code : this.collection.keySet()){
+               this.collection.get(code).setfrequence(this.collection);
+           }
+       }
+       public void setallposmoyenne(){
+           for(String code : this.collection.keySet()){
+               this.collection.get(code).setposmoyenne();
+           }
+       }
+
+       
+    //@require : les unités doivent être classées par ordre d'apparition       
+       public void ngrammeUpdate(int nbLettre,HashMap<String,Character> legende
+               ,String champ,Vue vue,boolean glissant,ModeleChaines donnees,boolean singleton,String typeChamp,
+               boolean activeParagraphe){
+           
+           ArrayList<Character> suiteLettre = new ArrayList();
+           String ngrammeCourant;
+           Unite[] unites=donnees.getUnites();
+           HashMap<String,ngramme> collection = new HashMap();
+           HashMap<Unite,Integer> noparagraphe = ChaineUtil.unitenumeroparagraphe(unites,vue);
+           int pas;
+           //on définit le pas de boucle en fonction du choix de l'utilisateur (glissant ou pas glissant)
+           if(glissant){
+               pas = 1;
+           }
+           else{
+               pas  = nbLettre;
+           }
+           //on crée la chaîne de lettres
+           for(int i = 0; i < unites.length; 
+                   i++){
+                Schema chaine;
+                if(singleton || donnees.getSchemacontenantunite((donnees.getUnites())[i])!=null){
+                    switch(typeChamp){
+                        case "Chaine":
+                            chaine=donnees.getSchemacontenantunite(unites[i]);
+                            suiteLettre.add(chaine==null ? legende.get("singleton") : (legende.get(vue.getValeurChamp(
+                      chaine,champ)))==null ? legende.get("autre") : legende.get(vue.getValeurChamp(chaine,champ)));
+                            break;
+                        default :
+                            suiteLettre.add(legende.get(vue.getValeurChamp(
+                      unites[i],champ))==null ? legende.get("autre") : legende.get(vue.getValeurChamp(unites[i],champ)));
+                            break;
+                    }
+                    if(activeParagraphe && i < (unites.length - 1) && noparagraphe.get(unites[i])<noparagraphe.get(unites[i+1])){
+                        suiteLettre.add('0');
+                    }
+               }
+           }
+           //on retient le numéro d'unité qui va être lue
+           int numeroUnite=0;
+           //on parcours la chaîne pour créer les ngrammes
+           for(int i = 0; i < suiteLettre.size()-(nbLettre-1); i = i + pas){
+               ArrayList<Unite> ajout=new ArrayList();
+               ngrammeCourant="";
+               int nbUnite=0;
+               //on crée le code constitué de nbLettre lettres
+               for(int j = 0; j < nbLettre;j++){
+                   ngrammeCourant=ngrammeCourant+suiteLettre.get(j+i);
+                   //si ce n'est pas un saut de paragraphe alors on incrémente le numéro de l'unité qui va être lue
+                   if(!suiteLettre.get(j+i).equals('0')){
+                       ajout.add(unites[numeroUnite+nbUnite]);
+                       nbUnite++;
+                   }
+               }
+               //on crée le ngramme obtenu
+               if(!collection.containsKey(ngrammeCourant)){
+                   collection.put(ngrammeCourant,new ngramme());
+               }
+               (collection.get(ngrammeCourant)).addUnites(
+                       ajout.toArray(new Unite[0]));
+               //on recherche l'éventuel suivant
+               if(i < suiteLettre.size() - nbLettre){
+                   (collection.get(ngrammeCourant)).addSuivant(suiteLettre.get(i+nbLettre).toString());
+               }
+               //si la première lettre correspond à une unité et non un suat de paragraphe on incrémente numeroUnite
+               if(!suiteLettre.get(i).equals('0')){
+                   numeroUnite++;
+               }
+           }
+           this.collection = collection;
+           setallfrequence();
+           setallposmoyenne();
+       }
+
+
+       public HashMap<String,ngramme> getCollection(){
+           return this.collection;
+       }
+       public Object[][] gettableau(boolean[] ligneSup){
+           Object[][] donnees;
+           int nbRowSup=0;   
+           for(int i = 0;i<ligneSup.length;i++){  
+               if(ligneSup[i]){
+                    nbRowSup++;
+               }
+           }
+           donnees = new Object[collection.size() + nbRowSup][4]; 
+           
+           int compte = 0;
+           for(String unit : collection.keySet()){
+               donnees[compte][0] = unit ;
+               donnees[compte][1] = collection.get(unit).getnboccurences() ;
+               donnees[compte][2] = collection.get(unit).getfrequence() ;
+               donnees[compte][3] = collection.get(unit).getposmoyenne();
+               compte++;
+           }
+           if(collection.size()>0){
+                //on ajoute les éventuelles lignes supplémentaires
+                switch(this.collection.keySet().iterator().next().length()){
+                    //si on a des digrammes
+                    case 2 :
+                         if(ligneSup[0]){
+                             donnees[compte] = calculXX();   
+                             compte++;
+                         }
+                        break;
+                     //si on a des trigrammes
+                    case 3 :
+                         if(ligneSup[0]){
+                             donnees[compte] = calculXOX();
+                             compte++;
+                         }
+                         if(ligneSup[1]){
+                             donnees[compte] = calculXOY();
+                             compte++;
+                         }
+                         if(ligneSup[2]){
+                             donnees[compte] = calculXYZ();
+                             compte++;
+                         }
+                         if(ligneSup[3]){
+                             donnees[compte] = calculXXX();
+                             compte++;
+                         }           
+                        break;
+                    default :
+                        break;
+                }
+           }
+           return donnees;
+           
+       }
+       //@require : le ngrammes contient des digrammes
+       public Object[] calculXX(){
+           Object[] retour  = new Object[4];
+           Float frequencecumulee = 0.0f;
+           Float positionmoyenne = 0.0f;
+           Integer Nboccurences = 0;
+           for(String doubletcourant : this.collection.keySet()){
+               if(doubletcourant.charAt(0)==doubletcourant.charAt(1)){
+                   frequencecumulee = frequencecumulee + this.collection.get(doubletcourant).getfrequence();
+                   positionmoyenne = positionmoyenne + this.collection.get(doubletcourant).getnboccurences()
+                           * this.collection.get(doubletcourant).getposmoyenne();
+                   Nboccurences = Nboccurences + this.collection.get(doubletcourant).getnboccurences();
+               }
+           }
+           positionmoyenne = Math.round(100 * positionmoyenne / Nboccurences)/100.0f;
+           retour[0] = "xx";
+           retour[1] = Nboccurences;
+           retour[2] = frequencecumulee;
+           retour[3] = positionmoyenne;
+           return retour;
+       } 
+       
+       public String[] infoSuivant(String code){
+           HashMap<String,Integer> totaux = new HashMap();
+           //on recense les lettres suivants le ngramme identifié par "code"
+           for(String next : this.collection.get(code).suivant){
+               if(totaux.containsKey(next)){
+                   totaux.put(next, totaux.get(next) + 1);
+               }
+               else{
+                   totaux.put(next, 1);
+               }
+           }
+           String[] retour = new String[totaux.size()];
+           int i = 0;
+           //on calcule des statistiques
+           for(String next : totaux.keySet()){
+               retour[i] = code + next + "   Nombre d'occurences : " + totaux.get(next).toString() +
+                       "   Fréquence : " + (Math.round(100.0f * totaux.get(next) / this.collection.get(code).suivant.size())/100.0f);
+               i = i + 1;
+           }
+           return retour;
+       }    
+       //@require : le ngrammes contient des digrammes
+       public Object[] calculXOX(){
+           Object[] retour  = new Object[4];
+           Float frequencecumulee = 0.0f;
+           Float positionmoyenne = 0.0f;
+           Integer Nboccurences = 0;
+           for(String tripletcourant : this.collection.keySet()){
+               if(tripletcourant.charAt(0)==tripletcourant.charAt(2) && tripletcourant.charAt(1)=='0'){
+                   frequencecumulee = frequencecumulee + this.collection.get(tripletcourant).getfrequence();
+                   positionmoyenne = positionmoyenne + this.collection.get(tripletcourant).getnboccurences()
+                           * this.collection.get(tripletcourant).getposmoyenne();
+                   Nboccurences = Nboccurences + this.collection.get(tripletcourant).getnboccurences();
+               }
+           }
+           positionmoyenne = Math.round(100 * positionmoyenne / Nboccurences)/100.0f;
+           retour[0] = "x0x";
+           retour[1] = Nboccurences;
+           retour[2] = frequencecumulee;
+           retour[3] = positionmoyenne;
+           return retour;
+       }
+              //@require : le ngrammes contient des digrammes
+//on recherche les triplets séparés par des paragraphe au extrémités différentes
+       public Object[] calculXOY(){
+           Object[] retour  = new Object[4];
+           Float frequencecumulee = 0.0f;
+           Float positionmoyenne = 0.0f;
+           Integer Nboccurences = 0;
+           for(String tripletcourant : this.collection.keySet()){
+               if(tripletcourant.charAt(1)=='0' && tripletcourant.charAt(0)!=tripletcourant.charAt(2)){
+                   frequencecumulee = frequencecumulee + this.collection.get(tripletcourant).getfrequence();
+                   positionmoyenne = positionmoyenne + this.collection.get(tripletcourant).getnboccurences()
+                           * this.collection.get(tripletcourant).getposmoyenne();
+                   Nboccurences = Nboccurences + this.collection.get(tripletcourant).getnboccurences();
+               }
+           }
+           positionmoyenne = Math.round(100 * positionmoyenne / Nboccurences)/100.0f;
+           retour[0] = "x0y";
+           retour[1] = Nboccurences;
+           retour[2] = frequencecumulee;
+           retour[3] = positionmoyenne;
+           return retour;
+       } 
+              //@require : le ngrammes contient des digrammes
+        public Object[] calculXYZ(){
+           Object[] retour  = new Object[4];
+           Float frequencecumulee = 0.0f;
+           Float positionmoyenne = 0.0f;
+           Integer Nboccurences = 0;
+           for(String tripletcourant : this.collection.keySet()){
+               if(tripletcourant.charAt(1)!=tripletcourant.charAt(2) && tripletcourant.charAt(0)!=tripletcourant.charAt(1) &&
+                       tripletcourant.charAt(0)!=tripletcourant.charAt(2) && tripletcourant.charAt(1)!='0'){
+                   frequencecumulee = frequencecumulee + this.collection.get(tripletcourant).getfrequence();
+                   positionmoyenne = positionmoyenne + this.collection.get(tripletcourant).getnboccurences()
+                           * this.collection.get(tripletcourant).getposmoyenne();
+                   Nboccurences = Nboccurences + this.collection.get(tripletcourant).getnboccurences();
+               }
+           }
+           positionmoyenne = Math.round(100 * positionmoyenne / Nboccurences)/100.0f;
+           retour[0] = "xyz";
+           retour[1] = Nboccurences;
+           retour[2] = frequencecumulee;
+           retour[3] = positionmoyenne;
+           return retour;
+       }
+       //@require : le ngrammes contient des digrammes
+       public Object[] calculXXX(){
+           Object[] retour  = new Object[4];
+           Float frequencecumulee = 0.0f;
+           Float positionmoyenne = 0.0f;
+           Integer Nboccurences = 0;
+           for(String tripletcourant : this.collection.keySet()){
+               if(tripletcourant.charAt(1)==tripletcourant.charAt(2) && tripletcourant.charAt(0)==tripletcourant.charAt(1)){
+                   frequencecumulee = frequencecumulee + this.collection.get(tripletcourant).getfrequence();
+                   positionmoyenne = positionmoyenne + this.collection.get(tripletcourant).getnboccurences()
+                           * this.collection.get(tripletcourant).getposmoyenne();
+                   Nboccurences = Nboccurences + this.collection.get(tripletcourant).getnboccurences();
+               }
+           }
+           positionmoyenne = Math.round(100 * positionmoyenne / Nboccurences)/100.0f;
+           retour[0] = "xxx";
+           retour[1] = Nboccurences;
+           retour[2] = frequencecumulee;
+           retour[3] = positionmoyenne;
+           return retour;
+       }         
+    
+    
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/NgrammesModel.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuConversion.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuConversion.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuConversion.java	(revision 481)
@@ -0,0 +1,315 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.chaines;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+/**
+ *
+ * @author marc
+ */
+public class VisuConversion extends JFrame implements VueListener, ActionListener{
+    private Box PanneauCommande = Box.createVerticalBox();
+    private Box PanneauCommandeSource = Box.createVerticalBox();
+    private Vue vue;
+    private PanneauEditeur panneauEditeur;
+    private JList choixModeConversion = new JList();
+    private JButton lancerConversion = new JButton("Convertir");
+    private JTextField nomSchema = new JTextField("Chaine de coréférence");
+    private Val0ComboBox typeSource = new Val0ComboBox("Rien");
+    private Val0ComboBox primaryKey = new Val0ComboBox("Rien");
+    private String[] otherKey = new String[0];
+    private Val0ComboBox addOtherKey = new Val0ComboBox("Rien");
+    private Val0ComboBox removeOtherKey = new Val0ComboBox("Rien");
+    private String[] sourcesPossibles = new String[]{"Type de Relation", "Type d'unité","Propriété d'unité"};
+    private String[] typesSourceDisponibles = new String[0];
+    private ArrayList<String> primaryKeyDisponibles = new ArrayList();
+    private ArrayList<String> otherKeyDisponibles = new ArrayList();
+    private ArrayList<String> otherKeyAjoutees = new ArrayList();
+    public VisuConversion(Container fenetre, Vue vue, PanneauEditeur pEditeur){
+        super("Conversion de données en schéma");
+        Point pos = new Point(fenetre.getX()+20, fenetre.getY()+20);
+        Dimension dim = new Dimension(700, 500);
+        setLocation(pos);
+        setSize(dim);
+        this.vue = vue;
+        vue.addEventListener(this);
+        this.panneauEditeur = pEditeur;
+        choixModeConversion.addMouseListener(new MouseAdapter() {
+        public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+          check(e);
+        }
+        public void mouseReleased(MouseEvent e) {
+          //check(e);
+        }
+        public void check(MouseEvent e) {
+          if (!e.isPopupTrigger()) {//si on a un clique gauche sur la liste
+            listAction(choixModeConversion.getSelectedIndex());
+          }
+        }
+        });
+        lancerConversion.addActionListener(this);
+        PanneauCommandeSource.add(Box.createVerticalStrut(20));
+        PanneauCommandeSource.add(new JLabel("Choix de la source de donnée :"));
+        PanneauCommandeSource.add(Box.createVerticalStrut(20));
+        PanneauCommandeSource.add(choixModeConversion);
+        PanneauCommandeSource.add(Box.createVerticalStrut(20));
+        PanneauCommandeSource.add(lancerConversion);        
+        JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, PanneauCommandeSource, PanneauCommande);
+        getContentPane().add(split);
+        split.setDividerLocation(1./3);
+        setVisible(true);
+        typeSource.setAlignmentX(0);
+        primaryKey.setAlignmentX(0);
+        addOtherKey.setAlignmentX(0);
+        removeOtherKey.setAlignmentX(0);
+        choixModeConversion.setAlignmentX(0);
+        // Fermeture de la fenêtre
+        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+        addWindowListener(new WindowAdapter() {
+          @Override
+          public void windowClosing(WindowEvent evt) {
+            fermerFenetre();
+          }
+        });
+        initVide();
+    }
+    public void initVide(){
+        PanneauCommande.removeAll();
+        choixModeConversion.setListData(sourcesPossibles);
+    }
+    public void actionPerformed(ActionEvent evt) {
+        try {
+               if(choixModeConversion.isSelectionEmpty()){
+                   initVide();
+                   return;
+               }
+               else{
+                   switch(choixModeConversion.getSelectedIndex()){
+                       case 0 :
+                            if(evt.getSource().equals(typeSource)){
+                                primaryKeyDisponibles = vue.getListeChamps(Relation.class, typeSource.getSelection());
+                                primaryKey.removeActionListener(this);
+                                primaryKey.setModele(primaryKeyDisponibles.toArray(new String[0]));
+                                primaryKey.addActionListener(this);
+                                return;
+                            }
+                            if(evt.getSource().equals(primaryKey)){
+                                return;
+                            }
+                            if(evt.getSource().equals(lancerConversion)){
+                                if(!typeSource.pasdeSelection() && !primaryKey.pasdeSelection()){
+                                    ChaineUtil.conversion("Relation",nomSchema.getText(),typeSource.getSelection(),
+                                            primaryKey.getSelection(),null,vue);
+                                    fermerFenetre();
+                                }
+                                return;
+                            }
+                       break;
+                       case 1 :
+                            if(evt.getSource().equals(lancerConversion)){
+                                ChaineUtil.conversion("typeUnite",nomSchema.getText(),null,null,new String[0],vue);
+                                fermerFenetre();
+                                return;
+                            }
+                       break;
+                       case 2 :
+                            if(evt.getSource().equals(typeSource)){
+                                if(!typeSource.pasdeSelection()){
+                                    primaryKeyDisponibles = vue.getListeChamps(Unite.class, typeSource.getSelection());
+                                    primaryKey.removeActionListener(this);
+                                    primaryKey.setModele(primaryKeyDisponibles.toArray(new String[0]));
+                                    primaryKey.addActionListener(this);
+                                    otherKeyDisponibles = vue.getListeChamps(Unite.class, typeSource.getSelection());
+                                    addOtherKey.removeActionListener(this);
+                                    addOtherKey.setModele(otherKeyDisponibles.toArray(new String[0]));
+                                    addOtherKey.addActionListener(this);
+                                    otherKeyAjoutees = new ArrayList();
+                                    removeOtherKey.removeActionListener(this);
+                                    removeOtherKey.setModele(otherKeyAjoutees.toArray(new String[0]));
+                                    removeOtherKey.addActionListener(this);
+                                }
+                                return;
+                            }
+                            if(evt.getSource().equals(primaryKey)){
+                                if(!typeSource.pasdeSelection() && !primaryKey.pasdeSelection()){
+                                    otherKeyDisponibles = vue.getListeChamps(Unite.class, typeSource.getSelection());
+                                    otherKeyDisponibles.remove(primaryKey.getSelection());
+                                    for(String key : otherKeyAjoutees){
+                                        otherKeyDisponibles.remove(key);
+                                    }
+                                    otherKeyAjoutees.remove(primaryKey.getSelection());
+                                    addOtherKey.removeActionListener(this);
+                                    removeOtherKey.removeActionListener(this);
+                                    addOtherKey.setModele(otherKeyDisponibles.toArray(new String[0]));
+                                    removeOtherKey.setModele(otherKeyAjoutees.toArray(new String[0]));
+                                    addOtherKey.addActionListener(this);
+                                    removeOtherKey.addActionListener(this);
+                                }
+                                return;
+                            }
+                            if(evt.getSource().equals(lancerConversion)){
+                                if(!typeSource.pasdeSelection() && !primaryKey.pasdeSelection()){
+                                    ChaineUtil.conversion("attributUnite",nomSchema.getText(),typeSource.getSelection(),
+                                            primaryKey.getSelection(),otherKeyAjoutees.toArray(new String[0]),vue);
+                                    fermerFenetre();
+                                }
+                                return;
+                            } 
+                            if(evt.getSource().equals(addOtherKey)){
+                                if(!typeSource.pasdeSelection() && !addOtherKey.pasdeSelection()){
+                                    otherKeyDisponibles.remove(addOtherKey.getSelection());
+                                    otherKeyAjoutees.add(addOtherKey.getSelection());
+                                    addOtherKey.removeActionListener(this);
+                                    removeOtherKey.removeActionListener(this);
+                                    addOtherKey.setModele(otherKeyDisponibles.toArray(new String[0]));
+                                    removeOtherKey.setModele(otherKeyAjoutees.toArray(new String[0]));
+                                    addOtherKey.addActionListener(this);
+                                    removeOtherKey.addActionListener(this);
+                                }
+                                return;
+                            } 
+                            if(evt.getSource().equals(removeOtherKey)){
+                                if(!typeSource.pasdeSelection() && !removeOtherKey.pasdeSelection()){
+                                    otherKeyDisponibles.add(removeOtherKey.getSelection());
+                                    otherKeyAjoutees.remove(removeOtherKey.getSelection());
+                                    addOtherKey.removeActionListener(this);
+                                    removeOtherKey.removeActionListener(this);
+                                    addOtherKey.setModele(otherKeyDisponibles.toArray(new String[0]));
+                                    removeOtherKey.setModele(otherKeyAjoutees.toArray(new String[0]));
+                                    addOtherKey.addActionListener(this);
+                                    removeOtherKey.addActionListener(this);
+                                }
+                                return;
+                            } 
+                       break;
+                       default :
+                           initVide();
+                       break;
+                           
+                    }
+                   
+               }
+          throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+    }
+      
+    private void fermerFenetre() {
+      vue.removeEventListener(this);
+      dispose();
+    }
+     public void traiterEvent(Message evt) { // très grossier : à améliorer
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre chaines présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        fermerFenetre();
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        fermerFenetre();
+        return;
+      case MODIF_ELEMENT:
+//        ElementEvent evtE = (ElementEvent) evt;
+//        if (evtE.getModif() != TypeModifElement.BORNES_UNITE) fermerFenetre();
+        fermerFenetre();
+        return;
+      case CORPUS_SAVED:
+          fermerFenetre();
+          return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+     public void listAction(int Index){
+         if(!choixModeConversion.isSelectionEmpty()){
+             PanneauCommande.removeAll();
+             PanneauCommande.add(Box.createVerticalStrut(20));
+             PanneauCommande.add(new JLabel("Saisisez un nom pour votre nouveau type de schéma :"));
+             nomSchema.setMaximumSize(new Dimension(500,50));
+             PanneauCommande.add(Box.createVerticalStrut(20));
+             PanneauCommande.add(nomSchema);
+             switch(Index){
+                 case 0 :
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(new JLabel("Sélectionner un type de relation :"));
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(typeSource);
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(new JLabel("Sélectionner une propriété caractérisant chaque chaine :"));
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(primaryKey);
+                     this.typesSourceDisponibles = vue.getTypesRelationsAVoir();
+                     typeSource.removeActionListener(this);
+                     typeSource.setModele(typesSourceDisponibles);
+                     typeSource.addActionListener(this);
+                     this.primaryKeyDisponibles = new ArrayList();
+                     primaryKey.removeActionListener(this);
+                     this.primaryKey.setModele(this.primaryKeyDisponibles.toArray(new String[0]));
+                     primaryKey.addActionListener(this);
+                     break;
+                 case 1:
+                     break; 
+                 case 2 :
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(new JLabel("Sélectionner un type d'unité :"));
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(typeSource);
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(new JLabel("Sélectionner une propriété caractérisant chaque chaine :"));
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(primaryKey);
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(new JLabel("Sélectionner une propriété des unités à ajouter aux schémas :"));
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(addOtherKey);
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(new JLabel("Sélectionner une propriété des unités à enlever aux schemas :"));
+                     PanneauCommande.add(Box.createVerticalStrut(20));
+                     PanneauCommande.add(removeOtherKey);
+                     this.typesSourceDisponibles = vue.getTypesUnitesAVoir();
+                     typeSource.removeActionListener(this);
+                     typeSource.setModele(typesSourceDisponibles);
+                     typeSource.addActionListener(this);
+                     primaryKey.removeActionListener(this);
+                     this.primaryKeyDisponibles = new ArrayList();
+                     this.primaryKey.setModele(this.primaryKeyDisponibles.toArray(new String[0]));
+                     primaryKey.addActionListener(this);
+                     this.otherKeyDisponibles = new ArrayList();
+                     addOtherKey.removeActionListener(this);
+                     this.addOtherKey.setModele(this.otherKeyDisponibles.toArray(new String[0]));
+                     addOtherKey.addActionListener(this);
+                     this.otherKeyAjoutees = new ArrayList();
+                     removeOtherKey.removeActionListener(this);
+                     this.removeOtherKey.setModele(this.otherKeyAjoutees.toArray(new String[0]));
+                     removeOtherKey.addActionListener(this);
+                     break;
+                 default :
+                     PanneauCommande.removeAll();
+                     break;
+             }
+             revalidate();
+             repaint();
+         }
+     }
+
+    
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuConversion.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ExportCSV.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ExportCSV.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ExportCSV.java	(revision 481)
@@ -0,0 +1,223 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.chaines;
+
+import com.itextpdf.awt.DefaultFontMapper;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.pdf.PdfContentByte;
+import com.itextpdf.text.pdf.PdfTemplate;
+import com.itextpdf.text.pdf.PdfWriter;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.geom.Rectangle2D;
+import java.io.File;
+import java.io.FileOutputStream;
+import javax.swing.*;
+import org.jfree.chart.ChartPanel;
+import visuAnalec.*;
+import visuAnalec.fichiers.FichiersTexte;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.GAction;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Marc
+ */
+public class ExportCSV extends JFrame implements Vue.VueListener, ActionListener{
+    private Vue vue;
+    private PanneauEditeur panneauEditeur;
+    private JCheckBox activeChamp1;
+    private JCheckBox activeChamp2;
+    private JCheckBox activeChamp3;
+    private JCheckBox activeChamp4;
+    private JCheckBox activeChamp5;
+    private JCheckBox activeChampChaine;
+    private JCheckBox activeChampUnite;
+    private JCheckBox activeChampParagraphe;
+    private JButton exporter;
+    
+    
+    public ExportCSV(Container fenetre, Vue vue, PanneauEditeur pEditeur, VisuCoref visucoref){
+        super("Analyse générale du texte");
+        Point pos = new Point(fenetre.getX()+20, fenetre.getY()+20);
+        Dimension dim = new Dimension(300, 500);
+        setLocation(pos);
+        setSize(dim);
+        this.panneauEditeur = pEditeur;
+        final VisuCoref visucorefs = visucoref;
+        final VisuChaines visuchaine = null;
+        this.vue = vue;
+        vue.addEventListener(this);
+        Box commandes = Box.createVerticalBox();
+        commandes.add(this.activeChampChaine = new JCheckBox("Afficher le Champ de la Chaine"));
+        commandes.add(Box.createVerticalStrut(20));
+        commandes.add(this.activeChampUnite = new JCheckBox("Afficher le Champ ds Unités"));
+        commandes.add(Box.createVerticalStrut(20));
+        commandes.add(this.activeChampParagraphe = new JCheckBox("Afficher le numéro des paragraphes"));
+        commandes.add(Box.createVerticalStrut(20));
+        commandes.add(this.exporter=new JButton("Exporter"));
+        exporter.setAction(new GAction("exporter") {
+            public void executer() {
+              exporterCSV(visucorefs.donneesCSV(new boolean[]{activeChampUnite.isSelected(),activeChampChaine.isSelected(),
+              activeChampParagraphe.isSelected()}));
+              fermerFenetre();
+            }
+          });
+        exporter.setSize(100, 40);
+        exporter.setVisible(true);
+        getContentPane().add(commandes);
+        setVisible(true);
+        // Fermeture de la fenêtre
+        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+        addWindowListener(new WindowAdapter() {
+        @Override
+        public void windowClosing(WindowEvent evt) {
+         fermerFenetre();
+        }
+        });
+    }
+    
+    public ExportCSV(Container fenetre, Vue vue, PanneauEditeur pEditeur, VisuChaines visuchaine){
+        super("Analyse générale du texte");
+        Point pos = new Point(fenetre.getX()+20, fenetre.getY()+20);
+        Dimension dim = new Dimension(300, 500);
+        setLocation(pos);
+        setSize(dim);
+        this.panneauEditeur = pEditeur;
+        final VisuCoref visucoref = null;
+        final VisuChaines visuchaines = visuchaine;
+        this.vue = vue;
+        vue.addEventListener(this);
+        Box commandes = Box.createVerticalBox();
+        commandes.add(this.activeChamp1 = new JCheckBox("Afficher le Champ1"));
+        commandes.add(Box.createVerticalStrut(20));
+        commandes.add(this.activeChamp2 = new JCheckBox("Afficher le Champ2"));
+        commandes.add(Box.createVerticalStrut(20));
+        commandes.add(this.activeChamp3 = new JCheckBox("Afficher le Champ3"));
+        commandes.add(Box.createVerticalStrut(20));
+        commandes.add(this.activeChamp4 = new JCheckBox("Afficher le Champ4"));
+        commandes.add(Box.createVerticalStrut(20));
+        commandes.add(this.activeChamp5 = new JCheckBox("Afficher le Champ5"));
+        commandes.add(Box.createVerticalStrut(20));
+        commandes.add(this.exporter=new JButton("Exporter"));
+        exporter.setAction(new GAction("exporter") {
+            public void executer() {
+              exporterCSV(visuchaines.donneesCSV(new boolean[]{activeChamp1.isSelected(),activeChamp2.isSelected(),
+              activeChamp3.isSelected(),activeChamp4.isSelected(),activeChamp5.isSelected()}));
+              fermerFenetre();
+            }
+          });
+        exporter.setSize(100, 40);
+        exporter.setVisible(true);
+        getContentPane().add(commandes);
+        setVisible(true);
+        // Fermeture de la fenêtre
+        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+        addWindowListener(new WindowAdapter() {
+        @Override
+        public void windowClosing(WindowEvent evt) {
+         fermerFenetre();
+        }
+        });
+    }    
+    
+       private void fermerFenetre() {
+        vue.removeEventListener(this);
+        dispose();
+        }
+    
+    public void traiterEvent(Message evt) { // très grossier : à améliorer
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre chaines présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        fermerFenetre();
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        fermerFenetre();
+        return;
+      case MODIF_ELEMENT:
+//        ElementEvent evtE = (ElementEvent) evt;
+//        if (evtE.getModif() != TypeModifElement.BORNES_UNITE) fermerFenetre();
+        fermerFenetre();
+        return;
+      case CORPUS_SAVED:
+          fermerFenetre();
+          return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+    
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  
+  public static void exporterCSV(Object[][] donnees){
+      JOptionPane jop = new JOptionPane();
+      String delimiteur = jop.showInputDialog(null, "Veuillez saisir un délimiteur d'un caractère maximum"
+              , "Saisie délimiteur pour export en UTF-8", JOptionPane.QUESTION_MESSAGE);
+      if(delimiteur!=null && !delimiteur.isEmpty() && delimiteur.length()==1){
+          String texte = "";
+          for(Object[] ligne : donnees){
+              for(Object cellule : ligne){
+                  texte = texte + (cellule==null ? "" : cellule.toString().replaceAll(delimiteur, "")) + delimiteur;
+              }
+              texte = texte + System.getProperty("line.separator");
+          }
+          FichiersTexte.exporterCSV(texte);
+      }
+  }
+  /*ajouté probablement dans la mauvaise classe, la package fichier semble plus adapté pour recevoir les classes*/
+  /*ici on laisse l'utilisateur choisir un répertoire où enregistrer*/
+  public static void writeChartToPDF(ChartPanel chart,int width,int height) {
+    String fileName="";
+    
+    File fichierGraphique;
+    if ((fichierGraphique = Fichiers.choisirFichier(Fichiers.Commande.ENREGISTRER,
+            "Nom du fichier ?", Fichiers.TypeFichier.PDF)) == null) return;
+    
+    fileName = fichierGraphique.getAbsolutePath();
+            
+    
+    PdfWriter writer = null;
+ 
+    Document document = new Document();
+ 
+    try {
+        writer = PdfWriter.getInstance(document,  new FileOutputStream(
+                fileName));
+        document.open();
+        PdfContentByte contentByte = writer.getDirectContent();
+        PdfTemplate template = contentByte.createTemplate(width, height);
+        Graphics2D graphics2d = template.createGraphics(width, height,
+                new DefaultFontMapper());
+        Rectangle2D rectangle2d = new Rectangle2D.Double(0, 0, width,
+                height);
+ 
+        chart.getChart().draw(graphics2d, rectangle2d);
+         
+        graphics2d.dispose();
+        contentByte.addTemplate(template, 0, 0);
+ 
+    } catch (Exception e) {
+        e.printStackTrace();
+    }
+    document.close();
+}
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ExportCSV.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/Courbe.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/Courbe.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/Courbe.java	(revision 481)
@@ -0,0 +1,146 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.chaines;
+import java.awt.*;
+import javax.swing.JPopupMenu;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.ChartPanel;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.data.xy.XYDataset;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+import visuAnalec.util.GMessages.GAction;
+/**
+ *
+ * @author Marc
+ */
+//requiert des donnees positives
+public class Courbe{
+    
+
+
+
+public static ChartPanel courbeFactory(){
+    
+        
+        final XYSeriesCollection dataset = new XYSeriesCollection();
+        
+        final JFreeChart chart = ChartFactory.createXYLineChart(
+            "Courbe vide",      // chart title
+            "X",                      // x axis label
+            "Y",                      // y axis label
+            dataset,                  // data
+            PlotOrientation.VERTICAL,
+            true,                     // include legend
+            true,                     // tooltips
+            false                     // urls
+        );
+
+
+        chart.setBackgroundPaint(Color.white);
+
+        final XYPlot plot = chart.getXYPlot();
+        plot.setBackgroundPaint(Color.lightGray);
+
+        plot.setDomainGridlinePaint(Color.white);
+        plot.setRangeGridlinePaint(Color.white);
+        
+        final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
+        renderer.setSeriesLinesVisible(0, false);
+        renderer.setSeriesShapesVisible(1, false);
+        plot.setRenderer(renderer);
+
+
+        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
+        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
+        
+        final ChartPanel chartPanel = new ChartPanel(chart);
+        chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
+
+        
+        JPopupMenu save = (JPopupMenu) chartPanel.getPopupMenu().getSubElements()[2].getSubElements()[0];
+        save.add(new GAction("Exporter en PDF") {
+        @Override
+        public void executer() {
+        ExportCSV.writeChartToPDF(chartPanel,500,400);
+        }
+      });
+      save.add(new GAction("Exporter en CSV") {
+        @Override
+        public void executer() {
+        XYDataset dataSet = chartPanel.getChart().getXYPlot().getDataset();
+        if(dataSet.getSeriesCount()>0 && dataSet.getItemCount(0)>0){
+        Object[][] Donnees = new Object[dataSet.getItemCount(0)][dataSet.getSeriesCount()*2];
+        for(int i = 0 ; i < dataSet.getItemCount(0) ; i++){
+            for(int j = 0 ; j < dataSet.getSeriesCount() ; j++){
+                Donnees[i][2*j]=dataSet.getXValue(j, i);
+                Donnees[i][2*j+1]=dataSet.getYValue(j, i);
+            }
+        }
+        ExportCSV.exporterCSV(Donnees);
+        }
+        }
+      });
+    return chartPanel;
+}
+
+
+
+
+public static void updatePanel(ChartPanel window,String titre,Integer[] xData,Integer[] yData,Color couleur, int maxheight, 
+           String abscisse,String ordonnee){
+    
+        final XYSeries series1 = new XYSeries("Point");
+        final XYSeriesCollection dataset = new XYSeriesCollection();
+        for(int i = 0 ; i < xData.length;i++){
+            series1.add(xData[i],yData[i]);
+        }
+        dataset.addSeries(series1);
+        
+        final JFreeChart chart = ChartFactory.createXYLineChart(
+            titre,      // chart title
+            abscisse,                      // x axis label
+            ordonnee,                      // y axis label
+            dataset,                  // data
+            PlotOrientation.VERTICAL,
+            true,                     // include legend
+            true,                     // tooltips
+            false                     // urls
+        );
+
+
+        chart.setBackgroundPaint(Color.white);
+
+        final XYPlot plot = chart.getXYPlot();
+        plot.setBackgroundPaint(Color.lightGray);
+
+        plot.setDomainGridlinePaint(Color.white);
+        plot.setRangeGridlinePaint(Color.white);
+        
+        final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
+        plot.setRenderer(renderer);
+
+
+        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
+        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
+        
+        window.setChart(chart);
+        window.setPreferredSize(new java.awt.Dimension(500, 270));
+
+    
+}
+ 
+
+ 
+   
+ 
+    
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/Courbe.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/Histogramme.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/Histogramme.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/Histogramme.java	(revision 481)
@@ -0,0 +1,115 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.chaines;
+import java.awt.*;
+import javax.swing.JPopupMenu;
+import org.jfree.chart.*;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.data.statistics.*;
+import org.jfree.data.xy.XYDataset;
+import visuAnalec.util.GMessages.GAction;
+
+import visuAnalec.vue.Vue;
+/**
+ *
+ * @author Marc
+ * inspiré par la page 
+ * http://sebastien-estienne.developpez.com/tutoriels/java/exercices-graphisme-java2d/?page=exo1#LI-3
+ */
+public class Histogramme{
+    
+
+ 
+
+
+
+public static ChartPanel histogrammeFactory(){
+    double[] value = new double[1];
+    value[0]=1.0f;
+    int number = 1;
+    HistogramDataset dataset = new HistogramDataset();
+    dataset.setType(HistogramType.RELATIVE_FREQUENCY);
+    dataset.addSeries("Histogram",value,number);
+    String plotTitle = "Histogram"; 
+    String xaxis = "";
+    String yaxis = ""; 
+    PlotOrientation orientation = PlotOrientation.VERTICAL; 
+    boolean show = false; 
+    boolean toolTips = false;
+    boolean urls = false; 
+    JFreeChart chart = ChartFactory.createHistogram( plotTitle, xaxis, yaxis, 
+    dataset, orientation, show, toolTips, urls);
+    final ChartPanel chartPanel = new ChartPanel(chart);
+    chartPanel.setFillZoomRectangle(true);
+    chartPanel.setMouseWheelEnabled(true);
+    chartPanel.setPreferredSize(new Dimension(500,270));
+    chartPanel.setVisible(true);
+    JPopupMenu save = (JPopupMenu) chartPanel.getPopupMenu().getSubElements()[2].getSubElements()[0];
+        save.add(new GAction("Exporter en PDF") {
+        @Override
+        public void executer() {
+        ExportCSV.writeChartToPDF(chartPanel,500,400);
+        }
+      });
+      save.add(new GAction("Exporter en CSV") {
+        @Override
+        public void executer() {
+        XYDataset dataSet = chartPanel.getChart().getXYPlot().getDataset();
+        if(dataSet.getSeriesCount()>0 && dataSet.getItemCount(0)>0){
+        Object[][] Donnees = new Object[dataSet.getItemCount(0)][dataSet.getSeriesCount()*2];
+        for(int i = 0 ; i < dataSet.getItemCount(0) ; i++){
+            for(int j = 0 ; j < dataSet.getSeriesCount() ; j++){
+                Donnees[i][2*j]=dataSet.getXValue(j, i);
+                Donnees[i][2*j+1]=dataSet.getYValue(j, i);
+            }
+        }
+        ExportCSV.exporterCSV(Donnees);
+        }
+        }
+      });
+    return chartPanel;
+}
+
+
+
+public static void updatePanel(ChartPanel window,String titre,ModeleChaines data,int nb_classes,Color couleur, int maxheight, 
+           String abscisse,String ordonnee,Vue vue){
+    
+        double[] value = new double[data.getUnites().length];
+    for (int i=1; i < data.getUnites().length; i++) {
+            value[i] = (double) data.getUnites()[i].getDeb();
+    }
+    HistogramDataset dataset = new HistogramDataset();
+    dataset.setType(HistogramType.RELATIVE_FREQUENCY);
+    dataset.addSeries("Histogram",value,nb_classes,0.0f,(double) vue.getCorpus().getTexte().length());
+    String plotTitle = "Distribution spatiale des unités"; 
+    String xaxis = abscisse;
+    String yaxis = ordonnee; 
+    PlotOrientation orientation = PlotOrientation.VERTICAL; 
+    boolean show = false; 
+    boolean toolTips = false;
+    boolean urls = false; 
+    JFreeChart chart = ChartFactory.createHistogram( plotTitle, xaxis, yaxis, 
+    dataset, orientation, show, toolTips, urls);
+    window.setChart(chart);
+    window.revalidate();
+    window.repaint();
+    window.setFillZoomRectangle(true);
+    window.setMouseWheelEnabled(true);
+    window.setPreferredSize(new Dimension(500,270));
+    window.setVisible(true);
+    
+}
+ 
+
+
+   
+ 
+
+} 
+
+

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/Histogramme.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ModeleChaines.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ModeleChaines.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ModeleChaines.java	(revision 481)
@@ -0,0 +1,741 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.chaines;
+
+import java.awt.*;
+import java.util.*;
+import java.util.ArrayList;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class ModeleChaines {
+  static class Chainon {
+    Unite unite;
+    String texte;
+    Schema chaine = null;
+    int nbEltsChaine = 0;
+    String idChaine = "";
+    int noChaine = 0;
+    Chainon(Unite unite, String texte) {
+      this.unite = unite;
+      this.texte = texte;
+    }
+  }
+  private Vue vue;
+  private GChaines panneauGraphique;
+  private Unite[] listeUnites;
+  private boolean peutafficher = true;
+  private HashMap<Unite, Schema> chainesUnitesNonFiltrees =
+          new HashMap<Unite, Schema>();
+  private int[] seuilsValsNbElements = new int[0];
+  private HashMap<Unite, Chainon> chainonsUnites = new HashMap<Unite, Chainon>();
+  private HashMap<Schema, ArrayList<Unite>> unitesChaines =
+          new HashMap<Schema, ArrayList<Unite>>();
+  private HashMap<String, HashSet<String>> valsMasqueesChamp =
+          new HashMap<String, HashSet<String>>();
+  private HashSet<String> valNulleMasqueeChamp = new HashSet<String>();
+  private boolean[] valsMasqueesNbElements = new boolean[0];
+  
+  public ModeleChaines(Vue vue, GChaines panneauGraphique) {
+    this.vue = vue;
+    this.panneauGraphique = panneauGraphique;
+  }
+  Schema getChaine(Unite unit) {
+    return chainonsUnites.get(unit).chaine;
+  }
+  public HashMap<Unite, Chainon> getChainonUnites(){
+      return chainonsUnites;
+  }
+  Unite[] getUnites() {
+    return listeUnites;
+  }
+  Unite[] getUnitesChaine(Schema chaine) {
+    ArrayList<Unite> units = unitesChaines.get(chaine);
+    return units.toArray(new Unite[0]);
+  }
+  boolean isMasqueeValChamp(String champ, String val) {
+    return valsMasqueesChamp.containsKey(champ)
+            &&valsMasqueesChamp.get(champ).contains(val);
+  }
+  boolean isMasqueeValNulleChamp(String champ) {
+    return valNulleMasqueeChamp.contains(champ);
+  }
+  boolean isMasqueeValNbElements(int i) {
+    return i >= valsMasqueesNbElements.length ? false : valsMasqueesNbElements[i];
+  }
+  public HashMap<String, HashSet<String>> getValsMasqueesChamp(){
+      return valsMasqueesChamp;
+  }
+  public HashSet<String> getValsNulleMasqueesChamp(){
+      return valNulleMasqueeChamp;
+  }  
+  public HashMap<Unite, Schema> getchainesUnitesNonFiltrees(){
+      return chainesUnitesNonFiltrees;
+  }
+  public boolean[] getValsNbMasqueesChamp(){
+      return valsMasqueesNbElements;
+  }    
+  public void setValsMasqueesChamp(HashMap<String, HashSet<String>> valsMasqueesChamp){
+      this.valsMasqueesChamp = valsMasqueesChamp;
+  }
+  public void setValsNulleMasqueesChamp(HashSet<String> valNulleMasqueeChamp){
+      this.valNulleMasqueeChamp = valNulleMasqueeChamp;
+  }  
+  public void setValsNbMasqueesChamp(boolean[] valsMasqueesNbElements){
+      this.valsMasqueesNbElements=valsMasqueesNbElements;
+  }      
+  //retourne le nombre de valeurs masquees pour le champ
+  public int nbvaleursmasquees(String champ){
+      int resultat=0;
+      if(champ==null){//si le champ affiché est le nombre de chainons
+          for(boolean val : valsMasqueesNbElements){
+              if(val){
+                  resultat = resultat + 1;
+              }
+          }
+      }
+      else{
+          resultat = valsMasqueesChamp.get(champ).size();
+      }
+      return resultat;
+  }
+  void demasquerToutesValsChamp(String champ) {
+    valsMasqueesChamp.get(champ).clear();
+    valNulleMasqueeChamp.remove(champ);
+  }
+  void demasquerToutesValsNbElts(String champ) {
+    for (int i = 0; i<valsMasqueesNbElements.length; i++) {
+      valsMasqueesNbElements[i] = false;  
+    }
+  }
+  void setGChaine(GChaines panneaugraphique){
+      this.panneauGraphique = panneaugraphique;
+  }
+  void setUnites(Unite[] donnees){
+      this.listeUnites = donnees;
+  }  
+  void permettreaffichage(boolean autorisation){
+      this.peutafficher = autorisation;
+  }
+  boolean peutetreafficher(){
+      return this.peutafficher;
+  }
+ void masquerAutresValsChamp(String typeunite, String champ, String val) {
+    for(String v: vue.getValeursChamp(Unite.class, typeunite, champ)) 
+      valsMasqueesChamp.get(champ).add(v);
+     valsMasqueesChamp.get(champ).remove(val);
+     valNulleMasqueeChamp.add(champ);
+  }
+ void masquerValChamp(boolean yes, String champ, String val) {
+    if (yes) valsMasqueesChamp.get(champ).add(val);
+    else valsMasqueesChamp.get(champ).remove(val);
+  }
+ void masquerValsNonNullesChamp(String typeunite, String champ) {
+    for(String v: vue.getValeursChamp(Unite.class, typeunite, champ)) 
+      valsMasqueesChamp.get(champ).add(v);
+     valNulleMasqueeChamp.remove(champ);
+  }
+  void masquerValNulleChamp(boolean yes, String champ) {
+    if (yes) valNulleMasqueeChamp.add(champ);
+    else valNulleMasqueeChamp.remove(champ);
+  }
+  void masquerAutresValsNbElts(String champ, int i0) {
+    for (int i = 0; i<valsMasqueesNbElements.length; i++) {
+      valsMasqueesNbElements[i] = i!=i0;  
+    }
+  }
+  void masquerValNbElements(boolean yes, int i) {
+    valsMasqueesNbElements[i] = yes;
+  }
+  void init(String typeChaines, String typeUnites, int[] seuils)
+          throws UnsupportedOperationException {
+    seuilsValsNbElements = seuils;
+    String[] champs = vue.getNomsChamps(Unite.class, typeUnites);
+    valsMasqueesChamp.clear();
+    for (String champ : champs)
+      valsMasqueesChamp.put(champ, new HashSet<String>());
+    valNulleMasqueeChamp.clear();
+    valsMasqueesNbElements = new boolean[seuils.length+3];
+    calculerChainesUnitesNonFiltrees(typeChaines, typeUnites);
+    calculerDonnees(typeChaines, typeUnites);
+  }
+  //struture qui n'est pas filtrées mais qui associe à une unité qui correspond au bon type d'unités
+  //la chaine qui la contient et qui est elle aussi du bon type de Schéma
+  private void calculerChainesUnitesNonFiltrees(String typeChaines,
+          String typeUnites) throws UnsupportedOperationException {
+    chainesUnitesNonFiltrees.clear();
+    for (Schema chaine : vue.getSchemasAVoir(typeChaines))
+      for (Element elt : chaine.getContenu()) {
+        if (elt.getClass()==Unite.class&&elt.getType().equals(typeUnites)) {
+          if (chainesUnitesNonFiltrees.containsKey(elt)) {
+            throw new UnsupportedOperationException("L'unité "+vue.getIdElement(elt)
+                    +" appartient à deux chaînes : "+vue.getIdElement(chaine)+" et "
+                    +vue.getIdElement(chainesUnitesNonFiltrees.get((Unite) elt)));
+          } else
+            chainesUnitesNonFiltrees.put((Unite) elt, chaine);
+        }
+      }
+  }
+  void modifMasqueVals(String typeChaines, String typeUnites) {
+    calculerDonnees(typeChaines, typeUnites);
+  }
+  void modifMasqueValsChampChaine(String typeChaines, String typeUnites,ArrayList noparagraphecachees,String champ
+  ,String Valeur) {
+    calculerDonnees(typeChaines, typeUnites, noparagraphecachees, champ
+  , Valeur);
+  }  
+  private void filtrerListeUnites(String typeUnites, String typeChaines) {
+    Unite[] unites = vue.getUnitesAVoir(typeUnites);
+    Schema[] chaines = vue.getSchemasAVoir(typeChaines);
+    unitesChaines.clear();
+    for (Schema chaine : chaines) unitesChaines.put(chaine, new ArrayList<Unite>());
+    ArrayList<Integer> indFiltrees = new ArrayList<Integer>();
+    String[] champs = vue.getNomsChamps(Unite.class, typeUnites);
+    boolean agarder;
+    for (int i = 0; i<unites.length; i++) {
+      agarder = true;
+      for (String champ : champs) {//pour tous les champs 
+        String val = vue.getValeurChamp(unites[i], champ);//je recupere la valeur du champ
+        if (val.isEmpty()) {
+          if (valNulleMasqueeChamp.contains(champ)) {
+            agarder = false;
+            break;
+          }
+        } else {
+          if (valsMasqueesChamp.get(champ).contains(val)) {
+            agarder = false;
+            break;
+          }
+        }
+      }
+      if (agarder) {
+        indFiltrees.add(i);
+        if (chainesUnitesNonFiltrees.containsKey(unites[i])) {
+          Schema chaine = chainesUnitesNonFiltrees.get(unites[i]);
+          unitesChaines.get(chaine).add(unites[i]);
+        }
+      }
+    }
+    ArrayList<Integer> indIndFiltrees = new ArrayList<Integer>();
+    for(int k=0; k<indFiltrees.size(); k++) {
+      Unite unit = unites[indFiltrees.get(k)];
+      if(chainesUnitesNonFiltrees.containsKey(unit)) {
+        if(!isMasqueeValNbElements(calculerValNbElements(
+                unitesChaines.get(chainesUnitesNonFiltrees.get(unit)).size())))
+          indIndFiltrees.add(k);
+      } else {
+        if(!isMasqueeValNbElements(0)) indIndFiltrees.add(k);
+      }      
+    }
+    listeUnites = new Unite[indIndFiltrees.size()];
+    for (int k = 0; k<listeUnites.length; k++) {
+      listeUnites[k] = unites[indFiltrees.get(indIndFiltrees.get(k))];
+    }
+        for (Schema chaine : chaines) {
+          int nb = unitesChaines.get(chaine).size();
+          if(nb==0||isMasqueeValNbElements(calculerValNbElements(nb)))
+            unitesChaines.remove(chaine);
+        }
+  }
+  private void calculerDonnees(String typeChaines, String typeUnites) {
+     filtrerListeUnites(typeUnites, typeChaines);
+    Chainon[] chainons = new Chainon[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Unite unit = listeUnites[i];
+      chainons[i] = new Chainon(unit, vue.getTexteUnite(unit));
+      if(chainesUnitesNonFiltrees.containsKey(unit)) {
+        Schema chaine = chainesUnitesNonFiltrees.get(unit);
+        chainons[i].chaine = chaine;
+        chainons[i].nbEltsChaine = unitesChaines.get(chaine).size();
+        chainons[i].idChaine = vue.getIdElement(chaine);
+      } 
+      chainonsUnites.put(listeUnites[i], chainons[i]);
+    }
+    HashMap<Schema, Integer> noChaine = new HashMap<Schema, Integer>();
+    int no = 0;
+    for (Schema chaine : vue.getSchemasAVoir(typeChaines)) {
+      if(unitesChaines.containsKey(chaine)) {
+        int nbElts = unitesChaines.get(chaine).size(); 
+       noChaine.put(chaine, nbElts>1 ? ++no : 0);
+    }
+    }
+    for (Unite unit : listeUnites) {
+      Chainon chainon = chainonsUnites.get(unit);
+      if (chainon.chaine!=null) chainon.noChaine = noChaine.get(chainon.chaine);
+    }
+    int[] noPar = vue.getCorpus().calculerNoParagraphe(listeUnites);
+    if(peutafficher){
+        panneauGraphique.setDonnees(chainons, noPar);
+    }
+  }
+  void initVide() {
+    listeUnites = new Unite[0];
+    chainesUnitesNonFiltrees.clear();
+    seuilsValsNbElements = new int[0];
+    chainonsUnites.clear();
+    unitesChaines.clear();
+    if(peutafficher){
+        panneauGraphique.setDonnees(new Chainon[0], new int[0]);
+        panneauGraphique.setCouleurs(new Color[0]);
+        panneauGraphique.setTaille(new int[0]);
+        panneauGraphique.setForme(new int[0]);
+        panneauGraphique.setSurTexte(new String[0]);
+        panneauGraphique.setSousTexte(new String[0]);
+    }
+    valNulleMasqueeChamp.clear();
+    valsMasqueesChamp.clear();
+    valsMasqueesNbElements = new boolean[0];
+  }
+  void setChampAffiche(String champ, HashMap<String, Color> couleursValeursChamp) {
+    if(peutafficher){  
+        panneauGraphique.setCouleurs(colorerChamp(champ, couleursValeursChamp));
+    }
+  }
+  void setChampAfficheTaille(String champ, HashMap<String, Integer> TaillesValeursChamp) {
+    if(peutafficher){  
+        panneauGraphique.setTaille(ReduireChamp(champ, TaillesValeursChamp));
+    }
+  }  
+  void setChampAfficheForme(String champ, HashMap<String, Integer> FormesValeursChamp) {
+    if(peutafficher){  
+        panneauGraphique.setForme(FormerChamp(champ, FormesValeursChamp));
+    }
+  }  
+  
+  void setChampAfficheSurTexte(String champ, HashMap<String, String> SurTexteValeursChamp) {
+    if(peutafficher){  
+        panneauGraphique.setSurTexte(SurTexteChamp(champ, SurTexteValeursChamp));
+    }
+  }  
+  void setChampAfficheSousTexte(String champ, HashMap<String, String> SousTexteValeursChamp) {
+    if(peutafficher){  
+        panneauGraphique.setSousTexte(SousTexteChamp(champ, SousTexteValeursChamp));
+    }
+  }  
+  
+  void setChampAfficheNbElts(Color[] couleurs) {
+    if(peutafficher){
+        panneauGraphique.setCouleurs(colorerNbElts(couleurs));
+    }
+  }
+  
+
+    
+  void setChampAfficheTailleNbElts(int[] taille) {
+    if(peutafficher){
+        panneauGraphique.setTaille(ReduireNbElts(taille));
+    }
+  }
+  
+  void setChampAfficheFormeNbElts(int[] forme) {
+    if(peutafficher){
+        panneauGraphique.setForme(FormeNbElts(forme));
+    }
+  }  
+  
+  void setChampAfficheSurTexteNbElts(String[] SurTexte) {
+    if(peutafficher){
+        panneauGraphique.setSurTexte(SurTexteNbElts(SurTexte));
+    }
+  }  
+  
+  void setChampAfficheSousTexteNbElts(String[] SousTexte) {
+    if(peutafficher){
+        panneauGraphique.setSousTexte(SousTexteNbElts(SousTexte));
+    }
+  }  
+  
+  private Color[] colorerNbElts(Color[] couleurs) {
+    Color[] couls = new Color[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      if (ch.chaine==null) couls[i] = couleurs[0];
+      else {
+        int nbElts = ch.nbEltsChaine;
+        couls[i] = couleurs[calculerValNbElements(nbElts)];
+      }
+    }
+    return couls;
+  }
+   private int[] FormeNbElts(int[] formes) {
+    int[] forme = new int[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      if (ch.chaine==null) forme[i] = formes[0];
+      else {
+        int nbElts = ch.nbEltsChaine;
+        forme[i] = formes[calculerValNbElements(nbElts)];
+      }
+    }
+    return forme;
+  }
+
+   private int[] ReduireNbElts(int[] tailles) {
+    int[] taille = new int[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      if (ch.chaine==null) taille[i] = tailles[0];
+      else {
+        int nbElts = ch.nbEltsChaine;
+        taille[i] = tailles[calculerValNbElements(nbElts)];
+      }
+    }
+    return taille;
+  }
+  private String[] SurTexteNbElts(String[] SurTextes) {
+    String[] SurTexte = new String[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      if (ch.chaine==null) SurTexte[i] = SurTextes[0];
+      else {
+        int nbElts = ch.nbEltsChaine;
+        SurTexte[i] = SurTextes[calculerValNbElements(nbElts)];
+      }
+    }
+    return SurTexte;
+  }
+    private String[] SousTexteNbElts(String[] SousTextes) {
+    String[] SousTexte = new String[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      if (ch.chaine==null) SousTexte[i] = SousTextes[0];
+      else {
+        int nbElts = ch.nbEltsChaine;
+        SousTexte[i] = SousTextes[calculerValNbElements(nbElts)];
+      }
+    }
+    return SousTexte;
+  }
+  
+   
+  private Color[] colorerChamp(String champ, HashMap<String, Color> couleursValeursChamp) {
+    Color[] couls = new Color[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      couls[i] = couleursValeursChamp.get(vue.getValeurChamp(ch.unite, champ));
+    }
+    return couls;
+  }
+  //même chose que colorer champ mais en influant la taille des chainons
+  private int[] ReduireChamp(String champ, HashMap<String, Integer> TaillesValeursChamp) {
+    int[] taille = new int[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      taille[i] = TaillesValeursChamp.get(vue.getValeurChamp(ch.unite, champ));
+    }
+    return taille;
+  }
+  //même chose que colorer champ mais en influant la forme des chainons
+  private int[] FormerChamp(String champ, HashMap<String, Integer> FormesValeursChamp) {
+    int[] forme = new int[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      forme[i] = FormesValeursChamp.get(vue.getValeurChamp(ch.unite, champ));
+    }
+    return forme;
+  }
+  //même chose que colorer champ mais en influant le texte au dessus des chainons
+  private String[] SurTexteChamp(String champ, HashMap<String, String> SurTexteValeursChamp) {
+    String[] SurTexte = new String[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      SurTexte[i] = SurTexteValeursChamp.get(vue.getValeurChamp(ch.unite, champ));
+    }
+    return SurTexte;
+  }
+  //même chose que colorer champ mais en influant le texte au dessous des chainons
+  private String[] SousTexteChamp(String champ, HashMap<String, String> SousTexteValeursChamp) {
+    String[] SousTexte = new String[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      SousTexte[i] = SousTexteValeursChamp.get(vue.getValeurChamp(ch.unite, champ));
+    }
+    return SousTexte;
+  }
+  
+  
+  public int calculerValNbElements(int nbElts) {
+    return nbElts==1 ? 1 : nbElts<=seuilsValsNbElements[0] ? 2 : 
+            nbElts<=seuilsValsNbElements[1] ? 3 : 4;
+  }
+  
+
+  
+  //retourne un tableau contenant les numéros de paragraphe qui contiennent des unités du modele
+  public Integer[] listenumeroparagraphe(){
+      int[] noparagraphe = (vue.getCorpus()).calculerNoParagraphe(listeUnites);
+      ArrayList<Integer> resultat = new ArrayList();
+      int former = -1;
+      for(int i = 0 ; i < noparagraphe.length;i++){
+          if(former!=noparagraphe[i]){
+              resultat.add(noparagraphe[i]);
+              former = noparagraphe[i];
+          }          
+      }
+      Integer[] resultatconversion = new Integer[resultat.size()];
+      return ( resultat.toArray(resultatconversion));
+  }
+
+  
+  //renvoie un Hashmap quidécrit la répartition des unités en position 
+  //au sein du texte
+  //@require : listesUnites est trié selon la position de debut de ses éléments
+  public ArrayList<int[]> dispositionunites(int nbclasses){
+    Unite[] unites = listeUnites; 
+    ArrayList<int[]> locationunites = new ArrayList<int[]>(nbclasses);
+    int longueurtexte = vue.getCorpus().getTexte().length();
+    int[] listeposition = ChaineUtil.discretisation(0,longueurtexte,nbclasses + 1);
+    int posprev = 0;
+    if(nbclasses > 0){
+        int posactuel = 1;
+        int compte = 0;
+        int k = 0;
+        while(k < unites.length || posactuel < nbclasses + 1){
+            if(k < unites.length  && unites[k].getDeb() < listeposition[posactuel] 
+                    && unites[k].getDeb() >= listeposition[posprev]){
+            //si l'unite est dans cette partie du texte alors on incrémente le compteur
+                compte = compte + 1;
+                k = k + 1;
+            }
+            else{
+                posprev = posactuel;//on actualise la position precedente
+                locationunites.add(new int[]{listeposition[posprev],compte});
+                compte = 0;
+                posactuel = posactuel + 1;
+            }
+        }
+    }    
+    return locationunites;
+  }
+
+   
+   
+
+   //renvoie un tableau contenant les fréquences de chaque valeur d'un champ de la chaine dans la liste d'unités
+   public HashMap<String, Float> calculerfrequencechaine(Unite[] donnees,String typeChaines
+           ,String Champcible,HashSet<String> valeurinterdite){
+       String[] valsdisponibles  = vue.getValeursChamp(Schema.class, typeChaines, Champcible);
+       HashMap<String, Float> tableaufrequence = new HashMap<String, Float>(valsdisponibles.length + 1); 
+       String valeurchamp;
+       //on initialise le tableau résultat
+       for(String valeur : valsdisponibles){
+           tableaufrequence.put(valeur, 0.0f);
+       }
+       tableaufrequence.put("", 0.0f);
+       int compteur  = 0;
+       //on compte le nombre d'occurences
+       for(Unite unit : donnees){
+           valeurchamp = chainesUnitesNonFiltrees.containsKey(unit) ? vue.getValeurChamp(chainesUnitesNonFiltrees.get(unit)
+                   , Champcible) : null;
+           if(valeurchamp!=null && !valeurinterdite.contains(valeurchamp)){
+                compteur = compteur + 1;
+                tableaufrequence.put(valeurchamp,tableaufrequence.get(valeurchamp) + 1); 
+           }
+       }
+       //on calcule les pourcentages
+       for(String valeur : valsdisponibles){
+           tableaufrequence.put(valeur,compteur==0 ? 0.0f : tableaufrequence.get(valeur) * 10000.0f /
+                   compteur / 100.0f);
+       }       
+           tableaufrequence.put("",compteur==0 ? 0.0f :  tableaufrequence.get("") * 10000.0f /
+                   compteur / 100.0f);       
+       
+       return tableaufrequence;
+   }
+   //renvoie un tableau contenant les fréquences de chaque longueur des chaines de la liste d'unités
+   public HashMap<String, Float> calculerfrequencenbelt(Unite[] donnees,String typeUnites
+           ,String[] valsdisponibles){
+       HashMap<String, Float> tableaufrequence = new HashMap<String, Float>(valsdisponibles.length); 
+       String valeurchamp;
+       //on initialise le tableau résultat
+       for(String valeur : valsdisponibles){
+           tableaufrequence.put(valeur, 0.0f);
+       }
+       int compte = 0;
+        //on compte le nombre d'occurences
+       for(Unite unit : donnees){
+           Schema chaine = chainesUnitesNonFiltrees.containsKey(unit) ? chainesUnitesNonFiltrees.get(unit)
+                    : null;
+                int nb = chaine==null ? 0 : unitesChaines.get(chaine).size() ;
+                if(isMasqueeValNbElements(calculerValNbElements(nb))){
+                    
+                }
+                else if(nb==0){
+                    valeurchamp = valsdisponibles[0];
+                    tableaufrequence.put(valeurchamp,tableaufrequence.get(valeurchamp) + 1); 
+                    compte = compte + 1;
+                }
+                else{
+                    valeurchamp = valsdisponibles[calculerValNbElements(nb)];
+                    tableaufrequence.put(valeurchamp,tableaufrequence.get(valeurchamp) + 1); 
+                    compte = compte + 1;
+                }           
+       }
+
+
+       //on calcule les pourcentages
+       for(String valeur : valsdisponibles){
+           tableaufrequence.put(valeur, tableaufrequence.get(valeur) * 10000.0f /
+                   compte / 100.0f);
+       }       
+       
+       
+       return tableaufrequence;
+   }   
+   
+
+   
+
+   //on enlève les unités dont les valeurs des chaines les contenant sont masquees
+   public Unite[] filtrechaine(Unite[] donnees, String Champ, HashSet<String> Valeurcachees){
+       ArrayList<Unite> unitefiltrees = new ArrayList<Unite>(); 
+       for(Unite unit : donnees){
+           if(chainesUnitesNonFiltrees.containsKey(unit) && !(Valeurcachees.contains(vue.getValeurChamp(chainesUnitesNonFiltrees.get(unit),Champ)))){
+               unitefiltrees.add(unit);
+           }
+       }
+       Unite[] resultat = unitefiltrees.toArray(new Unite[0]);
+       return resultat;
+   }   
+   //on ne garde que les unités dont les chaines les contenant possèdent la valeur "valeur" pour le champ 
+    //"Champ" 
+   public Unite[] filtrevaleurchaine(Unite[] donnees,String Champ,String valeur){
+       ArrayList<Unite> uniteduchamp = new ArrayList();
+       ArrayList<Unite> unitefiltrees = new ArrayList();
+       for(Schema chaine : unitesChaines.keySet()){
+           //on trie les unités dont les chaines contenant ont la bonne valeur pour le champ
+           if((vue.getValeurChamp(chaine, Champ)).equals(valeur)){
+               uniteduchamp.addAll(unitesChaines.get(chaine));
+           }
+       }
+       //on ne garde que les unités passée en paramètre
+       for(int i = 0; i < donnees.length;i++){
+           if(uniteduchamp.contains(donnees[i])){
+               unitefiltrees.add(donnees[i]);
+           }
+       }
+       //on met le résultat sous forme de tableau
+       Unite[] resultat =(Unite[]) unitefiltrees.toArray();
+       return resultat;
+   }
+   
+  
+   //renvoioe la chaine qui contient l'unité dans ModeleChaine
+   public Schema getSchemacontenantunite(Unite unit){
+        return chainesUnitesNonFiltrees.get(unit);
+   }
+
+   //filtre qui remplit les mêmes fonctions que le précédent mais également qui filtre suivant une liste de 
+   //paragraphes interdits et ne garde que les unités appartenant aux chaines ayant pour le champ Champ la valeur
+   //Valeur
+    private void filtrerListeUnites(String typeUnites, String typeChaines,ArrayList noparagraphecachees,
+            String Champ,String Valeur){
+    Unite[] unites = vue.getUnitesAVoir(typeUnites);
+    Schema[] chaines = vue.getSchemasAVoir(typeChaines);
+    unitesChaines.clear();
+    int[] noparagraphe = (vue.getCorpus()).calculerNoParagraphe(unites);
+    for (Schema chaine : chaines) unitesChaines.put(chaine, new ArrayList<Unite>());
+    ArrayList<Integer> indFiltrees = new ArrayList<Integer>();
+    String[] champs = vue.getNomsChamps(Unite.class, typeUnites);
+    boolean agarder;
+    for (int i = 0; i<unites.length; i++) {
+      agarder = true;
+      for (String champ : champs) {//pour tous les champs 
+        String val = vue.getValeurChamp(unites[i], champ);//je recupere la valeur du champ
+        if (val.isEmpty()) {
+          if (valNulleMasqueeChamp.contains(champ)) {
+            agarder = false;
+            break;
+          }
+        } else {
+          if (valsMasqueesChamp.get(champ).contains(val)) {
+            agarder = false;
+            break;
+          }
+        }
+      }
+      //si l'unité appartient à un paragraphe interdit
+      if(noparagraphecachees.contains(noparagraphe[i])){
+          agarder = false;
+      }
+      //si la chaine contenant l'unité a une mauvaise valeur pour le champ ou si l'unité est sans chaine
+      if(!chainesUnitesNonFiltrees.containsKey(unites[i]) || 
+              !vue.getValeurChamp(chainesUnitesNonFiltrees.get(unites[i]),Champ).equals(Valeur)){
+          agarder = false;
+      }
+      if (agarder) {
+        indFiltrees.add(i);
+        if (chainesUnitesNonFiltrees.containsKey(unites[i])) {
+          Schema chaine = chainesUnitesNonFiltrees.get(unites[i]);
+          unitesChaines.get(chaine).add(unites[i]);
+        }
+      }
+    }
+    ArrayList<Integer> indIndFiltrees = new ArrayList<Integer>();
+    for(int k=0; k<indFiltrees.size(); k++) {
+      Unite unit = unites[indFiltrees.get(k)];
+      if(chainesUnitesNonFiltrees.containsKey(unit)) {
+        if(!isMasqueeValNbElements(calculerValNbElements(
+                unitesChaines.get(chainesUnitesNonFiltrees.get(unit)).size())))
+          indIndFiltrees.add(k);
+      } else {
+        if(!isMasqueeValNbElements(0)) indIndFiltrees.add(k);
+      }      
+    }
+    listeUnites = new Unite[indIndFiltrees.size()];
+    for (int k = 0; k<listeUnites.length; k++) {
+      listeUnites[k] = unites[indFiltrees.get(indIndFiltrees.get(k))];
+    }
+        for (Schema chaine : chaines) {
+          int nb = unitesChaines.get(chaine).size();
+          if(nb==0||isMasqueeValNbElements(calculerValNbElements(nb)))
+            unitesChaines.remove(chaine);
+        }
+  }
+    //permet de calculer les données pour une valeur de champ de la chaine
+  private void calculerDonnees(String typeChaines, String typeUnites,ArrayList noparagraphecachees,String champ
+  ,String Valeur) {
+     filtrerListeUnites(typeUnites, typeChaines,noparagraphecachees, champ, Valeur);
+    Chainon[] chainons = new Chainon[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Unite unit = listeUnites[i];
+      chainons[i] = new Chainon(unit, vue.getTexteUnite(unit));
+      if(chainesUnitesNonFiltrees.containsKey(unit)) {
+        Schema chaine = chainesUnitesNonFiltrees.get(unit);
+        chainons[i].chaine = chaine;
+        chainons[i].nbEltsChaine = unitesChaines.get(chaine).size();
+        chainons[i].idChaine = vue.getIdElement(chaine);
+      } 
+      chainonsUnites.put(listeUnites[i], chainons[i]);
+    }
+    HashMap<Schema, Integer> noChaine = new HashMap<Schema, Integer>();
+    int no = 0;
+    for (Schema chaine : vue.getSchemasAVoir(typeChaines)) {
+      if(unitesChaines.containsKey(chaine)) {
+        int nbElts = unitesChaines.get(chaine).size(); 
+       noChaine.put(chaine, nbElts>1 ? ++no : 0);
+    }
+    }
+    for (Unite unit : listeUnites) {
+      Chainon chainon = chainonsUnites.get(unit);
+      if (chainon.chaine!=null) chainon.noChaine = noChaine.get(chainon.chaine);
+    }
+    int[] noPar = vue.getCorpus().calculerNoParagraphe(listeUnites);
+    if(peutafficher){
+        panneauGraphique.setDonnees(chainons, noPar);
+    }
+  }
+
+
+  
+
+    
+ 
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ModeleChaines.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/GChaines.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/GChaines.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/GChaines.java	(revision 481)
@@ -0,0 +1,1027 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.chaines;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.geom.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.chaines.ModeleChaines.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.fichiers.FichiersGraphique;
+/**
+ *
+ * @author Bernard
+ */
+public class GChaines extends JPanel {//donnée de la chaine
+  final static Font FONTE_ID = Font.decode("Arial bold 10");
+  final static int RAYON_DISQUES = 12;
+  final static int MARGE_DISQUES = 2;
+  final static int LARGEUR_INTER_CHAINONS = 10;
+  final static int MARGE_DEBUT_LIGNE = 15;
+  final static int HAUTEUR_LIGNES = 80;
+  final static int HAUTEUR_SEGMENT = 40;
+  final static int HAUTEUR_CHAINONS = 60;
+  final static int policeTailleSVG = 10;
+  final static String policeSVG = "font-size:50px;font-family:'Trebuchet MS', Verdana, serif;";
+  final static String SYMBOLE_SEGMENT = "§";
+//    final static int hauteurinfLien = 25;
+//    final static int deltahauteurLien = 5;
+//    final static int deltasupArcs = 95;
+//    final static int hauteurinfArcs = 5;
+//  final static int HAUTEUR_PANNEAU = 120;
+  final static String PAS_DE_NUMERO = "~";
+
+  static class GChainon extends JButton {//permet de créer un chainon hérite d'un bouton
+    VisuChaines visu;
+    VisuCoref visucoref;
+    Chainon chainon;
+    public GChainon(Chainon ch, VisuChaines vis) {
+      super();//on recupere le bouton
+      this.visu = vis;//on récupère le chainon et le visu
+      this.chainon = ch;
+      Icon d = new DisqueCouleurIcone(Color.WHITE, RAYON_DISQUES, MARGE_DISQUES);
+      setAction(new GAction(null, d) {
+        public void executer() {
+          //visu.afficherOccurrences(chainon.unite, chainon.chaine);
+        }
+      });
+  
+      setSize(2*(RAYON_DISQUES+MARGE_DISQUES), 2*(RAYON_DISQUES+MARGE_DISQUES));//on calcule la taille
+      setBorderPainted(false);
+      String t2 = "<html><div style=\"font-size:11pt\"><span style=\"font-style:italic\">"+chainon.texte
+              +"</span><p>"+chainon.idChaine+"<p>"+chainon.nbEltsChaine+" occurences </div>";//cree les metadonnees
+      setToolTipText(t2);
+      setBackground(Color.WHITE);//arrière plan
+      setFocusPainted(false);
+    }
+    public GChainon(Chainon ch, VisuCoref vis) {
+      super();//on recupere le bouton
+      this.visucoref = vis;//on récupère le chainon et le visu
+      this.chainon = ch;
+      Icon d = new DisqueCouleurIcone(Color.WHITE, RAYON_DISQUES, MARGE_DISQUES);
+      setAction(new GAction(null, d) {
+        public void executer() {
+          //visu.afficherOccurrences(chainon.unite, chainon.chaine);
+        }
+      }); 
+        
+      setSize(2*(RAYON_DISQUES+MARGE_DISQUES), 2*(RAYON_DISQUES+MARGE_DISQUES));//on calcule la taille
+      setBorderPainted(false);
+      String t2 = "<html><div style=\"font-size:11pt\"><span style=\"font-style:italic\">"+chainon.texte
+              +"</span><p>"+chainon.idChaine+"<p>"+chainon.nbEltsChaine+" occurences </div>";//cree les metadonnees
+      setToolTipText(t2);
+      setBackground(Color.WHITE);//arrière plan
+      setFocusPainted(false);
+    }
+      
+    @Override
+    public JToolTip createToolTip() {
+      JToolTip jt = new JToolTip();
+      jt.setBackground(Color.WHITE);
+      return jt;
+    }
+    void changerCouleur(Color couleur) {//change couleur du disque
+      setIcon(new DisqueCouleurIcone(couleur, RAYON_DISQUES, MARGE_DISQUES));
+    }
+    void changerCouleur(Color couleur,int taillediviseur,int forme) {
+    //change couleur,forme et taille du chainon
+        switch(forme){
+            case 0 :
+                setIcon(new DisqueCouleurIcone(couleur, RAYON_DISQUES / taillediviseur
+                        , MARGE_DISQUES));
+                break;
+            case 1 :
+                setIcon(new CarreCouleurIcone(couleur, RAYON_DISQUES / taillediviseur
+                        , MARGE_DISQUES));
+                break;
+            case 2 :
+                setIcon(new CroixCouleurIcone(couleur, RAYON_DISQUES / taillediviseur
+                        , MARGE_DISQUES));
+                break;
+            case 3 :
+                setIcon(new TriangleCouleurIcone(couleur, RAYON_DISQUES / taillediviseur
+                        , MARGE_DISQUES));
+                break;
+            default :
+                setIcon(new TriangleinverseCouleurIcone(couleur, RAYON_DISQUES / taillediviseur
+                        , MARGE_DISQUES));
+                break;
+        }
+    }    
+    
+  }
+
+  static class GNoChainon extends JLabel {//pas de chainon mais du texte
+    public GNoChainon(String contenu) {
+      super(contenu);
+      setFont(FONTE_ID);//police de texte
+      setSize(21,13);
+    }
+    void localiser(Point chainonPosition, Dimension chainonTaille) {
+      int x = chainonPosition.x+chainonTaille.width/2-getSize().width/2;
+      int y = chainonPosition.y-getSize().height;
+      setLocation(x, y);
+    }
+    
+  }
+  
+  static class GNoSousChainon extends JLabel {//pas de chainon mais du texte
+    public GNoSousChainon(String contenu) {
+      super(contenu);
+      setFont(FONTE_ID);//police de texte
+      setSize(21,13);
+    }
+    void localiser(Point chainonPosition, Dimension chainonTaille) {
+      int x = chainonPosition.x+chainonTaille.width/2-getSize().width/2;
+      int y = chainonPosition.y+2*(RAYON_DISQUES+MARGE_DISQUES);
+      setLocation(x, y);
+    }
+  }  
+
+  private enum TypeSegment {//segment correspondant au paragraphe 
+    COMPLET("", ""),
+    DEBUT("", "-"),
+    MILIEU("-", "-"),
+    FIN("-", "");
+    String marqueAvant, marqueApres;
+    private TypeSegment(String avant, String apres) {
+      marqueAvant = avant;
+      marqueApres = apres;
+    }
+  }
+
+  static class GSegment extends JLabel {//on ajoute des propriétés à un label texte
+    int xmin, xmax;
+    int ybas, yhaut;
+    int no;
+    TypeSegment type;
+    GSegment(int xmin, int xmax, int ybas, int yhaut, int no, TypeSegment type) {
+      super(type.marqueAvant+SYMBOLE_SEGMENT+Integer.toString(no)+type.marqueApres);
+      setFont(FONTE_ID);//police de texte
+      this.xmin = xmin;
+      this.xmax = xmax;
+      this.ybas = ybas;
+      this.yhaut = yhaut;
+      this.type = type;
+      setSize(getPreferredSize());
+    }
+    void localiser() {//on localise où placer le symbole du paragraphe
+      setLocation((xmin+xmax)/2-getSize().width/2, yhaut-getSize().height);
+    }
+    void dessinerTraits(Graphics graphics) {//dessine les traits du pragraphe
+      Graphics2D g = (Graphics2D) graphics;
+      g.setColor(Color.BLACK);
+      Point p0 = new Point(xmin, ybas);
+      Point p1 = new Point(xmin, yhaut);
+      Point p2 = new Point(xmax, yhaut);
+      Point p3 = new Point(xmax, ybas);
+      switch (type) {
+        case COMPLET:
+          g.draw(new Line2D.Float(p0, p1));
+          g.draw(new Line2D.Float(p1, p2));
+          g.draw(new Line2D.Float(p2, p3));
+          break;
+        case DEBUT:
+          g.draw(new Line2D.Float(p0, p1));
+          g.draw(new Line2D.Float(p1, p2));
+          break;
+        case FIN:
+          g.draw(new Line2D.Float(p1, p2));
+          g.draw(new Line2D.Float(p2, p3));
+          break;
+        case MILIEU:
+          g.draw(new Line2D.Float(p1, p2));
+          break;
+      }
+    }
+  }
+  /*
+   * Champs de la classeGChaines
+   */
+  VisuChaines visu;
+  VisuCoref visucoref;
+  Chainon[] chainons = new Chainon[0];
+  int[] noSegments = new int[0];
+  Color[] couleurs = new Color[0];
+  int[] taille = new int[0];
+  int[] forme = new int[0];
+  String[] SurTexte = new String[0];
+  String[] SousTexte = new String[0];  
+  boolean couperparagraphe = false;
+  GChainon[] gChainons;
+  GNoChainon[] gNoChainon;
+  GNoSousChainon[] gNoSousChainon;
+  JButton exporter;
+  boolean permettreSousTexte = false;
+  ArrayList<GSegment> gSegments = new ArrayList<GSegment>();
+  private int nbChainonsParLigne = 1000;
+  GChaines(VisuChaines vc) {
+    super((LayoutManager) null);
+    setBackground(Color.WHITE);
+    this.visu = vc;
+    addMouseListener(new MouseAdapter() {
+      @Override
+      public void mouseClicked(MouseEvent e) {
+       // visu.traiterAffTexteClicVide();
+      }
+    });
+  }
+  GChaines(VisuCoref vc) {
+    super((LayoutManager) null);
+    setBackground(Color.WHITE);
+    this.visucoref = vc;
+    addMouseListener(new MouseAdapter() {
+      @Override
+      public void mouseClicked(MouseEvent e) {
+       // visu.traiterAffTexteClicVide();
+      }
+    });
+  }  
+  GChaines(VisuStatGenerale vc) {
+    super((LayoutManager) null);
+    setBackground(Color.WHITE);
+    addMouseListener(new MouseAdapter() {
+      @Override
+      public void mouseClicked(MouseEvent e) {
+       // visu.traiterAffTexteClicVide();
+      }
+    });
+  }    
+  void setNbChainonsParLigne(int nb) {
+    nbChainonsParLigne = nb;
+    afficher();
+    colorer();
+  }
+  void setDonnees(Chainon[] chainons, int[] noSegments) {
+    this.chainons = chainons;
+    this.noSegments = noSegments;
+    afficher();
+  }
+  void setcouperparagraphe(boolean couperparagraphe){
+      this.couperparagraphe = couperparagraphe;
+  }
+  //cherche la longueur du paragraphe
+  private int longueurpara(int[] nosegments,int deb){
+      for(int  i = deb; i < nosegments.length - 1;i++){
+          if(noSegments[i+1]>noSegments[i]){
+              return i + 1 - deb;
+          }
+      }
+      return -1;
+  }
+  private void afficher() {
+    effacerTout();
+    if (chainons.length==0) return;
+    gChainons = new GChainon[chainons.length];
+    int xCourant = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS;
+    int yCourant = 0;
+    gNoChainon = new GNoChainon[chainons.length];
+    if(permettreSousTexte){
+    gNoSousChainon = new GNoSousChainon[chainons.length];
+    }
+    int positionligne = 0;
+    int xminSeg = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS/2+2;
+    GSegment gseg;
+    int xmaxSeg = 0;
+    int xmaxligne = 0;
+    for (int i = 0; i<chainons.length; i++) {
+        if(visu==null){
+      gChainons[i] = new GChainon(chainons[i], visu);
+        }
+        else{
+        gChainons[i] = new GChainon(chainons[i], visucoref);    
+        }
+      add(gChainons[i]);
+      gChainons[i].setLocation(xCourant, yCourant+HAUTEUR_CHAINONS);
+      add(gNoChainon[i] = new GNoChainon(chainons[i].texte.length()<4 ? 
+              chainons[i].texte.substring(0, chainons[i].texte.length()) 
+              : chainons[i].texte.substring(0,4)));
+      gNoChainon[i].localiser(gChainons[i].getLocation(), gChainons[i].getSize());
+      if(permettreSousTexte){
+      add(gNoSousChainon[i] = new GNoSousChainon(chainons[i].texte.length()<4 ? 
+              chainons[i].texte.substring(0, chainons[i].texte.length()) 
+              : chainons[i].texte.substring(0,4)));
+      gNoSousChainon[i].localiser(gChainons[i].getLocation(), gChainons[i].getSize());  
+      }
+      xCourant += gChainons[i].getWidth()+LARGEUR_INTER_CHAINONS;
+      xmaxligne = Math.max(xCourant, xmaxligne);
+      xmaxSeg = xCourant-LARGEUR_INTER_CHAINONS/2-2;
+      if (i+1==chainons.length||noSegments[i+1]>noSegments[i]) {
+        // fin de paragraphe, donc on trace un segment terminal  
+        if (xminSeg>0) {  // le paragraphe a commencé sur cette ligne
+          add(gseg = new GSegment(xminSeg, xmaxSeg, yCourant+HAUTEUR_CHAINONS,
+                  yCourant+HAUTEUR_SEGMENT, noSegments[i], TypeSegment.COMPLET));
+        } else {  // le paragraphe a commencé avant cette ligne
+          xminSeg = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS/2+2;
+          add(gseg = new GSegment(xminSeg, xmaxSeg, yCourant+HAUTEUR_CHAINONS,
+                  yCourant+HAUTEUR_SEGMENT, noSegments[i], TypeSegment.FIN));
+        }
+        gseg.localiser();
+        gSegments.add(gseg);
+        xminSeg = xmaxSeg+4;
+      }
+      if (i+1!=chainons.length && ((!couperparagraphe && (i+1)%nbChainonsParLigne==0) || 
+              (couperparagraphe && (((positionligne+1)%nbChainonsParLigne==0) || (noSegments[i+1]>noSegments[i]
+              && longueurpara(noSegments,i+1) <= nbChainonsParLigne && (nbChainonsParLigne - positionligne - 1) < 
+              longueurpara(noSegments,i+1)))))) {  // on va changer de ligne
+        if (xminSeg>xmaxSeg) {  // ça tombe bien : on change aussi de segment
+          xminSeg = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS/2+2;
+        } else { // ca tombe pas bien : il faut tracer un segment non terminal
+          if (xminSeg>0) { // le paragraphe a commencé sur cette ligne
+            add(gseg = new GSegment(xminSeg, xmaxSeg, yCourant+HAUTEUR_CHAINONS,
+                    yCourant+HAUTEUR_SEGMENT, noSegments[i], TypeSegment.DEBUT));
+          } else {  // le paragraphe a commencé avant cette ligne
+            xminSeg = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS/2+2;
+            add(gseg = new GSegment(xminSeg, xmaxSeg, yCourant+HAUTEUR_CHAINONS,
+                    yCourant+HAUTEUR_SEGMENT, noSegments[i], TypeSegment.MILIEU));
+          }
+          gseg.localiser();
+          gSegments.add(gseg);
+          xminSeg = -1;
+        }
+        xCourant = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS;
+        yCourant += HAUTEUR_LIGNES;
+        positionligne = -1;
+      }
+      positionligne = positionligne + 1;
+    }
+    exporter = new JButton("exporter en SVG");
+    exporter.setAction(new GAction("exporter en SVG") {
+        public void executer() {
+          exporterEnSvg();
+        }
+      });
+    add(exporter);
+    exporter.setLocation(100, yCourant +2*HAUTEUR_LIGNES);
+    exporter.setSize(150, 40);
+    exporter.setVisible(true);
+    
+    setPreferredSize(new Dimension(xmaxligne+30, yCourant+3*HAUTEUR_LIGNES+30));
+  }
+  void setCouleurs(Color[] couleurs) {//on affecte la couleur 
+    this.couleurs = couleurs;
+    colorer();
+  }
+  void setTaille(int[] tailles) {//on affecte la couleur 
+    this.taille = tailles;
+    Reduire();
+  }
+    void setForme(int[] formes) {//on affecte la couleur 
+    this.forme = formes;
+    Former();
+  }
+    void setSurTexte(String[] SurTexte) {//on affecte la couleur 
+    this.SurTexte = SurTexte;
+    SurTitrer();
+  }
+    void setSousTexte(String[] SousTexte) {//on affecte la couleur 
+    this.SousTexte = SousTexte;
+    SousTitrer();
+  }
+    
+    
+  private void colorer() {//on colore les chainons
+      boolean taillenoninitialisee=false;
+      boolean formenoninitialisee=false;
+      boolean SurTextenoninitialisee=false;
+      boolean SousTextenoninitialisee=false;
+        if(couleurs.length != taille.length){ 
+//dans le cas ou on n'a pas encore défini la tailleb et la forme des chainons
+            this.taille = new int[gChainons.length];
+            taillenoninitialisee = true;
+        }
+        if(couleurs.length != forme.length){
+            this.forme = new int[gChainons.length];
+            formenoninitialisee = true;
+        }
+        if(couleurs.length != SurTexte.length){
+            this.SurTexte = new String[gChainons.length];
+            SurTextenoninitialisee = true;
+        }
+        if(couleurs.length != SousTexte.length){
+            this.SousTexte = new String[gChainons.length];
+            SousTextenoninitialisee = true;
+        }
+    for (int i = 0; i<gChainons.length; i++) {
+        if(taillenoninitialisee){
+            this.taille[i] = 1;  
+        }
+        if(formenoninitialisee){
+            this.forme[i] = 0;          
+        }
+        if(SurTextenoninitialisee){
+            this.SurTexte[i] = "";          
+        }
+        if(SousTextenoninitialisee){
+            this.SousTexte[i] = "";          
+        }
+        gChainons[i].changerCouleur(couleurs[i],this.taille[i],this.forme[i]);
+        if(permettreSousTexte){
+            gNoChainon[i].setText(this.SurTexte[i]);
+            gNoSousChainon[i].setText(this.SousTexte[i]);
+        }
+        
+    }
+    if(exporter!=null){
+        exporter.setVisible(true);
+    }
+    revalidate();
+    repaint();
+  }
+
+  private void Reduire() {//on reduit les chainons
+      boolean couleurnoninitialisee=false;
+      boolean formenoninitialisee=false;
+      boolean SurTextenoninitialisee=false;
+      boolean SousTextenoninitialisee=false;
+        if(taille.length != couleurs.length){ 
+            this.couleurs = new Color[gChainons.length];
+            couleurnoninitialisee = true;
+        }
+        if(taille.length != forme.length){
+            this.forme = new int[gChainons.length];
+            formenoninitialisee = true;
+        }
+        if(taille.length != SurTexte.length){
+            this.SurTexte = new String[gChainons.length];
+            SurTextenoninitialisee = true;
+        }
+        if(taille.length != SousTexte.length){
+            this.SousTexte = new String[gChainons.length];
+            SousTextenoninitialisee = true;
+        }
+    for (int i = 0; i<gChainons.length; i++) {
+        if(couleurnoninitialisee){
+            this.couleurs[i] = Color.WHITE;  
+        }
+        if(formenoninitialisee){
+            this.forme[i] = 0;          
+        }
+        if(SurTextenoninitialisee){
+            this.SurTexte[i] = "";          
+        }
+        if(SousTextenoninitialisee){
+            this.SousTexte[i] = "";          
+        }
+        gChainons[i].changerCouleur(this.couleurs[i],taille[i],this.forme[i]);
+        if(permettreSousTexte){
+            gNoChainon[i].setText(this.SurTexte[i]);
+            gNoSousChainon[i].setText(this.SousTexte[i]);
+        }
+    }
+    if(exporter!=null){
+        exporter.setVisible(true);
+    }
+    revalidate();
+    repaint();
+  }
+  
+  private void Former() {//on change la forme des chainons
+      boolean couleurnoninitialisee=false;
+      boolean taillenoninitialisee=false;
+      boolean SurTextenoninitialisee=false;
+      boolean SousTextenoninitialisee=false;
+        if(forme.length != couleurs.length){ 
+            this.couleurs = new Color[gChainons.length];
+            couleurnoninitialisee = true;
+        }
+        if(forme.length != taille.length){
+            this.taille = new int[gChainons.length];
+            taillenoninitialisee = true;
+        }
+        if(forme.length != SurTexte.length){
+            this.SurTexte = new String[gChainons.length];
+            SurTextenoninitialisee = true;
+        }
+        if(forme.length != SousTexte.length){
+            this.SousTexte = new String[gChainons.length];
+            SousTextenoninitialisee = true;
+        }
+    for (int i = 0; i<gChainons.length; i++) {
+        if(couleurnoninitialisee){
+            this.couleurs[i] = Color.WHITE;  
+        }
+        if(taillenoninitialisee){
+            this.taille[i] = 1;          
+        }
+        if(SurTextenoninitialisee){
+            this.SurTexte[i] = "";          
+        }
+        if(SousTextenoninitialisee){
+            this.SousTexte[i] = "";          
+        }
+        gChainons[i].changerCouleur(this.couleurs[i],this.taille[i],this.forme[i]);
+        if(permettreSousTexte){
+            gNoChainon[i].setText(this.SurTexte[i]);
+            gNoSousChainon[i].setText(this.SousTexte[i]);
+        }
+    }
+    if(exporter!=null){
+        exporter.setVisible(true);
+    }
+    revalidate();
+    repaint();
+  }
+  private void SurTitrer() {//on change le texte au dessus des chainons
+      boolean couleurnoninitialisee=false;
+      boolean taillenoninitialisee=false;
+      boolean Formenoninitialisee=false;
+      boolean SousTextenoninitialisee=false;
+        if(SurTexte.length != couleurs.length){ 
+            this.couleurs = new Color[gChainons.length];
+            couleurnoninitialisee = true;
+        }
+        if(SurTexte.length != taille.length){
+            this.taille = new int[gChainons.length];
+            taillenoninitialisee = true;
+        }
+        if(SurTexte.length != forme.length){
+            this.forme = new int[gChainons.length];
+            Formenoninitialisee = true;
+        }
+        if(SurTexte.length != SousTexte.length){
+            this.SousTexte = new String[gChainons.length];
+            SousTextenoninitialisee = true;
+        }
+    for (int i = 0; i<gChainons.length; i++) {
+        if(couleurnoninitialisee){
+            this.couleurs[i] = Color.WHITE;  
+        }
+        if(taillenoninitialisee){
+            this.taille[i] = 1;          
+        }
+        if(Formenoninitialisee){
+            this.forme[i] = 0;          
+        }
+        if(SousTextenoninitialisee){
+            this.SousTexte[i] = "";          
+        }
+        gChainons[i].changerCouleur(this.couleurs[i],this.taille[i],this.forme[i]);
+        if(permettreSousTexte){
+            gNoChainon[i].setText(this.SurTexte[i]);
+            gNoSousChainon[i].setText(this.SousTexte[i]);
+        }
+    }
+    if(exporter!=null){
+        exporter.setVisible(true);
+    }
+    revalidate();
+    repaint();
+  } 
+  
+  private void SousTitrer() {//on change le texte au dessus des chainons
+      boolean couleurnoninitialisee=false;
+      boolean taillenoninitialisee=false;
+      boolean Formenoninitialisee=false;
+      boolean SurTextenoninitialisee=false;
+        if(SousTexte.length != couleurs.length){ 
+            this.couleurs = new Color[gChainons.length];
+            couleurnoninitialisee = true;
+        }
+        if(SousTexte.length != taille.length){
+            this.taille = new int[gChainons.length];
+            taillenoninitialisee = true;
+        }
+        if(SousTexte.length != forme.length){
+            this.forme = new int[gChainons.length];
+            Formenoninitialisee = true;
+        }
+        if(SousTexte.length != SurTexte.length){
+            this.SurTexte = new String[gChainons.length];
+            SurTextenoninitialisee = true;
+        }
+    for (int i = 0; i<gChainons.length; i++) {
+        if(couleurnoninitialisee){
+            this.couleurs[i] = Color.WHITE;  
+        }
+        if(taillenoninitialisee){
+            this.taille[i] = 1;          
+        }
+        if(Formenoninitialisee){
+            this.forme[i] = 0;          
+        }
+        if(SurTextenoninitialisee){
+            this.SurTexte[i] = "";          
+        }
+        gChainons[i].changerCouleur(this.couleurs[i],this.taille[i],this.forme[i]);
+        if(permettreSousTexte){
+            gNoChainon[i].setText(this.SurTexte[i]);
+            gNoSousChainon[i].setText(this.SousTexte[i]);
+        }
+    }
+    if(exporter!=null){
+        exporter.setVisible(true);
+    }
+    revalidate();
+    repaint();
+  }  
+
+  private void effacerTout() {//on efface tous les chainons
+    removeAll();
+    gChainons = new GChainon[0];
+    gSegments.clear();
+    repaint();
+  }
+  private void effacer(Graphics graphics) {//on efface le graphique 
+    graphics.setColor(Color.WHITE);
+    graphics.fillRect(0, 0, getWidth(), getHeight());
+  }
+  @Override
+  protected void paintComponent(Graphics graphics) {//a voir
+    effacer(graphics);
+    for (GSegment gs : gSegments) gs.dessinerTraits(graphics);
+  }
+  public void autoriserSousTexte(boolean permettresoustexte){
+      this.permettreSousTexte = permettresoustexte;
+  } 
+  public static String ecrireSVGIcon(GChainon icone){
+      String balise ="";
+      int x = icone.getX() + icone.getWidth()/2 - icone.getIcon().getIconWidth()/2;
+      int y = icone.getY()+ icone.getHeight()/2 - icone.getIcon().getIconHeight()/2;
+      if(icone.getIcon().getClass()== DisqueCouleurIcone.class){
+          DisqueCouleurIcone figure = (DisqueCouleurIcone) icone.getIcon();
+          balise="<ellipse cx=\""+(x + figure.getMarge() + figure.getRayon()
+                  )+"\" cy=\""+(y + figure.getMarge() + figure.getRayon()
+                  )+"\" rx=\""+ figure.getRayon()+"\" ry=\""+ figure.getRayon()+"\" "
+                  + "style=\" fill:rgb("+figure.getColor().getRed()+","+figure.getColor().getGreen()
+                  +","+figure.getColor().getBlue()+"); stroke:black\"/>"+System.getProperty("line.separator");
+      }
+      if(icone.getIcon().getClass()== CarreCouleurIcone.class){
+          CarreCouleurIcone figure = (CarreCouleurIcone) icone.getIcon();
+          balise="<rect x=\""+(x + figure.getMarge()) +
+                  "\" y=\""+(y + figure.getMarge())+"\" width=\""+figure.getRayon()*2+"\" height=\""
+                  +figure.getRayon()*2+"\" "+"style=\" fill:rgb("+figure.getColor().getRed()+
+                  ","+figure.getColor().getGreen()+","+figure.getColor().getBlue()+"); stroke:black\"/>"
+                  +System.getProperty("line.separator");
+      }      
+      if(icone.getIcon().getClass()== TriangleCouleurIcone.class){
+          TriangleCouleurIcone figure = (TriangleCouleurIcone) icone.getIcon();
+          balise="<polygon points=\"";
+          balise = balise + (x + figure.getMarge()) + "," 
+                  + (y + figure.getMarge()+ 2 * figure.getRayon());
+          balise = balise + " " + (x + figure.getMarge() + figure.getRayon()) + "," 
+                  + (y + figure.getMarge());
+          balise = balise + " " + (x + figure.getMarge() + 2 *figure.getRayon()) + "," 
+                  + (y + figure.getMarge()+ 2 * figure.getRayon());
+          balise = balise + "\" "+"style=\" fill:rgb("+figure.getColor().getRed()+
+                  ","+figure.getColor().getGreen()+","+figure.getColor().getBlue()+"); stroke:black\"/>"
+                  +System.getProperty("line.separator");
+      }       
+      if(icone.getIcon().getClass()== CroixCouleurIcone.class){
+          CroixCouleurIcone figure = (CroixCouleurIcone) icone.getIcon();
+          balise="<polygon points=\"";
+          balise = balise + (x + figure.getMarge()) + "," 
+                  + (y + figure.getMarge()+figure.getRayon()-1);
+          balise = balise + " " + (x + figure.getMarge() + figure.getRayon() - 1) + "," 
+                  + (y + figure.getMarge()+figure.getRayon()-1);
+          balise = balise + " " + (x + figure.getMarge() + figure.getRayon() - 1) + "," 
+                  + (y + figure.getMarge());
+          balise = balise + " " + (x + figure.getMarge() + figure.getRayon() + 1) + "," 
+                  + (y + figure.getMarge());
+          balise = balise + " " + (x + figure.getMarge() + figure.getRayon() + 1) + "," 
+                  + (y + figure.getMarge()+figure.getRayon()-1);
+          balise = balise + " " + (x + figure.getMarge() + 2 *figure.getRayon()) + "," 
+                  + (y + figure.getMarge()+figure.getRayon()-1);
+          balise = balise + " " + (x + figure.getMarge() + 2* figure.getRayon()) + "," 
+                  + (y + figure.getMarge()+figure.getRayon()+1);
+          balise = balise + " " + (x + figure.getMarge() + figure.getRayon() + 1) + "," 
+                  + (y + figure.getMarge()+figure.getRayon()+1);
+          balise = balise + " " + (x + figure.getMarge() + figure.getRayon() + 1) + "," 
+                  + (y + figure.getMarge()+ 2 * figure.getRayon());
+          balise = balise + " " + (x + figure.getMarge() + figure.getRayon() - 1) + "," 
+                  + (y + figure.getMarge()+2*figure.getRayon());
+          balise = balise + " " + (x + figure.getMarge() + figure.getRayon() - 1) + "," 
+                  + (y + figure.getMarge()+figure.getRayon()+1);
+          balise = balise + " " + (x + figure.getMarge()) + "," 
+                  + (y + figure.getMarge()+figure.getRayon()+1);
+          balise = balise + "\" "+"style=\" fill:rgb("+figure.getColor().getRed()+
+                  ","+figure.getColor().getGreen()+","+figure.getColor().getBlue()+"); stroke:black\"/>"
+                  +System.getProperty("line.separator");
+      }        
+      if(icone.getIcon().getClass()== TriangleinverseCouleurIcone.class){
+          TriangleinverseCouleurIcone figure = (TriangleinverseCouleurIcone) icone.getIcon();
+          balise="<polygon points=\"";
+          balise = balise + (x + figure.getMarge()) + "," 
+                  + (y + figure.getMarge());
+          balise = balise + " " + (x + figure.getMarge() + 2*figure.getRayon()) + "," 
+                  + (y + figure.getMarge());
+          balise = balise + " " + (x + figure.getMarge() + figure.getRayon()) + "," 
+                  + (y + figure.getMarge()+ 2 * figure.getRayon());
+          balise = balise + "\" "+"style=\" fill:rgb("+figure.getColor().getRed()+
+                  ","+figure.getColor().getGreen()+","+figure.getColor().getBlue()+"); stroke:black\"/>"
+                  +System.getProperty("line.separator");
+      }        
+      return balise;
+  }
+  
+  public static String ecrireSVGGsegment(GSegment seg){
+      String balise = "";
+      switch (seg.type) {
+        case COMPLET:
+            balise = balise + "<line x1=\""+seg.xmin+"\" y1=\""+seg.ybas+"\" x2=\""+seg.xmin+"\" y2=\""+seg.yhaut
+                    +"\" style=\" fill:black; stroke:black\"/>"+System.getProperty("line.separator");
+            balise = balise + "<line x1=\""+seg.xmin+"\" y1=\""+seg.yhaut+"\" x2=\""+seg.xmax+"\" y2=\""+seg.yhaut
+                    +"\" style=\" fill:black; stroke:black\"/>"+System.getProperty("line.separator");
+            balise = balise + "<line x1=\""+seg.xmax+"\" y1=\""+seg.yhaut+"\" x2=\""+seg.xmax+"\" y2=\""+seg.ybas
+                    +"\" style=\" fill:black; stroke:black\"/>"+System.getProperty("line.separator");
+          break;
+        case DEBUT:
+            balise = balise + "<line x1=\""+seg.xmin+"\" y1=\""+seg.ybas+"\" x2=\""+seg.xmin+"\" y2=\""+seg.yhaut
+                    +"\" style=\" fill:black; stroke:black\"/>"+System.getProperty("line.separator");
+            balise = balise + "<line x1=\""+seg.xmin+"\" y1=\""+seg.yhaut+"\" x2=\""+seg.xmax+"\" y2=\""+seg.yhaut
+                    +"\" style=\" fill:black; stroke:black\"/>"+System.getProperty("line.separator");
+          break;
+        case FIN:
+            balise = balise + "<line x1=\""+seg.xmin+"\" y1=\""+seg.yhaut+"\" x2=\""+seg.xmax+"\" y2=\""+seg.yhaut
+                    +"\" style=\" fill:black; stroke:black\"/>"+System.getProperty("line.separator");
+            balise = balise + "<line x1=\""+seg.xmax+"\" y1=\""+seg.yhaut+"\" x2=\""+seg.xmax+"\" y2=\""+seg.ybas
+                    +"\" style=\" fill:black; stroke:black\"/>"+System.getProperty("line.separator");
+          break;
+        case MILIEU:
+            balise = balise + "<line x1=\""+seg.xmin+"\" y1=\""+seg.yhaut+"\" x2=\""+seg.xmax+"\" y2=\""+seg.yhaut
+                    +"\" style=\" fill:black; stroke:black\"/>"+System.getProperty("line.separator");
+          break;
+      }
+      balise = balise + "<text x=\""+seg.getX()+"\" y=\""+(seg.getY() + seg.getHeight() - 4)+"\" "
+              + "style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+seg.getText()+"</text>"
+              +System.getProperty("line.separator");
+      return balise;
+  }
+  
+  public static String ecrireSVGSurTexte(GNoChainon sur){
+      String balise = "<text x=\""+sur.getX()+"\" y=\""+(sur.getY() + sur.getHeight())+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+sur.getText()+
+              "</text>"+System.getProperty("line.separator");
+      return balise;
+  }  
+  public static String ecrireSVGSousTexte(GNoSousChainon sous){
+      String balise = "<text x=\""+sous.getX()+"\" y=\""+(sous.getY() + sous.getHeight())+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+sous.getText()+
+              "</text>"+System.getProperty("line.separator");
+      return balise;
+  }
+  public static String ecrireSVGLegende (JTable legende,int posx, int posy){
+      String balise = "";
+      int x = posx;
+      int y = posy;
+      Object cellule;
+      for(int i = 0 ; i < legende.getRowCount();i++){
+          cellule = legende.getValueAt(i, 0)!=null ? legende.getValueAt(i, 0) : "99";
+          if(cellule.getClass()!=String.class){
+            y = y + (legende.getRowHeight(i) - ((Icon) cellule).getIconHeight())/2;
+          }
+          if(cellule.getClass()== DisqueCouleurIcone.class){
+              DisqueCouleurIcone figure = (DisqueCouleurIcone) cellule;
+              if(figure.getColor()!=null){
+              balise= balise + "<ellipse cx=\""+(x + figure.getMarge() + figure.getRayon()
+                      )+"\" cy=\""+(y + figure.getMarge() + figure.getRayon()
+                      )+"\" rx=\""+ figure.getRayon()+"\" ry=\""+ figure.getRayon()+"\" "
+                      + "style=\" fill:rgb("+figure.getColor().getRed()+","+figure.getColor().getGreen()
+                      +","+figure.getColor().getBlue()+"); stroke:black\"/>"+System.getProperty("line.separator");
+              }
+              else{
+              balise = balise + "<text x=\""+x+"\" y=\""+(y + (policeTailleSVG + legende.getRowHeight(i))/2
+                      - (legende.getRowHeight(i) - ((Icon) cellule).getIconHeight())/2)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+"X"+
+              "</text>"+System.getProperty("line.separator");
+              }
+          }
+          if(cellule.getClass()== CarreCouleurIcone.class){
+              CarreCouleurIcone figure = (CarreCouleurIcone) cellule;
+              if(figure.getColor()!=null){
+              balise= balise + "<rect x=\""+(x + figure.getMarge()) +
+                      "\" y=\""+(y + figure.getMarge())+"\" width=\""+figure.getRayon()*2+"\" height=\""
+                      +figure.getRayon()*2+"\" "+"style=\" fill:rgb("+figure.getColor().getRed()+
+                      ","+figure.getColor().getGreen()+","+figure.getColor().getBlue()+"); stroke:black\"/>"
+                      +System.getProperty("line.separator");
+              }
+              else{
+              balise = balise + "<text x=\""+x+"\" y=\""+(y + (policeTailleSVG + legende.getRowHeight(i))/2
+                      - (legende.getRowHeight(i) - ((Icon) cellule).getIconHeight())/2)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+"X"+
+              "</text>"+System.getProperty("line.separator");
+              }
+              
+          }      
+          if(cellule.getClass()== TriangleCouleurIcone.class){
+              TriangleCouleurIcone figure = (TriangleCouleurIcone) cellule;
+              if(figure.getColor()!=null){
+              balise= balise + "<polygon points=\"";
+              balise = balise + (x + figure.getMarge()) + "," 
+                      + (y + figure.getMarge()+ 2 * figure.getRayon());
+              balise = balise + " " + (x + figure.getMarge() + figure.getRayon()) + "," 
+                      + (y + figure.getMarge());
+              balise = balise + " " + (x + figure.getMarge() + 2 *figure.getRayon()) + "," 
+                      + (y + figure.getMarge()+ 2 * figure.getRayon());
+              balise = balise + "\" "+"style=\" fill:rgb("+figure.getColor().getRed()+
+                      ","+figure.getColor().getGreen()+","+figure.getColor().getBlue()+"); stroke:black\"/>"
+                      +System.getProperty("line.separator");
+              }
+              else{
+              balise = balise + "<text x=\""+x+"\" y=\""+(y + (policeTailleSVG + legende.getRowHeight(i))/2
+                      - (legende.getRowHeight(i) - ((Icon) cellule).getIconHeight())/2)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+"X"+
+              "</text>"+System.getProperty("line.separator");
+              }
+          }       
+          if(cellule.getClass()== CroixCouleurIcone.class){
+              CroixCouleurIcone figure = (CroixCouleurIcone) cellule;
+              if(figure.getColor()!=null){
+              balise= balise + "<polygon points=\"";
+              balise = balise + (x + figure.getMarge()) + "," 
+                      + (y + figure.getMarge()+figure.getRayon()-1);
+              balise = balise + " " + (x + figure.getMarge() + figure.getRayon() - 1) + "," 
+                      + (y + figure.getMarge()+figure.getRayon()-1);
+              balise = balise + " " + (x + figure.getMarge() + figure.getRayon() - 1) + "," 
+                      + (y + figure.getMarge());
+              balise = balise + " " + (x + figure.getMarge() + figure.getRayon() + 1) + "," 
+                      + (y + figure.getMarge());
+              balise = balise + " " + (x + figure.getMarge() + figure.getRayon() + 1) + "," 
+                      + (y + figure.getMarge()+figure.getRayon()-1);
+              balise = balise + " " + (x + figure.getMarge() + 2 *figure.getRayon()) + "," 
+                      + (y + figure.getMarge()+figure.getRayon()-1);
+              balise = balise + " " + (x + figure.getMarge() + 2* figure.getRayon()) + "," 
+                      + (y + figure.getMarge()+figure.getRayon()+1);
+              balise = balise + " " + (x + figure.getMarge() + figure.getRayon() + 1) + "," 
+                      + (y + figure.getMarge()+figure.getRayon()+1);
+              balise = balise + " " + (x + figure.getMarge() + figure.getRayon() + 1) + "," 
+                      + (y + figure.getMarge()+ 2 * figure.getRayon());
+              balise = balise + " " + (x + figure.getMarge() + figure.getRayon() - 1) + "," 
+                      + (y + figure.getMarge()+2*figure.getRayon());
+              balise = balise + " " + (x + figure.getMarge() + figure.getRayon() - 1) + "," 
+                      + (y + figure.getMarge()+figure.getRayon()+1);
+              balise = balise + " " + (x + figure.getMarge()) + "," 
+                      + (y + figure.getMarge()+figure.getRayon()+1);
+              balise = balise + "\" "+"style=\" fill:rgb("+figure.getColor().getRed()+
+                      ","+figure.getColor().getGreen()+","+figure.getColor().getBlue()+"); stroke:black\"/>"
+                      +System.getProperty("line.separator");
+              }
+              else{
+              balise = balise + "<text x=\""+x+"\" y=\""+(y + (policeTailleSVG + legende.getRowHeight(i))/2
+                      - (legende.getRowHeight(i) - ((Icon) cellule).getIconHeight())/2)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+"X"+
+              "</text>"+System.getProperty("line.separator");
+              }
+          }        
+          if(cellule.getClass()== TriangleinverseCouleurIcone.class){
+              TriangleinverseCouleurIcone figure = (TriangleinverseCouleurIcone) cellule;
+              if(figure.getColor()!=null){
+              balise= balise + "<polygon points=\"";
+              balise = balise + (x + figure.getMarge()) + "," 
+                      + (y + figure.getMarge());
+              balise = balise + " " + (x + figure.getMarge() + 2*figure.getRayon()) + "," 
+                      + (y + figure.getMarge());
+              balise = balise + " " + (x + figure.getMarge() + figure.getRayon()) + "," 
+                      + (y + figure.getMarge()+ 2 * figure.getRayon());
+              balise = balise + "\" "+"style=\" fill:rgb("+figure.getColor().getRed()+
+                      ","+figure.getColor().getGreen()+","+figure.getColor().getBlue()+"); stroke:black\"/>"
+                      +System.getProperty("line.separator");
+              }
+              else{
+              balise = balise + "<text x=\""+x+"\" y=\""+(y + (policeTailleSVG + legende.getRowHeight(i))/2
+                      - (legende.getRowHeight(i) - ((Icon) cellule).getIconHeight())/2)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+"X"+
+              "</text>"+System.getProperty("line.separator");
+              }
+          }
+          if(cellule.getClass() == String.class){
+              String texte = cellule.toString();
+              balise = balise + "<text x=\""+x+"\" y=\""+(y + legende.getRowHeight(i))+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+texte+
+              "</text>"+System.getProperty("line.separator");
+          }
+          if(cellule.getClass()!=String.class){
+            y = y - (legende.getRowHeight(i) - ((Icon) cellule).getIconHeight())/2;
+          }
+          y = y + legende.getRowHeight(i);
+      }
+      x = x + legende.getColumnModel().getColumn(0).getWidth();
+      y = posy;
+      for(int i = 0 ; i < legende.getRowCount();i++){
+              String texte = legende.getValueAt(i, 1).toString();
+              //si le texte commence par une balise html comme pour la valeur <autre> on enlève les balises
+              if(texte.charAt(0)=='<'){
+                  texte=texte.substring(1, texte.length()-1);
+              }
+              balise = balise + "<text x=\""+x+"\" y=\""+(y + (policeTailleSVG+legende.getRowHeight(i))/2)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+texte+
+              "</text>"+System.getProperty("line.separator");
+              y = y + legende.getRowHeight(i);
+      }
+      x = x + legende.getColumnModel().getColumn(1).getWidth();
+      y = posy;
+      for(int i = 0 ; i < legende.getRowCount();i++){
+              String texte = (legende.getValueAt(i, 2)==null ? "NC" : legende.getValueAt(i, 2).toString());
+              balise = balise + "<text x=\""+x+"\" y=\""+(y + (policeTailleSVG+legende.getRowHeight(i))/2)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+texte+
+              "</text>"+System.getProperty("line.separator");
+              y = y + legende.getRowHeight(i);
+      }
+      return balise;
+  }  
+  
+  public void exporterEnSvg(){
+      String graphique = "";
+      String fin = "</svg>";
+      for(GChainon figure : this.gChainons){
+        graphique = graphique + ecrireSVGIcon(figure);
+      }
+      for(GSegment figure : this.gSegments){
+        graphique = graphique + ecrireSVGGsegment(figure);
+      }
+      for(GNoChainon figure : this.gNoChainon){
+        graphique = graphique + ecrireSVGSurTexte(figure);
+      }
+      if(this.gNoSousChainon!=null){
+        for(GNoSousChainon figure : this.gNoSousChainon){
+            graphique = graphique + ecrireSVGSousTexte(figure);
+        }
+      }
+      int x = 40;
+      int y = (int) Math.round(this.getPreferredSize().getHeight() + 30);
+      if(this.visu==null){
+          graphique = graphique + this.visucoref.getSelection(policeTailleSVG,x,y,policeSVG);
+          y =  y + policeTailleSVG * 7;//on laisse de la place pour le texte
+          y = y + 30;
+      }
+      else{
+          graphique = graphique + this.visu.getSelection(policeTailleSVG,x,y,policeSVG);
+          y =  y + policeTailleSVG * 10;//on laisse de la place pour le texte
+          y = y +30;
+      }
+      int ymax = y;
+      int xtot =  x;
+      if(visu==null){
+          graphique = graphique + "<text x=\""+x+"\" y=\""+(y + policeTailleSVG)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+"Champ 1 :"+
+              "</text>"+System.getProperty("line.separator");
+          graphique = graphique + ecrireSVGLegende(visucoref.getLegende(),x,y+2*policeTailleSVG);
+          ymax = y + visucoref.getLegende().getHeight()+2*policeTailleSVG;
+          xtot = xtot + visucoref.getLegende().getWidth();
+      }
+      else{
+          graphique = graphique + "<text x=\""+x+"\" y=\""+(y + policeTailleSVG)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+"Champ 1 :"+
+              "</text>"+System.getProperty("line.separator");
+          graphique = graphique + ecrireSVGLegende(visu.getLegende(0),x,y+2*policeTailleSVG);
+          x=x+visu.getLegende(0).getWidth() + 40;
+          if(y + visu.getLegende(0).getHeight()+2*policeTailleSVG>ymax){
+              ymax = y + visu.getLegende(0).getHeight()+2*policeTailleSVG;
+          }
+          xtot = xtot + visu.getLegende(0).getWidth();
+          graphique = graphique + "<text x=\""+x+"\" y=\""+(y + policeTailleSVG)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+"Champ 2 :"+
+              "</text>"+System.getProperty("line.separator");
+          graphique = graphique + ecrireSVGLegende(visu.getLegende(1),x,y+2*policeTailleSVG);
+          x=x+visu.getLegende(1).getWidth() + 40;
+          if(y + visu.getLegende(1).getHeight()+2*policeTailleSVG>ymax){
+              ymax = y + visu.getLegende(1).getHeight()+2*policeTailleSVG;
+          }
+          xtot = xtot + visu.getLegende(1).getWidth();
+          graphique = graphique + "<text x=\""+x+"\" y=\""+(y + policeTailleSVG)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+"Champ 3 :"+
+              "</text>"+System.getProperty("line.separator");
+          graphique = graphique + ecrireSVGLegende(visu.getLegende(2),x,y+2*policeTailleSVG);
+          x=x+visu.getLegende(2).getWidth() + 40;
+          if(y + visu.getLegende(2).getHeight()+2*policeTailleSVG>ymax){
+              ymax = y + visu.getLegende(2).getHeight()+2*policeTailleSVG;
+          }
+          xtot = xtot + visu.getLegende(2).getWidth();
+          x= 40;
+          y = ymax +20;
+          graphique = graphique + "<text x=\""+x+"\" y=\""+(y + policeTailleSVG)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+"Champ 4 :"+
+              "</text>"+System.getProperty("line.separator");
+          graphique = graphique + ecrireSVGLegende(visu.getLegende(3),x,y+2*policeTailleSVG);
+          x=x+visu.getLegende(3).getWidth() + 40;
+          if(y + visu.getLegende(3).getHeight()+2*policeTailleSVG>ymax){
+              ymax = y + visu.getLegende(3).getHeight()+2*policeTailleSVG;
+          }
+          graphique = graphique + "<text x=\""+x+"\" y=\""+(y + policeTailleSVG)+"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+policeTailleSVG+"px "+policeSVG+"\">"+"Champ 5 :"+
+              "</text>"+System.getProperty("line.separator");
+          graphique = graphique + ecrireSVGLegende(visu.getLegende(4),x,y+2*policeTailleSVG);
+          if(y + visu.getLegende(4).getHeight()+2*policeTailleSVG>ymax){
+              ymax = y + visu.getLegende(4).getHeight()+2*policeTailleSVG;
+          }
+          xtot = xtot + visu.getLegende(4).getWidth();
+      }
+      String debut = "<?xml version=\"1.0\" standalone=\"no\"?>" +System.getProperty("line.separator")
+             + "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"
+                +System.getProperty("line.separator")+ 
+              "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\""+(Math.round(this.getPreferredSize().getWidth()) <
+              xtot ? xtot : Math.round(this.getPreferredSize().getWidth()))+"\" height=\""+(ymax+100)+"\">"+
+              System.getProperty("line.separator");
+      FichiersGraphique.exporterGChaineSVG(debut + graphique + fin);
+      
+      
+  }
+ 
+}
+ 
+ 

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/GChaines.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuChaines.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuChaines.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuChaines.java	(revision 481)
@@ -0,0 +1,1501 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.chaines;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import org.jfree.chart.ChartPanel;
+import visuAnalec.*;
+import visuAnalec.elements.*;
+import visuAnalec.fichiers.FichiersJava;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.GAction;
+import visuAnalec.util.GVisu.LegendeLabel;
+import visuAnalec.util.GVisu.LegendeModeleTable;
+import visuAnalec.util.GVisu.LegendeModeleTableTexte;
+import visuAnalec.util.GVisu.TypeComboBox;
+import visuAnalec.util.GVisu.Val0ComboBox;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.VueListener;
+
+/**
+ *
+ * @author Bernard
+ */
+public class VisuChaines extends JFrame implements VueListener, ActionListener {
+  private static final int[] seuilsValsNbElts = {3, 10};
+  private static final Color[] couleursNbElts = {Color.WHITE, GVisu.getCouleurSansValeur(),
+    GVisu.getCouleur(0), GVisu.getCouleur(3), GVisu.getCouleur(1)};
+  private static final int[] TaillesNbElts = {1,2,3,4,4};
+  private static final int[] FormesNbElts = {0,1,2,3,4};
+  private static final String[] TexteNbElts = {"00","01","02","03","04"};
+  private final int colwidth = 50;
+  private final int colheight = 30;
+  private static final String[] labelsNbElements = {
+    "pas de chaîne associée",
+    "chaîne d'un seul chaînon",
+    "chaîne de 2-"+Integer.toString(seuilsValsNbElts[0])+" chaînons",
+    "chaîne de "+Integer.toString(seuilsValsNbElts[0]+1)+"-"
+    +Integer.toString(seuilsValsNbElts[1])+"  chaînons",
+    "chaîne de plus de "+Integer.toString(seuilsValsNbElts[1])+" chaînons"
+  };
+  private final Vue vue;
+  private final ModeleChaines donneesChaines;
+  private String typeChaines;
+  private String typeUnites;
+  private String[] valsAffichees;
+  private String[] valsAffichees1;
+  private String[] valsAffichees2;
+  private String[] valsAffichees3;
+  private String[] valsAffichees4;
+  private HashMap<String,HashMap<String,String>> codeLegende = new HashMap();
+  private final TypeComboBox saisieTypeChaines;
+  private final TypeComboBox saisieTypeUnites;
+  private Val0ComboBox saisieChampAffiche;
+  private Val0ComboBox saisieChampAffiche1;  
+  private Val0ComboBox saisieChampAffiche2;
+  private Val0ComboBox saisieChampAffiche3;
+  private Val0ComboBox saisieChampAffiche4;
+  private final JComboBox saisieTailleLigne;
+  private ChartPanel histochaine;
+  /*private JComboBox saisieTailleLigne;*/
+  private JTable legendeChampAffiche;
+  private LegendeModeleTable legendeChampAfficheModele;
+  private JTable legendeChampAffiche1;
+  private LegendeModeleTable legendeChampAfficheModele1;
+  private JTable legendeChampAffiche2;
+  private LegendeModeleTable legendeChampAfficheModele2;
+  private JTable legendeChampAffiche3;
+  private LegendeModeleTableTexte legendeChampAfficheModele3;
+  private JTable legendeChampAffiche4;
+  private LegendeModeleTableTexte legendeChampAfficheModele4;
+  private JPopupMenu popupChamp = new JPopupMenu();
+  private JPopupMenu popupChamp1 = new JPopupMenu();
+  private JPopupMenu popupChamp2 = new JPopupMenu();
+  private JPopupMenu popupChamp3 = new JPopupMenu();
+  private JPopupMenu popupChamp4 = new JPopupMenu();
+  private final GChaines panneauGraphique;//affichage graphique des chaines
+  private final PanneauEditeur panneauEditeur;
+  private final JCheckBox activeCouperParagraphe;
+  private NgrammesPanel ngrammes;
+  private final JSplitPane split2;
+  private final JMenuBar menuBar = new JMenuBar();
+  public VisuChaines(Container fenetre, Vue vue, PanneauEditeur pEditeur) {
+    super("Analyse des suites d'occurences");
+    Point pos = new Point(fenetre.getX()+20, fenetre.getY()+20);
+    Dimension dim = new Dimension(fenetre.getWidth(), fenetre.getHeight());
+    setLocation(pos);
+    setSize(dim);
+    this.vue = vue;
+    vue.addEventListener(this);
+    this.panneauEditeur = pEditeur;
+    saisieTypeChaines = new TypeComboBox(Schema.class);
+    saisieTypeChaines.setModele(vue.getTypesSchemasAVoir());
+    saisieTypeChaines.addActionListener(this);
+    saisieTypeUnites = new TypeComboBox(Unite.class);
+    saisieTypeUnites.setModele(vue.getTypesUnitesAVoir());
+    saisieTypeUnites.addActionListener(this);
+    saisieTailleLigne = new JComboBox(
+            new String[]{"<tous>", "10", "20", "30", "40", "50"});
+    saisieTailleLigne.setEditable(true);
+    saisieTailleLigne.setMaximumSize(getPreferredSize());
+    saisieTailleLigne.addActionListener(this);
+    saisieChampAffiche = new Val0ComboBox("Nombre de chaînons");
+    saisieChampAffiche.addActionListener(this);
+    saisieChampAffiche1 = new Val0ComboBox("Nombre de chaînons");
+    saisieChampAffiche1.addActionListener(this);
+    saisieChampAffiche2 = new Val0ComboBox("Nombre de chaînons");
+    saisieChampAffiche2.addActionListener(this);
+    saisieChampAffiche3 = new Val0ComboBox("Nombre de chaînons");
+    saisieChampAffiche3.addActionListener(this);
+    saisieChampAffiche4 = new Val0ComboBox("Nombre de chaînons");
+    saisieChampAffiche4.addActionListener(this);
+    // Panneau de présentation du graphique
+    JPanel pGraphique = new JPanel(new BorderLayout());
+    Box commandes = Box.createVerticalBox();
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Chaînes : "));
+    commandes.add(saisieTypeChaines);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Unites : "));
+    commandes.add(saisieTypeUnites);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Nb de chainons par ligne : "));
+    commandes.add(saisieTailleLigne);
+    commandes.add(Box.createVerticalGlue());
+    activeCouperParagraphe = new JCheckBox("Ne pas couper ls paragraphes");
+    commandes.add(activeCouperParagraphe);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Champ à afficher : "));
+    commandes.add(saisieChampAffiche);
+    commandes.add(Box.createVerticalGlue());
+    
+    
+    legendeChampAfficheModele = new LegendeModeleTable();
+    legendeChampAffiche = new JTable(new Object[0][0],new String[]{"Icone","Valeur de champ","Fréquence"});
+    legendeChampAffiche.addMouseListener(new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+        check(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInit(legendeChampAffiche.rowAtPoint(e.getPoint()),0);
+          popupChamp.show(legendeChampAffiche, e.getX(), e.getY());
+        }
+      }
+    });
+    
+    commandes.add(legendeChampAffiche);
+    
+    
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Champ à afficher : "));
+    commandes.add(saisieChampAffiche1);
+    commandes.add(Box.createVerticalGlue());
+    
+        legendeChampAfficheModele1 = new LegendeModeleTable();
+        legendeChampAffiche1 = new JTable(legendeChampAfficheModele1);
+    legendeChampAffiche1.addMouseListener(new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+        check(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInit(legendeChampAffiche1.rowAtPoint(e.getPoint()),1);
+          popupChamp1.show(legendeChampAffiche1, e.getX(), e.getY());
+        }
+      }
+    });
+    
+    commandes.add(legendeChampAffiche1);
+    
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Champ à afficher : "));
+    commandes.add(saisieChampAffiche2);
+    commandes.add(Box.createVerticalGlue());
+    
+    legendeChampAfficheModele2 = new LegendeModeleTable();
+    legendeChampAffiche2 = new JTable(legendeChampAfficheModele2);
+    legendeChampAffiche2.addMouseListener(new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+        check(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInit(legendeChampAffiche2.rowAtPoint(e.getPoint()),2);
+          popupChamp2.show(legendeChampAffiche2, e.getX(), e.getY());
+        }
+      }
+    });
+    commandes.add(legendeChampAffiche2);
+    
+        
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Champ à afficher : "));
+    commandes.add(saisieChampAffiche3);
+    commandes.add(Box.createVerticalGlue());
+    
+    legendeChampAfficheModele3 = new LegendeModeleTableTexte();
+    legendeChampAffiche3 = new JTable(legendeChampAfficheModele3);
+    legendeChampAffiche3.addMouseListener(new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+        check(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInit(legendeChampAffiche3.rowAtPoint(e.getPoint()),3);
+          popupChamp3.show(legendeChampAffiche3, e.getX(), e.getY());
+        }
+      }
+    });
+    commandes.add(legendeChampAffiche3);
+    
+        commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Champ à afficher : "));
+    commandes.add(saisieChampAffiche4);
+    commandes.add(Box.createVerticalGlue());
+    
+    legendeChampAfficheModele4 = new LegendeModeleTableTexte();
+    legendeChampAffiche4 = new JTable(legendeChampAfficheModele4);
+    legendeChampAffiche4.addMouseListener(new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+        check(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInit(legendeChampAffiche4.rowAtPoint(e.getPoint()),4);
+          popupChamp4.show(legendeChampAffiche4, e.getX(), e.getY());
+        }
+      }
+    });
+    commandes.add(legendeChampAffiche4);
+    JScrollPane scrollLegende = new JScrollPane(commandes);
+
+    panneauGraphique = new GChaines(this);
+    panneauGraphique.autoriserSousTexte(true);
+    
+    donneesChaines = new ModeleChaines(vue, panneauGraphique);
+    JScrollPane scrollGraphique = new JScrollPane(panneauGraphique);
+    histochaine = Histogramme.histogrammeFactory();
+    this.ngrammes=new NgrammesPanel(vue);
+    JScrollPane scrollstatresultat = new JScrollPane(this.ngrammes);
+    JScrollPane scrollHistogramme = new JScrollPane(histochaine);
+    split2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollHistogramme, scrollstatresultat);
+    JSplitPane split3 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollGraphique, split2);
+    pGraphique.add(split3, BorderLayout.CENTER);  
+    saisieTypeChaines.setAlignmentX(0);
+    saisieTypeUnites.setAlignmentX(0);
+    saisieTailleLigne.setAlignmentX(0);
+    saisieChampAffiche.setAlignmentX(0);
+    saisieChampAffiche1.setAlignmentX(0);
+    saisieChampAffiche2.setAlignmentX(0);
+    saisieChampAffiche3.setAlignmentX(0);
+    saisieChampAffiche4.setAlignmentX(0);
+    legendeChampAffiche.setAlignmentX(0);
+    legendeChampAffiche1.setAlignmentX(0);
+    legendeChampAffiche2.setAlignmentX(0);
+    legendeChampAffiche3.setAlignmentX(0);
+    legendeChampAffiche4.setAlignmentX(0);
+    
+    
+
+    JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,  scrollLegende,pGraphique);
+    getContentPane().add(split);
+    setVisible(true);
+    split.setDividerLocation(1./3);
+    split2.setDividerLocation(1./2);
+    split3.setDividerLocation(1./3);
+    setJMenuBar(menuBar);
+    JMenu corpusMenu = new JMenu("Paramètres d'affichage");
+    menuBar.add(corpusMenu);
+    corpusMenu.add(new GAction("Reprendre un affichage") {
+      @Override
+      public void executer() {
+         importerAffichage();
+      }
+    });
+    corpusMenu.add(new GAction("Sauver les paramètres d'affichage") {
+      @Override
+      public void executer() {
+         exporterAffichage();
+      }
+    });   
+    JMenu csvMenu = new JMenu("Exporter les données");
+    menuBar.add(csvMenu);
+    final VisuChaines visu = this;
+    final Vue vues = this.vue;
+    final PanneauEditeur pEditeurs = pEditeur;
+    csvMenu.add(new GAction("Exporter les données de filtrage") {
+      @Override
+      public void executer() {
+          new ExportCSV(getContentPane(),vues,pEditeurs,visu);
+      }
+    });
+    csvMenu.add(new GAction("Exporter le tableau statistique") {
+      @Override
+      public void executer() {
+             ExportCSV.exporterCSV(ngrammes.donneesCSV());
+      }
+    });
+    csvMenu.add(new GAction("Exporter les fréquences pour le champ1") {
+      public void executer() {
+          Object[][] donneesCSV = new Object[legendeChampAffiche.getRowCount()+1][2];
+         for(int i = 0 ; i < legendeChampAffiche.getRowCount();i++){
+                donneesCSV[i+1][0]=legendeChampAffiche.getValueAt(i, 1);
+                donneesCSV[i+1][1]=legendeChampAffiche.getValueAt(i, 2)==null ? "0" 
+                        : legendeChampAffiche.getValueAt(i, 2);
+         }
+                donneesCSV[0][1]="frequence";
+                donneesCSV[0][0]=saisieChampAffiche.pasdeSelection() ? "Nombre de Chainons"
+                        : saisieChampAffiche.getSelection();
+             ExportCSV.exporterCSV(donneesCSV);
+      }
+    });
+    csvMenu.add(new GAction("Exporter les fréquences pour le champ2") {
+      @Override
+      public void executer() {
+          Object[][] donneesCSV = new Object[legendeChampAffiche1.getRowCount()+1][2];
+         for(int i = 0 ; i < legendeChampAffiche1.getRowCount();i++){
+                donneesCSV[i+1][0]=legendeChampAffiche1.getValueAt(i, 1);
+                donneesCSV[i+1][1]=legendeChampAffiche1.getValueAt(i, 2)==null ? "0" 
+                        : legendeChampAffiche1.getValueAt(i, 2);
+         }
+                donneesCSV[0][1]="frequence";
+                donneesCSV[0][0]=saisieChampAffiche1.pasdeSelection() ? "Nombre de Chainons"
+                        : saisieChampAffiche1.getSelection();
+             ExportCSV.exporterCSV(donneesCSV);
+      }
+    });
+    csvMenu.add(new GAction("Exporter les fréquences pour le champ3") {
+      @Override
+      public void executer() {
+          Object[][] donneesCSV = new Object[legendeChampAffiche2.getRowCount()+1][2];
+         for(int i = 0 ; i < legendeChampAffiche2.getRowCount();i++){
+                donneesCSV[i+1][0]=legendeChampAffiche2.getValueAt(i, 1);
+                donneesCSV[i+1][1]=legendeChampAffiche2.getValueAt(i, 2)==null ? "0" 
+                        : legendeChampAffiche2.getValueAt(i, 2);
+         }
+                donneesCSV[0][1]="frequence";
+                donneesCSV[0][0]=saisieChampAffiche2.pasdeSelection() ? "Nombre de Chainons"
+                        : saisieChampAffiche2.getSelection();
+             ExportCSV.exporterCSV(donneesCSV);
+      }
+    }); 
+    csvMenu.add(new GAction("Exporter les fréquences pour le champ4") {
+      @Override
+      public void executer() {
+          Object[][] donneesCSV = new Object[legendeChampAffiche3.getRowCount()+1][2];
+         for(int i = 0 ; i < legendeChampAffiche3.getRowCount();i++){
+                donneesCSV[i+1][0]=legendeChampAffiche3.getValueAt(i, 1);
+                donneesCSV[i+1][1]=legendeChampAffiche3.getValueAt(i, 2)==null ? "0" 
+                        : legendeChampAffiche3.getValueAt(i, 2);
+         }
+                donneesCSV[0][1]="frequence";
+                donneesCSV[0][0]=saisieChampAffiche3.pasdeSelection() ? "Nombre de Chainons"
+                        : saisieChampAffiche3.getSelection();
+             ExportCSV.exporterCSV(donneesCSV);
+      }
+    }); 
+    csvMenu.add(new GAction("Exporter les fréquences pour le champ5") {
+      @Override
+      public void executer() {
+          Object[][] donneesCSV = new Object[legendeChampAffiche4.getRowCount()+1][2];
+         for(int i = 0 ; i < legendeChampAffiche4.getRowCount();i++){
+                donneesCSV[i+1][0]=legendeChampAffiche4.getValueAt(i, 1);
+                donneesCSV[i+1][1]=legendeChampAffiche4.getValueAt(i, 2)==null ? "0" 
+                        : legendeChampAffiche4.getValueAt(i, 2);
+         }
+                donneesCSV[0][1]="frequence";
+                donneesCSV[0][0]=saisieChampAffiche4.pasdeSelection() ? "Nombre de Chainons"
+                        : saisieChampAffiche4.getSelection();
+             ExportCSV.exporterCSV(donneesCSV);
+      }
+    });        
+    
+    // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+    // Initialisation
+    saisieTailleLigne.removeActionListener(this);
+    saisieTailleLigne.setSelectedIndex(0);
+    saisieTailleLigne.addActionListener(this);
+    saisieTailleLigne.setMaximumSize(getPreferredSize());
+    if (saisieTypeChaines.nbItems()==1) {
+      saisieTypeChaines.setSelection(0);
+      if (saisieTypeUnites.nbItems()==1) saisieTypeUnites.setSelection(0);
+      else saisieTypeUnites.effSelection();
+    } else {
+      saisieTypeChaines.effSelection();
+      saisieTypeUnites.effSelection();
+    }
+  }
+
+  private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+  }
+  @Override
+  public void traiterEvent(Message evt) { // très grossier : à améliorer
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre chaines présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        fermerFenetre();
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        fermerFenetre();
+        return;
+      case MODIF_ELEMENT:
+//        ElementEvent evtE = (ElementEvent) evt;
+//        if (evtE.getModif() != TypeModifElement.BORNES_UNITE) fermerFenetre();
+        fermerFenetre();
+        return;
+      case CORPUS_SAVED:
+          fermerFenetre();
+          return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+
+  @Override
+  public void actionPerformed(ActionEvent evt) {
+    try {
+        panneauGraphique.setcouperparagraphe(activeCouperParagraphe.isSelected());
+      if (evt.getSource().equals(saisieTypeChaines)
+              ||evt.getSource().equals(saisieTypeUnites)) {
+        if (saisieTypeChaines.pasdeSelection()||saisieTypeUnites.pasdeSelection()) {
+          initVide();
+          return;
+        }
+        try {
+          init();
+        } catch (UnsupportedOperationException ex) {
+          GMessages.impossibiliteAction("Erreur de type : "+ex.getMessage());
+          initVide();
+          return;
+        }
+        return;
+      }
+      if (evt.getSource().equals(saisieChampAffiche)) {
+        if(!saisieTypeChaines.pasdeSelection()&&!saisieTypeUnites.pasdeSelection()){
+            if (saisieChampAffiche.pasdeSelection()) initCouleursNbElts();
+            else initCouleursChamp(saisieChampAffiche.getSelection());
+        }
+        return;
+      }
+    if (evt.getSource().equals(saisieChampAffiche1)) {
+        if(!saisieTypeChaines.pasdeSelection()&&!saisieTypeUnites.pasdeSelection()){
+            if (saisieChampAffiche1.pasdeSelection()) initFormesNbElts();
+            else initFormesChamp(saisieChampAffiche1.getSelection());
+        }
+        return;
+      }
+      if (evt.getSource().equals(saisieChampAffiche2)) {
+        if(!saisieTypeChaines.pasdeSelection()&&!saisieTypeUnites.pasdeSelection()){
+            if (saisieChampAffiche2.pasdeSelection()) initTaillesNbElts();
+            else initTaillesChamp(saisieChampAffiche2.getSelection());
+          }
+        return;
+      }
+      if (evt.getSource().equals(saisieChampAffiche3)) {
+        if(!saisieTypeChaines.pasdeSelection()&&!saisieTypeUnites.pasdeSelection()){
+            if (saisieChampAffiche3.pasdeSelection()) initSurTexteNbElts();
+            else initSurTexteChamp(saisieChampAffiche3.getSelection());
+          }
+        return;
+      }
+      if (evt.getSource().equals(saisieChampAffiche4)) {
+        if(!saisieTypeChaines.pasdeSelection()&&!saisieTypeUnites.pasdeSelection()){
+            if (saisieChampAffiche4.pasdeSelection()) initSousTexteNbElts();
+            else initSousTexteChamp(saisieChampAffiche4.getSelection());
+        }
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  private void initVide() {
+    typeChaines = null;
+    typeUnites = null;
+    donneesChaines.initVide();
+    saisieChampAffiche.setModeleVide();
+    saisieChampAffiche1.setModeleVide();
+    saisieChampAffiche2.setModeleVide();
+    saisieChampAffiche3.setModeleVide();
+    saisieChampAffiche4.setModeleVide();
+    this.ngrammes.init();
+    legendeChampAfficheModele = new LegendeModeleTable(new String[]{"icone","nom du champ","frequence"},new LegendeLabel[0],new HashMap());
+    legendeChampAffiche.setModel(legendeChampAfficheModele);
+    legendeChampAfficheModele1 = new LegendeModeleTable(new String[]{"icone","nom du champ","frequence"},new LegendeLabel[0],new HashMap());
+    legendeChampAffiche1.setModel(legendeChampAfficheModele1);
+    legendeChampAfficheModele2 = new LegendeModeleTable(new String[]{"icone","nom du champ","frequence"},new LegendeLabel[0],new HashMap());
+    legendeChampAffiche2.setModel(legendeChampAfficheModele2);
+    legendeChampAfficheModele3 = new LegendeModeleTableTexte(new String[]{"Symbole","nom du champ","frequence"},new LegendeLabel[0],new HashMap());
+    legendeChampAffiche3.setModel(legendeChampAfficheModele3);
+    legendeChampAfficheModele4 = new LegendeModeleTableTexte(new String[]{"Symbole","nom du champ","frequence"},new LegendeLabel[0],new HashMap());
+    legendeChampAffiche4.setModel(legendeChampAfficheModele4);
+  }
+  private void init() throws UnsupportedOperationException {
+    typeChaines = saisieTypeChaines.getTypeSelection();
+    typeUnites = saisieTypeUnites.getTypeSelection();
+    donneesChaines.init(typeChaines, typeUnites, seuilsValsNbElts);
+    initCouleursNbElts();
+    initTaillesNbElts();
+    initFormesNbElts();
+    initSurTexteNbElts();
+    initSousTexteNbElts();
+    saisieChampAffiche.removeActionListener(this);
+    saisieChampAffiche.setModele(vue.getNomsChamps(Unite.class, typeUnites));
+    saisieChampAffiche.addActionListener(this);
+    saisieChampAffiche1.removeActionListener(this);
+    saisieChampAffiche1.setModele(vue.getNomsChamps(Unite.class, typeUnites));
+    saisieChampAffiche1.addActionListener(this);
+    saisieChampAffiche2.removeActionListener(this);
+    saisieChampAffiche2.setModele(vue.getNomsChamps(Unite.class, typeUnites));
+    saisieChampAffiche2.addActionListener(this);
+    saisieChampAffiche3.removeActionListener(this);
+    saisieChampAffiche3.setModele(vue.getNomsChamps(Unite.class, typeUnites));
+    saisieChampAffiche3.addActionListener(this);
+    saisieChampAffiche4.removeActionListener(this);
+    saisieChampAffiche4.setModele(vue.getNomsChamps(Unite.class, typeUnites));
+    saisieChampAffiche4.addActionListener(this);
+    Histogramme.updatePanel(histochaine,"Titre",donneesChaines,10,Color.BLUE,200,
+            "position de l'unité","Fréquence d'unités",vue);
+    this.ngrammes.setDonneesChaines(donneesChaines);
+    this.ngrammes.setTypeChaines(typeChaines);
+    this.ngrammes.setTypeUnites(typeUnites);
+    this.ngrammes.update();
+    
+    
+
+  }
+  private void initCouleursNbElts() {
+    HashMap<String, Float> freq = donneesChaines.calculerfrequencenbelt
+        (donneesChaines.getUnites(),typeUnites, labelsNbElements); 
+    donneesChaines.setChampAfficheNbElts(couleursNbElts);
+    legendeChampAfficheModele = new LegendeModeleTable(new String[]{"icone","nom du champ","frequence"},creerLegendesNbElements(),freq);
+    legendeChampAffiche.setModel(legendeChampAfficheModele);
+    legendeChampAffiche.getColumnModel().getColumn(0).setMaxWidth(colwidth);    
+    legendeChampAffiche.getColumnModel().getColumn(2).setMaxWidth(colwidth);
+    legendeChampAffiche.setRowHeight(colheight);
+  }
+
+  private void initTaillesNbElts() {
+    HashMap<String, Float> freq = donneesChaines.calculerfrequencenbelt
+        (donneesChaines.getUnites(),typeUnites, labelsNbElements);       
+    donneesChaines.setChampAfficheTailleNbElts(TaillesNbElts);
+    legendeChampAfficheModele2 = new LegendeModeleTable(new String[]{"icone","nom du champ","frequence"},creerLegendesTailleNbElements(),freq);
+    Histogramme.updatePanel(histochaine,"Titre",donneesChaines,10,Color.BLUE,200,
+            "position de l'unité","Fréquence d'unités",vue);
+    legendeChampAffiche2.setModel(legendeChampAfficheModele2);
+    legendeChampAffiche2.getColumnModel().getColumn(0).setMaxWidth(colwidth);    
+    legendeChampAffiche2.getColumnModel().getColumn(2).setMaxWidth(colwidth);
+    legendeChampAffiche2.setRowHeight(colheight);
+  }
+  private void initFormesNbElts() {
+    HashMap<String, Float> freq = donneesChaines.calculerfrequencenbelt
+        (donneesChaines.getUnites(),typeUnites, labelsNbElements);       
+    donneesChaines.setChampAfficheFormeNbElts(FormesNbElts);
+    legendeChampAfficheModele1 = new LegendeModeleTable(new String[]{"icone","nom du champ","frequence"},creerLegendesFormeNbElements(),freq);
+    legendeChampAffiche1.setModel(legendeChampAfficheModele1);
+    legendeChampAffiche1.getColumnModel().getColumn(0).setMaxWidth(colwidth);    
+    legendeChampAffiche1.getColumnModel().getColumn(2).setMaxWidth(colwidth);
+    legendeChampAffiche1.setRowHeight(colheight);
+  }
+  private void initSurTexteNbElts() {
+    HashMap<String, Float> freq = donneesChaines.calculerfrequencenbelt
+        (donneesChaines.getUnites(),typeUnites, labelsNbElements);       
+    donneesChaines.setChampAfficheSurTexteNbElts(TexteNbElts);
+    legendeChampAfficheModele3 = new LegendeModeleTableTexte(new String[]{"symbole","nom du champ","frequence"},creerLegendesSurTexteNbElements(),freq);
+    legendeChampAffiche3.setModel(legendeChampAfficheModele3);
+    legendeChampAffiche3.getColumnModel().getColumn(0).setMaxWidth(colwidth);    
+    legendeChampAffiche3.getColumnModel().getColumn(2).setMaxWidth(colwidth);
+  }
+    private void initSousTexteNbElts() {
+    HashMap<String, Float> freq = donneesChaines.calculerfrequencenbelt
+        (donneesChaines.getUnites(),typeUnites, labelsNbElements);       
+    donneesChaines.setChampAfficheSousTexteNbElts(TexteNbElts);
+    legendeChampAfficheModele4 = new LegendeModeleTableTexte(new String[]{"symbole","nom du champ","frequence"},creerLegendesSousTexteNbElements(),freq);
+    legendeChampAffiche4.setModel(legendeChampAfficheModele4);
+    legendeChampAffiche4.getColumnModel().getColumn(0).setMaxWidth(colwidth);    
+    legendeChampAffiche4.getColumnModel().getColumn(2).setMaxWidth(colwidth);
+  }
+  
+  private LegendeLabel[] creerLegendesNbElements() {
+    LegendeLabel[] legendes = new LegendeLabel[couleursNbElts.length];
+    for (int i = 0; i<legendes.length; i++)
+      legendes[i] = new LegendeLabel(labelsNbElements[i],
+              donneesChaines.isMasqueeValNbElements(i) ? null : couleursNbElts[i]);
+    return legendes;
+  }
+  private LegendeLabel[] creerLegendesFormeNbElements() {
+    LegendeLabel[] legendes = new LegendeLabel[FormesNbElts.length];
+    for (int i = 0; i<legendes.length; i++)
+      legendes[i] = new LegendeLabel(labelsNbElements[i]
+              ,Color.WHITE,1,(donneesChaines.isMasqueeValNbElements(i) ? -1 : FormesNbElts[i]),12,2);
+    return legendes;
+  }
+  private LegendeLabel[] creerLegendesTailleNbElements() {
+    LegendeLabel[] legendes = new LegendeLabel[TaillesNbElts.length];
+    for (int i = 0; i<legendes.length; i++)
+      legendes[i] = new LegendeLabel(labelsNbElements[i]
+              ,Color.WHITE,donneesChaines.isMasqueeValNbElements(i) ? -1 : TaillesNbElts[i],0,12,2);
+    return legendes;
+  }
+
+  private LegendeLabel[] creerLegendesSurTexteNbElements() {
+    LegendeLabel[] legendes = new LegendeLabel[TexteNbElts.length];
+    for (int i = 0; i<legendes.length; i++)
+      legendes[i] = new LegendeLabel(labelsNbElements[i]
+              ,donneesChaines.isMasqueeValNbElements(i) ? null : TexteNbElts[i]);
+    return legendes;
+  }
+    
+  private LegendeLabel[] creerLegendesSousTexteNbElements() {
+    LegendeLabel[] legendes = new LegendeLabel[TexteNbElts.length];
+    for (int i = 0; i<legendes.length; i++)
+      legendes[i] = new LegendeLabel(labelsNbElements[i]
+              ,donneesChaines.isMasqueeValNbElements(i) ? null : TexteNbElts[i]);
+    return legendes;
+  }
+  
+  
+  private void initCouleursChamp(String champ) {
+    valsAffichees = vue.getValeursChamp(Unite.class, typeUnites, champ);
+    HashMap<String, Float> freq = ChaineUtil.calculerfrequencechamp
+        (donneesChaines.getUnites(),typeUnites, champ,vue);
+    ChaineUtil.triFusionMap(valsAffichees,freq);
+    HashMap<String, Color> couleursValeursChamp = new HashMap<String, Color>();
+    for (int i = 0, nocolor = 0; i<valsAffichees.length; i++)
+      if (!donneesChaines.isMasqueeValChamp(champ, valsAffichees[i]))
+        couleursValeursChamp.put(valsAffichees[i], GVisu.getCouleur(nocolor++));
+    if (!donneesChaines.isMasqueeValNulleChamp(champ))
+      couleursValeursChamp.put("", GVisu.getCouleurSansValeur());
+    donneesChaines.setChampAffiche(champ, couleursValeursChamp);
+    legendeChampAfficheModele = new LegendeModeleTable(new String[]{"icone","nom du champ","frequence"},creerLegendesChamp(valsAffichees,
+            couleursValeursChamp),freq);
+    legendeChampAffiche.setModel(legendeChampAfficheModele);
+    legendeChampAffiche.getColumnModel().getColumn(0).setMaxWidth(colwidth);    
+    legendeChampAffiche.getColumnModel().getColumn(2).setMaxWidth(colwidth);
+    legendeChampAffiche.setRowHeight(colheight);
+  }
+  
+   private void initTaillesChamp(String champ) {
+    valsAffichees2 = vue.getValeursChamp(Unite.class, typeUnites, champ);
+    HashMap<String, Float> freq = ChaineUtil.calculerfrequencechamp
+        (donneesChaines.getUnites(),typeUnites, champ,vue);
+    ChaineUtil.triFusionMap(valsAffichees2,freq);
+    HashMap<String, Integer> TaillesValeursChamp = new HashMap<String, Integer>();
+    for (int i = 0, nocolor = 0; i<valsAffichees2.length; i++)
+      if (!donneesChaines.isMasqueeValChamp(champ, valsAffichees2[i]))
+        TaillesValeursChamp.put(valsAffichees2[i], GVisu.getTaille(nocolor++));
+    if (!donneesChaines.isMasqueeValNulleChamp(champ))
+      TaillesValeursChamp.put("", GVisu.getTailleSansValeur());
+    donneesChaines.setChampAfficheTaille(champ, TaillesValeursChamp);
+    legendeChampAfficheModele2 = new LegendeModeleTable(new String[]{"icone","nom du champ","frequence"},creerLegendesChampTaille(valsAffichees2,
+            TaillesValeursChamp),freq);    
+    Histogramme.updatePanel(histochaine,"Titre",donneesChaines,10,Color.BLUE,200,
+            "position de l'unité","Fréquence d'unités",vue);
+    legendeChampAffiche2.setModel(legendeChampAfficheModele2);
+    legendeChampAffiche2.getColumnModel().getColumn(0).setMaxWidth(colwidth);    
+    legendeChampAffiche2.getColumnModel().getColumn(2).setMaxWidth(colwidth);
+    legendeChampAffiche2.setRowHeight(colheight);
+  }
+   
+   private void initFormesChamp(String champ) {
+    valsAffichees1 = vue.getValeursChamp(Unite.class, typeUnites, champ);
+    HashMap<String, Float> freq = ChaineUtil.calculerfrequencechamp
+        (donneesChaines.getUnites(),typeUnites, champ,vue);
+    ChaineUtil.triFusionMap(valsAffichees1,freq);
+    HashMap<String, Integer> FormesValeursChamp = new HashMap<String, Integer>();
+    for (int i = 0, nocolor = 0; i<valsAffichees1.length; i++)
+      if (!donneesChaines.isMasqueeValChamp(champ, valsAffichees1[i]))
+        FormesValeursChamp.put(valsAffichees1[i], GVisu.getForme(nocolor++));
+    if (!donneesChaines.isMasqueeValNulleChamp(champ))
+      FormesValeursChamp.put("", GVisu.getFormeSansValeur());
+    donneesChaines.setChampAfficheForme(champ, FormesValeursChamp);
+       legendeChampAfficheModele1 = new LegendeModeleTable(new String[]{"icone","nom du champ","frequence"},creerLegendesChampForme(valsAffichees1,
+            FormesValeursChamp),freq);
+       legendeChampAffiche1.setModel(legendeChampAfficheModele1);
+    legendeChampAffiche1.getColumnModel().getColumn(0).setMaxWidth(colwidth);    
+    legendeChampAffiche1.getColumnModel().getColumn(2).setMaxWidth(colwidth);
+    legendeChampAffiche1.setRowHeight(colheight);
+  }
+   
+  private void initSurTexteChamp(String champ) {
+    valsAffichees3 = vue.getValeursChamp(Unite.class, typeUnites, champ);
+    HashMap<String, Float> freq = ChaineUtil.calculerfrequencechamp
+        (donneesChaines.getUnites(),typeUnites, champ,vue);
+    ChaineUtil.triFusionMap(valsAffichees3,freq);
+    HashMap<String, String> SurTexteValeursChamp = new HashMap<String, String>();
+    for (int i = 0, nocolor = 0; i<valsAffichees3.length; i++)
+      if (!donneesChaines.isMasqueeValChamp(champ, valsAffichees3[i]))
+        SurTexteValeursChamp.put(valsAffichees3[i],codeLegende.containsKey(champ) && 
+                codeLegende.get(champ).containsKey(valsAffichees3[i]) ? codeLegende.get(champ).get(valsAffichees3[i])
+                : GVisu.getTexte(nocolor++));
+    if (!donneesChaines.isMasqueeValNulleChamp(champ))
+      SurTexteValeursChamp.put("",codeLegende.containsKey(champ) && 
+                codeLegende.get(champ).containsKey("") ? codeLegende.get(champ).get("")
+                : GVisu.getTexteSansValeur());
+    donneesChaines.setChampAfficheSurTexte(champ, SurTexteValeursChamp);
+       legendeChampAfficheModele3 = new LegendeModeleTableTexte(new String[]{"symbole","nom du champ","frequence"},creerLegendesChampSurTexte(valsAffichees3,
+            SurTexteValeursChamp),freq);
+       legendeChampAffiche3.setModel(legendeChampAfficheModele3);
+    legendeChampAffiche3.getColumnModel().getColumn(0).setMaxWidth(colwidth);    
+    legendeChampAffiche3.getColumnModel().getColumn(2).setMaxWidth(colwidth);
+  }
+   
+  private void initSousTexteChamp(String champ) {
+    valsAffichees4 = vue.getValeursChamp(Unite.class, typeUnites, champ);
+    HashMap<String, Float> freq = ChaineUtil.calculerfrequencechamp
+        (donneesChaines.getUnites(),typeUnites, champ,vue);
+    ChaineUtil.triFusionMap(valsAffichees4,freq);
+    HashMap<String, String> SousTexteValeursChamp = new HashMap<String, String>();
+    for (int i = 0, nocolor = 0; i<valsAffichees4.length; i++)
+      if (!donneesChaines.isMasqueeValChamp(champ, valsAffichees4[i]))
+        SousTexteValeursChamp.put(valsAffichees4[i], codeLegende.containsKey(champ) && 
+                codeLegende.get(champ).containsKey(valsAffichees4[i]) ? codeLegende.get(champ).get(valsAffichees4[i])
+                : GVisu.getTexte(nocolor++));
+    if (!donneesChaines.isMasqueeValNulleChamp(champ))
+      SousTexteValeursChamp.put("", codeLegende.containsKey(champ) && 
+                codeLegende.get(champ).containsKey("") ? codeLegende.get(champ).get("")
+                : GVisu.getTexteSansValeur());
+    donneesChaines.setChampAfficheSousTexte(champ, SousTexteValeursChamp);
+       legendeChampAfficheModele4 = new LegendeModeleTableTexte(new String[]{"symbole","nom du champ","frequence"},creerLegendesChampSousTexte(valsAffichees4,
+            SousTexteValeursChamp),freq);
+       legendeChampAffiche4.setModel(legendeChampAfficheModele4);
+    legendeChampAffiche4.getColumnModel().getColumn(0).setMaxWidth(colwidth);    
+    legendeChampAffiche4.getColumnModel().getColumn(2).setMaxWidth(colwidth);
+  }
+  
+  
+  private LegendeLabel[] creerLegendesChamp(String[] valsAffichees,
+          HashMap<String, Color> couleursValeursChamp) {
+    LegendeLabel[] legendes = new LegendeLabel[valsAffichees.length+1];
+    for (int i = 0; i<valsAffichees.length; i++)
+      legendes[i] = new LegendeLabel(valsAffichees[i],
+              couleursValeursChamp.get(valsAffichees[i]));
+    legendes[valsAffichees.length] = new LegendeLabel("<aucune valeur>",
+            couleursValeursChamp.get(""));
+    return legendes;
+  }
+  
+  private LegendeLabel[] creerLegendesChampTaille(String[] valsAffichees,
+          HashMap<String, Integer> TaillesValeursChamp) {
+    LegendeLabel[] legendes = new LegendeLabel[valsAffichees.length+1];
+    for (int i = 0; i<valsAffichees.length; i++)
+      legendes[i] = new LegendeLabel(valsAffichees[i],Color.WHITE,
+              donneesChaines.isMasqueeValChamp(saisieChampAffiche2.getSelection(),
+                      valsAffichees[i]) ? -1 : (TaillesValeursChamp.get(valsAffichees[i])),0,12,2);
+    legendes[valsAffichees.length] = new LegendeLabel("<aucune valeur>",Color.WHITE,
+            donneesChaines.isMasqueeValNulleChamp(saisieChampAffiche2.getSelection()) ? -1 
+                    : (TaillesValeursChamp.get("")),0,6,2);
+    return legendes;
+  }
+  
+  private LegendeLabel[] creerLegendesChampForme(String[] valsAffichees,
+          HashMap<String, Integer> FormesValeursChamp) {
+    LegendeLabel[] legendes = new LegendeLabel[valsAffichees.length+1];
+    for (int i = 0; i<valsAffichees.length; i++)
+      legendes[i] = new LegendeLabel(valsAffichees[i],Color.WHITE,1,
+              donneesChaines.isMasqueeValChamp(saisieChampAffiche1.getSelection(),
+                      valsAffichees[i]) ? -1 : (FormesValeursChamp.get(valsAffichees[i])),12,2);
+    legendes[valsAffichees.length] = new LegendeLabel("<aucune valeur>",Color.WHITE,1,
+            donneesChaines.isMasqueeValNulleChamp(saisieChampAffiche1.getSelection()) ? -1 
+                    : (FormesValeursChamp.get("")),12,2);
+    return legendes;
+  }  
+  
+  private LegendeLabel[] creerLegendesChampSurTexte(String[] valsAffichees,
+          HashMap<String, String> SurTexteValeursChamp) {
+    LegendeLabel[] legendes = new LegendeLabel[valsAffichees.length+1];
+    for (int i = 0; i<valsAffichees.length; i++)
+      legendes[i] = new LegendeLabel(valsAffichees[i],
+              donneesChaines.isMasqueeValChamp(saisieChampAffiche3.getSelection(),
+                      valsAffichees[i]) ? "" : (SurTexteValeursChamp.get(valsAffichees[i])));
+    legendes[valsAffichees.length] = new LegendeLabel("<aucune valeur>",
+            donneesChaines.isMasqueeValNulleChamp(saisieChampAffiche3.getSelection()) ? "" 
+                    : (SurTexteValeursChamp.get("")));
+    return legendes;
+  }  
+  private LegendeLabel[] creerLegendesChampSousTexte(String[] valsAffichees,
+          HashMap<String, String> SousTexteValeursChamp) {
+    LegendeLabel[] legendes = new LegendeLabel[valsAffichees.length+1];
+    for (int i = 0; i<valsAffichees.length; i++)
+      legendes[i] = new LegendeLabel(valsAffichees[i],
+              donneesChaines.isMasqueeValChamp(saisieChampAffiche4.getSelection(),
+                      valsAffichees[i]) ? "" : (SousTexteValeursChamp.get(valsAffichees[i])));
+    legendes[valsAffichees.length] = new LegendeLabel("<aucune valeur>",
+            donneesChaines.isMasqueeValNulleChamp(saisieChampAffiche4.getSelection()) ? "" 
+                    : (SousTexteValeursChamp.get("")));
+    return legendes;
+  }  
+ 
+  private void popupChampInit(final int index, final int champ) {  
+    final boolean masquee;
+    String[] vals;
+    Val0ComboBox zonedesaisie;
+    JPopupMenu popup;
+    switch(champ){
+        case 0 :
+            vals = valsAffichees;
+            zonedesaisie = saisieChampAffiche;
+            popup = popupChamp;
+            break;
+        case 1 :
+            vals = valsAffichees1;
+            zonedesaisie = saisieChampAffiche1;
+            popup = popupChamp1;            
+            break;
+        case 2 :
+            vals = valsAffichees2;
+            zonedesaisie = saisieChampAffiche2;
+            popup = popupChamp2;            
+            break;
+        case 3 :
+            vals = valsAffichees3;
+            zonedesaisie = saisieChampAffiche3;
+            popup = popupChamp3;            
+            break;
+        case 4 :
+            vals = valsAffichees4;
+            zonedesaisie = saisieChampAffiche4;
+            popup = popupChamp4;            
+            break;
+        default:
+            vals = new String[0];
+            zonedesaisie = new Val0ComboBox("Nombre de chaînons");
+            popup = new JPopupMenu();                 
+            break;
+    }
+    popup.removeAll();
+    if (zonedesaisie.pasdeSelection()) {
+      masquee = donneesChaines.isMasqueeValNbElements(index);
+      popup.add(new GAction(masquee ? "Montrer cette valeur" : 
+              "Masquer cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValNbElements(masquee, index, false,champ);
+        }
+      });
+      popup.add(new GAction(masquee ? "Montrer toutes les valeurs" : 
+              "Ne montrer que cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValNbElements(masquee, index, true,champ);
+        }
+      });
+    } else if (index==vals.length) {
+      masquee = donneesChaines.isMasqueeValNulleChamp(zonedesaisie.getSelection());
+      popup.add(new GAction(masquee ? "Montrer cette valeur" : 
+              "Masquer cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValNulleChamp(masquee, false,champ);
+        }
+      });
+     popup.add(new GAction(masquee ? "Montrer toutes les valeurs" : 
+              "Ne montrer que cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValNulleChamp(masquee, true,champ);
+        }
+      });
+     if(champ == 3 || champ == 4){
+        popup.add(new GAction("Changer le code de la légende") {
+           @Override
+           public void executer() {
+             changerCodeTexte(index,champ);
+           }
+         });         
+     }
+    } else {
+      masquee = donneesChaines.isMasqueeValChamp(zonedesaisie.getSelection(),
+              vals[index]);
+      popup.add(new GAction(masquee ? "Montrer cette valeur" : 
+              "Masquer cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValChamp(masquee, index, false,champ);
+        }
+      });
+      popup.add(new GAction(masquee ? "Montrer toutes les valeurs" : 
+              "Ne montrer que cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValChamp(masquee, index, true,champ);
+        }
+      });
+     if(champ == 3 || champ == 4){
+        popup.add(new GAction("Changer le code de la légende") {
+           @Override
+           public void executer() {
+             changerCodeTexte(index,champ);
+           }
+         });         
+     }
+    }
+    
+  }
+  //il doit y avoir une saisie pour saisieChampAffiche3 ou pour saisieChampAffiche4
+  private void changerCodeTexte(int index, int noLegende){
+    JOptionPane saisieCode = new JOptionPane();
+    String ValAffichees;
+    Val0ComboBox saisiechampaffiche;
+    switch(noLegende){
+        case 3 :
+            saisiechampaffiche = saisieChampAffiche3;
+            ValAffichees = this.valsAffichees3[index];
+            break;
+        default :
+            saisiechampaffiche = saisieChampAffiche4;
+            ValAffichees = this.valsAffichees4[index];
+            break;
+    }
+    String code = saisieCode.showInputDialog(null, "Veuillez saisir un code légende d'au plus trois caractères", 
+            "Changer le code", JOptionPane.QUESTION_MESSAGE);
+    if(code!=null){
+        code = code.length() > 3 ? code.substring(0, 2) : code;
+        if(!codeLegende.containsKey(saisiechampaffiche.getSelection())){
+            codeLegende.put(saisiechampaffiche.getSelection(),new HashMap());
+        }
+        codeLegende.get(saisiechampaffiche.getSelection()).put(ValAffichees,code);
+        initSurTexteChamp(saisieChampAffiche3.getSelection());
+        initSousTexteChamp(saisieChampAffiche4.getSelection());
+    }
+  }
+  private void modifierStatutValChamp(boolean masquee, int index, boolean tous, int source) {
+      String[] vals;
+      Val0ComboBox zonedesaisie;
+      switch(source){
+          case 0:
+              vals = valsAffichees;
+              zonedesaisie = saisieChampAffiche;
+              break;
+          case 1:
+              vals = valsAffichees1;
+              zonedesaisie = saisieChampAffiche1;              
+              break;
+          case 2:
+              vals = valsAffichees2;
+              zonedesaisie = saisieChampAffiche2;                 
+              break;
+          case 3 :
+            vals = valsAffichees3;
+            zonedesaisie = saisieChampAffiche3;  
+            break;
+          case 4 :
+            vals = valsAffichees4;
+            zonedesaisie = saisieChampAffiche4;      
+            break;
+          default :
+              vals = new String[0];
+              zonedesaisie = new Val0ComboBox("Nombre de chaînons");                 
+              break;
+      }
+    if(!tous) donneesChaines.masquerValChamp(!masquee, 
+            zonedesaisie.getSelection(), vals[index]);
+    else if(masquee) donneesChaines.demasquerToutesValsChamp( 
+            zonedesaisie.getSelection());
+    else donneesChaines.masquerAutresValsChamp(typeUnites, 
+            zonedesaisie.getSelection(), vals[index]);
+    donneesChaines.modifMasqueVals(typeChaines, typeUnites);
+    if(saisieChampAffiche.pasdeSelection()){
+        initCouleursNbElts();
+    }
+    else{
+        initCouleursChamp(saisieChampAffiche.getSelection());
+    }
+    if(saisieChampAffiche1.pasdeSelection()){
+        initFormesNbElts();
+    }
+    else{
+        initFormesChamp(saisieChampAffiche1.getSelection());
+    }
+    if(saisieChampAffiche2.pasdeSelection()){
+        initTaillesNbElts();
+    }
+    else{
+        initTaillesChamp(saisieChampAffiche2.getSelection());
+    }
+    if(saisieChampAffiche3.pasdeSelection()){
+        initSurTexteNbElts();
+    }
+    else{
+        initSurTexteChamp(saisieChampAffiche3.getSelection());
+    }    
+    if(saisieChampAffiche4.pasdeSelection()){
+        initSousTexteNbElts();
+    }
+    else{
+        initSousTexteChamp(saisieChampAffiche4.getSelection());
+    }
+    
+    this.ngrammes.setDonneesChaines(donneesChaines);
+    this.ngrammes.setTypeChaines(typeChaines);
+    this.ngrammes.setTypeUnites(typeUnites);
+    this.ngrammes.update();
+  }
+  private void modifierStatutValNulleChamp(boolean masquee, boolean tous,int source) {
+      Val0ComboBox zonedesaisie;
+      switch(source){
+          case 0:
+              zonedesaisie = saisieChampAffiche;
+              break;
+          case 1:
+              zonedesaisie = saisieChampAffiche1;              
+              break;
+          case 2:
+              zonedesaisie = saisieChampAffiche2;                 
+              break;
+          case 3 :
+            zonedesaisie = saisieChampAffiche3;  
+            break;
+          case 4 :
+            zonedesaisie = saisieChampAffiche4;      
+            break;
+          default :
+              zonedesaisie = new Val0ComboBox("Nombre de chaînons");                 
+              break;
+      }      
+    if(!tous) donneesChaines.masquerValNulleChamp(!masquee, zonedesaisie.getSelection());
+   else if(masquee) donneesChaines.demasquerToutesValsChamp( 
+            zonedesaisie.getSelection());
+    else donneesChaines.masquerValsNonNullesChamp(typeUnites, 
+            zonedesaisie.getSelection());
+    donneesChaines.modifMasqueVals(typeChaines, typeUnites);
+    if(saisieChampAffiche.pasdeSelection()){
+        initCouleursNbElts();
+    }
+    else{
+        initCouleursChamp(saisieChampAffiche.getSelection());
+    }
+    if(saisieChampAffiche1.pasdeSelection()){
+        initFormesNbElts();
+    }
+    else{
+        initFormesChamp(saisieChampAffiche1.getSelection());
+    }
+    if(saisieChampAffiche2.pasdeSelection()){
+        initTaillesNbElts();
+    }
+    else{
+        initTaillesChamp(saisieChampAffiche2.getSelection());
+    }
+    if(saisieChampAffiche3.pasdeSelection()){
+        initSurTexteNbElts();
+    }
+    else{
+        initSurTexteChamp(saisieChampAffiche3.getSelection());
+    }    
+    if(saisieChampAffiche4.pasdeSelection()){
+        initSousTexteNbElts();
+    }
+    else{
+        initSousTexteChamp(saisieChampAffiche4.getSelection());
+    }
+//    initstat();
+    
+    this.ngrammes.setDonneesChaines(donneesChaines);
+    this.ngrammes.setTypeChaines(typeChaines);
+    this.ngrammes.setTypeUnites(typeUnites);
+    this.ngrammes.update();
+  }
+  private void modifierStatutValNbElements(boolean masquee, int index, boolean tous,int source) {
+      Val0ComboBox zonedesaisie;
+      switch(source){
+          case 0:
+              zonedesaisie = saisieChampAffiche;
+              break;
+          case 1:
+              zonedesaisie = saisieChampAffiche1;              
+              break;
+          case 2:
+              zonedesaisie = saisieChampAffiche2;                 
+              break;
+          case 3 :
+            zonedesaisie = saisieChampAffiche3;  
+            break;
+          case 4 :
+            zonedesaisie = saisieChampAffiche4;      
+            break;
+          default :
+              zonedesaisie = new Val0ComboBox("Nombre de chaînons");                 
+              break;
+      }            
+    if(!tous) donneesChaines.masquerValNbElements(!masquee, index);
+   else if(masquee) donneesChaines.demasquerToutesValsNbElts( 
+            zonedesaisie.getSelection());
+    else donneesChaines.masquerAutresValsNbElts( 
+            zonedesaisie.getSelection(), index);
+    donneesChaines.modifMasqueVals(typeChaines, typeUnites);
+    if(saisieChampAffiche.pasdeSelection()){
+        initCouleursNbElts();
+    }
+    else{
+        initCouleursChamp(saisieChampAffiche.getSelection());
+    }
+    if(saisieChampAffiche1.pasdeSelection()){
+        initFormesNbElts();
+    }
+    else{
+        initFormesChamp(saisieChampAffiche1.getSelection());
+    }
+    if(saisieChampAffiche2.pasdeSelection()){
+        initTaillesNbElts();
+    }
+    else{
+        initTaillesChamp(saisieChampAffiche2.getSelection());
+    }
+    if(saisieChampAffiche3.pasdeSelection()){
+        initSurTexteNbElts();
+    }
+    else{
+        initSurTexteChamp(saisieChampAffiche3.getSelection());
+    }    
+    if(saisieChampAffiche4.pasdeSelection()){
+        initSousTexteNbElts();
+    }
+    else{
+        initSousTexteChamp(saisieChampAffiche4.getSelection());
+    }
+//    initstat();
+    
+    this.ngrammes.setDonneesChaines(donneesChaines);
+    this.ngrammes.setTypeChaines(typeChaines);
+    this.ngrammes.setTypeUnites(typeUnites);
+    this.ngrammes.update();
+  }
+
+  
+  public JTable getLegende(int index){
+      JTable retour;
+      switch(index){
+          case 0 :
+              retour = this.legendeChampAffiche;
+              break;
+          case 1 :
+              retour = this.legendeChampAffiche1;
+              break;
+          case 2 :
+              retour = this.legendeChampAffiche2;
+              break;
+          case 3 : 
+              retour = this.legendeChampAffiche3;
+              break;
+          case 4 :
+              retour = this.legendeChampAffiche4;
+              break;
+          default :
+              retour = new JTable();
+              break;
+      }
+      return retour;
+  }
+  //retourne en format SVG la sélection
+  public String getSelection(int taillepolice, int x , int y, String police){
+      String retour = "";
+      if(saisieTypeChaines.pasdeSelection()){
+          retour = retour + "<text x=\""+x+"\" y=\""+(y) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Type de Schéma : aucun" + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      else{
+          retour = retour + "<text x=\""+x+"\" y=\""+(y) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Type de Schéma : " + saisieTypeChaines.getSelection() + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+                  
+      }
+      if(saisieTypeUnites.pasdeSelection()){
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 2 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Type d'Unités : aucun" + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      else{
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 2 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Type d'Unités : " + saisieTypeUnites.getSelection() + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      if(saisieChampAffiche.pasdeSelection()){
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 4 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 1 : nombre de Chainons" + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      else{
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 4 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 1 : " + saisieChampAffiche.getSelection() + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      if(saisieChampAffiche1.pasdeSelection()){
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 6 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 2 : nombre de Chainons" + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      else{
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 6 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 2 : " + saisieChampAffiche1.getSelection() + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      if(saisieChampAffiche2.pasdeSelection()){
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 8 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 3 : nombre de Chainons" + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      else{
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 8 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 3 : " + saisieChampAffiche2.getSelection() + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      if(saisieChampAffiche3.pasdeSelection()){
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 10 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 4 : nombre de Chainons" + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      else{
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 10 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 4 : " + saisieChampAffiche3.getSelection() + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      if(saisieChampAffiche4.pasdeSelection()){
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 12 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 5 : nombre de Chainons" + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      else{
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 12 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 5 : " + saisieChampAffiche4.getSelection() + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      return retour;
+  }
+  public void exporterAffichage(){
+      HashMap<String,Object> Choix = new HashMap();
+      HashMap<String,String> choixCommande = new HashMap();
+      
+      choixCommande.put("saisieTypeChaines",saisieTypeChaines.pasdeSelection() ? null : saisieTypeChaines.getSelection());
+      choixCommande.put("saisieTypeUnites",saisieTypeUnites.pasdeSelection() ? null : saisieTypeUnites.getSelection());
+      choixCommande.put("saisieTailleLigne",saisieTailleLigne.getSelectedItem().toString());
+      choixCommande.put("activeCouperParagraphe",activeCouperParagraphe.isSelected() ? "vrai" : "faux");
+      choixCommande.put("saisieChampAffiche",saisieChampAffiche.pasdeSelection() ? null : saisieChampAffiche.getSelection());
+      choixCommande.put("saisieChampAffiche1",saisieChampAffiche1.pasdeSelection() ? null : saisieChampAffiche1.getSelection());
+      choixCommande.put("saisieChampAffiche2",saisieChampAffiche2.pasdeSelection() ? null : saisieChampAffiche2.getSelection());
+      choixCommande.put("saisieChampAffiche3",saisieChampAffiche3.pasdeSelection() ? null : saisieChampAffiche3.getSelection());
+      choixCommande.put("saisieChampAffiche4",saisieChampAffiche4.pasdeSelection() ? null : saisieChampAffiche4.getSelection());
+
+      Choix.put("valmasquees",donneesChaines.getValsMasqueesChamp());
+      Choix.put("valNbmasquees",donneesChaines.getValsNbMasqueesChamp());
+      Choix.put("valNullemasquees",donneesChaines.getValsNulleMasqueesChamp());
+      Choix.put("codeLegende",this.codeLegende);
+      Choix.put("choixCommande1",choixCommande);
+      Choix.put("ngrammes",this.ngrammes.exporterAffichage());
+      Choix.put("nomFichier",Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC));
+      FichiersJava.enregistrerChaineSous(Choix);
+  }
+  public void importerAffichage(){
+      HashMap<String,Object> choix = FichiersJava.ouvrirChaineVue();
+      if(choix!=null && choix.containsKey("choixCommande1") &&
+              Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC).equals(choix.get("nomFichier"))){
+        HashMap<String,String> choixCommande = (HashMap<String,String>) choix.get("choixCommande1");
+        saisieTypeChaines.removeActionListener(this);
+        saisieTypeUnites.removeActionListener(this);
+        saisieTypeChaines.setSelectedItem(choixCommande.get("saisieTypeChaines"));
+        saisieTypeUnites.setSelectedItem(choixCommande.get("saisieTypeUnites"));
+        saisieTypeChaines.addActionListener(this);
+        saisieTypeUnites.addActionListener(this);
+        init();
+        //si on ne les paramètres d'affichage ont été enregistrés pour le même corpus
+        this.codeLegende = (HashMap<String,HashMap<String,String>>) choix.get("codeLegende");
+        donneesChaines.setValsMasqueesChamp((HashMap<String,HashSet<String>>) choix.get("valmasquees"));
+        donneesChaines.setValsNbMasqueesChamp((boolean[]) choix.get("valNbmasquees"));
+        donneesChaines.setValsNulleMasqueesChamp((HashSet<String>) choix.get("valNullemasquees"));
+        saisieTailleLigne.removeActionListener(this);
+        saisieChampAffiche.removeActionListener(this);
+        saisieChampAffiche1.removeActionListener(this);
+        saisieChampAffiche2.removeActionListener(this);
+        saisieChampAffiche3.removeActionListener(this);
+        saisieChampAffiche4.removeActionListener(this);
+        activeCouperParagraphe.setSelected(choixCommande.get("activeCouperParagraphe").equals("vrai"));
+        panneauGraphique.setcouperparagraphe(activeCouperParagraphe.isSelected());
+        saisieTailleLigne.setSelectedItem(choixCommande.get("saisieTailleLigne"));
+        int taille = saisieTailleLigne.getSelectedIndex()==0 ? Integer.MAX_VALUE :
+        Integer.parseInt((String)saisieTailleLigne.getSelectedItem());
+        panneauGraphique.setNbChainonsParLigne(taille);
+        if(choixCommande.get("saisieChampAffiche")!=null){
+          saisieChampAffiche.setSelectedItem(choixCommande.get("saisieChampAffiche"));
+        }
+        else{
+          saisieChampAffiche.effSelection();
+        }
+        if(choixCommande.get("saisieChampAffiche1")!=null){
+          saisieChampAffiche1.setSelectedItem(choixCommande.get("saisieChampAffiche1"));
+        }
+        else{
+          saisieChampAffiche1.effSelection();
+        }
+        if(choixCommande.get("saisieChampAffiche2")!=null){
+          saisieChampAffiche2.setSelectedItem(choixCommande.get("saisieChampAffiche2"));
+        }
+        else{
+          saisieChampAffiche2.effSelection();
+        }
+        if(choixCommande.get("saisieChampAffiche3")!=null){
+          saisieChampAffiche3.setSelectedItem(choixCommande.get("saisieChampAffiche3"));
+        }
+        else{
+          saisieChampAffiche3.effSelection();
+        }
+        if(choixCommande.get("saisieChampAffiche4")!=null){
+          saisieChampAffiche4.setSelectedItem(choixCommande.get("saisieChampAffiche4"));
+        }
+        else{
+          saisieChampAffiche4.effSelection();
+        }
+        saisieTailleLigne.addActionListener(this);
+        saisieChampAffiche.addActionListener(this);
+        saisieChampAffiche1.addActionListener(this);
+        saisieChampAffiche2.addActionListener(this);
+        saisieChampAffiche3.addActionListener(this);
+        saisieChampAffiche4.addActionListener(this);
+        donneesChaines.modifMasqueVals(typeChaines, typeUnites);
+
+          if(saisieChampAffiche.pasdeSelection()){
+              initCouleursNbElts();
+          }
+          else{
+              initCouleursChamp(saisieChampAffiche.getSelection());
+          }
+          if(saisieChampAffiche1.pasdeSelection()){
+              initFormesNbElts();
+          }
+          else{
+              initFormesChamp(saisieChampAffiche1.getSelection());
+          }
+          if(saisieChampAffiche2.pasdeSelection()){
+              initTaillesNbElts();
+          }
+          else{
+              initTaillesChamp(saisieChampAffiche2.getSelection());
+          }
+          if(saisieChampAffiche3.pasdeSelection()){
+              initSurTexteNbElts();
+          }
+          else{
+              initSurTexteChamp(saisieChampAffiche3.getSelection());
+          }    
+          if(saisieChampAffiche4.pasdeSelection()){
+              initSousTexteNbElts();
+          }
+          else{
+              initSousTexteChamp(saisieChampAffiche4.getSelection());
+          }
+        this.ngrammes.setDonneesChaines(donneesChaines);
+        this.ngrammes.setTypeChaines(typeChaines);
+        this.ngrammes.setTypeUnites(typeUnites);
+        this.ngrammes.importerAffichage((HashMap) choix.get("ngrammes"));
+          this.ngrammes.update();
+      }
+      else{
+          JOptionPane.showMessageDialog(null, "le fichier des paramètres d'affichage n'est pas destiné à cette fenêtre"
+                 + System.getProperty("line.separator") +
+                  "ou à ce corpus", "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      }
+      
+      
+  }
+  
+  public ModeleChaines getDonneesChaines(){
+      return this.donneesChaines;
+  }
+  
+    public Object[][] donneesCSV(boolean[] champ){
+      ArrayList<Object[]> donnees = new ArrayList();
+      int nbchamp=0;
+      for(boolean tmp : champ){
+          if(tmp){
+              nbchamp = nbchamp + 1;
+          }
+      }
+      if(champ.length==5){
+              GChaines chaine = this.panneauGraphique;
+              Object[] titre = new Object[nbchamp+1];
+                  titre[0] = "unité";
+                  int compteurTitre=1;
+                  for(int  i = 0 ; i < champ.length ; i++){
+                      if(champ[i]){
+                          switch(i){
+                              case 0 :
+                                  titre[compteurTitre] = this.saisieChampAffiche.pasdeSelection() ? 
+                                          "Nombre de Chainons"
+                                          : this.saisieChampAffiche.getSelection();
+                                  break;
+                              case 1 :
+                                  titre[compteurTitre] = this.saisieChampAffiche1.pasdeSelection() ? 
+                                          "Nombre de Chainons"
+                                          : this.saisieChampAffiche1.getSelection();
+                                  break;
+                              case 2 :
+                                  titre[compteurTitre] = this.saisieChampAffiche2.pasdeSelection() ? 
+                                          "Nombre de Chainons"
+                                          : this.saisieChampAffiche2.getSelection();
+                                  break;
+                              case 3 :
+                                  titre[compteurTitre] = this.saisieChampAffiche3.pasdeSelection() ? 
+                                          "Nombre de Chainons"
+                                          : this.saisieChampAffiche3.getSelection();
+                                  break;
+                              case 4 :
+                                  titre[compteurTitre] = this.saisieChampAffiche4.pasdeSelection() ? 
+                                          "Nombre de Chainons"
+                                          : this.saisieChampAffiche4.getSelection();
+                                  break;
+                          }
+                          compteurTitre = compteurTitre + 1;
+                      }
+                  }
+                  donnees.add(titre);
+              for(int  j = 0 ; j < chaine.chainons.length ; j++){
+                  ModeleChaines.Chainon unit = chaine.chainons[j];
+                  Object[] row = new Object[nbchamp+1];
+                  row[0] = unit.texte;
+                  int compteur=1;
+                  for(int  i = 0 ; i < champ.length ; i++){
+                      if(champ[i]){
+                          switch(i){
+                              case 0 :
+                                  row[compteur] = this.saisieChampAffiche.pasdeSelection() ? 
+                                          labelsNbElements[donneesChaines.calculerValNbElements(unit.nbEltsChaine)]
+                                          : vue.getValeurChamp(unit.unite, this.saisieChampAffiche.getSelection());
+                                  break;
+                              case 1 :
+                                  row[compteur] = this.saisieChampAffiche1.pasdeSelection() ? 
+                                          labelsNbElements[donneesChaines.calculerValNbElements(unit.nbEltsChaine)]
+                                          : vue.getValeurChamp(unit.unite, this.saisieChampAffiche1.getSelection());
+                                  break;
+                              case 2 :
+                                  row[compteur] = this.saisieChampAffiche2.pasdeSelection() ? 
+                                          labelsNbElements[donneesChaines.calculerValNbElements(unit.nbEltsChaine)]
+                                          : vue.getValeurChamp(unit.unite, this.saisieChampAffiche2.getSelection());
+                                  break;
+                              case 3 :
+                                  row[compteur] = this.saisieChampAffiche3.pasdeSelection() ? 
+                                          labelsNbElements[donneesChaines.calculerValNbElements(unit.nbEltsChaine)]
+                                          : vue.getValeurChamp(unit.unite, this.saisieChampAffiche3.getSelection());
+                                  break;
+                              case 4 :
+                                  row[compteur] = this.saisieChampAffiche4.pasdeSelection() ? 
+                                          labelsNbElements[donneesChaines.calculerValNbElements(unit.nbEltsChaine)]
+                                          : vue.getValeurChamp(unit.unite, this.saisieChampAffiche4.getSelection());
+                                  break;
+                          }
+                          compteur = compteur + 1;
+                      }
+                  }
+                  donnees.add(row);
+              }
+       }
+      return donnees.toArray(new Object[donnees.size()][nbchamp]);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuChaines.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ChaineUtil.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ChaineUtil.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ChaineUtil.java	(revision 481)
@@ -0,0 +1,939 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.chaines;
+import java.awt.*;
+import java.util.*;
+import java.util.ArrayList;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.vue.*;
+/**
+ *
+ * @author Marc
+ */
+public abstract class ChaineUtil {
+    
+   //renvoie un HashMap qui à un nombre de chainons de la chaine associe le nombre de chaines 
+   //qui ont ce nombre de chainons 
+   public static HashMap<Integer,Integer> calculerdonneecourbechainons(String[] typesdispo,Vue vue){
+       String[] typesChaines = vue.getTypesSchemasAVoir();
+       HashMap<Integer,Integer> retour = new HashMap();
+       for(String typechaine : typesChaines){
+           Schema[] chaines = vue.getSchemas(typechaine);
+           for(Schema chaine : chaines){
+               HashSet<Element> contenu = chaine.getContenu();
+               int compte = 0;
+               for(Element elt : contenu){
+                   if(elt.getClass()==Unite.class && tableauRecherche(typesdispo,elt.getType())){
+                       compte = compte + 1;
+                   }
+               }
+               if(retour.containsKey(compte)){
+                    retour.put(compte,retour.get(compte) + 1);
+               }
+               else{
+                    retour.put(compte,1);    
+               }
+           }
+       }
+       return retour;
+   }
+    
+   
+   
+       
+    
+   //Calcule à partir de la position en caractères la position en mot dans une chaine de caractère
+   //@require : la position en caractère doit être inférieure à la longueur de la chaine
+   private static int calculerPositionMot(int poscaractere, String chaine,Vue vue){
+       int compteur = 1;
+       int i = 0;
+       while(i < poscaractere){
+           if(chaine.charAt(i)=='\n'  || chaine.charAt(i)==' ' || chaine.charAt(i)=='\r'){
+               while(i < poscaractere && (chaine.charAt(i)=='\n'  || chaine.charAt(i)==' '
+                       || chaine.charAt(i)=='\r')){
+                   i = i + 1;
+               }
+               compteur = compteur  + 1;
+           }
+           i = i + 1;
+       }
+       return compteur;
+   }
+   
+   //cherche la position en nombre d'un caractère mot dans le corpus
+   public static int calculerPositionMotCorpus(int poscaractere, Vue vue){
+       String corpus = vue.getCorpus().getTexte();
+       int resultat = 0;
+       Integer[] finparagraphe = vue.getCorpus().getFinParagraphes();
+       int finparagraphecourant = 0;
+       for(int i = 0 ; i < corpus.length();i++){
+           if(corpus.charAt(i)==' ' || i > finparagraphe[finparagraphecourant]){
+               resultat = resultat + 1;
+               if(i > finparagraphe[finparagraphecourant]){
+                  finparagraphecourant = finparagraphecourant + 1;  
+               }
+           }
+           if(i == poscaractere){
+               return resultat;
+           }
+       }
+       return resultat;
+   }
+   //donne le nombre de paragraphes du corpus
+   public static int nbParagraphe(Vue vue){
+       return vue.getCorpus().getFinParagraphes().length;
+   }
+   //donne le nombre de caractères du corpus
+   public static int nbCaractere(Vue vue){
+       return vue.getCorpus().getTexte().length();
+   }
+   //donne le nombre de mots du Corpus
+   public static int nbMot(Vue vue){
+       return calculerPositionMotCorpus(nbCaractere(vue)-1,vue);
+   }
+  //donne le nombre d'unité appartenant à une chaine
+   public static int nombreDeReference(String[] typesUnite,Vue vue){
+       String[] types = vue.getTypesSchemasAVoir();
+       int compte = 0;
+       for(String type : types){
+           Schema[] chaines = vue.getSchemas(type);
+           for(Schema chaine : chaines){
+               for(Element unit : chaine.getContenu()){
+                   if(unit.getClass()==Unite.class && tableauRecherche(typesUnite,unit.getType())){
+                       compte =  compte + 1;
+                   }
+               }
+           }
+       }
+       return compte;
+   }
+   //donne le nombre de chaines non vides
+   public static int nbChaines(Vue vue){
+       String[] types = vue.getTypesSchemasAVoir();
+       int compte = 0;
+       for(String type : types){
+           Schema[] chaines = vue.getSchemas(type);
+           for(Schema chaine : chaines){
+               if(chaine.getContenu().size()>0){
+                       compte =  compte + 1;
+               }
+           }
+       }
+       return compte;       
+   }
+   //calcule le nombre de références par unité de longueur "choix"
+   public static float densiteReferentielle(String choix,String[] types,Vue vue){
+       float compte = 0.0f;
+       compte = compte + nombreDeReference(types,vue);
+       switch(choix){
+           case "Caractère":
+               compte = Math.round(compte * 10000.0f / nbCaractere(vue)) / 10000.0f; 
+               break;
+           case "Mot":
+               compte = Math.round(compte * 10000.0f / nbMot(vue)) / 10000.0f; 
+               break;
+           case "Paragraphe":
+               compte = Math.round(compte * 10000.0f / nbParagraphe(vue)) / 10000.0f; 
+               break;
+           default:
+               break;
+               
+       }
+       return compte;
+   }
+   //attention les unités sont dans le désordre
+   public static ArrayList<Integer> positionUnite(String[] types,Vue vue){
+       ArrayList<Integer> retour  = new ArrayList();
+       for(String type : types){
+           Unite[] unites = vue.getUnites(type);
+           for(Unite unit : unites){
+               retour.add(unit.getDeb());
+           }
+       }
+       return retour;
+   }
+   //renvoie les unités dont le type est contenu dans le tableau "types" puis et triée par ordre d'apparition 
+   // dans le corpus
+   public static Unite[] getUniteesTrieesEtFiltrees(String[] types,Vue vue){
+       ArrayList<Unite> stockage = new ArrayList();
+       for(String type : types){
+           Unite[] tmp = vue.getUnites(type);
+           for(int i  = 0; i < tmp.length;i++){
+               stockage.add(tmp[i]);
+           }
+       }
+       Unite[] retour = stockage.toArray(new Unite[stockage.size()]);
+       triFusionUnite(retour);
+       return retour;
+   }
+   //calcule les position en nombre de mots au sein d'un corpus des unités dont le 
+   //type est contenu dans le tableau "types" puis et triée par ordre d'apparition 
+   public static ArrayList<Integer> positionUniteEnMot(String[] types,Vue vue){
+       Unite[] donnees = getUniteesTrieesEtFiltrees(types,vue);
+       int postexte = 0;
+       int comptemot = 0;
+       String texte = vue.getCorpus().getTexte();
+       ArrayList<Integer> retour = new ArrayList();
+       for(int i = 0 ; i < donnees.length ; i++){
+           while(postexte < donnees[i].getDeb()){
+               if(texte.charAt(postexte)==' ' || texte.charAt(postexte)=='\n'){
+                   comptemot = comptemot + 1;
+               }
+               postexte = postexte + 1;
+           }
+           retour.add(comptemot);
+       }
+       return retour;
+   }
+    //calcule les écarts en nombre de caractères au sein d'un corpus des unités dont le 
+   //type est contenu dans le tableau "types"
+   //les écarts sont la différence les positions de début de deux unités consécutives respectant toutes deux 
+   //un type d'unités contenu dans "types"
+   public static ArrayList<Integer> ecartUniteCaractere(String[] types,Vue vue){
+       ArrayList<Integer> retour  = new ArrayList();
+           Unite[] unites = getUniteesTrieesEtFiltrees(types,vue);
+           for(int i = 0;i < unites.length-1;i++){
+               retour.add(unites[i+1].getDeb() - unites[i].getDeb());
+           }
+       return retour;
+   }   
+    //calcule les écarts en nombre de mots au sein d'un corpus des unités dont le 
+   //type est contenu dans le tableau "types" 
+   //les écarts sont la différence les positions de début de deux unités consécutives respectant toutes deux 
+   //un type d'unités contenu dans "types"
+   public static ArrayList<Integer> ecartUniteMot(String[] types,Vue vue){
+       ArrayList<Integer> retour  = new ArrayList();
+           Unite[] unites = getUniteesTrieesEtFiltrees(types,vue);
+           for(int i = 0;i < unites.length-1;i++){
+               String texte = vue.getCorpus().getTexte().substring(unites[i].getDeb(), unites[i+1].getDeb());
+               int compte = 0;
+               for(int j = 0 ; j < texte.length();j++){
+                   if(texte.charAt(j)==' ' || texte.charAt(j)=='\n'){
+                       compte = compte + 1; 
+                   }
+               }
+               retour.add(compte);
+           }
+       return retour;
+   }
+   
+   //détermine les longueurs en mots des unités contenu dans un corpus et dont le 
+   //type est contenu dans le tableau "types" 
+   public static ArrayList<Integer> longueurUniteMot(String[] types,Vue vue){
+       ArrayList<Integer> retour  = new ArrayList();
+       for(String type : types){
+           Unite[] unites = vue.getUnites(type);
+           for(int i = 0;i < unites.length;i++){
+               String texte = vue.getCorpus().getTexte().substring(unites[i].getDeb(), unites[i].getFin());
+               int compte = 0;
+               for(int j = 0 ; j < texte.length();j++){
+                   if(texte.charAt(j)==' ' || texte.charAt(j)=='\n'){
+                       compte = compte + 1; 
+                   }
+               }
+               retour.add(compte);
+           }
+       }
+       return retour;
+   }
+   
+   //détermine les longueurs en nombre de caractères des unités contenu dans un corpus et dont le 
+   //type est contenu dans le tableau "types" 
+   public static ArrayList<Integer> longueurUniteCaractere(String[] types,Vue vue){
+       ArrayList<Integer> retour  = new ArrayList();
+       for(String type : types){
+           Unite[] unites = vue.getUnites(type);
+           for(int i = 0;i < unites.length;i++){
+               int compte = unites[i].getFin()-unites[i].getDeb();
+               retour.add(compte);
+           }
+       }
+       return retour;
+   }
+   
+   //pas optimisé comme un binary search car on a pas d'ordre défini sur les objets du tableau
+   //et donc le tableau n'est pas trié
+   public static boolean tableauRecherche(Object[] tab, Object elt){
+       for(Object unit : tab){
+           if(unit.equals(elt)){
+               return true;
+           }
+       }
+       return false;
+   }
+   
+   //détermine la longueur des chaines en caractères
+   public static ArrayList<Integer> longueurChaineCaractere(String[] types,Vue vue){
+       String[] typeschaine = vue.getTypesSchemasAVoir();
+       ArrayList<Integer> retour = new ArrayList();
+       for(String type : typeschaine){
+           Schema[] chaines = vue.getSchemas(type);
+           for(Schema chaine : chaines){
+               HashSet<Element> contenu = chaine.getContenu();
+               Integer compte = 0;
+               for(Element elt : contenu){
+                   if(elt.getClass()==Unite.class && tableauRecherche(types,elt.getType())){
+                       Unite tmp = (Unite) elt;
+                       compte = compte + tmp.getFin() - tmp.getDeb();
+                   }
+               }
+               retour.add(compte);
+           }
+       }
+       return retour;
+   }
+   
+   //détermine la longueur des chaines en mots en sommant la longueur des maillons dont le type est contenu
+   //dans "types"
+   public static ArrayList<Integer> longueurChaineMot(String[] types,Vue vue){
+       String[] typeschaine = vue.getTypesSchemasAVoir();
+       ArrayList<Integer> retour = new ArrayList();
+       for(String type : typeschaine){
+           Schema[] chaines = vue.getSchemas(type);
+           for(Schema chaine : chaines){
+               HashSet<Element> contenu = chaine.getContenu();
+               Integer compte = 0;
+               for(Element elt : contenu){
+                   if(elt.getClass()==Unite.class && tableauRecherche(types,elt.getType())){
+                       Unite tmp = (Unite) elt;
+                       String texte = vue.getCorpus().getTexte().substring(tmp.getDeb(), tmp.getFin());
+                       for(int i = 0 ; i < texte.length();i++){
+                            if(texte.charAt(i)==' ' || texte.charAt(i)=='\n'){
+                                compte = compte + 1;
+                            }
+                       }
+                   }
+               }
+               retour.add(compte);
+           }
+       }
+       return retour;
+   }
+   
+   
+   //calcule le nombre de chainons(unités) dont le type est contenu dans "types" de chaque chaine
+   public static ArrayList<Integer> nombreDeChainons(String[] types,Vue vue){
+       String[] typeschaines = vue.getTypesSchemasAVoir();
+       ArrayList retour = new ArrayList();
+       for(String type : typeschaines){
+           Schema[] chaines = vue.getSchemas(type);
+           for(Schema chaine : chaines){
+               HashSet<Element> contenu = chaine.getContenu();
+               Integer compte = 0;
+               for(Element elt : contenu){
+                   if(elt.getClass()==Unite.class && tableauRecherche(types,elt.getType())){
+                       compte = compte + 1;
+                   }
+               }
+               retour.add(compte);
+           }
+       }
+       return retour;
+   }
+   
+   
+   
+   //recherche le numero de paragraphe dans le corpus qui correspond à une position en caractère 
+   public static int conversionPositionCaracterEtNoParagraphe(int poscaractere, Vue vue){
+       Integer[] noparagraphe = vue.getCorpus().getFinParagraphes();
+       for(int  i = 0 ; i < noparagraphe.length;i++ ){
+           if(poscaractere > noparagraphe[i] || i ==noparagraphe.length-1){
+               return i;
+           }
+           
+       }
+       return -1 ;
+   }
+   
+   
+    //@ensures : retourne la longueur d'une unité en caractère
+   public static int longueurUnite(Unite donnee){
+       return (donnee.getFin() - donnee.getDeb());
+   }
+   
+   //@ensures : retourne la longueur d'une unite en mot
+   public static int nbMotUnite(Unite donnee,Vue vue){
+       String chaine = (vue.getCorpus()).getTexteUnite(donnee);
+       return calculerPositionMot(chaine.length(),chaine,vue);
+   }
+   //cherche le maximum d'un tableau pas forcément trié 
+   public static Integer maxiTab(Integer[] donnees){
+       Integer max = -1;
+       if(donnees.length > 0){
+        max = donnees[0];
+        for(Integer nbr : donnees){
+            if(nbr > max){
+                max = nbr;
+            }
+        }
+       }
+       return max;
+   } 
+   //cherche le minimum d'un tableau pas forcément trié 
+   public static Integer miniTab(Integer[] donnees){
+       Integer min = -1;
+       if(donnees.length > 0){
+        min = donnees[0];
+        for(Integer nbr : donnees){
+            if(nbr < min){
+                min = nbr;
+            }
+        }
+       }
+       return min;
+   } 
+   //retourne la somme des éléments d'un tableau
+   public static int somme(Integer[] donnees){
+       int total = 0;
+       for(Integer nbr : donnees){
+           total = total + nbr;
+       }
+       return total;
+   }
+   
+   
+   public static int nbMotsDansUneUnite(int deb,int fin,Vue vue){
+       String texteunite = vue.getCorpus().getTexte().substring(deb, fin);
+       int compte = (deb<fin ? 1 : 0);
+       for(int i=0;i< texteunite.length();i++){
+           if(texteunite.charAt(i)==' '){
+               compte = compte + 1;
+           }
+       }
+       return compte;
+   }   
+ //permet de trier un tableau de valeurs suivant leur fréquence  
+ public static void triFusionMap(String tableau[],HashMap<String, Float> freq)
+        {
+        int longueur=tableau.length;
+        if (longueur>0)
+            {
+            triFusionMap(tableau,0,longueur-1,freq);
+            }
+        }
+
+  private static void triFusionMap(String tableau[],int deb,int fin,HashMap<String, Float> freq)
+        {
+        if (deb!=fin)
+            {
+            int milieu=(fin+deb)/2;
+            triFusionMap(tableau,deb,milieu,freq);
+            triFusionMap(tableau,milieu+1,fin,freq);
+            fusionMap(tableau,deb,milieu,fin,freq);
+            }
+        }
+    
+   private static void fusionMap(String tableau[],int deb1,int fin1,int fin2,HashMap<String, Float> freq)
+        {
+        int deb2=fin1+1;
+
+        //on recopie les éléments du début du tableau
+        String table1[]=new String[fin1-deb1+1];
+        for(int i=deb1;i<=fin1;i++)
+            {
+            table1[i-deb1]=tableau[i];
+            }
+        
+        int compt1=deb1;
+        int compt2=deb2;
+        
+        for(int i=deb1;i<=fin2;i++)
+            {        
+            if (compt1==deb2) //c'est que tous les éléments du premier tableau ont été utilisés
+                {
+                break; //tous les éléments ont donc été classés
+                }
+            else if (compt2==(fin2+1)) //c'est que tous les éléments du second tableau ont été utilisés
+                {
+                tableau[i]=table1[compt1-deb1]; //on ajoute les éléments restants du premier tableau
+                compt1++;
+                }
+            else if (freq.get(table1[compt1-deb1])>freq.get(tableau[compt2]))
+                {
+                tableau[i]=table1[compt1-deb1]; //on ajoute un élément du premier tableau
+                compt1++;
+                }
+            else
+                {
+                tableau[i]=tableau[compt2]; //on ajoute un élément du second tableau
+                compt2++;
+                }
+            }
+        }
+   //on enlève les unités dont le numero de paragraphe appartient à Noparagraphe
+   public static Unite[] filtreparagraphe(Unite[] donnees, ArrayList<Integer> Noparagraphemasque,Vue vue){
+       HashMap<Unite,Integer> noparagraphe = unitenumeroparagraphe(donnees,vue);
+       ArrayList<Unite> unitefiltrees = new ArrayList(); 
+       for(Unite unit : donnees){
+           if(!(Noparagraphemasque.contains(noparagraphe.get(unit)))){
+               unitefiltrees.add(unit);
+           }
+       }
+       Unite[] resultat = unitefiltrees.toArray(new Unite[0]);
+       return resultat;
+   }   
+    //renvoie un tableau contenant les fréquences de chaque valeur d'un champ dans la liste d'unités
+   public static HashMap<String, Float> calculerfrequencechamp(Unite[] donnees,String typeUnites
+           ,String Champcible,Vue vue){
+       String[] valsdisponibles  = vue.getValeursChamp(Unite.class, typeUnites, Champcible);
+       HashMap<String, Float> tableaufrequence = new HashMap<String, Float>(valsdisponibles.length + 1); 
+       String valeurchamp;
+       //on initialise le tableau résultat
+       for(String valeur : valsdisponibles){
+           tableaufrequence.put(valeur, 0.0f);
+       }
+       tableaufrequence.put("", 0.0f);
+       //on compte le nombre d'occurences
+       for(Unite unit : donnees){
+           valeurchamp = vue.getValeurChamp(unit, Champcible);
+           tableaufrequence.put(valeurchamp,tableaufrequence.get(valeurchamp) + 1); 
+       }
+       //on calcule les pourcentages
+       for(String valeur : valsdisponibles){
+           tableaufrequence.put(valeur, tableaufrequence.get(valeur) * 10000.0f /
+                   donnees.length / 100.0f);
+       }       
+           tableaufrequence.put("", tableaufrequence.get("") * 10000.0f /
+                   donnees.length / 100.0f);       
+       
+       return tableaufrequence;
+   }
+   
+  //détermine la moyenne par rapport à la deuxième variable d'un HashMap
+  public static float Esperance(HashMap<Object,Integer> donnees){
+      float moyenne  = 0.0f;
+      for(Object i : donnees.keySet()){
+          moyenne = moyenne + donnees.get(i);
+      }
+      moyenne = moyenne / donnees.size();
+      return moyenne;
+  }
+    //détermine la moyenne des valeurs d'un tableau
+  public static float Esperance(Integer[] donnees){
+      float moyenne  = 0.0f;
+      for(Integer i : donnees){
+          moyenne = moyenne + i;
+      }
+      moyenne = moyenne / donnees.length;
+      return moyenne;
+  }  
+    //détermine la variance par rapport à la deuxième variable d'un HashMap
+  public static float Variance(HashMap<Object,Integer> donnees){
+      float moyenne  = Esperance(donnees);
+      float variance = 0.0f;
+      if(donnees.size() > 1){
+        for(Object i : donnees.keySet()){
+            variance = variance + (donnees.get(i) - moyenne) * (donnees.get(i) - moyenne);
+        }
+          variance  =  variance / (donnees.size() - 1);
+      }
+
+      return variance;
+  }
+  //détermine la variance des valeurs d'un tableau
+  public static float Variance(Integer[] donnees){
+      float moyenne  = Esperance(donnees);
+      float variance = 0.0f;
+      if(donnees.length > 1){
+        for(Integer i : donnees){
+            variance = variance + (i - moyenne) * (i - moyenne);
+        }
+          variance  =  variance / (donnees.length - 1);
+      }
+      return variance;
+  }  
+  //permet de trier les unités d'un tableau
+  //la relation d'ordre entre les unités est la comparaison des positions de débuts des unités au sein du texte
+  public static void triFusionUnite(Unite tableau[])
+        {
+        int longueur=tableau.length;
+        if (longueur>0)
+            {
+            triFusionUnite(tableau,0,longueur-1);
+            }
+        }
+
+  private static void triFusionUnite(Unite tableau[],int deb,int fin)
+        {
+        if (deb!=fin)
+            {
+            int milieu=(fin+deb)/2;
+            triFusionUnite(tableau,deb,milieu);
+            triFusionUnite(tableau,milieu+1,fin);
+            fusionUnite(tableau,deb,milieu,fin);
+            }
+        }
+    
+   private static void fusionUnite(Unite tableau[],int deb1,int fin1,int fin2)
+        {
+        int deb2=fin1+1;
+
+        //on recopie les éléments du début du tableau
+        Unite table1[]=new Unite[fin1-deb1+1];
+        for(int i=deb1;i<=fin1;i++)
+            {
+            table1[i-deb1]=tableau[i];
+            }
+        
+        int compt1=deb1;
+        int compt2=deb2;
+        
+        for(int i=deb1;i<=fin2;i++)
+            {        
+            if (compt1==deb2) //c'est que tous les éléments du premier tableau ont été utilisés
+                {
+                break; //tous les éléments ont donc été classés
+                }
+            else if (compt2==(fin2+1)) //c'est que tous les éléments du second tableau ont été utilisés
+                {
+                tableau[i]=table1[compt1-deb1]; //on ajoute les éléments restants du premier tableau
+                compt1++;
+                }
+            else if (table1[compt1-deb1].getDeb()<tableau[compt2].getDeb())
+                {
+                tableau[i]=table1[compt1-deb1]; //on ajoute un élément du premier tableau
+                compt1++;
+                }
+            else
+                {
+                tableau[i]=tableau[compt2]; //on ajoute un élément du second tableau
+                compt2++;
+                }
+            }
+        }
+   
+    //permet de trier les unités d'une arrayList
+  //la relation d'ordre entre les unités est la comparaison des positions de débuts des unités au sein du texte 
+  public static void triFusionUnite(ArrayList<Unite> tableau)
+        {
+        int longueur=tableau.size();
+        if (longueur>0)
+            {
+            triFusionUnite(tableau,0,longueur-1);
+            }
+        }
+
+  private static void triFusionUnite(ArrayList<Unite> tableau,int deb,int fin)
+        {
+        if (deb!=fin)
+            {
+            int milieu=(fin+deb)/2;
+            triFusionUnite(tableau,deb,milieu);
+            triFusionUnite(tableau,milieu+1,fin);
+            fusionUnite(tableau,deb,milieu,fin);
+            }
+        }
+    
+   private static void fusionUnite(ArrayList<Unite> tableau,int deb1,int fin1,int fin2)
+        {
+        int deb2=fin1+1;
+
+        //on recopie les éléments du début du tableau
+        Unite table1[]=new Unite[fin1-deb1+1];
+        for(int i=deb1;i<=fin1;i++)
+            {
+            table1[i-deb1]=tableau.get(i);
+            }
+        
+        int compt1=deb1;
+        int compt2=deb2;
+        
+        for(int i=deb1;i<=fin2;i++)
+            {        
+            if (compt1==deb2) //c'est que tous les éléments du premier tableau ont été utilisés
+                {
+                break; //tous les éléments ont donc été classés
+                }
+            else if (compt2==(fin2+1)) //c'est que tous les éléments du second tableau ont été utilisés
+                {
+                tableau.add(i, table1[compt1-deb1]); //on ajoute les éléments restants du premier tableau
+                tableau.remove(i+1);
+                compt1++;
+                }
+            else if (table1[compt1-deb1].getDeb()<tableau.get(compt2).getDeb())
+                {
+                tableau.add(i,table1[compt1-deb1]); //on ajoute un élément du premier tableau
+                tableau.remove(i+1);
+                compt1++;
+                }
+            else
+                {
+                tableau.add(i,tableau.get(compt2)); //on ajoute un élément du second tableau
+                tableau.remove(i+1);
+                compt2++;
+                }
+            }
+        }
+   
+  //permet de créer un ensemble de points à intervalle régulier entre deux bornes
+  public static int[] discretisation(int deb, int fin, int nbpoints){
+      int[] subdivision = new int[nbpoints];
+      try{
+        int pas  = (fin - deb)/(nbpoints - 1);
+        for(int i = 0; i < nbpoints;i++){
+            subdivision[i] = deb + i * pas; 
+         }
+      }
+      catch(ArithmeticException e){
+          subdivision[0] = (deb + fin) / 2;
+      }
+      return subdivision;
+  }
+  
+  //@require : les paragraphes et les unités sont triés dans l'ordre
+  //@ensures : retourne une table associant les unités à leur numero de
+  //paragraphe
+  public static HashMap<Unite,Integer> unitenumeroparagraphe(Unite[] unites,Vue vue){ 
+    HashMap<Unite,Integer> numeroparagraphe = new HashMap<Unite,Integer>(unites.length);
+    int[] noparagraphe = (vue.getCorpus()).calculerNoParagraphe(unites); 
+    for(int i = 0; i < unites.length;i++){//pour toutes les unites 
+        numeroparagraphe.put(unites[i],noparagraphe[i]);
+    }
+    return numeroparagraphe; 
+  }  
+  //le nouveau type s'appellera "tout"
+  //attention les relations ne sont pas copiées pour vérifier pour maintenir le lien entre les unités
+  public static void fusionTypeUnite(Vue vue){
+      //on initialise les propriétés du nouveau type
+      long deb = System.nanoTime();
+    HashSet<String> nomsChamps = new HashSet(); 
+    for(String champ : (vue.getTypesUnitesAVoir().length==0 ? new String[0] : 
+            vue.getNomsChamps(Unite.class, vue.getTypesUnitesAVoir()[0]))){
+          nomsChamps.add(champ);
+    }
+    //les propriétés du nouveau seront l'intersection des propriétés de tous les types
+    for(String type : vue.getTypesUnitesAVoir()){
+        HashSet<String> nomsChampNonFiltres = (HashSet<String>) nomsChamps.clone();
+        nomsChamps = new HashSet();
+        for(String champ : vue.getNomsChamps(Unite.class, type)){
+            //si le champ est partagé par tous les autres types d'unités déjà passé en revue
+            //alors on l'ajoute à l'intersection provisoire
+            if(nomsChampNonFiltres.contains(champ)){
+                nomsChamps.add(champ);
+            }
+        }
+    }
+    //on parcours toutes les unités
+    for(String type : vue.getTypesUnitesAVoir()){
+        for(Unite unit : vue.getUnites(type)){
+            Unite cloneUnite = new Unite("tout",unit.getDeb(),unit.getFin());
+            for(String champ : nomsChamps){
+                cloneUnite.putProp(champ, vue.getValeurChamp(unit, champ));
+            }
+            vue.getCorpus().addUniteConvertit(cloneUnite);
+            //on ajoute la nouvelle unité aux autre schemas
+            for(Schema schemasContenant : unit.getSchemas()){
+                vue.getCorpus().ajouterElementSchemaSaisi(cloneUnite, schemasContenant);
+            }
+        }
+    }
+    long fin = System.nanoTime();
+    System.out.println((fin-deb)/1000000);
+    }  
+    //crée un type de schéma et les schémas correspondant à partir des choix de l'utilisateur
+  /*Deux éléments d'une même relation appartiennent au même Schéma et on crée un shéma 
+     pour chaque valeur différente d'une propriété de la relation*/
+  public static Schema[] conversion(String source,String nomType,String typeSource,String primaryKey, String[] otherKey,
+          Vue vue){
+      ArrayList<Schema> retour = new ArrayList();
+      HashMap<String,Schema> triSchema = new HashMap(); 
+       long deb = System.nanoTime();
+      switch(source){
+          case "Relation" :
+              Relation[] donnees = vue.getRelations(typeSource);
+              //pour toutes les relations
+              for(Relation Rel : donnees){
+                  String valeur = vue.getValeurChamp(Rel, primaryKey);
+                  //si aucun schema n'a la même valeur que la relation pour la clé primaire
+                  if(!triSchema.containsKey(valeur)){
+                      triSchema.put(valeur, new Schema(nomType));
+                      HashMap<String,String> propSchema = triSchema.get(valeur).getProps();
+                      //le schema prend les mêmes propriétés que le schéma
+                      for(String champ : Rel.getProps().keySet()){
+                          propSchema.put(champ, Rel.getProp(champ));
+                      }
+                  }
+                  triSchema.get(valeur).ajouter(Rel.getElt1());
+                  triSchema.get(valeur).ajouter(Rel.getElt2());
+              }
+              break;
+          case "typeUnite" :
+              //pour tous les types d'unités on crée un schéma
+              String[] typesUnites = vue.getTypesUnitesAVoir();
+              for(String type : typesUnites){
+                  triSchema.put(type,new Schema(nomType));
+                  HashMap<String,String> propSchema = triSchema.get(type).getProps();
+                  propSchema.put("type",type);
+                  for(Unite unit : vue.getUnites(type)){
+                    triSchema.get(type).ajouter(unit);
+                  }
+              }
+              break;
+          case "attributUnite" :
+              Unite[] UnitesAVoir = vue.getUnites(typeSource);
+              //pour toutes les unités
+              for(Unite unit : UnitesAVoir){
+                  String valeur = vue.getValeurChamp(unit, primaryKey);
+                  //si aucun schéma n'a la même valeur que l'unité pour la clé primaire
+                  if(!triSchema.containsKey(valeur)){
+                      triSchema.put(valeur, new Schema(nomType));
+                      HashMap<String,String> propSchema = triSchema.get(valeur).getProps();
+                      //le nouveau schéma prend les mêmes propriétés que l'unité
+                      propSchema.put(primaryKey, unit.getProp(primaryKey));
+                      for(String champ : otherKey){
+                          propSchema.put(champ, unit.getProp(champ));
+                      }
+                  }
+                  triSchema.get(valeur).ajouter(unit);
+              }
+              break;
+          default :
+              break;
+              
+      }
+      for(String valeur : triSchema.keySet()){
+          vue.getCorpus().addSchemaConvertit(triSchema.get(valeur));
+      }
+    long fin = System.nanoTime();
+    System.out.println((fin-deb)/1000000);
+      
+      return retour.toArray(new Schema[0]);
+  }
+  
+   //calcule les donnees nécessaires pour l'affichage du graphique dont l'axe des abscisses est le numéro de 
+   //paragraphe
+   public static HashMap<Integer,HashMap<String,Integer>> calculedonneecourbe(String[] typesdispo,String unitecomptage, Vue vue){
+       HashMap<Integer,HashMap<String,Integer>> donnees = new HashMap(); 
+       String texte =  vue.getCorpus().getTexte();
+       Integer[] noparagraphes = vue.getCorpus().getFinParagraphes();
+       int unitecourante = 0;
+       int paragraphecourant = 0;
+       int comptemot = 0;
+       int sommeUniteComptage = 0;
+       HashMap<Unite,Schema> chainesUnitesNonFiltrees = calculerChainesUnitesNonFiltrees(typesdispo,vue);
+       HashSet<Schema> chaineparagraphe = new HashSet();
+       Unite[] unites = ChaineUtil.getUniteesTrieesEtFiltrees(typesdispo,vue);
+       //initialisation
+       for(int i = 0;i < noparagraphes.length;i++){
+           donnees.put(i,new HashMap());
+           donnees.get(i).put("Nombre de Chaines de coreference",0);
+           donnees.get(i).put("Nombre de chainons",0);
+           donnees.get(i).put("ratio nombre de chainons par nombre de " + unitecomptage,0);
+           donnees.get(i).put("Densité référentielle",0);
+       }
+       for(int i = 0; i < texte.length();i++){
+           if(i > noparagraphes[paragraphecourant] || i == texte.length() - 1){
+               donnees.get(paragraphecourant).put("Nombre de Chaines de coreference",chaineparagraphe.size());
+               donnees.get(paragraphecourant).put("ratio nombre de chainons par nombre de " + unitecomptage,
+                     Math.round(sommeUniteComptage * 100.0f / (unitecomptage.equals("Mots") ? comptemot : 
+                             (noparagraphes[paragraphecourant] - (paragraphecourant==0 ? 0 : 
+                                     noparagraphes[paragraphecourant - 1])))));
+               donnees.get(paragraphecourant).put("Densité référentielle",
+                       Math.round((100.0f * donnees.get(paragraphecourant).get("Nombre de chainons")) / 
+                               (unitecomptage=="Mots" ? comptemot : (noparagraphes[paragraphecourant] - 
+                                       (paragraphecourant==0 ? 0 :  noparagraphes[paragraphecourant - 1])))));
+               chaineparagraphe = new HashSet();
+               paragraphecourant = paragraphecourant + 1;
+               comptemot = 1;
+               sommeUniteComptage = 0;
+           }
+           //si on decouvre une unité
+           while(unitecourante < unites.length && unites[unitecourante].getDeb()==i){
+               if(chainesUnitesNonFiltrees.containsKey(unites[unitecourante])){
+               donnees.get(paragraphecourant).put("Nombre de chainons", 
+                       (int) donnees.get(paragraphecourant).get("Nombre de chainons") + 1);
+               chaineparagraphe.add(chainesUnitesNonFiltrees.get(unites[unitecourante]));
+               sommeUniteComptage = sommeUniteComptage + (unitecomptage=="Mots" ? 
+                       ChaineUtil.nbMotsDansUneUnite(unites[unitecourante].getDeb(),unites[unitecourante].getFin(),vue)
+                       : unites[unitecourante].getFin() - unites[unitecourante].getDeb());
+               }
+               unitecourante = unitecourante + 1;
+           }
+            //si on change de mot
+            if(unitecomptage.equals("Mots") && texte.charAt(i)==' '){
+                comptemot = comptemot + 1;
+            }
+       }
+       
+       return donnees;
+   }
+   
+
+  //struture qui n'est pas filtrées mais qui associe à une unité qui correspond au bon type d'unités
+  //contenu dans "typeUnités" la chaine qui la contient et qui est elle aussi du bon type de Schéma
+  private static HashMap<Unite,Schema> calculerChainesUnitesNonFiltrees(String[] typeUnites, Vue vue) throws UnsupportedOperationException {
+    HashMap<Unite,Schema> chainesUnitesNonFiltrees = new HashMap();
+    for(String typechaine : vue.getTypesSchemasAVoir()){
+        Schema[] chaines = vue.getSchemas(typechaine);
+        for (Schema chaine : chaines){
+            HashSet<Element> contenu = chaine.getContenu();
+          for (Element elt : contenu) {
+            if (elt.getClass()==Unite.class && ChaineUtil.tableauRecherche(typeUnites,elt.getType())) {
+              if (chainesUnitesNonFiltrees.containsKey(elt)) {
+                throw new UnsupportedOperationException("L'unité "+vue.getIdElement(elt)
+                        +" appartient à deux chaînes : "+vue.getIdElement(chaine)+" et "
+                        +vue.getIdElement(chainesUnitesNonFiltrees.get((Unite) elt)));
+              } else
+                chainesUnitesNonFiltrees.put((Unite) elt, chaine);
+            }
+          }
+        }
+    }
+    return chainesUnitesNonFiltrees;
+  }
+  
+  //renvoie la valeur en un point d'un polynome interpolé à partir de deux tableau représentant les coordonnées de points
+  public static Integer interpolationLagrangienne(Integer[] abscisse,Integer[] ordonnee,int value){
+      if(abscisse.length == ordonnee.length){
+          Double retour = 0.0d; 
+          for(int i = 0;i<abscisse.length;i++ ){
+              Double produit = 1.0d ;
+              for(int j = 0; j < abscisse.length;j++){
+                  if(i!=j){
+                      produit = produit * (value - abscisse[j]) / (abscisse[i] - abscisse[j]);
+                  }
+              }
+              retour = retour + produit * ordonnee[i];
+          }
+          return (Math.round(retour)<0 ? 0 : (int) Math.round(retour));
+          
+      }
+      return -1;
+  }
+  /*@require: abscisse and length have the same length*/
+  public static ArrayList<Float[]> coef_spline_quad(Integer[] abscisse,Integer[] ordonnee){
+      Float[] coef_abs =  new Float[abscisse.length];
+      Float[] coef_ord =  new Float[ordonnee.length];
+      ArrayList<Float[]> retour  = new ArrayList();
+      coef_abs[0] = 0.0f;
+      for(int i = 1 ; i < abscisse.length;i++){
+          coef_abs[i] = 1.0f*2*(ordonnee[i]-ordonnee[i-1])/(abscisse[i]-abscisse[i-1]);
+          coef_ord[i] = ordonnee[i-1] + coef_abs[i-1] * (abscisse[i]-abscisse[i-1]) / 2 ;
+          
+      }
+      retour.add(coef_abs);
+      retour.add(coef_ord);
+      return retour;
+      
+  }
+  /*@require: abscisse and length have the same length superior to 2*/
+  public static Integer interpolation_spline_quad(Integer[] abscisse,Integer[] ordonnee,int value){
+      float retour;
+      ArrayList<Float[]> coef = coef_spline_quad(abscisse,ordonnee);
+      retour = coef.get(1)[1];
+      for(int i = 1; i < abscisse.length;i++){
+          if(value > abscisse[i-1] && value < abscisse[i]){
+              retour = 0 - coef.get(0)[i-1] * (value - abscisse[i]) * (value - abscisse[i]) + coef.get(0)[i]
+                       * (value - abscisse[i-1]) * (value - abscisse[i-1])/2/(abscisse[i]-abscisse[i-1])
+                      + coef.get(1)[i];
+          }
+      }
+      return  Math.round(retour);
+  }
+      
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/ChaineUtil.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuCoref.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuCoref.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuCoref.java	(revision 481)
@@ -0,0 +1,1134 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.chaines;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import org.jfree.chart.ChartPanel;
+import visuAnalec.*;
+import visuAnalec.elements.*;
+import visuAnalec.fichiers.FichiersJava;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.GAction;
+import visuAnalec.util.GVisu.LegendeLabel;
+import visuAnalec.util.GVisu.LegendeModeleTable;
+import visuAnalec.util.GVisu.LegendeModeleTableTexte;
+import visuAnalec.util.GVisu.TypeComboBox;
+import visuAnalec.util.GVisu.Val0ComboBox;
+import visuAnalec.vue.*;
+/**
+ *
+ * @author Marc
+ */
+public class VisuCoref extends JFrame implements Vue.VueListener, ActionListener{
+  private static final int[] seuilsValsNbElts = {3, 10};
+  private static final Color[] couleursNbElts = {Color.WHITE, GVisu.getCouleurSansValeur(),
+    GVisu.getCouleur(0), GVisu.getCouleur(3), GVisu.getCouleur(1)};
+  private static final String[] labelsNbElements = {
+    "pas de chaîne associée",
+    "chaîne d'un seul chaînon",
+    "chaîne de 2-"+Integer.toString(seuilsValsNbElts[0])+" chaînons",
+    "chaîne de "+Integer.toString(seuilsValsNbElts[0]+1)+"-"
+    +Integer.toString(seuilsValsNbElts[1])+"  chaînons",
+    "chaîne de plus de "+Integer.toString(seuilsValsNbElts[1])+" chaînons"
+  };
+  private final Vue vue;
+  private final JMenuBar menuBar = new JMenuBar();
+  private final ModeleChaines donneesChaines;
+  private String typeChaines;
+  private String typeUnites;
+  private String[] valsAffichees;
+  private HashSet<String> valsAffichees1cachees = new HashSet();
+  private ArrayList<Integer> noparagraphecachees = new ArrayList();
+  private String[] valsAffichees1;
+  private Integer[] valsAffichees2;
+  private final TypeComboBox saisieTypeChaines;
+  private final TypeComboBox saisieTypeUnites;
+  private Val0ComboBox saisieChampAffiche;
+  private Val0ComboBox saisieChampChaine;  
+  private final Val0ComboBox saisieChampStatistique;  
+  private JTable legendeChampAffiche;
+  private JTable legendeChampAfficheChaine;
+  private JTable legendeChampAfficheParagraphe;
+  private LegendeModeleTable legendeChampAfficheModele;
+  private LegendeModeleTableTexte legendeChampAfficheChaineModele;
+  private LegendeModeleTableTexte legendeChampAfficheParagrapheModele;  
+  private JPopupMenu popupChamp = new JPopupMenu();
+  private JPopupMenu popupChampChaine = new JPopupMenu();
+  private JPopupMenu popupChampParagraphe = new JPopupMenu();
+  private final JCheckBox activehistogramme;
+  private final Box listeGChaines;
+  private JTable ResultatStat;
+  private final HashSet<GChaines> suiteGChaines = new HashSet();
+  private final String[] statpossibles = new String[]{"Répartition des références par paragraphe",
+      "Répartition des paragraphes par référence","Répartition des paragraphe par valeur du champ",
+      "Répartition des valeurs du champ par paragraphe","Répartition des valeurs de champ par référence",
+      "Répartition des références par valeur de champ","Répartition par paragraphe et par réfences "
+          + "des valeurs du champ","Répartition par paragraphe et par valeur du champ des références",
+       "Répartition par référence et par valeur de champ des paragraphes"};
+  
+  
+  public VisuCoref(Container fenetre, Vue vue, PanneauEditeur pEditeur) {
+    super("Analyse d'une chaine de coréférence");
+    Point pos = new Point(fenetre.getX()+20, fenetre.getY()+20);
+    Dimension dim = new Dimension(fenetre.getWidth(), fenetre.getHeight());
+    setLocation(pos);
+    setSize(dim);
+    this.vue = vue;
+    vue.addEventListener(this);
+    saisieTypeChaines = new TypeComboBox(Schema.class);
+    saisieTypeChaines.setModele(vue.getTypesSchemasAVoir());
+    saisieTypeChaines.addActionListener(this);
+    saisieTypeUnites = new TypeComboBox(Unite.class);
+    saisieTypeUnites.setModele(vue.getTypesUnitesAVoir());
+    saisieTypeUnites.addActionListener(this);
+    saisieChampAffiche = new Val0ComboBox("Nombre de chaînons");
+    saisieChampAffiche.addActionListener(this);
+    saisieChampChaine = new Val0ComboBox("Rien");
+    saisieChampChaine.addActionListener(this); 
+    saisieChampStatistique = new Val0ComboBox("Rien");
+    saisieChampStatistique.addActionListener(this);
+    Box commandes = Box.createVerticalBox();
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Chaînes : "));
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(saisieTypeChaines);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Unites : "));
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(saisieTypeUnites);
+    commandes.add(Box.createVerticalGlue());    
+    activehistogramme = new JCheckBox("Afficher les histogrammes de répartition");
+    commandes.add(activehistogramme);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Champ à filtrer : "));
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(saisieChampAffiche);
+    commandes.add(Box.createVerticalGlue());
+    
+    legendeChampAffiche = new JTable();
+    legendeChampAffiche.addMouseListener(new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+        check(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInit(legendeChampAffiche.rowAtPoint(e.getPoint()));
+          popupChamp.show(legendeChampAffiche, e.getX(), e.getY());
+        }
+      }
+    });
+    
+    commandes.add(legendeChampAffiche);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Champ de la chaine à analyser : "));
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(saisieChampChaine);
+    commandes.add(Box.createVerticalGlue());
+    
+    legendeChampAfficheParagraphe = new JTable();
+    //legendeChampAfficheParagraphe.setCellRenderer(new LegendeCellRenderer());
+    legendeChampAfficheParagraphe.addMouseListener(new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+        check(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInitParagraphe(legendeChampAfficheParagraphe.rowAtPoint(e.getPoint()));
+          popupChampParagraphe.show(legendeChampAfficheParagraphe, e.getX(), e.getY());
+        }
+      }
+    });
+    
+    
+
+    legendeChampAfficheChaine = new JTable();
+    //legendeChampAfficheChaine.setCellRenderer(new LegendeCellRenderer());
+    legendeChampAfficheChaine.addMouseListener(new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+        check(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInitChaine(legendeChampAfficheChaine.rowAtPoint(e.getPoint()));
+          popupChampChaine.show(legendeChampAfficheChaine, e.getX(), e.getY());
+        }
+      }
+    });
+    commandes.add(legendeChampAfficheChaine); 
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Paragraphe à filtrer : "));
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(legendeChampAfficheParagraphe);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Sélectionner une statistique : "));
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(saisieChampStatistique);
+    JScrollPane scrollLegende = new JScrollPane(commandes);
+    listeGChaines = Box.createVerticalBox();
+    JScrollPane scrollList = new JScrollPane(listeGChaines);
+    Box resultatstat = Box.createVerticalBox();
+    resultatstat.add(Box.createVerticalGlue());
+    resultatstat.add(new JLabel("Statistique : "));
+    resultatstat.add(Box.createVerticalGlue());
+    ResultatStat = new JTable(new ModeleStatChaine());
+    JScrollPane jsp =new JScrollPane(ResultatStat);
+    resultatstat.add(ResultatStat.getTableHeader());
+    resultatstat.add(jsp);
+    JScrollPane scrollstatresultat = new JScrollPane(resultatstat);
+    JSplitPane split1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT,scrollList,scrollstatresultat);
+    JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,scrollLegende,split1);    
+    getContentPane().add(split);
+    setVisible(true);    
+    split.setDividerLocation(1./3);
+    split1.setDividerLocation(1./2);
+    setJMenuBar(menuBar);
+    JMenu corpusMenu = new JMenu("Paramètres d'affichage");
+    menuBar.add(corpusMenu);
+    corpusMenu.add(new GAction("Reprendre un affichage") {
+      @Override
+      public void executer() {
+         importerAffichage();
+      }
+    });
+    corpusMenu.add(new GAction("Sauver les paramètres d'affichage") {
+      @Override
+      public void executer() {
+         exporterAffichage();
+      }
+    });   
+    JMenu csvMenu = new JMenu("Exporter les données");
+    final VisuCoref visu = this;
+    final Vue vues = this.vue;
+    final PanneauEditeur pEditeurs = pEditeur;
+    menuBar.add(csvMenu);
+    csvMenu.add(new GAction("Exporter les données de filtrage") {
+      @Override
+      public void executer() {
+          new ExportCSV(getContentPane(),vues,pEditeurs,visu);
+      }
+    });
+    csvMenu.add(new GAction("Exporter le tableau statistique") {
+      @Override
+      public void executer() {
+          Object[][] donneesCSV = new Object[ResultatStat.getRowCount()+1][ResultatStat.getColumnCount()];
+         for(int i = 0 ; i < ResultatStat.getRowCount();i++){
+             for(int j = 0 ; j < ResultatStat.getColumnCount();j++){
+                donneesCSV[i+1][j]=ResultatStat.getValueAt(i, j);
+             }
+         }
+             for(int j = 0 ; j < ResultatStat.getColumnCount();j++){
+                donneesCSV[0][j]=ResultatStat.getColumnName(j);
+             }
+             
+             ExportCSV.exporterCSV(donneesCSV);
+      }
+    }); 
+    csvMenu.add(new GAction("Exporter les fréquences pour le champ des unités") {
+      @Override
+      public void executer() {
+          Object[][] donneesCSV = new Object[legendeChampAffiche.getRowCount()+1][2];
+         for(int i = 0 ; i < legendeChampAffiche.getRowCount();i++){
+                donneesCSV[i+1][0]=legendeChampAffiche.getValueAt(i, 1);
+                donneesCSV[i+1][1]=legendeChampAffiche.getValueAt(i, 2)==null ? "0" 
+                        : legendeChampAffiche.getValueAt(i, 2);
+         }
+                donneesCSV[0][1]="frequence";
+                donneesCSV[0][0]=saisieChampAffiche.pasdeSelection() ? "Nombre de Chainons"
+                        : saisieChampAffiche.getSelection();
+             ExportCSV.exporterCSV(donneesCSV);
+      }
+    }); 
+    csvMenu.add(new GAction("Exporter les fréquences pour le champ des chaines") {
+      @Override
+      public void executer() {
+          if(!saisieChampChaine.pasdeSelection()){
+            Object[][] donneesCSV = new Object[legendeChampAfficheChaine.getRowCount()+1][2];
+           for(int i = 0 ; i < legendeChampAfficheChaine.getRowCount();i++){
+                  donneesCSV[i+1][0]=legendeChampAfficheChaine.getValueAt(i, 1);
+                donneesCSV[i+1][1]=legendeChampAfficheChaine.getValueAt(i, 2)==null ? "0" 
+                        : legendeChampAfficheChaine.getValueAt(i, 2);
+           }
+                  donneesCSV[0][1]="frequence";
+                  donneesCSV[0][0]=saisieChampChaine.getSelection();
+                  ExportCSV.exporterCSV(donneesCSV);
+          }
+      }
+    });
+    JMenu typeMenu = new JMenu("Fusionner des types d'unités");
+    menuBar.add(typeMenu);
+    final Vue vueconv = vue;
+    typeMenu.add(new GAction("Fusionner tous les types") {
+      @Override
+      public void executer() {
+          JOptionPane jop = new JOptionPane();			
+          int option = jop.showConfirmDialog(null, "Voulez-créer un nouveau type rassemblant tous les autres ?"
+                  +System.getProperty("line.separator")+"Si oui, la fenêtre de visualisation des chaines se fermera pour mettre à jour les annotations."
+                  , "Création d'un type d'unités", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
+			
+          if(option == JOptionPane.OK_OPTION){
+                ChaineUtil.fusionTypeUnite(vueconv);
+                fermerFenetre();
+          }
+      }
+    });   
+    saisieTypeChaines.setAlignmentX(0);
+    saisieTypeUnites.setAlignmentX(0);
+    saisieChampAffiche.setAlignmentX(0);
+    saisieChampChaine.setAlignmentX(0);
+    saisieChampStatistique.setAlignmentX(0);
+    legendeChampAffiche.setAlignmentX(0);
+    legendeChampAfficheChaine.setAlignmentX(0);
+    legendeChampAfficheParagraphe.setAlignmentX(0);
+    
+        // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+    donneesChaines = new ModeleChaines(vue, new GChaines(this));
+    if (saisieTypeChaines.nbItems()==1) {
+      saisieTypeChaines.setSelection(0);
+      if (saisieTypeUnites.nbItems()==1) saisieTypeUnites.setSelection(0);
+      else saisieTypeUnites.effSelection();
+    } else {
+      saisieTypeChaines.effSelection();
+      saisieTypeUnites.effSelection();
+    }
+  }
+
+  private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+  }
+  @Override
+  public void traiterEvent(Message evt) { // très grossier : à améliorer
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre chaines présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        fermerFenetre();
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        fermerFenetre();
+        return;
+      case MODIF_ELEMENT:
+//        ElementEvent evtE = (ElementEvent) evt;
+//        if (evtE.getModif() != TypeModifElement.BORNES_UNITE) fermerFenetre();
+        fermerFenetre();
+        return;
+      case CORPUS_SAVED:
+          fermerFenetre();
+          return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+    
+  @Override
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource().equals(saisieTypeChaines)
+              ||evt.getSource().equals(saisieTypeUnites)) {
+        if (saisieTypeChaines.pasdeSelection()||saisieTypeUnites.pasdeSelection()) {
+          initVide();
+          return;
+        }
+        try {
+          init();
+        } catch (UnsupportedOperationException ex) {
+          GMessages.impossibiliteAction("Erreur de type : "+ex.getMessage());
+          initVide();
+          return;
+        }
+        return;
+      }
+      if (evt.getSource().equals(saisieChampAffiche)) {
+          if(!saisieTypeChaines.pasdeSelection()&&!saisieTypeUnites.pasdeSelection()){
+           if (saisieChampAffiche.pasdeSelection()) initCouleursNbElts();
+           else initCouleursChamp(saisieChampAffiche.getSelection());
+           afficherchaines();
+          }
+        return;
+      }
+    if (evt.getSource().equals(saisieChampChaine)) {
+        initChaineChamp();
+        afficherchaines();
+        return;
+      }
+      if (evt.getSource().equals(saisieChampStatistique)) {
+        afficherstat();
+        return;
+      }  
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  
+    private void initVide() {
+    donneesChaines.permettreaffichage(false);
+    typeChaines = null;
+    typeUnites = null;
+    donneesChaines.initVide();
+    saisieChampAffiche.setModeleVide();
+    saisieChampChaine.setModeleVide();
+    saisieChampStatistique.setModeleVide();
+    legendeChampAfficheModele = new LegendeModeleTable(new String[]{"icone","nom du champ"},new LegendeLabel[0],new HashMap());
+    legendeChampAffiche.setModel(legendeChampAfficheModele);
+    legendeChampAfficheChaineModele = new LegendeModeleTableTexte(new String[]{"Affiché","nom du champ","frequence"},new LegendeLabel[0],new HashMap());
+    legendeChampAfficheChaine.setModel(legendeChampAfficheChaineModele);
+    legendeChampAfficheParagrapheModele = new LegendeModeleTableTexte(new String[]{"Affiché","nom du champ","frequence"},new LegendeLabel[0],new HashMap());
+    legendeChampAfficheParagraphe.setModel(legendeChampAfficheParagrapheModele);
+  }
+    private void init() throws UnsupportedOperationException {
+    donneesChaines.permettreaffichage(false);
+    typeChaines = saisieTypeChaines.getTypeSelection();
+    typeUnites = saisieTypeUnites.getTypeSelection();
+    donneesChaines.init(typeChaines, typeUnites, seuilsValsNbElts);
+    initParagraphechamp();
+    initCouleursNbElts();
+    afficherchaines();
+    saisieChampAffiche.removeActionListener(this);
+    saisieChampAffiche.setModele(vue.getNomsChamps(Unite.class, typeUnites));
+    saisieChampAffiche.addActionListener(this);
+    saisieChampChaine.removeActionListener(this);
+    saisieChampChaine.setModele(vue.getNomsChamps(Schema.class, typeChaines));
+    saisieChampChaine.addActionListener(this);
+    saisieChampStatistique.removeActionListener(this);
+    saisieChampStatistique.setModele(statpossibles);
+    saisieChampStatistique.addActionListener(this);    
+    //histochaine.changeHistogramme(donneesChaines.dispositionunites(10),Color.BLUE,this,200);
+    //initstat();
+
+  }
+ 
+    private void initCouleursNbElts() {
+    if(!saisieChampChaine.pasdeSelection()){
+    donneesChaines.setChampAfficheNbElts(couleursNbElts);
+    }
+    if(!donneesChaines.peutetreafficher()){
+        HashMap<String, Float> freq = donneesChaines.calculerfrequencenbelt
+        (ChaineUtil.filtreparagraphe(saisieChampChaine.pasdeSelection() ? donneesChaines.getUnites() : 
+                donneesChaines.filtrechaine( donneesChaines.getUnites(), saisieChampChaine.getSelection(),
+                        valsAffichees1cachees),noparagraphecachees,vue),typeUnites,labelsNbElements); 
+        legendeChampAfficheModele = new LegendeModeleTable(new String[]{"icone","nom du champ","frequence"},
+                creerLegendesNbElements(),freq);
+        legendeChampAffiche.setModel(legendeChampAfficheModele);
+        legendeChampAffiche.getColumnModel().getColumn(0).setMaxWidth(50);    
+        legendeChampAffiche.getColumnModel().getColumn(2).setMaxWidth(50);
+        legendeChampAffiche.setRowHeight(30);
+    }
+  }
+    
+  private LegendeLabel[] creerLegendesNbElements() {
+    LegendeLabel[] legendes = new LegendeLabel[couleursNbElts.length];
+    for (int i = 0; i<legendes.length; i++)
+      legendes[i] = new LegendeLabel(labelsNbElements[i],
+              donneesChaines.isMasqueeValNbElements(i) ? null : couleursNbElts[i]);
+    return legendes;
+  }
+    
+    private void initCouleursChamp(String champ) {
+    valsAffichees = vue.getValeursChamp(Unite.class, typeUnites, champ);
+    HashMap<String, Color> couleursValeursChamp = new HashMap<String, Color>();
+    for (int i = 0, nocolor = 0; i<valsAffichees.length; i++)
+      if (!donneesChaines.isMasqueeValChamp(champ, valsAffichees[i]))
+        couleursValeursChamp.put(valsAffichees[i], GVisu.getCouleur(nocolor++));
+    if (!donneesChaines.isMasqueeValNulleChamp(champ))
+      couleursValeursChamp.put("", GVisu.getCouleurSansValeur());
+    donneesChaines.setChampAffiche(champ, couleursValeursChamp);
+    if(!donneesChaines.peutetreafficher()){
+        HashMap<String, Float> freq = ChaineUtil.calculerfrequencechamp
+    (ChaineUtil.filtreparagraphe(saisieChampChaine.pasdeSelection() ? donneesChaines.getUnites() : 
+            donneesChaines.filtrechaine(donneesChaines.getUnites(), saisieChampChaine.getSelection(),
+                    valsAffichees1cachees),noparagraphecachees,vue),typeUnites, champ,vue);
+        ChaineUtil.triFusionMap(valsAffichees,freq);
+        legendeChampAfficheModele = new LegendeModeleTable(new String[]{"icone","nom du champ","frequence"},
+                creerLegendesChamp(valsAffichees,couleursValeursChamp),freq);
+        legendeChampAffiche.setModel(legendeChampAfficheModele);
+        legendeChampAffiche.getColumnModel().getColumn(0).setMaxWidth(50);    
+        legendeChampAffiche.getColumnModel().getColumn(2).setMaxWidth(50);
+        legendeChampAffiche.setRowHeight(30);
+    }
+  }
+    
+  private LegendeLabel[] creerLegendesChamp(String[] valsAffichees,
+          HashMap<String, Color> couleursValeursChamp) {
+    LegendeLabel[] legendes = new LegendeLabel[valsAffichees.length+1];
+    for (int i = 0; i<valsAffichees.length; i++)
+      legendes[i] = new LegendeLabel(valsAffichees[i],
+              couleursValeursChamp.get(valsAffichees[i]));
+    legendes[valsAffichees.length] = new LegendeLabel("<aucune valeur>",
+            couleursValeursChamp.get(""));
+    return legendes;
+  }
+    
+    //initialise la Jlist des paragraphes
+    private void initParagraphechamp(){
+    valsAffichees2 = donneesChaines.listenumeroparagraphe();
+    LegendeLabel[] legende = new LegendeLabel[valsAffichees2.length];
+    for(int i = 0; i < valsAffichees2.length; i++){
+        int debutParagraphe = valsAffichees2[i] - 2 < 0 ? 0 : vue.getCorpus().getFinParagraphes()[valsAffichees2[i] - 2];
+        //on enlève 2 au paragraphe car quand on cherche le début d'un paragraphe on cherche la fin du précédent
+        //et de plus les paragraphes commencent à 1 quand les index de tableau commencent à 1
+        int longueur = debutParagraphe < vue.getCorpus().getTexte().length() - 20 ? 20 : 
+                vue.getCorpus().getTexte().length() - debutParagraphe;
+        if(noparagraphecachees.contains(valsAffichees2[i])){
+            legende[i] = new LegendeLabel("Paragraphe" + valsAffichees2[i].toString() + "  \"" +
+                    vue.getCorpus().getTexte().substring(debutParagraphe, debutParagraphe + longueur) + "\"","Non");
+        }
+        else{
+            legende[i] = new LegendeLabel("Paragraphe" + valsAffichees2[i].toString() + "  \"" +
+                    vue.getCorpus().getTexte().substring(debutParagraphe, debutParagraphe + longueur) + "\"","Oui");
+        }
+    }
+    if(!donneesChaines.peutetreafficher()){
+        legendeChampAfficheParagrapheModele = new LegendeModeleTableTexte(new String[]{"Affiché","Paragraphe"},legende,null);
+        legendeChampAfficheParagraphe.setModel(legendeChampAfficheParagrapheModele);
+        legendeChampAfficheParagraphe.getColumnModel().getColumn(0).setMaxWidth(50);
+    }
+    }
+    
+    //initialise la legende des valeurs de la Chaine
+    private void initChaineChamp(){
+    if(!donneesChaines.peutetreafficher()){
+        valsAffichees1 = vue.getValeursChamp(Schema.class, typeChaines, saisieChampChaine.getSelection());
+        LegendeLabel[] legende = new LegendeLabel[valsAffichees1.length];
+        HashMap<String, Float> freq; 
+        freq = donneesChaines.calculerfrequencechaine
+        (ChaineUtil.filtreparagraphe(donneesChaines.getUnites(),noparagraphecachees,vue),typeChaines, saisieChampChaine.getSelection(),valsAffichees1cachees);
+        ChaineUtil.triFusionMap(valsAffichees1,freq);
+        for(int i = 0; i < valsAffichees1.length; i++){
+            if(valsAffichees1cachees.contains(valsAffichees1[i])){
+                legende[i] = new LegendeLabel(valsAffichees1[i].toString(),"Non");
+            }
+            else{
+                legende[i] = new LegendeLabel(valsAffichees1[i].toString(),"Oui");
+            }
+        }
+        legendeChampAfficheChaineModele = new LegendeModeleTableTexte(new String[]{"Affiché","Paragraphe","frequence"},legende,freq);
+        legendeChampAfficheChaine.setModel(legendeChampAfficheChaineModele);
+        legendeChampAfficheChaine.getColumnModel().getColumn(0).setMaxWidth(50);  
+        legendeChampAfficheChaine.getColumnModel().getColumn(2).setMaxWidth(50); 
+    }
+    }
+    
+    
+  private void popupChampInit(final int index) {
+    final boolean masquee;
+    String[] vals= valsAffichees;
+    Val0ComboBox zonedesaisie=saisieChampAffiche;
+    JPopupMenu popup=popupChamp;
+    popup.removeAll();
+    if (zonedesaisie.pasdeSelection()) {
+      masquee = donneesChaines.isMasqueeValNbElements(index);
+      popup.add(new GAction(masquee ? "Montrer cette valeur" : 
+              "Masquer cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValNbElements(masquee, index, false);
+        }
+      });
+      popup.add(new GAction(masquee ? "Montrer toutes les valeurs" : 
+              "Ne montrer que cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValNbElements(masquee, index, true);
+        }
+      });
+    } else if (index==vals.length) {
+      masquee = donneesChaines.isMasqueeValNulleChamp(zonedesaisie.getSelection());
+      popup.add(new GAction(masquee ? "Montrer cette valeur" : 
+              "Masquer cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValNulleChamp(masquee, false);
+        }
+      });
+     popup.add(new GAction(masquee ? "Montrer toutes les valeurs" : 
+              "Ne montrer que cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValNulleChamp(masquee, true);
+        }
+      });
+    } else {
+      masquee = donneesChaines.isMasqueeValChamp(zonedesaisie.getSelection(),
+              vals[index]);
+      popup.add(new GAction(masquee ? "Montrer cette valeur" : 
+              "Masquer cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValChamp(masquee, index, false);
+        }
+      });
+      popup.add(new GAction(masquee ? "Montrer toutes les valeurs" : 
+              "Ne montrer que cette valeur") {
+        @Override
+        public void executer() {
+          modifierStatutValChamp(masquee, index, true);
+        }
+      });
+    }
+    
+  }
+  private void modifierStatutValChamp(boolean masquee, int index, boolean tous) {
+      String[] vals;
+      Val0ComboBox zonedesaisie;
+      vals = valsAffichees;
+      zonedesaisie = saisieChampAffiche;
+    if(!tous) donneesChaines.masquerValChamp(!masquee, 
+            zonedesaisie.getSelection(), vals[index]);
+    else if(masquee) donneesChaines.demasquerToutesValsChamp( 
+            zonedesaisie.getSelection());
+    else donneesChaines.masquerAutresValsChamp(typeUnites, 
+            zonedesaisie.getSelection(), vals[index]);
+    if(!saisieChampChaine.pasdeSelection()){
+        if(saisieChampAffiche.pasdeSelection()){
+            initCouleursNbElts();
+        }
+        else{
+            initCouleursChamp(saisieChampAffiche.getSelection());
+        }
+    }
+    afficherchaines();
+  }
+  private void modifierStatutValNulleChamp(boolean masquee, boolean tous) {
+      Val0ComboBox zonedesaisie;
+      zonedesaisie = saisieChampAffiche;
+    if(!tous) donneesChaines.masquerValNulleChamp(!masquee, zonedesaisie.getSelection());
+   else if(masquee) donneesChaines.demasquerToutesValsChamp( 
+            zonedesaisie.getSelection());
+    else donneesChaines.masquerValsNonNullesChamp(typeUnites, 
+            zonedesaisie.getSelection());
+    if(!saisieChampChaine.pasdeSelection()){
+        if(saisieChampAffiche.pasdeSelection()){
+            initCouleursNbElts();
+        }
+        else{
+            initCouleursChamp(saisieChampAffiche.getSelection());
+        }
+    }
+    afficherchaines();
+  }
+  private void modifierStatutValNbElements(boolean masquee, int index, boolean tous) {
+      Val0ComboBox zonedesaisie;
+      zonedesaisie = saisieChampAffiche;
+    if(!tous) donneesChaines.masquerValNbElements(!masquee, index);
+   else if(masquee) donneesChaines.demasquerToutesValsNbElts( 
+            zonedesaisie.getSelection());
+    else donneesChaines.masquerAutresValsNbElts( 
+            zonedesaisie.getSelection(), index);
+    if(!saisieChampChaine.pasdeSelection()){    
+        if(saisieChampAffiche.pasdeSelection()){
+            initCouleursNbElts();
+        }
+        else{
+            initCouleursChamp(saisieChampAffiche.getSelection());
+        }
+    }
+    afficherchaines();
+  }
+  
+    public void afficherchaines(){
+        donneesChaines.permettreaffichage(true);
+        this.suiteGChaines.clear();
+        listeGChaines.removeAll();
+        if(!saisieChampChaine.pasdeSelection() && !saisieTypeChaines.pasdeSelection() 
+                && !saisieTypeUnites.pasdeSelection()){
+           for(String val : valsAffichees1){ //pour toutes les valeurs de la propriété de la chaine
+               if(!valsAffichees1cachees.contains(val)){
+                   listeGChaines.add(Box.createVerticalGlue());
+                   GChaines graphique =  new GChaines(this);
+                   donneesChaines.setGChaine(graphique);
+                   donneesChaines.modifMasqueValsChampChaine(saisieTypeChaines.getSelection()
+                           ,saisieTypeUnites.getSelection(),noparagraphecachees,saisieChampChaine.getSelection(),
+                           val);
+                   if(!saisieChampAffiche.pasdeSelection()){
+                        initCouleursChamp(saisieChampAffiche.getSelection());
+                   }
+                   else{
+                        initCouleursNbElts();    
+                   }
+                   listeGChaines.add(new JLabel(val+" :"));
+                   listeGChaines.add(graphique);
+                   suiteGChaines.add(graphique);
+                   if(activehistogramme.isSelected()){
+                        ChartPanel histochaine = Histogramme.histogrammeFactory();
+                        Histogramme.updatePanel(histochaine,"Répartion des unités",donneesChaines,10, Color.blue, 200,
+                                "position de l'unité","Fréquence d'unités",vue);
+                        histochaine.setMaximumSize(new Dimension(550,300));
+                        listeGChaines.add(histochaine);
+                   }
+               }
+           }
+        }
+        donneesChaines.permettreaffichage(false);
+        GChaines graphique =  new GChaines(this);
+        donneesChaines.setGChaine(graphique);
+        donneesChaines.modifMasqueVals(saisieTypeChaines.getSelection()
+            ,saisieTypeUnites.getSelection());
+        if(!saisieChampChaine.pasdeSelection()){
+            if(saisieChampAffiche.pasdeSelection()){
+                initCouleursNbElts();
+            }
+            else{
+                initCouleursChamp(saisieChampAffiche.getSelection());
+            }
+            initChaineChamp();
+            initParagraphechamp();        
+         }
+        afficherstat();
+        listeGChaines.revalidate();
+        listeGChaines.repaint();
+    }
+    private void popupChampInitChaine(final int index) {
+    final boolean masquee;
+    Val0ComboBox zonedesaisie=saisieChampChaine;
+    JPopupMenu popup=popupChampChaine;
+    popup.removeAll();
+    if (zonedesaisie.pasdeSelection()) {
+    }
+    else {
+      masquee = valsAffichees1cachees.contains(valsAffichees1[index]);
+      popup.add(new GAction(masquee ? "Montrer cette valeur de la chaine" : 
+              "Masquer cette valeur de la chaine") {
+        @Override
+        public void executer() {
+          modifierStatutValChampChaine(masquee, index, false);
+        }
+      });
+      popup.add(new GAction(masquee ? "Montrer toutes les valeurs de la chaine" : 
+              "Ne montrer que cette valeur de la chaine") {
+        @Override
+        public void executer() {
+          modifierStatutValChampChaine(masquee, index, true);
+        }
+      });
+    }
+    
+  }
+  private void modifierStatutValChampChaine(boolean masquee, int index, boolean tous) {
+    if(!tous){ 
+        if(masquee){
+            valsAffichees1cachees.remove(valsAffichees1[index]);
+        }
+        else{
+            valsAffichees1cachees.add(valsAffichees1[index]);    
+        }
+    }
+    else if(masquee){ 
+        valsAffichees1cachees.clear();
+    }
+    else{ 
+        valsAffichees1cachees.clear();
+        for(String valeur : valsAffichees1){
+            if(!valeur.equals(valsAffichees1[index])){
+                valsAffichees1cachees.add(valeur);
+            }
+        }
+    
+    }
+    initChaineChamp();
+    if(!saisieChampChaine.pasdeSelection()){
+        afficherchaines();
+    }
+  }
+  
+  private void popupChampInitParagraphe(final int index) {
+    final boolean masquee;
+    Val0ComboBox zonedesaisie=saisieChampChaine;
+    JPopupMenu popup=popupChampParagraphe;
+    popup.removeAll();
+    if (zonedesaisie.pasdeSelection()) {
+    }
+    else {
+      masquee = noparagraphecachees.contains(valsAffichees2[index]);
+      popup.add(new GAction(masquee ? "Montrer ce paragraphe" : 
+              "Masquer ce paragraphe") {
+        @Override
+        public void executer() {
+          modifierStatutValChampParagraphe(masquee, index, false);
+        }
+      });
+      popup.add(new GAction(masquee ? "Montrer tous les paragraphes" : 
+              "Ne montrer que ce paragraphe") {
+        @Override
+        public void executer() {
+          modifierStatutValChampParagraphe(masquee, index, true);
+        }
+      });
+    }
+    
+  }
+  private void modifierStatutValChampParagraphe(boolean masquee, int index, boolean tous) {
+    if(!tous){ //on masque ou demasque un paragraphe
+        if(masquee){
+            noparagraphecachees.remove(valsAffichees2[index]);
+        }
+        else{
+            noparagraphecachees.add(valsAffichees2[index]);    
+        }
+    }
+    else if(masquee){ //on demasque tous les paragraphes
+        noparagraphecachees.clear();
+    }
+    else{ //on masque tous les autres paragraphes
+        noparagraphecachees.clear();
+        for(Integer numero : valsAffichees2){
+            if(numero.intValue()!=valsAffichees2[index]){
+                noparagraphecachees.add(numero);
+            }
+        }
+    }
+    initParagraphechamp();
+    if(!saisieChampChaine.pasdeSelection()){
+        afficherchaines();
+    }
+  }
+  public void afficherstat(){
+    if(!saisieChampStatistique.pasdeSelection() && !saisieChampChaine.pasdeSelection() 
+            && !saisieTypeChaines.pasdeSelection() && !saisieTypeUnites.pasdeSelection()){
+        ModeleStatChaine Modelestat = (ModeleStatChaine) ResultatStat.getModel();
+        String typeChampColonne;
+        String[] typeChampLigne;
+        switch(saisieChampStatistique.getSelection()){  
+            case "Répartition des références par paragraphe" :
+
+                typeChampColonne = "Chaine";
+                typeChampLigne = new String[1];
+                typeChampLigne[0] = "Paragraphe";
+                Modelestat=ModeleStatChaine.calculateStatCoref(saisieChampChaine.getSelection(), saisieChampAffiche.getSelection(), 
+                        valsAffichees1cachees, typeChampColonne, typeChampLigne, vue, 
+                        donneesChaines, noparagraphecachees, typeChaines, typeUnites, labelsNbElements);
+                break;
+            case "Répartition des paragraphes par référence" :
+
+                typeChampColonne = "Paragraphe";
+                typeChampLigne = new String[1];
+                typeChampLigne[0] = "Chaine";
+                Modelestat=ModeleStatChaine.calculateStatCoref(saisieChampChaine.getSelection(), saisieChampAffiche.getSelection(), 
+                        valsAffichees1cachees, typeChampColonne, typeChampLigne, vue, 
+                        donneesChaines, noparagraphecachees, typeChaines, typeUnites, labelsNbElements);
+                break;    
+            case "Répartition des paragraphe par valeur du champ" :
+                
+                typeChampColonne = "Paragraphe";
+                typeChampLigne = new String[1];
+                typeChampLigne[0] = "Unite";
+                Modelestat=ModeleStatChaine.calculateStatCoref(saisieChampChaine.getSelection(), saisieChampAffiche.getSelection(), 
+                        valsAffichees1cachees, typeChampColonne, typeChampLigne, vue, 
+                        donneesChaines, noparagraphecachees, typeChaines, typeUnites, labelsNbElements);
+                break; 
+            case "Répartition des valeurs du champ par paragraphe" :
+
+                typeChampColonne = "Unite";
+                typeChampLigne = new String[1];
+                typeChampLigne[0] = "Paragraphe";
+                Modelestat=ModeleStatChaine.calculateStatCoref(saisieChampChaine.getSelection(), saisieChampAffiche.getSelection(), 
+                        valsAffichees1cachees, typeChampColonne, typeChampLigne, vue, 
+                        donneesChaines, noparagraphecachees, typeChaines, typeUnites, labelsNbElements);
+                break; 
+            case "Répartition des valeurs de champ par référence" :
+
+                typeChampColonne = "Unite";
+                typeChampLigne = new String[1];
+                typeChampLigne[0] = "Chaine";
+                Modelestat=ModeleStatChaine.calculateStatCoref(saisieChampChaine.getSelection(), saisieChampAffiche.getSelection(), 
+                        valsAffichees1cachees, typeChampColonne, typeChampLigne, vue, 
+                        donneesChaines, noparagraphecachees, typeChaines, typeUnites, labelsNbElements);
+                break; 
+            case "Répartition des références par valeur de champ" :
+
+                typeChampColonne = "Chaine";
+                typeChampLigne = new String[1];
+                typeChampLigne[0] = "Unite";
+                Modelestat=ModeleStatChaine.calculateStatCoref(saisieChampChaine.getSelection(), saisieChampAffiche.getSelection(), 
+                        valsAffichees1cachees, typeChampColonne, typeChampLigne, vue, 
+                        donneesChaines, noparagraphecachees, typeChaines, typeUnites, labelsNbElements);
+                break; 
+            case "Répartition par paragraphe et par réfences des valeurs du champ" :
+
+                typeChampColonne = "Unite";
+                typeChampLigne = new String[2];
+                typeChampLigne[0] = "Chaine";
+                typeChampLigne[1] = "Paragraphe";
+                Modelestat=ModeleStatChaine.calculateStatCoref(saisieChampChaine.getSelection(), saisieChampAffiche.getSelection(), 
+                        valsAffichees1cachees, typeChampColonne, typeChampLigne, vue, 
+                        donneesChaines, noparagraphecachees, typeChaines, typeUnites, labelsNbElements);
+                break; 
+            case "Répartition par paragraphe et par valeur du champ des références" :
+
+                typeChampColonne = "Chaine";
+                typeChampLigne = new String[2];
+                typeChampLigne[0] = "Unite";
+                typeChampLigne[1] = "Paragraphe";
+                Modelestat=ModeleStatChaine.calculateStatCoref(saisieChampChaine.getSelection(), saisieChampAffiche.getSelection(), 
+                        valsAffichees1cachees, typeChampColonne, typeChampLigne, vue, 
+                        donneesChaines, noparagraphecachees, typeChaines, typeUnites, labelsNbElements);
+                break; 
+            case "Répartition par référence et par valeur de champ des paragraphes" :
+
+                typeChampColonne = "Paragraphe";
+                typeChampLigne = new String[2];
+                typeChampLigne[0] = "Chaine";
+                typeChampLigne[1] = "Unite";
+                Modelestat=ModeleStatChaine.calculateStatCoref(saisieChampChaine.getSelection(), saisieChampAffiche.getSelection(), 
+                        valsAffichees1cachees, typeChampColonne, typeChampLigne, vue, 
+                        donneesChaines, noparagraphecachees, typeChaines, typeUnites, labelsNbElements);
+                break; 
+            default :
+                break;
+            
+        }
+        
+        ResultatStat.setModel(Modelestat);
+        ResultatStat.setAutoCreateRowSorter(true); 
+        
+        for(int i = 0; i < ResultatStat.getColumnCount();i++){//on ajuste les tailles des cases du tableau
+            ResultatStat.getColumnModel().getColumn(i).setMinWidth(50);
+        }
+        ResultatStat.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+    
+    }
+  }
+  public JTable getLegende(){
+      return this.legendeChampAffiche;
+  }
+    
+  public String getSelection(int taillepolice, int x , int y, String police){
+      String retour = "";
+      if(saisieTypeChaines.pasdeSelection()){
+          retour = retour + "<text x=\""+x+"\" y=\""+(y) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Type de Schéma : aucun" + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      else{
+          retour = retour + "<text x=\""+x+"\" y=\""+(y) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Type de Schéma : " + saisieTypeChaines.getSelection() + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      if(saisieTypeUnites.pasdeSelection()){
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 2 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Type d'Unités : aucun" + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      else{
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 2 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Type d'Unités : " + saisieTypeUnites.getSelection() + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      if(saisieChampAffiche.pasdeSelection()){
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 4 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 1 : nombre de Chainons" + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      else{
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 4 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ 1 : " + saisieChampAffiche.getSelection() + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      if(saisieChampChaine.pasdeSelection()){
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 6 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ de la Chaine : aucun" + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      else{
+          retour = retour + "<text x=\""+x+"\" y=\""+(y + 6 * taillepolice) +"\""
+              + " style=\" fill:black; stroke:black ;font-size:"+taillepolice+"px "+police+"\">"+"Champ de la Chaine : " + saisieChampChaine.getSelection() + ";"+
+              "</text>"+System.getProperty("line.separator") + System.getProperty("line.separator");
+      }
+      return retour;
+  }
+  public void importerAffichage(){
+      HashMap<String,Object> Choix = FichiersJava.ouvrirChaineVue();
+      if(Choix!=null && Choix.containsKey("choixCommande2") &&
+              Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC).equals(Choix.get("nomFichier"))){
+        HashMap<String,String> choixCommande = (HashMap<String,String>) Choix.get("choixCommande2");
+
+        saisieTypeChaines.removeActionListener(this);
+        saisieTypeUnites.removeActionListener(this);
+        saisieTypeChaines.setSelectedItem(choixCommande.get("saisieTypeChaines"));
+        saisieTypeUnites.setSelectedItem(choixCommande.get("saisieTypeUnites"));
+        saisieTypeChaines.addActionListener(this);
+        saisieTypeUnites.addActionListener(this);
+        init();
+
+        saisieChampChaine.removeActionListener(this);
+        saisieChampAffiche.removeActionListener(this);
+        saisieChampStatistique.removeActionListener(this);
+        donneesChaines.setValsMasqueesChamp((HashMap<String,HashSet<String>>) Choix.get("valmasquees"));
+        donneesChaines.setValsNbMasqueesChamp((boolean[]) Choix.get("valNbmasquees"));
+        donneesChaines.setValsNulleMasqueesChamp((HashSet<String>) Choix.get("valNullemasquees"));
+        this.valsAffichees1cachees=(HashSet<String>) Choix.get("valsAffichees1cachees");
+        this.noparagraphecachees=(ArrayList<Integer>) Choix.get("noparagraphecachees");
+        activehistogramme.setSelected(choixCommande.get("activehistogramme").equals("vrai"));
+        if(choixCommande.get("saisieChampAffiche")!=null){
+          saisieChampAffiche.setSelectedItem(choixCommande.get("saisieChampAffiche"));
+        }
+        else{
+          saisieChampAffiche.effSelection();
+        }
+        if(choixCommande.get("saisieChampChaine")!=null){
+          saisieChampChaine.setSelectedItem(choixCommande.get("saisieChampChaine"));
+        }
+        else{
+          saisieChampChaine.effSelection();
+        }
+        if(choixCommande.get("saisieChampStatistique")!=null){
+          saisieChampStatistique.setSelectedItem(choixCommande.get("saisieChampStatistique"));
+        }
+        else{
+          saisieChampStatistique.effSelection();
+        }
+
+        saisieChampChaine.addActionListener(this);
+        saisieChampAffiche.addActionListener(this);
+        saisieChampStatistique.addActionListener(this); 
+
+
+        if(saisieChampAffiche.pasdeSelection()){
+              initCouleursNbElts();
+        }
+        else{
+              initCouleursChamp(saisieChampAffiche.getSelection());
+        }
+      initChaineChamp();
+      initParagraphechamp(); 
+      afficherchaines();
+      afficherstat();
+    }
+    else{
+          JOptionPane.showMessageDialog(null, "le fichier des paramètres d'affichage n'est pas destiné à cette fenêtre"
+                 + System.getProperty("line.separator") +
+                  "ou à ce corpus", "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+    }
+      
+  }
+  public void exporterAffichage(){
+      
+      HashMap<String,Object> Choix = new HashMap();
+      HashMap<String,String> choixCommande = new HashMap();
+      
+      choixCommande.put("saisieTypeChaines",saisieTypeChaines.pasdeSelection() ? null : saisieTypeChaines.getSelection());
+      choixCommande.put("saisieTypeUnites",saisieTypeUnites.pasdeSelection() ? null : saisieTypeUnites.getSelection());
+      choixCommande.put("saisieChampAffiche",saisieChampAffiche.pasdeSelection() ? null : saisieChampAffiche.getSelection());
+      choixCommande.put("saisieChampChaine",saisieChampChaine.pasdeSelection() ? null : saisieChampChaine.getSelection());
+      choixCommande.put("saisieChampStatistique",saisieChampStatistique.pasdeSelection() ? null : saisieChampStatistique.getSelection());
+      choixCommande.put("activehistogramme",activehistogramme.isSelected() ? "vrai" : "faux");
+      Choix.put("valmasquees",donneesChaines.getValsMasqueesChamp());
+      Choix.put("valNbmasquees",donneesChaines.getValsNbMasqueesChamp());
+      Choix.put("valNullemasquees",donneesChaines.getValsNulleMasqueesChamp());
+      Choix.put("valsAffichees1cachees",valsAffichees1cachees);
+      Choix.put("noparagraphecachees",noparagraphecachees);
+      Choix.put("choixCommande2",choixCommande);
+      Choix.put("nomFichier",Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC));
+      FichiersJava.enregistrerChaineSous(Choix);
+  }
+  
+  public HashSet<GChaines> getSuiteGChaines(){
+      return this.suiteGChaines;
+  }
+  public ModeleChaines getDonneesChaines(){
+      return this.donneesChaines;
+  }
+  
+  public Object[][] donneesCSV(boolean[] champ){
+      ArrayList<Object[]> donnees = new ArrayList();
+      int nbchamp=0;
+      for(boolean tmp : champ){
+          if(tmp){
+              nbchamp = nbchamp + 1;
+          }
+      }
+      //on crée les colonnes
+      if(champ.length==3){
+          Object[] titre = new Object[nbchamp+1];
+          titre[0] = "unité";
+          int compteurTitre=1;
+          for(int  i = 0 ; i < champ.length ; i++){
+             if(champ[i]){
+                switch(i){
+                    case 0 :
+                        titre[compteurTitre] = this.saisieChampAffiche.pasdeSelection() ?
+                        "Nombre de Chainons"
+                        : this.saisieChampAffiche.getSelection();
+                             break;
+                    case 1 :
+                        titre[compteurTitre] = this.saisieChampChaine.pasdeSelection() ? 
+                                ""
+                                : this.saisieChampChaine.getSelection();
+                             break;
+                    case 2 :
+                        titre[compteurTitre] = "Numéro de paragraphe";
+                             break;
+                     }
+                     compteurTitre = compteurTitre + 1;
+              }
+           }
+          donnees.add(titre);
+          for(GChaines chaine : this.suiteGChaines){
+              for(int  j = 0 ; j < chaine.chainons.length ; j++){
+                  ModeleChaines.Chainon unit = chaine.chainons[j];
+                  Object[] row = new Object[nbchamp+1];
+                  row[0] = unit.texte;
+                  int compteur=1;
+                  for(int  i = 0 ; i < champ.length ; i++){
+                      if(champ[i]){
+                          switch(i){
+                              case 0 :
+                                  row[compteur] = this.saisieChampAffiche.pasdeSelection() ? 
+                                          labelsNbElements[donneesChaines.calculerValNbElements(unit.nbEltsChaine)]
+                                          : vue.getValeurChamp(unit.unite, this.saisieChampAffiche.getSelection());
+                                  break;
+                              case 1 :
+                                  row[compteur] = this.saisieChampChaine.pasdeSelection() ? 
+                                          ""
+                                          : vue.getValeurChamp(unit.chaine, this.saisieChampChaine.getSelection());
+                                  break;
+                              case 2 :
+                                  row[compteur] = chaine.noSegments[j];
+                                  break;
+                          }
+                          compteur = compteur + 1;
+                      }
+                  }
+                  donnees.add(row);
+              }
+          }
+      }
+      return donnees.toArray(new Object[donnees.size()][nbchamp+1]);
+  }
+
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuCoref.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuStatGenerale.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuStatGenerale.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuStatGenerale.java	(revision 481)
@@ -0,0 +1,721 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.chaines;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import org.jfree.chart.ChartPanel;
+import visuAnalec.*;
+import visuAnalec.elements.*;
+import visuAnalec.fichiers.FichiersJava;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GMessages.GAction;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.util.GVisu.Val0ComboBox;
+import visuAnalec.vue.*;
+/**
+ *
+ * @author Marc
+ */
+public class VisuStatGenerale extends JFrame implements Vue.VueListener, ActionListener{
+  private Vue vue;
+  private ModeleChaines donneesChaines;
+  private String[] typesChainesAffiches;
+  private HashSet<String> typesChainesMasques=new HashSet();
+  private Val0ComboBox saisieUniteComptage;
+  private JList legendeTypeUnite;
+  private Val0ComboBox saisieAxeOrdonnee;
+  private Val0ComboBox saisieAxeAbscisse;
+  private Val0ComboBox saisieModeAffichage;
+  private JPopupMenu popupChamp = new JPopupMenu();
+  private PanneauEditeur panneauEditeur;
+  private Box listeStat = Box.createVerticalBox();
+  private ChartPanel graphique;  
+  private JMenuBar menuBar = new JMenuBar();
+  private String[] StatPossiblesAbscisses = new String[]{"Nombre de chainons","Numéro de paragraphe"};
+  private String[] StatPossiblesOrdonnees;
+  private String[] ModesPossibles = new String[]{"Activer l'interpolation","Désactiver l'affichage des valeurs nulles"};
+  private Object[][] donneesGenerales = new Object[0][0];
+  
+  public VisuStatGenerale(Container fenetre,final Vue vue, PanneauEditeur pEditeur){
+    super("Analyse générale du texte");
+    Point pos = new Point(fenetre.getX()+20, fenetre.getY()+20);
+    Dimension dim = new Dimension(fenetre.getWidth(), fenetre.getHeight());
+    setLocation(pos);
+    setSize(dim);
+    this.vue = vue;
+    vue.addEventListener(this);
+    typesChainesMasques = new HashSet();
+    this.panneauEditeur = pEditeur;   
+    saisieUniteComptage = new Val0ComboBox("Caractère");
+    saisieUniteComptage.addActionListener(this);
+    saisieAxeOrdonnee = new Val0ComboBox("Rien");
+    saisieAxeOrdonnee.addActionListener(this);
+    saisieAxeAbscisse = new Val0ComboBox("Rien");
+    saisieAxeAbscisse.addActionListener(this);
+    saisieModeAffichage = new Val0ComboBox("Normal");
+    saisieModeAffichage.addActionListener(this);
+    Box commandes = Box.createVerticalBox();
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Statistiques : "));   
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Selectionner une unité de comptage : "));
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(saisieUniteComptage);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Type unité : "));
+    commandes.add(Box.createVerticalGlue());
+        
+    legendeTypeUnite = new JList();
+    legendeTypeUnite.addMouseListener(new MouseAdapter() {
+      public void mousePressed(MouseEvent e) {//on gère les évènements de la souris
+        check(e);
+      }
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInit(legendeTypeUnite.locationToIndex(e.getPoint()));
+          popupChamp.show(legendeTypeUnite, e.getX(), e.getY());
+        }
+      }
+    });
+    commandes.add(legendeTypeUnite);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Ordonnée : "));
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(saisieAxeOrdonnee);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Abscisse : "));
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(saisieAxeAbscisse);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(new JLabel("Mode d'Affichage : "));
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(saisieModeAffichage);
+    commandes.add(Box.createVerticalGlue());
+    commandes.add(listeStat);
+    saisieUniteComptage.setAlignmentX(0);
+    legendeTypeUnite.setAlignmentX(0);
+    saisieAxeOrdonnee.setAlignmentX(0);
+    saisieAxeAbscisse.setAlignmentX(0);
+    saisieModeAffichage.setAlignmentX(0);
+    
+    JScrollPane scrollcommandes = new JScrollPane(commandes);
+    graphique =  Courbe.courbeFactory();
+    JScrollPane scrollcourbe = new JScrollPane(graphique);
+    JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,scrollcommandes,scrollcourbe);
+    split.setDividerLocation(1./2);
+    setJMenuBar(menuBar);
+    JMenu corpusMenu = new JMenu("Paramètres d'affichage");
+    menuBar.add(corpusMenu);;
+    corpusMenu.add(new GAction("Reprendre un affichage") {
+      public void executer() {
+         importerAffichage();
+      }
+    });
+    corpusMenu.add(new GAction("Sauver les paramètres d'affichage") {
+      public void executer() {
+         exporterAffichage();
+      }
+    });    
+    JMenu csvMenu = new JMenu("Exporter les données");
+    menuBar.add(csvMenu);;
+    csvMenu.add(new GAction("Exporter les données de filtrage") {
+      public void executer() {
+          ArrayList<Object[]> donnees = new ArrayList();
+          donnees.add(new Object[]{"Unité","type d'unité"});
+          for(String typeUnit : vue.getTypesUnitesAVoir()){
+              if(!typesChainesMasques.contains(typeUnit)){
+                for(Unite unit : vue.getUnites(typeUnit)){
+                    donnees.add(new Object[]{vue.getTexteUnite(unit),unit.getType()});
+                }
+              }
+          }
+          ExportCSV.exporterCSV(donnees.toArray(new Object[donnees.size()][2]));
+      }
+    });
+    csvMenu.add(new GAction("Exporter les statiques générales") {
+      public void executer() {
+          ExportCSV.exporterCSV(donneesGenerales);
+      }
+    }); 
+    getContentPane().add(split);
+    setVisible(true);    
+        // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+    donneesChaines = new ModeleChaines(vue, new GChaines(this));
+    donneesChaines.permettreaffichage(false);
+    saisieUniteComptage.setModele(new String[]{"Mots","Caractère"});
+    saisieAxeAbscisse.setModele(StatPossiblesAbscisses);
+    saisieModeAffichage.setModele(ModesPossibles);
+  }
+  
+    private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+  }
+    
+    public void traiterEvent(Message evt) { // très grossier : à améliorer
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre chaines présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        fermerFenetre();
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        fermerFenetre();
+        return;
+      case MODIF_ELEMENT:
+//        ElementEvent evtE = (ElementEvent) evt;
+//        if (evtE.getModif() != TypeModifElement.BORNES_UNITE) fermerFenetre();
+        fermerFenetre();
+        return;
+      case CORPUS_SAVED:
+          fermerFenetre();
+          return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+    
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource().equals(saisieUniteComptage)) {
+          if(vue.getTypesUnitesAVoir()==null || saisieUniteComptage.pasdeSelection()){
+           initVide();   
+          }
+          else{
+        init();
+          }
+        return;
+      }
+      if (evt.getSource().equals(saisieAxeOrdonnee)) {
+          if(!saisieAxeAbscisse.pasdeSelection() && !saisieAxeOrdonnee.pasdeSelection()){
+           affichercourbe();
+          }
+        return;
+      }
+    if (evt.getSource().equals(saisieAxeAbscisse)) {
+        if(!saisieUniteComptage.pasdeSelection()){
+        initChampOrdonnee();
+        }
+        return;
+      }
+    if (evt.getSource().equals(saisieModeAffichage)) {
+          if(!saisieAxeAbscisse.pasdeSelection() && !saisieAxeOrdonnee.pasdeSelection()){
+           affichercourbe();
+          }        
+        return;
+      }    
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  
+  private void initTypeUnite(){
+    String[] legende = new String[typesChainesAffiches.length];
+    for(int i = 0; i < typesChainesAffiches.length; i++){
+        if(typesChainesMasques.contains(typesChainesAffiches[i])){
+            legende[i] = "" +typesChainesAffiches[i].toString() + "     Non";
+        }
+        else{
+            legende[i] = "" +typesChainesAffiches[i].toString() + "     Oui";
+        }
+    }
+    legendeTypeUnite.setListData(legende);    
+  }
+  
+    private void popupChampInit(final int index) {
+    final boolean masquee;
+    masquee = typesChainesMasques.contains(typesChainesAffiches[index]);
+    popupChamp.removeAll();
+          popupChamp.add(new GAction(masquee ? "Montrer ce type d'unité" : 
+              "Masquer ce type d'unité") {
+        public void executer() {
+          modifierStatutValChampType(masquee, index, false);
+        }
+      });
+      popupChamp.add(new GAction(masquee ? "Montrer tous les types" : 
+              "Ne montrer que ce type d'unité") {
+        public void executer() {
+          modifierStatutValChampType(masquee, index, true);
+        }
+      });
+    
+  }
+    
+  private void modifierStatutValChampType(boolean masquee, int index, boolean tous) {
+    if(!tous){ 
+        if(masquee){
+            typesChainesMasques.remove(typesChainesAffiches[index]);
+        }
+        else{
+            typesChainesMasques.add(typesChainesAffiches[index]);    
+        }
+    }
+    else if(masquee){ 
+        typesChainesMasques.clear();
+    }
+    else{ 
+        typesChainesMasques.clear();
+        for(String valeur : typesChainesAffiches){
+            if(!valeur.equals(typesChainesAffiches[index])){
+                typesChainesMasques.add(valeur);
+            }
+        }
+    
+    }
+    afficherCalculs();
+    if(!saisieAxeAbscisse.pasdeSelection() && !saisieAxeOrdonnee.pasdeSelection()){
+    affichercourbe();
+    }
+  }
+  
+  private void initVide(){
+      listeStat.removeAll();
+      saisieAxeOrdonnee.setModeleVide();
+      legendeTypeUnite.setListData(new String[0]);
+  }
+  
+  private String[] getTypesAutorises(){
+      String[] retour;
+      if(typesChainesAffiches.length - typesChainesMasques.size()>0){
+        retour = new String[typesChainesAffiches.length - typesChainesMasques.size()];
+        int compte  = 0;
+        for(String type : typesChainesAffiches){
+            if(!typesChainesMasques.contains(type)){
+                retour[compte] = type;
+                compte = compte + 1 ;
+            }
+        }
+      }
+      else{
+        retour = new String[typesChainesAffiches.length];
+        int compte  = 0;
+        for(String type : typesChainesAffiches){
+                retour[compte] = type;
+                compte = compte + 1 ;
+        }
+      }
+      return retour;
+  }
+  
+  private void init(){
+      typesChainesAffiches = vue.getTypesUnitesAVoir();
+        saisieAxeAbscisse.setModele(StatPossiblesAbscisses);
+       initChampOrdonnee();
+      afficherCalculs();
+
+  }
+  private void afficherCalculs(){
+      initTypeUnite();
+      String unite = saisieUniteComptage.getSelection();
+      listeStat.removeAll();
+      this.donneesGenerales=new Object[20][2];
+      int donnee;
+      float donneef;
+      String[] typesDispo =getTypesAutorises() ;
+      listeStat.add(Box.createVerticalGlue());
+      donnee = ChaineUtil.nbCaractere(vue);
+      listeStat.add(new JLabel("Nombre de Caractères : " + donnee));
+      this.donneesGenerales[0][0]= "Nombre de Caractères";
+      this.donneesGenerales[0][1]= donnee;
+      listeStat.add(Box.createVerticalGlue());
+      donnee = ChaineUtil.nbMot(vue);
+      listeStat.add(new JLabel("Nombre de Mots : " + donnee));
+      this.donneesGenerales[1][0]= "Nombre de Mots";
+      this.donneesGenerales[1][1]= donnee;
+      listeStat.add(Box.createVerticalGlue());
+      donnee = ChaineUtil.nbParagraphe(vue);
+      listeStat.add(new JLabel("Nombre de Paragraphes : " + donnee));
+      this.donneesGenerales[2][0]= "Nombre de Paragraphes";
+      this.donneesGenerales[2][1]= donnee;
+      listeStat.add(Box.createVerticalGlue());
+      donnee = ChaineUtil.getUniteesTrieesEtFiltrees(typesDispo,vue).length;
+      listeStat.add(new JLabel("Nombre d'unités : " + donnee));
+      this.donneesGenerales[3][0]= "Nombre d'unités";
+      this.donneesGenerales[3][1]= donnee;
+      listeStat.add(Box.createVerticalGlue());
+      donnee = ChaineUtil.nombreDeReference(typesDispo,vue);
+      listeStat.add(new JLabel("Nombre de Références : " + donnee));
+      this.donneesGenerales[4][0]= "Nombre de Références";
+      this.donneesGenerales[4][1]= donnee;
+      listeStat.add(Box.createVerticalGlue());
+      donnee = ChaineUtil.nbChaines(vue);
+      listeStat.add(new JLabel("Nombre de Chaines : " + donnee));
+      this.donneesGenerales[5][0]= "Nombre de Chaines";
+      this.donneesGenerales[5][1]= donnee;
+      listeStat.add(Box.createVerticalGlue());
+      Integer[] tmp = ChaineUtil.nombreDeChainons(typesDispo,vue).toArray(new Integer[0]);
+      donneef = ChaineUtil.Esperance(tmp);
+      listeStat.add(new JLabel("Nombre moyen de Chainons par Chaine : " + donneef));
+      this.donneesGenerales[6][0]= "Nombre moyen de Chainons par Chaine";
+      this.donneesGenerales[6][1]= donneef;
+      listeStat.add(Box.createVerticalGlue());
+      donneef = ChaineUtil.Variance(tmp);
+      listeStat.add(new JLabel("Variance du Nombre de Chainons par Chaine : " + donneef));
+      this.donneesGenerales[7][0]= "Variance du Nombre de Chainons par Chaine";
+      this.donneesGenerales[7][1]= donneef;
+      listeStat.add(Box.createVerticalGlue());
+      donneef = ChaineUtil.densiteReferentielle("Paragraphe", typesDispo,vue);
+      listeStat.add(new JLabel("Densité référentielle par paragraphe : " + donneef));
+      this.donneesGenerales[8][0]= "Densité référentielle par paragraphe";
+      this.donneesGenerales[8][1]= donneef;
+      listeStat.add(Box.createVerticalGlue());
+      switch(unite){
+          case "Mots" :
+              donneef = ChaineUtil.densiteReferentielle("Mot", typesDispo,vue);
+              listeStat.add(new JLabel("Densité référentielle par nombre de mots : " + donneef));
+              this.donneesGenerales[9][0]= "Densité référentielle par nombre de mots";
+              this.donneesGenerales[9][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              tmp = ChaineUtil.positionUnite(typesDispo,vue).toArray(new Integer[0]);
+              //ici la position moyenne est calculé en caractère puis convertit en mots pour plus de précisions
+              donneef = ChaineUtil.calculerPositionMotCorpus(Math.round(ChaineUtil.Esperance(tmp)),vue);
+              listeStat.add(new JLabel("Position moyenne des unités : " + donneef));
+              this.donneesGenerales[10][0]= "Position moyenne des unités";
+              this.donneesGenerales[10][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              tmp = ChaineUtil.positionUniteEnMot(typesDispo,vue).toArray(new Integer[0]);
+              donneef = ChaineUtil.Variance(tmp);              
+              listeStat.add(new JLabel("Variance des positions des unités : " + donneef));
+              this.donneesGenerales[11][0]= "Variance des positions des unités";
+              this.donneesGenerales[11][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              tmp = ChaineUtil.ecartUniteMot(typesDispo,vue).toArray(new Integer[0]);
+              donneef = ChaineUtil.Esperance(tmp);   
+              listeStat.add(new JLabel("Ecart moyen entre les unités : " + donneef));
+              this.donneesGenerales[12][0]= "Ecart moyen entre les unités";
+              this.donneesGenerales[12][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              donneef = ChaineUtil.Variance(tmp);   
+              listeStat.add(new JLabel("Variance des écarts des unités : " + donneef));
+              this.donneesGenerales[13][0]= "Variance des écarts des unités";
+              this.donneesGenerales[13][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              tmp = ChaineUtil.longueurUniteMot(typesDispo,vue).toArray(new Integer[0]);
+              donnee = ChaineUtil.somme(tmp); 
+              listeStat.add(new JLabel("Longueur totale des unités : " + donnee));
+              this.donneesGenerales[14][0]= "Nombre de Mots";
+              this.donneesGenerales[14][1]= donnee;
+              listeStat.add(Box.createVerticalGlue());
+              donneef = ChaineUtil.Esperance(tmp);
+              listeStat.add(new JLabel("Longueur moyenne des unités : " + donneef));
+              this.donneesGenerales[15][0]= "Longueur moyenne des unités";
+              this.donneesGenerales[15][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              donneef = ChaineUtil.Variance(tmp);
+              listeStat.add(new JLabel("Variance des longueurs des unités : " + donneef));
+              this.donneesGenerales[16][0]= "Variance des longueurs des unités";
+              this.donneesGenerales[16][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              tmp = ChaineUtil.longueurChaineMot(typesDispo,vue).toArray(new Integer[0]);
+              donnee = ChaineUtil.somme(tmp); 
+              listeStat.add(new JLabel("Longueur totale des chaines de coréférences : " + donnee));
+              this.donneesGenerales[17][0]= "Longueur totale des chaines de coréférences";
+              this.donneesGenerales[17][1]= donnee;
+              listeStat.add(Box.createVerticalGlue());
+              donneef = ChaineUtil.Esperance(tmp);
+              listeStat.add(new JLabel("Longueur moyenne des chaines de coréférences : " + donneef));
+              this.donneesGenerales[18][0]= "Nombre de Mots";
+              this.donneesGenerales[18][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              donneef = ChaineUtil.Variance(tmp);
+              listeStat.add(new JLabel("Variance des longueurs des chaines de coréférences : " + donneef));
+              this.donneesGenerales[19][0]= "Variance des longueurs des chaines de coréférences";
+              this.donneesGenerales[19][1]= donneef;
+              
+              
+              break;
+          case "Caractère" :
+              donneef = ChaineUtil.densiteReferentielle("Caractère", typesDispo,vue);
+              listeStat.add(new JLabel("Densité référentielle par nombre de caractères : " + donneef));
+              this.donneesGenerales[9][0]= "Densité référentielle par nombre de caractères";
+              this.donneesGenerales[9][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              tmp = ChaineUtil.positionUnite(typesDispo,vue).toArray(new Integer[0]);
+              donneef = ChaineUtil.Esperance(tmp);
+              listeStat.add(new JLabel("Position moyenne des unités : " + donneef));
+              this.donneesGenerales[10][0]= "Position moyenne des unités";
+              this.donneesGenerales[10][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              donneef = ChaineUtil.Variance(tmp);
+              listeStat.add(new JLabel("Variance des positions des unités : " + donneef));
+              this.donneesGenerales[11][0]= "Variance des positions des unités";
+              this.donneesGenerales[11][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              tmp = ChaineUtil.ecartUniteCaractere(typesDispo,vue).toArray(new Integer[0]);
+              donneef = ChaineUtil.Esperance(tmp);
+              listeStat.add(new JLabel("Ecart moyen entre les unités : " + donneef));
+              this.donneesGenerales[12][0]= "Ecart moyen entre les unités";
+              this.donneesGenerales[12][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              donneef = ChaineUtil.Variance(tmp);
+              listeStat.add(new JLabel("Variance des écarts des unités : " + donneef));
+              this.donneesGenerales[13][0]= "Variance des écarts des unités";
+              this.donneesGenerales[13][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              tmp = ChaineUtil.longueurUniteCaractere(typesDispo,vue).toArray(new Integer[0]);
+              donnee = ChaineUtil.somme(tmp);
+              listeStat.add(new JLabel("Longueur totale des unités : " + donnee));
+              this.donneesGenerales[14][0]= "Longueur totale des unités";
+              this.donneesGenerales[14][1]= donnee;
+              listeStat.add(Box.createVerticalGlue());
+              donneef = ChaineUtil.Esperance(tmp);
+              listeStat.add(new JLabel("Longueur moyenne des unités : " + donneef));
+              this.donneesGenerales[15][0]= "Longueur moyenne des unités";
+              this.donneesGenerales[15][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              donneef = ChaineUtil.Variance(tmp);
+              listeStat.add(new JLabel("Variance des longueurs des unités : " + donneef));
+              this.donneesGenerales[16][0]= "Variance des longueurs des unités";
+              this.donneesGenerales[16][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              tmp = ChaineUtil.longueurChaineCaractere(typesDispo,vue).toArray(new Integer[0]);
+              donnee = ChaineUtil.somme(tmp);
+              listeStat.add(new JLabel("Longueur totale des chaines de coréférences : " + donnee));
+              this.donneesGenerales[17][0]= "Longueur totale des chaines de coréférences";
+              this.donneesGenerales[17][1]= donnee;
+              listeStat.add(Box.createVerticalGlue());
+              donneef = ChaineUtil.Esperance(tmp);
+              listeStat.add(new JLabel("Longueur moyenne des chaines de coréférences : " + donneef));
+              this.donneesGenerales[18][0]= "Longueur moyenne des chaines de coréférences";
+              this.donneesGenerales[18][1]= donneef;
+              listeStat.add(Box.createVerticalGlue());
+              donneef = ChaineUtil.Variance(tmp);
+              listeStat.add(new JLabel("Variance des longueurs des chaines de coréférences : " + donneef));
+              this.donneesGenerales[19][0]= "Variance des longueurs des chaines de coréférences";
+              this.donneesGenerales[19][1]= donneef;
+              break;
+          default : 
+              break;
+      }      
+  }
+  
+  private void initChampOrdonnee(){
+      if(!saisieAxeAbscisse.pasdeSelection()){
+        switch(saisieAxeAbscisse.getSelection()){
+            case "Nombre de chainons" :
+                StatPossiblesOrdonnees = new String[]{"Nombre de Chaines de coreference"};
+                break;
+            case "Numéro de paragraphe" :
+                StatPossiblesOrdonnees = new String[]{"Nombre de chainons","Nombre de Chaines de coreference",
+                "ratio nombre de chainons par nombre de " + saisieUniteComptage.getSelection(),"Densité référentielle"};
+                break;            
+            default :
+                StatPossiblesOrdonnees = new String[]{};
+                break;
+        }
+      }
+      else{
+        StatPossiblesOrdonnees = new String[]{};  
+      }
+      saisieAxeOrdonnee.setModele(StatPossiblesOrdonnees);
+  }
+  private void affichercourbe(){
+              switch(saisieAxeAbscisse.getSelection()){
+            case "Nombre de chainons" :
+                switch(saisieAxeOrdonnee.getSelection()){
+                    case "Nombre de Chaines de coreference" :
+                        HashMap donnee = ChaineUtil.calculerdonneecourbechainons(getTypesAutorises(),vue);
+                        afficherNbChainesEnFonctionNbChainons(donnee);
+                    break;
+                };
+                break;
+            case "Numéro de paragraphe" :
+                HashMap donnee = ChaineUtil.calculedonneecourbe(getTypesAutorises(),saisieUniteComptage.getSelection(),vue);
+                switch(saisieAxeOrdonnee.getSelection()){
+                    case "Nombre de Chaines de coreference" :
+                        afficherEnFonctionParagraphe(donnee);                        
+                    break;
+                    case "Nombre de chainons":
+                        afficherEnFonctionParagraphe(donnee);                         
+                    break;
+                    case "ratio nombre de chainons par nombre de " + "Mots":
+                        afficherEnFonctionParagraphe(donnee);                          
+                    break;
+                    case "ratio nombre de chainons par nombre de " + "Caractère":
+                        afficherEnFonctionParagraphe(donnee);                          
+                    break;                        
+                    case "Densité référentielle":
+                        afficherEnFonctionParagraphe(donnee);                          
+                    break;    
+                };                
+                break; 
+            default :
+                break;
+        }
+  }
+
+  
+  private void afficherEnFonctionParagraphe(HashMap<Integer,HashMap<String,Integer>> donnees){
+      ArrayList<Integer> classement = new ArrayList();
+      ArrayList<Integer> ordonnee = new ArrayList();
+      for(Integer nopa : donnees.keySet()){
+        classement.add(nopa,nopa);
+        ordonnee.add(nopa,donnees.get(nopa).get(saisieAxeOrdonnee.getSelection()));
+          
+      }
+      if(!saisieModeAffichage.pasdeSelection() && saisieModeAffichage.getSelection()=="Désactiver l'affichage des valeurs nulles"){
+          for(int nopa  = 0; nopa < ordonnee.size();nopa++){
+              if(nopa!=0 && nopa < ordonnee.size() - 1 && ordonnee.get(nopa)==0){
+                  classement.remove(nopa);
+                  ordonnee.remove(nopa);
+                  nopa = nopa - 1;
+              }
+          }
+          
+      }
+      
+      if(!saisieModeAffichage.pasdeSelection() && saisieModeAffichage.getSelection()=="Activer l'interpolation"){
+          ArrayList<Integer> valeurlagrange = new ArrayList();
+          for(int i  = 0;i< classement.size();i++){
+              valeurlagrange.add(i,ChaineUtil.interpolationLagrangienne(classement.toArray(new Integer[0]),
+                      ordonnee.toArray(new Integer[0]),i));
+          }
+          ordonnee = valeurlagrange;
+      }
+      Courbe.updatePanel(graphique,"Représentation de " + saisieAxeOrdonnee.getSelection()+ " en fonction du numéro pararaphe",
+              classement.toArray(new Integer[0]), ordonnee.toArray(new Integer[0]), 
+              Color.blue, -1,"numéro pararaphe",saisieAxeOrdonnee.getSelection());
+  }   
+  
+
+  
+  private void afficherNbChainesEnFonctionNbChainons(HashMap<Integer,Integer> donnees){
+      int max = 0;//on cherche l'abscisse maximum
+      for(Integer elt : donnees.keySet()){
+          if(elt>max){
+              max = elt;
+          }
+      }
+      ArrayList<Integer> abscisse;
+      ArrayList<Integer> ordonnee;
+      
+      if(saisieModeAffichage.pasdeSelection() || saisieModeAffichage.getSelection()!="Activer l'interpolation"){
+        abscisse = new ArrayList();
+        ordonnee = new ArrayList();  
+        for(int i = 0;i<max+1;i++){
+            abscisse.add(i,i);
+          if(donnees.containsKey(i)){
+              ordonnee.add(i,donnees.get(i));
+          }
+          else{
+              ordonnee.add(i,0) ;
+          }
+        }
+        if(!saisieModeAffichage.pasdeSelection() && saisieModeAffichage.getSelection().equals("Désactiver l'affichage des valeurs nulles")){
+             for(int nopa  = 0; nopa < ordonnee.size();nopa++){
+                 if(nopa!=0 && nopa < ordonnee.size() - 1 && ordonnee.get(nopa)==0){
+                     abscisse.remove(nopa);
+                     ordonnee.remove(nopa);
+                     nopa = nopa - 1;
+                 }
+             }
+
+         }
+      }
+      else{
+        Integer[] abscisses = new Integer[donnees.size()];
+        Integer[] ordonnees = new Integer[donnees.size()]; 
+        int compteur = 0;
+        for(int i = 0;i<max+1;i++){
+            
+          if(donnees.containsKey(i)){
+              abscisses[compteur] = i;
+              ordonnees[compteur] = donnees.get(i);
+              compteur = compteur + 1;
+          }        
+        }
+        abscisse = new ArrayList();
+        ordonnee = new ArrayList();  
+        for(int i = 0;i<max+1;i++){
+            abscisse.add(i,i);
+            ordonnee.add(i,ChaineUtil.interpolationLagrangienne(abscisses,ordonnees,i));
+        } 
+      }
+      Courbe.updatePanel(graphique,"Représentation de " + "nombre de chaines"+ " en fonction du nombre de chainons",
+              abscisse.toArray(new Integer[0]), ordonnee.toArray(new Integer[0]), 
+              Color.blue, -1,"numéro pararaphe",saisieAxeOrdonnee.getSelection());
+  }
+
+  private void importerAffichage(){
+      HashMap<String,Object> Choix = FichiersJava.ouvrirChaineVue();
+      if(Choix!=null && Choix.containsKey("choixCommande3") &&
+              Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC).equals(Choix.get("nomFichier"))){
+        HashMap<String,String> choixCommande = (HashMap<String,String>) Choix.get("choixCommande3");
+        saisieUniteComptage.removeActionListener(this);
+        saisieUniteComptage.setSelectedItem(choixCommande.get("saisieUniteComptage"));
+        saisieUniteComptage.addActionListener(this);
+        if(vue.getTypesUnitesAVoir()==null || saisieUniteComptage.pasdeSelection()){
+          initVide();   
+        }
+        else{
+          init();
+        }
+        this.typesChainesMasques = (HashSet<String>) Choix.get("typesChainesMasques");
+        saisieAxeOrdonnee.removeActionListener(this);
+        saisieAxeAbscisse.removeActionListener(this);
+        saisieModeAffichage.removeActionListener(this);
+
+
+        saisieAxeAbscisse.setSelectedItem(choixCommande.get("saisieAxeAbscisse"));
+        initChampOrdonnee();
+        saisieAxeOrdonnee.setSelectedItem(choixCommande.get("saisieAxeOrdonnee"));
+        saisieModeAffichage.setSelectedItem(choixCommande.get("saisieModeAffichage"));
+        saisieAxeOrdonnee.addActionListener(this);
+        saisieAxeAbscisse.addActionListener(this);
+        saisieModeAffichage.addActionListener(this);
+        affichercourbe();
+      }
+    else{
+          JOptionPane.showMessageDialog(null, "le fichier des paramètres d'affichage n'est pas destiné à cette fenêtre"
+                 + System.getProperty("line.separator") +
+                  "ou à ce corpus", "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+    }
+      
+      
+  }
+  private void exporterAffichage(){
+      
+      HashMap<String,Object> Choix = new HashMap();
+      HashMap<String,String> choixCommande = new HashMap();
+      
+      choixCommande.put("saisieUniteComptage",saisieUniteComptage.pasdeSelection() ? null : saisieUniteComptage.getSelection());
+      choixCommande.put("saisieAxeOrdonnee",saisieAxeOrdonnee.pasdeSelection() ? null : saisieAxeOrdonnee.getSelection());
+      choixCommande.put("saisieAxeAbscisse",saisieAxeAbscisse.pasdeSelection() ? null : saisieAxeAbscisse.getSelection());
+      choixCommande.put("saisieModeAffichage",saisieModeAffichage.pasdeSelection() ? null : saisieModeAffichage.getSelection());
+      Choix.put("typesChainesMasques",typesChainesMasques);
+      Choix.put("choixCommande3",choixCommande);
+      Choix.put("nomFichier",Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC));
+      FichiersJava.enregistrerChaineSous(Choix);      
+  }
+  
+  /*renvoie un tableau contenant les statistiques générales du texte*/
+  public Object[][] donneesCSV(){
+      return this.donneesGenerales;
+  }
+  
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/chaines/VisuStatGenerale.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/VisuMain.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/VisuMain.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/VisuMain.java	(revision 481)
@@ -0,0 +1,515 @@
+package visuAnalec;
+
+/**
+ *
+ * @author bernard
+ */
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.io.*;
+import visuAnalec.Message.*;
+import visuAnalec.chaines.*;
+import visuAnalec.donnees.*;
+import visuAnalec.fichiers.*;
+import visuAnalec.statistiques.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+
+@SuppressWarnings("serial")
+public class VisuMain extends JFrame implements VueListener {
+  private Corpus corpus;
+  private Vue vue;
+  private PanneauEditeur panneauEditeur;
+  private String nomCorpus = "";
+  private String nomVue = "";
+  private static String[] args;
+  VisuMain() {
+    super();
+    corpus = new Corpus();
+    vue = new Vue(corpus);
+    panneauEditeur = new PanneauEditeur(vue);
+    vue.addEventListener(this);
+    // Cadre global de la fenêtre
+    setContentPane(panneauEditeur);
+    // Menus
+    JMenuBar menuBar = new JMenuBar();
+    setJMenuBar(menuBar);
+
+    // Menu corpus
+    JMenu corpusMenu = new JMenu("Documents");
+    corpusMenu.setMnemonic(KeyEvent.VK_D);
+    menuBar.add(corpusMenu);
+    corpusMenu.add(new GAction("Ouvrir...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersJava.ouvrirCorpusVue(corpus, vue, "");
+        //       System.out.println(corpus.getStructure());
+      }
+    });
+    JMenuItem item;
+    corpusMenu.add(item = new JMenuItem(new GAction("Enregistrer") {
+      public void executer() {
+        if (corpus.isVide()) return;
+        if (!nomCorpus.isEmpty()) {
+          File fichier = Fichiers.getFichierCourant(Fichiers.TypeFichier.DOC_ANALEC);
+          if (FichiersJava.enregistrerCorpus(corpus, fichier)) setTitre();
+        } else if (FichiersJava.enregistrerCorpusSous(corpus)) {
+          nomCorpus = Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC);
+          setTitre();
+        }
+      }
+    }));
+    corpusMenu.add(new GAction("Enregistrer sous...") {
+      public void executer() {
+        if (FichiersJava.enregistrerCorpusSous(corpus)) {
+          nomCorpus = Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC);
+          setTitre();
+        }
+      }
+    });
+    corpusMenu.add(new GAction("Fermer") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+      }
+    });
+    corpusMenu.insertSeparator(corpusMenu.getMenuComponentCount());
+    corpusMenu.add(new GAction("Fusionner des annotations") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        FichiersJava.fusionnerAnnot(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Concaténer deux documents") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        FichiersJava.concatenerDocuments(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Concaténer un corpus") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersJava.concatenerCorpus(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Extraire un type d'un corpus") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        String type = JOptionPane.showInputDialog("Nom du type d'unité à extraire");
+        if (type==null) return;
+        corpus.fermer();
+        FichiersJava.extraireTypeCorpus(type, corpus);
+      }
+    });
+    corpusMenu.insertSeparator(corpusMenu.getMenuComponentCount());
+    corpusMenu.add(new GAction("Importer du texte brut...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        int rep = 0;
+        if (!corpus.getStructure().isVide()) {
+          rep = JOptionPane.showOptionDialog(null, "Utiliser la structure actuelle pour le nouveau document ?",
+                  "Structure déjà présente", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+                  null, new Object[]{"Oui", "Non", "Annuler"}, "Oui");
+          if (rep==2) return;
+        }
+        if (rep==0) corpus.fermerConserverStructure();
+        else corpus.fermer();
+        FichiersTexte.importerTexte(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Importer des données Excel...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersTableur.importerExcel(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Importer des données Syntex...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersSyntex.importerSyntex(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Importer des données Glozz...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersGlozz.importerGlozz(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Exporter des données Glozz...") {
+      public void executer() {
+        FichiersGlozz.exporterGlozz(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Convertir un corpus Glozz...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersGlozz.convertirCorpusGlozz(corpus);
+      }
+    });
+   corpusMenu.add(new GAction("Exporter un corpus TEI...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersTEI.exporterCorpusTEI(corpus);
+      }
+    });
+   corpusMenu.add(new GAction("Convertir un corpus TEI...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersTEI.convertirCorpusTEI(corpus);
+     }
+    });
+    corpusMenu.insertSeparator(corpusMenu.getMenuComponentCount());
+    corpusMenu.add(new GAction("Quitter") {
+      public void executer() {
+        fermerFenetre();
+      }
+    });
+
+    // Menu structure
+    JMenu structureMenu = new JMenu("Structure");
+    structureMenu.setMnemonic(KeyEvent.VK_S);
+    menuBar.add(structureMenu);
+    structureMenu.add(new GAction("Gestion de la structure...") {
+      public void executer() {
+        VisuStructure visuStructure = VisuStructure.newVisuStructure(getContentPane(), corpus);
+        visuStructure.setExtendedState(NORMAL);
+        visuStructure.setVisible(true);
+        visuStructure.agencer();
+      }
+    });
+    structureMenu.add(new GAction("Ouvrir...") {
+      public void executer() {
+        if (!fusionStructure()) return;
+        FichiersJava.ouvrirStructure(corpus);
+      }
+    });
+    structureMenu.add(item = new JMenuItem(new GAction("Enregistrer...") {
+      public void executer() {
+        FichiersJava.enregistrerStructure(corpus);
+        setTitre();
+      }
+    }));
+    structureMenu.add(new GAction("Importer un modèle Glozz...") {
+      public void executer() {
+        if (!fusionStructure()) return;
+        FichiersGlozz.importerModeleGlozz(corpus);
+        //       System.out.println(corpus.getStructure());
+      }
+    });
+    structureMenu.add(new GAction("Exporter un modèle Glozz...") {
+      public void executer() {
+        FichiersGlozz.exporterModeleGlozz(corpus.getStructure());
+      }
+    });
+
+    // Menu vue
+    JMenu vueMenu = new JMenu("Vue");
+    menuBar.add(vueMenu);
+    vueMenu.add(new GAction("Gestion de la vue...") {
+      public void executer() {
+        VisuVue.newVisuVue(getContentPane(), vue);
+      }
+    });
+    vueMenu.add(new GAction("Ouvrir (.ecv)...") {
+      public void executer() {
+        FichiersJava.ouvrirVue(vue);
+      }
+    });
+    vueMenu.add(new GAction("Enregistrer (.ecv)...") {
+      public void executer() {
+        if (FichiersJava.enregistrerVue(vue)) {
+          nomVue = Fichiers.getNomFichierCourant(Fichiers.TypeFichier.VUE);
+          setTitre();
+        }
+      }
+    });
+    vueMenu.add(new GAction("Rétablir la vue par défaut") {
+      public void executer() {
+        nomVue = "";
+        vue.retablirVueParDefaut();
+      }
+    });
+
+    // Menu texte
+    JMenu texteMenu = new JMenu("Texte");
+    texteMenu.setMnemonic(KeyEvent.VK_T);
+    menuBar.add(texteMenu);
+    texteMenu.add(new GAction("Modifier le texte") {
+      public void executer() {
+        panneauEditeur.initModifierTexte();
+      }
+    });
+    texteMenu.insertSeparator(texteMenu.getMenuComponentCount());
+    texteMenu.add(item = new JMenuItem(new GAction("Rechercher...") {
+      public void executer() {
+        panneauEditeur.initRechercherTexte();
+      }
+    }));
+    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, ActionEvent.CTRL_MASK));
+    texteMenu.add(item = new JMenuItem(new GAction("Suivant") {
+      public void executer() {
+        panneauEditeur.rechercherSuivantTexte();
+      }
+    }));
+    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, ActionEvent.CTRL_MASK));
+    texteMenu.insertSeparator(texteMenu.getMenuComponentCount());
+    texteMenu.add(new GAction("Style du document...") {
+      public void executer() {
+        panneauEditeur.saisirStyleTexte(vue);
+      }
+    });
+    texteMenu.add(new GAction("Exporter format RTF...") {
+      public void executer() {
+        FichiersTexte.exporterTexteRTF(panneauEditeur);
+      }
+    });
+    texteMenu.add(new GAction("Exporter format HTML...") {
+      public void executer() {
+        FichiersTexte.exporterTexteHTML(panneauEditeur);
+      }
+    });
+
+
+    // Menu unités
+    JMenu unitesMenu = new JMenu("Unités");
+    unitesMenu.setMnemonic(KeyEvent.VK_U);
+    menuBar.add(unitesMenu);
+    unitesMenu.add(new GAction("Gestion des unités") {
+      public void executer() {
+        panneauEditeur.initGestionUnites();
+      }
+    });
+    unitesMenu.add(new GAction("Création d'unités typographiques") {
+      public void executer() {
+        GMessages.pasImplemente();
+      }
+    });
+    unitesMenu.add(new GAction("Création d'unités de constituance") {
+      public void executer() {
+        GMessages.pasImplemente();
+      }
+    });
+
+    // Menu relations
+    JMenu relationsMenu = new JMenu("Relations");
+    relationsMenu.setMnemonic(KeyEvent.VK_R);
+    relationsMenu.setMnemonic(KeyEvent.VK_R);
+    menuBar.add(relationsMenu);
+    relationsMenu.add(new GAction("Gestion des relations") {
+      public void executer() {
+        panneauEditeur.initGestionRelations();
+      }
+    });
+    relationsMenu.add(new GAction("Visualisation d'arborescences") {
+      public void executer() {
+        GMessages.pasImplemente();
+      }
+    });
+    relationsMenu.add(new GAction("Saisie d'arborescences") {
+      public void executer() {
+        GMessages.pasImplemente();
+      }
+    });
+    relationsMenu.add(new GAction("Création d'arborescences") {
+      public void executer() {
+        GMessages.pasImplemente();
+      }
+    });
+
+    // Menu schémas
+    JMenu schemasMenu = new JMenu("Schémas");
+    schemasMenu.setMnemonic(KeyEvent.VK_H);
+    menuBar.add(schemasMenu);
+    schemasMenu.add(new GAction("Gestion des schémas") {
+      public void executer() {
+        panneauEditeur.initGestionSchemas();
+      }
+    });
+    schemasMenu.add(new GAction("Création de schémas à partir des annotations") {
+      public void executer() {
+        new VisuConversion(getContentPane(), vue, panneauEditeur);
+      }  
+    }); 
+    schemasMenu.add(new GAction("Visualisation de la suite d'occurences") {
+      public void executer() {
+        new VisuChaines(getContentPane(), vue, panneauEditeur);
+      }
+    });
+    schemasMenu.add(new GAction("Visualisation des chaines de coréférences") {
+      public void executer() {
+        new VisuCoref(getContentPane(), vue, panneauEditeur);
+      }  
+    });
+    schemasMenu.add(new GAction("Statistique Générale") {
+      public void executer() {
+        new VisuStatGenerale(getContentPane(), vue, panneauEditeur);
+      }  
+    });          
+
+    // Menu règles
+    JMenu reglesMenu = new JMenu("Règles");
+    reglesMenu.setMnemonic(KeyEvent.VK_G);
+    menuBar.add(reglesMenu);
+    
+    // Menu Stats
+    JMenu statsMenu = new JMenu("Statistiques");
+    statsMenu.setMnemonic(KeyEvent.VK_A);
+    menuBar.add(statsMenu);
+    statsMenu.add(new GAction("Fréquences...") {
+      public void executer() {
+        new VisuStatsFrequences(getContentPane(), vue, panneauEditeur);
+      }
+    });
+    statsMenu.add(new GAction("Corrélations...") {
+      public void executer() {
+        new VisuStatsCorrelations(getContentPane(), vue, panneauEditeur);
+      }
+    });
+    statsMenu.add(new GAction("Représentations géométriques...") {
+      @SuppressWarnings("ResultOfObjectAllocationIgnored")
+      public void executer() {
+        new VisuStatsGeometrie(getContentPane(), vue, panneauEditeur);
+      }
+    });
+    // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+
+  }
+  public void premierPlan() {
+    if ((getExtendedState()&Frame.ICONIFIED)>0) {
+      setExtendedState(getExtendedState()&~Frame.ICONIFIED);
+    }
+    toFront();
+
+  }
+  private void fermerFenetre() {
+    if (sauvegarde()) System.exit(0);
+  }
+  boolean sauvegarde() {
+    if (!corpus.isModifie()) return true;
+    int rep = JOptionPane.showOptionDialog(this, "Sauvegarder le document en cours ?",
+            "Document modifié", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+            null, new Object[]{"Oui", "Non", "Annuler"}, "Non");
+    if (rep==2) {
+      return false;
+    }
+    if (rep==0) {
+      FichiersJava.enregistrerCorpusSous(corpus);
+    }
+    return true;
+  }
+  boolean fusionStructure() {
+    if (corpus.getStructure().isVide()) return true;
+    int rep = JOptionPane.showOptionDialog(this, "La nouvelle structure va être fusionnée avec la structure courante",
+            "Structure déjà présente", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+            null, new Object[]{"Poursuivre", "Annuler"}, "Poursuivre");
+    return rep==0;
+  }
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        nomCorpus = "";
+        Fichiers.removeFichierCourant(Fichiers.TypeFichier.DOC_ANALEC);
+        setTitre();
+        return;
+      case NEW_CORPUS:
+        nomCorpus = Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC);
+        setTitre();
+        return;
+      case CORPUS_SAVED:
+          return;
+      case MODIF_VUE:
+        switch (((VueEvent) evt).getModif()) {
+          case VUE_DEFAUT:
+            nomVue = "";
+            setTitre();
+            return;
+          case NEW_VUE:
+            nomVue = Fichiers.getNomFichierCourant(Fichiers.TypeFichier.VUE);
+            setTitre();
+            return;
+          case EXTRACTION:
+            setTitre();
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas "+((VueEvent) evt).getModif()+" oublié dans un switch");
+        }
+      case MODIF_TEXTE:
+      case MODIF_STRUCTURE:
+      case MODIF_ELEMENT:
+        setTitre();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  private void setTitre() {
+    String titre = "Analec 1.4";
+    if (!nomCorpus.isEmpty()) {
+      titre += " : "+nomCorpus;
+      if (corpus.isModifie()) titre += "*";
+      if (nomVue.isEmpty()) {
+        if (vue.isModifiee()) titre += " - vue modifiée*";
+        else titre += " - vue par défaut";
+      } else {
+        titre += " - vue : "+nomVue;
+        if (vue.isModifiee()) titre += "*";
+      }
+    }
+    setTitle(titre);
+  }
+  public static void main(String[] args) {
+    VisuMain.args = args;
+    javax.swing.SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        try {
+          // Fenêtre
+          lancerVisuAnalec();
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    });
+  }
+//    try {
+//      // Fenêtre
+//      lancerVisuAnalec(args);
+//    } catch (Throwable ex) {
+//      GMessages.erreurFatale(ex);
+//    }
+//  }
+  public static void lancerVisuAnalec() throws IOException, ClassNotFoundException {
+    // Fenêtre
+    VisuMain fenetre = new VisuMain();
+    fenetre.setTitre();
+    Rectangle rmax = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
+    fenetre.setLocation(50, 50);
+    fenetre.setSize(rmax.width-100, rmax.height-100);
+    fenetre.setVisible(true);
+    fenetre.panneauEditeur.agencerPanneaux();
+    fenetre.traiterArguments(args);
+//    System.out.println(fenetre.corpus.getStructure().toString());
+//   new GMessages.GProgression(fenetre);
+  }
+  private void traiterArguments(String[] args) throws IOException, ClassNotFoundException {
+    if (args.length==0) return;
+    FichiersJava.ouvrirCorpusVue(corpus, vue, args[0]);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/VisuMain.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/donnees/VisuStructure.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/donnees/VisuStructure.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/donnees/VisuStructure.java	(revision 481)
@@ -0,0 +1,680 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.donnees;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.tree.*;
+import visuAnalec.*;
+import visuAnalec.Message.*;
+import visuAnalec.donnees.Corpus.*;
+import visuAnalec.vue.Vue.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.GMessages;
+import visuAnalec.util.GMessages.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class VisuStructure extends JFrame implements CorpusListener {
+	static private VisuStructure instance = null;
+	private Corpus corpus;
+	private Structure structure;
+	private JScrollPane panneauUnites, panneauRelations, panneauSchemas;
+	private HashMap<Class<? extends Element>, ModeleArbreProp> donneesClasse =
+			new HashMap<Class<? extends Element>, ModeleArbreProp>();
+	static public VisuStructure newVisuStructure(Container fenetre, Corpus corpus) {
+		if (instance==null) instance = new VisuStructure(fenetre, corpus);
+		return instance;
+	}
+	private VisuStructure(Container fenetre, Corpus corps) {
+		super("Structure des annotations");
+		if (fenetre != null) {
+			Point locFenetre = new Point(fenetre.getX()+20, fenetre.getY()+50);
+			Dimension dimFenetre = new Dimension(fenetre.getWidth(), fenetre.getHeight()-30);
+			setLocation(locFenetre);
+			setSize(dimFenetre);
+		}
+		this.corpus = corps;
+		this.structure = corps.getStructure();
+		corps.addEventListener(this);
+		// Panneau des types d'unités
+		ModeleArbreProp donneesPropUnites = new ModeleArbreProp(structure, Unite.class);
+		JTree arbrePropUnites = new JTree(donneesPropUnites);
+		donneesClasse.put(Unite.class, donneesPropUnites);
+		arbrePropUnites.setRootVisible(true);
+		arbrePropUnites.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+		panneauUnites = new JScrollPane(arbrePropUnites);
+		panneauUnites.setBorder(new TitledBorder("Unités"));
+		// Panneau des types de relations
+		ModeleArbreProp donneesPropRelations = new ModeleArbreProp(structure, Relation.class);
+		JTree arbrePropRelations = new JTree(donneesPropRelations);
+		donneesClasse.put(Relation.class, donneesPropRelations);
+		arbrePropRelations.setRootVisible(true);
+		arbrePropRelations.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+		panneauRelations = new JScrollPane(arbrePropRelations);
+		panneauRelations.setBorder(new TitledBorder("Relations"));
+		// Panneau des types de schémas
+		ModeleArbreProp donneesPropSchemas = new ModeleArbreProp(structure, Schema.class);
+		JTree arbrePropSchemas = new JTree(donneesPropSchemas);
+		donneesClasse.put(Schema.class, donneesPropSchemas);
+		arbrePropSchemas.setRootVisible(true);
+		arbrePropSchemas.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+		panneauSchemas = new JScrollPane(arbrePropSchemas);
+		panneauSchemas.setBorder(new TitledBorder("Schémas"));
+
+		// cadre global de la fenêtre
+		JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panneauUnites,
+				new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+						panneauRelations, panneauSchemas));
+		getContentPane().add(split);
+
+		// Gestion des menus contextuels
+		final JPopupMenuStructure popupMenuStructure = new JPopupMenuStructure();
+
+		MouseListener popupListener = new MouseAdapter() {
+			@Override
+			public void mousePressed(MouseEvent e) {
+				try {
+					if (e.isPopupTrigger()) showPopup(e);
+					else if (e.getClickCount()==2) {
+						JTree arbre = (JTree) e.getComponent();
+						TreePath item = arbre.getPathForLocation(e.getX(), e.getY());
+						if (item==null) return;
+						if (item.getPathCount()!=4) return;
+						ModeleArbreProp donnees = (ModeleArbreProp) arbre.getModel();
+						Class<? extends Element> classe = donnees.classe;
+						DefaultMutableTreeNode noeudType = (DefaultMutableTreeNode) item.getPathComponent(1);
+						DefaultMutableTreeNode noeudProp = (DefaultMutableTreeNode) item.getPathComponent(2);
+						DefaultMutableTreeNode noeudVal = (DefaultMutableTreeNode) item.getPathComponent(3);
+						String type = (String) noeudType.getUserObject();
+						String prop = (String) noeudProp.getUserObject();
+						String val = (String) noeudVal.getUserObject();
+						if (isDefaut(val)) {
+							corpus.modifierValParDefaut(classe, type, prop, "");
+							//             noeudVal.setUserObject(oteDefaut(val));
+						} else {
+							corpus.modifierValParDefaut(classe, type, prop, val);
+							//              for (Enumeration noeuds = noeudProp.children(); noeuds.hasMoreElements();) {
+							//                DefaultMutableTreeNode noeud1 = (DefaultMutableTreeNode) noeuds.nextElement();
+							//                String val1 = (String) noeud1.getUserObject();
+							//                if (isDefaut(val1)) {
+							//                  noeud1.setUserObject(oteDefaut(val1));
+							//                  donnees.nodeChanged(noeudVal);
+							//                  break;
+							//                }
+							//              }
+							////              noeudVal.setUserObject(placeDefaut(val));
+							//             corpus.newValeurDefaut(classe, type, prop, val);
+						}
+						//          donnees.nodeChanged(noeudVal);
+
+					}
+				} catch (Throwable ex) {
+					GMessages.erreurFatale(ex);
+				}
+			}
+			@Override
+			public void mouseReleased(MouseEvent e) {
+				try {
+					if (e.isPopupTrigger()) showPopup(e);
+				} catch (Throwable ex) {
+					GMessages.erreurFatale(ex);
+				}
+			}
+			private void showPopup(MouseEvent e) {
+				JTree arbre = (JTree) e.getComponent();
+				TreePath item = arbre.getPathForLocation(e.getX(), e.getY());
+				if (item==null) return;
+				popupMenuStructure.init(arbre, item);
+				popupMenuStructure.show(e.getComponent(), e.getX(), e.getY());
+			}
+		};
+
+		arbrePropUnites.addMouseListener(popupListener);
+		arbrePropRelations.addMouseListener(popupListener);
+		arbrePropSchemas.addMouseListener(popupListener);
+		// Fermeture de la fenêtre
+		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+		addWindowListener(new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent evt) {
+				fermerFenetre();
+			}
+		});
+
+	}
+	public void agencer() {
+		((JSplitPane) panneauUnites.getParent()).setDividerLocation(1./3);
+		((JSplitPane) panneauRelations.getParent()).setDividerLocation(1./3);
+	}
+	private void fermerFenetre() {
+		corpus.removeEventListener(this);
+		dispose();
+		instance = null;
+	}
+	public void traiterEvent(Message evt) {
+		switch (evt.getType()) {
+		case CLEAR_CORPUS:
+			fermerFenetre();
+			return;
+		case CORPUS_SAVED:
+			return;
+		case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+			throw new UnsupportedOperationException("Fenêtre stat présente lors d'un message NEW_CORPUS ???");
+		case MODIF_STRUCTURE:
+			StructureEvent evtS = (StructureEvent) evt;
+			ModeleArbreProp donnees = donneesClasse.get(evtS.getClasse());
+			switch (evtS.getModif()) { // pour les modifs ayant lieu en dehors de VisuStructure 
+			case AJOUT_TYPE:
+				donnees.insererNewType(evtS.getArg(0));
+				return;
+			case AJOUT_PROP:
+				donnees.insererNewProp(evtS.getArg(0), evtS.getArg(1));
+				return;
+			case AJOUT_VALEUR:
+				donnees.insererNewValeur(evtS.getArg(0), evtS.getArg(1), evtS.getArg(2));
+				return;
+			case VALEUR_PAR_DEFAUT:
+				donnees.modifierValDefaut(evtS.getArg(0), evtS.getArg(1), evtS.getArg(2));
+				return;
+			default:
+				return;
+			}
+		case MODIF_ELEMENT:
+		case MODIF_TEXTE:
+			return;
+		default:
+			throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+		}
+	}
+	static boolean isDefaut(String val) {
+		return val.startsWith("=>");
+	}
+	static String placeDefaut(String val) {
+		return isDefaut(val) ? val : "=>"+val;
+	}
+	static String oteDefaut(String val) {
+		return isDefaut(val) ? val.substring(2) : val;
+	}
+
+	private class JPopupMenuStructure extends JPopupMenu {
+		void init(JTree arbre, TreePath item) {
+			ModeleArbreProp donnees = (ModeleArbreProp) arbre.getModel();
+			removeAll();
+			int niveau = item.getPathCount();
+			if (niveau<4) {
+				add(new ActionAjouter(donnees.classe, arbre, donnees, item));
+			}
+			if (niveau>1) {
+				if (niveau!=3||!donnees.classe.equals(Unite.class)||!Structure.FORME.equals(
+						((DefaultMutableTreeNode) item.getLastPathComponent()).getUserObject()))
+					add(new ActionRenommer(donnees.classe, donnees, item));
+				add(new ActionSupprimer(donnees.classe, donnees, item));
+			}
+			if (niveau==2&&donnees.classe.equals(Unite.class)
+					&&!donnees.hasForme((DefaultMutableTreeNode) item.getLastPathComponent()))
+				add(new ActionAjouterForme(arbre, donnees, item));
+			if (niveau==3)
+				add(new ActionDispatcher(donnees.classe, arbre, donnees, item));
+		}
+	}
+	static String[] commandesAjout = new String[]{
+		"Ajouter un type",
+		"Ajouter une propriété",
+		"Ajouter une valeur"
+	};
+
+	private class ActionAjouter extends GAction {
+		TreePath item;
+		Class<? extends Element> classe;
+		JTree arbre;
+		ModeleArbreProp donnees;
+		ActionAjouter(Class<? extends Element> classe, JTree arbre, ModeleArbreProp donnees, TreePath item) {
+			super(commandesAjout[item.getPathCount()-1]);
+			this.item = item;
+			this.classe = classe;
+			this.donnees = donnees;
+			this.arbre = arbre;
+		}
+		public void executer() {
+			corpus.removeEventListener(VisuStructure.this);
+			DefaultMutableTreeNode noeud, noeud1, noeud2;
+			noeud = (DefaultMutableTreeNode) item.getLastPathComponent();
+			switch (item.getPathCount()) {
+			case 1: // racine : ajout d'un type
+			String newType =
+			corpus.saisirAjouterType(VisuStructure.this, classe);
+			if (newType!=null) {
+				noeud1 = new DefaultMutableTreeNode(newType, true);
+				donnees.insertNodeInto(noeud1, noeud, 0);
+				arbre.makeVisible(item.pathByAddingChild(noeud1));
+			}
+			break;
+			case 2: // type : ajout d'une prop
+				String newProp =
+				corpus.saisirAjouterProp(VisuStructure.this, classe,
+						(String) noeud.getUserObject());
+				if (newProp!=null) {
+					noeud1 = new DefaultMutableTreeNode(newProp, true);
+					donnees.insertNodeInto(noeud1, noeud, 0);
+					arbre.makeVisible(item.pathByAddingChild(noeud1));
+				}
+				break;
+			case 3: // prop : ajout d'une valeur
+				noeud1 = (DefaultMutableTreeNode) item.getPathComponent(1);
+				String newVal = corpus.saisirAjouterVal(VisuStructure.this, classe,
+						(String) noeud1.getUserObject(), (String) noeud.getUserObject());
+				if (newVal!=null) {
+					noeud2 = new DefaultMutableTreeNode(newVal, false);
+					donnees.insertNodeInto(noeud2, noeud, 0);
+					arbre.makeVisible(item.pathByAddingChild(noeud1));
+				}
+				break;
+			default:
+				throw new UnsupportedOperationException("Cas d'ajout non prévu ");
+			}
+			corpus.addEventListener(VisuStructure.this);
+		}
+	}
+	static String[] commandesRenom = new String[]{
+		"Renommer le type",
+		"Renommer la propriété",
+		"Renommer la valeur"
+	};
+
+	private class ActionRenommer extends GAction {
+		TreePath item;
+		Class<? extends Element> classe;
+		ModeleArbreProp donnees;
+		ActionRenommer(Class<? extends Element> classe, ModeleArbreProp donnees, TreePath item) {
+			super(commandesRenom[item.getPathCount()-2]);
+			this.item = item;
+			this.classe = classe;
+			this.donnees = donnees;
+		}
+		@SuppressWarnings("unchecked")
+		public void executer() {
+			corpus.removeEventListener(VisuStructure.this);
+			DefaultMutableTreeNode noeud, noeud0, noeud1, noeud2;
+			noeud = (DefaultMutableTreeNode) item.getLastPathComponent();
+			switch (item.getPathCount()) {
+			case 2: // type
+				String newType = corpus.saisirRenommerType(VisuStructure.this, classe,
+						(String) noeud.getUserObject());
+				if (newType!=null) {
+					DefaultMutableTreeNode ntypefusion = null;
+					noeud0 = (DefaultMutableTreeNode) item.getPathComponent(0);
+					for (Enumeration<DefaultMutableTreeNode> etype = noeud0.children(); etype.hasMoreElements();) {
+						DefaultMutableTreeNode ntype = etype.nextElement();
+						String type0 = (String) ntype.getUserObject();
+						if (newType.equals(type0)) {
+							ntypefusion = ntype;
+							break;
+						}
+					}
+					if (ntypefusion!=null)
+						donnees.fusionnerType(noeud, ntypefusion);
+					else {
+						noeud.setUserObject(newType);
+						donnees.nodeChanged(noeud);
+					}
+				}
+				break;
+			case 3: // prop
+				noeud1 = (DefaultMutableTreeNode) item.getPathComponent(1);
+				String newProp = corpus.saisirRenommerProp(VisuStructure.this, classe,
+						(String) noeud1.getUserObject(), (String) noeud.getUserObject());
+				if (newProp!=null) {
+					DefaultMutableTreeNode npropfusion = null;
+					for (Enumeration<DefaultMutableTreeNode> eprop = noeud1.children(); eprop.hasMoreElements();) {
+						DefaultMutableTreeNode nprop = eprop.nextElement();
+						String prop0 = (String) nprop.getUserObject();
+						if (newProp.equals(prop0)) {
+							npropfusion = nprop;
+							break;
+						}
+					}
+					if (npropfusion!=null)
+						donnees.fusionnerProp(noeud1, noeud, npropfusion);
+					else {
+						noeud.setUserObject(newProp);
+						donnees.nodeChanged(noeud);
+					}
+				}
+				break;
+			case 4: // val
+				noeud1 = (DefaultMutableTreeNode) item.getPathComponent(1);
+				noeud2 = (DefaultMutableTreeNode) item.getPathComponent(2);
+				String val = (String) noeud.getUserObject();
+				boolean isDefaut = isDefaut(val);
+				if (isDefaut) val = oteDefaut(val);
+				String newVal = corpus.saisirRenommerVal(VisuStructure.this, classe,
+						(String) noeud1.getUserObject(), (String) noeud2.getUserObject(), val);
+				if (newVal!=null) {
+					for (Enumeration<DefaultMutableTreeNode> eval = noeud2.children(); eval.hasMoreElements();) {
+						DefaultMutableTreeNode nval = eval.nextElement();
+						String val0 = (String) nval.getUserObject();
+						if (newVal.equals(isDefaut(val0) ? oteDefaut(val0) : val0)) {
+							isDefaut = isDefaut||isDefaut(val0);
+							donnees.removeNodeFromParent(nval);
+							break;
+						}
+					}
+					if (isDefaut) newVal = placeDefaut(newVal);
+					noeud.setUserObject(newVal);
+					donnees.nodeChanged(noeud);
+				}
+				break;
+			default:
+				throw new UnsupportedOperationException("Cas de renommage non prévu ");
+			}
+			corpus.addEventListener(VisuStructure.this);
+		}
+	}
+	static String[] commandesSuppr = new String[]{
+		"Supprimer le type",
+		"Supprimer la propriété",
+		"Supprimer la valeur"
+	};
+
+	private class ActionSupprimer extends GAction {
+		TreePath item;
+		Class<? extends Element> classe;
+		ModeleArbreProp donnees;
+		ActionSupprimer(Class<? extends Element> classe, ModeleArbreProp donnees, TreePath item) {
+			super(commandesSuppr[item.getPathCount()-2]);
+			this.item = item;
+			this.classe = classe;
+			this.donnees = donnees;
+		}
+		@SuppressWarnings("unchecked")
+		public void executer() {
+			corpus.removeEventListener(VisuStructure.this);
+			DefaultMutableTreeNode noeud, noeud1, noeud2;
+			noeud = (DefaultMutableTreeNode) item.getLastPathComponent();
+			switch (item.getPathCount()) {
+			case 1: // racine
+				return;
+			case 2: // type
+				if (corpus.saisirSupprimerType(VisuStructure.this, classe,
+						(String) noeud.getUserObject())) {
+					donnees.removeNodeFromParent(noeud);
+				}
+				break;
+			case 3: // prop
+				noeud1 = (DefaultMutableTreeNode) item.getPathComponent(1);
+				if (corpus.saisirSupprimerProp(VisuStructure.this, classe,
+						(String) noeud1.getUserObject(), (String) noeud.getUserObject())) {
+					donnees.removeNodeFromParent(noeud);
+				}
+				;
+				break;
+			case 4: // val
+				noeud1 = (DefaultMutableTreeNode) item.getPathComponent(1);
+				noeud2 = (DefaultMutableTreeNode) item.getPathComponent(2);
+				String val = (String) noeud.getUserObject();
+				if (isDefaut(val)) val = oteDefaut(val);
+				if (corpus.saisirSupprimerVal(VisuStructure.this, classe,
+						(String) noeud1.getUserObject(), (String) noeud2.getUserObject(), val)) {
+					donnees.removeNodeFromParent(noeud);
+				}
+				break;
+			default:
+				throw new UnsupportedOperationException("Cas de suppression non prévu ");
+			}
+			corpus.addEventListener(VisuStructure.this);
+		}
+	}
+
+	private class ActionAjouterForme extends GAction {
+		TreePath item;
+		Class<? extends Element> classe;
+		JTree arbre;
+		ModeleArbreProp donnees;
+		ActionAjouterForme(JTree arbre, ModeleArbreProp donnees, TreePath item) {
+			super("Ajouter la forme de surface");
+			this.item = item;
+			this.donnees = donnees;
+			this.arbre = arbre;
+		}
+		@SuppressWarnings("unchecked")
+		public void executer() {
+			corpus.removeEventListener(VisuStructure.this);
+			DefaultMutableTreeNode noeud, noeud1;
+			noeud = (DefaultMutableTreeNode) item.getLastPathComponent();
+			String type = (String) noeud.getUserObject();
+			corpus.ajouterFormeUnite(type);
+			noeud1 = new DefaultMutableTreeNode(Structure.FORME, true);
+			donnees.insertNodeInto(noeud1, noeud, 0);
+			arbre.makeVisible(item.pathByAddingChild(noeud1));
+			corpus.addEventListener(VisuStructure.this);
+			corpus.instancierFormeUnite(type);
+
+		}
+	}
+
+	private class ActionDispatcher extends GAction {
+		TreePath item;
+		Class<? extends Element> classe;
+		JTree arbre;
+		ModeleArbreProp donnees;
+		ActionDispatcher(Class<? extends Element> classe, JTree arbre,
+				ModeleArbreProp donnees, TreePath item) {
+			super("Transformer en types distincts");
+			this.item = item;
+			this.classe = classe;
+			this.donnees = donnees;
+			this.arbre = arbre;
+		}
+		@SuppressWarnings("unchecked")
+		public void executer() {
+			corpus.removeEventListener(VisuStructure.this);
+			DefaultMutableTreeNode noeudprop = (DefaultMutableTreeNode) item.getLastPathComponent();
+			int nbval = noeudprop.getChildCount();
+			String[] vals = new String[nbval];
+			Enumeration<DefaultMutableTreeNode> eval = noeudprop.children();
+			for (int i = 0; i<nbval; i++)
+				vals[i] = (String) eval.nextElement().getUserObject();
+			DefaultMutableTreeNode noeudtype = (DefaultMutableTreeNode) item.getPathComponent(1);
+			int nbprop = noeudtype.getChildCount();
+			String[] props = new String[nbprop-1];
+			String[][] propsvals = new String[nbprop-1][];
+			Enumeration<DefaultMutableTreeNode> eprop = noeudtype.children();
+			for (int i = 0; eprop.hasMoreElements(); i++) {
+				DefaultMutableTreeNode nprop = eprop.nextElement();
+				if (nprop!=noeudprop) {
+					props[i] = (String) nprop.getUserObject();
+					propsvals[i] = new String[nprop.getChildCount()];
+					Enumeration<DefaultMutableTreeNode> epropval = nprop.children();
+					for (int j = 0; epropval.hasMoreElements(); j++)
+						propsvals[i][j] = (String) epropval.nextElement().getUserObject();
+				} else i--;
+			}
+			if (corpus.saisirDispatcherProp(VisuStructure.this, classe,
+					(String) noeudtype.getUserObject(),
+					(String) noeudprop.getUserObject(), vals, props, propsvals))
+				donnees.dispatcherProp(noeudtype, noeudprop, vals, props, propsvals);
+			corpus.addEventListener(VisuStructure.this);
+		}
+	}
+
+	private static class ModeleArbreProp extends DefaultTreeModel {
+		Structure structure;
+		Class<? extends Element> classe;
+		ModeleArbreProp(Structure structure, Class<? extends Element> classe) {
+			super(null, true);
+			this.structure = structure;
+			this.classe = classe;
+			setModele();
+		}
+		private void setModele() {
+			DefaultMutableTreeNode racine = new DefaultMutableTreeNode("TYPES :", true);
+			setRoot(racine);
+			String[] types = structure.getTypes(classe).toArray(new String[0]);
+			Arrays.sort(types);
+			for (String type : types) {
+				DefaultMutableTreeNode ntype =
+						new DefaultMutableTreeNode(type, true);
+				racine.add(ntype);
+				String[] props =
+						structure.getNomsProps(classe, type).toArray(new String[0]);
+				Arrays.sort(props);
+				for (String prop : props) {
+					DefaultMutableTreeNode nprop =
+							new DefaultMutableTreeNode(prop, true);
+					ntype.add(nprop);
+					String[] vals =
+							structure.getValeursProp(classe, type, prop).toArray(new String[0]);
+					Arrays.sort(vals);
+					for (String val : vals) {
+						if (val.equals(structure.getValeurParDefaut(classe, type, prop)))
+							val = placeDefaut(val);
+						DefaultMutableTreeNode nval =
+								new DefaultMutableTreeNode(val, false);
+						nprop.add(nval);
+					}
+				}
+			}
+			reload();
+		}
+		@SuppressWarnings("unchecked")
+		void insererNewType(String type) {
+			DefaultMutableTreeNode racine = (DefaultMutableTreeNode) getRoot();
+			insertNodeInto(new DefaultMutableTreeNode(type, true), racine, 0);
+		}
+		@SuppressWarnings("unchecked")
+		void insererNewProp(String type, String prop) {
+			DefaultMutableTreeNode racine = (DefaultMutableTreeNode) getRoot();
+			DefaultMutableTreeNode ntype = null;
+			for (Enumeration<DefaultMutableTreeNode> etype = racine.children();
+					etype.hasMoreElements();) {
+				ntype = etype.nextElement();
+				if (type.equals(ntype.getUserObject())) break;
+			}
+			insertNodeInto(new DefaultMutableTreeNode(prop, true), ntype, 0);
+		}
+		@SuppressWarnings("unchecked")
+		void insererNewValeur(String type, String prop, String valeur) {
+			DefaultMutableTreeNode racine = (DefaultMutableTreeNode) getRoot();
+			DefaultMutableTreeNode ntype = null;
+			DefaultMutableTreeNode nprop = null;
+			for (Enumeration<DefaultMutableTreeNode> etype = racine.children();
+					etype.hasMoreElements();) {
+				ntype = etype.nextElement();
+				if (type.equals(ntype.getUserObject())) {
+					for (Enumeration<DefaultMutableTreeNode> eprop = ntype.children(); eprop.hasMoreElements();) {
+						nprop = eprop.nextElement();
+						if (prop.equals(nprop.getUserObject())) break;
+					}
+					break;
+				}
+			}
+			insertNodeInto(new DefaultMutableTreeNode(valeur, false), nprop, 0);
+		}
+		@SuppressWarnings("unchecked")
+		void modifierValDefaut(String type, String prop, String valeur) {
+			DefaultMutableTreeNode racine = (DefaultMutableTreeNode) getRoot();
+			DefaultMutableTreeNode ntype = null;
+			DefaultMutableTreeNode nprop = null;
+			DefaultMutableTreeNode nval = null;
+			for (Enumeration<DefaultMutableTreeNode> etype = racine.children(); etype.hasMoreElements();) {
+				ntype = etype.nextElement();
+				if (type.equals(ntype.getUserObject())) {
+					for (Enumeration<DefaultMutableTreeNode> eprop = ntype.children(); eprop.hasMoreElements();) {
+						nprop = eprop.nextElement();
+						if (prop.equals(nprop.getUserObject())) break;
+					}
+					break;
+				}
+			}
+			for (Enumeration<DefaultMutableTreeNode> eval = nprop.children(); eval.hasMoreElements();) {
+				nval = eval.nextElement();
+				String val = (String) nval.getUserObject();
+				if (isDefaut(val)) {
+					nval.setUserObject(oteDefaut(val));
+					nodeChanged(nval);
+				}
+				if (val.equals(valeur)) {
+					nval.setUserObject(placeDefaut(val));
+					nodeChanged(nval);
+				}
+
+			}
+		}
+		void fusionnerType(DefaultMutableTreeNode noeudafusionner,
+				DefaultMutableTreeNode noeudagarder) {
+			removeNodeFromParent(noeudafusionner);
+			noeudagarder.removeAllChildren();
+			String type = (String) noeudagarder.getUserObject();
+			String[] props = structure.getNomsProps(classe, type).toArray(new String[0]);
+			Arrays.sort(props);
+			for (String prop : props) {
+				DefaultMutableTreeNode nprop = new DefaultMutableTreeNode(prop, true);
+				noeudagarder.add(nprop);
+				String[] vals = structure.getValeursProp(classe, type, prop).toArray(new String[0]);
+				Arrays.sort(vals);
+				for (String val : vals) {
+					if (val.equals(structure.getValeurParDefaut(classe, type, prop)))
+						val = placeDefaut(val);
+					DefaultMutableTreeNode nval = new DefaultMutableTreeNode(val, false);
+					nprop.add(nval);
+				}
+			}
+			nodeStructureChanged(noeudagarder);
+		}
+		void fusionnerProp(DefaultMutableTreeNode noeudtype, DefaultMutableTreeNode noeudafusionner,
+				DefaultMutableTreeNode noeudagarder) {
+			removeNodeFromParent(noeudafusionner);
+			noeudagarder.removeAllChildren();
+			String type = (String) noeudtype.getUserObject();
+			String prop = (String) noeudagarder.getUserObject();
+			String[] vals = structure.getValeursProp(classe, type, prop).toArray(new String[0]);
+			Arrays.sort(vals);
+			for (String val : vals) {
+				if (val.equals(structure.getValeurParDefaut(classe, type, prop)))
+					val = placeDefaut(val);
+				DefaultMutableTreeNode nval = new DefaultMutableTreeNode(val, false);
+				noeudagarder.add(nval);
+			}
+			nodeStructureChanged(noeudagarder);
+		}
+		void dispatcherProp(DefaultMutableTreeNode noeudtype,
+				DefaultMutableTreeNode noeudprop, String[] newtypes, String[] props,
+				String[][] propsvals) {
+			removeNodeFromParent(noeudtype);
+			removeNodeFromParent(noeudprop);
+			DefaultMutableTreeNode racine = (DefaultMutableTreeNode) getRoot();
+			DefaultMutableTreeNode ntype = null;
+			DefaultMutableTreeNode nprop = null;
+			for (String type : newtypes) {
+				insertNodeInto(ntype = new DefaultMutableTreeNode(type, true), racine, 0);
+				for (int i = 0; i<props.length; i++) {
+					insertNodeInto(nprop = new DefaultMutableTreeNode(props[i], true),
+							ntype, i);
+					for (int j = 0; j<propsvals[i].length; j++)
+						insertNodeInto(new DefaultMutableTreeNode(oteDefaut(propsvals[i][j]),
+								false), nprop, j);
+
+				}
+
+			}
+		}
+		@SuppressWarnings("unchecked")
+		boolean hasForme(DefaultMutableTreeNode noeudtype) {
+			for (Enumeration<DefaultMutableTreeNode> eprop = noeudtype.children();
+					eprop.hasMoreElements();) {
+				DefaultMutableTreeNode nprop = eprop.nextElement();
+				if (Structure.FORME.equals(nprop.getUserObject())) return true;
+			}
+
+			return false;
+		}
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/donnees/VisuStructure.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/donnees/Corpus.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/donnees/Corpus.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/donnees/Corpus.java	(revision 481)
@@ -0,0 +1,1107 @@
+
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.donnees;
+
+import java.awt.*;
+import java.io.*;
+import java.util.*;
+import java.util.ArrayList;
+import javax.swing.*;
+import visuAnalec.*;
+import visuAnalec.elements.*;
+import visuAnalec.Message.*;
+import visuAnalec.texte.PanneauTexte;
+import visuAnalec.util.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class Corpus {
+	public static interface CorpusListener extends EventListener {  // VisuAnalec, Vue et VisuStructure sont les seuls destinaires
+		void traiterEvent(Message e);
+	}
+	private ArrayList<CorpusListener> listeCorrespondants = new ArrayList<CorpusListener>();
+	private boolean modifie = false;
+	private String texte = "";
+	private ArrayList<Integer> finParagraphes = new ArrayList<Integer>();
+	private Structure structure = new Structure();
+	private HashMap<String, ArrayList<Unite>> unites = new HashMap<String, ArrayList<Unite>>();
+	private HashMap<String, ArrayList<Relation>> relations = new HashMap<String, ArrayList<Relation>>();
+	private HashMap<String, ArrayList<Schema>> schemas = new HashMap<String, ArrayList<Schema>>();
+	public void addEventListener(CorpusListener correspondant) {
+		listeCorrespondants.add(correspondant);
+	}
+	public void removeEventListener(CorpusListener correspondant) {
+		listeCorrespondants.remove(correspondant);
+	}
+	private void fireMessage(Message evt) {
+		boolean newModifie = !EnumSet.of(TypeMessage.CLEAR_CORPUS, TypeMessage.NEW_CORPUS, TypeMessage.CORPUS_SAVED).
+				contains(evt.getType());
+		//    if (!modifie && newModifie) {
+		//    	System.out.println("corpus modified: "+evt);
+		//    }
+		modifie = newModifie;
+		for (Object corresp : listeCorrespondants.toArray()) {
+			((CorpusListener) corresp).traiterEvent(evt);
+		}
+	}
+	public Structure getStructure() {
+		return structure;
+	}
+	public String getTexte() {
+		return texte;
+	}
+	public void setTexte(String texte) {
+		this.texte = texte;
+	}
+	public Integer[] getFinParagraphes() {
+		return finParagraphes.toArray(new Integer[0]);
+	}
+	public void setFinParagraphes(ArrayList<Integer> finpars) {
+		finParagraphes = finpars;
+	}
+	public String getTexteUnite(Unite unit) {
+		int deb = unit.getDeb();
+		int fin = unit.getFin();
+		return PanneauTexte.insereCarFinParagraphe(getTexte().substring(deb, fin),
+				getFinParagraphes(), deb);
+	}
+	public void modifTexte(String texte, ArrayList<Integer> finparag) {
+		this.texte = texte;
+		this.finParagraphes = finparag;
+		verifierFormesUnites();
+		fireMessage(new Message(this, TypeMessage.MODIF_TEXTE));
+	}
+	private void verifierFormesUnites() {
+		for (String type : structure.getTypes(Unite.class)) {
+			if (structure.getNomsProps(Unite.class, type).contains(Structure.FORME)) {
+				boolean modif = false;
+				for (Unite unit : getUnites(type)) {
+					String forme = getTexteUnite(unit);
+					if (!forme.equals(unit.getProp(Structure.FORME))) {
+						setValeurPropElement(unit, Structure.FORME, forme);
+					}
+				}
+			}
+		}
+	}
+	public void addFinParagraphe(int ind) {
+		finParagraphes.add(ind);
+	}
+	public void verifierFinParagrapheFinTexte() {
+		if (finParagraphes.isEmpty()
+				||finParagraphes.get(finParagraphes.size()-1)<texte.length())
+			finParagraphes.add(texte.length());
+	}
+	public void trierFinParagraphes() {
+		Integer[] fins = getFinParagraphes();
+		Arrays.sort(fins);
+		finParagraphes = new ArrayList<Integer>(Arrays.asList(fins));
+	}
+	public void verifierFinParagraphesTypesUnites(String[] types) {
+		// Attention : les fins de paragraphes sont en désordre à la fin de la fonction
+		Integer[] fins = getFinParagraphes();
+		Arrays.sort(fins);
+		ArrayList<Integer> newFinPars = new ArrayList<Integer>();
+		for (String type : types) for (Unite unit : getUnites(type)) {
+			Integer fin = unit.getFin();
+			if (Arrays.binarySearch(fins, fin)<0) newFinPars.add(fin);
+		}
+		finParagraphes.addAll(newFinPars);
+	}
+	public int[] calculerNoParagraphe(Unite[] unites) {
+		// les unites sont triées
+		// les numéros de paragraphe commencent à 1 
+		int[] nosPar = new int[unites.length];
+		Integer[] finPar = getFinParagraphes();
+		Arrays.sort(finPar);
+		int nopar = 0;
+		for (int i = 0; i<unites.length; i++) {
+			while (unites[i].getDeb()>=finPar[nopar]) nopar++;
+			nosPar[i] = nopar+1;
+		}
+		return nosPar;
+	}
+	public String[][] getConcordances(Element[] elts, int empan) {
+		Integer[] finPar = getFinParagraphes();
+		String[][] concordances = new String[elts.length][3];
+		for (int i = 0; i<elts.length; i++) {
+			Unite unite0 = elts[i].getUnite0();
+			int debElt = unite0.getDeb();
+			int finElt = unite0.getFin();
+			int deb;
+			if (debElt-empan>0) {
+				concordances[i][0] = "[...]";
+				deb = debElt-empan;
+			} else {
+				concordances[i][0] = "";
+				deb = 0;
+			}
+			concordances[i][0] += PanneauTexte.insereCarFinParagraphe(
+					texte.substring(deb, debElt), finPar, deb);
+			concordances[i][1] = PanneauTexte.insereCarFinParagraphe(
+					texte.substring(debElt, finElt), finPar, debElt);
+			if (finElt+empan<texte.length()) {
+				concordances[i][2] = PanneauTexte.insereCarFinParagraphe(
+						texte.substring(finElt, finElt+empan), finPar, finElt)+"[...]";
+			} else
+				concordances[i][2] = PanneauTexte.insereCarFinParagraphe(
+						texte.substring(finElt), finPar, finElt);
+		}
+		return concordances;
+	}
+	public Unite addUniteSaisie(String type, int deb, int fin) { // ajout d'une unité saisie
+		Unite unite = new Unite(type, deb, fin);
+		addValeursDefauts(unite);
+		if (!unites.containsKey(type)) {
+			unites.put(type, new ArrayList<Unite>());
+		}
+		unites.get(type).add(unite);
+		fireMessage(new ElementEvent(this, TypeModifElement.AJOUT_UNITE, unite));
+		return unite;
+	}
+	public Unite addUniteSaisie(String type, int deb, int fin, HashMap<String, String> properties) { // ajout d'une unité saisie
+		Unite unite = new Unite(type, deb, fin);
+		addValeursDefauts(unite);
+		for (String k : properties.keySet()) {
+			unite.getProps().put(k, properties.get(k));
+		}
+		if (!unites.containsKey(type)) {
+			unites.put(type, new ArrayList<Unite>());
+		}
+		unites.get(type).add(unite);
+		fireMessage(new ElementEvent(this, TypeModifElement.AJOUT_UNITE, unite));
+		return unite;
+	}
+	public void addUniteLue(Unite unite) { // ajout d'une unité créée par la lecture d'un corpus: pas de message 
+		// et mise à jour éventuelle de la structure et de la HashMap unites
+		String type = unite.getType();
+		if (type==null||type.isEmpty()) return;
+		structure.majNewElement(unite);
+		if (!unites.containsKey(type)) {
+			unites.put(type, new ArrayList<Unite>());
+		}
+		unites.get(type).add(unite);
+	}
+
+	public void addUniteConvertit(Unite unite) {  // ajout d'une unité créé par fusion de tous les types d'unités
+		//: pas de message et mise à jour éventuelle de la structure et de la HashMap schemas
+		String type = unite.getType();
+		if (type==null||type.isEmpty()) return;
+		structure.majNewElement(unite);
+		if (!unites.containsKey(type)) {
+			unites.put(type, new ArrayList<Unite>());
+		}
+		unites.get(type).add(unite);
+		fireMessage(new Message(this, TypeMessage.NEW_CORPUS));
+	}
+
+	public void modifBornesUnite(Unite unite, int deb, int fin) {
+		unite.setDeb(deb);
+		unite.setFin(fin);
+		fireMessage(new ElementEvent(this, TypeModifElement.BORNES_UNITE, unite));
+	}
+	public void supUnite(Unite unite) {
+		String type = unite.getType();
+		unites.get(type).remove(unite);
+		fireMessage(new ElementEvent(this, TypeModifElement.SUP_UNITE, unite));
+		supLiensElement(unite);
+	}
+	public boolean checkPresenceUnite(String type, int deb, int fin) { // pas très efficace
+		if (!unites.containsKey(type)) return false;
+		for (Unite unit : getUnites(type))
+			if (unit.getDeb()==deb&&unit.getFin()==fin) return true;
+		return false;
+
+	}
+	private int checkFusionnerUnites(HashMap<String, ArrayList<Unite>> newunites, HashSet<Unite> unitesAajouter,
+			HashMap<Unite, Unite> unitesAfusionner) {
+		int nbEcrases = 0;
+		for (String type : newunites.keySet()) {
+			if (!unites.containsKey(type)) {
+				unitesAajouter.addAll(newunites.get(type));
+				continue;
+			}
+			for (Unite newunite : newunites.get(type)) {
+				Unite unit = chercherUniteCoincidente(newunite, unites.get(type));
+				if (unit==null) unitesAajouter.add(newunite);
+				else {
+					unitesAfusionner.put(newunite, unit);
+					for (String prop : newunite.getProps().keySet())
+						if (!unit.getProp(prop).isEmpty()&&!newunite.getProp(prop).isEmpty()
+								&&!unit.getProp(prop).equals(newunite.getProp(prop))) {
+							nbEcrases++;
+							break;
+						}
+				}
+			}
+		}
+		return nbEcrases;
+	}
+	private Unite chercherUniteCoincidente(Unite unite, ArrayList<Unite> lunites) {
+		for (Unite unit : lunites) if (unite.coincide(unit)) return unit;
+		return null;
+	}
+	public void addRelationSaisie(String type, Element elt1, Element elt2) {
+		Relation relation = new Relation(type, elt1, elt2);
+		addValeursDefauts(relation);
+		if (!relations.containsKey(type)) {
+			relations.put(type, new ArrayList<Relation>());
+		}
+		relations.get(type).add(relation);
+		relation.getElt2().addRelationEntrante(relation);
+		relation.getElt1().addRelationSortante(relation);
+		fireMessage(new ElementEvent(this, TypeModifElement.AJOUT_RELATION, relation));
+	}
+	public void addRelationLue(Relation relation) { // ajout d'une relation créée par la lecture d'un corpus: pas de message
+		// et mise à jour éventuelle de la structure et de la HashMap relations
+		String type = relation.getType();
+		if (type==null||type.isEmpty()) return;
+		structure.majNewElement(relation);
+		if (!relations.containsKey(type)) {
+			relations.put(type, new ArrayList<Relation>());
+		}
+		relations.get(type).add(relation);
+		relation.getElt2().addRelationEntrante(relation);
+		relation.getElt1().addRelationSortante(relation);
+	}
+	public void supRelation(Relation rel) {
+		String type = rel.getType();
+		relations.get(type).remove(rel);
+		rel.getElt1().oteRelationSortante(rel);
+		rel.getElt2().oteRelationEntrante(rel);
+		fireMessage(new ElementEvent(this, TypeModifElement.SUP_RELATION, rel));
+		supLiensElement(rel);
+	}
+	private int checkFusionnerRelations(HashMap<String, ArrayList<Relation>> newrels, HashSet<Relation> relsAajouter,
+			HashMap<Relation, Relation> relsAfusionner) {
+		int nbEcrases = 0;
+		for (String type : newrels.keySet()) {
+			if (!relations.containsKey(type)) {
+				relsAajouter.addAll(newrels.get(type));
+				continue;
+			}
+			for (Relation newrel : newrels.get(type)) {
+				Relation rel = chercherRelationCoincidente(newrel, relations.get(type));
+				if (rel==null) relsAajouter.add(newrel);
+				else {
+					relsAfusionner.put(newrel, rel);
+					for (String prop : newrel.getProps().keySet())
+						if (!rel.getProp(prop).isEmpty()&&!newrel.getProp(prop).isEmpty()
+								&&!rel.getProp(prop).equals(newrel.getProp(prop))) {
+							nbEcrases++;
+							break;
+						}
+				}
+			}
+		}
+		return nbEcrases;
+	}
+	private Relation chercherRelationCoincidente(Relation rel, ArrayList<Relation> lrels) {
+		for (Relation rel1 : lrels) if (rel.coincide(rel1)) return rel1;
+		return null;
+	}
+	private static void fusionnerElementsRelation(Relation relation, HashMap<Unite, Unite> unitesAfusionner,
+			HashMap<Relation, Relation> relationsAfusionner, HashMap<Schema, Schema> schemasAfusionner) {
+		if (relation.getElt1().getClass()==Unite.class&&unitesAfusionner.containsKey(relation.getElt1()))
+			relation.setElt1(unitesAfusionner.get(relation.getElt1()));
+		else if (relation.getElt1().getClass()==Relation.class&&relationsAfusionner.containsKey(relation.getElt1()))
+			relation.setElt1(relationsAfusionner.get(relation.getElt1()));
+		else if (relation.getElt1().getClass()==Schema.class&&schemasAfusionner.containsKey(relation.getElt1()))
+			relation.setElt1(schemasAfusionner.get(relation.getElt1()));
+		if (relation.getElt2().getClass()==Unite.class&&unitesAfusionner.containsKey(relation.getElt2()))
+			relation.setElt2(unitesAfusionner.get(relation.getElt2()));
+		else if (relation.getElt2().getClass()==Relation.class&&relationsAfusionner.containsKey(relation.getElt2()))
+			relation.setElt2(relationsAfusionner.get(relation.getElt2()));
+		else if (relation.getElt2().getClass()==Schema.class&&schemasAfusionner.containsKey(relation.getElt2()))
+			relation.setElt2(schemasAfusionner.get(relation.getElt2()));
+	}
+	public void addSchemaSaisi(String type, Element elt) {
+		Schema schema = new Schema(type);
+		addValeursDefauts(schema);
+		if (!schemas.containsKey(type)) {
+			schemas.put(type, new ArrayList<Schema>());
+		}
+		schemas.get(type).add(schema);
+		if (elt!=null) {
+			schema.ajouter(elt);
+			elt.addSchemaContenant(schema);
+		}
+		fireMessage(new ElementEvent(this, TypeModifElement.AJOUT_SCHEMA, schema));
+	}
+	public void addSchemaLu(Schema schema) {  // ajout d'un schéma créé par la lecture d'un corpus: pas de message
+		// et mise à jour éventuelle de la structure et de la HashMap schemas
+		String type = schema.getType();
+		if (type==null||type.isEmpty()) return;
+		structure.majNewElement(schema);
+		if (!schemas.containsKey(type)) {
+			schemas.put(type, new ArrayList<Schema>());
+		}
+		schemas.get(type).add(schema);
+		for (Element elt : schema.getContenu()) {
+			elt.addSchemaContenant(schema);
+		}
+	}
+	public void addSchemaConvertit(Schema schema) {  // ajout d'un schéma créé par conversion des données: pas de message
+		// et mise à jour éventuelle de la structure et de la HashMap schemas
+		String type = schema.getType();
+		if (type==null||type.isEmpty()) return;
+		structure.majNewElement(schema);
+		if (!schemas.containsKey(type)) {
+			schemas.put(type, new ArrayList<Schema>());
+		}
+		schemas.get(type).add(schema);
+		for (Element elt : schema.getContenu()) {
+			elt.addSchemaContenant(schema);
+		}
+		fireMessage(new Message(this, TypeMessage.NEW_CORPUS));
+	}
+
+
+
+	public void ajouterElementSchemaSaisi(Element elt, Schema sch) {
+		if (!sch.ajouter(elt)) {
+			GMessages.impossibiliteAction("Impossible d'ajouter cet élément "
+					+"au schéma courant :\n problème de récursivité infinie");
+		}
+		elt.addSchemaContenant(sch);
+		fireMessage(new ElementEvent(this, TypeModifElement.MODIF_SCHEMA, sch));
+	}
+	public void oterElementSchema(Element elt, Schema sch) {
+		sch.oter(elt);
+		elt.oteSchemaContenant(sch);
+		fireMessage(new ElementEvent(this, TypeModifElement.MODIF_SCHEMA, sch));
+	}
+	public void supSchema(Schema sch) {
+		String type = sch.getType();
+		schemas.get(type).remove(sch);
+		fireMessage(new ElementEvent(this, TypeModifElement.SUP_SCHEMA, sch));
+		supLiensElement(sch);
+	}
+	private int checkFusionnerSchemas(HashMap<String, ArrayList<Schema>> newschs, HashSet<Schema> schsAajouter,
+			HashMap<Schema, Schema> schsAfusionner) {
+		int nbEcrases = 0;
+		for (String type : newschs.keySet()) {
+			if (!schemas.containsKey(type)) {
+				schsAajouter.addAll(newschs.get(type));
+				continue;
+			}
+			for (Schema newsch : newschs.get(type)) {
+				Schema sch = chercherSchemaCoincident(newsch, schemas.get(type));
+				if (sch==null) schsAajouter.add(newsch);
+				else {
+					schsAfusionner.put(newsch, sch);
+					for (String prop : newsch.getProps().keySet())
+						if (!sch.getProp(prop).isEmpty()&&!newsch.getProp(prop).isEmpty()
+								&&!sch.getProp(prop).equals(newsch.getProp(prop))) {
+							nbEcrases++;
+							break;
+						}
+				}
+			}
+		}
+		return nbEcrases;
+	}
+	private Schema chercherSchemaCoincident(Schema sch, ArrayList<Schema> lschs) {
+		for (Schema sch1 : lschs) if (sch.coincide(sch1)) return sch1;
+		return null;
+	}
+	private static void fusionnerElementsSchema(Schema schema, HashMap<Unite, Unite> unitesAfusionner,
+			HashMap<Relation, Relation> relationsAfusionner, HashMap<Schema, Schema> schemasAfusionner) {
+		for (Element elt : schema.getContenu()) {
+			if (elt.getClass()==Unite.class&&unitesAfusionner.containsKey(elt)) {
+				schema.oter(elt);
+				schema.ajouter(unitesAfusionner.get(elt));
+			} else if (elt.getClass()==Relation.class&&relationsAfusionner.containsKey(elt)) {
+				schema.oter(elt);
+				schema.ajouter(relationsAfusionner.get(elt));
+			} else if (elt.getClass()==Schema.class&&schemasAfusionner.containsKey(elt)) {
+				schema.oter(elt);
+				schema.ajouter(schemasAfusionner.get(elt));
+			}
+		}
+	}
+	private void supLiensElement(Element elt) {
+		ArrayList<Relation> rels = elt.getRelations();
+		for (Relation rel : rels) {
+			supRelation(rel);
+		}
+		ArrayList<Schema> schs = elt.getSchemas();
+		for (Schema sch : schs) {
+			oterElementSchema(elt, sch);
+		}
+	}
+	public void addValeur(Class<? extends Element> classe, String type, String prop, String valeur) {
+		structure.ajouterVal(classe, type, prop, valeur);
+		fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_VALEUR, classe, type, prop, valeur));
+	}
+	public void addValeursDefauts(Element elt) {
+		for (String prop : structure.getNomsProps(elt.getClass(), elt.getType())) {
+			elt.putProp(prop, structure.getValeurParDefaut(elt.getClass(), elt.getType(), prop));
+		}
+	}
+	public void ajouterFormeUnite(String type) {
+		structure.ajouterProp(Unite.class, type, Structure.FORME);
+		fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_FORME_UNITE,
+				Unite.class, type));
+	}
+	public void instancierFormeUnite(String type) {
+		ArrayList<Unite> units = getUnites(type);
+		for (Unite unit : units) {
+			String forme = getTexteUnite(unit);
+			setValeurPropElement(unit, Structure.FORME, forme);
+		}
+	}
+	public void modifierValParDefaut(Class<? extends Element> classe, String type, String prop, String val) {
+		structure.modifierValParDefaut(classe, type, prop, val);
+		if (!val.isEmpty()) instancierParValeurDefaut(classe, type, prop, val);
+		fireMessage(new StructureEvent(this, TypeModifStructure.VALEUR_PAR_DEFAUT, classe, type, prop, val));
+	}
+	private void instancierParValeurDefaut(Class<? extends Element> classe, String type, String prop, String val) {
+		ArrayList<? extends Element> elts = getElements(classe, type);
+		boolean noninstancies = false;
+		for (Element elt : elts) if (elt.getProp(prop).isEmpty()) {
+			noninstancies = true;
+			break;
+		}
+		if (noninstancies&&JOptionPane.showConfirmDialog(null, "Voulez-vous donner "
+				+"cette valeur par défaut aux éléments existants non encore instanciés",
+				"Action optionnelle", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)
+				!=JOptionPane.NO_OPTION)
+			for (Element elt : elts) if (elt.getProp(prop).isEmpty())
+				elt.putProp(prop, val);
+	}
+	public void setValeurPropElement(Element elt, String prop, String newval) {
+		if (newval.isEmpty()) {
+			elt.supProp(prop);
+		} else {
+			if (!structure.getValeursProp(elt.getClass(), elt.getType(), prop).contains(newval)) {
+				addValeur(elt.getClass(), elt.getType(), prop, newval);
+			}
+			elt.putProp(prop, newval);
+		}
+		fireMessage(new ElementEvent(this, TypeModifElement.MODIF_VALEUR, elt, prop, newval));
+
+	}
+	public ArrayList<? extends Element> getElements(Class<? extends Element> classe, String type) {
+		if (classe==Unite.class) return getUnites(type);
+		if (classe==Relation.class) return getRelations(type);
+		if (classe==Schema.class) return getSchemas(type);
+		throw new UnsupportedOperationException("sous-classe non traitée");
+	}
+	public ArrayList<Unite> getUnites(String type) {
+		if (unites.get(type)==null) {
+			return new ArrayList<Unite>();
+		}
+		return unites.get(type);
+	}
+	public ArrayList<Unite> getToutesUnites() {
+		ArrayList<Unite> ttesUnites = new ArrayList<Unite>();
+		for (String type : structure.getTypes(Unite.class)) {
+			ttesUnites.addAll(getUnites(type));
+		}
+		return ttesUnites;
+	}
+	public ArrayList<Relation> getRelations(String type) {
+		if (relations.get(type)==null) {
+			return new ArrayList<Relation>();
+		}
+		return relations.get(type);
+	}
+	public ArrayList<Relation> getToutesRelations() {
+		ArrayList<Relation> ttesRelations = new ArrayList<Relation>();
+		for (String type : structure.getTypes(Relation.class)) {
+			ttesRelations.addAll(getRelations(type));
+		}
+		return ttesRelations;
+	}
+	public ArrayList<Schema> getSchemas(String type) {
+		if (schemas.get(type)==null) {
+			return new ArrayList<Schema>();
+		}
+		return schemas.get(type);
+	}
+	public ArrayList<Schema> getTousSchemas() {
+		ArrayList<Schema> tsSchemas = new ArrayList<Schema>();
+		for (String type : structure.getTypes(Schema.class)) {
+			tsSchemas.addAll(getSchemas(type));
+		}
+		return tsSchemas;
+	}
+	// Modifs de la structure provenant de VisuStructure
+	public String saisirAjouterType(Container fenetre, Class<? extends Element> classe) {
+		String newNom = JOptionPane.showInputDialog(fenetre, "Nom du nouveau type ",
+				"Ajouter un type "+GVisu.getNomDeClasse(classe),
+				JOptionPane.PLAIN_MESSAGE);
+		if (newNom==null) return null;
+		newNom = newNom.trim();
+		if (newNom.isEmpty()) return null;
+		if (structure.getTypes(classe).contains(newNom)) {
+			JOptionPane.showMessageDialog(fenetre, "Ajout impossible : le type "+"\""+newNom+"\""+" existe déjà",
+					"Erreur d'ajout de type", JOptionPane.ERROR_MESSAGE);
+			return null;
+		}
+		ajouterType(classe, newNom);
+		
+		return newNom;
+	}
+	/**
+	 * Ajoute un nouveau type et lance un StructureEvent
+	 * 
+	 * @param classe
+	 * @param type
+	 * @param newNom
+	 * @return
+	 */
+	private void ajouterType(Class<? extends Element> classe, String type) {
+		structure.ajouterType(classe, type);
+		if (classe==Unite.class) {
+			unites.put(type, new ArrayList<Unite>());
+		} else if (classe==Relation.class) {
+			relations.put(type, new ArrayList<Relation>());
+		} else if (classe==Schema.class) {
+			schemas.put(type, new ArrayList<Schema>());
+		}
+		fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_TYPE, classe, type));
+	}
+
+	/**
+	 * Ajoute une nouvelle propriété et lance un StructureEvent
+	 * 
+	 * @param classe
+	 * @param type
+	 * @param newNom
+	 * @return
+	 */
+	public String ajouterProp(Class<? extends Element> classe, String type, String newNom) {
+
+		if (newNom.isEmpty()) return null;
+		if (Structure.FORME.equals(newNom)) {
+			GMessages.impossibiliteAction("Le nom "+Structure.FORME+" est réservé par le système");
+			return null;
+		}
+		if (structure.getNomsProps(classe, type).contains(newNom)) {
+			return null;
+		}
+		structure.ajouterProp(classe, type, newNom);
+		fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_PROP, classe, type, newNom));
+		return newNom;
+	}
+
+	public String saisirAjouterProp(Container fenetre, Class<? extends Element> classe, String type) {
+		String newNom = JOptionPane.showInputDialog(fenetre, "Nom de la nouvelle propriété",
+				"Ajouter une propriété au type "+"\""+type+"\"", JOptionPane.PLAIN_MESSAGE);
+		if (newNom==null) return null;
+		newNom = newNom.trim();
+		if (newNom.isEmpty()) return null;
+		if (Structure.FORME.equals(newNom)) {
+			GMessages.impossibiliteAction("Le nom "+Structure.FORME+" est réservé par le système");
+			return null;
+		}
+		if (structure.getNomsProps(classe, type).contains(newNom)) {
+			JOptionPane.showMessageDialog(fenetre, "Ajout impossible :la propriété "+"\""+newNom+"\""+" existe déjà",
+					"Erreur d'ajout de propriété", JOptionPane.ERROR_MESSAGE);
+			return null;
+		}
+		structure.ajouterProp(classe, type, newNom);
+		fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_PROP, classe, type, newNom));
+		return newNom;
+	}
+	public String saisirAjouterVal(Container fenetre, Class<? extends Element> classe, String type, String prop) {
+		String newNom = JOptionPane.showInputDialog(fenetre, "Nom de la nouvelle valeur",
+				"Ajouter une valeur pour la propriété "+"\""+prop+"\"", JOptionPane.PLAIN_MESSAGE);
+		if (newNom==null) return null;
+		newNom = newNom.trim();
+		if (newNom.isEmpty()) return null;
+		if (structure.getValeursProp(classe, type, prop).contains(newNom)) {
+			JOptionPane.showMessageDialog(fenetre, "Ajout impossible : la valeur "+"\""+newNom+"\""+" existe déjà",
+					"Erreur d'ajout de valeur", JOptionPane.ERROR_MESSAGE);
+			return null;
+		}
+		structure.ajouterVal(classe, type, prop, newNom);
+		fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_VALEUR, classe, type, prop, newNom));
+		return newNom;
+	}
+	/**
+	 * Ajoute une nouvelle valeur et lance un StructureEvent
+	 * 
+	 * @param classe
+	 * @param type
+	 * @param newNom
+	 * @return
+	 */
+	public String ajouterVal(Class<? extends Element> classe, String type, String prop, String newNom) {
+		if (newNom==null) return null;
+		newNom = newNom.trim();
+		if (newNom.isEmpty()) return null;
+		if (structure.getValeursProp(classe, type, prop).contains(newNom)) {
+			return null;
+		}
+		structure.ajouterVal(classe, type, prop, newNom);
+		fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_VALEUR, classe, type, prop, newNom));
+		return newNom;
+	}
+	public String saisirRenommerType(Container fenetre, Class<? extends Element> classe, String oldNom) {
+		String newNom = (String) JOptionPane.showInputDialog(fenetre, "Nouveau nom pour le type "+"\""+oldNom+"\"",
+				"Renommer un type "+GVisu.getNomDeClasse(classe), JOptionPane.PLAIN_MESSAGE, null, null, oldNom);
+		if (newNom==null) return null;
+		newNom = newNom.trim();
+		if (oldNom.equals(newNom)||newNom.isEmpty()) return null;
+		boolean fusion = structure.getTypes(classe).contains(newNom);
+		if (fusion&&!GMessages.confirmationAction("Le type "+"\""+newNom+"\""
+				+" existe déjà. Fusionner les deux types ? ")) return null;
+		if (classe==Unite.class) {
+			if (fusion) unites.get(newNom).addAll(unites.get(oldNom));
+			else unites.put(newNom, unites.get(oldNom));
+			for (Unite unit : unites.get(oldNom)) unit.setType(newNom);
+			unites.remove(oldNom);
+		} else if (classe==Relation.class) {
+			if (fusion) relations.get(newNom).addAll(relations.get(oldNom));
+			else relations.put(newNom, relations.get(oldNom));
+			for (Relation rel : relations.get(oldNom)) {
+				rel.getElt1().oteRelationSortante(rel);
+				rel.getElt2().oteRelationEntrante(rel);
+				rel.setType(newNom);
+				rel.getElt1().addRelationSortante(rel);
+				rel.getElt2().addRelationEntrante(rel);
+			}
+			relations.remove(oldNom);
+		} else if (classe==Schema.class) {
+			if (fusion) schemas.get(newNom).addAll(schemas.get(oldNom));
+			else schemas.put(newNom, schemas.get(oldNom));
+			for (Schema sch : schemas.get(oldNom)) {
+				for (Element elt : sch.getContenu()) elt.oteSchemaContenant(sch);
+				sch.setType(newNom);
+				for (Element elt : sch.getContenu()) elt.addSchemaContenant(sch);
+			}
+			schemas.remove(oldNom);
+		}
+		if (fusion) {
+			structure.fusionnerType(classe, oldNom, newNom);
+			fireMessage(new StructureEvent(this, TypeModifStructure.FUSION_TYPE,
+					classe, oldNom, newNom));
+		} else {
+			structure.renommerType(classe, oldNom, newNom);
+			fireMessage(new StructureEvent(this, TypeModifStructure.RENOM_TYPE,
+					classe, oldNom, newNom));
+		}
+		return newNom;
+	}
+	public String saisirRenommerProp(Container fenetre,
+			Class<? extends Element> classe, String type, String oldNom) {
+		String newNom = (String) JOptionPane.showInputDialog(fenetre, "Nouveau nom pour la propriété "+"\""+oldNom+"\"",
+				"Renommer une propriété du type "+"\""+type+"\"", JOptionPane.PLAIN_MESSAGE, null, null, oldNom);
+		if (newNom==null) return null;
+		newNom = newNom.trim();
+		if (oldNom.equals(newNom)||newNom.isEmpty()) return null;
+		if (Structure.FORME.equals(newNom)) {
+			GMessages.impossibiliteAction("Le nom "+Structure.FORME+" est réservé par le système");
+			return null;
+		}
+		boolean fusion = false;
+		ArrayList<? extends Element> elements = getElements(classe, type);
+		if (structure.getNomsProps(classe, type).contains(newNom)) {
+			int rep = JOptionPane.showOptionDialog(fenetre, "La propriété "+"\""+newNom+"\""+" existe déjà."
+					+" Fusionner les deux propriétés ? ", "Propriété existante",
+					JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+					null, new Object[]{"Oui", "Annuler"}, "Oui");
+			if (rep==1) return null;
+			int nbEcrases = 0;
+			for (Element elt : elements) if (!elt.getProp(newNom).isEmpty()
+					&&!elt.getProp(newNom).equals(elt.getProp(oldNom))) nbEcrases++;
+			if (nbEcrases>0) {
+				int rep1 = JOptionPane.showOptionDialog(fenetre, "L'opération de fusion va écraser l'ancienne valeur de la propriété "
+						+"\""+newNom+"\""+" pour "+nbEcrases+" élément(s)", "Fusion de deux propriétés",
+						JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+						null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+				if (rep1==1) return null;
+			}
+			fusion = true;
+		}
+		if (fusion) structure.fusionnerProp(classe, type, oldNom, newNom);
+		else structure.renommerProp(classe, type, oldNom, newNom);
+		for (Element elt : elements) {
+			String val = elt.getProp(oldNom);
+			if (!val.isEmpty()) elt.putProp(newNom, val);
+			elt.getProps().remove(oldNom);
+		}
+		if (fusion)
+			fireMessage(new StructureEvent(this, TypeModifStructure.FUSION_PROP, classe, type, oldNom, newNom));
+		else
+			fireMessage(new StructureEvent(this, TypeModifStructure.RENOM_PROP, classe, type, oldNom, newNom));
+		return newNom;
+	}
+	public String saisirRenommerVal(Container fenetre, Class<? extends Element> classe, String type,
+			String prop, String oldNom) {
+		String newNom = (String) JOptionPane.showInputDialog(fenetre, "Nouveau nom pour la valeur "+"\""+oldNom+"\"",
+				"Renommer une valeur de la propriété "+"\""+prop+"\"", JOptionPane.PLAIN_MESSAGE, null, null, oldNom);
+		if (newNom==null) return null;
+		newNom = newNom.trim();
+		if (oldNom.equals(newNom)||newNom.isEmpty()) return null;
+		boolean fusion = false;
+		if (structure.getValeursProp(classe, type, prop).contains(newNom)) {
+			int rep = JOptionPane.showOptionDialog(fenetre, "La valeur "+"\""+newNom+"\""+" existe déjà."
+					+" Fusionner les deux valeurs ? ", "Valeur existante",
+					JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+					null, new Object[]{"Oui", "Annuler"}, "Oui");
+			if (rep==1) return null;
+			fusion = true;
+		}
+		structure.renommerVal(classe, type, prop, oldNom, newNom);
+		ArrayList<? extends Element> elements = getElements(classe, type);
+		for (Element elt : elements) {
+			String val = elt.getProp(prop);
+			if (oldNom.equals(val)) {
+				elt.putProp(prop, newNom);
+			}
+		}
+		if (fusion)
+			fireMessage(new StructureEvent(this, TypeModifStructure.FUSION_VALEUR, classe, type, prop, oldNom, newNom));
+		else
+			fireMessage(new StructureEvent(this, TypeModifStructure.RENOM_VALEUR, classe, type, prop, oldNom, newNom));
+		return newNom;
+	}
+	public boolean saisirSupprimerType(Container fenetre, Class<? extends Element> classe, String type) {
+		Element[] elements = null;
+		if (classe==Unite.class)
+			elements = unites.get(type).toArray(new Element[0]);
+		else if (classe==Relation.class)
+			elements = relations.get(type).toArray(new Element[0]);
+		else if (classe==Schema.class)
+			elements = schemas.get(type).toArray(new Element[0]);
+
+		if (elements.length>0) {
+			int nbSupprimes = elements.length;
+			int rep = JOptionPane.showOptionDialog(fenetre, "La suppresion du type  "+"\""+type+"\""
+					+" va entraîner la suppression "+(nbSupprimes==1 ? "d'un élément" : "de "+nbSupprimes+" éléments"),
+					"Suppression "+GVisu.getNomDeClasse(classe)+"s",
+					JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+					null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+			if (rep==1) return false;
+			if (classe==Unite.class) {
+				for (Element elt : elements) supUnite((Unite) elt);
+				unites.remove(type);
+			}
+			if (classe==Relation.class) {
+				for (Element elt : elements) supRelation((Relation) elt);
+				relations.remove(type);
+			}
+			if (classe==Schema.class) {
+				for (Element elt : elements) supSchema((Schema) elt);
+				schemas.remove(type);
+			}
+		}
+		structure.supprimerType(classe, type);
+		fireMessage(new StructureEvent(this, TypeModifStructure.SUPPR_TYPE, classe, type));
+		return true;
+	}
+	public boolean saisirSupprimerProp(Container fenetre, Class<? extends Element> classe, String type, String oldNom) {
+		ArrayList<? extends Element> elements = getElements(classe, type);
+		int nbSup = 0;
+		for (Element elt : elements) if (!elt.getProp(oldNom).isEmpty()) nbSup++;
+		if (nbSup>0) {
+			int rep = JOptionPane.showOptionDialog(fenetre, "La propriété "+"\""+oldNom+"\""+" était instanciée pour "
+					+(nbSup==1 ? "un élément" : nbSup+" éléments"), "Suppression d'une propriété",
+					JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+					null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+			if (rep==1) return false;
+		}
+		for (Element elt : elements) elt.supProp(oldNom);
+		structure.supprimerProp(classe, type, oldNom);
+		fireMessage(new StructureEvent(this, TypeModifStructure.SUPPR_PROP, classe, type, oldNom));
+		return true;
+	}
+	public boolean saisirSupprimerVal(Container fenetre, Class<? extends Element> classe, String type,
+			String prop, String oldNom) {
+		ArrayList<? extends Element> elements = getElements(classe, type);
+		int nbSup = 0;
+		for (Element elt : elements) if (oldNom.equals(elt.getProp(prop)))
+			nbSup++;
+		if (nbSup>0) {
+			int rep = JOptionPane.showOptionDialog(fenetre, "La valeur "+"\""+oldNom+"\""+" était attribuée à "
+					+(nbSup==1 ? "un élément" : nbSup+" éléments"), "Suppression d'une valeur",
+					JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+					null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+			if (rep==1) return false;
+		}
+		structure.supprimerVal(classe, type, prop, oldNom);
+		for (Element elt : elements) if (oldNom.equals(elt.getProp(prop)))
+			elt.supProp(prop);
+		fireMessage(new StructureEvent(this, TypeModifStructure.SUPPR_VALEUR, classe, type, prop, oldNom));
+		return true;
+	}
+	public boolean saisirDispatcherProp(Container fenetre,
+			Class<? extends Element> classe, String oldtype, String oldprop,
+			String[] newtypes, String[] props, String[][] propsvals) {
+		HashSet<String> types = structure.getTypes(classe);
+		for (String type : newtypes) if (types.contains(type)) {
+			GMessages.impossibiliteAction("Le type "+type+" existe déjà");
+			return false;
+		}
+		ArrayList<? extends Element> elements = getElements(classe, oldtype);
+		for (Element elt : elements) if (elt.getProp(oldprop).isEmpty()) {
+			GMessages.impossibiliteAction("Certains éléments de type "+oldtype
+					+" ne possèdent pas de valeur pour la propriété "+oldprop);
+			return false;
+		}
+		structure.supprimerType(classe, oldtype);
+		for (String type : newtypes) {
+			structure.ajouterType(classe, type);
+			for (int i = 0; i<props.length; i++) {
+				structure.ajouterProp(classe, type, props[i]);
+				for (String val : propsvals[i])
+					structure.ajouterVal(classe, type, props[i], val);
+			}
+		}
+		if (classe==Unite.class) {
+			for (String type : newtypes) unites.put(type, new ArrayList<Unite>());
+			for (Unite unit : unites.get(oldtype)) {
+				String newtype = unit.getProp(oldprop);
+				unit.supProp(oldprop);
+				unit.setType(newtype);
+				unites.get(newtype).add(unit);
+			}
+			unites.remove(oldtype);
+		} else if (classe==Relation.class) {
+			for (String type : newtypes)
+				relations.put(type, new ArrayList<Relation>());
+			for (Relation rel : relations.get(oldtype)) {
+				String newtype = rel.getProp(oldprop);
+				rel.supProp(oldprop);
+				rel.getElt1().oteRelationSortante(rel);
+				rel.getElt2().oteRelationEntrante(rel);
+				rel.setType(newtype);
+				rel.getElt1().addRelationSortante(rel);
+				rel.getElt2().addRelationEntrante(rel);
+				relations.get(newtype).add(rel);
+			}
+			relations.remove(oldtype);
+		} else if (classe==Schema.class) {
+			for (String type : newtypes) schemas.put(type, new ArrayList<Schema>());
+			for (Schema sch : schemas.get(oldtype)) {
+				String newtype = sch.getProp(oldprop);
+				sch.supProp(oldprop);
+				for (Element elt : sch.getContenu()) elt.oteSchemaContenant(sch);
+				sch.setType(newtype);
+				for (Element elt : sch.getContenu()) elt.addSchemaContenant(sch);
+				schemas.get(newtype).add(sch);
+			}
+			schemas.remove(oldtype);
+		}
+		fireMessage(new StructureEvent(this, TypeModifStructure.SUPPR_TYPE,
+				classe, oldtype));
+		for (String type : newtypes) {
+			fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_TYPE_ET_ELEMENTS,
+					classe, type));
+			for (String prop : props)
+				fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_PROP,
+						classe, type, prop));
+		}
+		return true;
+	}
+	public void clearAnnot() {
+		finParagraphes.clear();
+		unites.clear();
+		relations.clear();
+		schemas.clear();
+	}
+	public void clearAll() {
+		clearAnnot();
+		structure.clear();
+		texte = "";
+	}
+	public boolean isModifie() {
+		return modifie;
+	}
+	public boolean isVide() {
+		return texte.isEmpty()&&structure.isVide();
+	}
+	public void fermer() {
+		if (isVide()) return;
+		clearAnnot();
+		structure.clear();
+		texte = "";
+		fireMessage(new Message(this, TypeMessage.CLEAR_CORPUS));
+	}
+	public void fermerConserverStructure() {
+		if (texte.isEmpty()) return;
+		clearAnnot();
+		texte = "";
+		fireMessage(new Message(this, TypeMessage.CLEAR_CORPUS));
+	}
+	@SuppressWarnings("unchecked")
+	public void lireJava(ObjectInputStream ois, boolean batch) throws IOException, ClassNotFoundException, ClassCastException {
+		texte = (String) ois.readObject();
+		finParagraphes = (ArrayList<Integer>) ois.readObject();
+		unites = (HashMap<String, ArrayList<Unite>>) ois.readObject();
+		relations = (HashMap<String, ArrayList<Relation>>) ois.readObject();
+		schemas = (HashMap<String, ArrayList<Schema>>) ois.readObject();
+		structure = Structure.lireJava(ois);
+		if (!batch) fireMessage(new Message(this, TypeMessage.NEW_CORPUS));
+	}
+	@SuppressWarnings("unchecked")
+	public void fusionnerAnnotJava(ObjectInputStream ois) throws IOException, ClassNotFoundException, ClassCastException {
+		String texte1 = (String) ois.readObject();
+		ArrayList<Integer> finParagraphes1 = (ArrayList<Integer>) ois.readObject();
+		if (!texte1.equals(texte)||!finParagraphes1.equals(finParagraphes)) {
+			JOptionPane.showMessageDialog(null, "Le texte du corpus à fusionner est différent du texte en cours",
+					"Fusion d'annotations impossible.", JOptionPane.ERROR_MESSAGE);
+			return;
+		}
+		HashMap<String, ArrayList<Unite>> unites1 = (HashMap<String, ArrayList<Unite>>) ois.readObject();
+		HashMap<String, ArrayList<Relation>> relations1 = (HashMap<String, ArrayList<Relation>>) ois.readObject();
+		HashMap<String, ArrayList<Schema>> schemas1 = (HashMap<String, ArrayList<Schema>>) ois.readObject();
+		Structure structure1 = Structure.lireJava(ois);
+		fusionnerStructureLue(structure1);
+		HashSet<Unite> unitesAajouter = new HashSet<Unite>();
+		HashMap<Unite, Unite> unitesAfusionner = new HashMap<Unite, Unite>();
+		int nbUnitesEcrasees = checkFusionnerUnites(unites1, unitesAajouter, unitesAfusionner);
+		HashSet<Relation> relationsAajouter = new HashSet<Relation>();
+		HashMap<Relation, Relation> relationsAfusionner = new HashMap<Relation, Relation>();
+		int nbRelationsEcrasees = checkFusionnerRelations(relations1, relationsAajouter, relationsAfusionner);
+		HashSet<Schema> schemasAajouter = new HashSet<Schema>();
+		HashMap<Schema, Schema> schemasAfusionner = new HashMap<Schema, Schema>();
+		int nbSchemasEcrases = checkFusionnerSchemas(schemas1, schemasAajouter, schemasAfusionner);
+		int nbEcrases = nbUnitesEcrasees+nbRelationsEcrasees+nbSchemasEcrases; // à améliorer
+		if (nbUnitesEcrasees>0||nbRelationsEcrasees>0||nbSchemasEcrases>0) {
+			int rep = JOptionPane.showOptionDialog(null, "L'opération de fusion va écraser d'anciennes valeurs de propriétés "
+					+" pour "+nbEcrases+" élément(s)", "Fusion d'annotations",
+					JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+					null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+			if (rep==1) return;
+		}
+		for (Unite unit : unitesAajouter) addUniteLue(unit);
+		for (Unite unit : unitesAfusionner.keySet())
+			for (String prop : unit.getProps().keySet())
+				unitesAfusionner.get(unit).putProp(prop, unit.getProp(prop));
+		for (Relation rel : relationsAajouter) {
+			fusionnerElementsRelation(rel, unitesAfusionner, relationsAfusionner, schemasAfusionner);
+			addRelationLue(rel);
+		}
+		for (Relation rel : relationsAfusionner.keySet())
+			for (String prop : rel.getProps().keySet())
+				relationsAfusionner.get(rel).putProp(prop, rel.getProp(prop));
+		for (Schema sch : schemasAajouter) {
+			fusionnerElementsSchema(sch, unitesAfusionner, relationsAfusionner, schemasAfusionner);
+			addSchemaLu(sch);
+		}
+		for (Schema sch : schemasAfusionner.keySet())
+			for (String prop : sch.getProps().keySet())
+				unitesAfusionner.get(sch).putProp(prop, sch.getProp(prop));
+		fireMessage(new Message(this, TypeMessage.NEW_CORPUS));
+	}
+	@SuppressWarnings("unchecked")
+	public void concatenerCorpusJava(ObjectInputStream ois) throws IOException, ClassNotFoundException, ClassCastException {
+		String texte1 = (String) ois.readObject();
+		ArrayList<Integer> finParagraphes1 = (ArrayList<Integer>) ois.readObject();
+		int offset = texte.length();
+		texte += texte1;
+		for (int finP : finParagraphes1) finParagraphes.add(finP+offset);
+		verifierFinParagrapheFinTexte();
+		HashMap<String, ArrayList<Unite>> unites1 = (HashMap<String, ArrayList<Unite>>) ois.readObject();
+		HashMap<String, ArrayList<Relation>> relations1 = (HashMap<String, ArrayList<Relation>>) ois.readObject();
+		HashMap<String, ArrayList<Schema>> schemas1 = (HashMap<String, ArrayList<Schema>>) ois.readObject();
+		Structure structure1 = Structure.lireJava(ois);
+		fusionnerStructureLue(structure1);
+		for (String type : unites1.keySet()) for (Unite unit : unites1.get(type)) {
+			unit.setDeb(unit.getDeb()+offset);
+			unit.setFin(unit.getFin()+offset);
+			addUniteLue(unit);
+		}
+		for (String type : relations1.keySet())
+			for (Relation rel : relations1.get(type)) {
+				addRelationLue(rel);
+			}
+		for (String type : schemas1.keySet())
+			for (Schema sch : schemas1.get(type)) {
+				addSchemaLu(sch);
+			}
+	}
+	@SuppressWarnings("unchecked")
+	public void extraireEtConcatenerCorpusJava(ObjectInputStream ois,
+			String nomDocument, String type)
+					throws IOException, ClassNotFoundException, ClassCastException {
+		//    System.out.println(nomDocument);
+		String texte1 = (String) ois.readObject();
+		ArrayList<Integer> finParagraphes1 = (ArrayList<Integer>) ois.readObject();
+		HashMap<String, ArrayList<Unite>> unites1 = (HashMap<String, ArrayList<Unite>>) ois.readObject();
+		if (unites1.containsKey(type)) {
+			int indFinPar1 = -1;
+			int offset1 = -1;
+			int offset = -1;
+			for (Unite unit : unites1.get(type)) {
+				int finUnit = unit.getFin();
+				if (indFinPar1<0||finUnit>finParagraphes1.get(indFinPar1)) {
+					do indFinPar1++;
+					while (finUnit>finParagraphes1.get(indFinPar1));
+					offset1 = indFinPar1==0 ? 0 : finParagraphes1.get(indFinPar1-1);
+					offset = texte.length();
+					texte += texte1.substring(offset1, finParagraphes1.get(indFinPar1));
+					finParagraphes.add(texte.length());
+				}
+				unit.setDeb(unit.getDeb()-offset1+offset);
+				unit.setFin(unit.getFin()-offset1+offset);
+				unit.putProp("sourceFile", nomDocument);
+				addUniteLue(unit);
+			}
+		}
+	}
+	public void ecrireJava(ObjectOutputStream oos) throws IOException {
+		oos.writeObject(texte);
+		oos.writeObject(finParagraphes);
+		oos.writeObject(unites);
+		oos.writeObject(relations);
+		oos.writeObject(schemas);
+		structure.ecrireJava(oos);
+		modifie = false;
+		fireMessage(new Message(this, TypeMessage.CORPUS_SAVED));
+	}
+	@SuppressWarnings("unchecked")
+	public void fusionnerStructureLue(Structure structureLue) {
+		for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class
+		}) {
+			for (String typeLu : structureLue.getTypes(classe)) {
+				if (!structure.getTypes(classe).contains(typeLu))
+					ajouterType(classe, typeLu);
+				for (String propLue : structureLue.getNomsProps(classe, typeLu)) {
+					if (!structure.getNomsProps(classe, typeLu).contains(propLue))
+						structure.ajouterProp(classe, typeLu, propLue);
+					for (String valLue : structureLue.getValeursProp(classe, typeLu, propLue))
+						if (!structure.getValeursProp(classe, typeLu, propLue).contains(valLue))
+							structure.ajouterVal(classe, typeLu, propLue, valLue);
+					String valdefLue = structureLue.getValeurParDefaut(classe, typeLu, propLue);
+					String valdef = structure.getValeurParDefaut(classe, typeLu, propLue);
+					if (!valdefLue.isEmpty()&&!valdefLue.equals(valdef)) {
+						structure.modifierValParDefaut(classe, typeLu, propLue, valdefLue);
+					}
+				}
+			}
+		}
+		fireMessage(new StructureEvent(this, TypeModifStructure.FUSION_TYPE, Unite.class, "", "", ""));
+	}
+	public void ecrireStructureJava(ObjectOutputStream oos) throws IOException {
+		structure.ecrireJava(oos);
+	}
+	public Structure lireStructureJava(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+		return Structure.lireJava(ois);
+	}
+	public void lireTexte(BufferedReader text) throws IOException {
+		String parag;
+		String newtexte = "";
+		ArrayList<Integer> newfinParag = new ArrayList<Integer>();
+		while ((parag = text.readLine())!=null) {
+			newtexte += parag;
+			newfinParag.add(newtexte.length());
+		}
+		texte = newtexte;
+		finParagraphes = newfinParag;
+		fireMessage(new Message(this, TypeMessage.NEW_CORPUS));
+	}
+	public void newCorpusLu() {
+		fireMessage(new Message(this, TypeMessage.NEW_CORPUS));
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/donnees/Corpus.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/donnees/Structure.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/donnees/Structure.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/donnees/Structure.java	(revision 481)
@@ -0,0 +1,312 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.donnees;
+
+import java.io.*;
+import java.util.*;
+import visuAnalec.elements.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class Structure implements Serializable {
+  public final static String FORME = "#forme#";
+  private HashMap<Class<? extends Element>, HashSet<String>> types =
+          new HashMap<Class<? extends Element>, HashSet<String>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashSet<String>>> nomsProps =
+          new HashMap<Class<? extends Element>, HashMap<String, HashSet<String>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashSet<String>>>> valeursProps =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashSet<String>>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, String>>> valeursParDefaut =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, String>>>();
+
+  @SuppressWarnings("unchecked")
+  public Structure() {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      types.put(classe, new HashSet<String>());
+      nomsProps.put(classe, new HashMap<String, HashSet<String>>());
+      valeursProps.put(classe, new HashMap<String, HashMap<String, HashSet<String>>>());
+      valeursParDefaut.put(classe, new HashMap<String, HashMap<String, String>>());
+    }
+  }
+  
+  public HashSet<String> getSchemas() {
+	  return this.getTypes(Schema.class);
+  }
+  
+  public HashSet<String> getRelations() {
+	  return this.getTypes(Relation.class);
+  }
+  
+  public HashSet<String> getUnites() {
+	  return this.getTypes(Unite.class);
+  }
+  
+  public HashSet<String> getSchemaProperties(String schema_type) {
+	  return getNomsProps(Schema.class, schema_type);
+  }
+  
+  public HashSet<String> getUniteProperties(String schema_type) {
+	  return getNomsProps(Unite.class, schema_type);
+  }
+  
+  public HashSet<String> getRelationProperties(String schema_type) {
+	  return getNomsProps(Relation.class, schema_type);
+  }
+
+  @Override
+  public String toString() {
+    String dump = "STRUCTURE :";
+    dump += "\n\tUNITES : ";
+    dump += "\n\t\tTYPES : ";
+    for (String type : types.get(Unite.class)) {
+      dump += type+"; ";
+    }
+    dump += "\n\t\tNOMSPROP : ";
+    for (String type : nomsProps.get(Unite.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : nomsProps.get(Unite.class).get(type)) {
+        dump += prop+"; ";
+      }
+    }
+    dump += "\n\t\tVALEURSPROP : ";
+    for (String type : valeursProps.get(Unite.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : valeursProps.get(Unite.class).get(type).keySet()) {
+        dump += "\n\t\t\t\t"+prop+" : ";
+        for (String val : valeursProps.get(Unite.class).get(type).get(prop)) {
+          dump += val+"; ";
+        }
+      }
+    }
+
+    dump += "\n\tRELATIONS : ";
+    dump += "\n\t\tTYPES : ";
+    for (String type : types.get(Relation.class)) {
+      dump += type+"; ";
+    }
+    dump += "\n\t\tNOMSPROP : ";
+    for (String type : nomsProps.get(Relation.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : nomsProps.get(Relation.class).get(type)) {
+        dump += prop+"; ";
+      }
+    }
+    dump += "\n\t\tVALEURSPROP : ";
+    for (String type : valeursProps.get(Relation.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : valeursProps.get(Relation.class).get(type).keySet()) {
+        dump += "\n\t\t\t\t"+prop+" : ";
+        for (String val : valeursProps.get(Relation.class).get(type).get(prop)) {
+          dump += val+"; ";
+        }
+      }
+    }
+
+    dump += "\n\tSCHEMAS : ";
+    dump += "\n\t\tTYPES : ";
+    for (String type : types.get(Schema.class)) {
+      dump += type+"; ";
+    }
+    dump += "\n\t\tNOMSPROP : ";
+    for (String type : nomsProps.get(Schema.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : nomsProps.get(Schema.class).get(type)) {
+        dump += prop+"; ";
+      }
+    }
+    dump += "\n\t\tVALEURSPROP : ";
+    for (String type : valeursProps.get(Schema.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : valeursProps.get(Schema.class).get(type).keySet()) {
+        dump += "\n\t\t\t\t"+prop+" : ";
+        for (String val : valeursProps.get(Schema.class).get(type).get(prop)) {
+          dump += val+"; ";
+        }
+      }
+    }
+
+
+    return dump;
+  }
+
+  public HashSet<String> getNomsProps(Class<? extends Element> classe, String type) {
+    if (nomsProps.get(classe).containsKey(type)) {
+      return nomsProps.get(classe).get(type);
+    }
+    return new HashSet<String>();
+  }
+
+  public HashSet<String> getValeursProp(Class<? extends Element> classe, String type, String prop) {
+    if (valeursProps.get(classe).containsKey(type)&&valeursProps.get(classe).get(type).containsKey(prop)) {
+      return (valeursProps.get(classe).get(type).get(prop));
+    }
+    return new HashSet<String>();
+  }
+
+  public String getValeurParDefaut(Class<? extends Element> classe, String type, String prop) {
+    if (valeursParDefaut.get(classe).containsKey(type)&&valeursParDefaut.get(classe).get(type).containsKey(prop)) {
+      return (valeursParDefaut.get(classe).get(type).get(prop));
+    }
+    return "";
+  }
+
+  public HashSet<String> getTypes(Class<? extends Element> classe) {
+    return (types.get(classe));
+  }
+
+  public boolean isVide() {
+    for (Class classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      if (!types.get(classe).isEmpty()) return false;
+    }
+    return true;
+  }
+
+  void clear() {
+    for (Class classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      types.get(classe).clear();
+      nomsProps.get(classe).clear();
+      valeursProps.get(classe).clear();
+      valeursParDefaut.get(classe).clear();
+    }
+  }
+
+  public void ajouterVal(Class<? extends Element> classe, String type, String prop, String val) {
+    valeursProps.get(classe).get(type).get(prop).add(val);
+  }
+
+  void renommerVal(Class<? extends Element> classe, String type, String prop, String oldNom, String newNom) {
+    valeursProps.get(classe).get(type).get(prop).add(newNom);
+    valeursProps.get(classe).get(type).get(prop).remove(oldNom);
+    if (oldNom.equals(valeursParDefaut.get(classe).get(type).get(prop))) {
+      valeursParDefaut.get(classe).get(type).put(prop, newNom);
+    }
+  }
+
+  void supprimerVal(Class<? extends Element> classe, String type, String prop, String oldNom) {
+    valeursProps.get(classe).get(type).get(prop).remove(oldNom);
+    if (oldNom.equals(valeursParDefaut.get(classe).get(type).get(prop))) {
+      valeursParDefaut.get(classe).get(type).put(prop, "");
+    }
+  }
+
+  public void modifierValParDefaut(Class<? extends Element> classe, String type, String prop, String val) {
+    valeursParDefaut.get(classe).get(type).put(prop, val);
+  }
+
+  public void ajouterProp(Class<? extends Element> classe, String type, String prop) {
+    nomsProps.get(classe).get(type).add(prop);
+    valeursProps.get(classe).get(type).put(prop, new HashSet<String>());
+    valeursParDefaut.get(classe).get(type).put(prop, "");
+  }
+
+  void renommerProp(Class<? extends Element> classe, String type, String oldNom, String newNom) {
+    nomsProps.get(classe).get(type).add(newNom);
+    nomsProps.get(classe).get(type).remove(oldNom);
+    valeursProps.get(classe).get(type).put(newNom, valeursProps.get(classe).get(type).get(oldNom));
+    valeursProps.get(classe).get(type).remove(oldNom);
+    valeursParDefaut.get(classe).get(type).put(newNom, valeursParDefaut.get(classe).get(type).get(oldNom));
+    valeursParDefaut.get(classe).get(type).remove(oldNom);
+  }
+
+  void fusionnerProp(Class<? extends Element> classe, String type, String oldNom, String newNom) {
+    nomsProps.get(classe).get(type).remove(oldNom);
+    valeursProps.get(classe).get(type).get(newNom).addAll(valeursProps.get(classe).get(type).get(oldNom));
+    valeursProps.get(classe).get(type).remove(oldNom);
+    if (!valeursParDefaut.get(classe).get(type).get(oldNom).isEmpty()) {
+      valeursParDefaut.get(classe).get(type).put(newNom, valeursParDefaut.get(classe).get(type).get(oldNom));
+    }
+    valeursParDefaut.get(classe).get(type).remove(oldNom);
+  }
+
+  void supprimerProp(Class<? extends Element> classe, String type, String prop) {
+    nomsProps.get(classe).get(type).remove(prop);
+    valeursProps.get(classe).get(type).remove(prop);
+    valeursParDefaut.get(classe).get(type).remove(prop);
+  }
+
+  @SuppressWarnings("unchecked")
+  public void ajouterType(Class<? extends Element> classe, String type) {
+    types.get(classe).add(type);
+    nomsProps.get(classe).put(type, new HashSet<String>());
+    valeursProps.get(classe).put(type, new HashMap<String, HashSet<String>>());
+    valeursParDefaut.get(classe).put(type, new HashMap<String, String>());
+  }
+  // }
+
+  void renommerType(Class<? extends Element> classe, String oldType, String newType) {
+    types.get(classe).add(newType);
+    types.get(classe).remove(oldType);
+    nomsProps.get(classe).put(newType, nomsProps.get(classe).get(oldType));
+    nomsProps.get(classe).remove(oldType);
+    valeursProps.get(classe).put(newType, valeursProps.get(classe).get(oldType));
+    valeursProps.get(classe).remove(oldType);
+    valeursParDefaut.get(classe).put(newType, valeursParDefaut.get(classe).get(oldType));
+    valeursParDefaut.get(classe).remove(oldType);
+  }
+
+  void fusionnerType(Class<? extends Element> classe, String oldType, String newType) {
+    types.get(classe).remove(oldType);
+    for (String prop : nomsProps.get(classe).get(oldType)) {
+      if (!nomsProps.get(classe).get(newType).contains(prop))
+        ajouterProp(classe, newType, prop);
+      for (String val : valeursProps.get(classe).get(oldType).get(prop))
+        if (!valeursProps.get(classe).get(newType).get(prop).contains(val))
+          ajouterVal(classe, newType, prop, val);
+      String valdef1 = getValeurParDefaut(classe, oldType, prop);
+      String valdef = getValeurParDefaut(classe, newType, prop);
+      if (!valdef1.isEmpty()&&!valdef1.equals(valdef)) {
+        modifierValParDefaut(classe, newType, prop, valdef1);
+      }
+    }
+    nomsProps.get(classe).remove(oldType);
+    valeursProps.get(classe).remove(oldType);
+    valeursParDefaut.get(classe).remove(oldType);
+
+  }
+
+  void supprimerType(Class<? extends Element> classe, String type) {
+    types.get(classe).remove(type);
+    nomsProps.get(classe).remove(type);
+    valeursProps.get(classe).remove(type);
+    valeursParDefaut.get(classe).remove(type);
+  }
+
+  void majNewElement(Element element) { // appelé par corpus.addUniteLue, addRelationLue, addSchemaLu
+    String type = element.getType();
+    Class<? extends Element> classe = element.getClass();
+    if (!types.get(classe).contains(type)) {
+      ajouterType(classe, type);
+    }
+    HashMap<String, String> props = element.getProps();
+    for (String prop : props.keySet()) {
+      if (!nomsProps.get(classe).get(type).contains(prop)) {
+        ajouterProp(classe, type, prop);
+      }
+      String val = props.get(prop);
+      if (val!=null&&!val.isEmpty()&&!valeursProps.get(classe).get(type).get(prop).contains(val)) {
+        ajouterVal(classe, type, prop, val);
+      }
+    }
+  }
+
+ @SuppressWarnings("unchecked")
+   public static Structure lireJava(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+    Structure structure = new Structure();
+    structure.types = (HashMap<Class<? extends Element>, HashSet<String>>) ois.readObject();
+    structure.nomsProps = (HashMap<Class<? extends Element>, HashMap<String, HashSet<String>>>) ois.readObject();
+    structure.valeursProps = (HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashSet<String>>>>) ois.readObject();
+    structure.valeursParDefaut = (HashMap<Class<? extends Element>, HashMap<String, HashMap<String, String>>>) ois.readObject();
+    return structure;
+  }
+
+  public void ecrireJava(ObjectOutputStream oos) throws IOException {
+    oos.writeObject(types);
+    oos.writeObject(nomsProps);
+    oos.writeObject(valeursProps);
+    oos.writeObject(valeursParDefaut);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/donnees/Structure.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/elements/Relation.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/elements/Relation.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/elements/Relation.java	(revision 481)
@@ -0,0 +1,64 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.elements;
+
+import java.util.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class Relation extends Element {
+  private Element elt1, elt2;
+  public Relation() {
+    super();
+  }
+  public Relation(String type, Element elt1, Element elt2) {
+    super(type);
+    setElt1(elt1);
+    setElt2(elt2);
+  }
+  public Element getElt1() {
+    return elt1;
+  }
+  public void setElt1(Element elt) {
+    elt1 = elt;
+  }
+  public Element getElt2() {
+    return elt2;
+  }
+  public void setElt2(Element elt) {
+    elt2 = elt;
+  }
+  @Override
+  public Element getElementSuivant(Jalon jalon) {
+    switch (jalon.origine) {
+      case ELT_2:
+        if (elt2.getClass()==jalon.classe&&elt2.getType().equals(jalon.type))
+          return elt2;
+        return null;
+      case ELT_1:
+        if (elt1.getClass()==jalon.classe&&elt1.getType().equals(jalon.type))
+          return elt1;
+        return null;
+      default:
+        return super.getElementSuivant(jalon);
+    }
+  }
+  protected HashSet<Unite> getUnitesSousjacentesNonTriees() {
+    HashSet<Unite> units = elt1.getUnitesSousjacentesNonTriees();
+    units.addAll(elt2.getUnitesSousjacentesNonTriees());
+    return units;
+  }
+//  boolean contientSchemaSousJacent(Schema sch) {
+//    return elt1.contientSchemaSousJacent(sch)||elt2.contientSchemaSousJacent(sch);
+//  }
+  public boolean coincide(Element elt) {
+    if (elt.getClass()!=Relation.class) return false;
+    Relation rel = (Relation) elt;
+    return getType().equals(rel.getType())&&elt1.coincide(rel.elt1)&&elt2.coincide(rel.elt2);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/elements/Relation.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/elements/Schema.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/elements/Schema.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/elements/Schema.java	(revision 481)
@@ -0,0 +1,83 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.elements;
+
+import java.util.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class Schema extends Element {
+  private HashSet<Element> contenu = new HashSet<Element>();
+  public Schema() {
+    super();
+  }
+  public Schema(String type) {
+    super(type);
+  }
+  public boolean ajouter(Element elt) {
+    // retourne false ssi pb de recursivité
+    if (elt==null) return true;
+    // à remplacer lors d'un chgt de version modifiant la signature de la classe
+// Element par :if (elt.contientSchemaSousJacent(this)) return false;
+    if (contientSchemaSousJacent(elt, this)) return false;
+    contenu.add(elt);
+    return true;
+  }
+  public boolean oter(Element elt) {
+    return contenu.remove(elt);
+  }
+  public HashSet<Element> getContenu() {
+    return contenu;
+  }
+  public boolean contient(Element elt) {
+    return contenu.contains(elt);
+  }
+  protected HashSet<Unite> getUnitesSousjacentesNonTriees() {
+    HashSet<Unite> units = new HashSet<Unite>();
+    for (Element elt : contenu) {
+      units.addAll(elt.getUnitesSousjacentesNonTriees());
+    }
+    return units;
+  }
+//  boolean contientSchemaSousJacent(Schema sch) {
+//    if (coincide(sch)) return true;
+//    for (Element elt : contenu) if (elt.contientSchemaSousJacent(sch))
+//        return true;
+//    return false;
+//  }
+  private static boolean contientSchemaSousJacent(Element elt, Schema sch) {
+    // Solution provisoire en attendant le chgt de version modifiant la signature
+    // de la classe Element
+    if (elt.getClass()==Unite.class) return false;
+    if (elt.getClass()==Relation.class) {
+      Relation rel = (Relation) elt;
+      return contientSchemaSousJacent(rel.getElt1(), sch)
+              ||contientSchemaSousJacent(rel.getElt2(), sch);
+    }
+    if (elt.getClass()==Schema.class) {
+      Schema sch1 = (Schema) elt;
+      if (sch1.coincide(sch)) return true;
+      for (Element elt1 : sch1.contenu) if (contientSchemaSousJacent(elt1, sch))
+          return true;
+      return false;
+    }
+    throw new IllegalArgumentException("Element de classe non identifiée");
+  }
+  public boolean coincide(Element elt) {
+    if (elt.getClass()!=Schema.class) return false;
+    Schema sch = (Schema) elt;
+    if (!getType().equals(sch.getType())) return false;
+    if (contenu.size()!=sch.getContenu().size()) return false;
+    Element[] contenu1 = contenu.toArray(new Element[0]);
+    Arrays.sort(contenu1);
+    Element[] contenu2 = sch.getContenu().toArray(new Element[0]);
+    Arrays.sort(contenu2);
+    for (int i = 0; i<contenu1.length; i++)
+      if (!contenu1[i].coincide(contenu2[i])) return false;
+    return true;
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/elements/Schema.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/elements/Unite.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/elements/Unite.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/elements/Unite.java	(revision 481)
@@ -0,0 +1,70 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.elements;
+
+import java.util.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class Unite extends Element implements Comparable {
+  private int deb;
+  private int fin;
+  public Unite() {
+    super();
+  }
+  public Unite(String type, int deb, int fin) {
+    super(type);
+    this.deb = deb;
+    this.fin = fin;
+  }
+  public int getDeb() {
+    return deb;
+  }
+  public void setDeb(int deb) {
+    this.deb = deb;
+  }
+  public int getFin() {
+    return fin;
+  }
+  public void setFin(int fin) {
+    this.fin = fin;
+  }
+//  boolean contientSchemaSousJacent(Schema sch) {
+//    return false;
+//  }
+  public boolean coincide(Element elt) {
+    if (elt.getClass()!=Unite.class) return false;
+    Unite unit = (Unite) elt;
+    return getType().equals(unit.getType())&&deb==unit.deb&&fin==unit.fin;
+  }
+  public int compareTo(Unite unit2) {
+    int comp = Integer.signum(deb-unit2.deb);
+    if (comp==0) {
+      comp = -Integer.signum(fin-unit2.fin);
+      if (comp==0) {
+        comp = getType().compareTo(unit2.getType());
+        if (comp==0) {
+          comp = Integer.signum(hashCode()-unit2.hashCode());
+        }
+      }
+    }
+    return comp;
+  }
+  protected HashSet<Unite> getUnitesSousjacentesNonTriees() {
+    HashSet<Unite> units = new HashSet<Unite>();
+    units.add(this);
+    return units;
+  }
+  @Override
+  public Unite getUnite0() {
+    return this;
+  }
+  @Override
+  public Unite[] getUnitesSousjacentes() {
+    return new Unite[]{this};
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/elements/Unite.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/elements/Element.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/elements/Element.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/elements/Element.java	(revision 481)
@@ -0,0 +1,193 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.elements;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.ArrayList;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public abstract class Element implements Serializable, Comparable {
+  private String type;
+  private HashMap<String, String> props = new HashMap<String, String>();
+  private HashMap<String, ArrayList<Relation>> relationsEntrantes = new HashMap<String, ArrayList<Relation>>();
+  private HashMap<String, ArrayList<Relation>> relationsSortantes = new HashMap<String, ArrayList<Relation>>();
+  private HashMap<String, ArrayList<Schema>> schemasContenants = new HashMap<String, ArrayList<Schema>>();
+  Element() {
+  }
+  Element(String type) {
+    this.type = type;
+  }
+  @Override
+  public String toString() {
+    String dump = "ELEMENT "+type;
+    dump += "\n\tPROPS : ";
+    for (String prop : props.keySet()) {
+      dump += "\n\t\t"+prop+" : "+props.get(prop);
+    }
+    dump += "\n\tRELATIONS ENTRANTES : ";
+    for (String typ : relationsEntrantes.keySet()) {
+      dump += "\n\t\t"+typ+" : ";
+      for (Relation rel : relationsEntrantes.get(typ)) {
+        dump += rel.getElt1().getType();
+      }
+    }
+    dump += "\n\tRELATIONS SORTANTES : ";
+    for (String typ : relationsSortantes.keySet()) {
+      dump += "\n\t\t"+typ+" : ";
+      for (Relation rel : relationsSortantes.get(typ)) {
+        dump += rel.getElt2().getType();
+      }
+    }
+    return dump;
+  }
+  public String getType() {
+    return type;
+  }
+  public void setType(String type) {
+    this.type = type;
+  }
+  public HashMap<String, String> getProps() {
+    return props;
+  }
+  public String getProp(String prop) {
+    if (props.get(prop)==null) {
+      return "";
+    }
+    return props.get(prop);
+  }
+  public void putProp(String prop, String valeur) {
+    props.put(prop, valeur);
+  }
+  public void supProp(String prop) {
+    props.remove(prop);
+  }
+  public void addRelationEntrante(Relation rel) {
+    if (!relationsEntrantes.containsKey(rel.getType())) {
+      relationsEntrantes.put(rel.getType(), new ArrayList<Relation>());
+    }
+    relationsEntrantes.get(rel.getType()).add(rel);
+  }
+  public void oteRelationEntrante(Relation rel) {
+    relationsEntrantes.get(rel.getType()).remove(rel);
+  }
+  public void addRelationSortante(Relation rel) {
+    if (!relationsSortantes.containsKey(rel.getType())) {
+      relationsSortantes.put(rel.getType(), new ArrayList<Relation>());
+    }
+    relationsSortantes.get(rel.getType()).add(rel);
+  }
+  public void oteRelationSortante(Relation rel) {
+    relationsSortantes.get(rel.getType()).remove(rel);
+  }
+  public void addSchemaContenant(Schema sch) {
+    if (!schemasContenants.containsKey(sch.getType())) {
+      schemasContenants.put(sch.getType(), new ArrayList<Schema>());
+    }
+    schemasContenants.get(sch.getType()).add(sch);
+  }
+  public void oteSchemaContenant(Schema sch) {
+    schemasContenants.get(sch.getType()).remove(sch);
+  }
+  public ArrayList<Relation> getRelations() {
+    ArrayList<Relation> rels = new ArrayList<Relation>();
+    for (String typerel : relationsEntrantes.keySet()) {
+      rels.addAll(relationsEntrantes.get(typerel));
+    }
+    for (String typerel : relationsSortantes.keySet()) {
+      rels.addAll(relationsSortantes.get(typerel));
+    }
+    return rels;
+  }
+  public ArrayList<Schema> getSchemas() {
+    ArrayList<Schema> schs = new ArrayList<Schema>();
+    for (String typesch : schemasContenants.keySet()) {
+      schs.addAll(schemasContenants.get(typesch));
+    }
+    return schs;
+  }
+  public Element getElementSuivant(Jalon jalon) {
+    switch (jalon.origine) {
+      case ELT_0:
+        return this;
+      case REL_SORTANTE:
+        if (!relationsSortantes.containsKey(jalon.type)||relationsSortantes.get(jalon.type).isEmpty()) {
+          return null;
+        }
+        return relationsSortantes.get(jalon.type).get(0);
+      case REL_ENTRANTE:
+        if (!relationsEntrantes.containsKey(jalon.type)||relationsEntrantes.get(jalon.type).isEmpty()) {
+          return null;
+        }
+        return relationsEntrantes.get(jalon.type).get(0);
+      case SCH_CONTENANT:
+        if (!schemasContenants.containsKey(jalon.type)||schemasContenants.get(jalon.type).isEmpty()) {
+          return null;
+        }
+        return schemasContenants.get(jalon.type).get(0);
+      default:  // les cas ELT_1 et ELT_2 sont traités par la classe Relation
+        throw new UnsupportedOperationException("Pas encore implémenté");
+    }
+  }
+  protected abstract HashSet<Unite> getUnitesSousjacentesNonTriees();
+  public Unite[] getUnitesSousjacentes() { // triées
+    Unite[] units = getUnitesSousjacentesNonTriees().toArray(new Unite[0]);
+    Arrays.sort(units);
+    return units;
+  }
+  public Unite getUnite0() {
+    Unite[] units = getUnitesSousjacentes();
+    if (units.length==0) return null;
+    return units[0];
+  }
+  public static Unite[] getUnites0(Element[] elts) {
+    Unite[] units = new Unite[elts.length];
+    for (int i = 0; i<elts.length; i++) units[i] = elts[i].getUnite0();
+    return units;
+  }
+  public static Unite[] getUnitesSousjacentes(Element[] elts) { // triées : est-ce nécessaire ??
+    ArrayList<Unite> lunits = new ArrayList<Unite>();
+    for (Element elt : elts)
+      lunits.addAll(elt.getUnitesSousjacentesNonTriees());
+    Unite[] units = lunits.toArray(new Unite[0]);
+    Arrays.sort(units);
+    return units;
+  }
+  public static Element trouverElementParUniteSousjacente(Element[] elements, Unite unite) { // prend le premier
+    for (Element elt : elements) {
+      int i = Arrays.binarySearch(elt.getUnitesSousjacentes(), unite);
+      if (i>=0) return elt;
+    }
+    return null;
+  }
+  public static ArrayList<Element> trouverElementsParUniteSousjacente(Element[] elements, Unite unite) {
+    ArrayList<Element> elts = new ArrayList<Element>();
+    for (Element elt : elements) {
+      int i = Arrays.binarySearch(elt.getUnitesSousjacentes(), unite);
+      if (i>=0) elts.add(elt);
+    }
+    return elts;
+  }
+  public int compareTo(Object obj) {
+    if (obj.getClass().getSuperclass()!=Element.class) {
+      throw new ClassCastException("Comparaison impossible : "+obj.toString()+" n'est pas une instance d'Elément");
+    }
+    Unite[] unites1 = getUnitesSousjacentes();
+    Unite[] unites2 = ((Element) obj).getUnitesSousjacentes();
+    int comp;
+    for (int i = 0; i<unites1.length; i++) {
+      if (i==unites2.length) return 1;
+      if ((comp = unites1[i].compareTo(unites2[i]))!=0) return comp;
+    }
+    if (unites1.length<unites2.length) return -1;
+    return Integer.signum(hashCode()-obj.hashCode());
+  }
+  abstract public boolean coincide(Element elt);
+//  abstract boolean contientSchemaSousJacent(Schema sch);
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/elements/Element.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTableur.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTableur.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTableur.java	(revision 481)
@@ -0,0 +1,165 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.TableModel;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.PanneauOccurrences;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class FichiersTableur {
+  public static void importerExcel(Corpus corpus) {
+    BufferedReader enonces = null;
+    BufferedReader annot = null;
+    File fichierCorpus;
+    File fichierAnnot;
+    if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix du fichier des énoncés", Fichiers.TypeFichier.TABLEUR_ENONCES))==null)
+      return;
+    if ((fichierAnnot = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix du fichier des annotations", Fichiers.TypeFichier.TABLEUR_ANNOT))==null)
+      return;
+    try {
+      enonces = new BufferedReader(new InputStreamReader(new FileInputStream(fichierCorpus), "ISO-8859-1"));
+      annot = new BufferedReader(new InputStreamReader(new FileInputStream(fichierAnnot), "ISO-8859-1"));
+      ExcelParser ep = new ExcelParser(corpus);
+      corpus.setTexte(ep.parserEnonces(enonces, 2));
+      ep.parserAnnot(annot, 2, "<*", "*>");
+      corpus.newCorpusLu();
+    } catch (IOException ex) {
+      corpus.fermer();
+      GMessages.impossibiliteAction("Erreur de lecture de fichier : \n"
+              +ex.getLocalizedMessage());
+      return;
+    } finally {
+      try {
+        if (enonces!=null) enonces.close();
+        if (annot!=null) annot.close();
+      } catch (IOException ex) {
+        GMessages.impossibiliteAction("Erreur de fermeture du fichier lu : \n"
+                +ex.getLocalizedMessage());
+      }
+    }
+  }
+  public static void exporterTable(TableModel donnees) {
+    PrintWriter ecrittableur = null;
+    File fichierStats;
+    GCodage codage = new GCodage();
+    if ((fichierStats = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier ?", Fichiers.TypeFichier.TABLEUR_STATS,
+            codage.getContenant()))==null) return;
+    String code = codage.getCode();
+    try {
+      ecrittableur = new PrintWriter(fichierStats, code);
+      ecrireTable(ecrittableur, donnees);
+    } catch (FileNotFoundException ex) {
+      GMessages.impossibiliteAction("Erreur d'écriture de fichier : \n"
+              +"Codage de caractères non pris en charge : "+code);
+    } catch (UnsupportedEncodingException ex) {
+    } finally {
+      if (ecrittableur!=null) ecrittableur.close();
+    }
+  }
+  private static void ecrireTable(PrintWriter ecrittableur, TableModel donnees) {
+    int nbcol = donnees.getColumnCount();
+    for (int j = 0; j<nbcol; j++) {
+      ecrittableur.print(donnees.getColumnName(j));
+      ecrittableur.print(j==nbcol-1 ? '\n' : '\t');
+    }
+    int nblig = donnees.getRowCount();
+    for (int i = 0; i<nblig; i++) for (int j = 0; j<nbcol; j++) {
+        ecrittableur.print(donnees.getValueAt(i, j));
+        ecrittableur.print(j==nbcol-1 ? '\n' : '\t');
+      }
+
+  }
+
+  static class ExcelParser {
+    Corpus corpus;
+    HashMap<String, Unite> enonces;
+    ExcelParser(Corpus corpus) {
+      this.corpus = corpus;
+      this.enonces = new HashMap<String, Unite>();
+    }
+    private String parserEnonces(BufferedReader lEnonces, int nbPropEnonces) throws IOException {
+      String texte = "";
+      String lEnonce;
+      int nbcar = 0;
+      while ((lEnonce = lEnonces.readLine())!=null) {
+        if (lEnonce.trim().isEmpty()) continue;
+        String[] chs = lEnonce.split("\t");
+        if (chs.length!=2+nbPropEnonces) {
+          throw new IOException("Format incorrect de fichier d'énoncés ligne : \n"+lEnonce);
+        }
+        String idEnonce = chs[0].trim();
+        if (enonces.containsKey(idEnonce)) {
+          throw new IOException("Identifant d'énoncés non unique  : "+idEnonce);
+        }
+        String texteEnonce = chs[1].trim();
+        Unite enonce = new Unite("Enoncé", nbcar, nbcar += texteEnonce.length());
+        for (int i = 0; i<nbPropEnonces; i++) {
+          enonce.putProp("Propriété "+i, chs[i+2].trim());
+        }
+        enonces.put(idEnonce, enonce);
+        enonce.putProp("id", idEnonce);
+        corpus.addUniteLue(enonce);
+        corpus.addFinParagraphe(nbcar);
+        texte += texteEnonce;
+      }
+      return texte;
+    }
+    private void parserAnnot(BufferedReader lAnnots, int nbPropAnnots, String bGauche, String bDroite)
+            throws IOException {
+      String lAnnot;
+      while ((lAnnot = lAnnots.readLine())!=null) {
+        if (lAnnot.trim().isEmpty()) continue;
+        String[] chs = lAnnot.split("\t", -1);
+        if (chs.length!=2+nbPropAnnots) {
+          throw new IOException("Format incorrect de fichier d'énoncés ligne : \n"+lAnnot);
+        }
+        String idEnonce = chs[0].trim();
+        String texteEnonceAnnot = chs[1].trim();
+        if (!enonces.containsKey(idEnonce)) {
+          throw new IOException("Identifiant d'énoncés non trouvé : \n"+idEnonce);
+        }
+        int deb = texteEnonceAnnot.indexOf(bGauche);
+        if (texteEnonceAnnot.substring(deb+bGauche.length()).indexOf(bGauche)>=0) {
+          throw new IOException("Plusieurs bornes gauches dans : \n"+texteEnonceAnnot);
+        }
+        String texteEnonce = texteEnonceAnnot.replace(bGauche, "");
+        int fin = texteEnonce.indexOf(bDroite);
+        if (texteEnonce.substring(fin+bDroite.length()).indexOf(bDroite)>=0) {
+          throw new IOException("Plusieurs bornes droites dans : \n"+texteEnonceAnnot);
+        }
+        if (fin<=deb) {
+          throw new IOException("Borne droite précédant la borne gauche dans : \n"+texteEnonceAnnot);
+        }
+        texteEnonce = texteEnonce.replace(bDroite, "");
+        Unite enonce = enonces.get(idEnonce);
+        if (!texteEnonce.equals(corpus.getTexte().substring(enonce.getDeb(), enonce.getFin()))) {
+          throw new IOException("Erreur d'énoncé identifié par "+idEnonce+" : \n"+texteEnonceAnnot
+                  +"Enoncé dans le corpus : "+corpus.getTexte().substring(enonce.getDeb(), enonce.getFin()));
+        }
+        Unite marqueur = new Unite("Marqueur", enonce.getDeb()+deb, enonce.getDeb()+fin);
+        for (int i = 0; i<nbPropAnnots; i++) {
+          marqueur.putProp("Propriété "+i, chs[i+2].trim());
+        }
+        corpus.addUniteLue(marqueur);
+        Relation rel = new Relation("Inclusion", marqueur, enonce);
+        corpus.addRelationLue(rel);
+
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTableur.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersJava.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersJava.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersJava.java	(revision 481)
@@ -0,0 +1,453 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+import java.io.*;
+import javax.swing.*;
+import visuAnalec.donnees.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+import java.util.*;
+import visuAnalec.vue.*;
+import java.beans.PersistenceDelegate;
+import java.beans.XMLEncoder;
+import java.beans.XMLDecoder;
+/**
+ *
+ * @author Bernard
+ */
+public abstract class FichiersJava {
+  public static void ouvrirCorpusVue(Corpus corpus, Vue vue, String nomfichier) {
+    File fichierCorpus;
+    if (nomfichier.isEmpty()) {
+      if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR,
+              "Choix du document", Fichiers.TypeFichier.DOC_ANALEC))==null) return;
+    } else {
+      if ((fichierCorpus = Fichiers.trouverFichier(Fichiers.TypeFichier.DOC_ANALEC, nomfichier))==null) {
+        JOptionPane.showMessageDialog(null, "Fichier "+nomfichier+" inexistant dans le répertoire "
+                +Fichiers.getRepertoireCourant(Fichiers.TypeFichier.DOC_ANALEC).getPath(), "Erreur de lecture de fichier",
+                JOptionPane.ERROR_MESSAGE);
+        return;
+      }
+    }
+    if(!ouvrirCorpus(corpus, fichierCorpus, false)) return;
+    File fichierVue = Fichiers.trouverFichier(Fichiers.TypeFichier.VUE, fichierCorpus);
+    if (fichierVue==null) return;
+    ouvrirVue(vue, fichierVue);
+  }
+  
+  
+
+public static boolean ouvrirCorpus(Corpus corpus, File fichierCorpus, boolean batch) {
+     ObjectInputStream ois = null;
+     try {
+      ois = new ObjectInputStream(new FileInputStream(fichierCorpus));
+      corpus.lireJava(ois, batch);
+    } catch (ClassNotFoundException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le document "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (InvalidClassException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le document "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (ClassCastException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le document "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (IOException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } finally {
+      try {
+        if (ois!=null) ois.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+        return false;
+      }
+      return true;
+    }
+}
+  public static boolean ouvrirStructure(Corpus corpus) {
+    File fichierStructure;
+    if ((fichierStructure = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix de la structure", Fichiers.TypeFichier.STRUCTURE))==null) return false;
+    ObjectInputStream ois = null;
+    try {
+      ois = new ObjectInputStream(new FileInputStream(fichierStructure));
+      Structure structureLue = corpus.lireStructureJava(ois);
+      corpus.fusionnerStructureLue(structureLue);
+      corpus.newCorpusLu();
+    } catch (ClassNotFoundException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire la structure "+fichierStructure.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ecs", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (InvalidClassException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire la structure "+fichierStructure.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ecs", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (ClassCastException ex) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire la structure "+fichierStructure.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ecs", JOptionPane.ERROR_MESSAGE);
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } finally {
+      try {
+        if (ois!=null) ois.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+      }
+    }
+    return true;
+  }
+
+  public static boolean ouvrirVue(Vue vue, File fichierVue) {
+    ObjectInputStream ois = null;
+    try {
+      ois = new ObjectInputStream(new FileInputStream(fichierVue));
+      if (!vue.lireJava(ois)) {
+        JOptionPane.showMessageDialog(null, "Impossible d'utiliser la vue "+fichierVue.getName()
+                +" : vue incompatible avec le document courant", "Erreur de lecture de fichier .ecv", JOptionPane.ERROR_MESSAGE);
+        if (ois!=null) ois.close();
+        return false;
+      }
+    } catch (InvalidClassException ex) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire la vue "+fichierVue.getName()
+              +" : versions d'Analec incompatibles ", "Erreur d'ouverture de fichier .ecv", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (ClassNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire la vue "+fichierVue.getName()
+              +" : versions d'Analec incompatibles ", "Erreur d'ouverture de fichier .ecv", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (ClassCastException ex) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire la vue "+fichierVue.getName()
+              +" : versions d'Analec incompatibles ", "Erreur d'ouverture de fichier .ecv", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } finally {
+      try {
+        if (ois!=null) ois.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+      }
+    }
+    return true;
+  }
+
+  public static boolean ouvrirVue(Vue vue) {
+    File fichierVue;
+    if ((fichierVue = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix de la vue", Fichiers.TypeFichier.VUE))==null) return false;
+    return ouvrirVue(vue, fichierVue);
+  }
+
+  public static void fusionnerAnnot(Corpus corpus) {
+    File fichierCorpus;
+    if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix du fichier à fusionner", Fichiers.TypeFichier.DOC_ANALEC))==null)
+      return;
+    ObjectInputStream ois = null;
+    try {
+      ois = new ObjectInputStream(new FileInputStream(fichierCorpus));
+      corpus.fusionnerAnnotJava(ois);
+    } catch (ClassNotFoundException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (ClassCastException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (InvalidClassException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (IOException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      try {
+        if (ois!=null) ois.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+      }
+    }
+
+  }
+
+  public static void concatenerDocuments(Corpus corpus) {
+    File fichierCorpus;
+    if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix du fichier à concaténer", Fichiers.TypeFichier.DOC_ANALEC))==null)
+      return;
+    concatener(fichierCorpus, corpus);
+    corpus.newCorpusLu();
+  }
+
+  public static void concatenerCorpus(final Corpus corpus) {
+    File rep;
+    if ((rep = Fichiers.choisirRepertoire("Choix du répertoire à concaténer"))
+            ==null) return;
+    final File[] fics = Fichiers.listerFichiers(rep, Fichiers.TypeFichier.DOC_ANALEC);
+    final GMessages.GProgression progression =
+            new GMessages.GProgression(fics.length, "Concaténation", "fichiers");
+    Thread traitement = new Thread() {
+      @Override
+      public void run() {
+        for (int i = 0; i<fics.length; i++) {
+          if (progression.isCanceled()) break;
+          progression.setNbTraites(i+1);
+          concatener(fics[i], corpus);
+        }
+        corpus.newCorpusLu();
+      }
+    };
+    traitement.start();
+  }
+
+  public static void extraireTypeCorpus(final String type, final Corpus corpus) {
+    File rep;
+    if ((rep = Fichiers.choisirRepertoire("Choix du répertoire à traiter"))
+            ==null) return;
+   final  File[] fics = Fichiers.listerFichiers(rep, Fichiers.TypeFichier.DOC_ANALEC);
+    final GMessages.GProgression progression =
+            new GMessages.GProgression(fics.length, "Extraction", "fichiers");
+  Thread traitement = new Thread() {
+      @Override
+      public void run() {
+        for (int i = 0; i<fics.length; i++) {
+          if (progression.isCanceled()) break;
+          progression.setNbTraites(i+1);
+      extraireType(fics[i], Fichiers.extraireNom(fics[i]), type, corpus);        
+        }
+        corpus.newCorpusLu();
+      }
+    };
+    traitement.start();
+  }
+
+  private static void extraireType(File fichierCorpus, String nomDocument,
+          String type, Corpus corpus) {
+    ObjectInputStream ois = null;
+    try {
+      ois = new ObjectInputStream(new FileInputStream(fichierCorpus));
+      corpus.extraireEtConcatenerCorpusJava(ois, nomDocument, type);
+    } catch (ClassNotFoundException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (ClassCastException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (InvalidClassException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (IOException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      try {
+        if (ois!=null) ois.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+      }
+    }
+  }
+
+  public static void concatener(File fichierCorpus, Corpus corpus) {
+    ObjectInputStream ois = null;
+    try {
+      ois = new ObjectInputStream(new FileInputStream(fichierCorpus));
+      corpus.concatenerCorpusJava(ois);
+    } catch (ClassNotFoundException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (ClassCastException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (InvalidClassException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (IOException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      try {
+        if (ois!=null) ois.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+      }
+    }
+  }
+
+  public static boolean enregistrerCorpus(Corpus corpus, File fichier) {
+    if (fichier!=null) return ecrireCorpus(corpus, fichier);
+    return false;
+  }
+
+  public static boolean enregistrerCorpusSous(Corpus corpus) {
+    File fichier;
+    if ((fichier = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier corpus", Fichiers.TypeFichier.DOC_ANALEC))==null) return false;
+    return ecrireCorpus(corpus, fichier);
+  }
+
+	public static boolean enregistrerStructure(Corpus corpus) {
+		File fichier;
+		if ((fichier = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Nom du fichier structure", Fichiers.TypeFichier.STRUCTURE))==null) return false;
+		
+		return enregistrerStructure(corpus, fichier);
+	}
+
+	public static boolean enregistrerStructure(Corpus corpus, File fichier) {
+		ObjectOutputStream oos = null;
+		try {
+			oos = new ObjectOutputStream(new FileOutputStream(fichier));
+			corpus.ecrireStructureJava(oos);
+		} catch (IOException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			try {
+				if (oos!=null) oos.close();
+			} catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier écrit", JOptionPane.ERROR_MESSAGE);
+			}
+		}
+		return true;
+	}
+
+  private static boolean ecrireCorpus(Corpus corpus, File fichier) {
+    ObjectOutputStream oos = null;
+    try {
+      oos = new ObjectOutputStream(new FileOutputStream(fichier));
+      corpus.ecrireJava(oos);
+        return true;
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+         if (oos!=null) try {
+        oos.close();
+      } catch (IOException ex1) {
+      }
+     return false;
+    
+    }
+  }
+
+  public static boolean enregistrerVue(Vue vue) {
+    File fichier;
+    if ((fichier = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier vue", Fichiers.TypeFichier.VUE))==null) return false;
+    ObjectOutputStream oos = null;
+    try {
+      oos = new ObjectOutputStream(new FileOutputStream(fichier));
+      vue.ecrireJava(oos);
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } finally {
+      try {
+        if (oos!=null) oos.close();
+        return true;
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier écrit", JOptionPane.ERROR_MESSAGE);
+        return false;
+      }
+    }
+  }
+  /*permet d'ouvrir un procédure d'affichage du module des chaines de coréférence*/
+    public static HashMap<String,Object> ouvrirChaineVue() {
+    File fichierAffichage;
+    HashMap<String,Object> choix = null;
+      if ((fichierAffichage = Fichiers.choisirFichier(Commande.OUVRIR,
+              "Choix du document", Fichiers.TypeFichier.VUE_CHAINE))==null){ 
+          return null;
+      }
+    
+    if((choix=ouvrirChaine(fichierAffichage))==null){
+        return null;
+    }
+    return choix;
+  }
+    public static HashMap<String,Object> ouvrirChaine(File fichierAffichage) {
+     XMLDecoder ois = null;
+     HashMap<String,Object> choix =null;
+     try {
+         ois = new XMLDecoder(new FileInputStream(fichierAffichage));
+         choix = (HashMap<String,Object>) ois.readObject();
+    } catch (ClassCastException e) {
+      JOptionPane.showMessageDialog(null, "Impossible de lire le document "+fichierAffichage.getName()
+              +" : versions d'Analec incompatibles ",
+              "Erreur d'ouverture de fichier .eccv", JOptionPane.ERROR_MESSAGE);
+      return null;
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return null;
+    } finally {
+        if (ois!=null) ois.close();
+        
+    return choix;
+    }
+}
+    
+      @SuppressWarnings("unchecked")
+  public static HashMap<String,Object> lireJavaChaine(ObjectInputStream ois) throws IOException, ClassNotFoundException, ClassCastException {
+        HashMap<String,Object> choix = (HashMap<String,Object>) ois.readObject();
+        return choix;
+  }
+  
+    public static boolean enregistrerChaineSous(HashMap<String,Object> Choix) {
+    File fichier;
+    if ((fichier = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier des paramètres", Fichiers.TypeFichier.VUE_CHAINE))==null) return false;
+    return ecrireChaine(Choix, fichier);
+  }
+    
+    private static boolean ecrireChaine(HashMap<String,Object> Choix, File fichier) {
+    XMLEncoder oos = null;       
+    try {
+            // serialisation de l'objet
+            oos = new XMLEncoder(new FileOutputStream(fichier));
+            oos.writeObject(Choix);
+            oos.flush();
+            return true;
+        } finally {
+            // fermeture de l'encodeur
+            oos.close();
+            return false;
+        }
+    
+
+  }
+  
+  
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersJava.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTEI.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTEI.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTEI.java	(revision 481)
@@ -0,0 +1,953 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.awt.*;
+import java.io.*;
+import java.util.*;
+
+import javax.swing.*;
+import javax.xml.parsers.*;
+
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+import visuAnalec.util.GMessages.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public abstract class FichiersTEI {
+  public static void convertirCorpusTEI(final Corpus corpus) {
+    final File ficTEI;
+    final File repJava;
+    if ((ficTEI = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix du fichier corpus TEI", TypeFichier.TEI))==null)
+      return;
+    if ((repJava = Fichiers.choisirRepertoire("Choix du répertoire Java"))==null)
+      return;
+    if (!repJava.exists()) {
+      if (!GMessages.confirmationAction("Le répertoire spécifié n'existe pas."
+              +" Voulez-vous le créer ?")) return;
+      if (!repJava.mkdir()) {
+        GMessages.impossibiliteAction("Echec de la création du répertoire");
+        return;
+      }
+    }
+    convertir(ficTEI, repJava, corpus);
+  }
+  
+  public static boolean convertir(File ficTEI, File repJava, Corpus corpus) {
+    BufferedInputStream tei = null;
+    String nomTEI = Fichiers.extraireNom(ficTEI)+"-";
+    if (Fichiers.existeDebutFichier(repJava, TypeFichier.DOC_ANALEC, nomTEI))
+      if (!GMessages.confirmationAction("Attention! Certains fichiers du "
+              +"répertoire "+repJava.getName()
+              +" risquent d'être écrasés")) return false;
+    try {
+      tei = new BufferedInputStream(
+              new ProgressMonitorInputStream(
+              null, "Conversion du corpus TEI "+nomTEI,
+              new FileInputStream(ficTEI)));
+      SAXParserFactory pf = (SAXParserFactory) SAXParserFactory.newInstance();
+      SAXParser sp = pf.newSAXParser();
+      sp.parse(tei, new TEIHandler(corpus, repJava, nomTEI));
+    } catch (IOException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (ParserConfigurationException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (SAXException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } finally {
+      try {
+        if (tei!=null) tei.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
+      }
+    }
+    return true;
+  }
+
+  static class TEIHandler extends DefaultHandler {
+    File repJava;
+    String nomTEI;
+    Corpus corpus;
+    int noDoc;
+    String texte;
+    ArrayList<Integer> finParagraphes = new ArrayList<Integer>();
+    Balise etatCourant;
+    String typeCourant;
+    HashMap<String, Integer> ancres = new HashMap<String, Integer>();
+    HashMap<Unite, String[]> posUnites = new HashMap<Unite, String[]>();
+    HashMap<String, Element> idElements = new HashMap<String, Element>();
+    HashMap<Relation, String[]> eltsRelations = new HashMap<Relation, String[]>();
+    HashMap<Schema, String[]> eltsSchemas = new HashMap<Schema, String[]>();
+    HashMap<Element, String> propsElements = new HashMap<Element, String>();
+    HashMap<String, HashMap<String, String>> valsprops =
+            new HashMap<String, HashMap<String, String>>();
+    String idPropsEltCourant;
+    String champCourant;
+    String valCourant;
+
+    enum Balise {
+      TEICORPUS, TEIHEADER, TEIHEADER_CORPUS, TEI, TEXT, BODY, P, ANCHOR,
+      BACK, SPANGRP, SPAN, JOINGRP, JOIN, JOINGRP_REL, JOIN_REL,
+      JOINGRP_SCH, JOIN_SCH, FVLIB, FS, F, STRING, DEBUT_DOC, FIN_DOC,
+      AUTRE
+    };
+    static Balise balise(String nomBalise) {
+      try {
+        return Balise.valueOf(nomBalise.replaceAll("\\W", "").toUpperCase());
+      } catch (IllegalArgumentException e) {
+        return Balise.AUTRE;
+      }
+    }
+    TEIHandler(Corpus corpus, File repJava, String nomTEI) {
+      super();
+      this.corpus = corpus;
+      this.repJava = repJava;
+      this.nomTEI = nomTEI;
+    }
+    @Override
+    public void startDocument() {
+      noDoc = 0;
+      etatCourant = Balise.DEBUT_DOC;
+    }
+    @Override
+    public void endDocument() throws SAXNotSupportedException {
+      if (etatCourant!=Balise.FIN_DOC)
+        throw new SAXNotSupportedException("Fin de fichier inattendue");
+    }
+    @Override
+    public void startElement(String uri, String local, String nomBalise,
+            Attributes attributs) throws SAXException {
+      switch (balise(nomBalise)) {
+        case TEICORPUS:
+          if (etatCourant==Balise.DEBUT_DOC) etatCourant = Balise.TEICORPUS;
+          else
+            throw new SAXNotSupportedException("Balise <teiCorpus> mal placée");
+          break;
+        case TEIHEADER:
+          if (etatCourant==Balise.TEICORPUS)
+            etatCourant = Balise.TEIHEADER_CORPUS;
+          else if (etatCourant==Balise.TEI) etatCourant = Balise.TEIHEADER;
+          else
+            throw new SAXNotSupportedException("Balise <teiHeader> mal placée");
+
+          break;
+        case TEI:
+          if (etatCourant==Balise.TEICORPUS) {
+            noDoc++;
+            initCorpus();
+            etatCourant = Balise.TEI;
+          } else
+            throw new SAXNotSupportedException("Balise <tei> mal placée");
+          break;
+        case TEXT:
+          if (etatCourant==Balise.TEI) {
+            etatCourant = Balise.TEXT;
+          } else
+            throw new SAXNotSupportedException("Balise <text> mal placée");
+          break;
+        case BODY:
+          if (etatCourant==Balise.TEXT) {
+            etatCourant = Balise.BODY;
+          } else
+            throw new SAXNotSupportedException("Balise <body> mal placée");
+          break;
+        case P:
+          if (etatCourant==Balise.BODY) {
+            etatCourant = Balise.P;
+          } else
+            throw new SAXNotSupportedException("Balise <p> mal placée");
+          break;
+        case ANCHOR:
+          if ("AnalecDelimiter".equals(attributs.getValue("type"))) {
+            if (etatCourant==Balise.BODY||etatCourant==Balise.P) {
+              ancres.put(attributs.getValue("xml:id"), texte.length());
+            } else
+              throw new SAXNotSupportedException("Balise <anchor> de type "
+                      +"\"AnalecDelimiter\" mal placée");
+          }
+          break;
+        case BACK:
+          if (etatCourant==Balise.TEXT) {
+            etatCourant = Balise.BACK;
+          } else
+            throw new SAXNotSupportedException("Balise <back> mal placée");
+          break;
+        case SPANGRP:
+          if ("AnalecUnit".equals(attributs.getValue("type"))) {
+            if (etatCourant==Balise.BACK) {
+              typeCourant = decodeId(attributs.getValue("n"));
+              if (typeCourant.isEmpty())
+                throw new SAXNotSupportedException("Attribut \"n\" d'une balise "
+                        +"<spanGrp> de type \"AnalecUnit\" manquant");
+              etatCourant = Balise.SPANGRP;
+            } else
+              throw new SAXNotSupportedException("Balise <spanGrp> "
+                      +"de type \"AnalecUnit\" mal placée");
+          }
+          break;
+        case SPAN:
+          if (etatCourant==Balise.SPANGRP) {
+            Unite unit = new Unite();
+            unit.setType(typeCourant);
+            posUnites.put(unit, new String[]{
+                      xmlId(attributs.getValue("from")),
+                      xmlId(attributs.getValue("to"))});
+            idElements.put(attributs.getValue("xml:id"), unit);
+            propsElements.put(unit, xmlId(attributs.getValue("ana")));
+            etatCourant = Balise.SPAN;
+          }
+          break;
+        case JOINGRP:
+          if ("AnalecRelation".equals(attributs.getValue("type"))) {
+            if (etatCourant==Balise.BACK) {
+              typeCourant = decodeId(attributs.getValue("n"));
+              if (typeCourant.isEmpty())
+                throw new SAXNotSupportedException("Attribut \"n\" d'une balise "
+                        +"<joinGrp> de type \"AnalecRelation\" manquant");
+              etatCourant = Balise.JOINGRP_REL;
+            } else
+              throw new SAXNotSupportedException("Balise <joinGrp> "
+                      +"de type \"AnalecRelation\" mal placée");
+          } else if ("AnalecSchema".equals(attributs.getValue("type"))) {
+            if (etatCourant==Balise.BACK) {
+              typeCourant = decodeId(attributs.getValue("n"));
+              if (typeCourant.isEmpty())
+                throw new SAXNotSupportedException("Attribut \"n\" d'une balise "
+                        +"<joinGrp> de type \"AnalecSchema\" manquant");
+              etatCourant = Balise.JOINGRP_SCH;
+            } else
+              throw new SAXNotSupportedException("Balise <joinGrp> "
+                      +"de type \"AnalecSchema\" mal placée");
+          }
+
+          break;
+        case JOIN:
+          if (etatCourant==Balise.JOINGRP_REL) {
+            Relation rel = new Relation();
+            rel.setType(typeCourant);
+            eltsRelations.put(rel, splitIds(attributs.getValue("target")));
+            idElements.put(attributs.getValue("xml:id"), rel);
+            propsElements.put(rel, xmlId(attributs.getValue("ana")));
+            etatCourant = Balise.JOIN_REL;
+          } else if (etatCourant==Balise.JOINGRP_SCH) {
+            Schema sch = new Schema();
+            sch.setType(typeCourant);
+            eltsSchemas.put(sch, splitIds(attributs.getValue("target")));
+            idElements.put(attributs.getValue("xml:id"), sch);
+            propsElements.put(sch, xmlId(attributs.getValue("ana")));
+            etatCourant = Balise.JOIN_SCH;
+          }
+          break;
+        case FVLIB:
+          if ("AnalecElementProperties".equals(attributs.getValue("n"))) {
+            if (etatCourant==Balise.BACK) {
+              etatCourant = Balise.FVLIB;
+            } else
+              throw new SAXNotSupportedException("Balise <fvLib> "
+                      +"de type \"AnalecElementProperties\" mal placée");
+          }
+          break;
+        case FS:
+          if (etatCourant==Balise.FVLIB) {
+            idPropsEltCourant = attributs.getValue("xml:id");
+            valsprops.put(idPropsEltCourant, new HashMap<String, String>());
+            etatCourant = Balise.FS;
+          }
+          break;
+        case F:
+          if (etatCourant==Balise.FS) {
+            champCourant = decodeId(attributs.getValue("name"));
+            if (champCourant.isEmpty())
+              throw new SAXNotSupportedException("Attribut \"name\" "
+                      + "d'une balise <f> dans le <fvLib> de type"
+                      + " \"AnalecElementProperties\" manquant");
+
+            etatCourant = Balise.F;
+          }
+          break;
+        case STRING:
+          if (etatCourant==Balise.F) {
+            valCourant = "";
+            etatCourant = Balise.STRING;
+          }
+          break;
+      }
+    }
+    private String xmlId(String id) {
+      if (id==null||id.isEmpty()||id.charAt(0)!='#') return null;
+      return id.substring(1);
+    }
+    private String[] splitIds(String ids) {
+      if(ids.isEmpty()) return new String[0];
+      String[] idsplit = ids.split("\\s+");
+      for (int i = 0; i<idsplit.length; i++) {
+        idsplit[i] = xmlId(idsplit[i]);
+      }
+      return idsplit;
+    }
+    @Override
+    public void endElement(String uri, String local, String nomBalise) throws SAXException {
+      String type = "";
+      switch (balise(nomBalise)) {
+        case TEICORPUS:
+          if (etatCourant==Balise.TEICORPUS) etatCourant = Balise.FIN_DOC;
+          else
+            throw new SAXNotSupportedException("Balise </teiCorpus> mal placée");
+          break;
+        case TEIHEADER:
+          if (etatCourant==Balise.TEIHEADER_CORPUS)
+            etatCourant = Balise.TEICORPUS;
+          else if (etatCourant==Balise.TEIHEADER) etatCourant = Balise.TEI;
+          else
+            throw new SAXNotSupportedException("Balise </teiHeader> mal placée");
+          break;
+        case TEI:
+          if (etatCourant==Balise.TEI) {
+            remplirCorpus();
+            if (!ecrireFichier()) throw new SAXException("Erreur d'écriture "
+                      +"du fichier "+nomTEI+noDoc+".ec");
+            etatCourant = Balise.TEICORPUS;
+          } else
+            throw new SAXNotSupportedException("Balise </tei> mal placée");
+          break;
+        case TEXT:
+          if (etatCourant==Balise.TEXT) etatCourant = Balise.TEI;
+          else
+            throw new SAXNotSupportedException("Balise </text> mal placée");
+          break;
+        case BODY:
+          if (etatCourant==Balise.BODY) {
+            corpus.setTexte(texte);
+            corpus.setFinParagraphes(finParagraphes);
+            etatCourant = Balise.TEXT;
+          } else
+            throw new SAXNotSupportedException("Balise </body> mal placée");
+          break;
+        case P:
+          if (etatCourant==Balise.P) {
+            finParagraphes.add(texte.length());
+            etatCourant = Balise.BODY;
+          }
+          break;
+        case BACK:
+          if (etatCourant==Balise.BACK) etatCourant = Balise.TEXT;
+          else
+            throw new SAXNotSupportedException("Balise </back> mal placée");
+          break;
+        case SPANGRP:
+          if (etatCourant==Balise.SPANGRP) etatCourant = Balise.BACK;
+          break;
+        case SPAN:
+          if (etatCourant==Balise.SPAN) etatCourant = Balise.SPANGRP;
+          break;
+        case JOINGRP:
+          if (etatCourant==Balise.JOINGRP_REL||etatCourant==Balise.JOINGRP_SCH)
+            etatCourant = Balise.BACK;
+          break;
+        case JOIN:
+          if (etatCourant==Balise.JOIN_REL) etatCourant = Balise.JOINGRP_REL;
+          else if (etatCourant==Balise.JOIN_SCH)
+            etatCourant = Balise.JOINGRP_SCH;
+          break;
+        case FVLIB:
+          if (etatCourant==Balise.FVLIB) etatCourant = Balise.BACK;
+          break;
+        case FS:
+          if (etatCourant==Balise.FS) etatCourant = Balise.FVLIB;
+          break;
+        case F:
+          if (etatCourant==Balise.F) etatCourant = Balise.FS;
+          break;
+        case STRING:
+          if (etatCourant==Balise.STRING) {
+            valsprops.get(idPropsEltCourant).put(champCourant, valCourant);
+            etatCourant = Balise.F;
+          }
+          break;
+      }
+    }
+    @Override
+    public void characters(char[] ch, int start, int taille) throws SAXException {
+      if (etatCourant==Balise.P)
+        texte += decodeTexte(new String(ch, start, taille));
+      if (etatCourant==Balise.STRING)
+        valCourant += decodeTexte(new String(ch, start, taille));
+    }
+    private static String decodeTexte(String ch) {
+      return ch.replaceAll("&amp;", "&").replaceAll("&lt;", "<").
+              replaceAll("&gt;", ">").replaceAll("&quot;", "\"").
+              replaceAll("&apos;", "\'").replaceAll("[\\t\\n\\r\\f]", "");
+    }
+    private static String decodeId(String ch) {
+      if (ch==null||ch.isEmpty()) return "";
+      String id = ch.charAt(0)=='_' ? ch.substring(1) : ch;
+      return id.replaceAll("_", " ");
+    }
+    private void initCorpus() {
+      corpus.clearAll();
+      texte = "";
+      finParagraphes.clear();
+      ancres.clear();
+      posUnites.clear();
+      eltsRelations.clear();
+      eltsSchemas.clear();
+      idElements.clear();
+      propsElements.clear();
+      valsprops.clear();
+    }
+    private void remplirCorpus() throws SAXNotSupportedException {
+      for (Unite unit : posUnites.keySet()) {
+        String[] pos = posUnites.get(unit);
+        if (pos[0]==null||!ancres.containsKey(pos[0])
+                ||pos[1]==null||!ancres.containsKey(pos[1]))
+          throw new SAXNotSupportedException("Pas trouvé d'ancrage pour "
+                  +"une unité de type "+unit.getType());
+        unit.setDeb(ancres.get(pos[0]));
+        unit.setFin(ancres.get(pos[1]));
+        String idProps = propsElements.get(unit);
+        if (idProps==null||!valsprops.containsKey(idProps))
+          throw new SAXNotSupportedException("Pas trouvé de propriétés pour "
+                  +"une unité de type "+unit.getType());
+        HashMap<String, String> props = valsprops.get(idProps);
+        for (String champ : props.keySet())
+          unit.putProp(champ, props.get(champ));
+        corpus.addUniteLue(unit);
+      }
+      for (Relation rel : eltsRelations.keySet()) {
+        String[] idElts = eltsRelations.get(rel);
+        if (idElts.length!=2) {
+          throw new SAXNotSupportedException("Une relation de type "
+                  +rel.getType()+" n'a pas deux termes");
+        }
+        if (idElts[0]==null||!idElements.containsKey(idElts[0])
+                ||idElts[1]==null||!idElements.containsKey(idElts[1])) {
+          throw new SAXNotSupportedException("Errreur d'identification de termes "
+                  +" pour une relation de type "+rel.getType());
+        }
+        rel.setElt1(idElements.get(idElts[0]));
+        rel.setElt2(idElements.get(idElts[1]));
+        String idProps = propsElements.get(rel);
+        if (idProps==null||!valsprops.containsKey(idProps))
+          throw new SAXNotSupportedException("Pas trouvé de propriétés pour "
+                  +"une relation de type "+rel.getType());
+        HashMap<String, String> props = valsprops.get(idProps);
+        for (String champ : props.keySet())
+          rel.putProp(champ, props.get(champ));
+        corpus.addRelationLue(rel);
+      }
+      for (Schema sch : eltsSchemas.keySet()) {
+        String[] idElts = eltsSchemas.get(sch);
+        for (String idElt : idElts) {
+          if (idElt==null||!idElements.containsKey(idElt)) {
+            throw new SAXNotSupportedException("Errreur d'identification de termes "
+                    +" pour un schema de type "+sch.getType());
+          }
+          sch.ajouter(idElements.get(idElt));
+        }
+        String idProps = propsElements.get(sch);
+        if (idProps==null||!valsprops.containsKey(idProps))
+          throw new SAXNotSupportedException("Pas trouvé de propriétés pour "
+                  +"un schéma de type "+sch.getType());
+        HashMap<String, String> props = valsprops.get(idProps);
+        for (String champ : props.keySet())
+          sch.putProp(champ, props.get(champ));
+        corpus.addSchemaLu(sch);
+      }
+    }
+    private boolean ecrireFichier() {
+      return FichiersJava.enregistrerCorpus(corpus, Fichiers.creerFichier(
+              repJava, TypeFichier.DOC_ANALEC, nomTEI+noDoc));
+    }
+  }
+  public final static String TYPE_INFOS_META_DOCUMENTS = "Titre";
+  public final static String CHAMP_NON_RENSEIGNE = "non renseigné";
+  public final static String DEFAUT_TITRE_CORPUS = "";
+  public final static String DEFAUT_ANNOTATEURS = "";
+  public final static String DEFAUT_EDITEUR = "";
+  public final static String DEFAUT_SOURCE_CORPUS = "";
+  public static boolean exporterCorpusTEI(final Corpus corpus) {
+    File repJava;
+    final File ficTEI;
+    final File[] fics = Fichiers.choisirCorpus("Choix du répertoire Java",
+            TypeFichier.CORPUS_ANALEC);
+    if (fics.length==0) return false; ;
+    final HashMap<String, String> infosCorpus = new HashMap<String, String>();
+    saisirInfosCorpus(infosCorpus);
+    if ((ficTEI = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier TEI", Fichiers.TypeFichier.TEI))==null) return false;
+    final PrintWriter teiWriter;
+    try {
+      teiWriter = new PrintWriter(ficTEI, "UTF-8");
+    } catch (FileNotFoundException ex) {
+      GMessages.impossibiliteAction("Pas de fichier TEI ? ");
+
+      return false;
+    } catch (UnsupportedEncodingException ex) {
+      GMessages.impossibiliteAction("Pas de codage UTF8 ?");
+      return false;
+    }
+    final TEIPrinter teiPrinter = new TEIPrinter(corpus, teiWriter);
+    final GMessages.GProgression progression =
+            new GMessages.GProgression(fics.length, "Conversion", "fichiers");
+    Thread traitement = new Thread() {
+      @Override
+      public void run() {
+        try {
+          teiPrinter.ecrireEnteteCorpus(infosCorpus);
+          for (int i = 0; i<fics.length; i++) {
+            if (progression.isCanceled()) break;
+            progression.setNbTraites(i+1);
+            File ficJava = fics[i];
+            if (FichiersJava.ouvrirCorpus(corpus, ficJava, true))
+              teiPrinter.ecrireDocument(Fichiers.extraireNom(ficJava));
+          }
+          corpus.fermer();
+          teiPrinter.ecrireFinCorpus();
+          teiWriter.close();
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    };
+    traitement.start();
+    try {
+		traitement.join();
+	} catch (InterruptedException e) {
+		GMessages.erreurFatale(e);
+		return false;
+	}
+    return true;
+  }
+  private static boolean saisirInfosCorpus(HashMap<String, String> infosCorpus) {
+    final boolean[] pvalide = new boolean[1];
+    SaisieInfos fenetre = new SaisieInfos(pvalide, infosCorpus);
+    return pvalide[0];
+  }
+
+  private static class SaisieInfos extends JDialog {
+    private SaisieInfos(final boolean[] pvalide,
+            final HashMap<String, String> infosCorpus) {
+      super((JFrame) null, "Informations sur le corpus", true);
+      JPanel cadre = new JPanel(new BorderLayout());
+      setContentPane(cadre);
+      Rectangle rmax = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
+      int largeur = Math.min(rmax.width-100, 600);
+      int hauteur = Math.min(rmax.height-100, 400);
+      Point locFenetre = new Point((rmax.x+rmax.width)/2-largeur/2,
+              (rmax.y+rmax.height)/2-hauteur/2);
+      Dimension dimFenetre = new Dimension(largeur, hauteur);
+      setLocation(locFenetre);
+      setSize(dimFenetre);
+      setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
+      int hauteurCars = cadre.getFontMetrics(cadre.getFont()).getHeight()+5;
+      final JTextField champTitre = new JTextField(40);
+      champTitre.setMaximumSize(new Dimension(500, hauteurCars));
+      champTitre.setText(DEFAUT_TITRE_CORPUS);
+      final JTextField champAnnot = new JTextField(40);
+      champAnnot.setMaximumSize(new Dimension(500, hauteurCars));
+      champAnnot.setText(DEFAUT_ANNOTATEURS);
+      final JTextField champEditeur = new JTextField(40);
+      champEditeur.setMaximumSize(new Dimension(500, hauteurCars));
+      champEditeur.setText(DEFAUT_EDITEUR);
+      final JTextField champSource = new JTextField(40);
+      champSource.setMaximumSize(new Dimension(500, hauteurCars));
+      champSource.setText(DEFAUT_SOURCE_CORPUS);
+      Box box = Box.createVerticalBox();
+      box.add(Box.createVerticalGlue());
+      Box boxTitre = Box.createHorizontalBox();
+      boxTitre.add(Box.createHorizontalGlue());
+      boxTitre.add(new JLabel("Titre du corpus"));
+      boxTitre.add(Box.createHorizontalStrut(5));
+      boxTitre.add(champTitre);
+      boxTitre.add(Box.createHorizontalGlue());
+      box.add(boxTitre);
+      box.add(Box.createVerticalGlue());
+      Box boxAnnot = Box.createHorizontalBox();
+      boxAnnot.add(Box.createHorizontalGlue());
+      boxAnnot.add(new JLabel("Annotateurs"));
+      boxAnnot.add(Box.createHorizontalStrut(5));
+      boxAnnot.add(champAnnot);
+      boxAnnot.add(Box.createHorizontalGlue());
+      box.add(boxAnnot);
+      box.add(Box.createVerticalGlue());
+      Box boxEditeur = Box.createHorizontalBox();
+      boxEditeur.add(Box.createHorizontalGlue());
+      boxEditeur.add(new JLabel("Editeur"));
+      boxEditeur.add(Box.createHorizontalStrut(5));
+      boxEditeur.add(champEditeur);
+      boxEditeur.add(Box.createHorizontalGlue());
+      box.add(boxEditeur);
+      box.add(Box.createVerticalGlue());
+      Box boxSource = Box.createHorizontalBox();
+      boxSource.add(Box.createHorizontalGlue());
+      boxSource.add(new JLabel("Description du corpus"));
+      boxSource.add(Box.createHorizontalStrut(5));
+      boxSource.add(champSource);
+      boxSource.add(Box.createHorizontalGlue());
+      box.add(boxSource);
+      box.add(Box.createVerticalGlue());
+      add(box);
+      JButton valideModifs = new JButton(
+              new GAction("Valider") {
+                @Override
+                public void executer() {
+                  pvalide[0] = true;
+                  infosCorpus.put("Titre", champTitre.getText());
+                  infosCorpus.put("Annot", champAnnot.getText());
+                  infosCorpus.put("Editeur", champEditeur.getText());
+                  infosCorpus.put("Source", champSource.getText());
+                  dispose();
+                }
+              ;
+      });
+    JButton annuleModifs = new JButton(
+              new GAction("Annuler") {
+                @Override
+                public void executer() {
+                  pvalide[0] = false;
+                  dispose();
+                }
+              ;
+      });
+     Box boutons = Box.createHorizontalBox();
+      boutons.add(Box.createGlue());
+      boutons.add(valideModifs, Box.CENTER_ALIGNMENT);
+      boutons.add(Box.createHorizontalStrut(5));
+      boutons.add(annuleModifs, Box.CENTER_ALIGNMENT);
+      boutons.add(Box.createGlue());
+      add(boutons, BorderLayout.SOUTH);
+      setVisible(
+              true);
+
+    }
+  }
+
+  static private class TEIPrinter {
+    static private class Delimiteur implements Comparable<Delimiteur> {
+      private String id;
+      private int taille; // signé : négatif pour les délimiteurs de fin
+      private Delimiteur(String id, int taille) {
+        this.id = id;
+        this.taille = taille;
+      }
+      public int compareTo(Delimiteur d) {
+        if (taille!=d.taille) {
+          if (taille<0&&d.taille<0||taille>0&&d.taille>0)
+            return d.taille-taille;
+          else return taille-d.taille;
+        } else return taille>0 ? -d.id.compareTo(id) : d.id.compareTo(id);
+      }
+    }
+    private Corpus corpus;
+    private PrintWriter writer;
+    private String titreCorpus, annot, editeur, sourceCorpus;
+    private HashMap<String, ArrayList<Unite>> unites =
+            new HashMap<String, ArrayList<Unite>>();
+    private HashMap<String, ArrayList<Relation>> relations =
+            new HashMap<String, ArrayList<Relation>>();
+    private HashMap<String, ArrayList<Schema>> schemas =
+            new HashMap<String, ArrayList<Schema>>();
+    private HashMap<Element, String> ids = new HashMap<Element, String>();
+    private HashMap<String, String> encodeName = new HashMap<String, String>();
+    private HashMap<Integer, ArrayList<Delimiteur>> delimiteurs =
+            new HashMap<Integer, ArrayList<Delimiteur>>();
+    TEIPrinter(Corpus corpus, PrintWriter writer) {
+      this.corpus = corpus;
+      this.writer = writer;
+    }
+    private void ecrireEnteteCorpus(HashMap<String, String> infosCorpus) {
+      titreCorpus = traiterSaisie(infosCorpus.get("Titre"));
+      annot = traiterSaisie(infosCorpus.get("Annot"));
+      editeur = traiterSaisie(infosCorpus.get("Editeur"));
+      sourceCorpus = traiterSaisie(infosCorpus.get("Source"));
+      writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
+      writer.println("<teiCorpus xmlns=\"http://www.tei-c.org/ns/1.0\">");
+      writer.println(" <teiHeader>");
+      writer.println("<fileDesc>");
+      writer.println("<titleStmt>");
+      writer.println("<title>"+titreCorpus+"</title>");
+      writer.println("<respStmt>");
+      writer.println("<resp>annotated by</resp>");
+      writer.println("<name>"+annot+"</name>");
+      writer.println("</respStmt>");
+      writer.println("</titleStmt>");
+      writer.println("<publicationStmt>");
+      writer.println("<publisher>"+editeur+"</publisher>");
+      writer.println("</publicationStmt>");
+      writer.println("<sourceDesc>");
+      writer.println("<bibl>"+sourceCorpus+"</bibl>");
+      writer.println("</sourceDesc>");
+      writer.println("</fileDesc>");
+      writer.println("</teiHeader>");
+    }
+    private void ecrireFinCorpus() {
+      writer.println("</teiCorpus>");
+    }
+    private void preparerDonnees() {
+      unites.clear();
+      relations.clear();
+      schemas.clear();
+      ids.clear();
+      encodeName.clear();
+      delimiteurs.clear();
+      String codeType = "";
+      for (String type : corpus.getStructure().getTypes(Unite.class)) {
+        Unite[] units = corpus.getUnites(type).toArray(new Unite[0]);
+        Arrays.sort(units);
+        if (units.length>0) {
+          unites.put(type, new ArrayList<Unite>());
+          codeType = encodeId(type);
+          encodeName.put(type, codeType);
+          for (String prop : corpus.getStructure().getNomsProps(Unite.class, type))
+            encodeName.put(prop, encodeId(prop));
+        }
+        for (int no = 0; no<units.length; no++) {
+          Unite unit = units[no];
+          String id = "u-"+codeType+"-"+(no+1);
+          ids.put(unit, id);
+          unites.get(type).add(unit);
+          int taille = unit.getFin()-unit.getDeb();
+          Delimiteur del = new Delimiteur(id, taille);
+          addDel(unit.getDeb(), del);
+          if (taille>0) {
+            del = new Delimiteur(id, -taille);
+            addDel(unit.getFin(), del);
+          }
+        }
+      }
+      for (String type : corpus.getStructure().getTypes(Relation.class)) {
+        Relation[] rels = corpus.getRelations(type).toArray(new Relation[0]);
+        Arrays.sort(rels);
+        if (rels.length>0) {
+          relations.put(type, new ArrayList<Relation>());
+          codeType = encodeId(type);
+          encodeName.put(type, codeType);
+          for (String prop : corpus.getStructure().getNomsProps(Relation.class, type))
+            encodeName.put(prop, encodeId(prop));
+
+        }
+        for (int no = 0; no<rels.length; no++) {
+          Relation rel = rels[no];
+          String id = "r-"+codeType+"-"+(no+1);
+          ids.put(rel, id);
+          relations.get(type).add(rel);
+        }
+      }
+      for (String type : corpus.getStructure().getTypes(Schema.class)) {
+        Schema[] schs = corpus.getSchemas(type).toArray(new Schema[0]);
+        Arrays.sort(schs);
+        if (schs.length>0) {
+          schemas.put(type, new ArrayList<Schema>());
+          codeType = encodeId(type);
+          encodeName.put(type, codeType);
+          for (String prop : corpus.getStructure().getNomsProps(Schema.class, type))
+            encodeName.put(prop, encodeId(prop));
+        }
+        for (int no = 0; no<schs.length; no++) {
+          Schema sch = schs[no];
+          String id = "s-"+codeType+"-"+(no+1);
+          ids.put(sch, id);
+          schemas.get(type).add(sch);
+        }
+      }
+      int deb = 0;
+      for (int fin : corpus.getFinParagraphes()) {
+        int taille = fin-deb;
+        Delimiteur del = new Delimiteur("p", taille);
+        addDel(deb, del);
+        if (taille>0) {
+          del = new Delimiteur("p", -taille);
+          addDel(fin, del);
+        }
+        deb = fin;
+      }
+    }
+    private void addDel(int pos, Delimiteur del) {
+      if (!delimiteurs.containsKey(pos))
+        delimiteurs.put(pos, new ArrayList<Delimiteur>());
+      delimiteurs.get(pos).add(del);
+    }
+    private void ecrireDocument(String nomfic) {
+      preparerDonnees();
+      writer.println("<TEI>");
+      ecrireEntete(nomfic);
+      writer.println("<text>");
+      ecrireTexte();
+      ecrireAnnot();
+      writer.println("</text>");
+      writer.println("</TEI>");
+    }
+    private void ecrireEntete(String nomfic) {
+      String titre = "";
+      String auteur = "";
+      String source = "";
+      if (!corpus.getUnites(TYPE_INFOS_META_DOCUMENTS).isEmpty()) {
+        Unite infos = corpus.getUnites(TYPE_INFOS_META_DOCUMENTS).get(0);
+        titre = encodeTexte(infos.getProp("titre"));
+        auteur = encodeTexte(infos.getProp("auteur"));
+        source = encodeTexte(infos.getProp("source"));
+      }
+      if (titre.isEmpty()) titre = nomfic;
+      if (auteur.isEmpty()) auteur = CHAMP_NON_RENSEIGNE;
+      if (source.isEmpty()) source = CHAMP_NON_RENSEIGNE;
+      writer.println("<teiHeader>");
+      writer.println("<fileDesc>");
+      writer.println("<titleStmt>");
+      writer.println("<title>"+titre+"</title>");
+      writer.println("<author>"+auteur+"</author>");
+      writer.println("<respStmt>");
+      writer.println("<resp>annotated by</resp>");
+      writer.println("<name>"+annot+"</name>");
+      writer.println("</respStmt>");
+      writer.println("</titleStmt>");
+      writer.println("<publicationStmt>");
+      writer.println("<publisher>"+editeur+"</publisher>");
+      writer.println("</publicationStmt>");
+      writer.println("<sourceDesc>");
+      writer.println("<bibl>"+source+"</bibl>");
+      writer.println("</sourceDesc>");
+      writer.println("</fileDesc>");
+      writer.println("</teiHeader>");
+    }
+    private void ecrireTexte() {
+      writer.println("<body>");
+      Integer[] pos = delimiteurs.keySet().toArray(new Integer[0]);
+      Arrays.sort(pos);
+      ecrireDel(delimiteurs.get(0));
+      int deb = 0;
+      for (int i = 1; i<pos.length; i++) {
+        int fin = pos[i];
+        writer.print(encodeTexte(corpus.getTexte().substring(deb, fin)));
+        ecrireDel(delimiteurs.get(fin));
+        deb = fin;
+      }
+      writer.println("</body>");
+    }
+    private void ecrireDel(ArrayList<Delimiteur> delims) {
+      Delimiteur[] dels = delims.toArray(new Delimiteur[0]);
+      Arrays.sort(dels);
+      for (Delimiteur del : dels) {
+        if (del.id.equals("p")) {
+          if (del.taille>0)
+            writer.println("<p>");
+          else {
+            writer.println();
+            if (del.taille<0) writer.println("</p>");
+            else writer.println("<p/>");
+          }
+        } else {
+          String ancre1 = "<anchor xml:id=\""+del.id;
+          String ancre2 = "\" type=\"AnalecDelimiter\" subtype=\"Unit";
+          if (del.taille>0)
+            writer.print(ancre1+"-start"+ancre2+"Start\"/>");
+          else if (del.taille<0)
+            writer.print(ancre1+"-end"+ancre2+"End\"/>");
+          else {  // ne devrait pas se produire : une unité de taille nulle
+            writer.print(ancre1+"-start"+ancre2+"Start\"/>");
+            writer.print(ancre1+"-end"+ancre2+"End\"/>");
+          }
+        }
+      }
+    }
+    private void ecrireAnnot() {
+      writer.println("<back>");
+      for (String type : unites.keySet()) {
+        writer.println("<spanGrp type=\"AnalecUnit\""
+                +" n=\""+encodeName.get(type)+"\">");
+        for (Unite unit : unites.get(type)) ecrireUnite(unit);
+        writer.println("</spanGrp>");
+      }
+      for (String type : relations.keySet()) {
+        writer.println("<joinGrp type=\"AnalecRelation\""
+                +" n=\""+encodeName.get(type)+"\">");
+        for (Relation rel : relations.get(type)) ecrireRelation(rel);
+        writer.println("</joinGrp>");
+      }
+      for (String type : schemas.keySet()) {
+        writer.println("<joinGrp type=\"AnalecSchema\""
+                +" n=\""+encodeName.get(type)+"\">");
+        for (Schema sch : schemas.get(type)) ecrireSchema(sch);
+        writer.println("</joinGrp>");
+      }
+      writer.println("<fvLib n=\"AnalecElementProperties\">");
+      for (String type : unites.keySet())
+        for (Unite unit : unites.get(type)) ecrireProps(unit);
+      for (String type : relations.keySet())
+        for (Relation rel : relations.get(type)) ecrireProps(rel);
+      for (String type : schemas.keySet())
+        for (Schema sch : schemas.get(type)) ecrireProps(sch);
+      writer.println("</fvLib>");
+      writer.println("</back>");
+    }
+    private void ecrireUnite(Unite unit) {
+      String id = ids.get(unit);
+      writer.println("<span xml:id=\""+id+"\"");
+      writer.println("from=\"#"+id+"-start\" to=\"#"+id+"-end\"");
+      writer.println("ana=\"#"+id+"-fs\"/>");
+    }
+    private void ecrireRelation(Relation rel) {
+      String id = ids.get(rel);
+      writer.println("<join xml:id=\""+ids.get(rel)+"\"");
+      writer.println("target=\"#"+ids.get(rel.getElt1())
+              +" #"+ids.get(rel.getElt2())+"\"");
+      writer.println("ana=\"#"+id+"-fs\"/>");
+    }
+    private void ecrireSchema(Schema sch) {
+      String id = ids.get(sch);
+      writer.println("<join xml:id=\""+ids.get(sch)+"\"");
+      writer.print("target=\"");
+      for (Element elt : sch.getContenu())
+        writer.print("#"+ids.get(elt)+" ");
+      writer.println("\"");
+      writer.println("ana=\"#"+id+"-fs\"/>");
+    }
+    private void ecrireProps(Element elt) {
+      writer.println("<fs xml:id=\""+ids.get(elt)+"-fs\">");
+      HashMap<String, String> props = elt.getProps();
+      for (String nom : props.keySet()) {
+        if (props.get(nom)!=null)
+          writer.println("<f name=\""+encodeName.get(nom)+"\"><string>"
+                  +encodeTexte(props.get(nom))+"</string></f>");
+      }
+      writer.println("</fs>");
+    }
+    private static String encodeTexte(String ch) {
+      return ch.replaceAll("&", "&amp;").replaceAll("<", "&lt;").
+              replaceAll(">", "&gt;").replaceAll("\"", "&quot;").
+              replaceAll("\'", "&apos;");
+    }
+    final static String interdits = "[!\\\"#\\$%&'\\(\\)\\*+,/;<=>\\?"
+            +"@\\[\\\\\\]\\^`\\{\\|\\}\\~]";
+    private static String encodeId(String ch) {
+      String id = ch.replaceAll("\\s", "_");
+      if (id.matches("[-\\.0-9];*")) id = '_'+id;
+      id = id.replaceAll(interdits, "\u00b7");
+      if (id.substring(0, 3).equalsIgnoreCase("xml")) id = '_'+id;
+      return id;
+    }
+    private static String traiterSaisie(String ch) {
+      if (ch==null) return CHAMP_NON_RENSEIGNE;
+      if (ch.trim().isEmpty()) return CHAMP_NON_RENSEIGNE;
+      return encodeTexte(ch);
+    }
+  }
+  
+
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTEI.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/ProgressMonitorDemo.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/ProgressMonitorDemo.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/ProgressMonitorDemo.java	(revision 481)
@@ -0,0 +1,173 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+/**
+ *
+ * @author Bernard
+ */
+/*
+ * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle or the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */ 
+
+
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import java.beans.*;
+import java.util.Random;
+
+public class ProgressMonitorDemo extends JPanel
+                                 implements ActionListener,
+                                            PropertyChangeListener {
+
+    private ProgressMonitor progressMonitor;
+    private JButton startButton;
+    private JTextArea taskOutput;
+    private Task task;
+
+    class Task extends SwingWorker<Void, Void> {
+        @Override
+        public Void doInBackground() {
+            Random random = new Random();
+            int progress = 0;
+            setProgress(0);
+            try {
+                Thread.sleep(1000);
+                while (progress < 100 && !isCancelled()) {
+                    //Sleep for up to one second.
+                    Thread.sleep(random.nextInt(1000));
+                    //Make random progress.
+                    progress += random.nextInt(10);
+                    setProgress(Math.min(progress, 100));
+                }
+            } catch (InterruptedException ignore) {}
+            return null;
+        }
+
+        @Override
+        public void done() {
+            Toolkit.getDefaultToolkit().beep();
+            startButton.setEnabled(true);
+            progressMonitor.setProgress(0);
+        }
+    }
+
+    public ProgressMonitorDemo() {
+        super(new BorderLayout());
+
+        //Create the demo's UI.
+        startButton = new JButton("Start");
+        startButton.setActionCommand("start");
+        startButton.addActionListener(this);
+
+        taskOutput = new JTextArea(5, 20);
+        taskOutput.setMargin(new Insets(5,5,5,5));
+        taskOutput.setEditable(false);
+
+        add(startButton, BorderLayout.PAGE_START);
+        add(new JScrollPane(taskOutput), BorderLayout.CENTER);
+        setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+
+    }
+
+
+    /**
+     * Invoked when the user presses the start button.
+     */
+    public void actionPerformed(ActionEvent evt) {
+        progressMonitor = new ProgressMonitor(ProgressMonitorDemo.this,
+                                  "Running a Long Task",
+                                  "", 0, 100);
+        progressMonitor.setProgress(0);
+        task = new Task();
+        task.addPropertyChangeListener(this);
+        task.execute();
+        startButton.setEnabled(false);
+    }
+
+    /**
+     * Invoked when task's progress property changes.
+     */
+    public void propertyChange(PropertyChangeEvent evt) {
+        if ("progress" == evt.getPropertyName() ) {
+            int progress = (Integer) evt.getNewValue();
+            progressMonitor.setProgress(progress);
+            String message =
+                String.format("Completed %d%%.\n", progress);
+            progressMonitor.setNote(message);
+            taskOutput.append(message);
+            if (progressMonitor.isCanceled() || task.isDone()) {
+                Toolkit.getDefaultToolkit().beep();
+                if (progressMonitor.isCanceled()) {
+                    task.cancel(true);
+                    taskOutput.append("Task canceled.\n");
+                } else {
+                    taskOutput.append("Task completed.\n");
+                }
+                startButton.setEnabled(true);
+            }
+        }
+
+    }
+
+    /**
+     * Create the GUI and show it.  For thread safety,
+     * this method should be invoked from the
+     * event-dispatching thread.
+     */
+    private static void createAndShowGUI() {
+        //Create and set up the window.
+        JFrame frame = new JFrame("ProgressMonitorDemo");
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+        //Create and set up the content pane.
+        JComponent newContentPane = new ProgressMonitorDemo();
+        newContentPane.setOpaque(true); //content panes must be opaque
+        frame.setContentPane(newContentPane);
+
+        //Display the window.
+        frame.pack();
+        frame.setVisible(true);
+    }
+
+    public static void main(String[] args) {
+        //Schedule a job for the event-dispatching thread:
+        //creating and showing this application's GUI.
+        javax.swing.SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                createAndShowGUI();
+            }
+        });
+    }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/ProgressMonitorDemo.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersGlozz.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersGlozz.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersGlozz.java	(revision 481)
@@ -0,0 +1,718 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import javax.xml.parsers.*;
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public abstract class FichiersGlozz {
+  public static void convertirCorpusGlozz(final Corpus corpus) {
+    File repGlozz;
+    final File repJava;
+    if ((repGlozz = Fichiers.choisirRepertoire("Choix du répertoire Glozz"))==null)
+      return;
+    if ((repJava = Fichiers.choisirRepertoire("Choix du répertoire Java"))==null)
+      return;
+    if (!repJava.exists()) {
+      if (!GMessages.confirmationAction("Le répertoire spécifié n'existe pas."
+              +" Voulez-vous le créer ?")) return;
+      if (!repJava.mkdir()) {
+        GMessages.impossibiliteAction("Echec de la création du répertoire");
+        return;
+      }
+    }
+    final File[] fics = Fichiers.listerFichiers(repGlozz, Fichiers.TypeFichier.GLOZZ_CORPUS);
+    final GMessages.GProgression progression =
+            new GMessages.GProgression(fics.length, "Conversion", "fichiers");
+    Thread traitement = new Thread() {
+      @Override
+      public void run() {
+        try {
+        for (int i = 0; i<fics.length; i++) {
+          if (progression.isCanceled()) break;
+          progression.setNbTraites(i+1);
+          File fichierCorpus = fics[i];
+          File fichierAnnot = Fichiers.trouverFichier(TypeFichier.GLOZZ_ANNOT, fichierCorpus);
+          if (fichierAnnot==null) continue;
+          importer(fichierCorpus, fichierAnnot, corpus);
+          FichiersJava.enregistrerCorpus(corpus, Fichiers.creerFichier(repJava, TypeFichier.DOC_ANALEC, fichierCorpus));
+//          corpus.fermer();
+        }
+        corpus.fermer();
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    };
+    traitement.start();
+  }
+
+	public static boolean importerGlozz(Corpus corpus, File fichierCorpus, File fichierAnnot) {
+		if (!importer(fichierCorpus, fichierAnnot, corpus)) {
+			return false;
+		}
+		corpus.newCorpusLu();
+		
+		return true;
+	}
+	
+	/**
+	 * 
+	 * @param corpus
+	 */
+	public static boolean importerGlozz(Corpus corpus) {
+		File fichierCorpus;
+		File fichierAnnot;
+		if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR,
+				"Choix du fichier corpus", Fichiers.TypeFichier.GLOZZ_CORPUS))==null)
+			return false;
+		if ((fichierAnnot = Fichiers.choisirFichier(Commande.OUVRIR,
+				"Choix du fichier annotations", Fichiers.TypeFichier.GLOZZ_ANNOT))==null)
+			return false;
+		
+		return importerGlozz(corpus, fichierCorpus, fichierAnnot);
+	}
+	
+  
+  private static boolean importer(File fichierCorpus, File fichierAnnot, Corpus corpus) {
+    BufferedReader text = null;
+    BufferedInputStream annot = null;
+    try {
+      text = new BufferedReader(new InputStreamReader(new FileInputStream(fichierCorpus), "UTF-8"));
+      annot = new BufferedInputStream(new FileInputStream(fichierAnnot));
+      corpus.setTexte(text.readLine());
+      SAXParserFactory pf = (SAXParserFactory) SAXParserFactory.newInstance();
+      SAXParser sp = pf.newSAXParser();
+      sp.parse(annot, new GlozzHandler(corpus));
+    } catch (IOException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (ParserConfigurationException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (SAXException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } finally {
+      try {
+        if (text!=null) text.close();
+        if (annot!=null) annot.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
+      }
+    }
+    return true;
+  }
+	public static boolean importerModeleGlozz(Corpus corpus, File fichierModele) {
+		BufferedInputStream modele = null;
+		
+		try {
+			modele = new BufferedInputStream(new FileInputStream(fichierModele));
+			SAXParserFactory pf = (SAXParserFactory) SAXParserFactory.newInstance();
+			SAXParser sp = pf.newSAXParser();
+			Structure structureLue = new Structure();
+			sp.parse(modele, new ModeleGlozzHandler(structureLue));
+			corpus.fusionnerStructureLue(structureLue);
+			corpus.newCorpusLu();
+		} catch (IOException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (ParserConfigurationException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (SAXException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			try {
+				if (modele!=null) modele.close();
+			} catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
+			}
+		}
+		return true;
+	}
+	
+	public static boolean importerModeleGlozz(Corpus corpus) {
+		File fichierModele;
+		if ((fichierModele = Fichiers.choisirFichier(Commande.OUVRIR,
+				"Choix du fichier modèle", Fichiers.TypeFichier.GLOZZ_MODELE))==null)
+			return false;
+		
+		return importerModeleGlozz(corpus, fichierModele);
+	}
+  public static boolean exporterGlozz(Corpus corpus) {
+    PrintWriter text = null;
+    PrintWriter annot = null;
+    PrintWriter model = null;
+    File fichierCorpus;
+    File fichierAnnot;
+    File fichierModel;
+    if ((fichierCorpus = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier corpus", Fichiers.TypeFichier.GLOZZ_CORPUS))==null) return false;
+    if ((fichierAnnot = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier annotations", Fichiers.TypeFichier.GLOZZ_ANNOT))==null)
+      return false;
+    try {
+      text = new PrintWriter(fichierCorpus, "UTF-8");
+      annot = new PrintWriter(fichierAnnot, "UTF-8");
+      text.print(corpus.getTexte());
+      GlozzPrinter gp = new GlozzPrinter(corpus, annot);
+      gp.ecrireAnnot();
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } finally {
+      if (text!=null) text.close();
+      if (annot!=null) annot.close();
+    }
+    if ((fichierModel = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Exporter aussi le modèle ?", Fichiers.TypeFichier.GLOZZ_MODELE))==null)
+      return true;
+    try {
+      model = new PrintWriter(fichierModel, "UTF-8");
+      ModelGlozzPrinter gp = new ModelGlozzPrinter(corpus.getStructure(), model);
+      gp.ecrireModel();
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+    } finally {
+      if (model!=null) model.close();
+    }
+    return true;
+  }
+  
+  public static boolean exporterModeleGlozz(Structure structure) {
+    PrintWriter model = null;
+    File fichierModel;
+    if ((fichierModel = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier modèle ?", Fichiers.TypeFichier.GLOZZ_MODELE))==null)
+      return false;
+    try {
+      model = new PrintWriter(fichierModel, "UTF-8");
+      ModelGlozzPrinter gp = new ModelGlozzPrinter(structure, model);
+      gp.ecrireModel();
+    } catch (Exception ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return false;
+    } finally {
+      if (model!=null) model.close();
+    }
+    return true;
+  }
+
+  static class GlozzHandler extends DefaultHandler {
+    Corpus corpus;
+    Balise etatCourant = null;
+    Element elementCourant = null;
+    String champCourant = null;
+    String valCourant = null;
+    HashMap<String, Element> elements = new HashMap<String, Element>();
+    ArrayList<Relation> relations = new ArrayList<Relation>();
+    HashMap<Relation, ArrayList<String>> idTermes = new HashMap<Relation, ArrayList<String>>();
+    ArrayList<Schema> schemas = new ArrayList<Schema>();
+    HashMap<Schema, ArrayList<String>> idContenus = new HashMap<Schema, ArrayList<String>>();
+
+    enum Balise {
+      ANNOTATIONS, UNIT, RELATION, SCHEMA, METADATA, AUTHOR, CREATIONDATE,
+      LASTMODIFIER, LASTMODIFICATIONDATE, CHARACTERISATION, TYPE, FEATURESET,
+      FEATURE, POSITIONING, START, END, SINGLEPOSITION, TERM,
+      EMBEDDEDUNIT, EMBEDDEDRELATION, EMBEDDEDSCHEMA,
+      FLAG, COMMENT
+    };
+    static Balise balise(String nomBalise) {
+      return Balise.valueOf(nomBalise.replaceAll("\\W", "").toUpperCase());
+    }
+    GlozzHandler(Corpus corpus) {
+      super();
+      this.corpus = corpus;
+    }
+    @Override
+    public void startDocument() {
+      corpus.clearAnnot();
+    }
+    @Override
+    public void endDocument() throws SAXNotSupportedException {
+      for (Relation rel : relations) {
+        ArrayList<String> idterms = idTermes.get(rel);
+        if (idterms.size()!=2) {
+          throw new SAXNotSupportedException("Une relation de type "+rel.getType()+" n'a pas deux termes");
+        }
+        if (elements.get(idterms.get(0))==null) {
+          throw new SAXNotSupportedException("Terme inconnu id = "+idterms.get(0)
+                  +" pour une relation de type "+rel.getType());
+        }
+        rel.setElt1(elements.get(idterms.get(0)));
+        if (elements.get(idterms.get(1))==null) {
+          throw new SAXNotSupportedException("Terme inconnu id = "+idterms.get(1)
+                  +" pour une relation de type "+rel.getType());
+        }
+        rel.setElt2(elements.get(idterms.get(1)));
+        corpus.addRelationLue(rel);
+      }
+      for (Schema sch : schemas) {
+        for (String id : idContenus.get(sch)) {
+          if (elements.get(id)==null) {
+            throw new SAXNotSupportedException("Contenu inconnu id = "+id
+                    +" pour un schéma de type "+sch.getType());
+          }
+          sch.ajouter(elements.get(id));
+        }
+        corpus.addSchemaLu(sch);
+      }
+      corpus.verifierFinParagraphesTypesUnites(new String[]{
+                "title", "subTitle", "sectionTitle", "subSectionTitle",
+                "subSubSectionTitle", "subSubSubSectionTitle", "quote", "listItem"});
+      corpus.trierFinParagraphes();
+      corpus.verifierFinParagrapheFinTexte();
+    }
+    @Override
+    public void startElement(String uri, String local, String nomBalise, Attributes attributs) throws SAXException {
+      if (etatCourant==Balise.FLAG) return;
+      switch (balise(nomBalise)) {
+        case FLAG:
+          etatCourant = Balise.FLAG;
+          break;
+        case UNIT:
+          elementCourant = new Unite();
+          elements.put(attributs.getValue("id"), elementCourant);
+          break;
+        case RELATION:
+          elementCourant = new Relation();
+          elements.put(attributs.getValue("id"), elementCourant);
+          idTermes.put((Relation) elementCourant, new ArrayList<String>());
+          break;
+        case SCHEMA:
+          elementCourant = new Schema();
+          elements.put(attributs.getValue("id"), elementCourant);
+          idContenus.put((Schema) elementCourant, new ArrayList<String>());
+          break;
+        case TYPE:
+          etatCourant = Balise.TYPE;
+          valCourant = "";
+          break;
+        case FEATURE:
+          etatCourant = Balise.FEATURE;
+          champCourant = attributs.getValue("name");
+          valCourant = "";
+          break;
+        case START:
+          etatCourant = Balise.START;
+          break;
+        case END:
+          etatCourant = Balise.END;
+          break;
+        case SINGLEPOSITION:
+          if (elementCourant.getClass()!=Unite.class) {
+            throw new SAXNotSupportedException("La balise singlePosition ne peut être utilisée que pour des unités");
+          }
+          if (elementCourant.getType().equals("paragraph")) {
+            if (etatCourant==Balise.END) {
+              corpus.addFinParagraphe(Integer.parseInt(attributs.getValue("index")));
+            }
+          } else {
+            switch (etatCourant) {
+              case START:
+                ((Unite) elementCourant).setDeb(Integer.parseInt(attributs.getValue("index")));
+                break;
+              case END:
+                ((Unite) elementCourant).setFin(Integer.parseInt(attributs.getValue("index")));
+                break;
+            }
+          }
+          break;
+        case TERM:
+          if (elementCourant.getClass()!=Relation.class)
+            throw new SAXNotSupportedException("La balise term ne peut être utilisée que pour des relations");
+          idTermes.get((Relation) elementCourant).add(attributs.getValue("id"));
+          break;
+
+        case EMBEDDEDUNIT:
+        case EMBEDDEDRELATION:
+        case EMBEDDEDSCHEMA:
+          if (elementCourant.getClass()!=Schema.class)
+            throw new SAXNotSupportedException(
+                    "Les balises embedded ne peuvent être utilisées que pour des schémas");
+          idContenus.get((Schema) elementCourant).add(attributs.getValue("id"));
+          break;
+      }
+    }
+    @Override
+    public void endElement(String uri, String local, String nomBalise) throws SAXException {
+      if (etatCourant==Balise.FLAG) {
+        if (balise(nomBalise)==Balise.FLAG) etatCourant = null;
+        return;
+      }
+      String type = "";
+      switch (balise(nomBalise)) {
+        case UNIT:
+          type = elementCourant.getType();
+          if (type==null||type.isEmpty())
+            throw new SAXNotSupportedException("Pas trouvé de type pour cette unité");
+          if (!type.equals("paragraph")) {
+            corpus.addUniteLue((Unite) elementCourant);
+            elementCourant = null;
+          }
+          break;
+        case RELATION:
+          type = elementCourant.getType();
+          if (type==null||type.isEmpty())
+            throw new SAXNotSupportedException("Pas trouvé de type pour cette relation");
+          relations.add((Relation) elementCourant);
+          elementCourant = null;
+          break;
+        case SCHEMA:
+          type = elementCourant.getType();
+          if (type==null||type.isEmpty())
+            throw new SAXNotSupportedException("Pas trouvé de type pour ce shéma");
+          schemas.add((Schema) elementCourant);
+          elementCourant = null;
+          break;
+        case TYPE:
+          elementCourant.setType(valCourant);
+          valCourant = null;
+          etatCourant = null;
+          break;
+        case FEATURE:
+          elementCourant.putProp(champCourant, valCourant);
+          etatCourant = null;
+          champCourant = null;
+          valCourant = null;
+          break;
+        case START:
+          etatCourant = null;
+          break;
+        case END:
+          etatCourant = null;
+          break;
+      }
+    }
+    @Override
+    public void characters(char[] ch, int start, int taille) throws SAXException {
+      if (etatCourant==null||!EnumSet.of(Balise.TYPE, Balise.FEATURE).contains(etatCourant)) {
+        return;
+      }
+      valCourant += new String(ch, start, taille);
+    }
+  }
+
+  static class ModeleGlozzHandler extends DefaultHandler {
+    Structure structure;
+    boolean listeValeurs = false;
+    Class<? extends Element> classeCourante = Unite.class;  // par défaut : balise <units> sous-entendue 
+    String typeCourant = null;
+    String champCourant = null;
+    String valeurCourante = null;
+
+    enum Balise {
+      ANNOTATIONMODEL, UNITS, RELATIONS, SCHEMAS, TYPE, FEATURESET,
+      FEATURE, POSSIBLEVALUES, VALUE
+    };
+    static Balise balise(String nomBalise) throws SAXNotRecognizedException {
+      try {
+        return Balise.valueOf(nomBalise.replaceAll("\\W", "").toUpperCase());
+      } catch (Exception e) {
+        throw new SAXNotRecognizedException("Balise non reconnue : "+nomBalise);
+      }
+    }
+    ModeleGlozzHandler(Structure structure) {
+      super();
+      this.structure = structure;
+    }
+    @Override
+    public void startDocument() {
+    }
+    @Override
+    public void endDocument() throws SAXNotSupportedException {
+    }
+    @Override
+    public void startElement(String uri, String local, String nomBalise, Attributes attributs) throws SAXException {
+      String valdef = null;
+      switch (balise(nomBalise)) {
+        case UNITS:
+          classeCourante = Unite.class;
+          break;
+        case RELATIONS:
+          classeCourante = Relation.class;
+          break;
+        case SCHEMAS:
+          classeCourante = Schema.class;
+          break;
+        case TYPE:
+          typeCourant = attributs.getValue("name");
+          if (typeCourant==null||typeCourant.isEmpty())
+            throw new SAXNotSupportedException("Nom de type absent");
+          structure.ajouterType(classeCourante, typeCourant);
+          break;
+        case FEATURE:
+          if (typeCourant==null||typeCourant.isEmpty())
+            throw new SAXNotSupportedException("Nom de type absent");
+          champCourant = attributs.getValue("name");
+          if (champCourant==null||champCourant.isEmpty())
+            throw new SAXNotSupportedException("Nom de type absent");
+          structure.ajouterProp(classeCourante, typeCourant, champCourant);
+          break;
+        case POSSIBLEVALUES:
+          if (typeCourant==null||typeCourant.isEmpty()||champCourant==null||champCourant.isEmpty())
+            throw new SAXNotSupportedException("Nom de type ou de feature absent");
+          listeValeurs = true;
+          valdef = attributs.getValue("default");
+          if (valdef!=null&&!valdef.isEmpty())
+            structure.modifierValParDefaut(classeCourante, typeCourant, champCourant, valdef);
+          break;
+        case VALUE:
+          if (listeValeurs) valeurCourante = "";
+          valdef = attributs.getValue("default");
+          if (valdef!=null&&!valdef.isEmpty()) {
+            if (typeCourant==null||typeCourant.isEmpty()||champCourant==null||champCourant.isEmpty())
+              throw new SAXNotSupportedException("Nom de type ou de feature absent");
+            structure.ajouterVal(classeCourante, typeCourant, champCourant, valdef);
+            structure.modifierValParDefaut(classeCourante, typeCourant, champCourant, valdef);
+          }
+          break;
+      }
+    }
+    @Override
+    public void endElement(String uri, String local, String nomBalise) throws SAXException {
+      switch (balise(nomBalise)) {
+        case POSSIBLEVALUES:
+          listeValeurs = false;
+          break;
+        case VALUE:
+          if (listeValeurs&&valeurCourante!=null&&!valeurCourante.isEmpty())
+            structure.ajouterVal(classeCourante, typeCourant, champCourant, valeurCourante);
+          break;
+      }
+    }
+    @Override
+    public void characters(char[] ch, int start, int taille) throws SAXException {
+      if (listeValeurs) {
+        valeurCourante += new String(ch, start, taille);
+      }
+    }
+  }
+
+  static class GlozzPrinter {
+    Corpus corpus;
+    PrintWriter annot;
+    HashMap<Element, String> idDates = new HashMap<Element, String>();
+    String idAuteur = "analec0.2";
+    String idDateParagraphes = "0";
+    String idParagraphes = idAuteur+"_"+idDateParagraphes;
+    GlozzPrinter(Corpus corpus, PrintWriter annot) {
+      this.corpus = corpus;
+      this.annot = annot;
+      attribueIdDates();
+    }
+    void attribueIdDates() {
+      long idDate = (new Date()).getTime();
+      for (Unite unite : corpus.getToutesUnites()) {
+        idDates.put(unite, Long.toString(idDate++));
+      }
+      for (Relation relation : corpus.getToutesRelations()) {
+        idDates.put(relation, Long.toString(idDate++));
+      }
+      for (Schema schema : corpus.getTousSchemas()) {
+        idDates.put(schema, Long.toString(idDate++));
+      }
+    }
+    String getId(Element elt) {
+      return idAuteur+"_"+idDates.get(elt);
+    }
+    void ecrireAnnot() {
+      annot.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
+      annot.println("<annotations>");
+      ecrireFinParagraphes();
+      ecrireUnites();
+      ecrireRelations();
+      ecrireSchemas();
+      annot.println("</annotations>");
+    }
+    private void ecrireFinParagraphes() {
+      int deb = 0;
+      for (int fin : corpus.getFinParagraphes()) {
+        ecrireUnite("paragraph", idAuteur, idDateParagraphes, idParagraphes, new HashMap<String, String>(), deb, fin);
+        deb = fin;
+      }
+    }
+    private void ecrireUnites() {
+      for (Unite unit : corpus.getToutesUnites()) {
+        ecrireUnite(unit.getType(), idAuteur, idDates.get(unit), getId(unit), unit.getProps(), unit.getDeb(), unit.getFin());
+      }
+    }
+    private void ecrireRelations() {
+      for (Relation rel : corpus.getToutesRelations()) {
+        ecrireRelation(rel.getType(), idAuteur, idDates.get(rel), getId(rel), rel.getProps(), rel.getElt1(), rel.getElt2());
+      }
+    }
+    private void ecrireSchemas() {
+      for (Schema sch : corpus.getTousSchemas()) {
+        ecrireSchema(sch.getType(), idAuteur, idDates.get(sch), getId(sch), sch.getProps(), sch.getContenu());
+      }
+    }
+    private void ecrireUnite(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, int deb, int fin) {
+      annot.println("<unit id=\""+id+"\">");
+      ecrireMetadata(idAuteur, idDate);
+      ecrireProps(type, props);
+      ecrirePos(deb, fin);
+      annot.println("</unit>");
+    }
+    private void ecrireRelation(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, Element elt1, Element elt2) {
+      annot.println("<relation id=\""+id+"\">");
+      ecrireMetadata(idAuteur, idDate);
+      ecrireProps(type, props);
+      ecrireRel(elt1, elt2);
+      annot.println("</relation>");
+    }
+    private void ecrireSchema(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, HashSet<Element> elts) {
+      annot.println("<schema id=\""+id+"\">");
+      ecrireMetadata(idAuteur, idDate);
+      ecrireProps(type, props);
+      ecrireSch(elts);
+      annot.println("</schema>");
+    }
+    private void ecrireMetadata(String idAuteur, String id) {
+      annot.println("<metadata>");
+      annot.println("<author>"+idAuteur+"</author>");
+      annot.println("<creation-date>"+id+"</creation-date>");
+      annot.println("</metadata>");
+    }
+    private void ecrireProps(String type, HashMap<String, String> props) {
+      annot.println("<characterisation>");
+      annot.println("<type>"+encodeXMLTexte(type)+"</type>");
+      if (props.isEmpty()) {
+        annot.println("<featureSet/>");
+      } else {
+        annot.println("<featureSet>");
+        for (String prop : props.keySet()) {
+          if (props.get(prop)!=null) {
+            annot.println("<feature name =\""+encodeXMLTexte(prop)+"\">"
+                    +encodeXMLTexte(props.get(prop))+"</feature>");
+          }
+        }
+        annot.println("</featureSet>");
+
+      }
+      annot.println("</characterisation>");
+    }
+    private void ecrirePos(int deb, int fin) {
+      annot.println("<positioning>");
+      annot.println("<start>");
+      annot.println("<singlePosition index = \""+deb+"\"/>");
+      annot.println("</start>");
+      annot.println("<end>");
+      annot.println("<singlePosition index = \""+fin+"\"/>");
+      annot.println("</end>");
+      annot.println("</positioning>");
+    }
+    private void ecrireRel(Element elt1, Element elt2) {
+      annot.println("<positioning>");
+      annot.println("<term id = \""+getId(elt1)+"\"/>");
+      annot.println("<term id = \""+getId(elt2)+"\"/>");
+      annot.println("</positioning>");
+    }
+    private void ecrireSch(HashSet<Element> elts) {
+      annot.println("<positioning>");
+      for (Element elt : elts) {
+        Class classe = elt.getClass();
+        if (classe==Unite.class) {
+          annot.print("<embedded-unit ");
+        }
+        if (classe==Relation.class) {
+          annot.print("<embedded-relation ");
+        }
+        if (classe==Schema.class) {
+          annot.print("<embedded-schema ");
+        }
+        annot.println("id = \""+getId(elt)+"\"/>");
+      }
+      annot.println("</positioning>");
+    }
+  }
+
+  static class ModelGlozzPrinter {
+    Structure structure;
+    PrintWriter model;
+    ModelGlozzPrinter(Structure structure, PrintWriter model) {
+      this.structure = structure;
+      this.model = model;
+    }
+    void ecrireModel() {
+      model.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
+      model.println("<annotationModel>");
+      ecrireUnites();
+      ecrireRelations();
+      ecrireSchemas();
+      model.println("</annotationModel>");
+    }
+    private void ecrireUnites() {
+      model.println("<units>");
+      for (String type : structure.getTypes(Unite.class))
+        ecrireType(Unite.class, type);
+      model.println("</units>");
+    }
+    private void ecrireRelations() {
+      model.println("<relations>");
+      for (String type : structure.getTypes(Relation.class))
+        ecrireType(Relation.class, type);
+      model.println("</relations>");
+    }
+    private void ecrireSchemas() {
+      model.println("<schemas>");
+      for (String type : structure.getTypes(Schema.class))
+        ecrireType(Schema.class, type);
+      model.println("</schemas>");
+    }
+    private void ecrireType(Class<? extends Element> classe, String type) {
+      model.print("<type name=\""+encodeXMLTexte(type)+"\"");
+      if (classe==Relation.class) model.print(" oriented=\"true\"");
+      model.println(">");
+      model.println("<featureSet>");
+      for (String prop : structure.getNomsProps(classe, type))
+        ecrireProp(classe, type, prop);
+      model.println("</featureSet>");
+      model.println("</type>");
+    }
+    private void ecrireProp(Class<? extends Element> classe, String type, String prop) {
+      model.println("<feature name=\""+encodeXMLTexte(prop)+"\">");
+      if (structure.getValeursProp(classe, type, prop).isEmpty()) {
+        model.println("<value type=\"free\" default=\"\" />");
+      } else {
+        model.println("<possibleValues default = \""
+                +structure.getValeurParDefaut(classe, type, prop)+"\">");
+        for (String val : structure.getValeursProp(classe, type, prop))
+          model.println("<value>"+encodeXMLTexte(val)+"</value>");
+        model.println("</possibleValues>");
+      }
+      model.println("</feature>");
+
+    }
+  }
+  static String encodeXMLTexte(String ch) {
+//    return ch;
+    return ch.replaceAll("&", "&amp;").replaceAll("<", "&lt;").
+            replaceAll(">", "&gt;").replaceAll("\"", "&quot;").
+            replaceAll("\'", "&apos;");
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersGlozz.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersGraphique.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersGraphique.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersGraphique.java	(revision 481)
@@ -0,0 +1,216 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.awt.*;
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class FichiersGraphique {
+
+  public static class CercleColore {
+
+    public int cx, cy, r;
+    public Color couleur;
+  }
+
+  public static interface GraphiqueExport {
+
+    public Dimension initExport();
+
+    public Rectangle getCadre();
+
+    public CercleColore[] getCerclesColores();
+  }
+
+  public static void exporterGraphiqueSVG(GraphiqueExport donnees) {
+    PrintWriter sortie = null;
+    File fichierGraphique;
+    if ((fichierGraphique = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier ?", Fichiers.TypeFichier.GRAPHIQUE_SVG)) == null) return;
+    try {
+      sortie = new PrintWriter(fichierGraphique, "UTF-8");
+      ecrireSVG(sortie, donnees);
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier",
+              JOptionPane.ERROR_MESSAGE);
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier",
+              JOptionPane.ERROR_MESSAGE);
+    } finally {
+      if (sortie != null) sortie.close();
+    }
+  }
+  
+   public static void exporterGChaineSVG(String fichier) {
+    PrintWriter sortie = null;
+    File fichierGraphique;
+    if ((fichierGraphique = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier ?", Fichiers.TypeFichier.GRAPHIQUE_SVG)) == null) return;
+    try {
+      sortie = new PrintWriter(fichierGraphique, "UTF-8");
+      sortie.println(fichier);
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier",
+              JOptionPane.ERROR_MESSAGE);
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier",
+              JOptionPane.ERROR_MESSAGE);
+    } finally {
+      if (sortie != null) sortie.close();
+    }
+  }
+  
+
+  public static void ecrireSVG(PrintWriter sortie, GraphiqueExport donnees) {
+    sortie.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+    sortie.println("<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"");
+    Dimension dim = donnees.initExport();
+    sortie.println("x=\"0px\" y=\"0px\" width=\"" + dim.width
+            + "px\" height=\"" + dim.height + "px\">");
+    Rectangle cadre = donnees.getCadre();
+    if (cadre != null)
+      sortie.println("<rect x=\"" + cadre.x + "\" y=\"" + cadre.y
+              + "\" fill=\"none\" stroke=\"#000000\" width=\"" + cadre.width
+              + "\" height=\"" + cadre.height + "\"/>");
+    CercleColore[] cercles = donnees.getCerclesColores();
+    for (CercleColore cercle : cercles)
+      sortie.println("<ellipse cx=\"" + cercle.cx + "\" cy=\""
+              + cercle.cy + "\" fill=\"" + ecritCouleurSVG(cercle.couleur)
+              + "\" stroke=\"#000000\" rx=\"" + cercle.r
+              + "\" ry=\"" + cercle.r + "\"/>");
+
+    sortie.println("</svg>");
+  }
+  
+
+  private static String ecritCouleurSVG(Color c) {
+    String res = "#";
+    res += Integer.toHexString(c.getRGB()).substring(2);
+    return res;
+  }
+
+  public static void exporterGraphiqueEMF(GraphiqueExport donnees) {
+    FileChannel canal = null;
+    FileOutputStream sortie = null;
+    File fichierGraphique;
+    if ((fichierGraphique = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier ?", Fichiers.TypeFichier.GRAPHIQUE_EMF)) == null) return;
+    try {
+      sortie = new FileOutputStream(fichierGraphique);
+      canal = sortie.getChannel();
+      ByteBuffer buff = ecrireEMF(donnees);
+      canal.write(buff);
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier",
+              JOptionPane.ERROR_MESSAGE);
+    } finally {
+      if (canal != null)
+        try {
+          canal.close();
+        } catch (IOException ex) {
+          JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier",
+                  JOptionPane.ERROR_MESSAGE);
+        }
+      if (sortie != null)
+        try {
+          sortie.close();
+        } catch (IOException ex) {
+          JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier",
+                  JOptionPane.ERROR_MESSAGE);
+        }
+    }
+  }
+
+  private static ByteBuffer ecrireEMF(GraphiqueExport donnees) {
+    ArrayList<Integer> dessin = new ArrayList<Integer>();
+        Dimension dim = donnees.initExport();
+    int nbrecords = 0;
+    dessin.add(1); // header
+    dessin.add(88); // taille du header 
+    dessin.addAll(Arrays.asList(0, 0, dim.width, dim.height)); 
+                                                   // taille du graphique en px 
+    dessin.addAll(Arrays.asList(0, 0, dim.width*32, dim.height*32)); 
+                                                  // taille en 0.01 mm (px * 32)
+    dessin.add(0x464D4520); // signature (" EMF" à l'endroit!!) 
+    dessin.add(0x00010000); // version 
+    int indTailles = dessin.size();  // endroit où mettre les tailles 
+    dessin.addAll(Arrays.asList(0, 0)); // taille du fichier, nb records : remplis à la fin
+    dessin.add(2); // nbobjs : pen et brush
+    dessin.addAll(Arrays.asList(0, 0));   //taille et offset de la description
+    dessin.add(0); // nb d'entrees de palette 
+    dessin.addAll(Arrays.asList(1024, 768, 320, 240)); // taille du device en px et en mm
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x11, 0xC, 0x8));  // mapmode : 0x8 (anisotropique)
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x12, 0xC, 0x1));  // bkmode : 0x1 (transparent)
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0xA, 0x10, 0, 0));  // setWindowOrgEx: 0,0
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0xC, 0x10, 0, 0));  // setViewPortOrgEx: 0,0
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x9, 0x10, dim.width, dim.height));  // setWindowExtEx
+    nbrecords++; // setWindowExtEx: 0,0
+    dessin.addAll(Arrays.asList(0xB, 0x10, dim.width, dim.height));  // setViewPortExtEx
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x27, 0x18, 1, 1, 0, 0));  // createBrushIndirect : 
+    nbrecords++;                                        //1 (NoObj) 1 (BS_NULL) 0 0
+    dessin.addAll(Arrays.asList(0x25, 0xC, 1));  // selectObject 1
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x5F, 0x34, 2, 0, 0, 0, 0, 0x12200, 0x4, 0, 0, 0, 0));
+    // extCreatePen : 2 (NoObj) 0 0 0 0 (absence de DIB) 
+    // 0x12200 (PS_GEOMETRIC, JOIN_MITER, ENDCAP_FLAT) 
+    // 0x4 (largeur) 0 (BS_NULL) 0 (Color) 0 (BrushHatch) 0 (numStyleEntries)     
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x25, 0xC, 2));  // selectObject 2
+    nbrecords++;
+      Rectangle cadre = donnees.getCadre();
+    if (cadre != null) {
+  
+    dessin.addAll(Arrays.asList(0x2B, 0x18, cadre.x, cadre.y, 
+            cadre.x+cadre.width, cadre.y+cadre.height));  //  Rectangle
+    nbrecords++;
+    }
+ CercleColore[] cercles = donnees.getCerclesColores();
+   for (CercleColore cercle : cercles) {
+//      sortie.println("<ellipse cx=\"" + cercle.cx + "\" cy=\""
+//              + cercle.cy + "\" fill=\"" + ecritCouleurSVG(cercle.couleur)
+//              + "\" stroke=\"#000000\" rx=\"" + cercle.r
+//              + "\" ry=\"" + cercle.r + "\"/>");
+    dessin.addAll(Arrays.asList(0x28, 0xC, 1));  // deleteObject 1
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x27, 0x18, 1, 0, ecritCouleurEMF(cercle.couleur), 0));  
+    nbrecords++;      // createBrushIndirect : 1 (NoObj) 0 (BS_SOLID) Color (0BGR) 0
+    dessin.addAll(Arrays.asList(0x25, 0xC, 1));  // selectObject 1
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x2A, 0x18, cercle.cx-cercle.r, cercle.cy-cercle.r,
+            cercle.cx+cercle.r, cercle.cy+cercle.r));  //  Ellipse
+    nbrecords++;
+   }
+    dessin.addAll(Arrays.asList(0xE, 0x14, 0, 0, 0x14));  //  EOF 0xE 
+    nbrecords++;                                      //+ taille (20?) et offset palette
+    dessin.set(indTailles++, dessin.size() * 4);
+    dessin.set(indTailles, nbrecords);
+    ByteBuffer buff = ByteBuffer.allocate(dessin.size() * 4).order(ByteOrder.LITTLE_ENDIAN);
+    buff.clear();
+    for (int n : dessin) buff.putInt(n);
+    buff.flip();
+    return buff;
+  }
+    private static int ecritCouleurEMF(Color c) {
+    return c.getRed() | (c.getGreen()<<8) | (c.getBlue()<<16);
+  }
+
+
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersGraphique.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersCoNLL.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersCoNLL.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersCoNLL.java	(revision 481)
@@ -0,0 +1,212 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public abstract class FichiersCoNLL {
+  static final String TYPE_UNITES = "Token";
+  static final String TYPE_RELATION = "Dependency";
+  static final String TYPE_RELATION_PROJ = "Projective Dependency";
+  static final String PROP_LEMME = "Lemma";
+  static final String PROP_C_POS = "C-POS";
+  static final String PROP_POS = "POS";
+  static final String PROP_TRAITS = "Features";
+  static final String PROP_REL = "Function";
+  public static void importerCoNLL(Corpus corpus) {
+    BufferedReader in = null;
+    File ficCoNLL;
+    GCodage codage = new GCodage();
+    if ((ficCoNLL = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix du fichier CoNLL", TypeFichier.CONLL))==null)
+      return;
+    try {
+      in = new BufferedReader(new InputStreamReader(
+              new FileInputStream(ficCoNLL), "UTF-8"));
+      CoNLLParser parseur = new CoNLLParser(corpus);
+      parseur.parser(in);
+      corpus.newCorpusLu();
+    } catch (IOException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      try {
+        if (in!=null) in.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
+      }
+    }
+  }
+
+  static class CoNLLParser {
+    private Corpus corpus;
+    private String texte="";
+    private ArrayList<String> noHeads = new ArrayList<String>();
+    private ArrayList<String> depRels = new ArrayList<String>();
+    private ArrayList<String> noPHeads = new ArrayList<String>();
+    private ArrayList<String> pDepRels = new ArrayList<String>();
+    private ArrayList<Unite> units = new ArrayList<Unite>();
+    private HashMap<String, Integer> noTokenUnits = new HashMap<String, Integer>();
+    CoNLLParser(Corpus corpus) {
+      this.corpus = corpus;
+    }
+    private void parser(BufferedReader in) throws IOException {
+      String ligne;
+      int noligne = 0;
+      while (true) {
+        ligne = in.readLine();
+        if (ligne==null) {
+          finDocument(noligne);
+          break;
+        }
+        noligne++;
+        if (ligne.trim().isEmpty()) finPhrase(noligne);
+        else parserToken(ligne, noligne);
+      }
+    }
+    private void parserToken(String ligne, int noligne) throws IOException {
+      String ch;
+      String[] items = ligne.split("\\t");
+      if (items.length!=10)
+        throw new CoNLLException("Nombre de colonnes incorrect ("
+                +items.length+")", noligne);
+      Unite unit = new Unite();
+      unit.setType(TYPE_UNITES);
+      units.add(unit);
+      // champ ID
+      ch = items[0].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de numéro de token", noligne);
+      noTokenUnits.put(ch, units.size()-1);
+      // champ FORM
+      ch = items[1].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de token", noligne);
+      if (isPonct1(ch)) texte = texte.trim();
+      unit.setDeb(texte.length());
+      texte += ch;
+      unit.setFin(texte.length());
+      if (!isPonct2(ch)) texte += " ";
+      // champ LEMMA    
+      ch = items[2].replace('_', ' ').trim();
+      if (!ch.isEmpty())
+        unit.putProp(PROP_LEMME, ch);
+      // champ CPOSTAG
+      ch = items[3].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de C-POS", noligne);
+      unit.putProp(PROP_C_POS, ch);
+      // champ POSTAG
+      ch = items[4].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de POS", noligne);
+      unit.putProp(PROP_POS, ch);
+      // champ FEATS
+      ch = items[5].replace('_', ' ').trim();
+      if (!ch.isEmpty()) {
+        String[] chs = ch.split("\\|");
+        String traits = "";
+        for (String trait : chs) {
+          String[] attval = trait.split("=");
+          if (attval.length==2)
+            unit.putProp(attval[0].trim(), attval[1].trim());
+          else {
+            if (!traits.isEmpty()) traits += '|';
+            traits += trait;
+          }
+        }
+        if (!traits.isEmpty())
+          unit.putProp(PROP_TRAITS, traits);
+      }
+      // champ HEAD
+      ch = items[6].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de HEAD", noligne);
+      noHeads.add(ch);
+      // champ DEPREL
+      ch = items[7].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de DEP-REL", noligne);
+      depRels.add(ch);
+      // champ PHEAD
+      ch = items[8].replace('_', ' ').trim();
+      noPHeads.add(ch);
+      // champ PDEPREL
+      ch = items[9].replace('_', ' ').trim();
+      pDepRels.add(ch);
+    }
+    static private boolean isPonct1(String ch) {
+      if (ch.length()!=1) return false;
+      return ".,;:)]}!?'".contains(ch);
+    }
+    static private boolean isPonct2(String ch) {
+      if (ch.length()!=1) return false;
+      return "([{'".contains(ch);
+    }
+    private void finPhrase(int noligne) throws CoNLLException {
+      for (Unite unit : units) corpus.addUniteLue(unit);
+      for (int i = 0; i<units.size(); i++) {
+        Unite unit = units.get(i);
+        String nohead = noHeads.get(i);
+        String deprel = depRels.get(i);
+        if (!nohead.equals("0")) {
+          Integer k = noTokenUnits.get(nohead);
+          if (k==null)
+            throw new CoNLLException("Erreur de numéro de token de HEAD : "
+                    +nohead+" sur l'une des lignes précédentes", noligne);
+          Relation rel = new Relation(TYPE_RELATION, units.get(i), units.get(k));
+          if (deprel.isEmpty())
+            throw new CoNLLException("Pas trouvé de DEP-REL"
+                    +" sur l'une des lignes précédentes", noligne);
+          rel.putProp(PROP_REL, deprel);
+          corpus.addRelationLue(rel);
+          nohead = noPHeads.get(i);
+          deprel = pDepRels.get(i);
+          if (!nohead.isEmpty()&&!nohead.equals("0")) {
+            k = noTokenUnits.get(nohead);
+            if (k==null)
+              throw new CoNLLException("Erreur de numéro de token de P-HEAD : "
+                      +nohead+" sur l'une des lignes précédentes", noligne);
+            rel = new Relation(TYPE_RELATION_PROJ, units.get(i), units.get(k));
+            if (deprel.isEmpty())
+              throw new CoNLLException("Pas trouvé de P-DEP-REL"
+                      +" sur l'une des lignes précédentes", noligne);
+            rel.putProp(PROP_REL, deprel);
+            corpus.addRelationLue(rel);
+          }
+        }
+      }
+      units.clear();
+      noTokenUnits.clear();
+      noHeads.clear();
+      depRels.clear();
+      noPHeads.clear();
+      pDepRels.clear();
+    }
+    private void finDocument(int noligne) throws IOException {
+      finPhrase(noligne);
+      texte = texte.trim();
+      corpus.setTexte(texte);
+      corpus.addFinParagraphe(texte.length());
+    }
+
+    static class CoNLLException extends IOException {
+      public CoNLLException(String ex, int noligne) {
+        super("Erreur de syntaxe ligne "+noligne+" :\n"+ex);
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersCoNLL.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTexte.java	(revision 481)
@@ -0,0 +1,304 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.awt.*;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.text.rtf.*;
+import visuAnalec.PanneauEditeur;
+import visuAnalec.donnees.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public abstract class FichiersTexte {
+  public static void importerTexte(Corpus corpus) {
+    BufferedReader fluxIn = null;
+    File fichier;
+    GCodage codage = new GCodage();
+    if ((fichier = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix du corpus", Fichiers.TypeFichier.TEXTE, codage.getContenant())) == null) return;
+    String code = codage.getCode();
+    try {
+      fluxIn = new BufferedReader(new InputStreamReader(new FileInputStream(fichier), code));
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, "Codage de caractères non pris en charge : " + code,
+              "Erreur d'ouverture de fichier texte", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'ouverture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    }
+    try {
+      corpus.lireTexte(fluxIn);
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      try {
+        if (fluxIn != null) fluxIn.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+        return;
+      }
+    }
+  }
+  
+  /*ecrit simplement une chaine de caractère au dans un fichier csv*/
+     public static void exporterCSV(String fichier) {
+    PrintWriter sortie = null;
+    File fichierGraphique;
+    if ((fichierGraphique = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier ?", Fichiers.TypeFichier.DONNEES_CSV)) == null) return;
+    try {
+      sortie = new PrintWriter(fichierGraphique, "UTF-8");
+      sortie.println(fichier);
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier",
+              JOptionPane.ERROR_MESSAGE);
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier",
+              JOptionPane.ERROR_MESSAGE);
+    } finally {
+      if (sortie != null) sortie.close();
+    }
+  }
+  
+  public static void exporterTexteRTF(PanneauEditeur pEditeur) {
+    FileOutputStream fluxOut = null;
+    FiltreCorrectionRTFOutputStream filtre = null;
+    File fichierCorpus;
+    if ((fichierCorpus = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier texte", Fichiers.TypeFichier.TEXTE_RTF)) == null) return;
+    try {
+      fluxOut = new FileOutputStream(fichierCorpus);
+      filtre = new FiltreCorrectionRTFOutputStream(fluxOut);
+      Document doc = pEditeur.getTexteFormate();
+      RTFEditorKit editeur = new RTFEditorKit();
+      editeur.write(filtre, doc, 0, doc.getLength());
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (BadLocationException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      if (fluxOut != null) try {
+          fluxOut.close();
+        } catch (IOException ex) {
+          JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+  }
+
+  private static class FiltreCorrectionRTFOutputStream extends FilterOutputStream {
+    // Note: Windows versions of Word have never supported \cbN, 
+    //but it can be emulated by the control word sequence 
+    // \chshdng0\chcbpatN.
+    private final static char[] CodeCouleurFondcorrect = "\\chshdng0\\chcbpat".toCharArray();
+    private final static char[] CodeUnicodecorrect = "\\'".toCharArray();
+    private int etat;
+    private int[] buffer;
+    private int pt = 0;
+    private FiltreCorrectionRTFOutputStream(OutputStream out) {
+      super(out);
+      pt = etat = 0;
+      buffer = new int[10];
+    }
+    @Override
+    public void write(int car) throws IOException {
+      switch (etat) {
+        case 0:
+          if (car == '\\') {
+            buffer[pt++] = car;
+            etat = 1;
+          } else out.write(car);
+          return;
+        case 1:
+          if (car == 'c') {  // debut d'une couleur de fond : etats 2, 3, 4
+            buffer[pt++] = car;
+            etat = 2;
+          } else if (car == 'u') {  // début d'un caractère unicode non décodé : etats 5, 6
+            buffer[pt++] = car;
+            etat = 5;
+          } else raz(car);
+          return;
+        case 2:
+          if (car == 'b') {
+            buffer[pt++] = car;
+            etat = 3;
+
+          } else raz(car);
+          return;
+        case 3:
+          if (car >= '0' && car <= '9') {
+            buffer[pt++] = car;
+            etat = 4;
+          } else raz(car);
+          return;
+        case 4:
+          if (car >= '0' && car <= '9') buffer[pt++] = car;
+          else correctionCouleurFond(car);
+          return;
+        case 5:
+          if (car >= '0' && car <= '9') {
+            buffer[pt++] = car;
+            etat = 6;
+          } else raz(car);
+          return;
+        case 6:
+          if (car >= '0' && car <= '9') buffer[pt++] = car;
+          else if (car == ' ') etat = 7;
+          else raz(car);
+          return;
+        case 7:
+          if (car == '?') correctionUnicode();
+          else raz(car);
+          return;
+        default:
+          throw new UnsupportedOperationException("Etat " + etat + " non prévu");
+      }
+    }
+    private void raz(int b) throws IOException {
+      for (int pt0 = 0; pt0 < pt; pt0++) out.write(buffer[pt0]);
+      pt = etat = 0;
+      write(b);
+    }
+    private void correctionCouleurFond(int b) throws IOException {
+      for (int c : CodeCouleurFondcorrect) out.write(c);
+      for (int pt0 = 3; pt0 < pt; pt0++) out.write(buffer[pt0]);
+      pt = etat = 0;
+      write(b);
+    }
+    private void correctionUnicode() throws IOException {
+      for (int c : CodeUnicodecorrect) out.write(c);
+      int n = 0;
+      for (int pt0 = 2; pt0 < pt; pt0++) n = 10 * n + (buffer[pt0] - '0');
+      String nhex = Integer.toHexString(n % 256);
+      if (nhex.length() == 1) out.write('0');
+      out.write(nhex.charAt(0));
+      if (nhex.length() == 2) out.write(nhex.charAt(1));
+      pt = etat = 0;
+    }
+  }
+  public static void exporterTexteHTML(PanneauEditeur pEditeur) {
+    FileWriter fluxOut = null;
+//   FiltreCorrectionRTFOutputStream filtre = null;
+    File fichierCorpus;
+    if ((fichierCorpus = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier texte", Fichiers.TypeFichier.TEXTE_HTML)) == null) return;
+    try {
+      fluxOut = new FileWriter(fichierCorpus);
+      Document doc = pEditeur.getTexteFormate();
+      HTMLWriterCorrige htmlWriter = new HTMLWriterCorrige(fluxOut, (StyledDocument) doc);
+      htmlWriter.write();
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (BadLocationException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'encodage de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      if (fluxOut != null)
+        try {
+          fluxOut.close();
+        } catch (IOException ex) {
+          JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+  }
+
+  private static class HTMLWriterCorrige extends AbstractWriter {
+    public HTMLWriterCorrige(Writer w, StyledDocument doc) {
+      super(w, doc);
+    }
+    @Override
+    protected void write() throws IOException, BadLocationException {
+      write("<html>\n");
+      ElementIterator it = getElementIterator();
+      Element elt;
+      it.first();  // le premier (la racine) n'a pas l'info intéressante)
+      if((elt = it.next()) != null) writeTagBody(elt.getAttributes());
+      while(elt!=null) {
+        if (elt.isLeaf()) {
+          writeSpan(elt.getAttributes(), getText(elt));
+        }
+        elt = it.next();
+      }       
+      write("</body>\n");
+      write("</html>\n");
+    }
+    private void writeTagBody(AttributeSet attr) throws IOException {
+      write("<body style=\" ");
+      write("font-family: " + StyleConstants.getFontFamily(attr));
+      write("; font-size: " + StyleConstants.getFontSize(attr) + "pt");
+      write("; font-style: " + (StyleConstants.isItalic(attr) ? "italic" : "normal"));
+      write("; font-weight: " + (StyleConstants.isBold(attr) ? "bold" : "normal"));
+      write("; text-decoration: " + (StyleConstants.isUnderline(attr) ? "underline" : "none"));
+      write("; color: ");
+      writeColor(StyleConstants.getForeground(attr));
+      write("; background-color: ");
+      writeColor(StyleConstants.getBackground(attr));
+      write("\">\n");
+    }
+    private void writeSpan(AttributeSet attr, String texte) throws IOException {
+      write("<span style=\" ");
+      write("; font-style: " + (StyleConstants.isItalic(attr) ? "italic" : ""));
+      write("; font-weight: " + (StyleConstants.isBold(attr) ? "bold" : ""));
+      write("; text-decoration: " + (StyleConstants.isUnderline(attr) ? "underline" : ""));
+      write("; color: ");
+      writeColor(StyleConstants.getForeground(attr));
+      write("; background-color: ");
+      writeColor(StyleConstants.getBackground(attr));
+      write("\">");
+      for(int i=0; i<texte.length(); i++) writeCar(texte.charAt(i));
+      write("</span>\n");
+    }
+    private void writeColor(Color couleur) throws IOException {
+      write('#');
+      String str = Integer.toHexString(couleur.getRed() % 256);
+      if (str.length() == 1) write('0');
+      write(str.charAt(0));
+      if (str.length() == 2) write(str.charAt(1));
+      str = Integer.toHexString(couleur.getGreen() % 256);
+      if (str.length() == 1) write('0');
+      write(str.charAt(0));
+      if (str.length() == 2) write(str.charAt(1));
+      str = Integer.toHexString(couleur.getBlue() % 256);
+      if (str.length() == 1) write('0');
+      write(str.charAt(0));
+      if (str.length() == 2) write(str.charAt(1));
+    }
+
+  private void writeCar(char car) throws IOException {
+    switch(car) {
+      case '\n': write("<p>"); return;
+      case '"': write("&quot;");return;
+      case'<': write("&lt;");return;
+      case'>': write("&gt;");return;
+      default:
+        if(car>128) write("&#"+(car%256)+";");
+        else write(car);
+    }   
+   }   
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersSyntex.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersSyntex.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersSyntex.java	(revision 481)
@@ -0,0 +1,152 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class FichiersSyntex {
+  public static void importerSyntex(Corpus corpus) {
+    BufferedReader analyse = null;
+    File fichierCorpus;
+    GCodage codage = new GCodage();
+    if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR, "Choix du fichier de résultats d'analyse syntaxique",
+            Fichiers.TypeFichier.SYNTEX, codage.getContenant())) == null) return;
+    String code = codage.getCode();
+    int cadence = 1; 
+    try {
+      analyse = new BufferedReader(new InputStreamReader(new FileInputStream(fichierCorpus), code));
+      SyntexParser sp = new SyntexParser(corpus);
+      sp.parser(analyse, cadence);
+      corpus.newCorpusLu();
+    } catch (IOException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      try {
+        if (analyse != null) analyse.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
+      }
+    }
+  }
+
+  static class SyntexParser {
+    Corpus corpus;
+    String texte;
+    SyntexParser(Corpus corpus) {
+      this.corpus = corpus;
+      texte = "";
+    }
+    private void parser(BufferedReader anasynt, int cadence) throws IOException {
+      String ligne;
+      int natLigne = 0;
+      int nophr = 0;
+      Schema phr = null;
+      String txt = null;
+      while ((ligne = anasynt.readLine()) != null) {
+        if (ligne.trim().isEmpty()) continue;
+        switch (natLigne) {
+          case 0:
+            phr = parserSEQ(ligne);
+            break;
+          case 1:
+            txt = parserTXT(ligne);
+            texte += txt;
+            corpus.addFinParagraphe(texte.length());
+            break;
+          case 2:
+            if (++nophr % cadence == 0) {
+              parserETIQ(ligne, phr, texte.length() - txt.length());
+            }
+            break;
+        }
+        natLigne = ++natLigne % 3;
+      }
+      if (natLigne > 0) throw new IOException("Fin de fichier prématurée");
+      corpus.setTexte(texte);
+    }
+    private Schema parserSEQ(String ligne) throws IOException {
+      if (!ligne.startsWith("<SEQ id=")) throw new IOException("SEQ attendu ligne :\n" + ligne);
+      Schema phr = new Schema("Phrase");
+      phr.putProp("id", ligne.substring(8, ligne.indexOf(';')));
+      return phr;
+    }
+    private String parserTXT(String ligne) throws IOException {
+      if (!ligne.startsWith("<TXT>")) throw new IOException("TXT attendu ligne :\n" + ligne);
+      return supBlancs(ligne.substring(5));
+    }
+    private String supBlancs(String txt) {
+      return txt.replaceAll("([\\'\\(\\-\\{\\[]) ", "$1").replaceAll(" ([\\.\\,\\-\\)\\%\\}\\]])", "$1");
+    }
+    private void parserETIQ(String ligne, Schema phr, int offset) throws IOException {
+      if (!ligne.startsWith("<ETIQ>")) throw new IOException("ETIQ attendu ligne :\n" + ligne);
+      String[] etiqs = ligne.substring(6).split("\t");
+      Unite[] units = new Unite[etiqs.length];
+      for (int i = 0; i < units.length; i++) units[i] = new Unite();
+      ArrayList<Relation> rels = new ArrayList<Relation>();
+      for (int i = 0; i < units.length; i++) {
+        String[] data = etiqs[i].split("\\|", -1);
+        if (data.length < 5) throw new IOException("Nombre de champs insuffisant pour " + etiqs[i]);
+        if (Integer.parseInt(data[3]) != i + 1) throw new IOException("Problème de numérotation pour " + etiqs[i]);
+        data[2] = supBlancs(data[2]);
+        while (texte.charAt(offset) == ' ') offset++;
+        if (!texte.startsWith(data[2], offset)) throw new IOException("Attendu : " + data[2] +
+                  " au début de la chaîne\n" + texte.substring(offset));
+        units[i].setType(typeSyntex(data[0]));
+        units[i].setDeb(offset);
+        units[i].setFin(offset += data[2].length());
+        units[i].putProp("Catégorie Syntex", data[0]);
+        units[i].putProp("Lemme", data[1]);
+        if (data[4].isEmpty()) continue;
+        String[] ascs = data[4].split(",");
+        for (String asc : ascs) {
+          String[] dataAsc = asc.split(";");
+          int noAsc = Integer.parseInt(dataAsc[1]);
+          if (noAsc <= 0 || noAsc > units.length)
+            throw new IOException("Problème de numérotation pour l'ascendant de " + etiqs[i]);
+          Relation rel = new Relation("Dépendance", units[i], units[noAsc - 1]);
+          rel.putProp("Fonction syntex", dataAsc[0]);
+          rels.add(rel);
+        }
+      }
+      for (Unite unit : units) {
+        corpus.addUniteLue(unit);
+        phr.ajouter(unit);
+      }
+      for (Relation rel : rels) {  
+        corpus.addRelationLue(rel);
+        phr.ajouter(rel);
+      }
+      corpus.addSchemaLu(phr);
+    }
+    private String typeSyntex(String catSyntex) throws IOException {
+      if (catSyntex.startsWith("Adj")) return "Adjectif";
+      if (catSyntex.startsWith("Adv")) return "Adverbe";
+      if (catSyntex.startsWith("CCoord") || catSyntex.startsWith("TypoCoord")) return "Coordonnant";
+      if (catSyntex.equals("CSub")) return "Subordonnant";
+      if (catSyntex.startsWith("Det")) return "Déterminant";
+      if (catSyntex.equals("Elim")) return "Interjection";
+      if (catSyntex.startsWith("Nom") || catSyntex.equals("NUM")) return "Nom";
+      if (catSyntex.startsWith("Pp") || catSyntex.startsWith("V")) return "Verbe";
+      if (catSyntex.startsWith("Prep")) return "Préposition";
+      if (catSyntex.equals("Pro")) return "Pronom";
+      if (catSyntex.equals("ProRel")) return "Relatif";
+      if (catSyntex.equals("Typo")) return "Ponctuation";
+      throw new IOException("Catégorie syntex non reconnue : " + catSyntex);
+    }
+  }
+}
+  

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersSyntex.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/util/Fichiers.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/util/Fichiers.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/util/Fichiers.java	(revision 481)
@@ -0,0 +1,331 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.util;
+
+import java.awt.*;
+import java.beans.*;
+import java.io.*;
+import java.util.*;
+import java.util.prefs.Preferences;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.filechooser.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public abstract class Fichiers {
+  public enum TypeFichier {
+    DOC_ANALEC("Document Analec", "ec"),
+    VUE_CHAINE("Paramètre affiche des schémas Analec", "xml"),
+    CORPUS_ANALEC("Fichiers Analec", "ec"),
+    STRUCTURE("Structure Analec", "ecs"),
+    VUE("Vue Analec", "ecv"),
+    PDF("fichier pdf", "pdf"),    
+    TABLEUR_STATS("Tableur format texte (séparateur : tabulation)", "txt"),
+    GRAPHIQUE_SVG("Graphique vectoriel format svg", "svg"),
+    GRAPHIQUE_EMF("Graphique vectoriel format emf", "emf"),
+    GLOZZ_CORPUS("Corpus Glozz", "ac"),
+    GLOZZ_ANNOT("Annotations Glozz", "aa"),
+    GLOZZ_MODELE("Modèle Glozz", "aam"),
+    SYNTEX("Résultats Syntex", "anasynt"),
+    TABLEUR_ENONCES("Table des énoncés", "txt"),
+    TABLEUR_ANNOT("Table des annotations", "txt"),
+    TEI("Corpus format TEI", "xml"),
+    RHAPS("Corpus Rhapsodie format tabulaire", "tabular"),
+    CONLL("Document format CoNLL", "out"),
+    TEXTE("Texte brut", "txt"),
+    TEXTE_RTF("Texte format RTF", "rtf"),
+    TEXTE_HTML("Texte format HTML", "html"),
+    DONNEES_CSV("Format de base de données", "csv");
+    
+    String ext;
+    String nom;
+    TypeFichier(String nom, String ext) {
+      this.nom = nom;
+      this.ext = ext;
+    }
+    public String getNom() {
+      return nom;
+    }
+    public String getExtension() {
+      return ext;
+    }
+    public boolean importCorpus() {
+      return EnumSet.of(TypeFichier.TEXTE, TypeFichier.GLOZZ_CORPUS, TypeFichier.SYNTEX).contains(this);
+    }
+    public boolean resultats() {
+      return EnumSet.of(TypeFichier.TABLEUR_STATS, TypeFichier.GRAPHIQUE_SVG, TypeFichier.GRAPHIQUE_EMF).contains(this);
+    }
+  }
+
+  public enum Commande {
+    OUVRIR("Ouvrir"),
+    ENREGISTRER("Enregistrer");
+    String label;
+    Commande(String label) {
+      this.label = label;
+    }
+    public String getLabel() {
+      return label;
+    }
+  }
+
+  public static class FiltreExt implements java.io.FileFilter {
+    private TypeFichier type;
+    public FiltreExt(TypeFichier type) {
+      this.type = type;
+    }
+    public boolean accept(File fic) {
+      return type.getExtension().equals(getExtension(fic));
+    }
+  }
+  // Variables de classe
+  private static Preferences pref = Preferences.userNodeForPackage(Fichiers.class);
+  private static File repertoireCourantCorpus = new File(pref.get("repertoire", System.getProperty("user.dir")));
+  private static EnumMap<TypeFichier, File> fichiersCourants = new EnumMap<TypeFichier, File>(TypeFichier.class);
+  static {
+    String nomfic = pref.get("nomCorpus", "");
+    if (!nomfic.isEmpty())
+      fichiersCourants.put(TypeFichier.DOC_ANALEC, new File(repertoireCourantCorpus, nomfic+'.'+TypeFichier.DOC_ANALEC.getExtension()));
+  }
+  public static File trouverFichier(TypeFichier type, String nomFichier) {
+    File fichier = new File(repertoireCourantCorpus, nomFichier);
+    if (!getExtension(fichier).equals(type.getExtension()))
+      fichier = changerExtension(fichier, type.getExtension());
+    if (!fichier.exists()) return null;
+    majFichiersCourants(type, fichier);
+    return fichier;
+  }
+  public static File trouverFichier(TypeFichier type, File oldfichier) {
+    File fichier = changerExtension(oldfichier, type.getExtension());
+    if (!fichier.exists()) return null;
+    majFichiersCourants(type, fichier);
+    return fichier;
+  }
+  public static File creerFichier(File rep, TypeFichier type, File oldfichier) {
+    return ajouterExtension(new File(rep, extraireNom(oldfichier)), type.getExtension());
+  }
+  public static File creerFichier(File rep, TypeFichier type, String nom) {
+    return ajouterExtension(new File(rep, nom), type.getExtension());
+  }
+  public static File getRepertoireCourant(TypeFichier type) {
+    if (fichiersCourants.containsKey(type))
+      return fichiersCourants.get(type).getParentFile();
+    return repertoireCourantCorpus;
+  }
+  public static File getFichierCourant(TypeFichier type) {
+    if (fichiersCourants.containsKey(type)) return fichiersCourants.get(type);
+    return null;
+  }
+  public static String getNomFichierCourant(TypeFichier type) {
+    if (fichiersCourants.containsKey(type))
+      return extraireNom(fichiersCourants.get(type));
+    return "";
+  }
+  public static void removeFichierCourant(TypeFichier type) {
+    fichiersCourants.remove(type);
+  }
+  private static void majFichiersCourants(TypeFichier type, File fichier) {
+    fichiersCourants.put(type, fichier);
+    if (type==TypeFichier.GLOZZ_CORPUS) {
+      fichiersCourants.put(TypeFichier.GLOZZ_ANNOT, changerExtension(fichier, TypeFichier.GLOZZ_ANNOT.ext));
+      fichiersCourants.put(TypeFichier.GLOZZ_MODELE, changerExtension(fichier, TypeFichier.GLOZZ_MODELE.ext));
+    }
+    if (type==TypeFichier.DOC_ANALEC) {
+      repertoireCourantCorpus = fichier.getParentFile();
+      pref.put("repertoire", repertoireCourantCorpus.getPath());
+      pref.put("nomCorpus", extraireNom(fichier));
+    }
+
+  }
+  // Utilitaires de manipulation de noms de fichiers
+  private static File ajouterExtension(File fichier, String extension) {
+    String nom = fichier.getName();
+    return new File(fichier.getParentFile(), nom+"."+extension);
+  }
+  private static File changerExtension(File fichier, String extension) {
+    String nom = fichier.getName();
+    int ind = nom.lastIndexOf('.');
+    if (ind>=0) nom = nom.substring(0, ind);
+    return new File(fichier.getParentFile(), nom+"."+extension);
+  }
+  public static String extraireNom(File fichier) {
+    if (fichier==null) return null;
+    String nom = fichier.getName();
+    int ind = nom.lastIndexOf('.');
+    if (ind<0) return nom;
+    else return nom.substring(0, ind);
+  }
+  private static String getExtension(File fichier) {
+    String nom = fichier.getName();
+    int ind = nom.lastIndexOf('.');
+    if (ind>=0) return nom.substring(ind+1);
+    return "";
+  }
+  public static File[] listerFichiers(File rep, TypeFichier type) {
+    return rep.listFiles(new FiltreExt(type));
+  }
+  public static boolean existeDebutFichier(File rep, TypeFichier type, 
+          String debut) {
+    File[] fics = listerFichiers(rep, type);
+    for (int i = 0; i<fics.length; i++) 
+      if(extraireNom(fics[i]).startsWith(debut)) return true;
+    return false;
+  }
+  // Choix des fichiers
+  public static File choisirFichier(Commande commande, String titre, TypeFichier type) {
+    return choisirFichier(commande, titre, type, null);
+  }
+  public static File choisirFichier(Commande commande, String titre, TypeFichier type, JComponent complement) {
+    JFileChooser choixFichier = new JFileChooser();
+    choixFichier.resetChoosableFileFilters();
+    choixFichier.setFileFilter(new FileNameExtensionFilter(type.getNom(), type.getExtension()));
+    choixFichier.setDialogTitle(titre);
+    if (complement!=null) choixFichier.setAccessory(complement);
+    choixFichier.setCurrentDirectory(getRepertoireCourant(type));
+    File fichierPropose;
+    if (type.resultats()) {
+      String nom = extraireNom(getFichierCourant(TypeFichier.DOC_ANALEC));
+      if (nom==null) fichierPropose = null;
+      else fichierPropose = new File(getRepertoireCourant(type), nom+"_res");
+    } else {
+      fichierPropose = getFichierCourant(type);
+    }
+    if (fichierPropose!=null) {
+      if (commande==Commande.OUVRIR&&!fichierPropose.exists()) {
+        fichierPropose = new File(getRepertoireCourant(type), "*."+type.getExtension());
+      }
+      choixFichier.setSelectedFile(fichierPropose);
+    }
+    int reponse = choixFichier.showDialog(null, commande.getLabel());
+    if (reponse!=JFileChooser.APPROVE_OPTION) return null;
+    File fichierChoisi = choixFichier.getSelectedFile();
+    if (commande==Commande.ENREGISTRER) {
+      if (!getExtension(fichierChoisi).equals(type.getExtension()))
+        fichierChoisi = ajouterExtension(fichierChoisi, type.getExtension());
+      if (fichierChoisi.exists()) {
+        int rep = JOptionPane.showOptionDialog(null, "Remplacer "+fichierChoisi.getName()+" ?",
+                "Fichier existant", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+                null, new Object[]{"Remplacer", "Annuler"}, "Remplacer");
+        if (rep==1) return null;
+      }
+    }
+    majFichiersCourants(type, fichierChoisi);
+    if (commande==Commande.OUVRIR&&type.importCorpus())
+      fichiersCourants.remove(TypeFichier.DOC_ANALEC);
+    return fichierChoisi;
+  }
+  public static File choisirRepertoire(String titre) {
+    JFileChooser choixRep = new JFileChooser();
+    choixRep.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+    choixRep.setAcceptAllFileFilterUsed(false);
+    choixRep.setFileFilter(new FileNameExtensionFilter("Répertoire", "*"));
+    choixRep.setDialogTitle(titre);
+    choixRep.setCurrentDirectory(repertoireCourantCorpus);
+    int reponse = choixRep.showDialog(null, "Sélectionner");
+    if (reponse!=JFileChooser.APPROVE_OPTION) return null;
+    return choixRep.getSelectedFile();
+  }
+  public static File[] choisirCorpus(String titre, TypeFichier type) {
+    JFileChooser choixFichier = new JFileChooser();
+    FilesystemFilter filtre = new FilesystemFilter(type.getExtension(), "", false);
+    choixFichier.addPropertyChangeListener(new SelectFics(choixFichier, filtre));
+    choixFichier.resetChoosableFileFilters();
+    choixFichier.setFileFilter(new FileNameExtensionFilter(
+            type.getNom(), type.getExtension()));
+    choixFichier.setDialogTitle(titre);
+    choixFichier.setMultiSelectionEnabled(true);
+    File rep = getRepertoireCourant(type);
+    choixFichier.setCurrentDirectory(rep);
+    int reponse = choixFichier.showDialog(null, "Choisir");
+    if (reponse!=JFileChooser.APPROVE_OPTION) return new File[0];
+    File[] fics = choixFichier.getSelectedFiles();
+    if (fics==null||fics.length==0) return new File[0];
+    majFichiersCourants(TypeFichier.CORPUS_ANALEC, fics[0]);
+    return fics;
+  }
+
+  static class FilesystemFilter extends javax.swing.filechooser.FileFilter
+          implements FilenameFilter {
+    private String[] extensions;
+    private String description;
+    private boolean accepteReps;
+    public FilesystemFilter(String extension, String description,
+            boolean accepteReps) {
+      this(new String[]{extension}, description, accepteReps);
+    }
+    public FilesystemFilter(String[] extensions, String description,
+            final boolean accepteReps) {
+      this.extensions = extensions;
+      this.description = description;
+      this.accepteReps = accepteReps;
+    }
+    public boolean accept(File rep, String nom) {
+      return accept(new File(rep, nom));
+    }
+    public boolean accept(final File fic) {
+      if (fic.isDirectory()&&accepteReps) return true;
+      for (int i = 0; i<this.extensions.length; i++)
+        if (fic.getName().endsWith(this.extensions[i])) return true;
+      return false;
+    }
+    public String getDescription() {
+      return this.description;
+    }
+ }
+ public static class SelectFics implements PropertyChangeListener{
+    JFileChooser choix;
+    FilesystemFilter filtre;
+    SelectFics(JFileChooser choix, FilesystemFilter filtre) {
+      this.choix = choix;
+      this.filtre = filtre;
+    }
+    @Override
+       public void propertyChange(PropertyChangeEvent e) {
+        if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(e.getPropertyName())) {
+           choix.setSelectedFiles(choix.getCurrentDirectory().listFiles(filtre));
+        }
+    }
+  }
+
+  public static class GCodage {
+    JPanel contenant;
+    JComboBox saisieCodage;
+    public GCodage() {
+      saisieCodage = new JComboBox(new String[]{
+                "Microsoft (windows-1252)",
+                "UTF-8 (unicode 8 bits)",
+                "UTF-16 (unicode 16 bits)",
+                "ISO-8859-1 (latin-1)",
+                "<autre (à saisir)>"
+              });
+      saisieCodage.setEditable(true);
+      saisieCodage.setSelectedIndex(0);
+      contenant = new JPanel(new BorderLayout());
+      contenant.setBorder(new TitledBorder("Codage des caractères"));
+      contenant.add(saisieCodage, BorderLayout.NORTH);
+      contenant.add(new JPanel(), BorderLayout.CENTER);
+    }
+    public JComponent getContenant() {
+      return contenant;
+    }
+    public String getCode() {
+      switch (saisieCodage.getSelectedIndex()) {
+        case 0:
+          return "windows-1252";
+        case 1:
+          return "UTF-8";
+        case 2:
+          return "UTF-16";
+        case 3:
+          return "ISO-8859-1";
+        default:
+          return (String) saisieCodage.getSelectedItem();
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/util/Fichiers.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/util/GVisu.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/util/GVisu.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/util/GVisu.java	(revision 481)
@@ -0,0 +1,1146 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.util;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.ArrayList;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.GMessages.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public abstract class GVisu {
+  public static class TitreBarre extends JLabel {
+    public TitreBarre(String titre) {
+      super(titre);
+    }
+    public TitreBarre(String titre, Color couleur) {
+      super(titre);
+      setOpaque(true);
+      setBackground(couleur);
+    }
+  }
+
+  public static abstract class Boutons {
+    public static void setDefaut(JButton bouton, boolean oui) {
+      ((JFrame) bouton.getTopLevelAncestor()).getRootPane().setDefaultButton(oui ? bouton : null);
+      if (oui) bouton.requestFocusInWindow();
+    }
+  }
+  public static String styleIdPopup(String texte, String id) {
+    if (texte.length()>35)
+      texte = texte.substring(0, 18)+" [...] "+texte.substring(texte.length()-8);
+    return "<html>"+id+" (<span style=\"font-style:italic \">"+texte+"</span>)";
+  }
+  public static String styleIdTooltip(ArrayList<String> textes, ArrayList<String> ids) {
+    String tooltip = "<html>";
+    for (int i = 0; i<textes.size(); i++) {
+      String texte = textes.get(i);
+      if (texte.length()>35)
+        texte = texte.substring(0, 18)+" [...] "+texte.substring(texte.length()-8);
+      tooltip += "<p>"+ids.get(i)+" (<span style=\"font-style:italic \">"+texte+"</span>)";
+    }
+    return tooltip;
+  }
+  public static String styleDef(String nom) {
+    return "<html><span style=\"color:gray\"> &lt <span style=\"font-style:italic \">"
+            +nom+"</span> &gt";
+  }
+  private final static Font STYLE_COMBO = Font.decode("Arial plain 12");
+
+  public enum SensSpinnerBinaire {
+    SUIVANT, PRECEDENT
+  }
+
+  public static class ModeleSpinnerBinaire extends AbstractSpinnerModel {
+    private SensSpinnerBinaire sens;
+    public Object getValue() {
+      return sens;
+    }
+    public void setValue(Object value) {
+      sens = (SensSpinnerBinaire) value;
+      fireStateChanged();
+    }
+    public Object getNextValue() {
+      return SensSpinnerBinaire.PRECEDENT;
+    }
+    public Object getPreviousValue() {
+      return SensSpinnerBinaire.SUIVANT;
+    }
+  }
+  private static Dimension dimZero = new Dimension(20, 20);
+  private static Insets insetsZero = new Insets(0, 0, 0, 0);
+
+  public static class ElementComboBox extends Box implements ActionListener, ChangeListener {
+    private ArrayList<ActionListener> listeCorrespondants = new ArrayList<ActionListener>();
+    public JComboBox combo;
+    private JButton zero;
+    private JSpinner spin;
+    public Element[] elements;  // liste triée
+    public ElementComboBox() {
+      super(BoxLayout.X_AXIS);
+      zero = new JButton(new GAction("0") {
+        public void executer() {
+          effSelection();
+        }
+      });
+      zero.setMargin(insetsZero);
+      zero.setPreferredSize(dimZero);
+      spin = new JSpinner(new ModeleSpinnerBinaire());
+      spin.setEditor(new JLabel());
+      spin.addChangeListener(this);
+      combo = new JComboBox();
+      combo.setEditable(false);
+      combo.setFont(STYLE_COMBO);
+      combo.addActionListener(this);
+      add(combo);
+      add(spin);
+      add(zero);
+      setModeleVide();
+    }
+    public void addActionListener(ActionListener correspondant) {
+      listeCorrespondants.add(correspondant);
+    }
+    public void removeActionListener(ActionListener correspondant) {
+      listeCorrespondants.remove(correspondant);
+    }
+    public void actionPerformed(ActionEvent evt) {
+      try {
+        evt.setSource(this);
+        for (Object corresp : listeCorrespondants.toArray()) {
+          ((ActionListener) corresp).actionPerformed(evt);
+        }
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+    public void setModeleVide() {
+      combo.setModel(new DefaultComboBoxModel(new String[]{styleDef("identifiant")}));
+      elements = new Element[0];
+      setMaximumSize(getPreferredSize());
+    }
+    public void setModele(Element[] elts, String[] ids) {
+      // elts doit être trié et en correspondance avec ids
+      combo.setModel(new DefaultComboBoxModel(Tableaux.insererStringEnTete(ids, styleDef("identifiant"))));
+      elements = elts;
+      setMaximumSize(getPreferredSize());
+    }
+    public Element[] getElements() {
+      return elements;
+    }
+    public void gotoPrecedent() {
+      int index;
+      if ((index = combo.getSelectedIndex())==0) index = combo.getItemCount();
+      combo.setSelectedIndex(index-1);
+    }
+    public void gotoSuivant() {
+      int index = combo.getSelectedIndex()+1;
+      if (index==combo.getItemCount()) index = 0;
+      combo.setSelectedIndex(index);
+    }
+    public boolean pasdeSelection() {
+      return combo.getSelectedIndex()<1;
+    }
+    public Element getSelection() {
+      if (combo.getSelectedIndex()>0)
+        return elements[combo.getSelectedIndex()-1];
+      return null;
+    }
+    public void effSelection() {
+      combo.setSelectedIndex(0);
+    }
+    public void setSelection(Element elt) {
+      int no = Arrays.binarySearch(elements, elt);
+      if (no<0)
+        throw new ArrayIndexOutOfBoundsException("Element à sélectionner absent");
+      combo.setSelectedIndex(no+1);
+    }
+    public String getIdElement(Element elt) {
+      int no = Arrays.binarySearch(elements, elt);
+      if (no<0)
+        throw new ArrayIndexOutOfBoundsException("Element recherché absent");
+      return ((String) combo.getItemAt(no+1));
+
+    }
+    public void stateChanged(ChangeEvent e) {
+      try {
+        switch ((SensSpinnerBinaire) spin.getValue()) {
+          case SUIVANT:
+            gotoSuivant();
+            return;
+          case PRECEDENT:
+            gotoPrecedent();
+            return;
+        }
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+  }
+
+  public static class Val0ComboBox extends JComboBox {
+    private String[] vals;
+    private String val0;
+    public Val0ComboBox(String val0) {
+      super();
+      this.val0 = val0;
+      setEditable(false);
+      setFont(STYLE_COMBO);
+      setModeleVide();
+    }
+    public void setModeleVide() {
+      setModel(new DefaultComboBoxModel(new String[]{styleDef(val0)}));
+      vals = new String[0];
+      setMaximumSize(getPreferredSize());
+    }
+    public void setModele(String[] types) {
+      setModel(new DefaultComboBoxModel(Tableaux.insererStringEnTete(types, styleDef(val0))));
+      this.vals = types;
+      setMaximumSize(getPreferredSize());
+    }
+    public boolean pasdeSelection() {
+      return getSelectedIndex()<1;
+    }
+    public int nbItems() {
+      return vals.length;
+    }
+    public String getSelection() {
+      if (getSelectedIndex()>0) return vals[getSelectedIndex()-1];
+      return null;
+    }
+    public void effSelection() {
+      setSelectedIndex(0);
+    }
+    public void setSelection(String type) {
+      setSelectedItem(type);
+    }
+    public void setSelection(int i) {
+      setSelectedIndex(i+1);
+    }
+  }
+  public static String getNomClasse(Class<? extends Element> classe) {
+    if (classe==Element.class) return "élément";
+    else if (classe==Unite.class) return "unité";
+    else if (classe==Relation.class) return "relation";
+    else if (classe==Schema.class) return "schéma";
+    else
+      throw new UnsupportedOperationException("Sous-classe inconnue pour getNomClasse()");
+  }
+  public static String getNomDeClasse(Class<? extends Element> classe) {
+    if (classe==Element.class) return "d'élément";
+    else if (classe==Unite.class) return "d'unité";
+    else if (classe==Relation.class) return "de relation";
+    else if (classe==Schema.class) return "de schéma";
+    else
+      throw new UnsupportedOperationException("Sous-classe inconnue pour getNomTypedeClasse()");
+  }
+  public static String getNomDeLaClasse(Element elt) {
+    Class<? extends Element> classe = elt.getClass();
+    if (classe==Unite.class) return "de l'unité";
+    else if (classe==Relation.class) return "de la relation";
+    else if (classe==Schema.class) return "du schéma";
+    else
+      throw new UnsupportedOperationException("Sous-classe inconnue pour getNomTypedeClasse()");
+  }
+  public static Class<? extends Element> getClasse(String classeType) {
+    if (classeType==null) return null;
+    if (classeType.startsWith("REL-")) return Relation.class;
+    if (classeType.startsWith("SCH-")) return Schema.class;
+    return Unite.class;
+  }
+  public static String getType(String classeType) {
+    if (classeType==null) return null;
+    if (classeType.startsWith("REL-")) return classeType.substring(4);
+    if (classeType.startsWith("SCH-")) return classeType.substring(4);
+    return classeType;
+  }
+  private static String getClasseType(Class<? extends Element> classe, String type) {
+    if (classe==Unite.class) return type;
+    else if (classe==Relation.class) return "REL-"+type;
+    else if (classe==Schema.class) return "SCH-"+type;
+    else
+      throw new UnsupportedOperationException("Sous-classe inconnue pour getClasseType()");
+  }
+  public static String[] getClassesTypes(String[] typesUnit, String[] typesRel, String[] typesSch) {
+    String[] types = Arrays.copyOf(typesUnit, typesUnit.length+typesRel.length+typesSch.length);
+    for (int i = 0; i<typesRel.length; i++)
+      types[i+typesUnit.length] = "REL-"+typesRel[i];
+    for (int i = 0; i<typesSch.length; i++)
+      types[i+typesUnit.length+typesRel.length] = "SCH-"+typesSch[i];
+    return types;
+  }
+
+  public static class TypeComboBox extends Val0ComboBox {
+    private Class<? extends Element> classe;
+    public TypeComboBox(Class<? extends Element> classe) {
+      super("type "+getNomDeClasse(classe));
+      this.classe = classe;
+    }
+    @Override
+    public void setModele(String[] types) {
+      if (this.classe==Element.class)
+        throw new UnsupportedOperationException("pas pour la classe Element");
+      super.setModele(types);
+    }
+    public void setModele(String[] typesUnites, String[] typesRelations, String[] typesSchemas) {
+      if (this.classe!=Element.class)
+        throw new UnsupportedOperationException("uniquement pour la classe Element");
+      super.setModele(getClassesTypes(typesUnites, typesRelations, typesSchemas));
+    }
+    public String getTypeSelection() {
+      String classetype = getSelection();
+      if (classetype==null) return null;
+      if (classe==Element.class) return getType(classetype);
+      return classetype;
+    }
+    public Class<? extends Element> getClasseSelection() {
+      String classetype = getSelection();
+      if (classetype==null) return null;
+      if (classe==Element.class) return getClasse(classetype);
+      return classe;
+    }
+    public void setSelection(Class<? extends Element> classe, String type) {
+      if (this.classe!=Element.class)
+        throw new UnsupportedOperationException("uniquement pour la classe Element");
+      super.setSelection(getClasseType(classe, type));
+    }
+    @Override
+    public void setSelection(String type) {
+      if (this.classe==Element.class)
+        throw new UnsupportedOperationException("pas pour la classe Element");
+      super.setSelection(type);
+    }
+  }
+  private final static Color[] couleursEtNoirEtBlanc = new Color[]{Color.BLACK, Color.WHITE, Color.YELLOW,
+    Color.RED, Color.BLUE, Color.ORANGE, Color.GREEN, Color.CYAN, Color.MAGENTA, Color.PINK
+  };
+  private final static Color[] couleurs = new Color[]{Color.YELLOW, Color.RED, Color.BLUE,
+    Color.ORANGE, Color.GREEN, Color.CYAN, Color.MAGENTA, Color.PINK
+  };
+  public static Color[] getCouleursEtNoirEtBlanc() {
+    return couleursEtNoirEtBlanc;
+  }
+  public static Color getCouleur(int i) {
+    Color c = couleurs[i%couleurs.length];
+    for (int n = 0; n<i/couleurs.length; n++) {
+      float[] rgb = c.getRGBColorComponents(null);
+      c = new Color(0.499f+rgb[0]/3, 0.499f+rgb[1]/3, 0.499f+rgb[2]/3);
+    }
+    return c;
+  }
+  public static int getTaille(int i) {
+    int c;
+    c = i + 1;
+    if(c > 4){
+        c = 4;
+    }
+    return c;
+  }
+  public static int getForme(int i) {
+    int c;
+    c = i;
+    return c;
+  }
+  /*@require : i doit être positif et inférieur ou égal 99*/
+  public static String getTexte(int i) {
+    String c;
+    c = "" + ((i - i%10)%100)/10 + i%10;
+    return c;
+  }
+  
+  public static Color getCouleurSansValeur() {
+    return Color.LIGHT_GRAY;
+  }
+  public static int getFormeSansValeur() {
+    return 10;
+  }
+  public static int getTailleSansValeur() {
+    return 4;
+  }
+
+  public static String getTexteSansValeur() {
+    return "99";
+  }
+
+  public static class DisqueCouleurIcone implements Icon {
+    private Color couleur;
+    int rayon;
+    int marge;
+    public DisqueCouleurIcone(Color couleur, int rayon, int marge) {
+      this.couleur = couleur;
+      this.rayon = rayon;
+      this.marge = marge;
+    }
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+      if (couleur==null) {
+        g.setColor(Color.BLACK);
+        g.drawLine(x+3*marge, y+3*marge, x+2*rayon-marge, y+2*rayon-marge);
+        g.drawLine(x+3*marge, y+2*rayon-marge, x+2*rayon-marge, y+3*marge);
+      } else {
+        g.setColor(couleur);
+        g.fillOval(x+marge, y+marge, 2*rayon, 2*rayon);
+        g.setColor(Color.BLACK);
+        g.drawOval(x+marge, y+marge, 2*rayon, 2*rayon);
+      }
+    }
+    public int getIconWidth() {
+      return 2*rayon+2*marge;
+    }
+    public int getIconHeight() {
+      return 2*rayon+2*marge;
+    }
+    public int getRayon(){
+        return rayon;
+    }
+    public int getMarge(){
+        return marge;
+    }
+    public Color getColor(){
+        return couleur;
+    }
+    
+  }
+
+  public static class CarreCouleurIcone implements Icon {
+    private Color couleur;
+    int rayon;
+    int marge;
+    public CarreCouleurIcone(Color couleur, int rayon, int marge) {
+      this.couleur = couleur;
+      this.rayon = rayon;
+      this.marge = marge;
+    }
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+      if (couleur==null) {
+        g.setColor(Color.BLACK);
+        g.drawLine(x+3*marge, y+3*marge, x+2*rayon-marge, y+2*rayon-marge);
+        g.drawLine(x+3*marge, y+2*rayon-marge, x+2*rayon-marge, y+3*marge);
+      } else {
+        g.setColor(couleur);
+        g.fillRect(x+marge, y+marge, 2*rayon, 2*rayon);
+        g.setColor(Color.BLACK);
+        g.drawRect(x+marge, y+marge, 2*rayon, 2*rayon);
+      }
+    }
+    public int getIconWidth() {
+      return 2*rayon+2*marge;
+    }
+    public int getIconHeight() {
+      return 2*rayon+2*marge;
+    }
+    public int getRayon(){
+        return rayon;
+    }
+    public int getMarge(){
+        return marge;
+    }
+    public Color getColor(){
+        return couleur;
+    }
+  }
+  public static class CroixCouleurIcone implements Icon {
+    private Color couleur;
+    int rayon;
+    int marge;
+    public CroixCouleurIcone(Color couleur, int rayon, int marge) {
+      this.couleur = couleur;
+      this.rayon = rayon;
+      this.marge = marge;
+    }
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+      if (couleur==null ) {
+        g.setColor(Color.BLACK);
+        g.drawLine(x+3*marge, y+3*marge, x+2*rayon-marge, y+2*rayon-marge);
+        g.drawLine(x+3*marge, y+2*rayon-marge, x+2*rayon-marge, y+3*marge);
+      } else {
+        g.setColor(couleur);
+        int x1[]=new int[]{x+marge,x+marge+rayon-1,x+marge+rayon-1,x+marge+rayon+1,x+marge+rayon+1
+                , x + marge + 2 * rayon,x + marge + 2 * rayon,x+marge+rayon+1,x+marge+rayon+1 
+                ,x+marge+rayon-1,x+marge+rayon-1,x+marge,x+marge};
+        int y1[]=new int[]{y + marge+rayon-1,y + marge+rayon-1,y + marge,y + marge,y + marge+rayon-1
+                ,y + marge+rayon-1,y + marge+rayon+1,y + marge+rayon+1,y + marge+2*rayon
+                ,y + marge+2*rayon,y + marge+rayon+1,y + marge+rayon+1,y + marge+rayon-1 };
+        g.fillPolygon(x1, y1, 13);
+        g.setColor(Color.BLACK);
+        g.drawPolygon(x1, y1, 13);
+      }
+    }
+    public int getIconWidth() {
+      return 2*rayon+2*marge;
+    }
+    public int getIconHeight() {
+      return 2*rayon+2*marge;
+    }
+    public int getRayon(){
+        return rayon;
+    }
+    public int getMarge(){
+        return marge;
+    }
+    public Color getColor(){
+        return couleur;
+    }
+    
+  }
+  public static class TriangleCouleurIcone implements Icon {
+    private Color couleur;
+    int rayon;
+    int marge;
+    public TriangleCouleurIcone(Color couleur, int rayon, int marge) {
+      this.couleur = couleur;
+      this.rayon = rayon;
+      this.marge = marge;
+    }
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+      if (couleur==null) {
+        g.setColor(Color.BLACK);
+        g.drawLine(x+3*marge, y+3*marge, x+2*rayon-marge, y+2*rayon-marge);
+        g.drawLine(x+3*marge, y+2*rayon-marge, x+2*rayon-marge, y+3*marge);
+      } else {
+        g.setColor(couleur);
+        int x1[]=new int[]{x + marge,x + marge + rayon,x + marge + 2 *rayon,x+marge};
+        int y1[]=new int[]{y + marge+ 2 * rayon,y+marge,y + marge+ 2 * rayon, y + marge+ 2 * rayon};
+        g.fillPolygon(x1,y1,4);
+        g.setColor(Color.BLACK);
+        g.drawPolygon(x1, y1, 4);
+      }
+    }
+    public int getIconWidth() {
+      return 2*rayon+2*marge;
+    }
+    public int getIconHeight() {
+      return 2*rayon+2*marge;
+    }
+    public int getRayon(){
+        return rayon;
+    }
+    public int getMarge(){
+        return marge;
+    }
+    public Color getColor(){
+        return couleur;
+    }
+  }
+  
+    public static class TriangleinverseCouleurIcone implements Icon {
+    private Color couleur;
+    int rayon;
+    int marge;
+    public TriangleinverseCouleurIcone(Color couleur, int rayon, int marge) {
+      this.couleur = couleur;
+      this.rayon = rayon;
+      this.marge = marge;
+    }
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+      if (couleur==null) {
+        g.setColor(Color.BLACK);
+        g.drawLine(x+3*marge, y+3*marge, x+2*rayon-marge, y+2*rayon-marge);
+        g.drawLine(x+3*marge, y+2*rayon-marge, x+2*rayon-marge, y+3*marge);
+      } else {
+        g.setColor(couleur);
+        int x1[]=new int[]{x + marge,x + marge + 2 * rayon,x + marge + rayon,x+marge};
+        int y1[]=new int[]{y + marge,y+marge,y + marge+ 2 * rayon, y + marge};
+        g.fillPolygon(x1,y1,4);
+        g.setColor(Color.BLACK);
+        g.drawPolygon(x1, y1, 4);
+      }
+    }
+    public int getIconWidth() {
+      return 2*rayon+2*marge;
+    }
+    public int getIconHeight() {
+      return 2*rayon+2*marge;
+    }
+    public int getRayon(){
+        return rayon;
+    }
+    public int getMarge(){
+        return marge;
+    }
+    public Color getColor(){
+        return couleur;
+    }
+  }
+  
+  
+  public static class LegendeLabel {
+    String texte;
+    String textelegende;
+    Icon icone;
+    public LegendeLabel(String texte,String textelegende){
+        this.texte = texte;
+        this.textelegende = textelegende;
+    }
+    public LegendeLabel(String texte, Color couleur) {
+      this.texte = texte;
+      this.icone = new DisqueCouleurIcone(couleur, 12, 2);
+    }
+    public LegendeLabel(String texte, Color couleur, int taille, int forme, int rayon , int marge) {
+      this.texte = texte;
+      if(taille!=-1 && forme !=-1){
+              switch(forme){
+            case 0 :
+                this.icone = new DisqueCouleurIcone(couleur, rayon / taille
+                        , marge);
+                break;
+            case 1 :
+                this.icone = new CarreCouleurIcone(couleur, rayon / taille
+                        , marge);
+                break;
+            case 2 :
+                this.icone = new CroixCouleurIcone(couleur, rayon / taille
+                        , marge);
+                break;
+            case 3 :
+                this.icone = new TriangleCouleurIcone(couleur, rayon / taille
+                        , marge);
+                break;
+            default :
+                this.icone = new TriangleinverseCouleurIcone(couleur, rayon / taille
+                        , marge);
+                break;
+        }
+      }
+      else{
+                        switch(forme){
+            case 0 :
+                this.icone = new DisqueCouleurIcone(null, 12
+                        , 2);
+                break;
+            case 1 :
+                this.icone = new CarreCouleurIcone(null, 12
+                        , 2);
+                break;
+            case 2 :
+                this.icone = new CroixCouleurIcone(null, 12
+                        , 2);
+                break;
+            case 3 :
+                this.icone = new TriangleCouleurIcone(null, 12
+                        , 2);
+                break;
+            default :
+                this.icone = new TriangleinverseCouleurIcone(null, 12
+                        , 2);
+                break;
+      }
+    }    
+    }
+  }
+
+  public static class LegendeCellRenderer extends JLabel implements ListCellRenderer {
+    public LegendeCellRenderer() {
+      setIconTextGap(12);
+    }
+    public Component getListCellRendererComponent(JList list, Object value,
+            int index, boolean isSelected, boolean cellHasFocus) {
+      LegendeLabel label = (LegendeLabel) value;
+      setText(label.texte);
+      setIcon(label.icone);
+      return this;
+    }
+  }
+  /*Modèle pour le tableau de la légende avec icone*/
+  public static class LegendeModeleTable extends AbstractTableModel{
+      private Object[][] donnees = new Object[0][0];
+      private String[] entetes = new String[0];
+          	@Override
+	public int getColumnCount() {
+		return entetes.length;
+        }
+        @Override
+	public String getColumnName(int columnIndex) {
+		return entetes[columnIndex];
+	}
+        public LegendeModeleTable(){
+        }
+        public LegendeModeleTable(String[] titres, LegendeLabel[] legende, HashMap<String, Float> freq){
+                        this.entetes = titres;
+            this.donnees = new Object[legende.length][freq==null ? 2 : 3];
+            for(int i = 0;i < legende.length;i++){
+                donnees[i][0] = legende[i].icone;
+                donnees[i][1] = legende[i].texte;
+                if(freq!=null){
+                donnees[i][2] = freq.get(legende[i].texte);
+                }
+            }
+        }        
+        public int getRowCount() {
+		return donnees.length;
+	}
+
+	@Override
+	public Object getValueAt(int rowIndex, int columnIndex) {
+		return donnees[rowIndex][columnIndex];
+	}
+        @Override
+        public Class getColumnClass(int columnIndex){
+            switch(columnIndex){
+                case 0 :
+                    return Icon.class;
+                case 2:
+                    return Float.class;
+                default:
+                    return String.class;
+            }
+        }
+        public void setLegendeModele(String[] titres, LegendeLabel[] legende, HashMap<String, Float> freq){
+            this.entetes = titres;
+            this.donnees = new Object[legende.length][3];
+            for(int i = 0;i < legende.length;i++){
+                donnees[i][0] = legende[i].icone;
+                donnees[i][1] = legende[i].texte;
+                donnees[i][2] = freq.get(legende[i].texte);
+            }
+        }
+  }
+  /*Modèle pour le tableau de la légende sans icone*/
+    public static class LegendeModeleTableTexte extends AbstractTableModel{
+      private Object[][] donnees = new Object[0][0];
+      private String[] entetes = new String[0];
+          	@Override
+	public int getColumnCount() {
+		return entetes.length;
+        }
+        @Override
+	public String getColumnName(int columnIndex) {
+		return entetes[columnIndex];
+	}
+        public LegendeModeleTableTexte(){
+        }
+        public LegendeModeleTableTexte(String[] titres, LegendeLabel[] legende, HashMap<String, Float> freq){
+                        this.entetes = titres;
+            this.donnees = new Object[legende.length][freq==null ? 2 : 3];
+            for(int i = 0;i < legende.length;i++){
+                donnees[i][0] = legende[i].textelegende;
+                donnees[i][1] = legende[i].texte;
+                if(freq!=null){
+                donnees[i][2] = freq.get(legende[i].texte);
+                }
+            }
+        }        
+        public int getRowCount() {
+		return donnees.length;
+	}
+
+	@Override
+	public Object getValueAt(int rowIndex, int columnIndex) {
+		return donnees[rowIndex][columnIndex];
+	}
+        @Override
+        public Class getColumnClass(int columnIndex){
+            switch(columnIndex){
+                case 0 :
+                    return String.class;
+                case 2:
+                    return Float.class;
+                default:
+                    return String.class;
+            }
+        }
+        public void setLegendeModele(String[] titres, LegendeLabel[] legende, HashMap<String, Float> freq){
+            this.entetes = titres;
+            this.donnees = new Object[legende.length][3];
+            for(int i = 0;i < legende.length;i++){
+                donnees[i][0] = legende[i].textelegende;
+                donnees[i][1] = legende[i].texte;
+                donnees[i][2] = freq.get(legende[i].texte);
+            }
+        }
+  }
+  
+  
+  
+
+  public static class RectangleCouleurIcone implements Icon {
+    private Color couleur;
+    private int largeur;
+    private int hauteur;
+    private int marge;
+    private boolean select;
+    public RectangleCouleurIcone(Color couleur, int largeur, int hauteur, int marge, boolean select) {
+      this.couleur = couleur;
+      this.largeur = largeur;
+      this.hauteur = hauteur;
+      this.marge = marge;
+      this.select = select;
+    }
+    void setCouleur(Color c) {
+      couleur = c;
+    }
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+      g.setColor(couleur);
+      g.fillRect(x+marge, y+marge, largeur, hauteur);
+      if (select) {
+        g.setColor(Color.BLACK);
+        g.drawRect(x+marge, y+marge, largeur, hauteur);
+      }
+    }
+    public int getIconWidth() {
+      return largeur+2*marge;
+    }
+    public int getIconHeight() {
+      return hauteur+2*marge;
+    }
+  }
+
+  public static class CouleurCellRenderer extends JLabel implements ListCellRenderer, TableCellRenderer {
+    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
+            boolean cellHasFocus) {
+      if (index==list.getModel().getSize()-1||index<0) {
+        setText(index<0 ? "" : styleDef("autre"));
+        setIcon(null);
+      } else {
+        setText(null);
+        setIcon(new RectangleCouleurIcone((Color) value, 40, 10, 2, isSelected));
+      }
+      return this;
+    }
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+      setText(null);
+      setIcon(new RectangleCouleurIcone((Color) value, 80, 10, 2, true));
+      return this;
+    }
+  }
+
+  public static class CouleurComboBoxEditor implements ComboBoxEditor {
+    CouleurComboBox comboBox;
+    RectangleCouleurIcone icone;
+    JLabel editeur;
+    Color couleur;
+    public CouleurComboBoxEditor(CouleurComboBox cb) {
+      comboBox = cb;
+      editeur = new JLabel(icone = new RectangleCouleurIcone(null, 80, 10, 2, true));
+    }
+    public Component getEditorComponent() {
+      return editeur;
+    }
+    private void init(Color couleur) {
+      this.couleur = couleur;
+      icone.setCouleur(couleur);
+    }
+    public void setItem(Object anObject) {
+      if (anObject==null) {
+        Color c = JColorChooser.showDialog(editeur, "Choix de la couleur", couleur);
+        if (c!=null) couleur = c;
+      } else couleur = (Color) anObject;
+      icone.setCouleur(couleur);
+      comboBox.setSelectedItem(couleur);
+    }
+    public Object getItem() {
+      return couleur;
+    }
+    public void selectAll() {
+    }
+    public void addActionListener(ActionListener l) {
+    }
+    public void removeActionListener(ActionListener l) {
+    }
+  }
+
+  public static class CouleurComboBox extends JComboBox {
+    public CouleurComboBox(Color[] couleurs) {
+      super(couleurs);
+      addItem(null);
+      setRenderer(new CouleurCellRenderer());
+      setEditor(new CouleurComboBoxEditor(this));
+      setMaximumRowCount(couleurs.length+1);
+    }
+  }
+
+  public static class CouleurTableEditor extends AbstractCellEditor implements TableCellEditor, ActionListener {
+    private CouleurComboBox comboBox;
+    private Color couleur;
+    public CouleurTableEditor(Color[] couleurs) {
+      comboBox = new CouleurComboBox(couleurs);
+      comboBox.setEditable(true);
+      comboBox.addActionListener(this);
+    }
+    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+      couleur = (Color) value;
+      comboBox.getEditor().setItem(value);
+      return comboBox;
+    }
+    public Object getCellEditorValue() {
+      return couleur;
+    }
+    public void actionPerformed(ActionEvent e) {
+      couleur = (Color) comboBox.getSelectedItem();
+      fireEditingStopped();
+    }
+  }
+  //fonctiontrès grossière mais si quelqu'un réussit à obtenir un charactère à partir  de son code ascci ou unicode
+  //quelque soit la machine, il devra remplacer cette fonction 
+
+    public static char intToChar(int value){
+        switch(value){
+            case 0:
+                return '0';
+            case 1:
+                return '1';
+            case 2:
+                return '2';
+            case 3:
+                return '3';
+            case 4:
+                return '4';
+            case 5:
+                return '5';
+            case 6: 
+                return '6';
+            case 7:
+                return '7';
+            case 8 :
+                return '8';
+            case 9 :
+                return '9'; 
+            case 10 :
+                return 'a';
+            case 11 :
+                return 'b';
+            case 12 :
+                return 'c';
+            case 13 :
+                return 'd';
+            case 14 :
+                return 'e';
+            case 15 :
+                return 'f';
+            case 16 :
+                return 'g';
+            case 17 :
+                return 'h';
+            case 18 :
+                return 'i';
+            case 19 :
+                return 'j';
+            case 20 :
+                return 'k';
+            case 21 :
+                return 'l';
+            case 22 :
+                return 'm';
+            case 23 :
+                return 'n';
+            case 24 :
+                return 'o';
+            case 25 :
+                return 'p';
+            case 26 :
+                return 'q';
+            case 27 :
+                return 'r';
+            case 28 :
+                return 's';
+            case 29 :
+                return 't';
+            case 30 :
+                return 'u';
+            case 31 :
+                return 'v';
+            case 32 :
+                return 'w';
+            case 33 :
+                return 'x';
+            case 34 :
+                return 'y';
+            case 35 :
+                return 'z';
+            case 36 :
+                return 'A';
+            case 37 : 
+                return 'B';
+            case 38 :
+                return 'C';
+            case 39 :
+                return 'D';           
+            case 40 :
+                return 'E';
+            case 41 :
+                return 'F';              
+            case 42 :
+                return 'G';                
+            case 43 :
+                return 'H';               
+            case 44 :
+                return 'I';
+            case 45 :
+                return 'J';               
+            case 46 :
+                return 'K';               
+            case 47 :
+                return 'L';              
+            case 48 :
+                return 'M';              
+            case 49 :
+                return 'N';                
+            case 50 :
+                return 'O';                
+            case 51 :
+                return 'P';                
+            case 52 :
+                return 'Q';               
+            case 53 :
+                return 'R';               
+            case 54 :
+                return 'S';               
+            case 55 :
+                return 'T';
+            case 56 :
+                return 'U';
+            case 57 :
+                return 'V';                
+            case 58 :
+                return 'W';               
+            case 59 :
+                return 'X';               
+            case 60 :
+                return 'Y';               
+            case 61 :
+                return 'Z';             
+            default : 
+                return '?';
+        }
+        
+    }
+    public static int CharToInt(char value){
+        switch(value){
+            case '0':
+                return 0;
+            case '1':
+                return 1;
+            case '2':
+                return 2;
+            case '3':
+                return 3;
+            case '4':
+                return 4;
+            case '5':
+                return 5;
+            case '6': 
+                return 6;
+            case '7':
+                return 7;
+            case '8' :
+                return 8;
+            case '9' :
+                return 9; 
+            case 'a' :
+                return 10;
+            case 'b' :
+                return 11;
+            case 'c':
+                return 12;
+            case 'd' :
+                return 13;
+            case 'e' :
+                return 14;
+            case 'f' :
+                return 15;
+            case 'g' :
+                return 16;
+            case 'h' :
+                return 17;
+            case 'i' :
+                return 18;
+            case 'j':
+                return 19;
+            case 'k' :
+                return 20;
+            case 'l' :
+                return 21;
+            case 'm' :
+                return 22;
+            case 'n' :
+                return 23;
+            case 'o' :
+                return 24;
+            case 'p' :
+                return 25;
+            case 'q' :
+                return 26;
+            case 'r' :
+                return 27;
+            case 's' :
+                return 28;
+            case 't' :
+                return 29;
+            case 'u' :
+                return 30;
+            case 'v' :
+                return 31;
+            case 'w':
+                return 32;
+            case 'x' :
+                return 33;
+            case 'y' :
+                return 34;
+            case 'z' :
+                return 35;
+            case 'A' :
+                return 36;
+            case 'B' : 
+                return 37;
+            case 'C' :
+                return 38;
+            case 'D' :
+                return 39;           
+            case 'E' :
+                return 40;
+            case 'F' :
+                return 41;              
+            case 'G' :
+                return 42;                
+            case 'H' :
+                return 43;               
+            case 'I' :
+                return 44;
+            case 'J' :
+                return 45;               
+            case 'K' :
+                return 46;               
+            case 'L' :
+                return 47;              
+            case 'M' :
+                return 48;              
+            case 'N' :
+                return 49;                
+            case 'O' :
+                return 50;                
+            case 'P' :
+                return 51;                
+            case 'Q' :
+                return 52;               
+            case 'R' :
+                return 53;               
+            case 'S' :
+                return 54;               
+            case 'T' :
+                return 55;
+            case 'U' :
+                return 56;
+            case 'V' :
+                return 57;                
+            case 'W' :
+                return 58;               
+            case 'X' :
+                return 59;               
+            case 'Y' :
+                return 60;               
+            case 'Z' :
+                return 61;             
+            default : 
+                return -1;
+        }
+        
+    }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/util/GVisu.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/util/GMessages.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/util/GMessages.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/util/GMessages.java	(revision 481)
@@ -0,0 +1,101 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.util;
+
+import java.awt.event.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class GMessages {
+  public static boolean confirmationAction(String texte) {
+    return (JOptionPane.showConfirmDialog(null, texte, "Confirmation d'action",
+            JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE)
+            !=JOptionPane.CANCEL_OPTION);
+  }
+
+  public static void pasImplemente() {
+    JOptionPane.showMessageDialog(null, "Désolé, cette fonctionnalité n'est pas encore implémentée",
+            "Patience...", JOptionPane.INFORMATION_MESSAGE);
+    return;
+  }
+
+  public static void impossibiliteAction(String texte) {
+    JOptionPane.showMessageDialog(null, texte,
+            "Désolé...", JOptionPane.INFORMATION_MESSAGE);
+    return;
+  }
+
+  public static void erreurFatale(Throwable ex) {
+    String message = "<center><b>Désolé pour ce bug... Vous allez devoir relancer Analec.</b></center>"
+            +"<i><br>Veuillez recopier  le message d'erreur ci-dessous et l'envoyer au concepteur du logiciel"
+            +" <br>en précisant les conditions dans lequel ce bug s'est produit</i>";
+    String erreur = "<p>"+ex.toString();
+    for (StackTraceElement tr : ex.getStackTrace())
+      if (tr.getClassName().startsWith("visuAnalec")||tr.getClassName().startsWith("JamaPlus") )
+        erreur += "<br>"+tr.getClassName()+" : "+tr.getMethodName()+" ligne "+tr.getLineNumber();
+    JEditorPane dialogue = new JEditorPane("text/html", message+erreur);
+    JOptionPane.showMessageDialog(null, dialogue, "Oups !", JOptionPane.ERROR_MESSAGE);
+   // System.exit(1);
+  }
+
+  public abstract static class GAction extends AbstractAction {
+    public GAction(String nom) {
+      super(nom);
+    }
+
+    public GAction(String nom, Icon icone) {
+      super(nom, icone);
+    }
+
+    public abstract void executer();
+
+    public void actionPerformed(ActionEvent evt) {
+      try {
+        executer();
+      } catch (Throwable ex) {
+        erreurFatale(ex);
+      }
+    }
+  }
+
+  public abstract static class GActionClavier extends GAction {
+    public GActionClavier(JComponent composant, String nom, String... touches) {
+      super(nom);
+      for(String touche: touches) {
+        composant.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
+                KeyStroke.getKeyStroke(touche), nom);
+      }
+      composant.getActionMap().put(nom, this);
+    }
+  }
+  public static class GProgression extends ProgressMonitor  {
+    private int compteur;
+    private String elementsTraites;
+
+    public GProgression(int max, String traitement, String elementsTraites) {
+      super(null, traitement + " en cours", "Démarrage", 0, max);
+      this.elementsTraites = elementsTraites;
+//      setMillisToPopup(0);
+      compteur = 0;
+     }
+
+    public void setNbTraites(int nb) {
+      compteur = nb;
+      SwingUtilities.invokeLater(new MiseAJour());
+    }
+
+    class MiseAJour implements Runnable {
+      public void run() {
+        setProgress(compteur);
+        setNote(compteur +" "+ elementsTraites + " traités");
+      }
+    }
+  }
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/util/GMessages.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/util/Tableaux.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/util/Tableaux.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/util/Tableaux.java	(revision 481)
@@ -0,0 +1,86 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.util;
+
+import java.util.*;
+import visuAnalec.elements.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public abstract class Tableaux {
+  public static int compterValeursVraies(boolean[] bls) {
+    int nb = 0;
+    for(boolean b: bls) if(b) nb++;
+    return nb;
+  }
+  public static String[] insererString(String[] strs, String str) {
+    // renvoie un tableau trié
+    String[] strs1 = insererStringEnTete(strs, str);
+    Arrays.sort(strs1);
+    return strs1;
+  }
+  public static String[] insererStringEnTete(String[] strs, String str) {
+    String[] strs1 = new String[strs.length + 1];
+    System.arraycopy(strs, 0, strs1, 1, strs.length);
+    strs1[0] = str;
+    return strs1;
+  }
+  static String[] oterString(String[] strs, String str) {
+    // strs doit être triée
+    int ind = Arrays.binarySearch(strs, str);
+    if (ind < 0) return strs;
+    return oterString(strs, ind);
+  }
+  public static String[] oterString(String[] strs, int ind) {
+    String[] strs1 = new String[strs.length - 1];
+    System.arraycopy(strs, 0, strs1, 0, ind);
+    System.arraycopy(strs, ind + 1, strs1, ind, strs.length - ind - 1);
+    return strs1;
+  }
+  public static String[] oterStrings(String[] strs, ArrayList<Integer> inds) {
+    //  inds doit être croissant
+    String[] strs1 = new String[strs.length - inds.size()];
+    inds.add(strs.length);
+    System.arraycopy(strs, 0, strs1, 0, inds.get(0));
+    for (int i = 1; i < inds.size(); i++)
+      System.arraycopy(strs, inds.get(i - 1) + 1, strs1, inds.get(i - 1) - i + 1, inds.get(i) - inds.get(i - 1) - 1);
+    return strs1;
+  }
+//  public static String[][] oterStrings(String[][] strs, ArrayList<Integer> inds1, ArrayList<Integer> inds2) {
+//    //  inds1 et inds2 doivent être de même taille
+//    String[] strs1 = new String[strs.length - inds.size()];
+//    inds.add(strs.length);
+//    System.arraycopy(strs, 0, strs1, 0, inds.get(0));
+//    for (int i = 1; i < inds.size(); i++)
+//      System.arraycopy(strs, inds.get(i - 1) + 1, strs1, inds.get(i - 1) - i + 1, inds.get(i) - inds.get(i - 1) - 1);
+//    return strs1;
+//  }
+  public static Element[] insererElementEnTete(Element[] elts, Element elt) {
+    Element[] elts1 = new Element[elts.length + 1];
+    System.arraycopy(elts, 0, elts1, 1, elts.length);
+    elts1[0] = elt;
+    return elts1;
+  }
+  public static Element[] oterElements(Element[] elts, ArrayList<Integer> inds) {
+    //  inds doit être croissant
+    Element[] elts1 = new Element[elts.length - inds.size()];
+    inds.add(elts.length);
+    System.arraycopy(elts, 0, elts1, 0, inds.get(0));
+    for (int i = 1; i < inds.size(); i++)
+      System.arraycopy(elts, inds.get(i - 1) + 1, elts1, inds.get(i - 1) - i + 1, inds.get(i) - inds.get(i - 1) - 1);
+    return elts1;
+  }
+  public static Relation[] oterRelations(Relation[] elts, ArrayList<Integer> inds) {
+    //  inds doit être croissant
+    Relation[] elts1 = new Relation[elts.length - inds.size()];
+    inds.add(elts.length);
+    System.arraycopy(elts, 0, elts1, 0, inds.get(0));
+    for (int i = 1; i < inds.size(); i++)
+      System.arraycopy(elts, inds.get(i - 1) + 1, elts1, inds.get(i - 1) - i + 1, inds.get(i) - inds.get(i - 1) - 1);
+    return elts1;
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/util/Tableaux.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesRelations.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesRelations.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesRelations.java	(revision 481)
@@ -0,0 +1,756 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.ArrayList;
+import javax.swing.*;
+import visuAnalec.Message.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.texte.PanneauAffTexte.*;
+import visuAnalec.texte.PanneauTexte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class PanneauCommandesRelations extends PanneauCommandes implements ActionListener {
+  private PanneauChamps panneauChamps;
+  private TypeComboBox saisieTypeRelations;
+  private ElementComboBox saisieRelation;
+  private TypeComboBox saisieTypeElt1;
+  private ElementComboBox saisieElt1;
+  private TypeComboBox saisieTypeElt2;
+  private ElementComboBox saisieElt2;
+  private JButton creeRelation;
+  private JButton supprimeRelation;
+  private JButton creeUniteElt1;
+  private JButton creeUniteElt2;
+  private boolean uniteCreeElt1 = true; // pour la création d'unités en cours de route
+  private int[] bornesSelectTexte;
+  /*
+  
+   * CREATION PAR LE PANNEAU EDITEUR
+   */
+  PanneauCommandesRelations(Vue vue, PanneauAffTexte pTexte, PanneauChamps pChamps) {
+    super(vue, pTexte);
+    JToolBar barre1 = new JToolBar();
+    barre1.setPreferredSize(new Dimension(0, 22));
+    barre1.setAlignmentX(0.0f);
+    //    barre1.setFloatable(false);
+    add(barre1);
+    JToolBar barre2 = new JToolBar();
+//    barre2.setBackground(PanneauTexte.getCouleurFond2());
+    barre2.setPreferredSize(new Dimension(0, 22));
+    barre2.setAlignmentX(0.0f);
+//     barre2.setFloatable(false);
+    add(barre2);
+    JToolBar barre3 = new JToolBar();
+    barre3.setPreferredSize(new Dimension(0, 22));
+    barre3.setAlignmentX(0.0f);
+//    barre3.setBackground(PanneauTexte.getCouleurFond2());
+//     barre3.setFloatable(false);
+    add(barre3);
+
+    panneauChamps = pChamps;
+    saisieTypeRelations = new TypeComboBox(Relation.class);
+    saisieTypeRelations.addActionListener(this);
+    saisieRelation = new ElementComboBox();
+    saisieRelation.addActionListener(this);
+    saisieTypeElt1 = new TypeComboBox(Element.class);
+    saisieTypeElt1.addActionListener(this);
+    saisieElt1 = new ElementComboBox();
+    saisieElt1.addActionListener(this);
+    saisieTypeElt2 = new TypeComboBox(Element.class);
+    saisieTypeElt2.addActionListener(this);
+    saisieElt2 = new ElementComboBox();
+    saisieElt2.addActionListener(this);
+    creeRelation = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerRelation();
+      }
+    });
+    supprimeRelation = new JButton(new GAction("Supprimer") {
+      public void executer() {
+        supprimerRelation();
+      }
+    });
+    creeUniteElt1 = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerUniteElt1();
+      }
+    });
+    creeUniteElt2 = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerUniteElt2();
+      }
+    });
+    barre1.addSeparator();
+    barre1.add(new TitreBarre("  Relation :  ", PanneauTexte.getCouleurFond1()));
+    barre1.addSeparator();
+    barre1.add(saisieTypeRelations);
+    barre1.add(saisieRelation);
+    barre1.addSeparator();
+    barre1.add(creeRelation);
+    barre1.addSeparator();
+    barre1.add(supprimeRelation);
+    barre2.addSeparator();
+    barre2.add(new TitreBarre("Elément 1 : ", PanneauTexte.getCouleurFond2()));
+    barre2.addSeparator();
+    barre2.add(saisieTypeElt1);
+    barre2.add(saisieElt1);
+    barre2.addSeparator();
+    barre2.add(creeUniteElt1);
+    barre3.addSeparator();
+    barre3.add(new TitreBarre("Elément 2 : ", PanneauTexte.getCouleurFond3()));
+    barre3.addSeparator();
+    barre3.add(saisieTypeElt2);
+    barre3.add(saisieElt2);
+    barre3.addSeparator();
+    barre3.add(creeUniteElt2);
+  }
+
+  /*
+   * COMMANDES UTILISEES PAR LE PANNEAU EDITEUR
+   */
+  public void reinitialiser() {
+    // typiquement, appelé par le panneau éditeur à la suite d'une modif de vue ou de structure
+    saisieTypeRelations.removeActionListener(this);
+    saisieTypeRelations.setModele(vue.getTypesRelationsAVoir());
+    saisieTypeRelations.effSelection();
+    saisieTypeRelations.addActionListener(this);
+    saisieTypeElt1.removeActionListener(this);
+    saisieTypeElt1.setModele(vue.getTypes(Unite.class), vue.getTypes(Relation.class), vue.getTypes(Schema.class));
+    saisieTypeElt1.effSelection();
+    saisieTypeElt1.addActionListener(this);
+    saisieTypeElt2.removeActionListener(this);
+    saisieTypeElt2.setModele(vue.getTypes(Unite.class), vue.getTypes(Relation.class), vue.getTypes(Schema.class));
+    saisieTypeElt2.effSelection();
+    saisieTypeElt2.addActionListener(this);
+    initSaisieRelation();
+    initSaisieElt1();
+    initSaisieElt2();
+    etatSelectRien();
+    revalidate();
+    repaint();
+  }
+  public void reafficher() {
+    // potentiellement appelé par le panneau éditeur ?
+    // appelé aussi par  traiterElementEvent
+    if (saisieRelation.pasdeSelection()) {
+      initSaisieRelation();
+      if (saisieElt1.pasdeSelection()) {
+        initSaisieElt1();
+        if (saisieElt2.pasdeSelection()) {
+          initSaisieElt2();
+          etatSelectRien();
+        } else {
+          Element elt2Courant = saisieElt2.getSelection();
+          initSaisieElt2(elt2Courant);
+          etatSelectElt2(elt2Courant);
+        }
+      } else {
+        Element elt1Courant = saisieElt1.getSelection();
+        initSaisieElt1(elt1Courant);
+        if (saisieElt2.pasdeSelection()) {
+          initSaisieElt2();
+          etatSelectElt1(elt1Courant);
+
+        } else {
+          Element elt2Courant = saisieElt2.getSelection();
+          initSaisieElt2(elt2Courant);
+          etatSelectElts(elt1Courant, elt2Courant);
+        }
+      }
+    } else {
+      Relation relCourant = (Relation) saisieRelation.getSelection();
+      initSaisieRelation(relCourant);
+      initSaisieElt1(relCourant.getElt1());
+      initSaisieElt2(relCourant.getElt2());
+      etatSelectRel(relCourant);
+    }
+  }
+  public void elementSuivant(int sens) {
+    if (sens>0) saisieRelation.gotoSuivant();
+    else saisieRelation.gotoPrecedent();
+  }
+ public Element elementSelectionne() {
+    if (saisieRelation.pasdeSelection()) return null;
+    return saisieRelation.getSelection();
+  }
+  public void editerElement(Element elt) {
+    // appelé par le panneauEditeur : elt est forcément une relation
+    if (elt.getClass()!=Relation.class)
+      throw new UnsupportedOperationException("Erreur : classe incorrecte");
+    editerRelation((Relation) elt);
+  }
+  public void traiterElementEvent(ElementEvent evt) {
+    switch (evt.getModif()) {
+      case AJOUT_RELATION:
+        Relation rel = (Relation) evt.getElement();
+        editerRelation(rel);
+        return;
+      case SUP_RELATION:
+        if (evt.getElement()==saisieRelation.getSelection()) {
+          initSaisieRelation();
+          initSaisieElt1();
+          initSaisieElt2();
+          etatSelectRien();
+        } else {
+          reafficher();
+        }
+        return;
+      case AJOUT_UNITE:
+        Unite unit = (Unite) evt.getElement();
+        boolean chgEtat = false;
+        if (!saisieTypeElt1.pasdeSelection()&&saisieTypeElt1.getClasseSelection()==Unite.class
+                &&saisieTypeElt1.getTypeSelection().equals(unit.getType())) {
+          initSaisieElt1(uniteCreeElt1 ? unit : null);
+          chgEtat = true;
+        }
+        if (!saisieTypeElt2.pasdeSelection()&&saisieTypeElt2.getClasseSelection()==Unite.class
+                &&saisieTypeElt2.getTypeSelection().equals(unit.getType())) {
+          initSaisieElt2(uniteCreeElt1 ? null : unit);
+          chgEtat = true;
+        }
+        if (chgEtat) {
+          if (uniteCreeElt1) etatSelectElt1(unit);
+          else etatSelectElt2(unit);
+          uniteCreeElt1 = true;
+        }
+        return;
+      case SUP_UNITE:
+      case BORNES_UNITE:
+      case AJOUT_SCHEMA:
+      case MODIF_SCHEMA:
+      case SUP_SCHEMA:
+      case MODIF_VALEUR:
+        reafficher();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getModif()+" oublié dans un switch");
+    }
+  }
+  public void editerRelation(Relation rel) {
+    // appelé  par traiterElementEvent, 
+    // et aussi directement par le panneau éditeur quand il est sollicité par d'autres fenêtres
+    if (!rel.getType().equals(saisieTypeRelations.getTypeSelection())) {
+      saisieTypeRelations.removeActionListener(this);
+      saisieTypeRelations.setSelection(rel.getType());
+      saisieTypeRelations.addActionListener(this);
+    }
+    initSaisieRelation(rel);
+    saisieRelation.setSelection(rel);
+  }
+  public ArrayList<ElementMarque> trouverElementsVises(Unite uniteVisee, TypeMarquage marqueUniteVisee,
+          boolean avecId) {
+    ArrayList<ElementMarque> eltsMarques = new ArrayList<ElementMarque>();
+    ArrayList<Element> eltsVises;
+    Element eltVise;
+    switch (marqueUniteVisee) {
+      case FOND1:
+        eltsVises = Element.trouverElementsParUniteSousjacente(saisieRelation.getElements(), uniteVisee);
+        for (Element elt : eltsVises)
+          eltsMarques.add(new ElementMarque(
+                  elt, marqueUniteVisee, avecId ? saisieRelation.getIdElement(elt) : null));
+        return eltsMarques;
+      case FOND2:
+        eltsVises = Element.trouverElementsParUniteSousjacente(saisieElt1.getElements(), uniteVisee);
+        for (Element elt : eltsVises)
+          eltsMarques.add(new ElementMarque(
+                  elt, marqueUniteVisee, avecId ? saisieElt1.getIdElement(elt) : null));
+        return eltsMarques;
+      case FOND3:
+        eltsVises = Element.trouverElementsParUniteSousjacente(saisieElt2.getElements(), uniteVisee);
+        for (Element elt : eltsVises)
+          eltsMarques.add(new ElementMarque(
+                  elt, marqueUniteVisee, avecId ? saisieElt2.getIdElement(elt) : null));
+        return eltsMarques;
+      case SELECT2:
+      case SELECT1_2:
+        eltVise = saisieElt1.getSelection();
+        eltsMarques.add(new ElementMarque(
+                eltVise, marqueUniteVisee, avecId ? saisieElt1.getIdElement(eltVise) : null));
+        return eltsMarques;
+      case SELECT3:
+      case SELECT1_3:
+        eltVise = saisieElt2.getSelection();
+        eltsMarques.add(new ElementMarque(
+                eltVise, marqueUniteVisee, avecId ? saisieElt2.getIdElement(eltVise) : null));
+        return eltsMarques;
+      default:
+        throw new UnsupportedOperationException("Marquage non prévu : "+marqueUniteVisee);
+
+    }
+  }
+
+  /*
+   * ACTIONS DE L'UTILISATEUR : CHANGEMENTS D'ETAT
+   */
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource()==saisieTypeRelations) {
+        initSaisieRelation();
+        if (saisieElt1.pasdeSelection()) {
+          if (saisieElt2.pasdeSelection()) etatSelectRien();
+          else etatSelectElt2(saisieElt2.getSelection());
+        } else {
+          if (saisieElt2.pasdeSelection())
+            etatSelectElt1(saisieElt1.getSelection());
+          else
+            checkEtatSelectElts(saisieElt1.getSelection(), saisieElt2.getSelection());
+        }
+        return;
+      }
+      if (evt.getSource()==saisieTypeElt1) {
+        forceEffSelectRel();
+        initSaisieElt1();
+        if (saisieElt2.pasdeSelection()) etatSelectRien();
+        else etatSelectElt2(saisieElt2.getSelection());
+        return;
+      }
+      if (evt.getSource()==saisieTypeElt2) {
+        forceEffSelectRel();
+        initSaisieElt2();
+        if (saisieElt1.pasdeSelection()) etatSelectRien();
+        else etatSelectElt1(saisieElt1.getSelection());
+        return;
+      }
+      if (evt.getSource()==saisieRelation) {
+        if (saisieRelation.pasdeSelection()) {
+          if (saisieElt1.pasdeSelection()) {
+            if (saisieElt2.pasdeSelection()) etatSelectRien();
+            else etatSelectElt2(saisieElt2.getSelection());
+          } else {
+            if (saisieElt2.pasdeSelection())
+              etatSelectElt1(saisieElt1.getSelection());
+            else
+              etatSelectElts(saisieElt1.getSelection(), saisieElt2.getSelection());
+          }
+        } else {
+          forceEtatSelectRel((Relation) saisieRelation.getSelection());
+        }
+        return;
+      }
+      if (evt.getSource()==saisieElt1) {
+        if (!saisieRelation.pasdeSelection()) {
+          saisieRelation.removeActionListener(this);
+          saisieRelation.effSelection();
+          saisieRelation.addActionListener(this);
+          saisieElt2.removeActionListener(this);
+          saisieElt2.effSelection();
+          saisieElt2.addActionListener(this);
+        }
+        if (saisieElt1.pasdeSelection()) {
+          if (saisieElt2.pasdeSelection()) etatSelectRien();
+          else etatSelectElt2(saisieElt2.getSelection());
+        } else {
+          if (saisieElt2.pasdeSelection())
+            etatSelectElt1(saisieElt1.getSelection());
+          else
+            checkEtatSelectElts(saisieElt1.getSelection(), saisieElt2.getSelection());
+        }
+        return;
+      }
+      if (evt.getSource()==saisieElt2) {
+        if (!saisieRelation.pasdeSelection()) {
+          saisieRelation.removeActionListener(this);
+          saisieRelation.effSelection();
+          saisieRelation.addActionListener(this);
+          saisieElt1.removeActionListener(this);
+          saisieElt1.effSelection();
+          saisieElt1.addActionListener(this);
+        }
+        if (saisieElt2.pasdeSelection()) {
+          if (saisieElt1.pasdeSelection()) etatSelectRien();
+          else etatSelectElt1(saisieElt1.getSelection());
+        } else {
+          if (saisieElt1.pasdeSelection())
+            etatSelectElt2(saisieElt2.getSelection());
+          else
+            checkEtatSelectElts(saisieElt1.getSelection(), saisieElt2.getSelection());
+        }
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  @Override
+  public void traiterSourisEvent(SourisEvent evt) {
+    switch (evt.getTypeEvent()) {
+      case SELECT_RIEN:
+        saisieElt1.removeActionListener(this);
+        saisieElt1.effSelection();
+        saisieElt1.addActionListener(this);
+        saisieElt2.removeActionListener(this);
+        saisieElt2.effSelection();
+        saisieElt2.addActionListener(this);
+        saisieRelation.removeActionListener(this);
+        saisieRelation.effSelection();
+        saisieRelation.addActionListener(this);
+        etatSelectRien();
+        return;
+      case SELECT_ELEMENT:
+        switch (evt.getMarquageElementVise()) {
+          case FOND1:
+            saisieRelation.setSelection(evt.getElementVise());
+            return;
+          case FOND2:
+            saisieElt1.setSelection(evt.getElementVise());
+            return;
+          case FOND3:
+            saisieElt2.setSelection(evt.getElementVise());
+            return;
+          case SELECT2:
+          case SELECT1_2:
+            forceEffSelectElt2();
+            return;
+          case SELECT3:
+          case SELECT1_3:
+            forceEffSelectElt1();
+            return;
+        }
+        return;
+      case SELECT_TEXTE:
+        if (!saisieElt1.pasdeSelection()&&!saisieElt2.pasdeSelection()) {
+          saisieElt1.removeActionListener(this);
+          saisieElt1.effSelection();
+          saisieElt1.addActionListener(this);
+          saisieElt2.removeActionListener(this);
+          saisieElt2.effSelection();
+          saisieElt2.addActionListener(this);
+          saisieRelation.removeActionListener(this);
+          saisieRelation.effSelection();
+          saisieRelation.addActionListener(this);
+        }
+        bornesSelectTexte = evt.getBornesSelectionTexte();
+        etatSelectTexte();
+        return;
+    }
+    throw new UnsupportedOperationException("Evénement non prévu : "+evt.getTypeEvent());
+  }
+  /*
+   * ACTIONS DE L'UTILISATEUR : BOUTONS
+   */
+  private void creerRelation() {
+    vue.getCorpus().addRelationSaisie((String) saisieTypeRelations.getTypeSelection(),
+            saisieElt1.getSelection(), saisieElt2.getSelection());
+  }
+  private void supprimerRelation() {
+    if (!GMessages.confirmationAction("Supprimer la relation sélectionnée ?"))
+      return;
+    vue.getCorpus().supRelation((Relation) saisieRelation.getSelection());
+  }
+  private void creerUniteElt1() {
+    if (vue.getCorpus().checkPresenceUnite(saisieTypeElt1.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1])
+            &&!GMessages.confirmationAction("Dupliquer cette unité  ?")) return;
+    uniteCreeElt1 = true;
+    vue.getCorpus().addUniteSaisie(saisieTypeElt1.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1]);
+  }
+  private void creerUniteElt2() {
+    if (vue.getCorpus().checkPresenceUnite(saisieTypeElt2.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1])
+            &&!GMessages.confirmationAction("Dupliquer cette unité  ?")) return;
+    uniteCreeElt1 = false;
+    vue.getCorpus().addUniteSaisie(saisieTypeElt2.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1]);
+  }
+
+  /* 
+   * GESTION INTERNE
+   */
+  private void etatSelectRien() {   // rien n'est sélectionné
+    if (saisieTypeRelations.pasdeSelection()) {
+      if (saisieTypeElt1.pasdeSelection()) {
+        if (saisieTypeElt2.pasdeSelection()) panneauTexte.pasDeMarquage();
+        else
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+      } else {
+        if (saisieTypeElt2.pasdeSelection())
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2);
+        else
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2,
+                  Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+      }
+    } else {
+      if (saisieTypeElt1.pasdeSelection()) {
+        if (saisieTypeElt2.pasdeSelection())
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(saisieRelation.getElements()), TypeMarquage.FOND1);
+        else
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(filtreElt2((Relation[]) saisieRelation.getElements())), TypeMarquage.FOND1,
+                  Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+      } else {
+        if (saisieTypeElt2.pasdeSelection())
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(filtreElt1((Relation[]) saisieRelation.getElements())), TypeMarquage.FOND1,
+                  Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2);
+        else
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(filtreElts((Relation[]) saisieRelation.getElements())), TypeMarquage.FOND1,
+                  Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2,
+                  Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+      }
+    }
+    panneauChamps.effacer();
+    creeRelation.setEnabled(false);
+    supprimeRelation.setEnabled(false);
+    creeUniteElt1.setEnabled(false);
+    creeUniteElt2.setEnabled(false);
+  }
+  private void etatSelectTexte() {   // du texte est sélectionné
+    if (saisieElt1.pasdeSelection()) {
+      if (saisieElt2.pasdeSelection()) panneauTexte.pasDeMarquage();
+      else
+        panneauTexte.saisir(null,
+                saisieElt2.getSelection().getUnitesSousjacentes(), TypeMarquage.SELECT3);
+    } else {
+      if (saisieElt2.pasdeSelection())
+        panneauTexte.saisir(null,
+                saisieElt1.getSelection().getUnitesSousjacentes(), TypeMarquage.SELECT2);
+      else // au moins un des 2 elt n'est pas sélectionné
+        throw new UnsupportedOperationException("Cas non prévu");
+    }
+    panneauChamps.effacer();
+    creeRelation.setEnabled(false);
+    supprimeRelation.setEnabled(false);
+    if (!saisieTypeElt1.pasdeSelection()&&saisieTypeElt1.getClasseSelection()==Unite.class
+            &&saisieElt1.pasdeSelection())
+      creeUniteElt1.setEnabled(true);
+    if (!saisieTypeElt2.pasdeSelection()&&saisieTypeElt2.getClasseSelection()==Unite.class
+            &&saisieElt2.pasdeSelection())
+      creeUniteElt2.setEnabled(true);
+  }
+  private void etatSelectElt1(Element elt1) { // seul Elt1 a été choisi
+    if (saisieTypeElt2.pasdeSelection()) {
+      if (saisieTypeRelations.pasdeSelection())
+        panneauTexte.saisir(elt1.getUnite0(), elt1.getUnitesSousjacentes(), TypeMarquage.SELECT2);
+      else
+        panneauTexte.saisir(elt1.getUnite0(), elt1.getUnitesSousjacentes(), TypeMarquage.SELECT2,
+                Element.getUnitesSousjacentes(filtreElt1((Relation[]) saisieRelation.getElements(), elt1)),
+                TypeMarquage.FOND1);
+    } else {
+      if (saisieTypeRelations.pasdeSelection())
+        panneauTexte.saisir(elt1.getUnite0(), elt1.getUnitesSousjacentes(), TypeMarquage.SELECT2,
+                Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+      else
+        panneauTexte.saisir(elt1.getUnite0(), elt1.getUnitesSousjacentes(), TypeMarquage.SELECT2,
+                Element.getUnitesSousjacentes(filtreElt1(filtreElt2((Relation[]) saisieRelation.getElements()), elt1)),
+                TypeMarquage.FOND1,
+                Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+    }
+    panneauChamps.afficher(elt1);
+    creeRelation.setEnabled(false);
+    supprimeRelation.setEnabled(false);
+    creeUniteElt1.setEnabled(false);
+    creeUniteElt2.setEnabled(false);
+  }
+  private void etatSelectElt2(Element elt2) {  // seul Elt2 a été choisi
+    if (saisieTypeElt1.pasdeSelection()) {
+      if (saisieTypeRelations.pasdeSelection())
+        panneauTexte.saisir(elt2.getUnite0(), elt2.getUnitesSousjacentes(), TypeMarquage.SELECT3);
+      else
+        panneauTexte.saisir(elt2.getUnite0(), elt2.getUnitesSousjacentes(), TypeMarquage.SELECT3,
+                Element.getUnitesSousjacentes(filtreElt2((Relation[]) saisieRelation.getElements(), elt2)),
+                TypeMarquage.FOND1);
+    } else {
+      if (saisieTypeRelations.pasdeSelection())
+        panneauTexte.saisir(elt2.getUnite0(), elt2.getUnitesSousjacentes(), TypeMarquage.SELECT3,
+                Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2);
+      else
+        panneauTexte.saisir(elt2.getUnite0(), elt2.getUnitesSousjacentes(), TypeMarquage.SELECT3,
+                Element.getUnitesSousjacentes(filtreElt2(filtreElt1((Relation[]) saisieRelation.getElements()), elt2)),
+                TypeMarquage.FOND1,
+                Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2);
+    }
+    panneauChamps.afficher(elt2);
+    creeRelation.setEnabled(false);
+    supprimeRelation.setEnabled(false);
+    creeUniteElt1.setEnabled(false);
+    creeUniteElt2.setEnabled(false);
+  }
+  private void etatSelectElts(Element elt1, Element elt2) { // Elt1 et Elt2 ont été choisis et ils ne forment pas encore de relation
+    panneauTexte.saisir(elt1.getUnite0(), elt1.getUnitesSousjacentes(), TypeMarquage.SELECT2,
+            elt2.getUnitesSousjacentes(), TypeMarquage.SELECT3);
+    panneauChamps.effacer();
+    if (!saisieTypeRelations.pasdeSelection()) {
+      creeRelation.setEnabled(true);
+//      Boutons.setDefaut(creeRelation, true);
+    }
+    supprimeRelation.setEnabled(false);
+    creeUniteElt1.setEnabled(false);
+    creeUniteElt2.setEnabled(false);
+  }
+  private void etatSelectRel(Relation rel) {  // une relation est sélectionnée
+    panneauTexte.saisir(rel.getElt1().getUnite0(),
+            rel.getElt1().getUnitesSousjacentes(), TypeMarquage.SELECT1_2,
+            rel.getElt2().getUnitesSousjacentes(), TypeMarquage.SELECT1_3);
+//            Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2,
+//            Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+    panneauChamps.afficher(rel);
+    creeRelation.setEnabled(false);
+    supprimeRelation.setEnabled(true);
+    creeUniteElt1.setEnabled(false);
+    creeUniteElt2.setEnabled(false);
+  }
+  private Relation[] filtreElt1(Relation[] relations) {
+    Class classe = saisieTypeElt1.getClasseSelection();
+    String type = saisieTypeElt1.getTypeSelection();
+    ArrayList<Integer> indsAOter = new ArrayList<Integer>();
+    for (int i = 0; i<relations.length; i++) {
+      Element elt1 = relations[i].getElt1();
+      if (elt1.getClass()!=classe||!elt1.getType().equals(type))
+        indsAOter.add(i);
+    }
+    return Tableaux.oterRelations(relations, indsAOter);
+  }
+  private Relation[] filtreElt1(Relation[] relations, Element elt1) {
+    ArrayList<Relation> rels = new ArrayList<Relation>();
+    for (Relation rel : relations) if (elt1==rel.getElt1()) rels.add(rel);
+    return rels.toArray(new Relation[0]);
+  }
+  private Relation[] filtreElt2(Relation[] relations) {
+    Class classe = saisieTypeElt2.getClasseSelection();
+    String type = saisieTypeElt2.getTypeSelection();
+    ArrayList<Integer> indsAOter = new ArrayList<Integer>();
+    for (int i = 0; i<relations.length; i++) {
+      Element elt2 = relations[i].getElt2();
+      if (elt2.getClass()!=classe||!elt2.getType().equals(type))
+        indsAOter.add(i);
+    }
+    return Tableaux.oterRelations(relations, indsAOter);
+  }
+  private Relation[] filtreElt2(Relation[] relations, Element elt2) {
+    ArrayList<Relation> rels = new ArrayList<Relation>();
+    for (Relation rel : relations) if (elt2==rel.getElt2()) rels.add(rel);
+    return rels.toArray(new Relation[0]);
+  }
+  private Relation[] filtreElts(Relation[] relations) {
+    Class classe1 = saisieTypeElt1.getClasseSelection();
+    String type1 = saisieTypeElt1.getTypeSelection();
+    Class classe2 = saisieTypeElt2.getClasseSelection();
+    String type2 = saisieTypeElt2.getTypeSelection();
+    ArrayList<Integer> indsAOter = new ArrayList<Integer>();
+    for (int i = 0; i<relations.length; i++) {
+      Element elt1 = relations[i].getElt1();
+      Element elt2 = relations[i].getElt2();
+      if (elt1.getClass()!=classe1||!elt1.getType().equals(type1)
+              ||elt2.getClass()!=classe2||!elt2.getType().equals(type2))
+        indsAOter.add(i);
+    }
+    return Tableaux.oterRelations(relations, indsAOter);
+  }
+  private void checkEtatSelectElts(Element elt1, Element elt2) {
+    if (!saisieTypeRelations.pasdeSelection())
+      for (Relation rel : (Relation[]) saisieRelation.getElements()) {
+        if (rel.getElt1()==elt1&&rel.getElt2()==elt2) {
+          saisieRelation.setSelection(rel);
+          return;
+        }
+      }
+    etatSelectElts(elt1, elt2);
+  }
+  private void forceEtatSelectRel(Relation rel) {
+    if (saisieTypeElt1.pasdeSelection()||saisieTypeElt1.getClasseSelection()!=rel.getElt1().getClass()
+            ||!saisieTypeElt1.getTypeSelection().equals(rel.getElt1().getType())) {
+      saisieTypeElt1.removeActionListener(this);
+      saisieTypeElt1.setSelection(rel.getElt1().getClass(), rel.getElt1().getType());
+      saisieTypeElt1.addActionListener(this);
+    }
+    initSaisieElt1(rel.getElt1());
+    if (saisieTypeElt2.pasdeSelection()||saisieTypeElt2.getClasseSelection()!=rel.getElt2().getClass()
+            ||!saisieTypeElt2.getTypeSelection().equals(rel.getElt2().getType())) {
+      saisieTypeElt2.removeActionListener(this);
+      saisieTypeElt2.setSelection(rel.getElt2().getClass(), rel.getElt2().getType());
+      saisieTypeElt2.addActionListener(this);
+    }
+    initSaisieElt2(rel.getElt2());
+    etatSelectRel(rel);
+  }
+  private void forceEffSelectElt1() {
+    if (saisieElt1.pasdeSelection()) return;
+    if (!saisieRelation.pasdeSelection()) {
+      saisieRelation.removeActionListener(this);
+      saisieRelation.effSelection();
+      saisieRelation.addActionListener(this);
+    }
+    saisieElt1.effSelection();
+  }
+  private void forceEffSelectElt2() {
+    if (saisieElt2.pasdeSelection()) return;
+    if (!saisieRelation.pasdeSelection()) {
+      saisieRelation.removeActionListener(this);
+      saisieRelation.effSelection();
+      saisieRelation.addActionListener(this);
+    }
+    saisieElt2.effSelection();
+  }
+  private void forceEffSelectRel() {
+    if (saisieRelation.pasdeSelection()) return;
+    saisieRelation.removeActionListener(this);
+    saisieRelation.effSelection();
+    saisieRelation.addActionListener(this);
+  }
+  private void initSaisieRelation(Relation rel) {
+    saisieRelation.removeActionListener(this);
+    if (saisieTypeRelations.pasdeSelection()) saisieRelation.setModeleVide();
+    else {
+      String type0 = saisieTypeRelations.getTypeSelection();
+      Relation[] relations = vue.getRelationsAVoir(type0);
+      saisieRelation.setModele(relations, vue.getIdRelations(type0, relations));
+    }
+    if (rel==null) saisieRelation.effSelection();
+    else saisieRelation.setSelection(rel);
+    saisieRelation.addActionListener(this);
+    saisieRelation.revalidate();
+  }
+  private void initSaisieRelation() {
+    initSaisieRelation(null);
+  }
+  private void initSaisieElt1(Element elt1) {
+    saisieElt1.removeActionListener(this);
+    if (saisieTypeElt1.pasdeSelection()) saisieElt1.setModeleVide();
+    else {
+      Class<? extends Element> classe = saisieTypeElt1.getClasseSelection();
+      String type = saisieTypeElt1.getTypeSelection();
+      saisieElt1.setModele(vue.getElements(classe, type), vue.getIdElements(classe, type));
+    }
+    if (elt1==null) saisieElt1.effSelection();
+    else saisieElt1.setSelection(elt1);
+    saisieElt1.addActionListener(this);
+    saisieElt1.revalidate();
+  }
+  private void initSaisieElt1() {
+    initSaisieElt1(null);
+  }
+  private void initSaisieElt2(Element elt2) {
+    saisieElt2.removeActionListener(this);
+    if (saisieTypeElt2.pasdeSelection()) saisieElt2.setModeleVide();
+    else {
+      Class<? extends Element> classe = saisieTypeElt2.getClasseSelection();
+      String type = saisieTypeElt2.getTypeSelection();
+      saisieElt2.setModele(vue.getElements(classe, type), vue.getIdElements(classe, type));
+    }
+
+    if (elt2==null) saisieElt2.effSelection();
+    else saisieElt2.setSelection(elt2);
+    saisieElt2.addActionListener(this);
+    saisieElt2.revalidate();
+  }
+  private void initSaisieElt2() {
+    initSaisieElt2(null);
+  }
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/PanneauCommandesRelations.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVue.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVue.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVue.java	(revision 481)
@@ -0,0 +1,433 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.vue;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.SimpleAttributeSet;
+import visuAnalec.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class VisuVue extends JFrame implements VueListener, ListSelectionListener, ChangeListener {
+  static private VisuVue instance = null;
+  private Vue vue;
+  // Les données spécifiant la vue (échangées avec vue à l'initialisation et à la validation)
+  private HashMap<Class<? extends Element>, HashMap<String, Boolean>> isTypesAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, Boolean>>();
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> niveauxChampsAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> positionsChampsAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> modifiabiliteChampsAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, String>> champsId =
+          new HashMap<Class<? extends Element>, HashMap<String, String>>();
+  private HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> stylesElements =
+          new HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> stylesValeursElements =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>>();  // le tableau des types à voir
+  private JTable tableauTypes;
+  private JTabbedPane panneauTabule;
+  VisuVueExtraction visuVueExtraction;
+  VisuVuePresentation visuVuePresentation;
+  VisuVueColoriage visuVueColoriage;
+
+  static public void newVisuVue(Container fenetre, Vue vue) {
+    if (instance!=null) instance.fermerFenetre();
+    instance = new VisuVue(fenetre, vue);
+  }
+
+  @SuppressWarnings("unchecked")
+  private VisuVue(Container fenetre, Vue vue) {
+    super("Gestion de la vue");
+    Point locFenetre = new Point(fenetre.getX()+20, fenetre.getY()+50);
+    Dimension dimFenetre = new Dimension(fenetre.getWidth(), fenetre.getHeight()-30);
+    setLocation(locFenetre);
+    setSize(dimFenetre);
+    this.vue = vue;
+    vue.addEventListener(this);
+    // initialisation des données spécifiant la vue
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      isTypesAVoir.put(classe, new HashMap<String, Boolean>());
+      for (String type : vue.getTypes(classe))
+        isTypesAVoir.get(classe).put(type, false);
+      for (String type : vue.getTypesAVoir(classe))
+        isTypesAVoir.get(classe).put(type, true);
+      champsAVoir.put(classe, new HashMap<String, ArrayList<String>>());
+      adressesAVoir.put(classe, new HashMap<String, ArrayList<Adresse>>());
+      positionsChampsAVoir.put(classe, new HashMap<String, HashMap<String, Integer>>());
+      niveauxChampsAVoir.put(classe, new HashMap<String, HashMap<String, Integer>>());
+      modifiabiliteChampsAVoir.put(classe, new HashMap<String, HashMap<String, Boolean>>());
+      for (String type : vue.getTypes(classe)) {
+        champsAVoir.get(classe).put(type, new ArrayList<String>());
+        adressesAVoir.get(classe).put(type, new ArrayList<Adresse>());
+        niveauxChampsAVoir.get(classe).put(type, new HashMap<String, Integer>());
+        positionsChampsAVoir.get(classe).put(type, new HashMap<String, Integer>());
+        modifiabiliteChampsAVoir.get(classe).put(type, new HashMap<String, Boolean>());
+      }
+      for (String type : vue.getTypesAVoir(classe)) {
+        champsAVoir.get(classe).put(type, vue.getListeChamps(classe, type));
+        for (String nom : vue.getNomsChamps(classe, type))
+          adressesAVoir.get(classe).get(type).add(vue.getAdresseChamps(classe, type, nom));
+      }
+      champsId.put(classe, new HashMap<String, String>());
+      for (String type : vue.getTypesAVoir(classe))
+        if (vue.getChampId(classe, type)!=null)
+          champsId.get(classe).put(type, vue.getChampId(classe, type));
+      for (String type : vue.getTypesAVoir(classe)) {
+        positionsChampsAVoir.get(classe).put(type, vue.getPositionsChampsAVoir(classe, type));
+        niveauxChampsAVoir.get(classe).put(type, vue.getNiveauxChampsAVoir(classe, type));
+        modifiabiliteChampsAVoir.get(classe).put(type, new HashMap<String, Boolean>());
+        for (String champ : vue.getNomsChamps(classe, type))
+          modifiabiliteChampsAVoir.get(classe).get(type).put(champ, vue.isChampModifiable(classe, type, champ));
+      }
+      stylesElements.put(classe, new HashMap<String, SimpleAttributeSet>());
+      for (String type : vue.getTypesAVoir(classe))
+        if (vue.getStyleElements(classe, type)!=null)
+          stylesElements.get(classe).put(type, vue.getStyleElements(classe, type));
+      stylesValeursElements.put(classe, new HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>());
+      for (String type : vue.getTypesAVoir(classe))
+        if (vue.getStyleValeursElements(classe, type)!=null)
+          stylesValeursElements.get(classe).put(type, vue.getStyleValeursElements(classe, type));
+    }
+    // Tableau des types d'éléments à visualiser
+    Box panneauTypes = Box.createVerticalBox();
+
+    panneauTypes.add(Box.createVerticalGlue());
+    ModeleTableauTypes donneesTypes = new ModeleTableauTypes();
+    tableauTypes = new JTable(donneesTypes) {
+      @Override
+      public boolean isCellSelected(int row, int col) {
+        if (col==1) {
+          return false;
+        }
+        String classeType = ((ModeleTableauTypes) getModel()).classesTypes[row];
+        return isRowSelected(row)&&isTypesAVoir.get(GVisu.getClasse(classeType)).get(GVisu.getType(classeType));
+      }
+    };
+
+    tableauTypes.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+    tableauTypes.getSelectionModel().addListSelectionListener(this);
+
+    JScrollPane scroll1 = new JScrollPane(tableauTypes);
+
+    scroll1.setBorder(
+            new TitledBorder("Types d'éléments à visualiser"));
+    panneauTypes.add(scroll1);
+    // les boutons de validation
+
+    panneauTypes.add(Box.createVerticalGlue());
+    JPanel pCommandesValidation = new JPanel(new FlowLayout());
+    JButton valideModifs = new JButton(
+            new GAction("Valider") {
+              public void executer() {
+                validerModifVue();
+              }
+            ;
+    });
+
+    JButton annuleModifs = new JButton(
+            new GAction("Annuler") {
+              public void executer() {
+                annulerModifVue();
+              }
+            ;
+
+    });
+    pCommandesValidation.add(valideModifs, CENTER_ALIGNMENT);
+
+    pCommandesValidation.add(annuleModifs, CENTER_ALIGNMENT);
+
+    panneauTypes.add(pCommandesValidation);
+    // Les panneaux tabulés Extraction, Sélection, Présentation, Coloriage
+    panneauTabule = new JTabbedPane();
+
+    panneauTabule.addChangeListener(
+            this);
+    visuVueExtraction = new VisuVueExtraction(this, vue, champsAVoir, adressesAVoir);
+
+    panneauTabule.add(
+            "Extraction de propriétés", visuVueExtraction);
+    visuVuePresentation = new VisuVuePresentation(this, vue, champsAVoir, champsId,
+            modifiabiliteChampsAVoir, niveauxChampsAVoir, positionsChampsAVoir);
+
+    panneauTabule.add(
+            "Présentation des champs", visuVuePresentation);
+    visuVueColoriage = new VisuVueColoriage(this, vue, champsAVoir, adressesAVoir,
+            stylesElements, stylesValeursElements);
+
+    panneauTabule.add(
+            "Coloriage d'éléments", visuVueColoriage);
+    // cadre global de la fenêtre
+    JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panneauTypes, panneauTabule);
+
+    setContentPane(split);
+
+    setVisible(
+            true);
+    split.setDividerLocation(
+            0.25);
+//    visuVueExtraction.agencerPanneaux();
+//
+    // initialisation de la sélection d'un premier type à voir (si possible)
+
+
+    for (int i = 0;
+            i<donneesTypes.getRowCount();
+            i++) {
+      if ((Boolean) donneesTypes.getValueAt(i, 1)) {
+        tableauTypes.setRowSelectionInterval(i, i);
+        tableauTypes.setColumnSelectionInterval(0, 0);
+        break;
+      }
+    }
+    // Fermeture de la fenêtre
+
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+
+    addWindowListener(
+            new WindowAdapter() {
+              @Override
+              public void windowClosing(WindowEvent evt) {
+                confirmerFermerFenetre();
+              }
+            });
+  }
+
+  public void stateChanged(ChangeEvent evt) {
+    if (((JTabbedPane) evt.getSource())!=panneauTabule) return;
+    try {
+      switch (panneauTabule.getSelectedIndex()) {
+        case 0:
+          return;
+        case 1:
+          visuVuePresentation.reinitialiser();
+          return;
+        case 2:
+          visuVueColoriage.reinitialiser();
+          return;
+        default:
+          throw new IndexOutOfBoundsException();
+      }
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  private void validerModifVue() {
+    vue.modifierVueParSaisie(isTypesAVoir, adressesAVoir, champsAVoir, champsId, modifiabiliteChampsAVoir,
+            positionsChampsAVoir, niveauxChampsAVoir, stylesElements, stylesValeursElements);
+  }
+
+  private void annulerModifVue() {
+    fermerFenetre();
+  }
+
+  void ajouterChamp(Class<? extends Element> classe, String type, Adresse ad) {
+    String champ = Vue.trouveNomChampParDefaut(ad, champsAVoir.get(classe).get(type));
+    champsAVoir.get(classe).get(type).add(champ);
+    adressesAVoir.get(classe).get(type).add(ad);
+    modifiabiliteChampsAVoir.get(classe).get(type).put(champ, ad.getLongueur()==1);
+    positionsChampsAVoir.get(classe).get(type).put(champ, 0);
+    niveauxChampsAVoir.get(classe).get(type).put(champ, 0);
+  }
+
+  void renommerChamp(Class<? extends Element> classe, String type, int rg, String newNom) {
+    String oldNom = champsAVoir.get(classe).get(type).get(rg);
+    champsAVoir.get(classe).get(type).set(rg, newNom);
+    if (champsId.get(classe).containsKey(type)&&oldNom.equals(champsId.get(classe).get(type))) {
+      champsId.get(classe).put(type, newNom);
+    }
+    modifiabiliteChampsAVoir.get(classe).get(type).put(newNom,
+            modifiabiliteChampsAVoir.get(classe).get(type).get(oldNom));
+    modifiabiliteChampsAVoir.get(classe).get(type).remove(oldNom);
+    positionsChampsAVoir.get(classe).get(type).put(newNom,
+            positionsChampsAVoir.get(classe).get(type).get(oldNom));
+    positionsChampsAVoir.get(classe).get(type).remove(oldNom);
+    niveauxChampsAVoir.get(classe).get(type).put(newNom,
+            niveauxChampsAVoir.get(classe).get(type).get(oldNom));
+    niveauxChampsAVoir.get(classe).get(type).remove(oldNom);
+    if (stylesValeursElements.get(classe).containsKey(type)
+            &&stylesValeursElements.get(classe).get(type).containsKey(oldNom)) {
+      stylesValeursElements.get(classe).get(type).
+              put(newNom, stylesValeursElements.get(classe).get(type).get(oldNom));
+      stylesValeursElements.get(classe).get(type).remove(oldNom);
+    }
+  }
+
+  void supprimerChamp(Class<? extends Element> classe, String type, int rg) {
+    String oldNom = champsAVoir.get(classe).get(type).get(rg);
+    champsAVoir.get(classe).get(type).remove(rg);
+    adressesAVoir.get(classe).get(type).remove(rg);
+    if (champsId.get(classe).containsKey(type)&&oldNom.equals(champsId.get(classe).get(type))) {
+      champsId.get(classe).remove(type);
+      modifiabiliteChampsAVoir.get(classe).get(type).remove(oldNom);
+      positionsChampsAVoir.get(classe).get(type).remove(oldNom);
+      niveauxChampsAVoir.get(classe).get(type).remove(oldNom);
+      if (stylesValeursElements.get(classe).containsKey(type)
+              &&stylesValeursElements.get(classe).get(type).containsKey(oldNom)) {
+        stylesValeursElements.get(classe).get(type).remove(oldNom);
+      }
+    }
+  }
+  String getPropChamp(Class<? extends Element> classe, String type, String champ) {
+    ArrayList<String> champs = champsAVoir.get(classe).get(type);
+    if(champs==null) return "";
+    int ind = champs.indexOf(champ);
+    if(ind<0) return "";
+     String prop = adressesAVoir.get(classe).get(type).get(ind).prop;
+     if(prop==null) return "";
+     return prop;
+   
+  }
+
+  public void valueChanged(ListSelectionEvent evt) {
+    if ((ListSelectionModel) evt.getSource()!=tableauTypes.getSelectionModel())
+      return;
+    try {
+      if (evt.getValueIsAdjusting()) {
+        return;
+      }
+      int row = ((ListSelectionModel) evt.getSource()).getMinSelectionIndex();
+      if (row<0) {
+        visuVueExtraction.setTypeSelected(null, null);
+        visuVuePresentation.setTypeSelected(null, null);
+        visuVueColoriage.setTypeSelected(null, null);
+      } else {
+        String classeType = ((ModeleTableauTypes) tableauTypes.getModel()).classesTypes[row];
+        Class<? extends Element> classeSelected = GVisu.getClasse(classeType);
+        String typeSelected = GVisu.getType(classeType);
+        if (isTypesAVoir.get(classeSelected).get(typeSelected)) {
+          visuVueExtraction.setTypeSelected(classeSelected, typeSelected);
+          visuVuePresentation.setTypeSelected(classeSelected, typeSelected);
+          visuVueColoriage.setTypeSelected(classeSelected, typeSelected);
+        } else {
+          visuVueExtraction.setTypeSelected(null, null);
+          visuVuePresentation.setTypeSelected(null, null);
+          visuVueColoriage.setTypeSelected(null, null);
+        }
+      }
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case CORPUS_SAVED:
+          fermerFenetre();
+          return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre vue présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        return;
+      case MODIF_VUE:
+        fermerFenetre();  // ferme même si la modif vient d'ici
+        return;
+      case MODIF_STRUCTURE:
+        fermerFenetre();
+        return;
+      case MODIF_ELEMENT:
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+
+  private void confirmerFermerFenetre() {
+    try {
+      int rep = JOptionPane.showOptionDialog(this, "Valider les modifications ?",
+              "Fermeture de la fenêtre \"Structure des annotations\"", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+              null, new Object[]{"Oui", "Non", "Annuler"}, "Non");
+      if (rep==2) {
+        return;
+      }
+      if (rep==0) {
+        validerModifVue();
+      }
+      annulerModifVue();
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+
+
+  }
+
+  private class ModeleTableauTypes extends AbstractTableModel {
+    String[] classesTypes;
+
+    private ModeleTableauTypes() {
+      super();
+      classesTypes = GVisu.getClassesTypes(vue.getTypes(Unite.class), vue.getTypes(Relation.class), vue.getTypes(Schema.class));
+    }
+
+    public int getColumnCount() {
+      return 2;
+    }
+
+    public int getRowCount() {
+      return classesTypes.length;
+    }
+
+    public Object getValueAt(int row, int col) {
+      String classeType = classesTypes[row];
+      return col==0 ? classeType : isTypesAVoir.get(GVisu.getClasse(classeType)).get(GVisu.getType(classeType));
+    }
+
+    @Override
+    public String getColumnName(int col) {
+      return col==0 ? "Types d'éléments" : "à voir";
+    }
+
+    @Override
+    public Class getColumnClass(int col) {
+      return col==0 ? String.class : Boolean.class;
+    }
+
+    @Override
+    public boolean isCellEditable(int row, int col) {
+      return col==1;
+    }
+
+    @Override
+    public void setValueAt(Object aValue, int row, int col) {
+      if (col==1) {
+        String classeType = classesTypes[row];
+        isTypesAVoir.get(GVisu.getClasse(classeType)).put(GVisu.getType(classeType), (Boolean) aValue);
+        tableauTypes.clearSelection();  // important : à faire même quand aValue est vrai
+        // pour que l'événement "ListSelection change" soit émis dans tous les cas
+        if ((Boolean) aValue) {
+          tableauTypes.setRowSelectionInterval(row, row);
+          tableauTypes.setColumnSelectionInterval(0, 0);
+        }
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVue.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVueExtraction.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVueExtraction.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVueExtraction.java	(revision 481)
@@ -0,0 +1,243 @@
+package visuAnalec.vue;
+
+import java.awt.BorderLayout;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.TreeExpansionEvent;
+import javax.swing.event.TreeWillExpandListener;
+import javax.swing.table.*;
+import javax.swing.tree.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class VisuVueExtraction extends JPanel implements TreeWillExpandListener {
+  private VisuVue visuVue;
+  private Vue vue;
+  private JTable tableauChampsAVoir;
+  private JTree arbreChampsAExtraire;
+  private JPopupMenuChamp popupMenuChamp;
+  private Class<? extends Element> classeSelected;
+  private String typeSelected;
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir;
+  private JPanel panneauChampsExtraits;
+  private JPanel panneauAExtraire;
+  VisuVueExtraction(VisuVue visuVue, Vue vue,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir) {
+    super(new BorderLayout());
+    this.visuVue = visuVue;
+    this.vue = vue;
+    this.champsAVoir = champsAVoir;
+    this.adressesAVoir = adressesAVoir;
+    classeSelected = null;
+    typeSelected = null;
+//    // Panneau des champs extraits à visualiser
+  panneauChampsExtraits =new JPanel(new BorderLayout());
+    // Le tableau des champs à visualiser
+    ModeleTableauChampsAVoir donneesChampsAVoir = new ModeleTableauChampsAVoir();
+    tableauChampsAVoir = new JTable(donneesChampsAVoir);
+    popupMenuChamp = new JPopupMenuChamp();
+    popupMenuChamp.add(new ActionSupprimerChamp());
+
+    MouseListener popupListener = new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {
+        maybeShowPopup(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        maybeShowPopup(e);
+      }
+      private void maybeShowPopup(MouseEvent e) {
+        try {
+          if (e.isPopupTrigger()) {
+            popupMenuChamp.rang = tableauChampsAVoir.rowAtPoint(e.getPoint());
+            ((JMenuItem) (popupMenuChamp.getSubElements()[0])).setText("supprimer le champ \"" +
+                    tableauChampsAVoir.getValueAt(popupMenuChamp.rang, 0) + "\"");
+            popupMenuChamp.show(e.getComponent(), e.getX(), e.getY());
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    };
+    tableauChampsAVoir.addMouseListener(popupListener);
+    tableauChampsAVoir.addKeyListener(new KeyAdapter() {
+      @Override
+      public void keyPressed(KeyEvent e) {
+        try {
+          if (e.getKeyCode() == KeyEvent.VK_DELETE && tableauChampsAVoir.getSelectedRowCount() == 1) {
+            ((ModeleTableauChampsAVoir) tableauChampsAVoir.getModel()).supprimerChamp(tableauChampsAVoir.getSelectedRow());
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    });
+    JScrollPane scroll2 = new JScrollPane(tableauChampsAVoir);
+    scroll2.setBorder(new TitledBorder("Propriétés à visualiser"));
+    panneauChampsExtraits.add(scroll2, BorderLayout.CENTER);
+
+    // Panneau des champs à extraire
+    panneauAExtraire = new JPanel(new BorderLayout());
+    ModeleArbreChampsAExtraire donneesChampsAExtraire = new ModeleArbreChampsAExtraire(vue);
+    arbreChampsAExtraire = new JTree(donneesChampsAExtraire);
+    arbreChampsAExtraire.addTreeWillExpandListener(this);
+    MouseListener ml2 = new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {
+        try {
+          TreePath selPath = arbreChampsAExtraire.getPathForLocation(e.getX(), e.getY());
+          if (selPath != null && e.getClickCount() == 2) {
+            NoeudChampAExtraire noeud = (NoeudChampAExtraire) selPath.getLastPathComponent();
+            if (noeud.getAllowsChildren()) return;
+            else ajouterChamp(noeud.getAdresse());
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    };
+    arbreChampsAExtraire.addMouseListener(ml2);
+    JScrollPane scroll3 = new JScrollPane(arbreChampsAExtraire);
+    scroll3.setBorder(new TitledBorder("Extraction de nouvelles propriétés à visualiser"));
+    panneauAExtraire.add(scroll3, BorderLayout.CENTER);
+      // Dimensionnement 
+    add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,panneauChampsExtraits, panneauAExtraire),
+            BorderLayout.CENTER);
+  }
+//  void agencerPanneaux() {
+//        JSplitPane split = (JSplitPane) panneauChampsExtraits.getParent();
+//    split.setDividerLocation(2. / 3);
+//    revalidate();
+//    repaint();
+//  }
+  public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
+    NoeudChampAExtraire noeud = (NoeudChampAExtraire) event.getPath().getLastPathComponent();
+    if(noeud.isLeaf()) {
+      ModeleArbreChampsAExtraire donnees = (ModeleArbreChampsAExtraire) arbreChampsAExtraire.getModel();
+     donnees.setSousArbre(noeud);
+    }
+  }
+  public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
+    return;
+  }
+  void setTypeSelected(Class<? extends Element> classe, String type) {
+    classeSelected = classe;
+    typeSelected = type;
+    ((ModeleTableauChampsAVoir) tableauChampsAVoir.getModel()).fireTableDataChanged();
+    ((ModeleArbreChampsAExtraire) arbreChampsAExtraire.getModel()).setModele(classeSelected, typeSelected);
+  }
+  private void ajouterChamp(Adresse ad) {
+     for (Adresse ad0 : adressesAVoir.get(classeSelected).get(typeSelected)) {
+      if (ad.toString().equals(ad0.toString())) {
+        JOptionPane.showMessageDialog(tableauChampsAVoir.getTopLevelAncestor(),
+                "Ajout impossible : le champ d'adresse  " + ad.toString() + " existe déjà",
+                "Erreur d'ajout de champ", JOptionPane.ERROR_MESSAGE);
+        return;
+      }
+    }
+    visuVue.ajouterChamp(classeSelected, typeSelected, ad);
+    ((ModeleTableauChampsAVoir) tableauChampsAVoir.getModel()).fireTableDataChanged();
+  }
+
+  private class ModeleTableauChampsAVoir extends AbstractTableModel {
+    public int getColumnCount() {
+      return 2;
+    }
+    public int getRowCount() {
+      return (typeSelected == null || !champsAVoir.get(classeSelected).containsKey(typeSelected)) ? 0 : 
+        champsAVoir.get(classeSelected).get(typeSelected).size();
+    }
+    public Object getValueAt(int row, int col) {
+      return col == 0 ? champsAVoir.get(classeSelected).get(typeSelected).get(row) : 
+        adressesAVoir.get(classeSelected).get(typeSelected).get(row).toString();
+    }
+    @Override
+    public String getColumnName(int col) {
+      return col == 0 ? "Noms abrégés des champs" : "Noms complets des propriétés";
+    }
+    @Override
+    public boolean isCellEditable(int row, int col) {
+      return col == 0;
+    }
+    @Override
+    public void setValueAt(Object aValue, int row, int col) {
+      if (col != 0)   throw new IndexOutOfBoundsException();
+    visuVue.renommerChamp(classeSelected, typeSelected, row,  (String) aValue);
+    }
+    void supprimerChamp(int row) {
+      visuVue.supprimerChamp(classeSelected, typeSelected,row);
+      fireTableDataChanged();
+    }
+  }
+
+  private static class JPopupMenuChamp extends JPopupMenu {
+    int rang = -1;
+  }
+
+  private class ActionSupprimerChamp extends AbstractAction {
+    ActionSupprimerChamp() {
+      super("supprimer le champ");
+    }
+    public void actionPerformed(ActionEvent e) {
+      try {
+        int rg = ((JPopupMenuChamp) ((JMenuItem) e.getSource()).getParent()).rang;
+        ((ModeleTableauChampsAVoir) tableauChampsAVoir.getModel()).supprimerChamp(rg);
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+  }
+
+  private static class ModeleArbreChampsAExtraire extends DefaultTreeModel {
+    Vue vue;
+    ModeleArbreChampsAExtraire(Vue vue) {
+      super(null, true);
+      this.vue = vue;
+    }
+    void setModele(Class<? extends Element> classeRacine, String typeRacine) {
+      if (typeRacine == null) {
+        setRoot(null);
+      } else {
+        NoeudChampAExtraire racine = new NoeudChampAExtraire(
+                new Adresse(new Jalon(Jalon.Origine.ELT_0, classeRacine, typeRacine)));
+        setRoot(racine);
+        setSousArbre(racine);
+      }
+      reload();
+    }
+    void setSousArbre(NoeudChampAExtraire noeud) {
+      Adresse adresse = noeud.getAdresse();
+      for (String prop : vue.getNomsProps(adresse)) {
+        noeud.add(new NoeudChampAExtraire(new Adresse(adresse, prop)));
+      }
+      Jalon[] jalons = vue.getNextJalonsPotentiels(adresse);
+      for (Jalon jalon : jalons) {
+        noeud.add(new NoeudChampAExtraire(new Adresse(adresse, jalon)));
+      }
+    }
+  }
+
+  private static class NoeudChampAExtraire extends DefaultMutableTreeNode {
+    NoeudChampAExtraire(Adresse adresse) {
+      super(adresse, adresse.prop == null);
+    }
+    Adresse getAdresse() {
+      return (Adresse) getUserObject();
+    }
+    @Override
+    public String toString() {
+      if (getAdresse().prop == null) return getAdresse().getLastJalon().toString();
+      return getAdresse().prop;
+    }
+  }
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVueExtraction.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVueColoriage.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVueColoriage.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVueColoriage.java	(revision 481)
@@ -0,0 +1,434 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.vue;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.ArrayList;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+import javax.swing.tree.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class VisuVueColoriage extends JPanel implements TreeWillExpandListener {
+  private VisuVue visuVue;
+  private int indexTab;
+  private Vue vue;
+  private JTable tableauValeursAColorier;
+  private JTree arbreValeursAChoisir;
+  private JPopupMenuValeur popupMenuValeur;
+  private Class<? extends Element> classeSelected;
+  private String typeSelected;
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> stylesElements;
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> stylesValeursElements;
+  private JPanel panneauValeursChoisies;
+  private JPanel panneauValeursAChoisir;
+  VisuVueColoriage(VisuVue visuVue, Vue vue,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> stylesElements,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> stylesValeursElements) {
+    super(new BorderLayout());
+    this.visuVue = visuVue;
+    this.vue = vue;
+    this.champsAVoir = champsAVoir;
+    this.adressesAVoir = adressesAVoir;
+    this.stylesElements = stylesElements;
+    this.stylesValeursElements = stylesValeursElements;
+    classeSelected = null;
+    typeSelected = null;
+//    // Panneau des valeurs choisies à colorier
+    panneauValeursChoisies = new JPanel();
+    // Le tableau des valeurs à colorier
+    ModeleTableauValeursAColorier donneesValeursAColorier = new ModeleTableauValeursAColorier();
+    tableauValeursAColorier = new JTable(donneesValeursAColorier);
+    GVisu.CouleurTableEditor couleurcombo =
+            new GVisu.CouleurTableEditor(GVisu.getCouleursEtNoirEtBlanc());
+    tableauValeursAColorier.setDefaultEditor(Color.class, couleurcombo);
+    tableauValeursAColorier.setDefaultRenderer(Color.class, new GVisu.CouleurCellRenderer());
+    popupMenuValeur = new JPopupMenuValeur();
+    popupMenuValeur.add(new ActionSupprimerValeur());
+
+    MouseListener popupListener = new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {
+        maybeShowPopup(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        maybeShowPopup(e);
+      }
+      private void maybeShowPopup(MouseEvent e) {
+        try {
+          if (e.isPopupTrigger()) {
+            int rg = popupMenuValeur.rang;
+            popupMenuValeur.rang = tableauValeursAColorier.rowAtPoint(e.getPoint());
+            ((JMenuItem) (popupMenuValeur.getSubElements()[0])).setText("supprimer ce coloriage");
+            popupMenuValeur.show(e.getComponent(), e.getX(), e.getY());
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    };
+    tableauValeursAColorier.addMouseListener(popupListener);
+    tableauValeursAColorier.addKeyListener(new KeyAdapter() {
+      @Override
+      public void keyPressed(KeyEvent e) {
+        try {
+          if (e.getKeyCode()==KeyEvent.VK_DELETE&&tableauValeursAColorier.getSelectedRowCount()==1) {
+            ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).supprimerRangee(
+                    tableauValeursAColorier.getSelectedRow());
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    });
+    JScrollPane scroll2 = new JScrollPane(tableauValeursAColorier);
+    scroll2.setBorder(new TitledBorder("Elements à colorier"));
+    panneauValeursChoisies.add(scroll2, BorderLayout.CENTER);
+    // Panneau des valeurs à choisir
+    panneauValeursAChoisir = new JPanel(new BorderLayout());
+    // L'arbre des champs à extraire
+    ModeleArbreValeursAChoisir donneesValeursAChoisir =
+            new ModeleArbreValeursAChoisir(vue, champsAVoir, adressesAVoir);
+    arbreValeursAChoisir = new JTree(donneesValeursAChoisir);
+    arbreValeursAChoisir.addTreeWillExpandListener(this);
+    MouseListener ml2 = new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {
+        try {
+          TreePath selPath = arbreValeursAChoisir.getPathForLocation(e.getX(), e.getY());
+          if (selPath!=null&&e.getClickCount()==2) {
+            NoeudValeurAChoisir noeud = (NoeudValeurAChoisir) selPath.getLastPathComponent();
+            if (noeud.getAllowsChildren()) return;
+            else ajouterValeur(noeud.champ, noeud.valeur);
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    };
+    arbreValeursAChoisir.addMouseListener(ml2);
+    JScrollPane scroll3 = new JScrollPane(arbreValeursAChoisir);
+    scroll3.setBorder(new TitledBorder("Choix de nouvelles valeurs à colorier"));
+    panneauValeursAChoisir.add(scroll3, BorderLayout.CENTER);
+    // Dimensionnement 
+    add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panneauValeursChoisies, panneauValeursAChoisir),
+            BorderLayout.CENTER);
+  }
+//    void agencerPanneaux() {
+//        JSplitPane split = (JSplitPane) panneauValeursChoisies.getParent();
+//    split.setDividerLocation(2. / 3);
+//    revalidate();
+//    repaint();
+//    }
+  public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
+    NoeudValeurAChoisir noeud = (NoeudValeurAChoisir) event.getPath().getLastPathComponent();
+    if (noeud.isLeaf()) {
+      ModeleArbreValeursAChoisir donnees = (ModeleArbreValeursAChoisir) arbreValeursAChoisir.getModel();
+      donnees.setSousArbre(noeud);
+    }
+  }
+  public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
+    return;
+  }
+  void setTypeSelected(Class<? extends Element> classe, String type) {
+    classeSelected = classe;
+    typeSelected = type;
+    ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).reinitialiser();
+    ((ModeleArbreValeursAChoisir) arbreValeursAChoisir.getModel()).setModele(classeSelected, typeSelected);
+  }
+  private void ajouterValeur(String champ, String valeur) {
+    if (champ.isEmpty())
+      ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).ajouterTousAColorier();
+    else
+      ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).ajouterValeurAColorier(champ, valeur);
+  }
+  void reinitialiser() {
+    ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).reinitialiser();
+    ((ModeleArbreValeursAChoisir) arbreValeursAChoisir.getModel()).setModele(classeSelected, typeSelected);
+  }
+  private static final String[] nomsColonnes = new String[]{
+    "Champ",
+    "Valeur",
+    "<html><span style=\"font-weight:900 \">Gras</span>",
+    "<html><span style=\"font-style:italic \">Italique</span>",
+    "<html><span style=\"text-decoration:underline \">Souligné</span>",
+    "<html><span style=\"color:red \">Couleur</span>",
+    "<html><span style=\"background-color:yellow \">Fond</span>",};
+  private static final Class[] classesColonnes = new Class[]{
+    String.class, String.class, Boolean.class, Boolean.class, Boolean.class, Color.class, Color.class
+  };
+
+  private class ModeleTableauValeursAColorier extends AbstractTableModel {
+    private ArrayList<String> champs = new ArrayList<String>();
+    private ArrayList<String> valeurs = new ArrayList<String>();
+    private ArrayList<Boolean> gras = new ArrayList<Boolean>();
+    private ArrayList<Boolean> italiques = new ArrayList<Boolean>();
+    private ArrayList<Boolean> soulignes = new ArrayList<Boolean>();
+    private ArrayList<Color> couleurs = new ArrayList<Color>();
+    private ArrayList<Color> fonds = new ArrayList<Color>();
+    private void reinitialiser() {
+      viderTableau();
+      AttributeSet att;
+      if (typeSelected!=null) {
+        if (stylesElements.get(classeSelected).containsKey(typeSelected)) {
+          att = stylesElements.get(classeSelected).get(typeSelected);
+          ajouterRangee("", "", att);
+        }
+        if (stylesValeursElements.get(classeSelected).containsKey(typeSelected))
+          for (String champ : stylesValeursElements.get(classeSelected).get(typeSelected).keySet())
+            for (String valeur : stylesValeursElements.get(classeSelected).get(typeSelected).get(champ).keySet()) {
+              att = stylesValeursElements.get(classeSelected).get(typeSelected).get(champ).get(valeur);
+              ajouterRangee(champ, valeur, att);
+            }
+        fireTableDataChanged();
+      }
+    }
+    private void viderTableau() {
+      champs.clear();
+      valeurs.clear();
+      gras.clear();
+      italiques.clear();
+      soulignes.clear();
+      couleurs.clear();
+      fonds.clear();
+    }
+    private void ajouterTousAColorier() {
+      if (!champs.isEmpty()&&champs.get(0).isEmpty()) return;
+      stylesElements.get(classeSelected).put(typeSelected, new SimpleAttributeSet());
+      insererRangee(0, "", "", vue.getStyleTexte());
+      fireTableDataChanged();
+    }
+    private void ajouterValeurAColorier(String champ, String valeur) {
+      for (int i = 0; i<champs.size(); i++)
+        if (champs.get(i).equals(champ)&&valeurs.get(i).equals(valeur)) return;
+      if (!stylesValeursElements.get(classeSelected).containsKey(typeSelected))
+        stylesValeursElements.get(classeSelected).put(typeSelected, new HashMap<String, HashMap<String, SimpleAttributeSet>>());
+      if (!stylesValeursElements.get(classeSelected).get(typeSelected).containsKey(champ))
+        stylesValeursElements.get(classeSelected).get(typeSelected).put(champ, new HashMap<String, SimpleAttributeSet>());
+      stylesValeursElements.get(classeSelected).get(typeSelected).get(champ).put(valeur, new SimpleAttributeSet());
+      ajouterRangee(champ, valeur, vue.getStyleTexte());
+      fireTableDataChanged();
+    }
+    private void ajouterRangee(String champ, String valeur, AttributeSet att) {
+      insererRangee(champs.size(), champ, valeur, att);
+    }
+    private void insererRangee(int row, String champ, String valeur, AttributeSet att) {
+      SimpleAttributeSet att0 = vue.getStyleTexte();
+      champs.add(row, champ);
+      valeurs.add(row, valeur);
+      if (att.isDefined(StyleConstants.Bold))
+        gras.add(row, StyleConstants.isBold(att));
+      else gras.add(row, StyleConstants.isBold(att0));
+      if (att.isDefined(StyleConstants.Italic))
+        italiques.add(row, StyleConstants.isItalic(att));
+      else italiques.add(row, StyleConstants.isItalic(att0));
+      if (att.isDefined(StyleConstants.Underline))
+        soulignes.add(row, StyleConstants.isUnderline(att));
+      else soulignes.add(row, StyleConstants.isUnderline(att0));
+      if (att.isDefined(StyleConstants.Foreground))
+        couleurs.add(row, StyleConstants.getForeground(att));
+      else couleurs.add(row, StyleConstants.getForeground(att0));
+      if (att.isDefined(StyleConstants.Background))
+        fonds.add(row, StyleConstants.getBackground(att));
+      else fonds.add(row, StyleConstants.getBackground(att0));
+      fireTableDataChanged();
+    }
+    void supprimerRangee(int row) {
+      if (champs.get(row).isEmpty())
+        stylesElements.get(classeSelected).remove(typeSelected);
+      else
+        stylesValeursElements.get(classeSelected).get(typeSelected).get(champs.get(row)).remove(valeurs.get(row));
+      champs.remove(row);
+      valeurs.remove(row);
+      gras.remove(row);
+      italiques.remove(row);
+      soulignes.remove(row);
+      couleurs.remove(row);
+      fonds.remove(row);
+
+      fireTableDataChanged();
+    }
+    public int getColumnCount() {
+      return nomsColonnes.length;
+    }
+    public int getRowCount() {
+      return (valeurs.size());
+    }
+    public Object getValueAt(int row, int col) {
+      switch (col) {
+        case 0:
+          if (champs.get(row).isEmpty()) return GVisu.styleDef("tous");
+          return champs.get(row);
+        case 1:
+          if (champs.get(row).isEmpty()) return GVisu.styleDef("toutes");
+          return valeurs.get(row);
+        case 2:
+          return gras.get(row);
+        case 3:
+          return italiques.get(row);
+        case 4:
+          return soulignes.get(row);
+        case 5:
+          return couleurs.get(row);
+        case 6:
+          return fonds.get(row);
+        default:
+          throw new IndexOutOfBoundsException();
+      }
+    }
+    @Override
+    public String getColumnName(int col) {
+      return nomsColonnes[col];
+    }
+    @Override
+    public Class getColumnClass(int col) {
+      return classesColonnes[col];
+    }
+    @Override
+    public boolean isCellEditable(int row, int col) {
+      return col>1;
+    }
+    @Override
+    public void setValueAt(Object aValue, int row, int col) {
+      Boolean valbool;
+      Color valcoul;
+      SimpleAttributeSet att = champs.get(row).isEmpty() ? stylesElements.get(classeSelected).get(typeSelected) : stylesValeursElements.get(classeSelected).get(typeSelected).get(champs.get(row)).get(valeurs.get(row));
+      SimpleAttributeSet att0 = vue.getStyleTexte();
+      switch (col) {
+        case 2:
+          valbool = (Boolean) aValue;
+          gras.set(row, valbool);
+          if (StyleConstants.isBold(att0)==valbool)
+            att.removeAttribute(StyleConstants.Bold);
+          else StyleConstants.setBold(att, valbool);
+          break;
+        case 3:
+          valbool = (Boolean) aValue;
+          italiques.set(row, valbool);
+          if (StyleConstants.isItalic(att0)==valbool)
+            att.removeAttribute(StyleConstants.Italic);
+          else StyleConstants.setItalic(att, valbool);
+          break;
+        case 4:
+          valbool = (Boolean) aValue;
+          soulignes.set(row, valbool);
+          if (StyleConstants.isUnderline(att0)==valbool)
+            att.removeAttribute(StyleConstants.Underline);
+          else StyleConstants.setUnderline(att, valbool);
+          break;
+        case 5:
+          valcoul = (Color) aValue;
+          couleurs.set(row, valcoul);
+          if (StyleConstants.getForeground(att0)==valcoul)
+            att.removeAttribute(StyleConstants.Foreground);
+          else StyleConstants.setForeground(att, valcoul);
+          break;
+        case 6:
+          valcoul = (Color) aValue;
+          fonds.set(row, valcoul);
+          if (StyleConstants.getBackground(att0)==valcoul)
+            att.removeAttribute(StyleConstants.Background);
+          else StyleConstants.setBackground(att, valcoul);
+          break;
+        default:
+          throw new IndexOutOfBoundsException("col = "+col);
+      }
+      fireTableCellUpdated(row, col);
+    }
+  }
+
+  private static class JPopupMenuValeur extends JPopupMenu {
+    int rang = -1;
+  }
+
+  private class ActionSupprimerValeur extends AbstractAction {
+    ActionSupprimerValeur() {
+      super("supprimer le champ");
+    }
+    public void actionPerformed(ActionEvent e) {
+      try {
+        int rg = ((JPopupMenuValeur) ((JMenuItem) e.getSource()).getParent()).rang;
+        ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).supprimerRangee(rg);
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+  }
+
+  private static class ModeleArbreValeursAChoisir extends DefaultTreeModel {
+    HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champs;
+    HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adresses;
+    Vue vue;
+    ModeleArbreValeursAChoisir(Vue vue, HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAvoir,
+            HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir) {
+      super(null, true);
+      this.champs = champsAvoir;
+      this.adresses = adressesAVoir;
+      this.vue = vue;
+    }
+    void setModele(Class<? extends Element> classeRacine, String typeRacine) {
+      if (typeRacine==null) {
+        setRoot(null);
+      } else {
+        NoeudValeurAChoisir racine = new NoeudValeurAChoisir(
+                classeRacine, typeRacine, null, null);
+        setRoot(racine);
+        setSousArbre(racine);
+      }
+      reload();
+    }
+    void setSousArbre(NoeudValeurAChoisir noeud) {
+      if (noeud.champ==null) {
+        noeud.add(new NoeudValeurAChoisir(noeud.classe, noeud.type, "", GVisu.styleDef("tous les éléments")));
+        for (String champ : champs.get(noeud.classe).get(noeud.type))
+          noeud.add(new NoeudValeurAChoisir(noeud.classe, noeud.type, champ, null));
+      } else {
+        int nochamp = champs.get(noeud.classe).get(noeud.type).indexOf(noeud.champ);
+        for (String valeur : vue.getValeursProp(adresses.get(noeud.classe).get(noeud.type).get(nochamp)))
+          noeud.add(new NoeudValeurAChoisir(noeud.classe, noeud.type, noeud.champ, valeur));
+      }
+    }
+  }
+
+  private static class NoeudValeurAChoisir extends DefaultMutableTreeNode {
+    Class<? extends Element> classe;
+    String type;
+    String champ;
+    String valeur;
+    NoeudValeurAChoisir(Class<? extends Element> classe, String type, String champ, String valeur) {
+      super();
+      this.classe = classe;
+      this.type = type;
+      this.champ = champ;
+      this.valeur = valeur;
+      setAllowsChildren(valeur==null);
+
+    }
+    @Override
+    public String toString() {
+      if (champ==null) return type;
+      if (valeur==null) return champ;
+      return valeur;
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVueColoriage.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/vue/Vue.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/vue/Vue.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/vue/Vue.java	(revision 481)
@@ -0,0 +1,1256 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.vue;
+
+import JamaPlus.*;
+import java.io.*;
+import java.util.*;
+import java.util.ArrayList;
+import javax.swing.text.SimpleAttributeSet;
+import visuAnalec.*;
+import visuAnalec.util.*;
+import visuAnalec.Message.*;
+import visuAnalec.elements.*;
+import visuAnalec.donnees.*;
+import visuAnalec.donnees.Corpus.*;
+import visuAnalec.texte.PanneauTexte;
+import visuAnalec.texte.PanneauTexte.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class Vue implements CorpusListener {
+  public static interface VueListener extends EventListener {
+    void traiterEvent(Message e);     // relaie les messages de Corpus + envoie ses propres messages (VueEvent)
+  }
+
+  public static class Adresse implements Serializable {
+    ArrayList<Jalon> chemin;
+    String prop;
+    Adresse(Adresse adresse, String prop) {
+      this.prop = prop;
+      this.chemin = new ArrayList<Jalon>(adresse.chemin);
+    }
+    Adresse(Adresse adresse, Jalon jalon) {
+      this.prop = null;
+      ArrayList<Jalon> chemin1 = new ArrayList<Jalon>(adresse.chemin);
+      chemin1.add(jalon);
+      this.chemin = chemin1;
+    }
+    Adresse(Adresse adresse) {
+      this.prop = adresse.prop;
+      this.chemin = new ArrayList<Jalon>();
+      for (Jalon jalon : adresse.chemin) this.chemin.add(new Jalon(jalon));
+    }
+    Adresse(Jalon jalon, String prop) {
+      this.prop = prop;
+      chemin = new ArrayList<Jalon>(Arrays.asList(jalon));
+    }
+    Adresse(Jalon jalon) {
+      this.prop = null;
+      chemin = new ArrayList<Jalon>(Arrays.asList(jalon));
+    }
+    int getLongueur() {
+      return chemin.size();
+    }
+    Jalon getLastJalon() {
+      return chemin.get(chemin.size()-1);
+    }
+    void renommer(Class<? extends Element> classe, String oldType, String newType) {
+      for (Jalon jalon : chemin)
+        if (jalon.classe==classe&&jalon.type.equals(oldType))
+          jalon.type = newType;
+    }
+    boolean contient(Class<? extends Element> classe, String type) {
+      for (Jalon jalon : chemin) {
+        if (jalon.classe==classe&&jalon.type.equals(type)) return true;
+      }
+      return false;
+    }
+    @Override
+    public String toString() {
+      String nom = "";
+      for (Jalon jalon : chemin) {
+        nom += jalon;
+      }
+      nom += ": "+prop;
+      return nom;
+    }
+  }
+
+  public static class Jalon implements Serializable {
+    public enum Origine {
+      ELT_0, ELT_1, ELT_2, REL_SORTANTE, REL_ENTRANTE, SCH_CONTENANT
+    }
+    /**
+     * L'origine d'un jalon indique d'où ce jalon provient :
+     * ELT_0 est  un jalon de classe quelconque qui est toujours le premier jalon d'une adresse complète. 
+     * ELT_1 et ELT_2 sont des jalons de classe quelconque qui proviennent d'un jalon précédent de classe Relation  
+     * REL_S et REL_E sont des jalons de classe Relation qui proviennent d'un jalon précédent de classe quelconque
+     * SCH_C est un jalon de classe Schema qui provient d'un jalon précédent de classe quelconque
+     */
+    public Origine origine;
+    public Class<? extends Element> classe;
+    public String type;
+    Jalon(Origine origine, Class<? extends Element> classe, String type) {
+      this.classe = classe;
+      this.origine = origine;
+      this.type = type;
+    }
+    Jalon(Jalon jalon) {
+      this.classe = jalon.classe;
+      this.origine = jalon.origine;
+      this.type = jalon.type;
+    }
+    @Override
+    public String toString() {
+      switch (origine) {
+        case SCH_CONTENANT:
+          return "{"+type;
+        case REL_ENTRANTE:
+          return "<"+type+"<";
+        case REL_SORTANTE:
+          return ">"+type+">";
+        case ELT_0:
+          return type;
+        case ELT_1:
+          return type;
+        case ELT_2:
+          return type;
+        default:
+          return "ERREUR!!";
+      }
+    }
+  }
+  /** 
+   * Champs de la classe Vue :
+   * Données spécifiant la vue: 
+   *   - typesA voir, champs, adresses, modifiables
+   *   - champsId
+   * (ce sont les seuls champs à sauvegarder et à recharger) 
+   * Le champ unitesAVoir est un raccourci pour éviter de retrier chaque fois les données correspondantes de Corpus
+   */
+  private ArrayList<VueListener> listeCorrespondants = new ArrayList<VueListener>();
+  private Corpus corpus;
+  private boolean modifiee = false;
+  ;
+  // types d'éléments à voir pour chaque classe
+  private HashMap<Class<? extends Element>, String[]> typesAVoir =
+          new HashMap<Class<? extends Element>, String[]>();
+  // champs en ordre (niveau et position) pour chaque type d'éléments à voir pour chaque classe 
+  private HashMap<Class<? extends Element>, HashMap<String, String[][]>> champspos =
+          new HashMap<Class<? extends Element>, HashMap<String, String[][]>>();
+  // adresse pour chaque champ pour chaque  type d'élément à voir pour chaque classe
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Adresse>>> adresses =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Adresse>>>();
+  // modifiabilité pour chaque champ pour chaque  type d'élément à voir pour chaque classe
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> modifiables =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>>();
+  // champ choisi comme identifiant (s'il existe) pour chaque type de chaque classe
+  private HashMap<Class<? extends Element>, HashMap<String, String>> champsId =
+          new HashMap<Class<? extends Element>, HashMap<String, String>>();
+// style pour tout le texte
+  private SimpleAttributeSet styleTexte;
+  // style (s'il existe) pour chaque type de chaque classe
+  private HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> stylesElements =
+          new HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>>();
+  // style (s'il existe) pour chaque valeur de chaque champ de chaque type de chaque classe
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> stylesValeursElements =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>>();
+  // unites par type d'unites à voir
+  private HashMap<String, Unite[]> unitesAVoir = new HashMap<String, Unite[]>();
+  /* Constructeur de la classe Vue */
+  @SuppressWarnings("unchecked")
+  public Vue(Corpus corpus) {
+    this.corpus = corpus;
+    corpus.addEventListener(this);
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      typesAVoir.put(classe, new String[0]);
+      champspos.put(classe, new HashMap<String, String[][]>());
+      adresses.put(classe, new HashMap<String, HashMap<String, Adresse>>());
+      modifiables.put(classe, new HashMap<String, HashMap<String, Boolean>>());
+      champsId.put(classe, new HashMap<String, String>());
+      stylesElements.put(classe, new HashMap<String, SimpleAttributeSet>());
+      stylesValeursElements.put(classe, new HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>());
+    }
+    this.styleTexte = new SimpleAttributeSet(PanneauTexte.STANDARD_DEFAUT);
+  }
+  public void addEventListener(VueListener correspondant) {
+    listeCorrespondants.add(correspondant);
+  }
+  public void removeEventListener(VueListener correspondant) {
+    listeCorrespondants.remove(correspondant);
+  }
+  private void fireMessage(Message evt) {
+    for (Object corresp : listeCorrespondants.toArray()) {
+      ((VueListener) corresp).traiterEvent(evt);
+    }
+  }
+  public boolean isModifiee() {
+    return modifiee;
+  }
+  public void ecrireJava(ObjectOutputStream oos) throws IOException {
+    oos.writeObject(typesAVoir);
+    oos.writeObject(champspos);
+    oos.writeObject(adresses);
+    oos.writeObject(modifiables);
+    oos.writeObject(champsId);
+    oos.writeObject(styleTexte);
+    oos.writeObject(stylesElements);
+    oos.writeObject(stylesValeursElements);
+    modifiee = false;
+  }
+  @SuppressWarnings("unchecked")
+  public boolean lireJava(ObjectInputStream ois) throws IOException, ClassNotFoundException, ClassCastException {
+    HashMap<Class<? extends Element>, String[]> typesAVoirLus =
+            (HashMap<Class<? extends Element>, String[]>) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, String[][]>> champsposLus =
+            (HashMap<Class<? extends Element>, HashMap<String, String[][]>>) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Adresse>>> adressesLues =
+            (HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Adresse>>>) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> modifablesLus =
+            (HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>>) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, String>> champsIdLus =
+            (HashMap<Class<? extends Element>, HashMap<String, String>>) ois.readObject();
+    SimpleAttributeSet styleTexteLu = (SimpleAttributeSet) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> stylesElementsLus =
+            (HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>>) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> stylesValeursElementsLus =
+            (HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>>) ois.readObject();
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      for (String type : typesAVoirLus.get(classe)) {
+        if (!corpus.getStructure().getTypes(classe).contains(type))
+          return false;
+      }
+    }
+    // En prévision d'une compatibilité ascendante
+    boolean suite = false;
+    try {
+      suite = ois.readBoolean();
+    } catch (EOFException eOFException) {
+    }
+    if (suite) {
+      System.out.println("Il y a d'autres objets dans le .ecv");
+    }
+    typesAVoir = typesAVoirLus;
+    champspos = champsposLus;
+    adresses = adressesLues;
+    modifiables = modifablesLus;
+    champsId = champsIdLus;
+    styleTexte = styleTexteLu;
+    stylesElements = stylesElementsLus;
+    stylesValeursElements = stylesValeursElementsLus;
+    unitesAVoir.clear();
+    modifiee = false;
+    for (String type : typesAVoir.get(Unite.class)) majUnitesAVoir(type);
+    fireMessage(new VueEvent(this, TypeModifVue.NEW_VUE));
+    return true;
+  }
+  public void traiterEvent(Message evt) { // Messages de corpus
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        initVueParDefaut();
+        fireMessage(evt);
+        return;
+      case CORPUS_SAVED:
+    	  fireMessage(evt);
+          return;
+      case NEW_CORPUS:
+        initVueParDefaut();
+        fireMessage(evt);
+        return;
+      case MODIF_TEXTE:
+        fireMessage(evt);
+        return;
+      case MODIF_ELEMENT:
+        ElementEvent evtE = (ElementEvent) evt;
+        switch (evtE.getModif()) {
+          case AJOUT_UNITE:
+            if (!unitesAVoir.containsKey(evtE.getElement().getType())) return;
+            majUnitesAVoir(evtE.getElement().getType());
+            fireMessage(evt);
+            return;
+          case SUP_UNITE:
+            if (!unitesAVoir.containsKey(evtE.getElement().getType())) return;
+            majUnitesAVoir(evtE.getElement().getType());
+            fireMessage(evt);
+            return;
+          case BORNES_UNITE:
+        	  if (!unitesAVoir.containsKey(evtE.getElement().getType())) return;
+              majUnitesAVoir(evtE.getElement().getType());
+              fireMessage(evt);
+              return;
+          case AJOUT_RELATION:
+          case AJOUT_SCHEMA:
+          case SUP_RELATION:
+          case SUP_SCHEMA:
+          case MODIF_SCHEMA:
+          case MODIF_VALEUR:
+            fireMessage(evt);
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas "+evtE.getModif()+" oublié dans un switch");
+        }
+      case MODIF_STRUCTURE:
+        StructureEvent evtS = (StructureEvent) evt;
+        switch (evtS.getModif()) {
+          case FUSION_TYPE:
+            fusionnerType(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1));
+            fireMessage(evt);
+            return;
+          case RENOM_TYPE:
+            renommerType(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1));
+            fireMessage(evt);
+            return;
+          case AJOUT_TYPE:
+            ajouterType(evtS.getClasse(), evtS.getArg());
+            fireMessage(evt);
+            return;
+          case AJOUT_TYPE_ET_ELEMENTS:
+            ajouterType(evtS.getClasse(), evtS.getArg());
+            if (evtS.getClasse()==Unite.class&&unitesAVoir.containsKey(evtS.getArg()))
+              majUnitesAVoir(evtS.getArg());
+            fireMessage(evt);
+            return;
+          case SUPPR_TYPE:
+            supprimerType(evtS.getClasse(), evtS.getArg());
+            fireMessage(evt);
+            return;
+          case AJOUT_PROP:
+            ajouterProp(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1));
+            fireMessage(evt);
+            return;
+          case AJOUT_FORME_UNITE:
+            ajouterFormeUnite(evtS.getArg(0));
+            fireMessage(evt);
+            return;
+           case FUSION_PROP:
+            fusionnerProp(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1), evtS.getArg(2));
+            fireMessage(evt);
+            return;
+          case RENOM_PROP:
+            renommerProp(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1), evtS.getArg(2));
+            fireMessage(evt);
+            return;
+          case SUPPR_PROP:
+            supprimerProp(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1));
+            fireMessage(evt);
+            return;
+          case RENOM_VALEUR:
+          case FUSION_VALEUR:
+          case SUPPR_VALEUR:
+          case AJOUT_VALEUR:
+            fireMessage(evt);
+            return;
+          case VALEUR_PAR_DEFAUT:
+            fireMessage(evt);
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas "+evtS.getModif()+" oublié dans un switch");
+        }
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  @SuppressWarnings("unchecked")
+  private void initVueParDefaut() {
+    unitesAVoir.clear();
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      String[] types = getTypes(classe);
+      Arrays.sort(types);
+      typesAVoir.put(classe, types);
+      champspos.get(classe).clear();
+      adresses.get(classe).clear();
+      champsId.get(classe).clear();
+      styleTexte = new SimpleAttributeSet(PanneauTexte.STANDARD_DEFAUT);
+      stylesElements.get(classe).clear();
+      stylesValeursElements.get(classe).clear();
+      for (String type : typesAVoir.get(classe)) {
+        Jalon jalon0 = new Jalon(Jalon.Origine.ELT_0, classe, type);
+        String[] chps = getNomsProps(new Adresse(jalon0));
+        champspos.get(classe).put(type, new String[1][]);
+        champspos.get(classe).get(type)[0] = chps;
+        adresses.get(classe).put(type, new HashMap<String, Adresse>());
+        modifiables.get(classe).put(type, new HashMap<String, Boolean>());
+        for (String chp : chps) {
+          adresses.get(classe).get(type).put(chp, new Adresse(jalon0, chp));
+          modifiables.get(classe).get(type).put(chp, true);
+        }
+        if (classe==Unite.class) majUnitesAVoir(type);
+      }
+    }
+    modifiee = false;
+    fireMessage(new VueEvent(this, TypeModifVue.VUE_DEFAUT));
+
+  }
+  private void majUnitesAVoir(String typeUnite) {
+    Unite[] unts = corpus.getUnites(typeUnite).toArray(new Unite[0]);
+    Arrays.sort(unts);
+    unitesAVoir.put(typeUnite, unts);
+  }
+  public void retablirVueParDefaut() {
+    initVueParDefaut();
+  }
+  public void setStyleTexte(SimpleAttributeSet att) {
+    styleTexte = att;
+  }
+  public SimpleAttributeSet getStyleTexte() {
+    return styleTexte;
+  }
+  public void modifierVueParSaisie(
+          HashMap<Class<? extends Element>, HashMap<String, Boolean>> newIsTypesAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> newAdressesAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> newChampsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, String>> newChampsId,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> newModifables,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> newPositionsChamps,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> newNiveauxChamps,
+          HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> newStylesElements,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> newStylesValeursElements) {
+    setTypesAVoir(newIsTypesAVoir);
+    setChampsAdresses(newChampsAVoir, newAdressesAVoir, newPositionsChamps, newNiveauxChamps);
+    setChampsModifiables(newChampsAVoir, newModifables);
+    setChampsId(newChampsId);
+    setStylesElements(newStylesElements);
+    setStylesValeursElements(newStylesValeursElements);
+    unitesAVoir.clear();
+    for (String typeUnite : typesAVoir.get(Unite.class))
+      majUnitesAVoir(typeUnite);
+    modifiee = true;
+    fireMessage(new VueEvent(this, TypeModifVue.EXTRACTION));
+  }
+  @SuppressWarnings("unchecked")
+  private void setTypesAVoir(HashMap<Class<? extends Element>, HashMap<String, Boolean>> isAVoir) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      ArrayList<String> types = new ArrayList<String>();
+      for (String type : getTypes(classe)) if (isAVoir.get(classe).get(type))
+          types.add(type);
+      typesAVoir.put(classe, types.toArray(new String[0]));
+    }
+  }
+  @SuppressWarnings("unchecked")
+  private void setChampsAdresses(
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> positionsChamps,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> niveauxChamps) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      adresses.get(classe).clear();
+      for (int i = 0; i<typesAVoir.get(classe).length; i++) {
+        String type = typesAVoir.get(classe)[i];
+        ArrayList<String> chps = champsAVoir.get(classe).get(type);
+        adresses.get(classe).put(type, new HashMap<String, Adresse>());
+        for (int j = 0; j<chps.size(); j++)
+          adresses.get(classe).get(type).put(chps.get(j), adressesAVoir.get(classe).get(type).get(j));
+        champspos.get(classe).put(type, ordonnerChamps(chps, niveauxChamps.get(classe).get(type),
+                positionsChamps.get(classe).get(type)));
+      }
+    }
+  }
+  private String[][] insererChamp(String[][] chpsenordre, String newchp) {
+    if (chpsenordre.length==0) {
+      String[][] chps = new String[1][1];
+      chps[0][0] = newchp;
+      return chps;
+    }
+    String[] chs1 = new String[chpsenordre[0].length+1];
+    chs1[0] = newchp;
+    System.arraycopy(chpsenordre[0], 0, chs1, 1, chpsenordre[0].length);
+    chpsenordre[0] = chs1;
+    return chpsenordre;
+  }
+  private String[][] ordonnerChamps(ArrayList<String> chps, HashMap<String, Integer> nivx, HashMap<String, Integer> poss) {
+    HashMap<Integer, HashMap<Integer, ArrayList<String>>> chpstries =
+            new HashMap<Integer, HashMap<Integer, ArrayList<String>>>();
+    for (String ch : chps) {
+      int niv = nivx.get(ch);
+      if (!chpstries.containsKey(niv))
+        chpstries.put(niv, new HashMap<Integer, ArrayList<String>>());
+      int pos = poss.get(ch);
+      if (!chpstries.get(niv).containsKey(pos))
+        chpstries.get(niv).put(pos, new ArrayList<String>());
+      chpstries.get(niv).get(pos).add(ch);
+    }
+    Integer[] niveaux = chpstries.keySet().toArray(new Integer[0]);
+    Arrays.sort(niveaux);
+    String[][] chpsenordre = new String[niveaux.length][];
+    int niveauenordre = 0;
+    for (int niv : niveaux) {
+      Integer[] positions = chpstries.get(niv).keySet().toArray(new Integer[0]);
+      Arrays.sort(positions);
+      int nbch = 0;
+      for (int pos : positions) nbch += chpstries.get(niv).get(pos).size();
+      chpsenordre[niveauenordre] = new String[nbch];
+      int positionenordre = 0;
+      for (int pos : positions) {
+        String[] chs = chpstries.get(niv).get(pos).toArray(new String[0]);
+        Arrays.sort(chs);
+        for (String ch : chs)
+          chpsenordre[niveauenordre][positionenordre++] = ch;
+      }
+      niveauenordre++;
+    }
+    return chpsenordre;
+  }
+  @SuppressWarnings("unchecked")
+  private void setChampsModifiables(HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> newChampsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> newModifables) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      modifiables.get(classe).clear();
+      for (int i = 0; i<typesAVoir.get(classe).length; i++) {
+        String type = typesAVoir.get(classe)[i];
+        modifiables.get(classe).put(type, new HashMap<String, Boolean>());
+        for (String chp : newChampsAVoir.get(classe).get(type))
+          modifiables.get(classe).get(type).put(chp, newModifables.get(classe).get(type).get(chp));
+      }
+    }
+  }
+  @SuppressWarnings("unchecked")
+  private void setChampsId(HashMap<Class<? extends Element>, HashMap<String, String>> newChampsId) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      champsId.get(classe).clear();
+      champsId.get(classe).putAll(newChampsId.get(classe));
+    }
+  }
+  @SuppressWarnings("unchecked")
+  private void setStylesElements(HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> newStylesElements) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      stylesElements.get(classe).clear();
+      stylesElements.get(classe).putAll(newStylesElements.get(classe));
+    }
+  }
+  @SuppressWarnings("unchecked")
+  private void setStylesValeursElements(HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> newStylesValeursElements) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      stylesValeursElements.get(classe).clear();
+      stylesValeursElements.get(classe).putAll(newStylesValeursElements.get(classe));
+    }
+  }
+  public Corpus getCorpus() {
+    return corpus;
+  }
+  public String[] getTypes(Class<? extends Element> classe) {
+    String[] types = corpus.getStructure().getTypes(classe).toArray(new String[0]);
+    Arrays.sort(types);
+    return types;
+  }
+  @SuppressWarnings("unchecked")
+  public HashMap<Class<? extends Element>, HashMap<String, Boolean>> isTypesAVoir() {
+    HashMap<Class<? extends Element>, HashMap<String, Boolean>> isAVoir =
+            new HashMap<Class<? extends Element>, HashMap<String, Boolean>>();
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      isAVoir.put(classe, new HashMap<String, Boolean>());
+      for (String type : getTypes(classe)) isAVoir.get(classe).put(type, false);
+      for (String type : typesAVoir.get(classe))
+        isAVoir.get(classe).put(type, true);
+    }
+    return isAVoir;
+  }
+  String[] getTypesAVoir(Class<? extends Element> classe) {
+    return typesAVoir.get(classe);
+  }
+  public String[] getTypesUnitesAVoir() {
+    return getTypesAVoir(Unite.class);
+  }
+  public String[] getTypesRelationsAVoir() {
+    return getTypesAVoir(Relation.class);
+  }
+  public String[] getTypesSchemasAVoir() {
+    return getTypesAVoir(Schema.class);
+  }
+  public String getChampId(Class<? extends Element> classe, String type) {
+    return champsId.get(classe).get(type);
+  }
+  public SimpleAttributeSet getStyleElements(Class<? extends Element> classe, String type) {
+    return stylesElements.get(classe).get(type);
+  }
+  public HashMap<String, HashMap<String, SimpleAttributeSet>> getStyleValeursElements(
+          Class<? extends Element> classe, String type) {
+    return stylesValeursElements.get(classe).get(type);
+  }
+  public String[][] getChamps(Class<? extends Element> classe, String type) {
+    if (champspos.get(classe).containsKey(type)) {
+      return champspos.get(classe).get(type);
+    } else {
+      return new String[0][];
+    }
+  }
+  public String[] getNomsChamps(Class<? extends Element> classe, String type) {
+    return getListeChamps(classe, type).toArray(new String[0]);
+  }
+  //la méthode suivante publique pour pouvoir l'utiliser dans une autre classe
+  public ArrayList<String> getListeChamps(Class<? extends Element> classe, String type) {
+    // utilisé aussi par VisuVue
+    ArrayList<String> lchps = new ArrayList<String>();
+    if (champspos.get(classe).containsKey(type))
+      for (String[] champsniveau : champspos.get(classe).get(type))
+        lchps.addAll(Arrays.asList(champsniveau));
+    return lchps;
+  }
+  static String trouveNomChampParDefaut(Adresse ad, ArrayList<String> chps) {
+    String nom;
+    if (ad.chemin.size()==1) {
+      nom = ad.prop;
+      while (chps.contains(nom)) nom += "-0";
+      return nom;
+    }
+    for (int i = 1; true; i++) {
+      nom = ad.prop+"-"+i;
+      if (!chps.contains(nom)) {
+        return nom;
+      }
+    }
+  }
+  String[] getNomsProps(Adresse adresse) {
+    String[] props;
+    Jalon jalon = adresse.getLastJalon();
+    props = corpus.getStructure().getNomsProps(jalon.classe, jalon.type).toArray(new String[0]);
+    Arrays.sort(props);
+    return props;
+  }
+  String[] getValeursProp(Adresse adresse) {
+    String[] vals;
+    Jalon jalon = adresse.getLastJalon();
+    vals = corpus.getStructure().getValeursProp(jalon.classe, jalon.type, adresse.prop).toArray(new String[0]);
+    Arrays.sort(vals);
+    return vals;
+  }
+  @SuppressWarnings("unchecked")
+  Jalon[] getNextJalonsPotentiels(Adresse adresse) {
+    ArrayList<Jalon> nextJalons = new ArrayList<Jalon>();
+    Jalon jalon = adresse.getLastJalon();
+    switch (jalon.origine) {
+      case REL_ENTRANTE:
+        for (Class<? extends Element> cl : new Class[]{Unite.class, Relation.class, Schema.class}) {
+          for (String typeRel : getTypes(cl)) {
+            nextJalons.add(new Jalon(Jalon.Origine.ELT_1, cl, typeRel));
+          }
+        }
+        break;
+      case REL_SORTANTE:
+        for (Class<? extends Element> cl : new Class[]{Unite.class, Relation.class, Schema.class}) {
+          for (String typeRel : getTypes(cl)) {
+            nextJalons.add(new Jalon(Jalon.Origine.ELT_2, cl, typeRel));
+          }
+        }
+        break;
+      default:
+        for (String typeRel : getTypes(Relation.class)) {
+          nextJalons.add(new Jalon(Jalon.Origine.REL_SORTANTE, Relation.class, typeRel));
+        }
+        for (String typeRel : getTypes(Relation.class)) {
+          nextJalons.add(new Jalon(Jalon.Origine.REL_ENTRANTE, Relation.class, typeRel));
+        }
+        for (String typeSch : getTypes(Schema.class)) {
+          nextJalons.add(new Jalon(Jalon.Origine.SCH_CONTENANT, Schema.class, typeSch));
+        }
+        break;
+    }
+    return nextJalons.toArray(new Jalon[0]);
+  }
+  Adresse getAdresseChamps(Class<? extends Element> classe, String type, String nomChamp) {
+    if (adresses.get(classe).containsKey(type)) {
+      return adresses.get(classe).get(type).get(nomChamp);
+    } else {
+      return null;
+    }
+  }
+  public boolean isChampModifiable(Class<? extends Element> classe, String type, String champ) {
+    return modifiables.get(classe).get(type).get(champ);
+  }
+  public HashMap<String, Integer> getPositionsChampsAVoir(Class<? extends Element> classe, String type) {
+    HashMap<String, Integer> positions = new HashMap<String, Integer>();
+    if (champspos.get(classe).containsKey(type)) {
+      for (String[] champsniveau : champspos.get(classe).get(type)) {
+        int i = 0;
+        for (String ch : champsniveau) positions.put(ch, i++);
+      }
+    }
+    return positions;
+  }
+  public HashMap<String, Integer> getNiveauxChampsAVoir(Class<? extends Element> classe, String type) {
+    HashMap<String, Integer> niveaux = new HashMap<String, Integer>();
+    if (champspos.get(classe).containsKey(type)) {
+      int i = 0;
+      for (String[] champsniveau : champspos.get(classe).get(type)) {
+        for (String ch : champsniveau) niveaux.put(ch, i);
+        i++;
+      }
+    }
+    return niveaux;
+  }
+  public String[] getValeursChamp(Class<? extends Element> classe, String type, String champ) {
+    Adresse adresse = getAdresseChamps(classe, type, champ);
+    if (adresse==null) {
+      return new String[0];
+    }
+    return getValeursProp(adresse);
+  }
+  public String getValeurChamp(Element element, String champ) {
+    Adresse adresse = getAdresseChamps(element.getClass(), element.getType(), champ);
+    if (adresse==null) {
+      return "";
+    }
+    Element elt = element;
+    for (Jalon jalon : adresse.chemin) {
+      if ((elt = elt.getElementSuivant(jalon))==null) return "";
+    }
+    return elt.getProp(adresse.prop);
+  }
+  public boolean setValeurChamp(Element element, String champ, String newval) {
+    Adresse adresse = getAdresseChamps(element.getClass(), element.getType(), champ);
+    if (adresse == null) return false;
+    
+    Element elt = element;
+    for (Jalon jalon : adresse.chemin) {
+      elt = elt.getElementSuivant(jalon);
+      if (elt==null) return false;
+    }
+    corpus.setValeurPropElement(elt, adresse.prop, newval);
+    return true;
+  }
+  public void copierValeurs(Element eltSource, Element eltCible) {
+    Class<? extends Element> classe = eltSource.getClass();
+    if (eltCible.getClass()!=classe) return;
+    String type = eltSource.getType();
+    if (!eltCible.getType().equals(type)) return;
+    for (String champ : getListeChamps(classe, type))
+      if (isChampModifiable(classe, type, champ))
+        setValeurChamp(eltCible, champ, getValeurChamp(eltSource, champ));
+  }
+  private void ajouterType(Class<? extends Element> classe, String newType) {
+
+//      ArrayList<String> typs = new ArrayList<String>(Arrays.asList(typesUnitesAVoir));
+//      typs.add(newType);
+//      typesUnitesAVoir = typs.toArray(new String[0]);
+//      Arrays.sort(typesUnitesAVoir);
+    typesAVoir.put(classe, Tableaux.insererString(typesAVoir.get(classe), newType));
+    champspos.get(classe).put(newType, new String[0][]);
+    adresses.get(classe).put(newType, new HashMap<String, Adresse>());
+    if (classe==Unite.class) unitesAVoir.put(newType, new Unite[0]);
+    modifiables.get(classe).put(newType, new HashMap<String, Boolean>());
+  }
+  private void renommerType(Class<? extends Element> classe, String oldType, String newType) {
+    for (Class<? extends Element> cl : adresses.keySet())
+      for (String type : adresses.get(cl).keySet())
+        for (String chp : adresses.get(cl).get(type).keySet()) {
+          adresses.get(cl).get(type).get(chp).renommer(classe, oldType, newType);
+        }
+    int ind = Arrays.binarySearch(typesAVoir.get(classe), oldType);
+    if (ind>=0) {
+      typesAVoir.get(classe)[ind] = newType;
+      Arrays.sort(typesAVoir.get(classe));
+      champspos.get(classe).put(newType, champspos.get(classe).get(oldType));
+      champspos.get(classe).remove(oldType);
+      adresses.get(classe).put(newType, adresses.get(classe).get(oldType));
+      adresses.get(classe).remove(oldType);
+      if (champsId.get(classe).containsKey(oldType)) {
+        champsId.get(classe).put(newType, champsId.get(classe).get(oldType));
+        champsId.get(classe).remove(oldType);
+      }
+      modifiables.get(classe).put(newType, modifiables.get(classe).get(oldType));
+      if (classe==Unite.class) {
+        unitesAVoir.put(newType, unitesAVoir.get(oldType));
+        unitesAVoir.remove(oldType);
+      }
+      if (stylesElements.get(classe).containsKey(oldType)) {
+        stylesElements.get(classe).put(newType, stylesElements.get(classe).get(oldType));
+        stylesElements.get(classe).remove(oldType);
+      }
+      if (stylesValeursElements.get(classe).containsKey(oldType)) {
+        stylesValeursElements.get(classe).put(newType, stylesValeursElements.get(classe).get(oldType));
+        stylesValeursElements.get(classe).remove(oldType);
+      }
+    }
+  }
+  private void fusionnerType(Class<? extends Element> classe, String oldType, String newType) {
+    int indold = Arrays.binarySearch(typesAVoir.get(classe), oldType);
+    if (indold>=0) {
+      int indnew = Arrays.binarySearch(typesAVoir.get(classe), newType);
+      if (indnew>=0) {
+        ArrayList<String> chpsnewtype = getListeChamps(classe, newType);
+        HashMap<String, Integer> nivxnewtype = getNiveauxChampsAVoir(classe, newType);
+        HashMap<String, Integer> possnewtype = getPositionsChampsAVoir(classe, newType);
+        for (String chpoldtype : getListeChamps(classe, oldType)) {
+          Adresse adroldtype = adresses.get(classe).get(oldType).get(chpoldtype);
+          String nomchamp = trouveNomChampParDefaut(adroldtype, chpsnewtype);
+          adresses.get(classe).get(newType).put(nomchamp, adroldtype);
+          chpsnewtype.add(nomchamp);
+          nivxnewtype.put(nomchamp, getNiveauxChampsAVoir(classe, oldType).get(chpoldtype));
+          possnewtype.put(nomchamp, getPositionsChampsAVoir(classe, oldType).get(chpoldtype));
+          modifiables.get(classe).get(newType).put(nomchamp, modifiables.get(classe).get(oldType).get(chpoldtype));
+          if (stylesValeursElements.get(classe).containsKey(oldType)&&stylesValeursElements.get(classe).get(oldType).containsKey(chpoldtype)) {
+            if (!stylesValeursElements.get(classe).containsKey(newType))
+              stylesValeursElements.get(classe).put(newType, new HashMap<String, HashMap<String, SimpleAttributeSet>>());
+            stylesValeursElements.get(classe).get(newType).put(nomchamp,
+                    stylesValeursElements.get(classe).get(oldType).get(chpoldtype));
+          }
+        }
+        champspos.get(classe).put(newType, ordonnerChamps(chpsnewtype, nivxnewtype, possnewtype));
+      }
+      typesAVoir.put(classe, Tableaux.oterString(typesAVoir.get(classe), indold));
+      champspos.get(classe).remove(oldType);
+      adresses.get(classe).remove(oldType);
+      champsId.get(classe).remove(oldType);
+      modifiables.get(classe).remove(oldType);
+      stylesElements.get(classe).remove(oldType);
+      stylesValeursElements.get(classe).remove(oldType);
+      if (classe==Unite.class) {
+        majUnitesAVoir(newType);
+        unitesAVoir.remove(oldType);
+      }
+    }
+    for (Class<? extends Element> cl : typesAVoir.keySet())
+      for (String typ : typesAVoir.get(cl)) {
+        ArrayList<String> chpsASup = new ArrayList<String>();
+        ArrayList<String> chps = getListeChamps(cl, typ);
+        HashMap<String, Integer> nivx = getNiveauxChampsAVoir(cl, typ);
+        HashMap<String, Integer> poss = getPositionsChampsAVoir(cl, typ);
+        for (String ch : chps) {
+          Adresse ad = adresses.get(cl).get(typ).get(ch);
+          if (ad.contient(classe, oldType)) {
+            Adresse ad1 = new Adresse(ad);
+            ad1.renommer(classe, oldType, newType);
+            boolean dejala = false;
+            for (String ch1 : chps)
+              if (adresses.get(cl).get(typ).get(ch1).toString().equals(ad1.toString())) {
+                dejala = true;
+                break;
+              }
+            if (!dejala) adresses.get(cl).get(typ).put(ch, ad1);
+            else {
+              chpsASup.add(ch);
+              if (ch.equals(champsId.get(cl).get(typ)))
+                champsId.get(cl).remove(typ);
+              modifiables.get(cl).get(typ).remove(ch);
+              if (stylesValeursElements.get(cl).containsKey(typ))
+                stylesValeursElements.get(cl).get(typ).remove(ch);
+              nivx.remove(ch);
+              poss.remove(ch);
+            }
+          }
+        }
+        chps.removeAll(chpsASup);
+        for (String ch : chpsASup) adresses.get(cl).get(typ).remove(ch);
+        champspos.get(cl).put(typ, ordonnerChamps(chps, nivx, poss));
+      }
+  }
+  private void supprimerType(Class<? extends Element> classe, String type) {
+    int ind = Arrays.binarySearch(typesAVoir.get(classe), type);
+    if (ind>=0) {
+      typesAVoir.put(classe, Tableaux.oterString(typesAVoir.get(classe), ind));
+      champspos.get(classe).remove(type);
+      adresses.get(classe).remove(type);
+      if (classe==Unite.class) unitesAVoir.remove(type);
+    }
+    champsId.get(classe).remove(type);
+    modifiables.get(classe).remove(type);
+    stylesElements.get(classe).remove(type);
+    stylesValeursElements.get(classe).remove(type);
+    for (Class<? extends Element> cl : typesAVoir.keySet())
+      for (String typ : typesAVoir.get(cl)) {
+        ArrayList<String> chpsASup = new ArrayList<String>();
+        ArrayList<String> chps = getListeChamps(cl, typ);
+        HashMap<String, Integer> nivx = getNiveauxChampsAVoir(cl, typ);
+        HashMap<String, Integer> poss = getPositionsChampsAVoir(cl, typ);
+        for (String ch : chps)
+          if (adresses.get(cl).get(typ).get(ch).contient(classe, type)) {
+            chpsASup.add(ch);
+            adresses.get(cl).get(typ).remove(ch);
+            if (ch.equals(champsId.get(cl).get(typ)))
+              champsId.get(cl).remove(typ);
+            modifiables.get(cl).get(typ).remove(ch);
+            if (stylesValeursElements.get(cl).containsKey(typ))
+              stylesValeursElements.get(cl).get(typ).remove(ch);
+            nivx.remove(ch);
+            poss.remove(ch);
+          }
+        chps.removeAll(chpsASup);
+        champspos.get(cl).put(typ, ordonnerChamps(chps, nivx, poss));
+      }
+  }
+  private void ajouterProp(Class<? extends Element> classe, String type, String prop) {
+    if (Arrays.binarySearch(typesAVoir.get(classe), type)>=0) {
+      Adresse ad = new Adresse(new Jalon(Jalon.Origine.ELT_0, classe, type), prop);
+      String newchp = trouveNomChampParDefaut(ad, getListeChamps(classe, type));
+      champspos.get(classe).put(type, insererChamp(champspos.get(classe).get(type), newchp));
+      adresses.get(classe).get(type).put(newchp, ad);
+      modifiables.get(classe).get(type).put(newchp, true);
+    }
+  }
+  private void ajouterFormeUnite( String type) {
+     if (Arrays.binarySearch(typesAVoir.get(Unite.class), type)>=0) {
+      Adresse ad = new Adresse(new Jalon(Jalon.Origine.ELT_0, Unite.class, type), Structure.FORME);
+      champspos.get(Unite.class).put(type, insererChamp(champspos.get(Unite.class).get(type), Structure.FORME));
+      adresses.get(Unite.class).get(type).put(Structure.FORME, ad);
+      modifiables.get(Unite.class).get(type).put(Structure.FORME, false);
+    }
+  }
+  private void renommerProp(Class<? extends Element> classe, String type, String oldNom, String newNom) {
+    // on ne change que les adresses : on ne renomme les champs que dans certains cas (cf. renommerChamp appelé à la fin)
+    for (Class<? extends Element> cl : adresses.keySet())
+      for (String typ : adresses.get(cl).keySet())
+        for (String chp : adresses.get(cl).get(typ).keySet()) {
+          if (adresses.get(cl).get(typ).get(chp).getLastJalon().classe==classe
+                  &&type.equals(adresses.get(cl).get(typ).get(chp).getLastJalon().type)
+                  &&oldNom.equals(adresses.get(cl).get(typ).get(chp).prop)) {
+            adresses.get(cl).get(typ).get(chp).prop = newNom;
+          }
+        }
+    renommerChamp(classe, type, oldNom, newNom);
+  }
+  private void renommerChamp(Class<? extends Element> classe, String type, String oldNom, String newNom) {
+    // renomme aussi le champ quand la correspondance prop<=>champ est directe (notamment dans la vue par défaut)
+    if (!champspos.get(classe).containsKey(type))
+      throw new IllegalArgumentException();
+    String[][] chps = champspos.get(classe).get(type);
+    if (!adresses.get(classe).get(type).containsKey(oldNom))
+      throw new IllegalArgumentException();
+    if (adresses.get(classe).get(type).get(oldNom).getLongueur()>1) return;
+    if (!adresses.get(classe).get(type).get(oldNom).prop.equals(oldNom)) return;
+    boolean fait = false;
+    for (int niv = 0; niv<chps.length; niv++) {
+      for (int pos = 0; pos<chps[niv].length; pos++)
+        if (chps[niv][pos].equals(oldNom)) {
+          chps[niv][pos] = newNom;
+          fait = true;
+          break;
+        }
+      if (fait) break;
+    }
+    if (!fait) throw new IllegalArgumentException();
+    adresses.get(classe).get(type).put(newNom, adresses.get(classe).get(type).get(oldNom));
+    adresses.get(classe).get(type).remove(oldNom);
+    modifiables.get(classe).get(type).put(newNom, modifiables.get(classe).get(type).get(oldNom));
+    modifiables.get(classe).get(type).remove(oldNom);
+    if (champsId.get(classe).containsKey(type)&&champsId.get(classe).get(type).equals(oldNom))
+      champsId.get(classe).put(type, newNom);
+    if (stylesValeursElements.get(classe).containsKey(type)
+            &&stylesValeursElements.get(classe).get(type).containsKey(oldNom)) {
+      stylesValeursElements.get(classe).get(type).put(newNom,
+              stylesValeursElements.get(classe).get(type).get(oldNom));
+      stylesValeursElements.get(classe).get(type).remove(oldNom);
+    }
+  }
+  private void fusionnerProp(Class<? extends Element> classe, String type, String oldNom, String newNom) {
+    // pour le moment, on se contente de supprimer tous les champs qui utilisent l'ancienne prop
+    // c'est un peu grossier...
+    supprimerProp(classe, type, oldNom);
+  }
+  private void supprimerProp(Class<? extends Element> classe, String type, String prop) {
+    // on parcourt tous les champs et les adresses correspondantes
+    for (Class<? extends Element> cl : typesAVoir.keySet())
+      for (String typ : typesAVoir.get(cl)) {
+        ArrayList<String> chpsASup = new ArrayList<String>();
+        ArrayList<String> chps = getListeChamps(cl, typ);
+        HashMap<String, Integer> nivx = getNiveauxChampsAVoir(cl, typ);
+        HashMap<String, Integer> poss = getPositionsChampsAVoir(cl, typ);
+        for (String ch : chps) {
+          Adresse ad = adresses.get(cl).get(typ).get(ch);
+          if (ad.getLastJalon().classe==classe&&type.equals(ad.getLastJalon().type)&&prop.equals(ad.prop)) {
+            chpsASup.add(ch);
+            adresses.get(cl).get(typ).remove(ch);
+            modifiables.get(cl).get(typ).remove(ch);
+            if (ch.equals(champsId.get(cl).get(typ)))
+              champsId.get(cl).remove(typ);
+            if (stylesValeursElements.get(cl).containsKey(typ))
+              stylesValeursElements.get(cl).get(typ).remove(ch);
+            nivx.remove(ch);
+            poss.remove(ch);
+          }
+        }
+        chps.removeAll(chpsASup);
+        champspos.get(cl).put(typ, ordonnerChamps(chps, nivx, poss));
+      }
+  }
+  public Unite[] getUnites(String type) {
+    Unite[] units = corpus.getUnites(type).toArray(new Unite[0]);
+    Arrays.sort(units);
+    return units;
+  }
+  public Unite[] getUnitesAVoir(String type) {
+    if (unitesAVoir.get(type)==null) {
+      return new Unite[0];
+    }
+    return unitesAVoir.get(type);
+  }
+  public Relation[] getRelations(String type) {
+    Relation[] rels = corpus.getRelations(type).toArray(new Relation[0]);
+    Arrays.sort(rels);
+    return rels;
+  }
+  public Relation[] getRelationsAVoir(String type) {
+    // Pour l'instant, toutes les relations de ce type, mais ça peut changer avec la mise en place des sélections
+    // nécessitera peut-être la mise en place d'une variable relationsAVoir (comme pour les unités) 
+    Relation[] rels = corpus.getRelations(type).toArray(new Relation[0]);
+    Arrays.sort(rels);
+    return rels;
+  }
+  public Schema[] getSchemas(String type) {
+    Schema[] schs = corpus.getSchemas(type).toArray(new Schema[0]);
+    Arrays.sort(schs);
+    return schs;
+  }
+  public Schema[] getSchemasAVoir(String type) {
+    // Pour l'instant, tous les schémas de ce type, mais ça peut changer avec la mise en place des sélections
+    // nécessitera peut-être la mise en place d'une variable schemasAVoir (comme pour les unités) 
+    Schema[] schs = corpus.getSchemas(type).toArray(new Schema[0]);
+    Arrays.sort(schs);
+    return schs;
+  }
+  public Element[] getElements(Class<? extends Element> classe, String type) {
+    if (classe==Unite.class) return getUnites(type);
+    if (classe==Relation.class) return getRelations(type);
+    if (classe==Schema.class) return getSchemas(type);
+    throw new UnsupportedOperationException("sous-classe non traitée");
+  }
+  public Element[] getElementsAVoir(Class<? extends Element> classe, String type) {
+    if (classe==Unite.class) return getUnitesAVoir(type);
+    if (classe==Relation.class) return getRelationsAVoir(type);
+    if (classe==Schema.class) return getSchemasAVoir(type);
+    throw new UnsupportedOperationException("sous-classe non traitée");
+  }
+  public String getTexteUnite(Unite unit) {  // utilisé par ModeleChaines et par ModeleStatsGeometrie - à revoir : pas très efficace
+    return corpus.getTexteUnite(unit);
+  }
+  public String getIdElement(Element elt) {  // utilisé  par PanneauOccurrences
+    String type = elt.getType();
+    Class<? extends Element> classe = elt.getClass();
+    String champId = getChampId(classe, type);
+    String id;
+    if (champId!=null) {
+      id = getValeurChamp(elt, champId);
+      if (!id.isEmpty()) return id;
+    }
+    Element[] listeElts = getElements(classe, type);
+    if (listeElts==null) return "";
+    int no = Arrays.binarySearch(listeElts, elt);
+    if (no<0) return "";
+    return type+"-"+Integer.toString(no+1);
+  }
+  private String[] getIdElements(Class<? extends Element> classe, String type,
+          Element[] eltsCorpus, Element[] eltsATraiter) {
+    // eltsATraiter doit être  trié ; s'il est null, on prend toutes les éléments du corpus de ce type 
+    String champId = getChampId(classe, type);
+    String[] ids = new String[eltsATraiter==null ? eltsCorpus.length : eltsATraiter.length];
+    String id;
+    int i = 0;
+    for (int no = 0; no<eltsCorpus.length; no++) {
+      if (eltsATraiter==null||eltsATraiter[i]==eltsCorpus[no]) {
+        id = champId==null ? "" : getValeurChamp(eltsCorpus[no], champId);
+        ids[i++] = id.isEmpty() ? type+"-"+Integer.toString(no+1) : id;
+      }
+    }
+    return ids;
+  }
+  public String[] getIdUnites(String type) {  // toutes les unités du corpus de ce type 
+    return getIdElements(Unite.class, type, getUnites(type), null);
+  }
+  public String[] getIdUnites(String type, Unite[] unites) {    // unites doit être  trié 
+    return getIdElements(Unite.class, type, getUnites(type), unites);
+  }
+  public String[] getIdRelations(String type) {  // toutes les relations du corpus de ce type 
+    return getIdElements(Relation.class, type, getRelations(type), null);
+  }
+  public String[] getIdRelations(String type, Relation[] relations) {   // relations doit être  trié 
+    return getIdElements(Relation.class, type, getRelations(type), relations);
+  }
+  public String[] getIdSchemas(String type) {  // tous les schémas du corpus de ce type 
+    return getIdElements(Schema.class, type, getSchemas(type), null);
+  }
+  public String[] getIdSchemas(String type, Schema[] schemas) {    // schemas doit être  trié 
+    return getIdElements(Schema.class, type, getSchemas(type), schemas);
+  }
+  public String[] getIdElements(Class<? extends Element> classe, String type) {
+    if (classe==Relation.class) return getIdRelations(type);
+    if (classe==Schema.class) return getIdSchemas(type);
+    return getIdUnites(type);
+  }
+  /**
+   * Fonction pour le coloriage
+   */
+  public UniteColoree[] getUnitesAColorier() {
+    ArrayList<UniteColoree> unites = new ArrayList<UniteColoree>();
+    for (Class<? extends Element> classe : stylesElements.keySet())
+      for (String type : stylesElements.get(classe).keySet()) {
+        for (Unite unit : Element.getUnitesSousjacentes(getElementsAVoir(classe, type)))
+          unites.add(new UniteColoree(unit, stylesElements.get(classe).get(type)));
+      }
+    for (Class<? extends Element> classe : stylesValeursElements.keySet())
+      for (String type : stylesValeursElements.get(classe).keySet())
+        for (String champ : stylesValeursElements.get(classe).get(type).keySet())
+          for (String valeur : stylesValeursElements.get(classe).get(type).get(champ).keySet()) {
+            for (Unite unit : Element.getUnitesSousjacentes(getElementsAVoirValeurChamp(classe, type, champ, valeur)))
+              unites.add(new UniteColoree(unit, stylesValeursElements.get(classe).get(type).get(champ).get(valeur)));
+          }
+    return unites.toArray(new UniteColoree[0]);
+  }
+  public Element[] getElementsAVoirValeurChamp(Class<? extends Element> classe,
+          String type, String champ, String valeur) {
+    ArrayList<Element> elts = new ArrayList<Element>();
+    for (Element elt : getElementsAVoir(classe, type))
+      if (valeur.equals(getValeurChamp(elt, champ))) elts.add(elt);
+    return elts.toArray(new Element[0]);
+  }
+  /**
+   * Fonctions de comptage pour les stats
+   */
+  public int getNbElementsAVoir(Class<? extends Element> classe, String type) {
+    return getElementsAVoir(classe, type).length;
+  }
+  public HashMap<String, Integer> compterOccurrencesFiltrees(Class<? extends Element> classe,
+          String type, String champCible, String champFiltre, String[] valeursChampFiltre) {
+    HashMap<String, Integer> compte = initCompte(classe, type, champCible);
+    for (Element elt : getElementsAVoir(classe, type)) {
+      String valCible = getValeurChamp(elt, champCible);
+      if (champFiltre==null) {
+        compte.put(valCible, compte.get(valCible)+1);
+      } else {
+        String valfiltre = getValeurChamp(elt, champFiltre);
+        for (Object valchfiltre : valeursChampFiltre) {
+          if (valfiltre.equals(valchfiltre)) {
+            compte.put(valCible, compte.get(valCible)+1);
+            break;
+          }
+        }
+      }
+    }
+    return compte;
+  }
+  public HashMap<String, HashMap<String, Integer>> compterOccurrencesCorrelees(
+          Class<? extends Element> classe, String type, String champ1, String champ2) {
+    HashMap<String, HashMap<String, Integer>> compte = new HashMap<String, HashMap<String, Integer>>();
+    for (String val : getValeursChamp(classe, type, champ1)) {
+      compte.put(val, initCompte(classe, type, champ2));
+    }
+    compte.put("", initCompte(classe, type, champ2));
+    for (Element elt : getElementsAVoir(classe, type)) {
+      String val1 = getValeurChamp(elt, champ1);
+      String val2 = getValeurChamp(elt, champ2);
+      compte.get(val1).put(val2, compte.get(val1).get(val2)+1);
+    }
+    return compte;
+  }
+  private HashMap<String, Integer> initCompte(Class<? extends Element> classe, String type, String champ) {
+    HashMap<String, Integer> hm = new HashMap<String, Integer>();
+    for (String val : getValeursChamp(classe, type, champ)) {
+      hm.put(val, 0);
+    }
+    hm.put("", 0);
+    return hm;
+  }
+  public Element[] getDoubleSelectionOccurrences(Class<? extends Element> classe, String type,
+          String champ1, String[] valeurs1, String champ2, String[] valeurs2) {
+    ArrayList<Element> aliste = new ArrayList<Element>();
+    for (Element elt : getElementsAVoir(classe, type)) {
+      if (verifierContrainteFiltre(elt, champ1, valeurs1)&&verifierContrainteFiltre(elt, champ2, valeurs2)) {
+        aliste.add(elt);
+      }
+    }
+    Element[] res = aliste.toArray(new Element[0]);
+    Arrays.sort(res);
+    return res;
+  }
+  private boolean verifierContrainteFiltre(Element elt, String champ, String[] valeurs) {
+    if (champ==null) {
+      return true;
+    }
+    String valeur = getValeurChamp(elt, champ);
+    for (String val : valeurs) {
+      if (val.equals(valeur)) {
+        return true;
+      }
+    }
+    return false;
+  }
+  public Matrix getMatrice(Class<? extends Element> classe, String type, String[] champsSelect, Element[] eltsSelect) {
+    HashMap<String, HashMap<String, Integer>> numeros = new HashMap<String, HashMap<String, Integer>>();
+    int nb = 0;
+    for (String champ : champsSelect) {
+      numeros.put(champ, new HashMap<String, Integer>());
+      numeros.get(champ).put("", nb++);
+      for (String val : getValeursChamp(classe, type, champ)) {
+        numeros.get(champ).put(val, nb++);
+      }
+    }
+    double[][] matrice = new double[eltsSelect.length][nb];
+    for (int i = 0; i<eltsSelect.length; i++) {
+      for (String champ : champsSelect) {
+        matrice[i][numeros.get(champ).get(getValeurChamp(eltsSelect[i], champ))] = 1.;
+      }
+    }
+    return new Matrix(matrice, eltsSelect.length, nb);
+  }
+  public SparseMatrix getMatriceCreuse(Class<? extends Element> classe, String type,
+          String[] champsSelect, Element[] eltsSelect) {
+    HashMap<String, HashMap<String, Integer>> numeros =
+            new HashMap<String, HashMap<String, Integer>>();
+    int nb = 0;
+    for (String champ : champsSelect) {
+      numeros.put(champ, new HashMap<String, Integer>());
+      numeros.get(champ).put("", nb++);
+      for (String val : getValeursChamp(classe, type, champ))
+        numeros.get(champ).put(val, nb++);
+    }
+//    double[][] matrice = new double[eltsSelect.length][nb];
+    ArrayList<Integer> rows = new ArrayList<Integer>();
+    ArrayList<Integer> cols = new ArrayList<Integer>();
+    for (int i = 0; i<eltsSelect.length; i++)
+      for (String champ : champsSelect) {
+        rows.add(i);
+        cols.add(numeros.get(champ).get(getValeurChamp(eltsSelect[i], champ)));
+      }
+    return new SparseMatrix(eltsSelect.length, nb, rows, cols, 1);
+  }
+
+  public static class TripletValTypique {
+    public String champ;
+    public String valeur;
+    public float pourcentage;
+    public TripletValTypique(String champ, String valeur, float pourcentage) {
+      this.champ = champ;
+      this.valeur = valeur;
+      this.pourcentage = pourcentage;
+    }
+  }
+  public TripletValTypique[] getValTypiques(Class<? extends Element> classe,
+          String type, Element[] elts) {
+    ArrayList<String> chps = new ArrayList<String>();
+    ArrayList<String> vals = new ArrayList<String>();
+    ArrayList<Float> pcts = new ArrayList<Float>();
+    HashMap<String, Integer> compte = new HashMap<String, Integer>();
+    int total = elts.length;
+    for (String champ : getListeChamps(classe, type)) {
+      compte.clear();
+      for (Element elt : elts) {
+        String val = getValeurChamp(elt, champ);
+        if (val.isEmpty()) continue;
+        if (compte.containsKey(val)) compte.put(val, compte.get(val)+1);
+        else compte.put(val, 1);
+      }
+      for (String val : compte.keySet()) if (2*compte.get(val)>total) {
+          chps.add(champ);
+          vals.add(val);
+          pcts.add(((float) compte.get(val))/total);
+          break;
+        }
+    }
+    TripletValTypique[] triplets = new TripletValTypique[chps.size()];
+    for (int i = 0; i<chps.size(); i++)
+      triplets[i] = new TripletValTypique(chps.get(i), vals.get(i), pcts.get(i));
+    return triplets;
+  }
+  public String[] getIdListeElements(Class<? extends Element> classe,
+          String type, Element[] elts) {
+    return getIdElements(classe, type, elts, null);
+  }
+  public String[][] getValeursChampsListeElements(String[] champs, Element[] elts) {
+    String[][] valeurs = new String[elts.length][champs.length];
+    for (int i = 0; i<elts.length; i++) for (int j = 0; j<champs.length; j++)
+        valeurs[i][j] = getValeurChamp(elts[i], champs[j]);
+    return valeurs;
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/vue/Vue.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVuePresentation.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVuePresentation.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVuePresentation.java	(revision 481)
@@ -0,0 +1,163 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.vue;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import visuAnalec.donnees.Structure;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class VisuVuePresentation extends JPanel implements ActionListener {
+  private VisuVue visuVue;
+  private Vue vue;
+  private JTable tableauChampsAVoir;
+  private JComboBox saisieChampId;
+  private Class<? extends Element> classeSelected;
+  private String typeSelected;
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> modifiabiliteChampsAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> niveauxChampsAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> positionsChampsAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, String>> champsId;
+  VisuVuePresentation(VisuVue visuVue, Vue vue,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, String>> champsId,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> modifiabiliteChampsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> niveauxChampsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> positionsChampsAVoir) {
+    super(new BorderLayout());
+    this.visuVue = visuVue;
+    this.vue = vue;
+    this.champsAVoir = champsAVoir;
+    this.champsId = champsId;
+    this.modifiabiliteChampsAVoir = modifiabiliteChampsAVoir;
+    this.niveauxChampsAVoir = niveauxChampsAVoir;
+    this.positionsChampsAVoir = positionsChampsAVoir;
+    classeSelected = null;
+    typeSelected = null;
+    // Panneau du champ identifiant
+    saisieChampId = new JComboBox();
+    saisieChampId.setEditable(false);
+    saisieChampId.addActionListener(this);
+    JPanel panneauChampId = new JPanel();
+    panneauChampId.add(new JLabel("Choix d'un champ identifiant"));
+    panneauChampId.add(saisieChampId);
+    add(panneauChampId, BorderLayout.NORTH);
+    // Le tableau des champs à visualiser
+    ModeleTableauChampsAVoir donneesChampsAVoir = new ModeleTableauChampsAVoir();
+    tableauChampsAVoir = new JTable(donneesChampsAVoir);
+    JScrollPane scroll2 = new JScrollPane(tableauChampsAVoir);
+    JPanel panneauChampsAVoir = new JPanel();
+    panneauChampsAVoir.add(scroll2);
+    add(panneauChampsAVoir, BorderLayout.CENTER);
+  }
+  void setTypeSelected(Class<? extends Element> classe, String type) {
+    classeSelected = classe;
+    typeSelected = type;
+    reinitialiser();
+  }
+  void reinitialiser() {
+    ((ModeleTableauChampsAVoir) tableauChampsAVoir.getModel()).fireTableDataChanged();
+    saisieChampId.removeActionListener(this);
+    if (typeSelected==null) saisieChampId.setModel(new DefaultComboBoxModel());
+    else {
+      String[] champs = champsAVoir.get(classeSelected).get(typeSelected).toArray(new String[0]);
+      champs = Tableaux.insererStringEnTete(champs, "<aucun>");
+      saisieChampId.setModel(new DefaultComboBoxModel(champs));
+      if (champsId.get(classeSelected).containsKey(typeSelected))
+        saisieChampId.setSelectedItem(champsId.get(classeSelected).get(typeSelected));
+      else saisieChampId.setSelectedIndex(0);
+    }
+    saisieChampId.addActionListener(this);
+  }
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource()==saisieChampId) {
+        if (saisieChampId.getSelectedIndex()==0)
+          champsId.get(classeSelected).remove(typeSelected);
+        else
+          champsId.get(classeSelected).put(typeSelected, (String) saisieChampId.getSelectedItem());
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  private static final String[] nomsColonnes = new String[]{
+    "<html><span style=\"font-weight:900 \">Champ</span>",
+    "<html><span style=\"font-weight:900 \">Niveau</span>",
+    "<html><span style=\"font-weight:900 \">Position</span>",
+    "<html><span style=\"font-weight:900 \">Modifiable ?</span>"
+  };
+  private static final Class[] classesColonnes = new Class[]{String.class, Integer.class, Integer.class, Boolean.class};
+
+  private class ModeleTableauChampsAVoir extends AbstractTableModel {
+    public int getColumnCount() {
+      return nomsColonnes.length;
+    }
+    public int getRowCount() {
+      return (typeSelected==null||!champsAVoir.get(classeSelected).containsKey(typeSelected)) ? 0 : champsAVoir.get(classeSelected).get(typeSelected).size();
+    }
+    public Object getValueAt(int row, int col) {
+      String champ = champsAVoir.get(classeSelected).get(typeSelected).get(row);
+      switch (col) {
+        case 0:
+          return champ;
+        case 1:
+          return niveauxChampsAVoir.get(classeSelected).get(typeSelected).get(champ);
+        case 2:
+          return positionsChampsAVoir.get(classeSelected).get(typeSelected).get(champ);
+        case 3:
+          return modifiabiliteChampsAVoir.get(classeSelected).get(typeSelected).get(champ);
+        default:
+          throw new IndexOutOfBoundsException();
+      }
+    }
+    @Override
+    public String getColumnName(int col) {
+      return nomsColonnes[col];
+    }
+    @Override
+    public Class getColumnClass(int col) {
+      return classesColonnes[col];
+    }
+    @Override
+    public boolean isCellEditable(int row, int col) {
+      if (col==3&&classeSelected==Unite.class) {
+        String champ = champsAVoir.get(classeSelected).get(typeSelected).get(row);
+        String prop = visuVue.getPropChamp(classeSelected, typeSelected, champ);
+        if (Structure.FORME.equals(prop)) return false;
+      }
+      return col>0;
+    }
+    @Override
+    public void setValueAt(Object aValue, int row, int col) {
+      String champ = champsAVoir.get(classeSelected).get(typeSelected).get(row);
+      switch (col) {
+        case 1:
+          niveauxChampsAVoir.get(classeSelected).get(typeSelected).put(champ, (Integer) aValue);
+          return;
+        case 2:
+          positionsChampsAVoir.get(classeSelected).get(typeSelected).put(champ, (Integer) aValue);
+          return;
+        case 3:
+          modifiabiliteChampsAVoir.get(classeSelected).get(typeSelected).put(champ, (Boolean) aValue);
+          return;
+        default:
+          throw new IndexOutOfBoundsException();
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/visuAnalec/vue/VisuVuePresentation.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/LUDecomposition.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/LUDecomposition.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/LUDecomposition.java	(revision 481)
@@ -0,0 +1,311 @@
+package JamaPlus;
+
+   /** LU Decomposition.
+   <P>
+   For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
+   unit lower triangular matrix L, an n-by-n upper triangular matrix U,
+   and a permutation vector piv of length m so that A(piv,:) = L*U.
+   If m < n, then L is m-by-m and U is m-by-n.
+   <P>
+   The LU decompostion with pivoting always exists, even if the matrix is
+   singular, so the constructor will never fail.  The primary use of the
+   LU decomposition is in the solution of square systems of simultaneous
+   linear equations.  This will fail if isNonsingular() returns false.
+   */
+
+public class LUDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Array for internal storage of decomposition.
+   @serial internal array storage.
+   */
+   private double[][] LU;
+
+   /** Row and column dimensions, and pivot sign.
+   @serial column dimension.
+   @serial row dimension.
+   @serial pivot sign.
+   */
+   private int m, n, pivsign; 
+
+   /** Internal storage of pivot vector.
+   @serial pivot vector.
+   */
+   private int[] piv;
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** LU Decomposition
+   @param  A   Rectangular matrix
+   @return     Structure to access L, U and piv.
+   */
+
+   public LUDecomposition (Matrix A) {
+
+   // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
+
+      LU = A.getArrayCopy();
+      m = A.getRowDimension();
+      n = A.getColumnDimension();
+      piv = new int[m];
+      for (int i = 0; i < m; i++) {
+         piv[i] = i;
+      }
+      pivsign = 1;
+      double[] LUrowi;
+      double[] LUcolj = new double[m];
+
+      // Outer loop.
+
+      for (int j = 0; j < n; j++) {
+
+         // Make a copy of the j-th column to localize references.
+
+         for (int i = 0; i < m; i++) {
+            LUcolj[i] = LU[i][j];
+         }
+
+         // Apply previous transformations.
+
+         for (int i = 0; i < m; i++) {
+            LUrowi = LU[i];
+
+            // Most of the time is spent in the following dot product.
+
+            int kmax = Math.min(i,j);
+            double s = 0.0;
+            for (int k = 0; k < kmax; k++) {
+               s += LUrowi[k]*LUcolj[k];
+            }
+
+            LUrowi[j] = LUcolj[i] -= s;
+         }
+   
+         // Find pivot and exchange if necessary.
+
+         int p = j;
+         for (int i = j+1; i < m; i++) {
+            if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) {
+               p = i;
+            }
+         }
+         if (p != j) {
+            for (int k = 0; k < n; k++) {
+               double t = LU[p][k]; LU[p][k] = LU[j][k]; LU[j][k] = t;
+            }
+            int k = piv[p]; piv[p] = piv[j]; piv[j] = k;
+            pivsign = -pivsign;
+         }
+
+         // Compute multipliers.
+         
+         if (j < m & LU[j][j] != 0.0) {
+            for (int i = j+1; i < m; i++) {
+               LU[i][j] /= LU[j][j];
+            }
+         }
+      }
+   }
+
+/* ------------------------
+   Temporary, experimental code.
+   ------------------------ *\
+
+   \** LU Decomposition, computed by Gaussian elimination.
+   <P>
+   This constructor computes L and U with the "daxpy"-based elimination
+   algorithm used in LINPACK and MATLAB.  In Java, we suspect the dot-product,
+   Crout algorithm will be faster.  We have temporarily included this
+   constructor until timing experiments confirm this suspicion.
+   <P>
+   @param  A             Rectangular matrix
+   @param  linpackflag   Use Gaussian elimination.  Actual value ignored.
+   @return               Structure to access L, U and piv.
+   *\
+
+   public LUDecomposition (Matrix A, int linpackflag) {
+      // Initialize.
+      LU = A.getArrayCopy();
+      m = A.getRowDimension();
+      n = A.getColumnDimension();
+      piv = new int[m];
+      for (int i = 0; i < m; i++) {
+         piv[i] = i;
+      }
+      pivsign = 1;
+      // Main loop.
+      for (int k = 0; k < n; k++) {
+         // Find pivot.
+         int p = k;
+         for (int i = k+1; i < m; i++) {
+            if (Math.abs(LU[i][k]) > Math.abs(LU[p][k])) {
+               p = i;
+            }
+         }
+         // Exchange if necessary.
+         if (p != k) {
+            for (int j = 0; j < n; j++) {
+               double t = LU[p][j]; LU[p][j] = LU[k][j]; LU[k][j] = t;
+            }
+            int t = piv[p]; piv[p] = piv[k]; piv[k] = t;
+            pivsign = -pivsign;
+         }
+         // Compute multipliers and eliminate k-th column.
+         if (LU[k][k] != 0.0) {
+            for (int i = k+1; i < m; i++) {
+               LU[i][k] /= LU[k][k];
+               for (int j = k+1; j < n; j++) {
+                  LU[i][j] -= LU[i][k]*LU[k][j];
+               }
+            }
+         }
+      }
+   }
+
+\* ------------------------
+   End of temporary code.
+ * ------------------------ */
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Is the matrix nonsingular?
+   @return     true if U, and hence A, is nonsingular.
+   */
+
+   public boolean isNonsingular () {
+      for (int j = 0; j < n; j++) {
+         if (LU[j][j] == 0)
+            return false;
+      }
+      return true;
+   }
+
+   /** Return lower triangular factor
+   @return     L
+   */
+
+   public Matrix getL () {
+      Matrix X = new Matrix(m,n);
+      double[][] L = X.getArray();
+      for (int i = 0; i < m; i++) {
+         for (int j = 0; j < n; j++) {
+            if (i > j) {
+               L[i][j] = LU[i][j];
+            } else if (i == j) {
+               L[i][j] = 1.0;
+            } else {
+               L[i][j] = 0.0;
+            }
+         }
+      }
+      return X;
+   }
+
+   /** Return upper triangular factor
+   @return     U
+   */
+
+   public Matrix getU () {
+      Matrix X = new Matrix(n,n);
+      double[][] U = X.getArray();
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            if (i <= j) {
+               U[i][j] = LU[i][j];
+            } else {
+               U[i][j] = 0.0;
+            }
+         }
+      }
+      return X;
+   }
+
+   /** Return pivot permutation vector
+   @return     piv
+   */
+
+   public int[] getPivot () {
+      int[] p = new int[m];
+      for (int i = 0; i < m; i++) {
+         p[i] = piv[i];
+      }
+      return p;
+   }
+
+   /** Return pivot permutation vector as a one-dimensional double array
+   @return     (double) piv
+   */
+
+   public double[] getDoublePivot () {
+      double[] vals = new double[m];
+      for (int i = 0; i < m; i++) {
+         vals[i] = (double) piv[i];
+      }
+      return vals;
+   }
+
+   /** Determinant
+   @return     det(A)
+   @exception  IllegalArgumentException  Matrix must be square
+   */
+
+   public double det () {
+      if (m != n) {
+         throw new IllegalArgumentException("Matrix must be square.");
+      }
+      double d = (double) pivsign;
+      for (int j = 0; j < n; j++) {
+         d *= LU[j][j];
+      }
+      return d;
+   }
+
+   /** Solve A*X = B
+   @param  B   A Matrix with as many rows as A and any number of columns.
+   @return     X so that L*U*X = B(piv,:)
+   @exception  IllegalArgumentException Matrix row dimensions must agree.
+   @exception  RuntimeException  Matrix is singular.
+   */
+
+   public Matrix solve (Matrix B) {
+      if (B.getRowDimension() != m) {
+         throw new IllegalArgumentException("Matrix row dimensions must agree.");
+      }
+      if (!this.isNonsingular()) {
+         throw new RuntimeException("Matrix is singular.");
+      }
+
+      // Copy right hand side with pivoting
+      int nx = B.getColumnDimension();
+      Matrix Xmat = B.getMatrix(piv,0,nx-1);
+      double[][] X = Xmat.getArray();
+
+      // Solve L*Y = B(piv,:)
+      for (int k = 0; k < n; k++) {
+         for (int i = k+1; i < n; i++) {
+            for (int j = 0; j < nx; j++) {
+               X[i][j] -= X[k][j]*LU[i][k];
+            }
+         }
+      }
+      // Solve U*X = Y;
+      for (int k = n-1; k >= 0; k--) {
+         for (int j = 0; j < nx; j++) {
+            X[k][j] /= LU[k][k];
+         }
+         for (int i = 0; i < k; i++) {
+            for (int j = 0; j < nx; j++) {
+               X[i][j] -= X[k][j]*LU[i][k];
+            }
+         }
+      }
+      return Xmat;
+   }
+}

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/LUDecomposition.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/util/DoubleArraysPlus.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/util/DoubleArraysPlus.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/util/DoubleArraysPlus.java	(revision 481)
@@ -0,0 +1,97 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus.util;
+
+import java.util.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class DoubleArraysPlus {
+  public static void copyReverse(int length, double[] src, int srcStart,
+          double[] dest, int destStart) {
+    destStart += length-1;
+    for (int i = 0; i<length; i++) dest[destStart-i] = src[srcStart+i];
+  }
+
+   private static class Couple implements Comparable<Couple> {
+    double x1;
+    Object x2;
+
+    public int compareTo(Couple c) {
+      return Double.compare(x1, c.x1);
+    }
+  }
+
+  public static void sort2(double[] a1, double[] a2, int n, int istart) {
+    // sort the first n elements of a1 and a2, starting at index istart,
+    // in increasing order for a1 
+    // (elements with indexes < istart or > istart + n preserved) 
+    Couple[] cs = new Couple[n];
+    for (int i = 0; i<n; i++) {
+      cs[i] = new Couple();
+      cs[i].x1 = a1[i+istart];
+      cs[i].x2 = a2[i+istart];
+    }
+    Arrays.sort(cs);
+    for (int i = 0; i<n; i++) {
+      a1[i+istart] = cs[i].x1;
+      a2[i+istart] = (Double) cs[i].x2;
+    }
+  }
+ public static void sort2(double[] a1, double[][] a2, int n, int istart) {
+    // sort the first n elements of a1 and a2[] (lines of array a2)
+//    starting at index istart, in increasing order for a1
+    // (elements with index < istart or > istart + n preserved) 
+    Couple[] cs = new Couple[n];
+    for (int i = 0; i<n; i++) {
+      cs[i] = new Couple();
+      cs[i].x1 = a1[i+istart];
+      cs[i].x2 = a2[i+istart];
+    }
+    Arrays.sort(cs);
+    for (int i = 0; i<n; i++) {
+      a1[i+istart] = cs[i].x1;
+      a2[i+istart] = (double[]) cs[i].x2;
+    }
+  }
+
+  public static int indAbsMax(int n, double x[], int istart) {
+    // finds the index of element having maximum absolute value 
+    // among the first n elements of x starting at index istart
+    if (n<1||istart<0||istart+n>x.length)
+      throw new ArrayIndexOutOfBoundsException();
+    if (n==1) return (istart);
+    double max = Math.abs(x[istart]);
+    int imax = istart;
+    for (int i = istart+1; i<istart+n; i++) {
+      double ax = Math.abs(x[i]);
+      if (ax>max) {
+        max = ax;
+        imax = i;
+      }
+    }
+    return imax;
+  }
+
+  public static double dot(double[] x, double[] y) {
+    // dot product of vectors x and y
+    int n = x.length;
+    if (n!=y.length) throw new IllegalArgumentException();
+    double res = 0;
+    for (int i = 0; i<n; i++) res += x[i]*y[i];
+    return res;
+  }
+  public static void rotateArray(double[][] a, int x) {
+    // permutation circulaire des lignes de la matrice a
+    // plaçant la ligne x en tête
+  double[][] b =new double[a.length-x][];
+ System.arraycopy(a, x, b, 0, b.length);
+ System.arraycopy(a, 0, a, b.length, a.length-b.length);
+ System.arraycopy(b, 0, a, 0, b.length);
+     }
+
+}

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/util/DoubleArraysPlus.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/util/Machine.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/util/Machine.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/util/Machine.java	(revision 481)
@@ -0,0 +1,143 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus.util;
+
+/**
+ *
+ * @author Bernard
+ */
+public class Machine {
+
+    /***********************************************************************
+     *                                                                     *
+     *				machar()			       *
+     *                                                                     *
+     ***********************************************************************/
+    /***********************************************************************
+    
+    Description
+    -----------
+    
+    This function is a partial translation of a Fortran-77 subroutine 
+    written by W. J. Cody of Argonne National Laboratory.
+    It dynamically determines the listed machine parameters of the
+    floating-point arithmetic.  According to the documentation of
+    the Fortran code, "the determination of the first three uses an
+    extension of an algorithm due to M. Malcolm, ACM 15 (1972), 
+    pp. 949-951, incorporating some, but not all, of the improvements
+    suggested by M. Gentleman and S. Marovich, CACM 17 (1974), 
+    pp. 276-277."  The complete Fortran version of this translation is
+    documented in W. J. Cody, "Machar: a Subroutine to Dynamically 
+    Determine Determine Machine Parameters," TOMS 14, December, 1988.
+    
+    
+    Parameters reported 
+    -------------------
+    
+    ibeta     the radix for the floating-point representation       
+    it        the number of base ibeta digits in the floating-point
+    significand					 
+    irnd      0 if floating-point addition chops		      
+    1 if floating-point addition rounds, but not in the 
+    ieee style					
+    2 if floating-point addition rounds in the ieee style
+    3 if floating-point addition chops, and there is    
+    partial underflow				
+    4 if floating-point addition rounds, but not in the
+    ieee style, and there is partial underflow    
+    5 if floating-point addition rounds in the ieee style,
+    and there is partial underflow                   
+    machep    the largest negative integer such that              
+    1.0+float(ibeta)**machep .ne. 1.0, except that 
+    machep is bounded below by  -(it+3)          
+    negeps    the largest negative integer such that          
+    1.0-float(ibeta)**negeps .ne. 1.0, except that 
+    negeps is bounded below by  -(it+3)	       
+    
+     ***********************************************************************/
+    public static double eps(/*int res[]*/) {
+        int ibeta, it, irnd, machep, negep;
+        double beta, betain, betah, a, b = 0, ZERO, ONE, TWO, temp, tempa, temp1;
+        int i, itemp;
+
+        ONE = (double) 1;
+        TWO = ONE + ONE;
+        ZERO = ONE - ONE;
+
+        a = ONE;
+        temp1 = ONE;
+        while (temp1 - ONE == ZERO) {
+            a += a;
+            temp = a + ONE;
+            temp1 = temp - a;
+            b += a; /* to prevent icc compiler error */
+        }
+        b = ONE;
+        itemp = 0;
+        while (itemp == 0) {
+            b += b;
+            temp = a + b;
+            itemp = (int) (temp - a);
+        }
+        ibeta = itemp;
+        beta = (double) ibeta;
+
+        it = 0;
+        b = ONE;
+        temp1 = ONE;
+        while (temp1 - ONE == ZERO) {
+            it++;
+            b *= beta;
+            temp = b + ONE;
+            temp1 = temp - b;
+        }
+        irnd = 0;
+        betah = beta / TWO;
+        temp = a + betah;
+        if (temp - a != ZERO) irnd = 1;
+        tempa = a + beta;
+        temp = tempa + betah;
+        if ((irnd == 0) && (temp - tempa != ZERO)) irnd = 2;
+
+        negep = it + 3;
+        betain = ONE / beta;
+        a = ONE;
+        for (i = 0; i < negep; i++) a *= betain;
+        b = a;
+        temp = ONE - a;
+        while (temp - ONE == ZERO) {
+            a *= beta;
+            negep--;
+            temp = ONE - a;
+        }
+        negep = -(negep);
+
+        machep = -(it) - 3;
+        a = b;
+        temp = ONE + a;
+        while (temp - ONE == ZERO) {
+            a *= beta;
+            machep += 1;
+            temp = ONE + a;
+        }
+//        res[0] = ibeta;
+//        res[1] = it;
+//        res[2] = irnd;
+//        res[3] = machep;
+//        res[4] = negep;
+        return a;
+    }
+
+    static public void main(String[] args) {
+        int[] res = new int[5];
+//        double precision = eps(res);
+//        System.out.println("eps = " + precision);
+        System.out.println("ibeta = " + res[0]);
+        System.out.println("it = " + res[1]);
+        System.out.println("irnd = " + res[2]);
+        System.out.println("machep = " + res[3]);
+        System.out.println("negep = " + res[4]);
+    }
+}

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/util/Machine.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/CholeskyDecomposition.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/CholeskyDecomposition.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/CholeskyDecomposition.java	(revision 481)
@@ -0,0 +1,199 @@
+package JamaPlus;
+
+   /** Cholesky Decomposition.
+   <P>
+   For a symmetric, positive definite matrix A, the Cholesky decomposition
+   is an lower triangular matrix L so that A = L*L'.
+   <P>
+   If the matrix is not symmetric or positive definite, the constructor
+   returns a partial decomposition and sets an internal flag that may
+   be queried by the isSPD() method.
+   */
+
+public class CholeskyDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Array for internal storage of decomposition.
+   @serial internal array storage.
+   */
+   private double[][] L;
+
+   /** Row and column dimension (square matrix).
+   @serial matrix dimension.
+   */
+   private int n;
+
+   /** Symmetric and positive definite flag.
+   @serial is symmetric and positive definite flag.
+   */
+   private boolean isspd;
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** Cholesky algorithm for symmetric and positive definite matrix.
+   @param  A   Square, symmetric matrix.
+   @return     Structure to access L and isspd flag.
+   */
+
+   public CholeskyDecomposition (Matrix Arg) {
+
+
+     // Initialize.
+      double[][] A = Arg.getArray();
+      n = Arg.getRowDimension();
+      L = new double[n][n];
+      isspd = (Arg.getColumnDimension() == n);
+      // Main loop.
+      for (int j = 0; j < n; j++) {
+         double[] Lrowj = L[j];
+         double d = 0.0;
+         for (int k = 0; k < j; k++) {
+            double[] Lrowk = L[k];
+            double s = 0.0;
+            for (int i = 0; i < k; i++) {
+               s += Lrowk[i]*Lrowj[i];
+            }
+            Lrowj[k] = s = (A[j][k] - s)/L[k][k];
+            d = d + s*s;
+            isspd = isspd & (A[k][j] == A[j][k]); 
+         }
+         d = A[j][j] - d;
+         isspd = isspd & (d > 0.0);
+         L[j][j] = Math.sqrt(Math.max(d,0.0));
+         for (int k = j+1; k < n; k++) {
+            L[j][k] = 0.0;
+         }
+      }
+   }
+
+/* ------------------------
+   Temporary, experimental code.
+ * ------------------------ *\
+
+   \** Right Triangular Cholesky Decomposition.
+   <P>
+   For a symmetric, positive definite matrix A, the Right Cholesky
+   decomposition is an upper triangular matrix R so that A = R'*R.
+   This constructor computes R with the Fortran inspired column oriented
+   algorithm used in LINPACK and MATLAB.  In Java, we suspect a row oriented,
+   lower triangular decomposition is faster.  We have temporarily included
+   this constructor here until timing experiments confirm this suspicion.
+   *\
+
+   \** Array for internal storage of right triangular decomposition. **\
+   private transient double[][] R;
+
+   \** Cholesky algorithm for symmetric and positive definite matrix.
+   @param  A           Square, symmetric matrix.
+   @param  rightflag   Actual value ignored.
+   @return             Structure to access R and isspd flag.
+   *\
+
+   public CholeskyDecomposition (Matrix Arg, int rightflag) {
+      // Initialize.
+      double[][] A = Arg.getArray();
+      n = Arg.getColumnDimension();
+      R = new double[n][n];
+      isspd = (Arg.getColumnDimension() == n);
+      // Main loop.
+      for (int j = 0; j < n; j++) {
+         double d = 0.0;
+         for (int k = 0; k < j; k++) {
+            double s = A[k][j];
+            for (int i = 0; i < k; i++) {
+               s = s - R[i][k]*R[i][j];
+            }
+            R[k][j] = s = s/R[k][k];
+            d = d + s*s;
+            isspd = isspd & (A[k][j] == A[j][k]); 
+         }
+         d = A[j][j] - d;
+         isspd = isspd & (d > 0.0);
+         R[j][j] = Math.sqrt(Math.max(d,0.0));
+         for (int k = j+1; k < n; k++) {
+            R[k][j] = 0.0;
+         }
+      }
+   }
+
+   \** Return upper triangular factor.
+   @return     R
+   *\
+
+   public Matrix getR () {
+      return new Matrix(R,n,n);
+   }
+
+\* ------------------------
+   End of temporary code.
+ * ------------------------ */
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Is the matrix symmetric and positive definite?
+   @return     true if A is symmetric and positive definite.
+   */
+
+   public boolean isSPD () {
+      return isspd;
+   }
+
+   /** Return triangular factor.
+   @return     L
+   */
+
+   public Matrix getL () {
+      return new Matrix(L,n,n);
+   }
+
+   /** Solve A*X = B
+   @param  B   A Matrix with as many rows as A and any number of columns.
+   @return     X so that L*L'*X = B
+   @exception  IllegalArgumentException  Matrix row dimensions must agree.
+   @exception  RuntimeException  Matrix is not symmetric positive definite.
+   */
+
+   public Matrix solve (Matrix B) {
+      if (B.getRowDimension() != n) {
+         throw new IllegalArgumentException("Matrix row dimensions must agree.");
+      }
+      if (!isspd) {
+         throw new RuntimeException("Matrix is not symmetric positive definite.");
+      }
+
+      // Copy right hand side.
+      double[][] X = B.getArrayCopy();
+      int nx = B.getColumnDimension();
+
+	      // Solve L*Y = B;
+	      for (int k = 0; k < n; k++) {
+	        for (int j = 0; j < nx; j++) {
+	           for (int i = 0; i < k ; i++) {
+	               X[k][j] -= X[i][j]*L[k][i];
+	           }
+	           X[k][j] /= L[k][k];
+	        }
+	      }
+	
+	      // Solve L'*X = Y;
+	      for (int k = n-1; k >= 0; k--) {
+	        for (int j = 0; j < nx; j++) {
+	           for (int i = k+1; i < n ; i++) {
+	               X[k][j] -= X[i][j]*L[i][k];
+	           }
+	           X[k][j] /= L[k][k];
+	        }
+	      }
+      
+      
+      return new Matrix(X,n,nx);
+   }
+}
+

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/CholeskyDecomposition.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/SingularValueDecomposition.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/SingularValueDecomposition.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/SingularValueDecomposition.java	(revision 481)
@@ -0,0 +1,556 @@
+package JamaPlus;
+import JamaPlus.util.*;
+
+   /** Singular Value Decomposition.
+   <P>
+   For an m-by-n matrix A with m >= n, the singular value decomposition is
+   an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and
+   an n-by-n orthogonal matrix V so that A = U*S*V'.
+   <P>
+   The singular values, sigma[k] = S[k][k], are ordered so that
+   sigma[0] >= sigma[1] >= ... >= sigma[n-1].
+   <P>
+   The singular value decompostion always exists, so the constructor will
+   never fail.  The matrix condition number and the effective numerical
+   rank can be computed from this decomposition.
+   */
+
+public class SingularValueDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Arrays for internal storage of U and V.
+   @serial internal storage of U.
+   @serial internal storage of V.
+   */
+   private double[][] U, V;
+
+   /** Array for internal storage of singular values.
+   @serial internal storage of singular values.
+   */
+   private double[] s;
+
+   /** Row and column dimensions.
+   @serial row dimension.
+   @serial column dimension.
+   */
+   private int m, n;
+   
+   private boolean transpose; // pour éviter les bugs quand m<n (cf.ci-dessous) 
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** Construct the singular value decomposition
+   @param A    Rectangular matrix
+   @return     Structure to access U, S and V.
+   */
+
+   public SingularValueDecomposition (Matrix Arg) {
+
+      // Derived from LINPACK code.
+      // Initialize.
+      /* Apparently the failing cases are only a proper subset of (m<n), 
+	 so let's not throw error.  Correct fix to come later?
+      if (m<n) {
+	  throw new IllegalArgumentException("Jama SVD only works for m >= n"); }
+      */
+      /* 
+       * Une façon très simple de contourner le problème ci-dessus :
+       * si m < n on transpose A
+       * (ce qui revient à échanger U et V, S restant inchangé)
+       */
+   transpose = Arg.getColumnDimension()>Arg.getRowDimension();
+    Matrix M = transpose ? Arg.transpose() : Arg.copy();
+  
+     double[][] A = M.getArray();
+      m = M.getRowDimension();
+      n = M.getColumnDimension();
+
+      s = new double [n];
+      U = new double [m][n];
+      V = new double [n][n];
+      double[] e = new double [n];
+      double[] work = new double [m];
+      boolean wantu = true;
+      boolean wantv = true;
+
+      // Reduce A to bidiagonal form, storing the diagonal elements
+      // in s and the super-diagonal elements in e.
+
+      int nct = Math.min(m-1,n);
+      int nrt = Math.max(0,Math.min(n-2,m));
+      for (int k = 0; k < Math.max(nct,nrt); k++) {
+         if (k < nct) {
+
+            // Compute the transformation for the k-th column and
+            // place the k-th diagonal in s[k].
+            // Compute 2-norm of k-th column without under/overflow.
+            s[k] = 0;
+            for (int i = k; i < m; i++) {
+               s[k] = Math.hypot(s[k],A[i][k]);
+            }
+            if (s[k] != 0.0) {
+               if (A[k][k] < 0.0) {
+                  s[k] = -s[k];
+               }
+               for (int i = k; i < m; i++) {
+                  A[i][k] /= s[k];
+               }
+               A[k][k] += 1.0;
+            }
+            s[k] = -s[k];
+         }
+         for (int j = k+1; j < n; j++) {
+            if ((k < nct) & (s[k] != 0.0))  {
+
+            // Apply the transformation.
+
+               double t = 0;
+               for (int i = k; i < m; i++) {
+                  t += A[i][k]*A[i][j];
+               }
+               t = -t/A[k][k];
+               for (int i = k; i < m; i++) {
+                  A[i][j] += t*A[i][k];
+               }
+            }
+
+            // Place the k-th row of A into e for the
+            // subsequent calculation of the row transformation.
+
+            e[j] = A[k][j];
+         }
+         if (wantu & (k < nct)) {
+
+            // Place the transformation in U for subsequent back
+            // multiplication.
+
+            for (int i = k; i < m; i++) {
+               U[i][k] = A[i][k];
+            }
+         }
+         if (k < nrt) {
+
+            // Compute the k-th row transformation and place the
+            // k-th super-diagonal in e[k].
+            // Compute 2-norm without under/overflow.
+            e[k] = 0;
+            for (int i = k+1; i < n; i++) {
+               e[k] = Math.hypot(e[k],e[i]);
+            }
+            if (e[k] != 0.0) {
+               if (e[k+1] < 0.0) {
+                  e[k] = -e[k];
+               }
+               for (int i = k+1; i < n; i++) {
+                  e[i] /= e[k];
+               }
+               e[k+1] += 1.0;
+            }
+            e[k] = -e[k];
+            if ((k+1 < m) & (e[k] != 0.0)) {
+
+            // Apply the transformation.
+
+               for (int i = k+1; i < m; i++) {
+                  work[i] = 0.0;
+               }
+               for (int j = k+1; j < n; j++) {
+                  for (int i = k+1; i < m; i++) {
+                     work[i] += e[j]*A[i][j];
+                  }
+               }
+               for (int j = k+1; j < n; j++) {
+                  double t = -e[j]/e[k+1];
+                  for (int i = k+1; i < m; i++) {
+                     A[i][j] += t*work[i];
+                  }
+               }
+            }
+            if (wantv) {
+
+            // Place the transformation in V for subsequent
+            // back multiplication.
+
+               for (int i = k+1; i < n; i++) {
+                  V[i][k] = e[i];
+               }
+            }
+         }
+      }
+
+      // Set up the final bidiagonal matrix or order p.
+
+      int p = Math.min(n,m+1);
+      if (nct < n) {
+         s[nct] = A[nct][nct];
+      }
+      if (m < p) {
+         s[p-1] = 0.0;
+      }
+      if (nrt+1 < p) {
+         e[nrt] = A[nrt][p-1];
+      }
+      e[p-1] = 0.0;
+
+      // If required, generate U.
+
+      if (wantu) {
+         for (int j = nct; j < n; j++) {
+            for (int i = 0; i < m; i++) {
+               U[i][j] = 0.0;
+            }
+            U[j][j] = 1.0;
+         }
+         for (int k = nct-1; k >= 0; k--) {
+            if (s[k] != 0.0) {
+               for (int j = k+1; j < n; j++) {
+                  double t = 0;
+                  for (int i = k; i < m; i++) {
+                     t += U[i][k]*U[i][j];
+                  }
+                  t = -t/U[k][k];
+                  for (int i = k; i < m; i++) {
+                     U[i][j] += t*U[i][k];
+                  }
+               }
+               for (int i = k; i < m; i++ ) {
+                  U[i][k] = -U[i][k];
+               }
+               U[k][k] = 1.0 + U[k][k];
+               for (int i = 0; i < k-1; i++) {
+                  U[i][k] = 0.0;
+               }
+            } else {
+               for (int i = 0; i < m; i++) {
+                  U[i][k] = 0.0;
+               }
+               U[k][k] = 1.0;
+            }
+         }
+      }
+
+      // If required, generate V.
+
+      if (wantv) {
+         for (int k = n-1; k >= 0; k--) {
+            if ((k < nrt) & (e[k] != 0.0)) {
+               for (int j = k+1; j < n; j++) {
+                  double t = 0;
+                  for (int i = k+1; i < n; i++) {
+                     t += V[i][k]*V[i][j];
+                  }
+                  t = -t/V[k+1][k];
+                  for (int i = k+1; i < n; i++) {
+                     V[i][j] += t*V[i][k];
+                  }
+               }
+            }
+            for (int i = 0; i < n; i++) {
+               V[i][k] = 0.0;
+            }
+            V[k][k] = 1.0;
+         }
+      }
+
+      // Main iteration loop for the singular values.
+
+      int pp = p-1;
+      int iter = 0;
+      double eps = Math.pow(2.0,-52.0);
+      double tiny = Math.pow(2.0,-966.0);
+      while (p > 0) {
+         int k,kase;
+
+         // Here is where a test for too many iterations would go.
+
+         // This section of the program inspects for
+         // negligible elements in the s and e arrays.  On
+         // completion the variables kase and k are set as follows.
+
+         // kase = 1     if s(p) and e[k-1] are negligible and k<p
+         // kase = 2     if s(k) is negligible and k<p
+         // kase = 3     if e[k-1] is negligible, k<p, and
+         //              s(k), ..., s(p) are not negligible (qr step).
+         // kase = 4     if e(p-1) is negligible (convergence).
+
+         for (k = p-2; k >= -1; k--) {
+            if (k == -1) {
+               break;
+            }
+            if (Math.abs(e[k]) <=
+                  tiny + eps*(Math.abs(s[k]) + Math.abs(s[k+1]))) {
+               e[k] = 0.0;
+               break;
+            }
+         }
+         if (k == p-2) {
+            kase = 4;
+         } else {
+            int ks;
+            for (ks = p-1; ks >= k; ks--) {
+               if (ks == k) {
+                  break;
+               }
+               double t = (ks != p ? Math.abs(e[ks]) : 0.) + 
+                          (ks != k+1 ? Math.abs(e[ks-1]) : 0.);
+               if (Math.abs(s[ks]) <= tiny + eps*t)  {
+                  s[ks] = 0.0;
+                  break;
+               }
+            }
+            if (ks == k) {
+               kase = 3;
+            } else if (ks == p-1) {
+               kase = 1;
+            } else {
+               kase = 2;
+               k = ks;
+            }
+         }
+         k++;
+
+         // Perform the task indicated by kase.
+
+         switch (kase) {
+
+            // Deflate negligible s(p).
+
+            case 1: {
+               double f = e[p-2];
+               e[p-2] = 0.0;
+               for (int j = p-2; j >= k; j--) {
+                  double t = Math.hypot(s[j],f);
+                  double cs = s[j]/t;
+                  double sn = f/t;
+                  s[j] = t;
+                  if (j != k) {
+                     f = -sn*e[j-1];
+                     e[j-1] = cs*e[j-1];
+                  }
+                  if (wantv) {
+                     for (int i = 0; i < n; i++) {
+                        t = cs*V[i][j] + sn*V[i][p-1];
+                        V[i][p-1] = -sn*V[i][j] + cs*V[i][p-1];
+                        V[i][j] = t;
+                     }
+                  }
+               }
+            }
+            break;
+
+            // Split at negligible s(k).
+
+            case 2: {
+               double f = e[k-1];
+               e[k-1] = 0.0;
+               for (int j = k; j < p; j++) {
+                  double t = Math.hypot(s[j],f);
+                  double cs = s[j]/t;
+                  double sn = f/t;
+                  s[j] = t;
+                  f = -sn*e[j];
+                  e[j] = cs*e[j];
+                  if (wantu) {
+                     for (int i = 0; i < m; i++) {
+                        t = cs*U[i][j] + sn*U[i][k-1];
+                        U[i][k-1] = -sn*U[i][j] + cs*U[i][k-1];
+                        U[i][j] = t;
+                     }
+                  }
+               }
+            }
+            break;
+
+            // Perform one qr step.
+
+            case 3: {
+
+               // Calculate the shift.
+   
+               double scale = Math.max(Math.max(Math.max(Math.max(
+                       Math.abs(s[p-1]),Math.abs(s[p-2])),Math.abs(e[p-2])), 
+                       Math.abs(s[k])),Math.abs(e[k]));
+               double sp = s[p-1]/scale;
+               double spm1 = s[p-2]/scale;
+               double epm1 = e[p-2]/scale;
+               double sk = s[k]/scale;
+               double ek = e[k]/scale;
+               double b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
+               double c = (sp*epm1)*(sp*epm1);
+               double shift = 0.0;
+               if ((b != 0.0) | (c != 0.0)) {
+                  shift = Math.sqrt(b*b + c);
+                  if (b < 0.0) {
+                     shift = -shift;
+                  }
+                  shift = c/(b + shift);
+               }
+               double f = (sk + sp)*(sk - sp) + shift;
+               double g = sk*ek;
+   
+               // Chase zeros.
+   
+               for (int j = k; j < p-1; j++) {
+                  double t = Math.hypot(f,g);
+                  double cs = f/t;
+                  double sn = g/t;
+                  if (j != k) {
+                     e[j-1] = t;
+                  }
+                  f = cs*s[j] + sn*e[j];
+                  e[j] = cs*e[j] - sn*s[j];
+                  g = sn*s[j+1];
+                  s[j+1] = cs*s[j+1];
+                  if (wantv) {
+                     for (int i = 0; i < n; i++) {
+                        t = cs*V[i][j] + sn*V[i][j+1];
+                        V[i][j+1] = -sn*V[i][j] + cs*V[i][j+1];
+                        V[i][j] = t;
+                     }
+                  }
+                  t = Math.hypot(f,g);
+                  cs = f/t;
+                  sn = g/t;
+                  s[j] = t;
+                  f = cs*e[j] + sn*s[j+1];
+                  s[j+1] = -sn*e[j] + cs*s[j+1];
+                  g = sn*e[j+1];
+                  e[j+1] = cs*e[j+1];
+                  if (wantu && (j < m-1)) {
+                     for (int i = 0; i < m; i++) {
+                        t = cs*U[i][j] + sn*U[i][j+1];
+                        U[i][j+1] = -sn*U[i][j] + cs*U[i][j+1];
+                        U[i][j] = t;
+                     }
+                  }
+               }
+               e[p-2] = f;
+               iter = iter + 1;
+            }
+            break;
+
+            // Convergence.
+
+            case 4: {
+
+               // Make the singular values positive.
+   
+               if (s[k] <= 0.0) {
+                  s[k] = (s[k] < 0.0 ? -s[k] : 0.0);
+                  if (wantv) {
+                     for (int i = 0; i <= pp; i++) {
+                        V[i][k] = -V[i][k];
+                     }
+                  }
+               }
+   
+               // Order the singular values.
+   
+               while (k < pp) {
+                  if (s[k] >= s[k+1]) {
+                     break;
+                  }
+                  double t = s[k];
+                  s[k] = s[k+1];
+                  s[k+1] = t;
+                  if (wantv && (k < n-1)) {
+                     for (int i = 0; i < n; i++) {
+                        t = V[i][k+1]; V[i][k+1] = V[i][k]; V[i][k] = t;
+                     }
+                  }
+                  if (wantu && (k < m-1)) {
+                     for (int i = 0; i < m; i++) {
+                        t = U[i][k+1]; U[i][k+1] = U[i][k]; U[i][k] = t;
+                     }
+                  }
+                  k++;
+               }
+               iter = 0;
+               p--;
+            }
+            break;
+         }
+      }
+   }
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Return the left singular vectors
+   @return     U
+   */
+
+   public Matrix getU () {
+      return transpose ? new Matrix(V,n,n) : new Matrix(U,m,n);
+   }
+
+   /** Return the right singular vectors
+   @return     V
+   */
+
+   public Matrix getV () {
+      return transpose ? new Matrix(U,m,n) : new Matrix(V,n,n);
+   }
+
+   /** Return the one-dimensional array of singular values
+   @return     diagonal of S.
+   */
+
+   public double[] getSingularValues () {
+      return s;
+   }
+
+   /** Return the diagonal matrix of singular values
+   @return     S
+   */
+
+   public Matrix getS () {
+      Matrix X = new Matrix(n,n);
+      double[][] S = X.getArray();
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            S[i][j] = 0.0;
+         }
+         S[i][i] = this.s[i];
+      }
+      return X;
+   }
+
+   /** Two norm
+   @return     max(S)
+   */
+
+   public double norm2 () {
+      return s[0];
+   }
+
+   /** Two norm condition number
+   @return     max(S)/min(S)
+   */
+
+   public double cond () {
+      return s[0]/s[Math.min(m,n)-1];
+   }
+
+   /** Effective numerical matrix rank
+   @return     Number of nonnegligible singular values.
+   */
+
+   public int rank () {
+      double eps = Math.pow(2.0,-52.0);
+      double tol = Math.max(m,n)*s[0]*eps;
+      int r = 0;
+      for (int i = 0; i < s.length; i++) {
+         if (s[i] > tol) {
+            r++;
+         }
+      }
+      return r;
+   }
+}

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/SingularValueDecomposition.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/SingularValueDecomposition.java0
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/SingularValueDecomposition.java0	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/SingularValueDecomposition.java0	(revision 481)
@@ -0,0 +1,547 @@
+package JamaPlus;
+import JamaPlus.util.*;
+
+   /** Singular Value Decomposition.
+   <P>
+   For an m-by-n matrix A with m >= n, the singular value decomposition is
+   an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and
+   an n-by-n orthogonal matrix V so that A = U*S*V'.
+   <P>
+   The singular values, sigma[k] = S[k][k], are ordered so that
+   sigma[0] >= sigma[1] >= ... >= sigma[n-1].
+   <P>
+   The singular value decompostion always exists, so the constructor will
+   never fail.  The matrix condition number and the effective numerical
+   rank can be computed from this decomposition.
+   */
+
+public class SingularValueDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Arrays for internal storage of U and V.
+   @serial internal storage of U.
+   @serial internal storage of V.
+   */
+   private double[][] U, V;
+
+   /** Array for internal storage of singular values.
+   @serial internal storage of singular values.
+   */
+   private double[] s;
+
+   /** Row and column dimensions.
+   @serial row dimension.
+   @serial column dimension.
+   */
+   private int m, n;
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** Construct the singular value decomposition
+   @param A    Rectangular matrix
+   @return     Structure to access U, S and V.
+   */
+
+   public SingularValueDecomposition (Matrix Arg) {
+
+      // Derived from LINPACK code.
+      // Initialize.
+      double[][] A = Arg.getArrayCopy();
+      m = Arg.getRowDimension();
+      n = Arg.getColumnDimension();
+
+      /* Apparently the failing cases are only a proper subset of (m<n), 
+	 so let's not throw error.  Correct fix to come later?
+      if (m<n) {
+	  throw new IllegalArgumentException("Jama SVD only works for m >= n"); }
+      */
+      int nu = Math.min(m,n);
+      s = new double [Math.min(m+1,n)];
+      U = new double [m][nu];
+      V = new double [n][n];
+      double[] e = new double [n];
+      double[] work = new double [m];
+      boolean wantu = true;
+      boolean wantv = true;
+
+      // Reduce A to bidiagonal form, storing the diagonal elements
+      // in s and the super-diagonal elements in e.
+
+      int nct = Math.min(m-1,n);
+      int nrt = Math.max(0,Math.min(n-2,m));
+      for (int k = 0; k < Math.max(nct,nrt); k++) {
+         if (k < nct) {
+
+            // Compute the transformation for the k-th column and
+            // place the k-th diagonal in s[k].
+            // Compute 2-norm of k-th column without under/overflow.
+            s[k] = 0;
+            for (int i = k; i < m; i++) {
+               s[k] = Math.hypot(s[k],A[i][k]);
+            }
+            if (s[k] != 0.0) {
+               if (A[k][k] < 0.0) {
+                  s[k] = -s[k];
+               }
+               for (int i = k; i < m; i++) {
+                  A[i][k] /= s[k];
+               }
+               A[k][k] += 1.0;
+            }
+            s[k] = -s[k];
+         }
+         for (int j = k+1; j < n; j++) {
+            if ((k < nct) & (s[k] != 0.0))  {
+
+            // Apply the transformation.
+
+               double t = 0;
+               for (int i = k; i < m; i++) {
+                  t += A[i][k]*A[i][j];
+               }
+               t = -t/A[k][k];
+               for (int i = k; i < m; i++) {
+                  A[i][j] += t*A[i][k];
+               }
+            }
+
+            // Place the k-th row of A into e for the
+            // subsequent calculation of the row transformation.
+
+            e[j] = A[k][j];
+         }
+         if (wantu & (k < nct)) {
+
+            // Place the transformation in U for subsequent back
+            // multiplication.
+
+            for (int i = k; i < m; i++) {
+               U[i][k] = A[i][k];
+            }
+         }
+         if (k < nrt) {
+
+            // Compute the k-th row transformation and place the
+            // k-th super-diagonal in e[k].
+            // Compute 2-norm without under/overflow.
+            e[k] = 0;
+            for (int i = k+1; i < n; i++) {
+               e[k] = Math.hypot(e[k],e[i]);
+            }
+            if (e[k] != 0.0) {
+               if (e[k+1] < 0.0) {
+                  e[k] = -e[k];
+               }
+               for (int i = k+1; i < n; i++) {
+                  e[i] /= e[k];
+               }
+               e[k+1] += 1.0;
+            }
+            e[k] = -e[k];
+            if ((k+1 < m) & (e[k] != 0.0)) {
+
+            // Apply the transformation.
+
+               for (int i = k+1; i < m; i++) {
+                  work[i] = 0.0;
+               }
+               for (int j = k+1; j < n; j++) {
+                  for (int i = k+1; i < m; i++) {
+                     work[i] += e[j]*A[i][j];
+                  }
+               }
+               for (int j = k+1; j < n; j++) {
+                  double t = -e[j]/e[k+1];
+                  for (int i = k+1; i < m; i++) {
+                     A[i][j] += t*work[i];
+                  }
+               }
+            }
+            if (wantv) {
+
+            // Place the transformation in V for subsequent
+            // back multiplication.
+
+               for (int i = k+1; i < n; i++) {
+                  V[i][k] = e[i];
+               }
+            }
+         }
+      }
+
+      // Set up the final bidiagonal matrix or order p.
+
+      int p = Math.min(n,m+1);
+      if (nct < n) {
+         s[nct] = A[nct][nct];
+      }
+      if (m < p) {
+         s[p-1] = 0.0;
+      }
+      if (nrt+1 < p) {
+         e[nrt] = A[nrt][p-1];
+      }
+      e[p-1] = 0.0;
+
+      // If required, generate U.
+
+      if (wantu) {
+         for (int j = nct; j < nu; j++) {
+            for (int i = 0; i < m; i++) {
+               U[i][j] = 0.0;
+            }
+            U[j][j] = 1.0;
+         }
+         for (int k = nct-1; k >= 0; k--) {
+            if (s[k] != 0.0) {
+               for (int j = k+1; j < nu; j++) {
+                  double t = 0;
+                  for (int i = k; i < m; i++) {
+                     t += U[i][k]*U[i][j];
+                  }
+                  t = -t/U[k][k];
+                  for (int i = k; i < m; i++) {
+                     U[i][j] += t*U[i][k];
+                  }
+               }
+               for (int i = k; i < m; i++ ) {
+                  U[i][k] = -U[i][k];
+               }
+               U[k][k] = 1.0 + U[k][k];
+               for (int i = 0; i < k-1; i++) {
+                  U[i][k] = 0.0;
+               }
+            } else {
+               for (int i = 0; i < m; i++) {
+                  U[i][k] = 0.0;
+               }
+               U[k][k] = 1.0;
+            }
+         }
+      }
+
+      // If required, generate V.
+
+      if (wantv) {
+         for (int k = n-1; k >= 0; k--) {
+            if ((k < nrt) & (e[k] != 0.0)) {
+               for (int j = k+1; j < nu; j++) {
+                  double t = 0;
+                  for (int i = k+1; i < n; i++) {
+                     t += V[i][k]*V[i][j];
+                  }
+                  t = -t/V[k+1][k];
+                  for (int i = k+1; i < n; i++) {
+                     V[i][j] += t*V[i][k];
+                  }
+               }
+            }
+            for (int i = 0; i < n; i++) {
+               V[i][k] = 0.0;
+            }
+            V[k][k] = 1.0;
+         }
+      }
+
+      // Main iteration loop for the singular values.
+
+      int pp = p-1;
+      int iter = 0;
+      double eps = Math.pow(2.0,-52.0);
+      double tiny = Math.pow(2.0,-966.0);
+      while (p > 0) {
+         int k,kase;
+
+         // Here is where a test for too many iterations would go.
+
+         // This section of the program inspects for
+         // negligible elements in the s and e arrays.  On
+         // completion the variables kase and k are set as follows.
+
+         // kase = 1     if s(p) and e[k-1] are negligible and k<p
+         // kase = 2     if s(k) is negligible and k<p
+         // kase = 3     if e[k-1] is negligible, k<p, and
+         //              s(k), ..., s(p) are not negligible (qr step).
+         // kase = 4     if e(p-1) is negligible (convergence).
+
+         for (k = p-2; k >= -1; k--) {
+            if (k == -1) {
+               break;
+            }
+            if (Math.abs(e[k]) <=
+                  tiny + eps*(Math.abs(s[k]) + Math.abs(s[k+1]))) {
+               e[k] = 0.0;
+               break;
+            }
+         }
+         if (k == p-2) {
+            kase = 4;
+         } else {
+            int ks;
+            for (ks = p-1; ks >= k; ks--) {
+               if (ks == k) {
+                  break;
+               }
+               double t = (ks != p ? Math.abs(e[ks]) : 0.) + 
+                          (ks != k+1 ? Math.abs(e[ks-1]) : 0.);
+               if (Math.abs(s[ks]) <= tiny + eps*t)  {
+                  s[ks] = 0.0;
+                  break;
+               }
+            }
+            if (ks == k) {
+               kase = 3;
+            } else if (ks == p-1) {
+               kase = 1;
+            } else {
+               kase = 2;
+               k = ks;
+            }
+         }
+         k++;
+
+         // Perform the task indicated by kase.
+
+         switch (kase) {
+
+            // Deflate negligible s(p).
+
+            case 1: {
+               double f = e[p-2];
+               e[p-2] = 0.0;
+               for (int j = p-2; j >= k; j--) {
+                  double t = Math.hypot(s[j],f);
+                  double cs = s[j]/t;
+                  double sn = f/t;
+                  s[j] = t;
+                  if (j != k) {
+                     f = -sn*e[j-1];
+                     e[j-1] = cs*e[j-1];
+                  }
+                  if (wantv) {
+                     for (int i = 0; i < n; i++) {
+                        t = cs*V[i][j] + sn*V[i][p-1];
+                        V[i][p-1] = -sn*V[i][j] + cs*V[i][p-1];
+                        V[i][j] = t;
+                     }
+                  }
+               }
+            }
+            break;
+
+            // Split at negligible s(k).
+
+            case 2: {
+               double f = e[k-1];
+               e[k-1] = 0.0;
+               for (int j = k; j < p; j++) {
+                  double t = Math.hypot(s[j],f);
+                  double cs = s[j]/t;
+                  double sn = f/t;
+                  s[j] = t;
+                  f = -sn*e[j];
+                  e[j] = cs*e[j];
+                  if (wantu) {
+                     for (int i = 0; i < m; i++) {
+                        t = cs*U[i][j] + sn*U[i][k-1];
+                        U[i][k-1] = -sn*U[i][j] + cs*U[i][k-1];
+                        U[i][j] = t;
+                     }
+                  }
+               }
+            }
+            break;
+
+            // Perform one qr step.
+
+            case 3: {
+
+               // Calculate the shift.
+   
+               double scale = Math.max(Math.max(Math.max(Math.max(
+                       Math.abs(s[p-1]),Math.abs(s[p-2])),Math.abs(e[p-2])), 
+                       Math.abs(s[k])),Math.abs(e[k]));
+               double sp = s[p-1]/scale;
+               double spm1 = s[p-2]/scale;
+               double epm1 = e[p-2]/scale;
+               double sk = s[k]/scale;
+               double ek = e[k]/scale;
+               double b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
+               double c = (sp*epm1)*(sp*epm1);
+               double shift = 0.0;
+               if ((b != 0.0) | (c != 0.0)) {
+                  shift = Math.sqrt(b*b + c);
+                  if (b < 0.0) {
+                     shift = -shift;
+                  }
+                  shift = c/(b + shift);
+               }
+               double f = (sk + sp)*(sk - sp) + shift;
+               double g = sk*ek;
+   
+               // Chase zeros.
+   
+               for (int j = k; j < p-1; j++) {
+                  double t = Math.hypot(f,g);
+                  double cs = f/t;
+                  double sn = g/t;
+                  if (j != k) {
+                     e[j-1] = t;
+                  }
+                  f = cs*s[j] + sn*e[j];
+                  e[j] = cs*e[j] - sn*s[j];
+                  g = sn*s[j+1];
+                  s[j+1] = cs*s[j+1];
+                  if (wantv) {
+                     for (int i = 0; i < n; i++) {
+                        t = cs*V[i][j] + sn*V[i][j+1];
+                        V[i][j+1] = -sn*V[i][j] + cs*V[i][j+1];
+                        V[i][j] = t;
+                     }
+                  }
+                  t = Math.hypot(f,g);
+                  cs = f/t;
+                  sn = g/t;
+                  s[j] = t;
+                  f = cs*e[j] + sn*s[j+1];
+                  s[j+1] = -sn*e[j] + cs*s[j+1];
+                  g = sn*e[j+1];
+                  e[j+1] = cs*e[j+1];
+                  if (wantu && (j < m-1)) {
+                     for (int i = 0; i < m; i++) {
+                        t = cs*U[i][j] + sn*U[i][j+1];
+                        U[i][j+1] = -sn*U[i][j] + cs*U[i][j+1];
+                        U[i][j] = t;
+                     }
+                  }
+               }
+               e[p-2] = f;
+               iter = iter + 1;
+            }
+            break;
+
+            // Convergence.
+
+            case 4: {
+
+               // Make the singular values positive.
+   
+               if (s[k] <= 0.0) {
+                  s[k] = (s[k] < 0.0 ? -s[k] : 0.0);
+                  if (wantv) {
+                     for (int i = 0; i <= pp; i++) {
+                        V[i][k] = -V[i][k];
+                     }
+                  }
+               }
+   
+               // Order the singular values.
+   
+               while (k < pp) {
+                  if (s[k] >= s[k+1]) {
+                     break;
+                  }
+                  double t = s[k];
+                  s[k] = s[k+1];
+                  s[k+1] = t;
+                  if (wantv && (k < n-1)) {
+                     for (int i = 0; i < n; i++) {
+                        t = V[i][k+1]; V[i][k+1] = V[i][k]; V[i][k] = t;
+                     }
+                  }
+                  if (wantu && (k < m-1)) {
+                     for (int i = 0; i < m; i++) {
+                        t = U[i][k+1]; U[i][k+1] = U[i][k]; U[i][k] = t;
+                     }
+                  }
+                  k++;
+               }
+               iter = 0;
+               p--;
+            }
+            break;
+         }
+      }
+   }
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Return the left singular vectors
+   @return     U
+   */
+
+   public Matrix getU () {
+      return new Matrix(U,m,Math.min(m+1,n));
+   }
+
+   /** Return the right singular vectors
+   @return     V
+   */
+
+   public Matrix getV () {
+      return new Matrix(V,n,n);
+   }
+
+   /** Return the one-dimensional array of singular values
+   @return     diagonal of S.
+   */
+
+   public double[] getSingularValues () {
+      return s;
+   }
+
+   /** Return the diagonal matrix of singular values
+   @return     S
+   */
+
+   public Matrix getS () {
+      Matrix X = new Matrix(n,n);
+      double[][] S = X.getArray();
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            S[i][j] = 0.0;
+         }
+         S[i][i] = this.s[i];
+      }
+      return X;
+   }
+
+   /** Two norm
+   @return     max(S)
+   */
+
+   public double norm2 () {
+      return s[0];
+   }
+
+   /** Two norm condition number
+   @return     max(S)/min(S)
+   */
+
+   public double cond () {
+      return s[0]/s[Math.min(m,n)-1];
+   }
+
+   /** Effective numerical matrix rank
+   @return     Number of nonnegligible singular values.
+   */
+
+   public int rank () {
+      double eps = Math.pow(2.0,-52.0);
+      double tol = Math.max(m,n)*s[0]*eps;
+      int r = 0;
+      for (int i = 0; i < s.length; i++) {
+         if (s[i] > tol) {
+            r++;
+         }
+      }
+      return r;
+   }
+}
Index: tmp/org.txm.analec.rcp/src/JamaPlus/QRDecomposition.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/QRDecomposition.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/QRDecomposition.java	(revision 481)
@@ -0,0 +1,218 @@
+package JamaPlus;
+import JamaPlus.util.*;
+
+/** QR Decomposition.
+<P>
+   For an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n
+   orthogonal matrix Q and an n-by-n upper triangular matrix R so that
+   A = Q*R.
+<P>
+   The QR decompostion always exists, even if the matrix does not have
+   full rank, so the constructor will never fail.  The primary use of the
+   QR decomposition is in the least squares solution of nonsquare systems
+   of simultaneous linear equations.  This will fail if isFullRank()
+   returns false.
+*/
+
+public class QRDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Array for internal storage of decomposition.
+   @serial internal array storage.
+   */
+   private double[][] QR;
+
+   /** Row and column dimensions.
+   @serial column dimension.
+   @serial row dimension.
+   */
+   private int m, n;
+
+   /** Array for internal storage of diagonal of R.
+   @serial diagonal of R.
+   */
+   private double[] Rdiag;
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** QR Decomposition, computed by Householder reflections.
+   @param A    Rectangular matrix
+   @return     Structure to access R and the Householder vectors and compute Q.
+   */
+
+   public QRDecomposition (Matrix A) {
+      // Initialize.
+      QR = A.getArrayCopy();
+      m = A.getRowDimension();
+      n = A.getColumnDimension();
+      Rdiag = new double[n];
+
+      // Main loop.
+      for (int k = 0; k < n; k++) {
+         // Compute 2-norm of k-th column without under/overflow.
+         double nrm = 0;
+         for (int i = k; i < m; i++) {
+            nrm = Math.hypot(nrm,QR[i][k]);
+         }
+
+         if (nrm != 0.0) {
+            // Form k-th Householder vector.
+            if (QR[k][k] < 0) {
+               nrm = -nrm;
+            }
+            for (int i = k; i < m; i++) {
+               QR[i][k] /= nrm;
+            }
+            QR[k][k] += 1.0;
+
+            // Apply transformation to remaining columns.
+            for (int j = k+1; j < n; j++) {
+               double s = 0.0; 
+               for (int i = k; i < m; i++) {
+                  s += QR[i][k]*QR[i][j];
+               }
+               s = -s/QR[k][k];
+               for (int i = k; i < m; i++) {
+                  QR[i][j] += s*QR[i][k];
+               }
+            }
+         }
+         Rdiag[k] = -nrm;
+      }
+   }
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Is the matrix full rank?
+   @return     true if R, and hence A, has full rank.
+   */
+
+   public boolean isFullRank () {
+      for (int j = 0; j < n; j++) {
+         if (Rdiag[j] == 0)
+            return false;
+      }
+      return true;
+   }
+
+   /** Return the Householder vectors
+   @return     Lower trapezoidal matrix whose columns define the reflections
+   */
+
+   public Matrix getH () {
+      Matrix X = new Matrix(m,n);
+      double[][] H = X.getArray();
+      for (int i = 0; i < m; i++) {
+         for (int j = 0; j < n; j++) {
+            if (i >= j) {
+               H[i][j] = QR[i][j];
+            } else {
+               H[i][j] = 0.0;
+            }
+         }
+      }
+      return X;
+   }
+
+   /** Return the upper triangular factor
+   @return     R
+   */
+
+   public Matrix getR () {
+      Matrix X = new Matrix(n,n);
+      double[][] R = X.getArray();
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            if (i < j) {
+               R[i][j] = QR[i][j];
+            } else if (i == j) {
+               R[i][j] = Rdiag[i];
+            } else {
+               R[i][j] = 0.0;
+            }
+         }
+      }
+      return X;
+   }
+
+   /** Generate and return the (economy-sized) orthogonal factor
+   @return     Q
+   */
+
+   public Matrix getQ () {
+      Matrix X = new Matrix(m,n);
+      double[][] Q = X.getArray();
+      for (int k = n-1; k >= 0; k--) {
+         for (int i = 0; i < m; i++) {
+            Q[i][k] = 0.0;
+         }
+         Q[k][k] = 1.0;
+         for (int j = k; j < n; j++) {
+            if (QR[k][k] != 0) {
+               double s = 0.0;
+               for (int i = k; i < m; i++) {
+                  s += QR[i][k]*Q[i][j];
+               }
+               s = -s/QR[k][k];
+               for (int i = k; i < m; i++) {
+                  Q[i][j] += s*QR[i][k];
+               }
+            }
+         }
+      }
+      return X;
+   }
+
+   /** Least squares solution of A*X = B
+   @param B    A Matrix with as many rows as A and any number of columns.
+   @return     X that minimizes the two norm of Q*R*X-B.
+   @exception  IllegalArgumentException  Matrix row dimensions must agree.
+   @exception  RuntimeException  Matrix is rank deficient.
+   */
+
+   public Matrix solve (Matrix B) {
+      if (B.getRowDimension() != m) {
+         throw new IllegalArgumentException("Matrix row dimensions must agree.");
+      }
+      if (!this.isFullRank()) {
+         throw new RuntimeException("Matrix is rank deficient.");
+      }
+      
+      // Copy right hand side
+      int nx = B.getColumnDimension();
+      double[][] X = B.getArrayCopy();
+
+      // Compute Y = transpose(Q)*B
+      for (int k = 0; k < n; k++) {
+         for (int j = 0; j < nx; j++) {
+            double s = 0.0; 
+            for (int i = k; i < m; i++) {
+               s += QR[i][k]*X[i][j];
+            }
+            s = -s/QR[k][k];
+            for (int i = k; i < m; i++) {
+               X[i][j] += s*QR[i][k];
+            }
+         }
+      }
+      // Solve R*X = Y;
+      for (int k = n-1; k >= 0; k--) {
+         for (int j = 0; j < nx; j++) {
+            X[k][j] /= Rdiag[k];
+         }
+         for (int i = 0; i < k; i++) {
+            for (int j = 0; j < nx; j++) {
+               X[i][j] -= X[k][j]*QR[i][k];
+            }
+         }
+      }
+      return (new Matrix(X,n,nx).getMatrix(0,n-1,0,nx-1));
+   }
+}

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/QRDecomposition.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/EigenvalueDecomposition.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/EigenvalueDecomposition.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/EigenvalueDecomposition.java	(revision 481)
@@ -0,0 +1,955 @@
+package JamaPlus;
+import JamaPlus.util.*;
+
+/** Eigenvalues and eigenvectors of a real matrix. 
+<P>
+    If A is symmetric, then A = V*D*V' where the eigenvalue matrix D is
+    diagonal and the eigenvector matrix V is orthogonal.
+    I.e. A = V.times(D.times(V.transpose())) and 
+    V.times(V.transpose()) equals the identity matrix.
+<P>
+    If A is not symmetric, then the eigenvalue matrix D is block diagonal
+    with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues,
+    lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda].  The
+    columns of V represent the eigenvectors in the sense that A*V = V*D,
+    i.e. A.times(V) equals V.times(D).  The matrix V may be badly
+    conditioned, or even singular, so the validity of the equation
+    A = V*D*inverse(V) depends upon V.cond().
+**/
+
+public class EigenvalueDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Row and column dimension (square matrix).
+   @serial matrix dimension.
+   */
+   private int n;
+
+   /** Symmetry flag.
+   @serial internal symmetry flag.
+   */
+   private boolean issymmetric;
+
+   /** Arrays for internal storage of eigenvalues.
+   @serial internal storage of eigenvalues.
+   */
+   private double[] d, e;
+
+   /** Array for internal storage of eigenvectors.
+   @serial internal storage of eigenvectors.
+   */
+   private double[][] V;
+
+   /** Array for internal storage of nonsymmetric Hessenberg form.
+   @serial internal storage of nonsymmetric Hessenberg form.
+   */
+   private double[][] H;
+
+   /** Working storage for nonsymmetric algorithm.
+   @serial working storage for nonsymmetric algorithm.
+   */
+   private double[] ort;
+
+/* ------------------------
+   Private Methods
+ * ------------------------ */
+
+   // Symmetric Householder reduction to tridiagonal form.
+
+   private void tred2 () {
+
+   //  This is derived from the Algol procedures tred2 by
+   //  Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+   //  Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+   //  Fortran subroutine in EISPACK.
+
+      for (int j = 0; j < n; j++) {
+         d[j] = V[n-1][j];
+      }
+
+      // Householder reduction to tridiagonal form.
+   
+      for (int i = n-1; i > 0; i--) {
+   
+         // Scale to avoid under/overflow.
+   
+         double scale = 0.0;
+         double h = 0.0;
+         for (int k = 0; k < i; k++) {
+            scale = scale + Math.abs(d[k]);
+         }
+         if (scale == 0.0) {
+            e[i] = d[i-1];
+            for (int j = 0; j < i; j++) {
+               d[j] = V[i-1][j];
+               V[i][j] = 0.0;
+               V[j][i] = 0.0;
+            }
+         } else {
+   
+            // Generate Householder vector.
+   
+            for (int k = 0; k < i; k++) {
+               d[k] /= scale;
+               h += d[k] * d[k];
+            }
+            double f = d[i-1];
+            double g = Math.sqrt(h);
+            if (f > 0) {
+               g = -g;
+            }
+            e[i] = scale * g;
+            h = h - f * g;
+            d[i-1] = f - g;
+            for (int j = 0; j < i; j++) {
+               e[j] = 0.0;
+            }
+   
+            // Apply similarity transformation to remaining columns.
+   
+            for (int j = 0; j < i; j++) {
+               f = d[j];
+               V[j][i] = f;
+               g = e[j] + V[j][j] * f;
+               for (int k = j+1; k <= i-1; k++) {
+                  g += V[k][j] * d[k];
+                  e[k] += V[k][j] * f;
+               }
+               e[j] = g;
+            }
+            f = 0.0;
+            for (int j = 0; j < i; j++) {
+               e[j] /= h;
+               f += e[j] * d[j];
+            }
+            double hh = f / (h + h);
+            for (int j = 0; j < i; j++) {
+               e[j] -= hh * d[j];
+            }
+            for (int j = 0; j < i; j++) {
+               f = d[j];
+               g = e[j];
+               for (int k = j; k <= i-1; k++) {
+                  V[k][j] -= (f * e[k] + g * d[k]);
+               }
+               d[j] = V[i-1][j];
+               V[i][j] = 0.0;
+            }
+         }
+         d[i] = h;
+      }
+   
+      // Accumulate transformations.
+   
+      for (int i = 0; i < n-1; i++) {
+         V[n-1][i] = V[i][i];
+         V[i][i] = 1.0;
+         double h = d[i+1];
+         if (h != 0.0) {
+            for (int k = 0; k <= i; k++) {
+               d[k] = V[k][i+1] / h;
+            }
+            for (int j = 0; j <= i; j++) {
+               double g = 0.0;
+               for (int k = 0; k <= i; k++) {
+                  g += V[k][i+1] * V[k][j];
+               }
+               for (int k = 0; k <= i; k++) {
+                  V[k][j] -= g * d[k];
+               }
+            }
+         }
+         for (int k = 0; k <= i; k++) {
+            V[k][i+1] = 0.0;
+         }
+      }
+      for (int j = 0; j < n; j++) {
+         d[j] = V[n-1][j];
+         V[n-1][j] = 0.0;
+      }
+      V[n-1][n-1] = 1.0;
+      e[0] = 0.0;
+   } 
+
+   // Symmetric tridiagonal QL algorithm.
+   
+   private void tql2 () {
+
+   //  This is derived from the Algol procedures tql2, by
+   //  Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+   //  Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+   //  Fortran subroutine in EISPACK.
+   
+      for (int i = 1; i < n; i++) {
+         e[i-1] = e[i];
+      }
+      e[n-1] = 0.0;
+   
+      double f = 0.0;
+      double tst1 = 0.0;
+      double eps = Math.pow(2.0,-52.0);
+      for (int l = 0; l < n; l++) {
+
+         // Find small subdiagonal element
+   
+         tst1 = Math.max(tst1,Math.abs(d[l]) + Math.abs(e[l]));
+         int m = l;
+         while (m < n) {
+            if (Math.abs(e[m]) <= eps*tst1) {
+               break;
+            }
+            m++;
+         }
+   
+         // If m == l, d[l] is an eigenvalue,
+         // otherwise, iterate.
+   
+         if (m > l) {
+            int iter = 0;
+            do {
+               iter = iter + 1;  // (Could check iteration count here.)
+   
+               // Compute implicit shift
+   
+               double g = d[l];
+               double p = (d[l+1] - g) / (2.0 * e[l]);
+               double r = Math.hypot(p,1.0);
+               if (p < 0) {
+                  r = -r;
+               }
+               d[l] = e[l] / (p + r);
+               d[l+1] = e[l] * (p + r);
+               double dl1 = d[l+1];
+               double h = g - d[l];
+               for (int i = l+2; i < n; i++) {
+                  d[i] -= h;
+               }
+               f = f + h;
+   
+               // Implicit QL transformation.
+   
+               p = d[m];
+               double c = 1.0;
+               double c2 = c;
+               double c3 = c;
+               double el1 = e[l+1];
+               double s = 0.0;
+               double s2 = 0.0;
+               for (int i = m-1; i >= l; i--) {
+                  c3 = c2;
+                  c2 = c;
+                  s2 = s;
+                  g = c * e[i];
+                  h = c * p;
+                  r = Math.hypot(p,e[i]);
+                  e[i+1] = s * r;
+                  s = e[i] / r;
+                  c = p / r;
+                  p = c * d[i] - s * g;
+                  d[i+1] = h + s * (c * g + s * d[i]);
+   
+                  // Accumulate transformation.
+   
+                  for (int k = 0; k < n; k++) {
+                     h = V[k][i+1];
+                     V[k][i+1] = s * V[k][i] + c * h;
+                     V[k][i] = c * V[k][i] - s * h;
+                  }
+               }
+               p = -s * s2 * c3 * el1 * e[l] / dl1;
+               e[l] = s * p;
+               d[l] = c * p;
+   
+               // Check for convergence.
+   
+            } while (Math.abs(e[l]) > eps*tst1);
+         }
+         d[l] = d[l] + f;
+         e[l] = 0.0;
+      }
+     
+      // Sort eigenvalues and corresponding vectors.
+   
+      for (int i = 0; i < n-1; i++) {
+         int k = i;
+         double p = d[i];
+         for (int j = i+1; j < n; j++) {
+            if (d[j] < p) {
+               k = j;
+               p = d[j];
+            }
+         }
+         if (k != i) {
+            d[k] = d[i];
+            d[i] = p;
+            for (int j = 0; j < n; j++) {
+               p = V[j][i];
+               V[j][i] = V[j][k];
+               V[j][k] = p;
+            }
+         }
+      }
+   }
+
+   // Nonsymmetric reduction to Hessenberg form.
+
+   private void orthes () {
+   
+      //  This is derived from the Algol procedures orthes and ortran,
+      //  by Martin and Wilkinson, Handbook for Auto. Comp.,
+      //  Vol.ii-Linear Algebra, and the corresponding
+      //  Fortran subroutines in EISPACK.
+   
+      int low = 0;
+      int high = n-1;
+   
+      for (int m = low+1; m <= high-1; m++) {
+   
+         // Scale column.
+   
+         double scale = 0.0;
+         for (int i = m; i <= high; i++) {
+            scale = scale + Math.abs(H[i][m-1]);
+         }
+         if (scale != 0.0) {
+   
+            // Compute Householder transformation.
+   
+            double h = 0.0;
+            for (int i = high; i >= m; i--) {
+               ort[i] = H[i][m-1]/scale;
+               h += ort[i] * ort[i];
+            }
+            double g = Math.sqrt(h);
+            if (ort[m] > 0) {
+               g = -g;
+            }
+            h = h - ort[m] * g;
+            ort[m] = ort[m] - g;
+   
+            // Apply Householder similarity transformation
+            // H = (I-u*u'/h)*H*(I-u*u')/h)
+   
+            for (int j = m; j < n; j++) {
+               double f = 0.0;
+               for (int i = high; i >= m; i--) {
+                  f += ort[i]*H[i][j];
+               }
+               f = f/h;
+               for (int i = m; i <= high; i++) {
+                  H[i][j] -= f*ort[i];
+               }
+           }
+   
+           for (int i = 0; i <= high; i++) {
+               double f = 0.0;
+               for (int j = high; j >= m; j--) {
+                  f += ort[j]*H[i][j];
+               }
+               f = f/h;
+               for (int j = m; j <= high; j++) {
+                  H[i][j] -= f*ort[j];
+               }
+            }
+            ort[m] = scale*ort[m];
+            H[m][m-1] = scale*g;
+         }
+      }
+   
+      // Accumulate transformations (Algol's ortran).
+
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            V[i][j] = (i == j ? 1.0 : 0.0);
+         }
+      }
+
+      for (int m = high-1; m >= low+1; m--) {
+         if (H[m][m-1] != 0.0) {
+            for (int i = m+1; i <= high; i++) {
+               ort[i] = H[i][m-1];
+            }
+            for (int j = m; j <= high; j++) {
+               double g = 0.0;
+               for (int i = m; i <= high; i++) {
+                  g += ort[i] * V[i][j];
+               }
+               // Double division avoids possible underflow
+               g = (g / ort[m]) / H[m][m-1];
+               for (int i = m; i <= high; i++) {
+                  V[i][j] += g * ort[i];
+               }
+            }
+         }
+      }
+   }
+
+
+   // Complex scalar division.
+
+   private transient double cdivr, cdivi;
+   private void cdiv(double xr, double xi, double yr, double yi) {
+      double r,d;
+      if (Math.abs(yr) > Math.abs(yi)) {
+         r = yi/yr;
+         d = yr + r*yi;
+         cdivr = (xr + r*xi)/d;
+         cdivi = (xi - r*xr)/d;
+      } else {
+         r = yr/yi;
+         d = yi + r*yr;
+         cdivr = (r*xr + xi)/d;
+         cdivi = (r*xi - xr)/d;
+      }
+   }
+
+
+   // Nonsymmetric reduction from Hessenberg to real Schur form.
+
+   private void hqr2 () {
+   
+      //  This is derived from the Algol procedure hqr2,
+      //  by Martin and Wilkinson, Handbook for Auto. Comp.,
+      //  Vol.ii-Linear Algebra, and the corresponding
+      //  Fortran subroutine in EISPACK.
+   
+      // Initialize
+   
+      int nn = this.n;
+      int n = nn-1;
+      int low = 0;
+      int high = nn-1;
+      double eps = Math.pow(2.0,-52.0);
+      double exshift = 0.0;
+      double p=0,q=0,r=0,s=0,z=0,t,w,x,y;
+   
+      // Store roots isolated by balanc and compute matrix norm
+   
+      double norm = 0.0;
+      for (int i = 0; i < nn; i++) {
+         if (i < low | i > high) {
+            d[i] = H[i][i];
+            e[i] = 0.0;
+         }
+         for (int j = Math.max(i-1,0); j < nn; j++) {
+            norm = norm + Math.abs(H[i][j]);
+         }
+      }
+   
+      // Outer loop over eigenvalue index
+   
+      int iter = 0;
+      while (n >= low) {
+   
+         // Look for single small sub-diagonal element
+   
+         int l = n;
+         while (l > low) {
+            s = Math.abs(H[l-1][l-1]) + Math.abs(H[l][l]);
+            if (s == 0.0) {
+               s = norm;
+            }
+            if (Math.abs(H[l][l-1]) < eps * s) {
+               break;
+            }
+            l--;
+         }
+       
+         // Check for convergence
+         // One root found
+   
+         if (l == n) {
+            H[n][n] = H[n][n] + exshift;
+            d[n] = H[n][n];
+            e[n] = 0.0;
+            n--;
+            iter = 0;
+   
+         // Two roots found
+   
+         } else if (l == n-1) {
+            w = H[n][n-1] * H[n-1][n];
+            p = (H[n-1][n-1] - H[n][n]) / 2.0;
+            q = p * p + w;
+            z = Math.sqrt(Math.abs(q));
+            H[n][n] = H[n][n] + exshift;
+            H[n-1][n-1] = H[n-1][n-1] + exshift;
+            x = H[n][n];
+   
+            // Real pair
+   
+            if (q >= 0) {
+               if (p >= 0) {
+                  z = p + z;
+               } else {
+                  z = p - z;
+               }
+               d[n-1] = x + z;
+               d[n] = d[n-1];
+               if (z != 0.0) {
+                  d[n] = x - w / z;
+               }
+               e[n-1] = 0.0;
+               e[n] = 0.0;
+               x = H[n][n-1];
+               s = Math.abs(x) + Math.abs(z);
+               p = x / s;
+               q = z / s;
+               r = Math.sqrt(p * p+q * q);
+               p = p / r;
+               q = q / r;
+   
+               // Row modification
+   
+               for (int j = n-1; j < nn; j++) {
+                  z = H[n-1][j];
+                  H[n-1][j] = q * z + p * H[n][j];
+                  H[n][j] = q * H[n][j] - p * z;
+               }
+   
+               // Column modification
+   
+               for (int i = 0; i <= n; i++) {
+                  z = H[i][n-1];
+                  H[i][n-1] = q * z + p * H[i][n];
+                  H[i][n] = q * H[i][n] - p * z;
+               }
+   
+               // Accumulate transformations
+   
+               for (int i = low; i <= high; i++) {
+                  z = V[i][n-1];
+                  V[i][n-1] = q * z + p * V[i][n];
+                  V[i][n] = q * V[i][n] - p * z;
+               }
+   
+            // Complex pair
+   
+            } else {
+               d[n-1] = x + p;
+               d[n] = x + p;
+               e[n-1] = z;
+               e[n] = -z;
+            }
+            n = n - 2;
+            iter = 0;
+   
+         // No convergence yet
+   
+         } else {
+   
+            // Form shift
+   
+            x = H[n][n];
+            y = 0.0;
+            w = 0.0;
+            if (l < n) {
+               y = H[n-1][n-1];
+               w = H[n][n-1] * H[n-1][n];
+            }
+   
+            // Wilkinson's original ad hoc shift
+   
+            if (iter == 10) {
+               exshift += x;
+               for (int i = low; i <= n; i++) {
+                  H[i][i] -= x;
+               }
+               s = Math.abs(H[n][n-1]) + Math.abs(H[n-1][n-2]);
+               x = y = 0.75 * s;
+               w = -0.4375 * s * s;
+            }
+
+            // MATLAB's new ad hoc shift
+
+            if (iter == 30) {
+                s = (y - x) / 2.0;
+                s = s * s + w;
+                if (s > 0) {
+                    s = Math.sqrt(s);
+                    if (y < x) {
+                       s = -s;
+                    }
+                    s = x - w / ((y - x) / 2.0 + s);
+                    for (int i = low; i <= n; i++) {
+                       H[i][i] -= s;
+                    }
+                    exshift += s;
+                    x = y = w = 0.964;
+                }
+            }
+   
+            iter = iter + 1;   // (Could check iteration count here.)
+   
+            // Look for two consecutive small sub-diagonal elements
+   
+            int m = n-2;
+            while (m >= l) {
+               z = H[m][m];
+               r = x - z;
+               s = y - z;
+               p = (r * s - w) / H[m+1][m] + H[m][m+1];
+               q = H[m+1][m+1] - z - r - s;
+               r = H[m+2][m+1];
+               s = Math.abs(p) + Math.abs(q) + Math.abs(r);
+               p = p / s;
+               q = q / s;
+               r = r / s;
+               if (m == l) {
+                  break;
+               }
+               if (Math.abs(H[m][m-1]) * (Math.abs(q) + Math.abs(r)) <
+                  eps * (Math.abs(p) * (Math.abs(H[m-1][m-1]) + Math.abs(z) +
+                  Math.abs(H[m+1][m+1])))) {
+                     break;
+               }
+               m--;
+            }
+   
+            for (int i = m+2; i <= n; i++) {
+               H[i][i-2] = 0.0;
+               if (i > m+2) {
+                  H[i][i-3] = 0.0;
+               }
+            }
+   
+            // Double QR step involving rows l:n and columns m:n
+   
+            for (int k = m; k <= n-1; k++) {
+               boolean notlast = (k != n-1);
+               if (k != m) {
+                  p = H[k][k-1];
+                  q = H[k+1][k-1];
+                  r = (notlast ? H[k+2][k-1] : 0.0);
+                  x = Math.abs(p) + Math.abs(q) + Math.abs(r);
+                  if (x != 0.0) {
+                     p = p / x;
+                     q = q / x;
+                     r = r / x;
+                  }
+               }
+               if (x == 0.0) {
+                  break;
+               }
+               s = Math.sqrt(p * p + q * q + r * r);
+               if (p < 0) {
+                  s = -s;
+               }
+               if (s != 0) {
+                  if (k != m) {
+                     H[k][k-1] = -s * x;
+                  } else if (l != m) {
+                     H[k][k-1] = -H[k][k-1];
+                  }
+                  p = p + s;
+                  x = p / s;
+                  y = q / s;
+                  z = r / s;
+                  q = q / p;
+                  r = r / p;
+   
+                  // Row modification
+   
+                  for (int j = k; j < nn; j++) {
+                     p = H[k][j] + q * H[k+1][j];
+                     if (notlast) {
+                        p = p + r * H[k+2][j];
+                        H[k+2][j] = H[k+2][j] - p * z;
+                     }
+                     H[k][j] = H[k][j] - p * x;
+                     H[k+1][j] = H[k+1][j] - p * y;
+                  }
+   
+                  // Column modification
+   
+                  for (int i = 0; i <= Math.min(n,k+3); i++) {
+                     p = x * H[i][k] + y * H[i][k+1];
+                     if (notlast) {
+                        p = p + z * H[i][k+2];
+                        H[i][k+2] = H[i][k+2] - p * r;
+                     }
+                     H[i][k] = H[i][k] - p;
+                     H[i][k+1] = H[i][k+1] - p * q;
+                  }
+   
+                  // Accumulate transformations
+   
+                  for (int i = low; i <= high; i++) {
+                     p = x * V[i][k] + y * V[i][k+1];
+                     if (notlast) {
+                        p = p + z * V[i][k+2];
+                        V[i][k+2] = V[i][k+2] - p * r;
+                     }
+                     V[i][k] = V[i][k] - p;
+                     V[i][k+1] = V[i][k+1] - p * q;
+                  }
+               }  // (s != 0)
+            }  // k loop
+         }  // check convergence
+      }  // while (n >= low)
+      
+      // Backsubstitute to find vectors of upper triangular form
+
+      if (norm == 0.0) {
+         return;
+      }
+   
+      for (n = nn-1; n >= 0; n--) {
+         p = d[n];
+         q = e[n];
+   
+         // Real vector
+   
+         if (q == 0) {
+            int l = n;
+            H[n][n] = 1.0;
+            for (int i = n-1; i >= 0; i--) {
+               w = H[i][i] - p;
+               r = 0.0;
+               for (int j = l; j <= n; j++) {
+                  r = r + H[i][j] * H[j][n];
+               }
+               if (e[i] < 0.0) {
+                  z = w;
+                  s = r;
+               } else {
+                  l = i;
+                  if (e[i] == 0.0) {
+                     if (w != 0.0) {
+                        H[i][n] = -r / w;
+                     } else {
+                        H[i][n] = -r / (eps * norm);
+                     }
+   
+                  // Solve real equations
+   
+                  } else {
+                     x = H[i][i+1];
+                     y = H[i+1][i];
+                     q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
+                     t = (x * s - z * r) / q;
+                     H[i][n] = t;
+                     if (Math.abs(x) > Math.abs(z)) {
+                        H[i+1][n] = (-r - w * t) / x;
+                     } else {
+                        H[i+1][n] = (-s - y * t) / z;
+                     }
+                  }
+   
+                  // Overflow control
+   
+                  t = Math.abs(H[i][n]);
+                  if ((eps * t) * t > 1) {
+                     for (int j = i; j <= n; j++) {
+                        H[j][n] = H[j][n] / t;
+                     }
+                  }
+               }
+            }
+   
+         // Complex vector
+   
+         } else if (q < 0) {
+            int l = n-1;
+
+            // Last vector component imaginary so matrix is triangular
+   
+            if (Math.abs(H[n][n-1]) > Math.abs(H[n-1][n])) {
+               H[n-1][n-1] = q / H[n][n-1];
+               H[n-1][n] = -(H[n][n] - p) / H[n][n-1];
+            } else {
+               cdiv(0.0,-H[n-1][n],H[n-1][n-1]-p,q);
+               H[n-1][n-1] = cdivr;
+               H[n-1][n] = cdivi;
+            }
+            H[n][n-1] = 0.0;
+            H[n][n] = 1.0;
+            for (int i = n-2; i >= 0; i--) {
+               double ra,sa,vr,vi;
+               ra = 0.0;
+               sa = 0.0;
+               for (int j = l; j <= n; j++) {
+                  ra = ra + H[i][j] * H[j][n-1];
+                  sa = sa + H[i][j] * H[j][n];
+               }
+               w = H[i][i] - p;
+   
+               if (e[i] < 0.0) {
+                  z = w;
+                  r = ra;
+                  s = sa;
+               } else {
+                  l = i;
+                  if (e[i] == 0) {
+                     cdiv(-ra,-sa,w,q);
+                     H[i][n-1] = cdivr;
+                     H[i][n] = cdivi;
+                  } else {
+   
+                     // Solve complex equations
+   
+                     x = H[i][i+1];
+                     y = H[i+1][i];
+                     vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
+                     vi = (d[i] - p) * 2.0 * q;
+                     if (vr == 0.0 & vi == 0.0) {
+                        vr = eps * norm * (Math.abs(w) + Math.abs(q) +
+                        Math.abs(x) + Math.abs(y) + Math.abs(z));
+                     }
+                     cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
+                     H[i][n-1] = cdivr;
+                     H[i][n] = cdivi;
+                     if (Math.abs(x) > (Math.abs(z) + Math.abs(q))) {
+                        H[i+1][n-1] = (-ra - w * H[i][n-1] + q * H[i][n]) / x;
+                        H[i+1][n] = (-sa - w * H[i][n] - q * H[i][n-1]) / x;
+                     } else {
+                        cdiv(-r-y*H[i][n-1],-s-y*H[i][n],z,q);
+                        H[i+1][n-1] = cdivr;
+                        H[i+1][n] = cdivi;
+                     }
+                  }
+   
+                  // Overflow control
+
+                  t = Math.max(Math.abs(H[i][n-1]),Math.abs(H[i][n]));
+                  if ((eps * t) * t > 1) {
+                     for (int j = i; j <= n; j++) {
+                        H[j][n-1] = H[j][n-1] / t;
+                        H[j][n] = H[j][n] / t;
+                     }
+                  }
+               }
+            }
+         }
+      }
+   
+      // Vectors of isolated roots
+   
+      for (int i = 0; i < nn; i++) {
+         if (i < low | i > high) {
+            for (int j = i; j < nn; j++) {
+               V[i][j] = H[i][j];
+            }
+         }
+      }
+   
+      // Back transformation to get eigenvectors of original matrix
+   
+      for (int j = nn-1; j >= low; j--) {
+         for (int i = low; i <= high; i++) {
+            z = 0.0;
+            for (int k = low; k <= Math.min(j,high); k++) {
+               z = z + V[i][k] * H[k][j];
+            }
+            V[i][j] = z;
+         }
+      }
+   }
+
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** Check for symmetry, then construct the eigenvalue decomposition
+   @param A    Square matrix
+   @return     Structure to access D and V.
+   */
+
+   public EigenvalueDecomposition (Matrix Arg) {
+      double[][] A = Arg.getArray();
+      n = Arg.getColumnDimension();
+      V = new double[n][n];
+      d = new double[n];
+      e = new double[n];
+
+      issymmetric = true;
+      for (int j = 0; (j < n) & issymmetric; j++) {
+         for (int i = 0; (i < n) & issymmetric; i++) {
+            issymmetric = (A[i][j] == A[j][i]);
+         }
+      }
+
+      if (issymmetric) {
+         for (int i = 0; i < n; i++) {
+            for (int j = 0; j < n; j++) {
+               V[i][j] = A[i][j];
+            }
+         }
+   
+         // Tridiagonalize.
+         tred2();
+   
+         // Diagonalize.
+         tql2();
+
+      } else {
+         H = new double[n][n];
+         ort = new double[n];
+         
+         for (int j = 0; j < n; j++) {
+            for (int i = 0; i < n; i++) {
+               H[i][j] = A[i][j];
+            }
+         }
+   
+         // Reduce to Hessenberg form.
+         orthes();
+   
+         // Reduce Hessenberg to real Schur form.
+         hqr2();
+      }
+   }
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Return the eigenvector matrix
+   @return     V
+   */
+
+   public Matrix getV () {
+      return new Matrix(V,n,n);
+   }
+
+   /** Return the real parts of the eigenvalues
+   @return     real(diag(D))
+   */
+
+   public double[] getRealEigenvalues () {
+      return d;
+   }
+
+   /** Return the imaginary parts of the eigenvalues
+   @return     imag(diag(D))
+   */
+
+   public double[] getImagEigenvalues () {
+      return e;
+   }
+
+   /** Return the block diagonal eigenvalue matrix
+   @return     D
+   */
+
+   public Matrix getD () {
+      Matrix X = new Matrix(n,n);
+      double[][] D = X.getArray();
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            D[i][j] = 0.0;
+         }
+         D[i][i] = d[i];
+         if (e[i] > 0) {
+            D[i][i+1] = e[i];
+         } else if (e[i] < 0) {
+            D[i][i-1] = e[i];
+         }
+      }
+      return X;
+   }
+}

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/EigenvalueDecomposition.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/SparseMatrix.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/SparseMatrix.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/SparseMatrix.java	(revision 481)
@@ -0,0 +1,271 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus;
+
+import JamaPlus.SparseSVD.SparseSVDException;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Bernard
+ */
+public class SparseMatrix {
+  private int m, n, nnz;
+  private int[] colpts, rowinds;
+  private double[] vals;
+  private double[] tempRow;  // stockage temporaire pour certains calculs (opb)
+
+  public SparseMatrix(int m, int n) { // null matrix
+    this.m = m;
+    this.n = n;
+    nnz = 0;
+    colpts = new int[n+1];
+    rowinds = new int[0];
+    vals = new double[0];
+  }
+
+   private static class Triple implements Comparable<Triple> {
+    int row;
+    int col;
+    double val;
+
+    private Triple(int row, int col, double val) {
+      this.row = row;
+      this.col = col;
+      this.val = val;
+    }
+    private Triple(int row, int col) {
+      this.row = row;
+      this.col = col;
+    }
+    public int compareTo(Triple t) {
+      int res = col - t.col;
+      if(res==0) res = row - t.row;
+      return res;
+    }
+  }
+
+ public SparseMatrix(int m, int n, ArrayList<Integer> rows, ArrayList<Integer> cols,
+          ArrayList<Double> values) {
+    this.m = m;
+    this.n = n;
+    nnz = rows.size();
+    if (nnz!=cols.size()||nnz!=rows.size())
+      throw new ArrayIndexOutOfBoundsException(
+              "Size of lines, cols and values don't agree");
+    colpts = new int[n+1];
+    rowinds = new int[nnz];
+    vals = new double[nnz];
+    Triple[] triples = new Triple[nnz];
+    for(int i=0; i<nnz; i++) 
+     triples[i] = new Triple(rows.get(i), cols.get(i), values.get(i));    
+    Arrays.sort(triples);
+    colpts[0] = 0;
+    int c = 0;
+    for(int i=0; i<nnz; i++) {
+      if(i>0 && triples[i].row == triples[i-1].row && triples[i].col == triples[i-1].col) 
+        throw new ArrayIndexOutOfBoundsException(
+              "Two values with same row and column numbers");
+      while(c<triples[i].col) colpts[++c] = i;
+      rowinds[i] = triples[i].row;
+      vals[i] = triples[i].val;
+    }
+    while(c<n) colpts[++c] = nnz;
+  }
+
+public SparseMatrix(int m, int n, ArrayList<Integer> rows, ArrayList<Integer> cols,
+          double value) {
+    this.m = m;
+    this.n = n;
+    nnz = rows.size();
+    if (nnz!=cols.size()||nnz!=rows.size())
+      throw new ArrayIndexOutOfBoundsException(
+              "Size of lines, cols and values don't agree");
+    colpts = new int[n+1];
+    rowinds = new int[nnz];
+        vals = new double[nnz];
+    Triple[] triples = new Triple[nnz];
+    for(int i=0; i<nnz; i++) 
+     triples[i] = new Triple(rows.get(i), cols.get(i));    
+    Arrays.sort(triples);
+    colpts[0] = 0;
+    int c = 0;
+    for(int i=0; i<nnz; i++) {
+      if(i>0 && triples[i].row == triples[i-1].row && triples[i].col == triples[i-1].col) 
+        throw new ArrayIndexOutOfBoundsException(
+              "Two values with same row and column numbers");
+      while(c<triples[i].col) colpts[++c] = i;
+      rowinds[i] = triples[i].row;
+      vals[i] = value;
+    }
+    while(c<n) colpts[++c] = nnz;
+  }
+
+  private SparseMatrix(int m, int n, int nnz, int[] colpts, int[] rowinds, double[] vals) {
+    this.m = m;
+    this.n = n;
+    this.nnz = nnz;
+    this.colpts = colpts;
+    this.rowinds = rowinds;
+    this.vals = vals;
+  }
+
+  public SparseMatrix(Matrix mat) {  // convert a dense matrix
+    m = mat.getRowDimension();
+    n = mat.getColumnDimension();
+    long nbval = mat.getNumberNonZeroValues();
+    if (nbval>Integer.MAX_VALUE) throw new ArrayIndexOutOfBoundsException(
+              "Number of non-zero values exceeds 32 bits integer");
+    nnz = (int) nbval;
+    colpts = new int[n+1];
+    rowinds = new int[nnz];
+    vals = new double[nnz];
+    int nval = 0;
+    for (int j = 0; j<n; j++) {
+      colpts[j] = nval;
+      for (int i = 0; i<m; i++) if (mat.get(i, j)!=0) {
+          rowinds[nval] = i;
+          vals[nval++] = mat.get(i, j);
+        }
+    }
+    colpts[n] = nnz;
+  }
+
+  public SparseMatrix copy() {
+    int[] colpts1 = new int[n+1];
+    int[] rowinds1 = new int[nnz];
+    double[] vals1 = new double[nnz];
+    System.arraycopy(colpts, 0, colpts1, 0, n+1);
+    System.arraycopy(rowinds, 0, rowinds1, 0, nnz);
+    System.arraycopy(vals, 0, vals1, 0, nnz);
+    return new SparseMatrix(m, n, nnz, colpts1, rowinds1, vals1);
+  }
+
+  public int getRowDimension() {
+    return m;
+  }
+
+  public int getColumnDimension() {
+    return n;
+  }
+
+  public double get(int i, int j) {
+    try {
+      for (int nval = colpts[j]; nval<colpts[j+1]; nval++)
+        if (rowinds[nval]==i) return vals[nval];
+      return 0;
+    } catch (ArrayIndexOutOfBoundsException ex) {
+      throw new ArrayIndexOutOfBoundsException("Sparse matrix : "
+              +ex.getLocalizedMessage());
+    }
+  }
+
+  public SparseMatrix transpose() {
+    int[] colpts1 = new int[m+1];
+    int[] rowinds1 = new int[nnz];
+    double[] vals1 = new double[nnz];
+    for (int v = 0; v<nnz; v++) colpts1[rowinds[v]]++;  // nnz in each row
+    colpts1[m] = nnz-colpts1[m-1];
+    for (int r = m-1; r>0; r--)
+      colpts1[r] = colpts1[r+1]-colpts1[r-1]; // starting point of the previous row
+    colpts1[0] = 0;
+    int i = 0;
+    for (int c = 0; c<n; c++) while (i<colpts[c+1]) {
+        int j = colpts1[rowinds[i]+1]++;  // j : index of the value in the new vectors
+        rowinds1[j] = c;
+        vals1[j] = vals[i++];
+      }
+    return new SparseMatrix(n, m, nnz, colpts1, rowinds1, vals1);
+  }
+
+  public void nulColumnSuppression() {
+    ArrayList<Integer> colpts1 = new ArrayList<Integer>();
+    colpts1.add(0);
+    for (int i = 0; i<n; i++) if (colpts[i+1]>colpts[i])
+        colpts1.add(colpts[i+1]);
+    n = colpts1.size()-1;
+    colpts = new int[n+1];
+    for (int i = 0; i<=n; i++) colpts[i] = colpts1.get(i);
+  }
+
+  public double elementSum() {
+    double s = 0;
+    for (int i = 0; i<nnz; i++) s += vals[i];
+
+    return s;
+  }
+
+  public Matrix lineSum() {
+    double[] S = new double[m];
+    for (int i = 0; i<nnz; i++) S[rowinds[i]] += vals[i];
+
+    return new Matrix(S, m);
+  }
+
+  public Matrix columnSum() {
+    double[] S = new double[n];
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        S[i] += vals[j];
+
+    return new Matrix(S, 1);
+  }
+
+  public SparseMatrix timesEquals(double s) {
+    for (int i = 0; i<nnz; i++) {
+      vals[i] *= s;
+    }
+    return this;
+  }
+
+  public SparseMatrix firstColumnTimesEqual(Matrix B) {
+    double[][] A = B.getArray();
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        vals[j] *= A[rowinds[j]][0];
+    return this;
+  }
+
+  public SparseMatrix firstLineTimesEqual(Matrix B) {
+    double[][] A = B.getArray();
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        vals[j] *= A[0][i];
+    return this;
+  }
+
+  public void opa(double x[], double y[]) {
+    // Computes y = Ax (x et y : length n)
+    Arrays.fill(y, 0);
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        y[rowinds[j]] += vals[j]*x[i];
+  }
+
+  public void opb(double x[], double y[]) {
+    // Computes y = A'Ax (x et y : length n)
+    if (tempRow==null) tempRow = new double[m];
+    else Arrays.fill(tempRow, 0);
+    Arrays.fill(y, 0);
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        tempRow[rowinds[j]] += vals[j]*x[i];
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        y[i] += vals[j]*tempRow[rowinds[j]];
+  }
+
+  public SparseSVD svd(int dim) throws SparseSVD.SparseSVDException {
+    return new SparseSVD(this, dim);
+  }
+
+  /** Analyse factorielle de correspondances
+  @return     Analyse factorielle de correspondances
+  @see Analyse factorielle de correspondances
+   */
+  public SparseAFC afc() {
+    try {
+      return new SparseAFC(this);
+    } catch (SparseSVDException ex) {
+      return null;
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/SparseMatrix.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/Matrix.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/Matrix.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/Matrix.java	(revision 481)
@@ -0,0 +1,1221 @@
+package JamaPlus;
+
+import java.text.NumberFormat;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+import java.io.PrintWriter;
+import java.io.BufferedReader;
+import java.io.StreamTokenizer;
+import JamaPlus.util.*;
+import java.util.ArrayList;
+
+/**
+Jama = Java Matrix class.
+<P>
+The Java Matrix Class provides the fundamental operations of numerical
+linear algebra.  Various constructors create Matrices from two dimensional
+arrays of double precision floating point numbers.  Various "gets" and
+"sets" provide access to submatrices and matrix elements.  Several methods 
+implement basic matrix arithmetic, including matrix addition and
+multiplication, matrix norms, and element-by-element array operations.
+Methods for reading and printing matrices are also included.  All the
+operations in this version of the Matrix Class involve real matrices.
+Complex matrices may be handled in a future version.
+<P>
+Five fundamental matrix decompositions, which consist of pairs or triples
+of matrices, permutation vectors, and the like, produce results in five
+decomposition classes.  These decompositions are accessed by the Matrix
+class to compute solutions of simultaneous linear equations, determinants,
+inverses and other matrix functions.  The five decompositions are:
+<P><UL>
+<LI>Cholesky Decomposition of symmetric, positive definite matrices.
+<LI>LU Decomposition of rectangular matrices.
+<LI>QR Decomposition of rectangular matrices.
+<LI>Singular Value Decomposition of rectangular matrices.
+<LI>Eigenvalue Decomposition of both symmetric and nonsymmetric square matrices.
+</UL>
+<DL>
+<DT><B>Example of use:</B></DT>
+<P>
+<DD>Solve a linear system A x = b and compute the residual norm, ||b - A x||.
+<P><PRE>
+double[][] vals = {{1.,2.,3},{4.,5.,6.},{7.,8.,10.}};
+Matrix A = new Matrix(vals);
+Matrix b = Matrix.random(3,1);
+Matrix x = A.solve(b);
+Matrix r = A.times(x).minus(b);
+double rnorm = r.normInf();
+</PRE></DD>
+</DL>
+
+@author The MathWorks, Inc. and the National Institute of Standards and Technology.
+@version 5 August 1998
+ */
+public class Matrix implements Cloneable, java.io.Serializable {
+
+  /* ------------------------
+  Class variables
+   * ------------------------ */
+  /** Array for internal storage of elements.
+  @serial internal array storage.
+   */
+  private double[][] A;
+  /** Row and column dimensions.
+  @serial row dimension.
+  @serial column dimension.
+   */
+  private int m, n;
+
+  /* ------------------------
+  Constructors
+   * ------------------------ */
+  /** Construct an m-by-n matrix of zeros. 
+  @param m    Number of rows.
+  @param n    Number of colums.
+   */
+  public Matrix(int m, int n) {
+    this.m = m;
+    this.n = n;
+    A = new double[m][n];
+  }
+
+  /** Construct an m-by-n constant matrix.
+  @param m    Number of rows.
+  @param n    Number of colums.
+  @param s    Fill the matrix with this scalar value.
+   */
+  public Matrix(int m, int n, double s) {
+    this.m = m;
+    this.n = n;
+    A = new double[m][n];
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = s;
+      }
+    }
+  }
+
+  /** Construct a matrix from a 2-D array.
+  @param A    Two-dimensional array of doubles.
+  @exception  IllegalArgumentException All rows must have the same length
+  @see        #constructWithCopy
+   */
+  public Matrix(double[][] A) {
+    m = A.length;
+    n = A[0].length;
+    for (int i = 0; i < m; i++) {
+      if (A[i].length != n) {
+        throw new IllegalArgumentException("All rows must have the same length.");
+      }
+    }
+    this.A = A;
+  }
+
+  /** Construct a matrix quickly without checking arguments.
+  @param A    Two-dimensional array of doubles.
+  @param m    Number of rows.
+  @param n    Number of colums.
+   */
+  public Matrix(double[][] A, int m, int n) {
+    this.A = A;
+    this.m = m;
+    this.n = n;
+  }
+
+  /** Construct a matrix from a one-dimensional packed array
+  @param vals One-dimensional array of doubles, packed by columns (ala Fortran).
+  @param m    Number of rows.
+  @exception  IllegalArgumentException Array length must be a multiple of m.
+   */
+  public Matrix(double vals[], int m) {
+    this.m = m;
+    n = (m != 0 ? vals.length / m : 0);
+    if (m * n != vals.length) {
+      throw new IllegalArgumentException("Array length must be a multiple of m.");
+    }
+    A = new double[m][n];
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = vals[i + j * m];
+      }
+    }
+  }
+
+  /* ------------------------
+  Public Methods
+   * ------------------------ */
+  /** Construct a matrix from a copy of a 2-D array.
+  @param A    Two-dimensional array of doubles.
+  @exception  IllegalArgumentException All rows must have the same length
+   */
+  public static Matrix constructWithCopy(double[][] A) {
+    int m = A.length;
+    int n = A[0].length;
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      if (A[i].length != n) {
+        throw new IllegalArgumentException("All rows must have the same length.");
+      }
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** Make a deep copy of a matrix
+   */
+  public Matrix copy() {
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      System.arraycopy(A[i], 0, C[i], 0, n);
+    }
+    return X;
+  }
+
+  /** Clone the Matrix object.
+   */
+  public Object clone() {
+    return this.copy();
+  }
+
+  /** Access the internal two-dimensional array.
+  @return     Pointer to the two-dimensional array of matrix elements.
+   */
+  public double[][] getArray() {
+    return A;
+  }
+
+  /** Copy the internal two-dimensional array.
+  @return     Two-dimensional array copy of matrix elements.
+   */
+  public double[][] getArrayCopy() {
+    double[][] C = new double[m][n];
+    for (int i = 0; i < m; i++) {
+      System.arraycopy(A[i], 0, C[i], 0, n);
+    }
+    return C;
+  }
+
+  /** Make a one-dimensional column packed copy of the internal array.
+  @return     Matrix elements packed in a one-dimensional array by columns.
+   */
+  public double[] getColumnPackedCopy() {
+    double[] vals = new double[m * n];
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        vals[i + j * m] = A[i][j];
+      }
+    }
+    return vals;
+  }
+
+  /** Make a one-dimensional row packed copy of the internal array.
+  @return     Matrix elements packed in a one-dimensional array by rows.
+   */
+  public double[] getRowPackedCopy() {
+    double[] vals = new double[m * n];
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        vals[i * n + j] = A[i][j];
+      }
+    }
+    return vals;
+  }
+
+  /** Get row dimension.
+  @return     m, the number of rows.
+   */
+  public int getRowDimension() {
+    return m;
+  }
+
+  /** Get column dimension.
+  @return     n, the number of columns.
+   */
+  public int getColumnDimension() {
+    return n;
+  }
+
+  /** Get a single element.
+  @param i    Row index.
+  @param j    Column index.
+  @return     A(i,j)
+  @exception  ArrayIndexOutOfBoundsException
+   */
+  public double get(int i, int j) {
+    return A[i][j];
+  }
+
+  /** Get a submatrix.
+  @param i0   Initial row index
+  @param i1   Final row index
+  @param j0   Initial column index
+  @param j1   Final column index
+  @return     A(i0:i1,j0:j1)
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public Matrix getMatrix(int i0, int i1, int j0, int j1) {
+    Matrix X = new Matrix(i1 - i0 + 1, j1 - j0 + 1);
+    double[][] B = X.getArray();
+    try {
+      for (int i = i0; i <= i1; i++) {
+        for (int j = j0; j <= j1; j++) {
+          B[i - i0][j - j0] = A[i][j];
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+    return X;
+  }
+
+  /** Get a submatrix.
+  @param r    Array of row indices.
+  @param c    Array of column indices.
+  @return     A(r(:),c(:))
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public Matrix getMatrix(int[] r, int[] c) {
+    Matrix X = new Matrix(r.length, c.length);
+    double[][] B = X.getArray();
+    try {
+      for (int i = 0; i < r.length; i++) {
+        for (int j = 0; j < c.length; j++) {
+          B[i][j] = A[r[i]][c[j]];
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+    return X;
+  }
+
+  /** Get a submatrix.
+  @param i0   Initial row index
+  @param i1   Final row index
+  @param c    Array of column indices.
+  @return     A(i0:i1,c(:))
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public Matrix getMatrix(int i0, int i1, int[] c) {
+    Matrix X = new Matrix(i1 - i0 + 1, c.length);
+    double[][] B = X.getArray();
+    try {
+      for (int i = i0; i <= i1; i++) {
+        for (int j = 0; j < c.length; j++) {
+          B[i - i0][j] = A[i][c[j]];
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+    return X;
+  }
+
+  /** Get a submatrix.
+  @param r    Array of row indices.
+  @param i0   Initial column index
+  @param i1   Final column index
+  @return     A(r(:),j0:j1)
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public Matrix getMatrix(int[] r, int j0, int j1) {
+    Matrix X = new Matrix(r.length, j1 - j0 + 1);
+    double[][] B = X.getArray();
+    try {
+      for (int i = 0; i < r.length; i++) {
+        for (int j = j0; j <= j1; j++) {
+          B[i][j - j0] = A[r[i]][j];
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+    return X;
+  }
+
+  /** Set a single element.
+  @param i    Row index.
+  @param j    Column index.
+  @param s    A(i,j).
+  @exception  ArrayIndexOutOfBoundsException
+   */
+  public void set(int i, int j, double s) {
+    A[i][j] = s;
+  }
+
+  /** Set a submatrix.
+  @param i0   Initial row index
+  @param i1   Final row index
+  @param j0   Initial column index
+  @param j1   Final column index
+  @param X    A(i0:i1,j0:j1)
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public void setMatrix(int i0, int i1, int j0, int j1, Matrix X) {
+    try {
+      for (int i = i0; i <= i1; i++) {
+        for (int j = j0; j <= j1; j++) {
+          A[i][j] = X.get(i - i0, j - j0);
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+  }
+
+  /** Set a submatrix.
+  @param r    Array of row indices.
+  @param c    Array of column indices.
+  @param X    A(r(:),c(:))
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public void setMatrix(int[] r, int[] c, Matrix X) {
+    try {
+      for (int i = 0; i < r.length; i++) {
+        for (int j = 0; j < c.length; j++) {
+          A[r[i]][c[j]] = X.get(i, j);
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+  }
+
+  /** Set a submatrix.
+  @param r    Array of row indices.
+  @param j0   Initial column index
+  @param j1   Final column index
+  @param X    A(r(:),j0:j1)
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public void setMatrix(int[] r, int j0, int j1, Matrix X) {
+    try {
+      for (int i = 0; i < r.length; i++) {
+        for (int j = j0; j <= j1; j++) {
+          A[r[i]][j] = X.get(i, j - j0);
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+  }
+
+  /** Set a submatrix.
+  @param i0   Initial row index
+  @param i1   Final row index
+  @param c    Array of column indices.
+  @param X    A(i0:i1,c(:))
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public void setMatrix(int i0, int i1, int[] c, Matrix X) {
+    try {
+      for (int i = i0; i <= i1; i++) {
+        for (int j = 0; j < c.length; j++) {
+          A[i][c[j]] = X.get(i - i0, j);
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+  }
+
+  /** Matrix transpose.
+  @return    A'
+   */
+  public Matrix transpose() {
+    Matrix X = new Matrix(n, m);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[j][i] = A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** One norm
+  @return    maximum column sum.
+   */
+  public double norm1() {
+    double f = 0;
+    for (int j = 0; j < n; j++) {
+      double s = 0;
+      for (int i = 0; i < m; i++) {
+        s += Math.abs(A[i][j]);
+      }
+      f = Math.max(f, s);
+    }
+    return f;
+  }
+
+  /** Two norm
+  @return    maximum singular value.
+   */
+  public double norm2() {
+    return (new SingularValueDecomposition(this).norm2());
+  }
+
+  /** Infinity norm
+  @return    maximum row sum.
+   */
+  public double normInf() {
+    double f = 0;
+    for (int i = 0; i < m; i++) {
+      double s = 0;
+      for (int j = 0; j < n; j++) {
+        s += Math.abs(A[i][j]);
+      }
+      f = Math.max(f, s);
+    }
+    return f;
+  }
+
+  /** Frobenius norm
+  @return    sqrt of sum of squares of all elements.
+   */
+  public double normF() {
+    double f = 0;
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        f = Math.hypot(f, A[i][j]);
+      }
+    }
+    return f;
+  }
+
+  /**  Unary minus
+  @return    -A
+   */
+  public Matrix uminus() {
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = -A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** C = A + B
+  @param B    another matrix
+  @return     A + B
+   */
+  public Matrix plus(Matrix B) {
+    checkMatrixDimensions(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] + B.A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** A = A + B
+  @param B    another matrix
+  @return     A + B
+   */
+  public Matrix plusEquals(Matrix B) {
+    checkMatrixDimensions(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = A[i][j] + B.A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** C = A - B
+  @param B    another matrix
+  @return     A - B
+   */
+  public Matrix minus(Matrix B) {
+    checkMatrixDimensions(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] - B.A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** A = A - B
+  @param B    another matrix
+  @return     A - B
+   */
+  public Matrix minusEquals(Matrix B) {
+    checkMatrixDimensions(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = A[i][j] - B.A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** Element-by-element multiplication, C = A.*B
+  @param B    another matrix
+  @return     A.*B
+   */
+  public Matrix arrayTimes(Matrix B) {
+    checkMatrixDimensions(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] * B.A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** Element-by-element multiplication in place, A = A.*B
+  @param B    another matrix
+  @return     A.*B
+   */
+  public Matrix arrayTimesEquals(Matrix B) {
+    checkMatrixDimensions(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = A[i][j] * B.A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** Element-by-element right division, C = A./B
+  @param B    another matrix
+  @return     A./B
+   */
+  public Matrix arrayRightDivide(Matrix B) {
+    checkMatrixDimensions(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] / B.A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** Element-by-element right division in place, A = A./B
+  @param B    another matrix
+  @return     A./B
+   */
+  public Matrix arrayRightDivideEquals(Matrix B) {
+    checkMatrixDimensions(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = A[i][j] / B.A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** Element-by-element left division, C = A.\B
+  @param B    another matrix
+  @return     A.\B
+   */
+  public Matrix arrayLeftDivide(Matrix B) {
+    checkMatrixDimensions(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = B.A[i][j] / A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** Element-by-element left division in place, A = A.\B
+  @param B    another matrix
+  @return     A.\B
+   */
+  public Matrix arrayLeftDivideEquals(Matrix B) {
+    checkMatrixDimensions(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = B.A[i][j] / A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** Multiply a matrix by a scalar, C = s*A
+  @param s    scalar
+  @return     s*A
+   */
+  public Matrix times(double s) {
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = s * A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** Multiply a matrix by a scalar in place, A = s*A
+  @param s    scalar
+  @return     replace A by s*A
+   */
+  public Matrix timesEquals(double s) {
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = s * A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** Linear algebraic matrix multiplication, A * B
+  @param B    another matrix
+  @return     Matrix product, A * B
+  @exception  IllegalArgumentException Matrix inner dimensions must agree.
+   */
+  public Matrix times(Matrix B) {
+    if (B.m != n) {
+      throw new IllegalArgumentException("Matrix inner dimensions must agree.");
+    }
+    Matrix X = new Matrix(m, B.n);
+    double[][] C = X.getArray();
+    double[] Bcolj = new double[n];
+    for (int j = 0; j < B.n; j++) {
+      for (int k = 0; k < n; k++) {
+        Bcolj[k] = B.A[k][j];
+      }
+      for (int i = 0; i < m; i++) {
+        double[] Arowi = A[i];
+        double s = 0;
+        for (int k = 0; k < n; k++) {
+          s += Arowi[k] * Bcolj[k];
+        }
+        C[i][j] = s;
+      }
+    }
+    return X;
+  }
+
+  /** LU Decomposition
+  @return     LUDecomposition
+  @see LUDecomposition
+   */
+  public LUDecomposition lu() {
+    return new LUDecomposition(this);
+  }
+
+  /** QR Decomposition
+  @return     QRDecomposition
+  @see QRDecomposition
+   */
+  public QRDecomposition qr() {
+    return new QRDecomposition(this);
+  }
+
+  /** Cholesky Decomposition
+  @return     CholeskyDecomposition
+  @see CholeskyDecomposition
+   */
+  public CholeskyDecomposition chol() {
+    return new CholeskyDecomposition(this);
+  }
+
+  /** Singular Value Decomposition
+  @return     SingularValueDecomposition
+  @see SingularValueDecomposition
+   */
+  public SingularValueDecomposition svd() {
+    return new SingularValueDecomposition(this);
+  }
+
+  /** Eigenvalue Decomposition
+  @return     EigenvalueDecomposition
+  @see EigenvalueDecomposition
+   */
+  public EigenvalueDecomposition eig() {
+    return new EigenvalueDecomposition(this);
+  }
+
+  /** Solve A*X = B
+  @param B    right hand side
+  @return     solution if A is square, least squares solution otherwise
+   */
+  public Matrix solve(Matrix B) {
+    return (m == n ? (new LUDecomposition(this)).solve(B) : (new QRDecomposition(this)).solve(B));
+  }
+
+  /** Solve X*A = B, which is also A'*X' = B'
+  @param B    right hand side
+  @return     solution if A is square, least squares solution otherwise.
+   */
+  public Matrix solveTranspose(Matrix B) {
+    return transpose().solve(B.transpose());
+  }
+
+  /** Matrix inverse or pseudoinverse
+  @return     inverse(A) if A is square, pseudoinverse otherwise.
+   */
+  public Matrix inverse() {
+    return solve(identity(m, m));
+  }
+
+  /** Matrix determinant
+  @return     determinant
+   */
+  public double det() {
+    return new LUDecomposition(this).det();
+  }
+
+  /** Matrix rank
+  @return     effective numerical rank, obtained from SVD.
+   */
+  public int rank() {
+    return new SingularValueDecomposition(this).rank();
+  }
+
+  /** Matrix condition (2 norm)
+  @return     ratio of largest to smallest singular value.
+   */
+  public double cond() {
+    return new SingularValueDecomposition(this).cond();
+  }
+
+  /** Matrix trace.
+  @return     sum of the diagonal elements.
+   */
+  public double trace() {
+    double t = 0;
+    for (int i = 0; i < Math.min(m, n); i++) {
+      t += A[i][i];
+    }
+    return t;
+  }
+
+  /** Generate matrix with random elements
+  @param m    Number of rows.
+  @param n    Number of colums.
+  @return     An m-by-n matrix with uniformly distributed random elements.
+   */
+  public static Matrix random(int m, int n) {
+    Matrix A = new Matrix(m, n);
+    double[][] X = A.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        X[i][j] = Math.random();
+      }
+    }
+    return A;
+  }
+
+  /** Generate identity matrix
+  @param m    Number of rows.
+  @param n    Number of colums.
+  @return     An m-by-n matrix with ones on the diagonal and zeros elsewhere.
+   */
+  public static Matrix identity(int m, int n) {
+    Matrix A = new Matrix(m, n);
+    double[][] X = A.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        X[i][j] = (i == j ? 1.0 : 0.0);
+      }
+    }
+    return A;
+  }
+
+  /** Print the matrix to stdout.   Line the elements up in columns
+   * with a Fortran-like 'Fw.d' style format.
+  @param w    Column width.
+  @param d    Number of digits after the decimal.
+   */
+  public void print(int w, int d) {
+    print(new PrintWriter(System.out, true), w, d);
+  }
+
+  /** Print the matrix to the output stream.   Line the elements up in
+   * columns with a Fortran-like 'Fw.d' style format.
+  @param output Output stream.
+  @param w      Column width.
+  @param d      Number of digits after the decimal.
+   */
+  public void print(PrintWriter output, int w, int d) {
+    DecimalFormat format = new DecimalFormat();
+    format.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
+    format.setMinimumIntegerDigits(1);
+    format.setMaximumFractionDigits(d);
+    format.setMinimumFractionDigits(d);
+    format.setGroupingUsed(false);
+    print(output, format, w + 2);
+  }
+
+  /** Print the matrix to stdout.  Line the elements up in columns.
+   * Use the format object, and right justify within columns of width
+   * characters.
+   * Note that is the matrix is to be read back in, you probably will want
+   * to use a NumberFormat that is set to US Locale.
+  @param format A  Formatting object for individual elements.
+  @param width     Field width for each column.
+  @see java.text.DecimalFormat#setDecimalFormatSymbols
+   */
+  public void print(NumberFormat format, int width) {
+    print(new PrintWriter(System.out, true), format, width);
+  }
+
+  // DecimalFormat is a little disappointing coming from Fortran or C's printf.
+  // Since it doesn't pad on the left, the elements will come out different
+  // widths.  Consequently, we'll pass the desired column width in as an
+  // argument and do the extra padding ourselves.
+  /** Print the matrix to the output stream.  Line the elements up in columns.
+   * Use the format object, and right justify within columns of width
+   * characters.
+   * Note that is the matrix is to be read back in, you probably will want
+   * to use a NumberFormat that is set to US Locale.
+  @param output the output stream.
+  @param format A formatting object to format the matrix elements 
+  @param width  Column width.
+  @see java.text.DecimalFormat#setDecimalFormatSymbols
+   */
+  public void print(PrintWriter output, NumberFormat format, int width) {
+    output.println();  // start on new line.
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        String s = format.format(A[i][j]); // format the number
+        int padding = Math.max(1, width - s.length()); // At _least_ 1 space
+        for (int k = 0; k < padding; k++) {
+          output.print(' ');
+        }
+        output.print(s);
+      }
+      output.println();
+    }
+    output.println();   // end with blank line.
+  }
+
+  /** Read a matrix from a stream.  The format is the same the print method,
+   * so printed matrices can be read back in (provided they were printed using
+   * US Locale).  Elements are separated by
+   * whitespace, all the elements for each row appear on a single line,
+   * the last row is followed by a blank line.
+  @param input the input stream.
+   */
+  @SuppressWarnings("unchecked")
+  public static Matrix read(BufferedReader input) throws java.io.IOException {
+    StreamTokenizer tokenizer = new StreamTokenizer(input);
+
+    // Although StreamTokenizer will parse numbers, it doesn't recognize
+    // scientific notation (E or D); however, Double.valueOf does.
+    // The strategy here is to disable StreamTokenizer's number parsing.
+    // We'll only get whitespace delimited words, EOL's and EOF's.
+    // These words should all be numbers, for Double.valueOf to parse.
+
+    tokenizer.resetSyntax();
+    tokenizer.wordChars(0, 255);
+    tokenizer.whitespaceChars(0, ' ');
+    tokenizer.eolIsSignificant(true);
+    java.util.Vector v = new java.util.Vector();
+
+    // Ignore initial empty lines
+    while (tokenizer.nextToken() == StreamTokenizer.TT_EOL);
+    if (tokenizer.ttype == StreamTokenizer.TT_EOF) {
+      throw new java.io.IOException("Unexpected EOF on matrix read.");
+    }
+    do {
+      v.addElement(Double.valueOf(tokenizer.sval)); // Read & store 1st row.
+    } while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
+
+    int n = v.size();  // Now we've got the number of columns!
+    double row[] = new double[n];
+    for (int j = 0; j < n; j++) // extract the elements of the 1st row.
+    {
+      row[j] = ((Double) v.elementAt(j)).doubleValue();
+    }
+    v.removeAllElements();
+    v.addElement(row);  // Start storing rows instead of columns.
+    while (tokenizer.nextToken() == StreamTokenizer.TT_WORD) {
+      // While non-empty lines
+      v.addElement(row = new double[n]);
+      int j = 0;
+      do {
+        if (j >= n) {
+          throw new java.io.IOException("Row " + v.size() + " is too long.");
+        }
+        row[j++] = Double.valueOf(tokenizer.sval).doubleValue();
+      } while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
+      if (j < n) {
+        throw new java.io.IOException("Row " + v.size() + " is too short.");
+      }
+    }
+    int m = v.size();  // Now we've got the number of rows.
+    double[][] A = new double[m][];
+    v.copyInto(A);  // copy the rows out of the vector
+    return new Matrix(A);
+  }
+
+
+  /* ------------------------
+  Private Methods
+   * ------------------------ */
+  /** Check if size(A) == size(B) **/
+  private void checkMatrixDimensions(Matrix B) {
+    if (B.m != m || B.n != n) {
+      throw new IllegalArgumentException("Matrix dimensions must agree.");
+    }
+  }
+
+  /* ---------------------------------
+  Quelques méthodes supplémentaires
+   * ---------------------------------*/
+  private void checkLineDimension(Matrix B) {
+    if (B.m != m) {
+      throw new IllegalArgumentException("Matrix line dimension must agree.");
+    }
+  }
+
+  private void checkColumnDimension(Matrix B) {
+    if (B.n != n) {
+      throw new IllegalArgumentException("Matrix column dimension must agree.");
+    }
+  }
+
+  public long getNumberNonZeroValues() {
+    long nnz = 0;
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        if (A[i][j] != 0) nnz++;
+      }
+    }
+    return nnz;
+  }
+
+  public double minColumn(int j) {
+    double min = Double.POSITIVE_INFINITY;
+    for (int i = 0; i < m; i++) {
+      min = Math.min(min, A[i][j]);
+    }
+    return min;
+  }
+
+  public double maxColumn(int j) {
+    double max = Double.NEGATIVE_INFINITY;
+    for (int i = 0; i < m; i++) {
+      max = Math.max(max, A[i][j]);
+    }
+    return max;
+  }
+
+  public double elementSum() {
+    double s = 0;
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        s += A[i][j];
+      }
+    }
+    return s;
+  }
+
+  public Matrix lineSum() {
+    Matrix S = new Matrix(m, 1);
+    double s[][] = S.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        s[i][0] += A[i][j];
+      }
+    }
+    return S;
+  }
+
+  public Matrix lineMean() {
+    Matrix S = new Matrix(m, 1);
+    double s[][] = S.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        s[i][0] += A[i][j];
+      }
+      s[i][0] /= n;
+    }
+    return S;
+  }
+
+  public Matrix columnSum() {
+    Matrix S = new Matrix(1, n);
+    double s[][] = S.getArray();
+    for (int j = 0; j < n; j++) {
+      for (int i = 0; i < m; i++) {
+        s[0][j] += A[i][j];
+      }
+    }
+    return S;
+  }
+
+  public Matrix columnMean() {
+    Matrix S = new Matrix(1, n);
+    double s[][] = S.getArray();
+    for (int j = 0; j < n; j++) {
+      for (int i = 0; i < m; i++) {
+        s[0][j] += A[i][j];
+      }
+      s[0][j] /= m;
+    }
+    return S;
+  }
+
+  public Matrix columnCovariance() {
+    double mean[] = new double[n];
+    for (int j = 0; j < n; j++) {
+      for (int i = 0; i < m; i++) {
+        mean[j] += A[i][j];
+      }
+      mean[j] /= m;
+    }
+    Matrix X = new Matrix(n, n);
+    double[][] B = X.getArray();
+    double[] Acolj = new double[m];
+    int coef = m > 2 ? m-1 : 1;
+    for (int j = 0; j < n; j++) {
+      for (int k = 0; k < m; k++) {
+        Acolj[k] = A[k][j] - mean[j];
+      }
+      for (int i = 0; i < n; i++) {
+        double[] Atrowi = new double[m];
+        for (int k = 0; k < m; k++) {
+          Atrowi[k] = A[k][i] - mean[i];
+        }
+        double s = 0;
+        for (int k = 0; k < m; k++) {
+          s += Atrowi[k] * Acolj[k];
+        }
+        B[i][j] = s / coef;
+      }
+    }
+    return X;
+  }
+
+public Matrix firstLineMinus(Matrix B) {
+     checkColumnDimension(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] - B.A[0][j];
+      }
+    }
+    return X;
+ 
+}
+  public Matrix nulColumnSuppression() {
+    ArrayList<Integer> cols = new ArrayList<Integer>();
+    for (int j = 0; j < n; j++) {
+      for (int i = 0; i < m; i++) {
+        if (A[i][j] != 0) {
+          cols.add(j);
+          break;
+        }
+      }
+    }
+    int[] c = new int[cols.size()];
+    for (int i = 0; i < c.length; i++) {
+      c[i] = cols.get(i);
+    }
+    return getMatrix(0, m - 1, c);
+  }
+
+  public Matrix arrayInverse() {
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = 1 / A[i][j];
+      }
+    }
+    return X;
+  }
+
+  public Matrix arraySqrt() {
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = Math.sqrt(A[i][j]);
+      }
+    }
+    return X;
+  }
+
+  public Matrix firstColumTimes(Matrix B) {
+    checkLineDimension(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+
+        C[i][j] = A[i][j] * B.A[i][0];
+      }
+    }
+    return X;
+  }
+
+  public Matrix firstColumnTimesEqual(Matrix B) {
+    checkLineDimension(B);
+    for (int i = 0; i < m; i++) {
+       for (int j = 0; j < n; j++) {
+
+        A[i][j] *= B.A[i][0];
+      }
+    }
+    return this;
+  }
+
+  public Matrix firstLineTimesEqual(Matrix B) {
+    checkColumnDimension(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] *= B.A[0][j];
+      }
+    }
+    return this;
+  }
+
+  public Matrix firstLineTimes(Matrix B) {
+    checkColumnDimension(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] * B.A[0][j];
+      }
+    }
+    return X;
+  }
+
+  public void fixColumnSigns() {
+    for (int j = 0; j < n; j++) {
+      int i = 0;
+      while (i<m && A[i][j] == 0) i++;
+      if (i==m || A[i][j] > 0)  continue;
+      while (i < m) {
+        A[i][j] = -A[i][j];
+        i++;
+      }
+    }
+  }
+
+  /** Analyse factorielle de correspondances
+  @return     Analyse factorielle de correspondances
+  @see Analyse factorielle de correspondances
+   */
+  public AFC afc() {
+    return new AFC(this);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/Matrix.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/SparseAFC.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/SparseAFC.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/SparseAFC.java	(revision 481)
@@ -0,0 +1,82 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus;
+
+import JamaPlus.SparseSVD.SparseSVDException;
+
+/**
+ /**
+ *
+ * SparseAFC analyse factorielle des correspondances (matrices creuses)
+ * mat :  matrice binaire (0. ou 1.) profil des lignes (un individu par ligne, un caractère par colonne)
+ * CP: composantes principales,
+ * VP: valeurs d'inertie, 
+ * CG: centres de gravité des CP contenant un même caractère (non calculé dans cette version)
+ * [p,q] = size(mat); p:nb de lignes, q:nb de col
+ * 
+ * @author Bernard
+ */
+public class SparseAFC {
+  private double[][] CP;
+  private double[] VP;
+  private int p, q, n;
+
+  SparseAFC(SparseMatrix Arg) throws SparseSVDException {
+    SparseMatrix mat = Arg.copy();
+    mat.nulColumnSuppression();
+    p = mat.getRowDimension();
+    q = mat.getColumnDimension();
+    n = Math.min(Math.min(p, q), 5); 
+    // n : nombre de composantes principales espérées (pas plus de 5)
+    if (n == 0) return;
+    if (n == 1) {
+      CP = new double[p][1];
+      VP = new double[1];
+      return;
+    }
+    double f = mat.elementSum();
+    if (f == 0) return;
+    mat = mat.timesEquals(1 / f);
+    Matrix r = mat.lineSum();
+    Matrix r1 = r.arrayInverse();
+    Matrix r2 = r.arraySqrt();
+    Matrix r3 = r2.arrayInverse();
+    Matrix c = mat.columnSum();
+    Matrix c1 = c.arrayInverse();
+    Matrix c2 = c.arraySqrt();
+    Matrix c3 = c2.arrayInverse();
+    mat = mat.firstColumnTimesEqual(r3);
+    mat = mat.firstLineTimesEqual(c3);
+    SparseSVD svd = mat.svd(n);
+    Matrix cp = svd.getU();
+    Matrix vp = new Matrix(svd.getSingularValues(), 1);
+    n = vp.getColumnDimension();   
+    // peut-être moins de composantes principales effectivement calculées
+     if (n == 0) return;
+    if (n == 1) {
+      CP = new double[p][1];
+      VP = new double[1];
+      return;
+    }
+    cp = cp.getMatrix(0, p - 1, 1, n - 1);
+    cp = cp.firstColumnTimesEqual(r2);
+    vp = vp.getMatrix(0, 0, 1, n - 1);
+    cp = cp.firstLineTimesEqual(vp);
+    cp.fixColumnSigns();
+    cp = cp.firstColumnTimesEqual(r1);
+    CP = cp.getArray();
+    VP = vp.getColumnPackedCopy();
+  }
+
+  public Matrix getCP() {
+    if (CP == null) return null;
+    return new Matrix(CP, p, n - 1);
+  }
+
+  public double[] getVP() {
+    return VP;
+  }
+}
+

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/SparseAFC.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/AFC.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/AFC.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/AFC.java	(revision 481)
@@ -0,0 +1,70 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus;
+
+/**
+ *
+ * AFC analyse factorielle des correspondances (optimisé mémoire)
+ * mat :  matrice binaire (0. ou 1.) profil des lignes (un individu par ligne, un caractère par colonne)
+ * CP: composantes principales,
+ * VP: valeurs d'inertie, 
+ * CG: centres de gravité des CP contenant un même caractère (non calculé dans cette version)
+ * [p,q] = size(mat); p:nb de lignes, q:nb de col
+ * 
+ * @author Bernard
+ */
+public class AFC {
+
+  private double[][] CP;
+  private double[] VP;
+  private int p, q, n;
+
+  AFC(Matrix Arg) {
+    Matrix mat = Arg.copy();
+    mat = mat.nulColumnSuppression();
+    p = mat.getRowDimension();
+    q = mat.getColumnDimension();
+    n = Math.min(Math.min(p, q), 5); // n : nombre de composantes principales calculées
+    if (n == 0) return;
+    if (n == 1) {
+      CP = new double[p][1];
+      VP = new double[1];
+      return;
+    }
+    double f = mat.elementSum();
+    if (f == 0) return;
+    mat = mat.timesEquals(1 / f);
+    Matrix r = mat.lineSum();
+    Matrix r1 = r.arrayInverse();
+    Matrix r2 = r.arraySqrt();
+    Matrix r3 = r2.arrayInverse();
+    Matrix c = mat.columnSum();
+    Matrix c1 = c.arrayInverse();
+    Matrix c2 = c.arraySqrt();
+    Matrix c3 = c2.arrayInverse();
+    mat = mat.firstColumnTimesEqual(r3);
+    mat = mat.firstLineTimesEqual(c3);
+    SingularValueDecomposition svd = mat.svd();
+    Matrix cp = svd.getU();
+    Matrix vp = new Matrix(svd.getSingularValues(), 1);
+    cp = cp.getMatrix(0, p - 1, 1, n - 1);
+    cp = cp.firstColumnTimesEqual(r2);
+    vp = vp.getMatrix(0, 0, 1, n - 1);
+    cp = cp.firstLineTimesEqual(vp);
+    cp.fixColumnSigns();
+    cp = cp.firstColumnTimesEqual(r1);
+    CP = cp.getArray();
+    VP = vp.getColumnPackedCopy();
+  }
+
+  public Matrix getCP() {
+    if (CP == null) return null;
+    return new Matrix(CP, p, n - 1);
+  }
+
+  public double[] getVP() {
+    return VP;
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/AFC.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/JamaPlus/SparseSVD.java
===================================================================
--- tmp/org.txm.analec.rcp/src/JamaPlus/SparseSVD.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/JamaPlus/SparseSVD.java	(revision 481)
@@ -0,0 +1,920 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus;
+
+import JamaPlus.util.*;
+import java.util.*;
+
+/**
+ *
+ * @author Bernard
+ */
+public class SparseSVD {  // based on code adapted from SVDLIBC - svdLAS2 (adapted from SVDPACKC)
+  private boolean transpose; // si transposition de la matrice en entrée
+  private int rows, cols, dim; // nb rows, nb cols, nb de val sing. désirées
+  // (après transposition éventuelle)
+  private double[][] Ut; // (d x m) transpose of left singular vectors (rows of Ut)
+  private double[][] Vt; // (d x n) transpose of right singular vectors (rows of Vt)
+  private double[] S; // d singular values
+  /* Constantes */
+  private final static int MAXLL = 2; // ??
+  private final static double[] END = {-1e-30, 1e-30};
+  private final static double EPS = Machine.eps(); // precision de la machine
+  private final static double RAD_EPS = Math.sqrt(EPS);
+  private final static double RAD34_EPS = RAD_EPS*Math.sqrt(RAD_EPS);
+  private final static double KAPPA = Math.max(RAD34_EPS, 1e-6);
+  private double EPS1;  // = precision * sqrt(nbcols)
+  /* Variables de travail : mémoire à libérer en fin de calcul */
+  private double[] alph;  // diagonale de la matrice tridiagonale T
+  private double[] bet; // éléments hors-diagonale de T
+  private double[] ritz; // valeurs propres de la  projection de A'A sur l'espace de Krylov
+  private double[] bnd; // a vérifier : initialisation (127) nécessaire ?? 
+  private double[] rj ;
+  private  double[] qj;
+  private  double[] qj1;
+  private  double[] pj ;
+  private  double[] pj1;
+  private  double[] wk;
+   private   double[] eta; 
+  private  double[] oldeta; 
+
+
+//    private static int irandom = 0;  // deboguage : à supprimer
+
+  private static class Storage {  // store Lanczos vectors q(j) 
+    private double[][] P, Q;  // P supplementary storage for j < MAXLL (j= 0 or 1)
+
+    private Storage(int nb, int maxll) {
+      P = new double[maxll][];
+      Q = new double[nb][];
+    }
+
+    private void storeP(int n, int j, double[] p) {
+      if (P[j]==null) P[j] = new double[n];
+      System.arraycopy(p, 0, P[j], 0, n);
+    }
+
+    private void storeQ(int n, int j, double[] q) {
+      if (Q[j]==null) Q[j] = new double[n];
+      System.arraycopy(q, 0, Q[j], 0, n);
+    }
+
+    private void retrieveP(int n, int j, double[] p) {
+      System.arraycopy(P[j], 0, p, 0, n);
+    }
+
+    private void retrieveQ(int n, int j, double[] q) {
+      System.arraycopy(Q[j], 0, q, 0, n);
+    }
+  }
+  private Storage storage;
+
+ public enum CodeSVDException {
+   DIM_OUT_OF_BOUNDS ("Nombre de valeurs singulières désirées invalide"),
+   FIRST_STEP_FAILURE("Impossible d'initialiser le premier pas de calcul"),
+   CONVERGENCE_FAILURE("Echec de convergence ");
+   String message;
+  CodeSVDException(String message) {
+   this.message = message;
+ }
+ }
+  public static class SparseSVDException extends Exception { // Erreurs
+    private CodeSVDException code;
+    private int k;
+
+    private SparseSVDException(CodeSVDException code, int k) {
+      super();
+      this.code = code;
+      this.k = k;
+    }
+
+    public CodeSVDException getCode() {
+      return code;
+    }
+
+    public int getK() {
+      return k;
+    }
+
+    @Override
+    public String getMessage() {
+      return super.getMessage()+"\ncode = "+getCode().message +", n = "+getK();
+    }
+  }
+
+  public SparseSVD(SparseMatrix spm, int d) throws SparseSVDException {
+    int iter = Math.min(spm.getRowDimension(), spm.getColumnDimension()); // nb d'itérations 
+    if (d<=0 || d>iter)
+      throw new SparseSVDException(CodeSVDException.DIM_OUT_OF_BOUNDS, d);
+    dim = d;
+    transpose = spm.getColumnDimension()>=spm.getRowDimension()*1.2;
+    SparseMatrix A = transpose ? spm.transpose() : spm.copy();
+    rows = A.getRowDimension();
+    cols = A.getColumnDimension();
+    EPS1 = EPS*Math.sqrt(cols);
+    alph = new double[iter];  // diagonale de la matrice tridiagonale T
+    bet = new double[iter+1]; // éléments hors-diagonale de T
+    ritz = new double[iter+1];
+    bnd = new double[iter+1]; // a vérifier : initialisation (127) nécessaire ?? 
+    storage = new Storage(iter, MAXLL);
+    // Calcul de la matrice tridiagonale 
+    int[] steps_neig_ = lanso(A, iter);
+    Ut = new double[dim][rows];
+    Vt = new double[dim][cols];
+    S = new double[dim];
+    // Calcul des  vecteurs propres
+    //  nsig  : nb de val. propres "kappa-acceptables"
+    int nsig = ritvec(A, steps_neig_);
+    if (nsig<dim) dim = nsig;  // moins de valeurs obtenues que demandées
+    // libère la mémoire
+    storage = null;
+    alph =  bet = ritz = bnd = null;
+
+  }
+
+  private int[] lanso(SparseMatrix A, int iter) throws SparseSVDException {
+    // Calcul de la matrice tridiagonale
+    int neig = 0;
+    // espace de travail
+    rj = new double[cols];
+    qj = new double[cols];
+     qj1 = new double[cols];
+     pj = new double[cols];
+     pj1 = new double[cols];
+     wk = new double[cols];
+    // step one 
+    double[] rnm_tol_ = stpone(A, cols); // initialise rmn et tol
+     eta = new double[iter]; // orthogonality estimate of Lanczos vectors
+    oldeta = new double[iter];
+    if (rnm_tol_[0]==0) {
+      ritz[0] = alph[0];
+      storage.storeQ(cols, 0, qj);
+      return new int[]{0, 1}; // steps = 0 et neig = 1
+    }
+    eta[0] = oldeta[0] = EPS1;
+    boolean[] enough_ = {false}; // flag de sortie de boucle
+    int steps = 0; // j = steps
+    int[] ll_ = {0};  // 0, 1 or 2 initial Lanczos vectors in local orthog.
+    int first = 1;
+    int last = Math.min(dim+Math.max(8, dim), iter);  // = iter dans notre version
+    int i, l;
+    int intro = 0;
+    while (!enough_[0]) {
+      steps = lanczos_step(A, first, last, 
+              ll_, enough_, rnm_tol_, cols);
+      steps = enough_[0] ? steps-1 : last-1;
+      first = steps+1;
+      bet[first] = rnm_tol_[0];
+      // analyse T
+      l = 0;
+      for (int id2 = 0; id2<steps; id2++) {
+        if (l>steps) break;
+        for (i = l; i<=steps; i++) if (bet[i+1]==0) break;
+        if (i>steps) i = steps;
+        // now i is at the end of an unreduced submatrix
+        DoubleArraysPlus.copyReverse(i-l+1, alph, l, ritz, l);
+        DoubleArraysPlus.copyReverse(i-l, bet, l+1, wk, l+1);
+        imtqlb(i-l+1, l, ritz, wk, bnd);
+        for (int id3 = l; id3<=i; id3++)
+          bnd[id3] = rnm_tol_[0]*Math.abs(bnd[id3]);
+        l = i+1;
+      }
+      // sort eigenvalues into increasing order
+      DoubleArraysPlus.sort2(ritz, bnd, steps+1, 0);
+      // massage error bounds for very close ritz values 
+      neig = error_bound(enough_, END[0], END[1], steps, rnm_tol_[1]);
+      // should we stop? 
+      if (neig<dim) {
+        if (neig==0) {
+          last = first+9;
+          intro = first;
+        } else {
+          last = first+Math.max(3, 1+((steps-intro)*(dim-neig))/neig);
+        }
+        last = Math.min(last, iter);
+      } else {
+        enough_[0] = true;
+      }
+      enough_[0] = enough_[0]||first>=iter;
+    }
+    storage.storeQ(cols, steps, qj);
+    // libère la mémoire
+     rj = qj =  qj1 = pj =  pj1 =  wk = null;
+     eta = oldeta = null;
+    return new int[]{steps, neig};
+  }
+
+  private double[] stpone(SparseMatrix A,  int n)
+          throws SparseSVDException {
+    /*  stp-one performs the first step of the Lanczos algorithm.  It also
+    does a step of extended local re-orthogonalization.
+    Arguments 
+    (input)
+    n      dimension of the eigenproblem for matrix B
+    (output)
+    wptr   array of pointers that point to work space that contains
+    wptr[0]             r[j]
+    wptr[1]             q[j]
+    wptr[2]             q[j-1]
+    wptr[3]             p
+    wptr[4]             p[j-1]
+    alph             diagonal elements of matrix T 
+    throw a SparseSVDException(-1) if the choice of initial vector (startv) failed
+     */
+    // get initial normalized vector; default is random 
+    startv0(A, n);
+    System.arraycopy(pj, 0, qj, 0, n);
+    // take the first step   
+    A.opb(pj, rj);
+    alph[0] = DoubleArraysPlus.dot(rj, pj);
+    for (int i = 0; i<n; i++) rj[i] -= alph[0]*qj[i];
+    /* extended local reorthogonalization */
+    double t = DoubleArraysPlus.dot(rj, pj);
+    for (int i = 0; i<n; i++) rj[i] -= t*qj[i];
+    alph[0] += t;
+    System.arraycopy(rj, 0, pj1, 0, n);
+    double rnm = Math.sqrt(DoubleArraysPlus.dot(pj1, pj1));
+    double tol = RAD_EPS*(rnm+Math.abs(alph[0]));
+    return new double[]{rnm, tol};
+  }
+
+//  private static double random2() {
+//    double x = 0.11*(++irandom);
+//    return x-Math.floor(x);
+//  }
+//
+private void startv0(SparseMatrix A, int n)
+          throws SparseSVDException {
+    /* startv delivers a starting normalized vector in r, 
+     * and throws a SparseSVDException(-1) if no starting vector can be found.
+    Parameters 
+    (input)
+    n      dimension of the eigenproblem matrix B
+    wptr   array of pointers that point to work space
+    step      starting index for a Lanczos run
+    (output)
+    wptr   array of pointers that point to work space that contains
+    r[j], q[j], q[j-1], p[j], p[j-1]
+     */
+// get initial vector; default is random
+    double rnm2 = 0;
+    Random random = new Random(918273);
+    for (int id = 0; id<3; id++) {
+      for (int i = 0; i<n; i++) wk[i]  = random.nextDouble(); 
+      // apply operator to put r in range (essential if m singular)
+      A.opb(wk, pj);
+      rnm2 = DoubleArraysPlus.dot(pj, pj);
+      if (rnm2>0) break;
+    }
+    // normalize
+    if (rnm2<=0) throw new SparseSVDException(CodeSVDException.FIRST_STEP_FAILURE, 0);
+    rnm2 = 1/Math.sqrt(rnm2);
+    for (int i = 0; i<n; i++) pj[i] *= rnm2;
+  }
+
+  private int lanczos_step(SparseMatrix A, int first, int last,int[] ll_,   
+          boolean[] enough_, double[] rnm_tol_, int n) throws SparseSVDException {
+    /*   embodies a single Lanczos step
+    Arguments 
+    (input)
+    n        dimension of the eigenproblem for matrix B
+    first    start of index through loop				      
+    last     end of index through loop				     
+    wptr	    array of pointers pointing to work space		    
+    alf	    array to hold diagonal of the tridiagonal matrix T
+    eta      orthogonality estimate of Lanczos vectors at step j   
+    oldeta   orthogonality estimate of Lanczos vectors at step j-1
+    bet      array to hold off-diagonal of T                     
+    ll       number of intitial Lanczos vectors in local orthog. 
+    (has value of 0, 1 or 2)			
+    enough   stop flag			
+     */
+    int j;
+    double t;
+    double mid[];
+    for (j = first; j<last; j++) {
+      mid = qj1;
+      qj1 = qj;
+      qj = mid;
+      mid = pj;
+      pj = pj1;
+      pj1 = mid;
+      storage.storeQ(n, j-1, qj1);
+      if (j-1<MAXLL) storage.storeP(n, j-1, pj1);
+      bet[j] = rnm_tol_[0];
+
+      // restart if invariant subspace is found 
+      if (bet[j]==0) {
+        rnm_tol_[0] = startv(A, j, n);
+        if (rnm_tol_[0]==0) enough_[0] = true;
+      }
+      if (enough_[0]) {
+        /* added by Doug... */
+        /* These lines fix a bug that occurs with low-rank matrices */
+        mid = qj1;
+        qj1 = qj;
+        qj = mid;
+        /* ...added by Doug */
+        break;
+      }
+      /* take a lanczos step */
+      t = 1.0/rnm_tol_[0];
+      for (int i = 0; i<n; i++) qj[i] = t*rj[i];
+      for (int i = 0; i<n; i++) pj[i] *= t;
+      A.opb(pj, rj);
+      for (int i = 0; i<n; i++) rj[i] -= rnm_tol_[0]*qj1[i];
+      alph[j] = DoubleArraysPlus.dot(rj, pj);
+      for (int i = 0; i<n; i++) rj[i] -= alph[j]*qj[i];
+      /* orthogonalize against initial lanczos vectors */
+      if (j<=MAXLL&&(Math.abs(alph[j-1])>4.0*Math.abs(alph[j])))
+        ll_[0] = j;
+      for (int i = 0; i<Math.min(ll_[0], j-1); i++) {
+        storage.retrieveP(n, i, wk);
+        t = DoubleArraysPlus.dot(wk, rj);
+        storage.retrieveQ(n, i, wk);
+        for (int ii = 0; ii<n; ii++) rj[ii] -= t*wk[ii];
+        oldeta[i] = eta[i] = EPS1;
+      }
+      /* extended local reorthogonalization */
+      t = DoubleArraysPlus.dot(rj, pj1);
+      for (int i = 0; i<n; i++) rj[i] -= t*qj1[i];
+      if (bet[j]>0) bet[j] += t;
+      t = DoubleArraysPlus.dot(rj, pj);
+      for (int i = 0; i<n; i++) rj[i] -= t*qj[i];
+      alph[j] += t;
+      System.arraycopy(rj, 0, pj1, 0, n);
+      rnm_tol_[0] = Math.sqrt(DoubleArraysPlus.dot(rj, pj1));
+      rnm_tol_[1] = RAD_EPS*(bet[j]+Math.abs(alph[j])+rnm_tol_[0]);
+      /* update the orthogonality bounds */
+      ortbnd(j, rnm_tol_[0]);
+      /* restore the orthogonality state when needed */
+      purge(n, ll_[0], j, rnm_tol_);
+      if (rnm_tol_[0]<=rnm_tol_[1]) rnm_tol_[0] = 0;
+    }
+    return j;
+  }
+
+  private double startv(SparseMatrix A, int step, int n)
+          throws SparseSVDException {
+    /* startv delivers a starting vector in r and returns |r|; it returns 
+    zero if the range is spanned, and throws a SparseSVDException(-1) if no starting 
+    vector within range of operator can be found.
+    Parameters 
+    (input)
+    n      dimension of the eigenproblem matrix B
+    wptr   array of pointers that point to work space
+    step      starting index for a Lanczos run
+    (output)
+    wptr   array of pointers that point to work space that contains
+    r[j], q[j], q[j-1], p[j], p[j-1]
+     */
+// get initial vector; default is random
+    double rnm2 = DoubleArraysPlus.dot(rj, rj);
+    Random random = new Random(918273+step);
+    for (int id = 0; id<3; id++) {
+      for (int i = 0; i<n; i++) rj[i] = random.nextDouble();
+      System.arraycopy(rj, 0, pj, 0, n);
+      // apply operator to put r in range (essential if m singular)
+      A.opb(pj, rj);
+      System.arraycopy(rj, 0, pj, 0, n);
+      rnm2 = DoubleArraysPlus.dot(rj, pj);
+      if (rnm2>0) break;
+    }
+    if (rnm2<=0) throw new SparseSVDException(CodeSVDException.FIRST_STEP_FAILURE, 0);
+    double t;
+    for (int j = 0; j<step; j++) {
+      storage.retrieveQ(n, j, wk);
+      t = -DoubleArraysPlus.dot(pj, wk);
+      for (int i = 0; i<n; i++) rj[i] += t*wk[i];
+    }
+    // make sure q[step] is orthogonal to q[step-1] 
+    t = DoubleArraysPlus.dot(pj1, rj);
+    for (int i = 0; i<n; i++) rj[i] -= t*qj1[i];
+    System.arraycopy(rj, 0, pj, 0, n);
+    t = DoubleArraysPlus.dot(pj, rj);
+    if (t<=EPS*rnm2) rnm2 = 0;
+    else rnm2 = t;
+    return Math.sqrt(rnm2);
+  }
+
+  private void ortbnd(int step, double rnm) {
+    /*  updates the eta recurrence
+    Arguments 
+    (input)
+    alf      array to hold diagonal of the tridiagonal matrix T         
+    eta      orthogonality estimate of Lanczos vectors at step j        
+    oldeta   orthogonality estimate of Lanczos vectors at step j-1     
+    bet      array to hold off-diagonal of T                          
+    n        dimension of the eigenproblem for matrix B		    
+    j        dimension of T					  
+    rnm	    norm of the next residual vector			 
+    eps1	    roundoff estimate for dot product of two unit vectors
+    (output)
+    eta      orthogonality estimate of Lanczos vectors at step j+1     
+    oldeta   orthogonality estimate of Lanczos vectors at step j        
+     */
+    if (step<1) return;
+    if (rnm!=0) {
+      if (step>1)
+        oldeta[0] = (bet[1]*eta[1]+(alph[0]-alph[step])*eta[0]
+                -bet[step]*oldeta[0])/rnm+EPS1;
+      for (int i = 1; i<=step-2; i++)
+        oldeta[i] = (bet[i+1]*eta[i+1]+(alph[i]-alph[step])*eta[i]
+                +bet[i]*eta[i-1]-bet[step]*oldeta[i])/rnm+EPS1;
+    }
+    oldeta[step-1] = EPS1;
+    double t;
+    for (int i = 0; i<step; i++) {
+      t = oldeta[i];
+      oldeta[i] = eta[i];
+      eta[i] = t;
+    }
+    eta[step] = EPS1;
+  }
+
+  private void purge(int n, int ll, int step, double[] rnm_tol_) {
+    /*
+    purge examines the state of orthogonality between the new Lanczos
+    vector and the previous ones to decide whether re-orthogonalization 
+    should be performed
+    Arguments 
+    (input)
+    n        dimension of the eigenproblem for matrix B		       
+    ll       number of intitial Lanczos vectors in local orthog.       
+    r        residual vector to become next Lanczos vector            
+    q        current Lanczos vector			           
+    ra       previous Lanczos vector
+    qa       previous Lanczos vector
+    wrk      temporary vector to hold the previous Lanczos vector
+    eta      state of orthogonality between r and prev. Lanczos vectors 
+    oldeta   state of orthogonality between q and prev. Lanczos vectors
+    j        current Lanczos step				     
+    (output)
+    r	    residual vector orthogonalized against previous Lanczos 
+    vectors
+    q        current Lanczos vector orthogonalized against previous ones    
+     */
+    if (step<ll+2) return;
+    int k = DoubleArraysPlus.indAbsMax(step-(ll+1), eta, ll);
+    if (Math.abs(eta[k])<=RAD_EPS) return;
+    double REPS1 = EPS1/RAD_EPS;
+    double t;
+    for (int iteration = 0; iteration<2; iteration++) {
+      if (rnm_tol_[0]<=rnm_tol_[1]) break;
+      /* bring in a lanczos vector t and orthogonalize both 
+       * r and q against it */
+      double tq = 0;
+      double tr = 0;
+      for (int i = ll; i<step; i++) {
+        storage.retrieveQ(n, i, wk);
+        t = -DoubleArraysPlus.dot(pj, wk);
+        tq += Math.abs(t);
+        for (int ii = 0; ii<n; ii++) qj[ii] += t*wk[ii];
+        t = -DoubleArraysPlus.dot(pj1, wk);
+        tr += Math.abs(t);
+        for (int ii = 0; ii<n; ii++) rj[ii] += t*wk[ii];
+      }
+      System.arraycopy(qj, 0, pj, 0, n);
+      t = -DoubleArraysPlus.dot(rj, pj);
+      tr += Math.abs(t);
+      for (int i = 0; i<n; i++) rj[i] += t*qj[i];
+      System.arraycopy(rj, 0, pj1, 0, n);
+      rnm_tol_[0] = Math.sqrt(DoubleArraysPlus.dot(pj1, rj));
+      if (tq<=REPS1&&tr<=REPS1*rnm_tol_[0]) break;
+    }
+    for (int i = ll; i<=step; i++) {
+      eta[i] = EPS1;
+      oldeta[i] = EPS1;
+    }
+  }
+
+  private static void imtqlb(int n, int i0, double[] d, double[] e, double[] bnd)
+          throws SparseSVDException {
+    /*   imtqlb() finds the eigenvalues of a symmetric tridiagonal
+    matrix by the implicit QL method.
+    Arguments 
+    (input)
+    n      order of the symmetric tridiagonal matrix   
+    d      contains the diagonal elements of the input matrix           
+    e      contains the subdiagonal elements of the input matrix in its
+    last n-1 positions.  e[0] is arbitrary
+    i0   starting index for the 3 vectors
+    (elements with index < i0 or >= i0+n are preserved)
+    (output)
+    d      contains the eigenvalues in ascending order.  if an error
+    exit is made, the eigenvalues are correct and ordered for
+    indices 0,1,...ierr, but may not be the smallest eigenvalues.
+    e      has been destroyed.					    
+    throws a SparseSVDException(j) if the j-th eigenvalue has
+    not been determined after 30 iterations.		    
+     */
+    if (n==1) return;
+    bnd[i0] = 1;
+    for (int i = i0+1; i<i0+n; i++) {
+      bnd[i] = 0;
+      e[i-1] = e[i];
+    }
+    e[i0+n-1] = 0;
+    for (int l = i0; l<i0+n; l++) {
+      for (int iteration = 0; iteration<=30; iteration++) {
+        double p = d[l];
+        double f = bnd[l];
+        int m;
+        for (m = l; m<i0+n-1; m++) { // test de convergence
+          double test = Math.abs(d[m])+Math.abs(d[m+1]);
+          if (test+Math.abs(e[m])==test) break;
+        }
+        if (m==l) {
+          d[l] = p;
+          bnd[l] = f;
+          /* order the eigenvalues */
+          DoubleArraysPlus.sort2(d, bnd, l-i0+1, i0);
+          break;
+        } else {
+          if (iteration==30) throw new SparseSVDException(CodeSVDException.CONVERGENCE_FAILURE, l);
+          /*........ form shift ........*/
+          double g = (d[l+1]-p)/(2.0*e[l]);
+          double r = Math.hypot(g, 1);
+          g = d[m]-p+e[l]/(g+Math.copySign(r, g));
+          double s = 1;
+          double c = 1;
+          p = 0;
+          boolean underflow = false;
+          for (int i = m-1; i>=l; i--) {
+            f = s*e[i];
+            double b = c*e[i];
+            r = Math.hypot(f, g);
+            e[i+1] = r;
+            if (r==0) {
+              /*........ recover from underflow .........*/
+              underflow = true;
+              d[i+1] -= p;
+              e[m] = 0.0;
+              break;
+            }
+            s = f/r;
+            c = g/r;
+            g = d[i+1]-p;
+            r = (d[i]-g)*s+2*c*b;
+            p = s*r;
+            d[i+1] = g+p;
+            g = c*r-b;
+            f = bnd[i+1];
+            bnd[i+1] = s*bnd[i]+c*f;
+            bnd[i] = c*bnd[i]-s*f;
+          }
+
+          if (!underflow) {
+            d[l] -= p;
+            e[l] = g;
+            e[m] = 0.0;
+          }
+        }
+      }
+    }
+  }
+
+  private int error_bound(boolean[] enough_, double endl, double endr,
+          int step, double tol) {
+    /*
+    massages error bounds for very close ritz values by placing 
+    a gap between them.  The error bounds are then refined to reflect this.
+    Arguments 
+    (input)
+    endl     left end of interval containing unwanted eigenvalues
+    endr     right end of interval containing unwanted eigenvalues
+    ritz     array to store the ritz values
+    bnd      array to store the error bounds
+    enough   stop flag
+     */
+    int mid = DoubleArraysPlus.indAbsMax(step+1, bnd, 1);
+
+    for (int i = step; i>mid; i--)
+      if (Math.abs(ritz[i-1]-ritz[i])<RAD34_EPS*Math.abs(ritz[i]))
+        if (bnd[i]>tol&&bnd[i-1]>tol) {
+          bnd[i-1] = Math.hypot(bnd[i], bnd[i-1]);
+          bnd[i] = 0;
+        }
+    for (int i = 1; i<mid; i++)
+      if (Math.abs(ritz[i+1]-ritz[i])<RAD34_EPS*Math.abs(ritz[i]))
+        if (bnd[i]>tol&&bnd[i+1]>tol) {
+          bnd[i+1] = Math.hypot(bnd[i], bnd[i+1]);
+          bnd[i] = 0.0;
+        }
+    /* refine the error bounds */
+    int neig = 0;
+    double gapl = ritz[step]-ritz[0];
+    for (int i = 0; i<=step; i++) {
+      double gap = gapl;
+      if (i<step) gapl = ritz[i+1]-ritz[i];
+      gap = Math.min(gap, gapl);
+      if (gap>bnd[i]) bnd[i] *= (bnd[i]/gap);
+      if (bnd[i]<=16.0*EPS*Math.abs(ritz[i])) {
+        neig++;
+        if (!enough_[0]) enough_[0] = endl<ritz[i]&&ritz[i]<endr;
+      }
+    }
+    return neig;
+  }
+
+  private int ritvec0(SparseMatrix A, int[] steps_neig_) throws SparseSVDException {
+
+    int js, jsq, i, k, /*size,*/ id2, tmp, nsig, x;
+    double[] s, xv2;
+    double tmp0, tmp1, xnorm;
+    double[] w1 = Vt[0];
+    double[] w2 = new double[cols];
+
+    js = steps_neig_[0]+1;
+    jsq = js*js;
+    /*size = sizeof(double) * n;*/
+
+    s = new double[jsq];
+    xv2 = new double[cols];
+
+    /* initialize s to an identity matrix */
+    for (i = 0; i<jsq; i += (js+1)) s[i] = 1.0;
+    DoubleArraysPlus.copyReverse(js, alph, 0, w1, 0);
+    DoubleArraysPlus.copyReverse(steps_neig_[0], bet, 1, w2, 1);
+
+    /* on return from imtql2(), w1 contains eigenvalues in ascending 
+     * order and s contains the corresponding eigenvectors */
+    double[][] z = new double[js][js];
+    for (int r = 0; r<js; r++) for (int c = 0; c<js; c++) z[r][c] = s[r*js+c];
+    imtql2(js, js, w1, w2, z);
+    for (int r = 0; r<js; r++) for (int c = 0; c<js; c++) s[r*js+c] = z[r][c];
+
+
+    /*fwrite((char *)&n, sizeof(n), 1, fp_out2);
+    fwrite((char *)&js, sizeof(js), 1, fp_out2);
+    fwrite((char *)&kappa, sizeof(kappa), 1, fp_out2);*/
+    /*id = 0;*/
+    nsig = 0;
+    x = 0;
+    id2 = jsq-js;
+    for (k = 0; k<js; k++) {
+      tmp = id2;
+      if (bnd[k]<=KAPPA*Math.abs(ritz[k])&&k>js-steps_neig_[1]-1) {
+        if (--x<0) x = dim-1;
+        w1 = Vt[x];
+        for (i = 0; i<cols; i++) w1[i] = 0.0;
+        for (i = 0; i<js; i++) {
+          storage.retrieveQ(cols, i, w2);
+          for (int ii = 0; ii<cols; ii++) w1[ii] += s[tmp]*w2[ii];
+          tmp -= js;
+        }
+        /*fwrite((char *)w1, size, 1, fp_out2);*/
+
+        /* store the w1 vector row-wise in array xv1;   
+         * size of xv1 is (steps+1) * (nrow+ncol) elements 
+         * and each vector, even though only ncol long,
+         * will have (nrow+ncol) elements in xv1.      
+         * It is as if xv1 is a 2-d array (steps+1) by     
+         * (nrow+ncol) and each vector occupies a row  */
+
+        /* j is the index in the R arrays, which are sorted by high to low 
+        singular values. */
+
+        /*for (i = 0; i < n; i++) R->Vt->value[x]xv1[id++] = w1[i];*/
+        /*id += nrow;*/
+        nsig++;
+      }
+      id2++;
+    }
+    s = null;
+
+    /* Rotate the singular vectors and values. */
+    /* x is now the location of the highest singular value. */
+    DoubleArraysPlus.rotateArray(Vt, x);
+    dim = Math.min(dim, nsig);
+    for (x = 0; x<dim; x++) {
+      /* multiply by matrix B first */
+      A.opb(Vt[x], xv2);
+      tmp0 = DoubleArraysPlus.dot(Vt[x], xv2);
+      for (int ii = 0; ii<cols; ii++) xv2[ii] -= tmp0*Vt[x][ii];
+      tmp0 = Math.sqrt(tmp0);
+      xnorm = Math.sqrt(DoubleArraysPlus.dot(xv2, xv2));
+
+      /* multiply by matrix A to get (scaled) left s-vector */
+      A.opa(Vt[x], Ut[x]);
+      tmp1 = 1.0/tmp0;
+      for (int ii = 0; ii<rows; ii++) Ut[x][ii] *= tmp1;
+      xnorm *= tmp1;
+      bnd[i] = xnorm;
+      S[x] = tmp0;
+    }
+
+    xv2 = w2 = null;
+    return nsig;
+    /* multiply by matrix A to get (scaled) left s-vector */
+
+  }
+
+  private int ritvec(SparseMatrix A, int[] steps_neig_) throws SparseSVDException {
+    //  computes the singular vectors of matrix A	       *
+/*  Parameters
+    (input)
+    nrow       number of rows of A
+    steps      number of Lanczos iterations performed
+    fp_out2    pointer to unformatted output file
+    n	      dimension of matrix A
+    kappa      relative accuracy of ritz values acceptable as 
+    eigenvalues of A'A
+    ritz       array of ritz values
+    bnd        array of error bounds
+    alf        array of diagonal elements of the tridiagonal matrix T
+    bet        array of off-diagonal elements of T
+    w1, w2     work space
+    (output)
+    xv1        array of eigenvectors of A'A (right singular vectors of A)
+    ierr	      error code
+    0 for normal return from imtql2()
+    k if convergence did not occur for k-th eigenvalue in
+    imtql2()
+    nsig       number of accepted ritz values based on kappa
+    (local)
+    s	      work array which is initialized to the identity matrix
+    of order (j + 1) upon calling imtql2().  After the call,
+    s contains the orthonormal eigenvectors of the symmetric 
+    tridiagonal matrix T
+     */
+    // int n = cols;
+
+    double[] w1 = Vt[0];
+    double[] w2 = new double[cols];
+    int js = steps_neig_[0]+1;
+    double[][] s = new double[js][js];
+    double[] xv2 = new double[cols];
+    /* initialize s to an identity matrix */
+    for (int i = 0; i<js; i++) s[i][i] = 1;
+    DoubleArraysPlus.copyReverse(js, alph, 0, w1, 0);
+    DoubleArraysPlus.copyReverse(steps_neig_[0], bet, 1, w2, 1);
+    /* on return from imtql2(), w1 contains eigenvalues in ascending 
+     * order and s contains the corresponding eigenvectors */
+    imtql2(js, js, w1, w2, s);
+    int nsig = 0;
+    int x = 0;
+    for (int k = 0; k<js; k++) {
+      if (bnd[k]<=KAPPA*Math.abs(ritz[k])&&k>js-steps_neig_[1]-1) {
+        if (--x<0) x = dim-1;
+        w1 = Vt[x];
+        for (int i = 0; i<cols; i++) w1[i] = 0;
+        for (int i = 0; i<js; i++) {
+          storage.retrieveQ(cols, i, w2);
+          for (int ii = 0; ii<cols; ii++) w1[ii] += s[k][js-1-i]*w2[ii];
+        }
+        /*fwrite((char *)w1, size, 1, fp_out2);*/
+
+        /* store the w1 vector row-wise in array xv1;   
+         * size of xv1 is (steps+1) * (nrow+ncol) elements 
+         * and each vector, even though only ncol long,
+         * will have (nrow+ncol) elements in xv1.      
+         * It is as if xv1 is a 2-d array (steps+1) by     
+         * (nrow+ncol) and each vector occupies a row  */
+
+        /* j is the index in the R arrays, which are sorted by high to low 
+        singular values. */
+
+        /*for (i = 0; i < n; i++) R->Vt->value[x]xv1[id++] = w1[i];*/
+        /*id += nrow;*/
+        nsig++;
+      }
+    }
+    s = null;  // libère la mémoire
+  /* Rotate the singular vectors and values. */
+    /* x is now the location of the highest singular value. */
+    DoubleArraysPlus.rotateArray(Vt, x);
+    int d = Math.min(dim, nsig);
+    for (x = 0; x<d; x++) {
+      /* multiply by matrix B first */
+      A.opb(Vt[x], xv2);
+      double tmp0 = DoubleArraysPlus.dot(Vt[x], xv2);
+      for (int i = 0; i<cols; i++) xv2[i] -= tmp0*Vt[x][i];
+      tmp0 = Math.sqrt(tmp0);
+      double xnorm = Math.sqrt(DoubleArraysPlus.dot(xv2, xv2));
+      /* multiply by matrix A to get (scaled) left s-vector */
+      A.opa(Vt[x], Ut[x]);
+      double tmp1 = 1/tmp0;
+      for (int i = 0; i<rows; i++) Ut[x][i] *= tmp1;
+      xnorm *= tmp1;
+      //   bnd[i] = xnorm; bizarre ??
+      S[x] = tmp0;
+    }
+    xv2 = w2 = null;
+    return nsig;
+  }
+
+  private static void imtql2(int nm, int n, double d[], double[] e, double[][] z)
+          throws SparseSVDException {
+    /*   imtqlb() finds the eigenvalues  and eigenvectors of a symmetric tridiagonal
+    matrix by the implicit QL method.
+    Arguments 
+    (input)
+    nm     row dimension of the symmetric tridiagonal matrix   
+    n      order of the symmetric tridiagonal matrix   
+    d      contains the diagonal elements of the input matrix           
+    e      contains the subdiagonal elements of the input matrix in its
+    last n-1 positions.  e[0] is arbitrary
+    z      contains the identity matrix
+    (output)
+    d      contains the eigenvalues in ascending order.  if an error
+    exit is made, the eigenvalues are correct but unordered for
+    indices 0,1,...ierr.
+    e      has been destroyed.					    
+    z      contains orthonormal eigenvectors of the symmetric   
+    tridiagonal (or full) matrix.  if an error exit is made,
+    z contains the eigenvectors associated with the stored 
+    eigenvalues.					
+    throws a SparseSVDException(j) if the j-th eigenvalue has
+    not been determined after 30 iterations.		    
+     */
+    if (n==1) return;
+    for (int i = 1; i<n; i++) e[i-1] = e[i];
+    e[n-1] = 0.0;
+    int nnm = n*nm;
+    for (int l = 0; l<n; l++) {
+      /* look for small sub-diagonal element */
+      for (int iteration = 0; iteration<=30; iteration++) {
+        double p = d[l];
+        int m;
+        for (m = l; m<n-1; m++) {// test de convergence
+          double test = Math.abs(d[m])+Math.abs(d[m+1]);
+          if (test+Math.abs(e[m])==test) break;
+        }
+        if (m==l) break;
+        /* set error -- no convergence to an eigenvalue after
+         * 30 iterations. */
+        if (iteration==30) throw new SparseSVDException(CodeSVDException.CONVERGENCE_FAILURE, l);
+        /* form shift */
+        double g = (d[l+1]-p)/(2*e[l]);
+        double r = Math.hypot(g, 1);
+        g = d[m]-p+e[l]/(g+Math.copySign(r, g));
+        double s = 1;
+        double c = 1;
+        p = 0;
+        boolean underflow = false;
+        for (int i = m-1; i>=l; i--) {
+          double f = s*e[i];
+          double b = c*e[i];
+          r = Math.hypot(f, g);
+          e[i+1] = r;
+          if (r==0) {
+            /*........ recover from underflow .........*/
+            underflow = true;
+            d[i+1] -= p;
+            e[m] = 0.0;
+            break;
+          }
+          s = f/r;
+          c = g/r;
+          g = d[i+1]-p;
+          r = (d[i]-g)*s+2*c*b;
+          p = s*r;
+          d[i+1] = g+p;
+          g = c*r-b;
+          /* form vector */
+          for (int k = 0; k<nm; k++) {
+            f = z[i+1][k];
+            z[i+1][k] = s*z[i][k]+c*f;
+            z[i][k] = c*z[i][k]-s*f;
+          }
+        }
+        if (!underflow) {
+          d[l] -= p;
+          e[l] = g;
+          e[m] = 0.0;
+        }
+      }
+    }
+    /* order the eigenvalues and corresponding eigenvectors */
+    DoubleArraysPlus.sort2(d, z, n, 0);
+  }
+
+  /* ------------------------
+  Public Methods
+   * ------------------------ */
+  /** Return the left singular vectors
+  @return     U
+   */
+  public Matrix getU() {
+    return transpose ? (new Matrix(Vt, dim, cols)).transpose()
+            : (new Matrix(Ut, dim, rows)).transpose();
+  }
+
+  /** Return the right singular vectors
+  @return     V
+   */
+  public Matrix getV() {
+    return transpose ? (new Matrix(Ut, dim, rows)).transpose()
+            : (new Matrix(Vt, dim, cols)).transpose();
+  }
+
+  /** Return the one-dimensional array of singular values
+  @return     diagonal of S.
+   */
+  public double[] getSingularValues() {
+    return Arrays.copyOfRange(S, 0, dim);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src/JamaPlus/SparseSVD.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/bin/org/eclipse/jface/fieldassist/TXMAutoCompleteField$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/eclipse/jface/fieldassist/TXMAutoCompleteField$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/eclipse/jface/fieldassist/TXMContentProposalAdapter.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/eclipse/jface/fieldassist/TXMContentProposalAdapter.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/eclipse/jface/fieldassist/TXMAutoCompleteField.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/eclipse/jface/fieldassist/TXMAutoCompleteField.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesMacro$_run_closure4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesMacro$_run_closure4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesInSchemaMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesInSchemaMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/AllMesuresMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/AllMesuresMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CategorieGrammaticaleMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CategorieGrammaticaleMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/ChainesMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/ChainesMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CategorieGrammaticaleMacro$_run_closure2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CategorieGrammaticaleMacro$_run_closure2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/PremierMaillonMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/PremierMaillonMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/ChainesMacro$_run_closure2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/ChainesMacro$_run_closure2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CompUnitPropertiesMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CompUnitPropertiesMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/ConcordanceToUnitMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/ConcordanceToUnitMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Fropos2CategorieMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Fropos2CategorieMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Fropos2CategorieMacro$_run_closure2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Fropos2CategorieMacro$_run_closure2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CreationRelationsMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CreationRelationsMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/SchemaTypesMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/SchemaTypesMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/NombreDeChainesMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/NombreDeChainesMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/DistanceInterMaillonnaireMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/DistanceInterMaillonnaireMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/AjoutDefinitudeMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/AjoutDefinitudeMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/NatureDuPremierMaillonMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/NatureDuPremierMaillonMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/NatureDuPremierMaillonMacro$_run_closure2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/NatureDuPremierMaillonMacro$_run_closure2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Frpos2CategorieMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Frpos2CategorieMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/AllMesuresMacro$_run_closure1_closure2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/AllMesuresMacro$_run_closure1_closure2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/ResetAnnotationsMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/ResetAnnotationsMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesNotInSchemaMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesNotInSchemaMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CreationChainesMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CreationChainesMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitsMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitsMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CheckAnnotationStructureValuesMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CheckAnnotationStructureValuesMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CategorieGrammaticaleMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CategorieGrammaticaleMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/ChainesMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/ChainesMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CompUnitPropertiesMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CompUnitPropertiesMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Fropos2CategorieMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Fropos2CategorieMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CoefficientStabiliteMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CoefficientStabiliteMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/AllMesuresMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/AllMesuresMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesInSchemaMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesInSchemaMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$_run_closure2_closure5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$_run_closure2_closure5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesInSchemaMacro$_run_closure2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesInSchemaMacro$_run_closure2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/AjoutDefinitudeMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/AjoutDefinitudeMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesInSchemaMacro$_run_closure3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesInSchemaMacro$_run_closure3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesInSchemaMacro$_run_closure4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesInSchemaMacro$_run_closure4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/PremierMaillonMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/PremierMaillonMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/NatureDuPremierMaillonMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/NatureDuPremierMaillonMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CreationRelationsMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CreationRelationsMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/SchemaTypesMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/SchemaTypesMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/SchemaTypesMacro$_run_closure2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/SchemaTypesMacro$_run_closure2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/DistanceInterMaillonnaireMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/DistanceInterMaillonnaireMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesNotInSchemaMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesNotInSchemaMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CreationChainesMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/CreationChainesMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/RelationsMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/RelationsMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$_run_closure2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$_run_closure2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/DensiteReferentielleMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/DensiteReferentielleMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitsMacro.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitsMacro.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$_run_closure3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$_run_closure3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$_run_closure4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/LongueurMoyenneMacro$_run_closure4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Frpos2CategorieMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Frpos2CategorieMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Frpos2CategorieMacro$_run_closure2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/Frpos2CategorieMacro$_run_closure2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesMacro$_run_closure1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesMacro$_run_closure1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesMacro$_run_closure2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesMacro$_run_closure2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesMacro$_run_closure3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/macro/analec/UnitTypesMacro$_run_closure3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$10.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$10.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$6.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$6.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$11$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$11$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/AnnotationToolbar.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/AnnotationToolbar.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$7.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$7.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$8.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$8.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$9.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$9.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$8$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$8$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$10.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$10.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$11.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$11.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$12.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$12.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$13.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/UnitToolbar$13.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$6.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$6.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$7.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$7.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$8.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$8.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$9.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbar/SchemaToolbar$9.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/DropDownButton$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/DropDownButton$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/NavigationField.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/NavigationField.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/TextItem.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/TextItem.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/DropDownButton.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/DropDownButton.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/NavigationField$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/NavigationField$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/NavigationField$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/NavigationField$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/NavigationField$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/NavigationField$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/NavigationField$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/NavigationField$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/DropDownButton$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/widgets/DropDownButton$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/AnalecAnnotationReIndexer.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/AnalecAnnotationReIndexer.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/testers/IsCorpusAnnotated.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/testers/IsCorpusAnnotated.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$6.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$6.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$7.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$7.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$8.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$8.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$6.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$6.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$7.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$7.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$1$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementPropertiesView$1$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$1$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/view/ElementSearchView$1$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/AnalecAnnotationReIndexer$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/AnalecAnnotationReIndexer$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/AnalecCorpora.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/AnalecCorpora.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$3$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$3$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$4$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$4$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$1$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$1$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$3$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/toolbarbutton/StartButton$3$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ExportGlozzCorpus.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ExportGlozzCorpus.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/EditStructure.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/EditStructure.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportTEICorpus.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportTEICorpus.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/SaveStructureAsGlozzModel.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/SaveStructureAsGlozzModel.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/LoadStructureFromGlozz.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/LoadStructureFromGlozz.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/LoadCorpus.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/LoadCorpus.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/SaveVue.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/SaveVue.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportGlozzAnnotations.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportGlozzAnnotations.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/SaveStructure.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/SaveStructure.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/SaveCorpus$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/SaveCorpus$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ExportTEICorpus.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ExportTEICorpus.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportGlozzCorpus$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportGlozzCorpus$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportGlozzCorpus$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportGlozzCorpus$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportGlozzCorpus$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportGlozzCorpus$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/DoInstallStep.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/DoInstallStep.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/SaveCorpus.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/SaveCorpus.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/EditStructure$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/EditStructure$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportGlozzCorpus.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportGlozzCorpus.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportTEICorpus$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/ImportTEICorpus$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/LoadVue.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/LoadVue.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/LoadStructure.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/commands/LoadStructure.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/preferences/AnalecPreferencePage.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/preferences/AnalecPreferencePage.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/org/txm/analec/preferences/AnalecPreferences.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/org/txm/analec/preferences/AnalecPreferences.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/analecrcp/Activator.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/analecrcp/Activator.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesRelations$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesRelations$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$7.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$7.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesRelations$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesRelations$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersCoNLL.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersCoNLL.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$TEIHandler$Balise.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$TEIHandler$Balise.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGraphique$CercleColore.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGraphique$CercleColore.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersJava.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersJava.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$SaisieInfos.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$SaisieInfos.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$ModeleGlozzHandler.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$ModeleGlozzHandler.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$ModelGlozzPrinter.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$ModelGlozzPrinter.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersSyntex.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersSyntex.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTexte$HTMLWriterCorrige.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTexte$HTMLWriterCorrige.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersCoNLL$CoNLLParser$CoNLLException.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersCoNLL$CoNLLParser$CoNLLException.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/ProgressMonitorDemo$Task.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/ProgressMonitorDemo$Task.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$GlozzHandler.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$GlozzHandler.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTableur.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTableur.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTableur$ExcelParser.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTableur$ExcelParser.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGraphique$GraphiqueExport.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGraphique$GraphiqueExport.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$GlozzPrinter.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$GlozzPrinter.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTexte$FiltreCorrectionRTFOutputStream.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTexte$FiltreCorrectionRTFOutputStream.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/ProgressMonitorDemo.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/ProgressMonitorDemo.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersJava$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersJava$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$ModeleGlozzHandler$Balise.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$ModeleGlozzHandler$Balise.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$SaisieInfos$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$SaisieInfos$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersJava$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersJava$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$SaisieInfos$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$SaisieInfos$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersCoNLL$CoNLLParser.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersCoNLL$CoNLLParser.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$GlozzHandler$Balise.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$GlozzHandler$Balise.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$TEIPrinter$Delimiteur.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$TEIPrinter$Delimiteur.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGraphique.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGraphique.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$TEIHandler.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$TEIHandler.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersSyntex$SyntexParser.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersSyntex$SyntexParser.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/ProgressMonitorDemo$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/ProgressMonitorDemo$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTexte.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTexte.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersGlozz$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$TEIPrinter.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/fichiers/FichiersTEI$TEIPrinter.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$9.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$9.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$TypeModifVue.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$TypeModifVue.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesUnites$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesUnites$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$21.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$21.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$40.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$40.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$23.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$23.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$42.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$42.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$25.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$25.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$44.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$44.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$27.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$27.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$46.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$46.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$29.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$29.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$48.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$48.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$TypeModifElement.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$TypeModifElement.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauModifTexte$BorneUnite.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauModifTexte$BorneUnite.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauModifTexte.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauModifTexte.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/VisuStyleTexte.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/VisuStyleTexte.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauOccurrences.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauOccurrences.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauTexte$UniteColoree.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauTexte$UniteColoree.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$ListenerSourisTexte$EtatClic.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$ListenerSourisTexte$EtatClic.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauTexte$Marquage.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauTexte$Marquage.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$SourisEvent.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$SourisEvent.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauTexte$TypeMarquage.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauTexte$TypeMarquage.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauTexte$Coloriage.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauTexte$Coloriage.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauOccurrences$ModeleTableur.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauOccurrences$ModeleTableur.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauCommandesModifTexte$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauCommandesModifTexte$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$JPopupMenuUnites$ActionSelectionUnites.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$JPopupMenuUnites$ActionSelectionUnites.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$JPopupMenuUnites.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$JPopupMenuUnites.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauCommandesModifTexte$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauCommandesModifTexte$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauOccurrences$ModeleTableauOcc.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauOccurrences$ModeleTableauOcc.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauTexte.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauTexte.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$SourisEvent$TypeEvent.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$SourisEvent$TypeEvent.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffChainesTexte$ListenerSourisTexte.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffChainesTexte$ListenerSourisTexte.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauModifTexte$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauModifTexte$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/VisuStyleTexte$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/VisuStyleTexte$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauCommandesModifTexte.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauCommandesModifTexte.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$ListenerSourisTexte.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffTexte$ListenerSourisTexte.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/VisuStyleTexte$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/VisuStyleTexte$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/VisuStyleTexte$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/VisuStyleTexte$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffChainesTexte.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/texte/PanneauAffChainesTexte.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$TypeModifStructure.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$TypeModifStructure.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$11.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$11.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$30.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$30.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$13.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$13.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$Commandes.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$Commandes.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$ElementEvent.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$ElementEvent.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$32.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$32.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$15.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$15.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesUnites.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesUnites.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$34.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$34.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$17.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$17.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/elements/Unite.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/elements/Unite.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/elements/Element.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/elements/Element.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/elements/Relation.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/elements/Relation.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/elements/Schema.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/elements/Schema.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$36.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$36.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$GCodage.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$GCodage.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$Boutons.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$Boutons.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$FilesystemFilter.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$FilesystemFilter.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$LegendeCellRenderer.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$LegendeCellRenderer.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$Val0ComboBox.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$Val0ComboBox.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GMessages.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GMessages.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$LegendeModeleTable.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$LegendeModeleTable.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$TitreBarre.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$TitreBarre.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GMessages$GAction.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GMessages$GAction.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$FiltreExt.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$FiltreExt.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$DisqueCouleurIcone.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$DisqueCouleurIcone.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$ElementComboBox$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$ElementComboBox$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CarreCouleurIcone.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CarreCouleurIcone.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$TypeComboBox.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$TypeComboBox.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$TypeFichier.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$TypeFichier.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GMessages$GActionClavier.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GMessages$GActionClavier.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$LegendeModeleTableTexte.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$LegendeModeleTableTexte.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$TriangleinverseCouleurIcone.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$TriangleinverseCouleurIcone.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Tableaux.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Tableaux.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GMessages$GProgression$MiseAJour.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GMessages$GProgression$MiseAJour.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CouleurTableEditor.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CouleurTableEditor.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$ModeleSpinnerBinaire.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$ModeleSpinnerBinaire.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$SensSpinnerBinaire.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$SensSpinnerBinaire.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CroixCouleurIcone.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CroixCouleurIcone.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GMessages$GProgression.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GMessages$GProgression.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$LegendeLabel.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$LegendeLabel.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CouleurCellRenderer.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CouleurCellRenderer.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CouleurComboBox.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CouleurComboBox.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CouleurComboBoxEditor.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$CouleurComboBoxEditor.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$RectangleCouleurIcone.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$RectangleCouleurIcone.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$TriangleCouleurIcone.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$TriangleCouleurIcone.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$ElementComboBox.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/GVisu$ElementComboBox.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$Commande.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$Commande.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$SelectFics.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/util/Fichiers$SelectFics.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$19.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$19.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$38.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$38.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesRelations$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesRelations$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$6.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$6.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesRelations$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesRelations$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$8.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$8.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ActionRenommer.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ActionRenommer.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ModeleArbreProp.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ModeleArbreProp.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$JPopupMenuStructure.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$JPopupMenuStructure.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/Structure.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/Structure.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ActionDispatcher.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ActionDispatcher.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ActionSupprimer.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ActionSupprimer.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/Corpus$CorpusListener.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/Corpus$CorpusListener.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ActionAjouter.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ActionAjouter.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/Corpus.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/Corpus.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ActionAjouterForme.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$ActionAjouterForme.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/donnees/VisuStructure$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesUnites$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesUnites$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue$ModeleTableauTypes.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue$ModeleTableauTypes.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$NoeudChampAExtraire.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$NoeudChampAExtraire.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$ModeleArbreValeursAChoisir.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$ModeleArbreValeursAChoisir.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$ActionSupprimerChamp.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$ActionSupprimerChamp.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$NoeudValeurAChoisir.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$NoeudValeurAChoisir.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVuePresentation.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVuePresentation.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$JPopupMenuChamp.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$JPopupMenuChamp.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$ModeleArbreChampsAExtraire.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$ModeleArbreChampsAExtraire.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$ActionSupprimerValeur.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$ActionSupprimerValeur.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$ModeleTableauValeursAColorier.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$ModeleTableauValeursAColorier.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue$Jalon.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue$Jalon.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVuePresentation$ModeleTableauChampsAVoir.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVuePresentation$ModeleTableauChampsAVoir.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue$VueListener.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue$VueListener.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue$TripletValTypique.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue$TripletValTypique.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$ModeleTableauChampsAVoir.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction$ModeleTableauChampsAVoir.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$JPopupMenuValeur.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueColoriage$JPopupMenuValeur.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVue.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/VisuVueExtraction.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue$Jalon$Origine.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue$Jalon$Origine.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue$Adresse.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/vue/Vue$Adresse.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesUnites$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesUnites$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GPlanAFC$Ellipse.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GPlanAFC$Ellipse.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsGeometrie$DonneesGrapheEvent.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsGeometrie$DonneesGrapheEvent.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GPlanAFC$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GPlanAFC$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsGeometrie$TypeEventDonneesGraphe.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsGeometrie$TypeEventDonneesGraphe.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/BarresPainter.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/BarresPainter.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GPlanAFC$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GPlanAFC$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsGeometrie$DonneesGrapheListener.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsGeometrie$DonneesGrapheListener.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GPlanAFC$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GPlanAFC$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsFrequences.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsFrequences.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$ModeleValTypiques.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$ModeleValTypiques.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsCorrelations.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsCorrelations.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GPlanAFC.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GPlanAFC.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsFrequences$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsFrequences$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsFrequences$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsFrequences$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsFrequences$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsFrequences$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsCorrelations$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsCorrelations$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsCorrelations$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsCorrelations$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsCorrelations$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsCorrelations$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GBarres.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/GBarres.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsGeometrie.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/ModeleStatsGeometrie.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsFrequences.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsFrequences.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsCorrelations.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsCorrelations.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/CorrelationsRenderer.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/CorrelationsRenderer.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/statistiques/VisuStatsGeometrie$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$TypeMessage.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$TypeMessage.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$20.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$20.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$ElementMarque.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$ElementMarque.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$22.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$22.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$41.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$41.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$24.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$24.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$43.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$43.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$26.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$26.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauChamps$GChamp.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauChamps$GChamp.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$45.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$45.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$28.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$28.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$47.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$47.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$VueEvent.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$VueEvent.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas$5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesSchemas$5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$StructureEvent.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/Message$StructureEvent.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$PanneauCommandes.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$PanneauCommandes.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$49.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$49.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauChamps.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauChamps.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/Message.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/Message.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesRelations.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauCommandesRelations.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$10.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$10.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/PanneauEditeur$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$12.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$12.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$31.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$31.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$14.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$14.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$33.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$33.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$18.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$18.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$7.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$7.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$9.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$9.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ModeleStatChaine.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ModeleStatChaine.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$6.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$6.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$20.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$20.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$8.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$8.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Courbe.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Courbe.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GChainon$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GChainon$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ExportCSV$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ExportCSV$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ExportCSV$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ExportCSV$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$21.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$21.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$23.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$23.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ModeleChaines$Chainon.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ModeleChaines$Chainon.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Histogramme$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Histogramme$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Courbe$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Courbe$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$10.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$10.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$12.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$12.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$14.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$14.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$6.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$6.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$16.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$16.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$8.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$8.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$18.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$18.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuConversion$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuConversion$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$11.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$11.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$13.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$13.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$15.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$15.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GChainon.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GChainon.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$17.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$17.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$6.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$6.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$19.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$19.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ModeleChaines.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ModeleChaines.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$8.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$8.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GNoSousChainon.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GNoSousChainon.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$7.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$7.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$21.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$21.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$9.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$9.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GSegment.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GSegment.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Histogramme.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Histogramme.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GChainon$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GChainon$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel$5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel$5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ExportCSV$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ExportCSV$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ExportCSV$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ExportCSV$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ChaineUtil.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ChaineUtil.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$20.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$20.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$22.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$22.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GNoChainon.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$GNoChainon.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuConversion.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuConversion.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Courbe$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Courbe$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Histogramme$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/Histogramme$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesModel$ngramme.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesModel$ngramme.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$2.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$2.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$4.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$4.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$TypeSegment.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/GChaines$TypeSegment.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$11.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$11.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$13.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$13.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$5.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$5.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$15.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$15.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$7.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuStatGenerale$7.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$17.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$17.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuConversion$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuConversion$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$19.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$19.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$10.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$10.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$12.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$12.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesPanel.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesModel.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/NgrammesModel.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$14.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$14.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$1.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$1.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$3.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuCoref$3.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$16.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/VisuChaines$16.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ExportCSV.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/chaines/ExportCSV.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$16.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$16.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$35.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$35.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$18.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$18.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$37.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$37.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$39.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/visuAnalec/VisuMain$39.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/LUDecomposition.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/LUDecomposition.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/CholeskyDecomposition.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/CholeskyDecomposition.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/SingularValueDecomposition.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/SingularValueDecomposition.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/QRDecomposition.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/QRDecomposition.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/EigenvalueDecomposition.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/EigenvalueDecomposition.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseMatrix.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseMatrix.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseSVD$SparseSVDException.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseSVD$SparseSVDException.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/AFC.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/AFC.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseSVD$Storage.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseSVD$Storage.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/Matrix.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/Matrix.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseSVD$CodeSVDException.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseSVD$CodeSVDException.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseMatrix$Triple.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseMatrix$Triple.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseAFC.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseAFC.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/util/Machine.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/util/Machine.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/util/DoubleArraysPlus$Couple.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/util/DoubleArraysPlus$Couple.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/util/DoubleArraysPlus.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/util/DoubleArraysPlus.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/bin/JamaPlus/SingularValueDecomposition.java0
===================================================================
--- tmp/org.txm.analec.rcp/bin/JamaPlus/SingularValueDecomposition.java0	(revision 0)
+++ tmp/org.txm.analec.rcp/bin/JamaPlus/SingularValueDecomposition.java0	(revision 481)
@@ -0,0 +1,547 @@
+package JamaPlus;
+import JamaPlus.util.*;
+
+   /** Singular Value Decomposition.
+   <P>
+   For an m-by-n matrix A with m >= n, the singular value decomposition is
+   an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and
+   an n-by-n orthogonal matrix V so that A = U*S*V'.
+   <P>
+   The singular values, sigma[k] = S[k][k], are ordered so that
+   sigma[0] >= sigma[1] >= ... >= sigma[n-1].
+   <P>
+   The singular value decompostion always exists, so the constructor will
+   never fail.  The matrix condition number and the effective numerical
+   rank can be computed from this decomposition.
+   */
+
+public class SingularValueDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Arrays for internal storage of U and V.
+   @serial internal storage of U.
+   @serial internal storage of V.
+   */
+   private double[][] U, V;
+
+   /** Array for internal storage of singular values.
+   @serial internal storage of singular values.
+   */
+   private double[] s;
+
+   /** Row and column dimensions.
+   @serial row dimension.
+   @serial column dimension.
+   */
+   private int m, n;
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** Construct the singular value decomposition
+   @param A    Rectangular matrix
+   @return     Structure to access U, S and V.
+   */
+
+   public SingularValueDecomposition (Matrix Arg) {
+
+      // Derived from LINPACK code.
+      // Initialize.
+      double[][] A = Arg.getArrayCopy();
+      m = Arg.getRowDimension();
+      n = Arg.getColumnDimension();
+
+      /* Apparently the failing cases are only a proper subset of (m<n), 
+	 so let's not throw error.  Correct fix to come later?
+      if (m<n) {
+	  throw new IllegalArgumentException("Jama SVD only works for m >= n"); }
+      */
+      int nu = Math.min(m,n);
+      s = new double [Math.min(m+1,n)];
+      U = new double [m][nu];
+      V = new double [n][n];
+      double[] e = new double [n];
+      double[] work = new double [m];
+      boolean wantu = true;
+      boolean wantv = true;
+
+      // Reduce A to bidiagonal form, storing the diagonal elements
+      // in s and the super-diagonal elements in e.
+
+      int nct = Math.min(m-1,n);
+      int nrt = Math.max(0,Math.min(n-2,m));
+      for (int k = 0; k < Math.max(nct,nrt); k++) {
+         if (k < nct) {
+
+            // Compute the transformation for the k-th column and
+            // place the k-th diagonal in s[k].
+            // Compute 2-norm of k-th column without under/overflow.
+            s[k] = 0;
+            for (int i = k; i < m; i++) {
+               s[k] = Math.hypot(s[k],A[i][k]);
+            }
+            if (s[k] != 0.0) {
+               if (A[k][k] < 0.0) {
+                  s[k] = -s[k];
+               }
+               for (int i = k; i < m; i++) {
+                  A[i][k] /= s[k];
+               }
+               A[k][k] += 1.0;
+            }
+            s[k] = -s[k];
+         }
+         for (int j = k+1; j < n; j++) {
+            if ((k < nct) & (s[k] != 0.0))  {
+
+            // Apply the transformation.
+
+               double t = 0;
+               for (int i = k; i < m; i++) {
+                  t += A[i][k]*A[i][j];
+               }
+               t = -t/A[k][k];
+               for (int i = k; i < m; i++) {
+                  A[i][j] += t*A[i][k];
+               }
+            }
+
+            // Place the k-th row of A into e for the
+            // subsequent calculation of the row transformation.
+
+            e[j] = A[k][j];
+         }
+         if (wantu & (k < nct)) {
+
+            // Place the transformation in U for subsequent back
+            // multiplication.
+
+            for (int i = k; i < m; i++) {
+               U[i][k] = A[i][k];
+            }
+         }
+         if (k < nrt) {
+
+            // Compute the k-th row transformation and place the
+            // k-th super-diagonal in e[k].
+            // Compute 2-norm without under/overflow.
+            e[k] = 0;
+            for (int i = k+1; i < n; i++) {
+               e[k] = Math.hypot(e[k],e[i]);
+            }
+            if (e[k] != 0.0) {
+               if (e[k+1] < 0.0) {
+                  e[k] = -e[k];
+               }
+               for (int i = k+1; i < n; i++) {
+                  e[i] /= e[k];
+               }
+               e[k+1] += 1.0;
+            }
+            e[k] = -e[k];
+            if ((k+1 < m) & (e[k] != 0.0)) {
+
+            // Apply the transformation.
+
+               for (int i = k+1; i < m; i++) {
+                  work[i] = 0.0;
+               }
+               for (int j = k+1; j < n; j++) {
+                  for (int i = k+1; i < m; i++) {
+                     work[i] += e[j]*A[i][j];
+                  }
+               }
+               for (int j = k+1; j < n; j++) {
+                  double t = -e[j]/e[k+1];
+                  for (int i = k+1; i < m; i++) {
+                     A[i][j] += t*work[i];
+                  }
+               }
+            }
+            if (wantv) {
+
+            // Place the transformation in V for subsequent
+            // back multiplication.
+
+               for (int i = k+1; i < n; i++) {
+                  V[i][k] = e[i];
+               }
+            }
+         }
+      }
+
+      // Set up the final bidiagonal matrix or order p.
+
+      int p = Math.min(n,m+1);
+      if (nct < n) {
+         s[nct] = A[nct][nct];
+      }
+      if (m < p) {
+         s[p-1] = 0.0;
+      }
+      if (nrt+1 < p) {
+         e[nrt] = A[nrt][p-1];
+      }
+      e[p-1] = 0.0;
+
+      // If required, generate U.
+
+      if (wantu) {
+         for (int j = nct; j < nu; j++) {
+            for (int i = 0; i < m; i++) {
+               U[i][j] = 0.0;
+            }
+            U[j][j] = 1.0;
+         }
+         for (int k = nct-1; k >= 0; k--) {
+            if (s[k] != 0.0) {
+               for (int j = k+1; j < nu; j++) {
+                  double t = 0;
+                  for (int i = k; i < m; i++) {
+                     t += U[i][k]*U[i][j];
+                  }
+                  t = -t/U[k][k];
+                  for (int i = k; i < m; i++) {
+                     U[i][j] += t*U[i][k];
+                  }
+               }
+               for (int i = k; i < m; i++ ) {
+                  U[i][k] = -U[i][k];
+               }
+               U[k][k] = 1.0 + U[k][k];
+               for (int i = 0; i < k-1; i++) {
+                  U[i][k] = 0.0;
+               }
+            } else {
+               for (int i = 0; i < m; i++) {
+                  U[i][k] = 0.0;
+               }
+               U[k][k] = 1.0;
+            }
+         }
+      }
+
+      // If required, generate V.
+
+      if (wantv) {
+         for (int k = n-1; k >= 0; k--) {
+            if ((k < nrt) & (e[k] != 0.0)) {
+               for (int j = k+1; j < nu; j++) {
+                  double t = 0;
+                  for (int i = k+1; i < n; i++) {
+                     t += V[i][k]*V[i][j];
+                  }
+                  t = -t/V[k+1][k];
+                  for (int i = k+1; i < n; i++) {
+                     V[i][j] += t*V[i][k];
+                  }
+               }
+            }
+            for (int i = 0; i < n; i++) {
+               V[i][k] = 0.0;
+            }
+            V[k][k] = 1.0;
+         }
+      }
+
+      // Main iteration loop for the singular values.
+
+      int pp = p-1;
+      int iter = 0;
+      double eps = Math.pow(2.0,-52.0);
+      double tiny = Math.pow(2.0,-966.0);
+      while (p > 0) {
+         int k,kase;
+
+         // Here is where a test for too many iterations would go.
+
+         // This section of the program inspects for
+         // negligible elements in the s and e arrays.  On
+         // completion the variables kase and k are set as follows.
+
+         // kase = 1     if s(p) and e[k-1] are negligible and k<p
+         // kase = 2     if s(k) is negligible and k<p
+         // kase = 3     if e[k-1] is negligible, k<p, and
+         //              s(k), ..., s(p) are not negligible (qr step).
+         // kase = 4     if e(p-1) is negligible (convergence).
+
+         for (k = p-2; k >= -1; k--) {
+            if (k == -1) {
+               break;
+            }
+            if (Math.abs(e[k]) <=
+                  tiny + eps*(Math.abs(s[k]) + Math.abs(s[k+1]))) {
+               e[k] = 0.0;
+               break;
+            }
+         }
+         if (k == p-2) {
+            kase = 4;
+         } else {
+            int ks;
+            for (ks = p-1; ks >= k; ks--) {
+               if (ks == k) {
+                  break;
+               }
+               double t = (ks != p ? Math.abs(e[ks]) : 0.) + 
+                          (ks != k+1 ? Math.abs(e[ks-1]) : 0.);
+               if (Math.abs(s[ks]) <= tiny + eps*t)  {
+                  s[ks] = 0.0;
+                  break;
+               }
+            }
+            if (ks == k) {
+               kase = 3;
+            } else if (ks == p-1) {
+               kase = 1;
+            } else {
+               kase = 2;
+               k = ks;
+            }
+         }
+         k++;
+
+         // Perform the task indicated by kase.
+
+         switch (kase) {
+
+            // Deflate negligible s(p).
+
+            case 1: {
+               double f = e[p-2];
+               e[p-2] = 0.0;
+               for (int j = p-2; j >= k; j--) {
+                  double t = Math.hypot(s[j],f);
+                  double cs = s[j]/t;
+                  double sn = f/t;
+                  s[j] = t;
+                  if (j != k) {
+                     f = -sn*e[j-1];
+                     e[j-1] = cs*e[j-1];
+                  }
+                  if (wantv) {
+                     for (int i = 0; i < n; i++) {
+                        t = cs*V[i][j] + sn*V[i][p-1];
+                        V[i][p-1] = -sn*V[i][j] + cs*V[i][p-1];
+                        V[i][j] = t;
+                     }
+                  }
+               }
+            }
+            break;
+
+            // Split at negligible s(k).
+
+            case 2: {
+               double f = e[k-1];
+               e[k-1] = 0.0;
+               for (int j = k; j < p; j++) {
+                  double t = Math.hypot(s[j],f);
+                  double cs = s[j]/t;
+                  double sn = f/t;
+                  s[j] = t;
+                  f = -sn*e[j];
+                  e[j] = cs*e[j];
+                  if (wantu) {
+                     for (int i = 0; i < m; i++) {
+                        t = cs*U[i][j] + sn*U[i][k-1];
+                        U[i][k-1] = -sn*U[i][j] + cs*U[i][k-1];
+                        U[i][j] = t;
+                     }
+                  }
+               }
+            }
+            break;
+
+            // Perform one qr step.
+
+            case 3: {
+
+               // Calculate the shift.
+   
+               double scale = Math.max(Math.max(Math.max(Math.max(
+                       Math.abs(s[p-1]),Math.abs(s[p-2])),Math.abs(e[p-2])), 
+                       Math.abs(s[k])),Math.abs(e[k]));
+               double sp = s[p-1]/scale;
+               double spm1 = s[p-2]/scale;
+               double epm1 = e[p-2]/scale;
+               double sk = s[k]/scale;
+               double ek = e[k]/scale;
+               double b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
+               double c = (sp*epm1)*(sp*epm1);
+               double shift = 0.0;
+               if ((b != 0.0) | (c != 0.0)) {
+                  shift = Math.sqrt(b*b + c);
+                  if (b < 0.0) {
+                     shift = -shift;
+                  }
+                  shift = c/(b + shift);
+               }
+               double f = (sk + sp)*(sk - sp) + shift;
+               double g = sk*ek;
+   
+               // Chase zeros.
+   
+               for (int j = k; j < p-1; j++) {
+                  double t = Math.hypot(f,g);
+                  double cs = f/t;
+                  double sn = g/t;
+                  if (j != k) {
+                     e[j-1] = t;
+                  }
+                  f = cs*s[j] + sn*e[j];
+                  e[j] = cs*e[j] - sn*s[j];
+                  g = sn*s[j+1];
+                  s[j+1] = cs*s[j+1];
+                  if (wantv) {
+                     for (int i = 0; i < n; i++) {
+                        t = cs*V[i][j] + sn*V[i][j+1];
+                        V[i][j+1] = -sn*V[i][j] + cs*V[i][j+1];
+                        V[i][j] = t;
+                     }
+                  }
+                  t = Math.hypot(f,g);
+                  cs = f/t;
+                  sn = g/t;
+                  s[j] = t;
+                  f = cs*e[j] + sn*s[j+1];
+                  s[j+1] = -sn*e[j] + cs*s[j+1];
+                  g = sn*e[j+1];
+                  e[j+1] = cs*e[j+1];
+                  if (wantu && (j < m-1)) {
+                     for (int i = 0; i < m; i++) {
+                        t = cs*U[i][j] + sn*U[i][j+1];
+                        U[i][j+1] = -sn*U[i][j] + cs*U[i][j+1];
+                        U[i][j] = t;
+                     }
+                  }
+               }
+               e[p-2] = f;
+               iter = iter + 1;
+            }
+            break;
+
+            // Convergence.
+
+            case 4: {
+
+               // Make the singular values positive.
+   
+               if (s[k] <= 0.0) {
+                  s[k] = (s[k] < 0.0 ? -s[k] : 0.0);
+                  if (wantv) {
+                     for (int i = 0; i <= pp; i++) {
+                        V[i][k] = -V[i][k];
+                     }
+                  }
+               }
+   
+               // Order the singular values.
+   
+               while (k < pp) {
+                  if (s[k] >= s[k+1]) {
+                     break;
+                  }
+                  double t = s[k];
+                  s[k] = s[k+1];
+                  s[k+1] = t;
+                  if (wantv && (k < n-1)) {
+                     for (int i = 0; i < n; i++) {
+                        t = V[i][k+1]; V[i][k+1] = V[i][k]; V[i][k] = t;
+                     }
+                  }
+                  if (wantu && (k < m-1)) {
+                     for (int i = 0; i < m; i++) {
+                        t = U[i][k+1]; U[i][k+1] = U[i][k]; U[i][k] = t;
+                     }
+                  }
+                  k++;
+               }
+               iter = 0;
+               p--;
+            }
+            break;
+         }
+      }
+   }
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Return the left singular vectors
+   @return     U
+   */
+
+   public Matrix getU () {
+      return new Matrix(U,m,Math.min(m+1,n));
+   }
+
+   /** Return the right singular vectors
+   @return     V
+   */
+
+   public Matrix getV () {
+      return new Matrix(V,n,n);
+   }
+
+   /** Return the one-dimensional array of singular values
+   @return     diagonal of S.
+   */
+
+   public double[] getSingularValues () {
+      return s;
+   }
+
+   /** Return the diagonal matrix of singular values
+   @return     S
+   */
+
+   public Matrix getS () {
+      Matrix X = new Matrix(n,n);
+      double[][] S = X.getArray();
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            S[i][j] = 0.0;
+         }
+         S[i][i] = this.s[i];
+      }
+      return X;
+   }
+
+   /** Two norm
+   @return     max(S)
+   */
+
+   public double norm2 () {
+      return s[0];
+   }
+
+   /** Two norm condition number
+   @return     max(S)/min(S)
+   */
+
+   public double cond () {
+      return s[0]/s[Math.min(m,n)-1];
+   }
+
+   /** Effective numerical matrix rank
+   @return     Number of nonnegligible singular values.
+   */
+
+   public int rank () {
+      double eps = Math.pow(2.0,-52.0);
+      double tol = Math.max(m,n)*s[0]*eps;
+      int r = 0;
+      for (int i = 0; i < s.length; i++) {
+         if (s[i] > tol) {
+            r++;
+         }
+      }
+      return r;
+   }
+}
Index: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseSVD.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/bin/JamaPlus/SparseSVD.class
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/libs/itextpdf-5.5.4.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/libs/itextpdf-5.5.4.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/libs/glazedlists_java15-1.9.0.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/libs/glazedlists_java15-1.9.0.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/libs/jcommon-xml-1.0.23.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/libs/jcommon-xml-1.0.23.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/libs/itext-pdfa-5.5.8.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/libs/itext-pdfa-5.5.8.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/libs/jcommon-1.0.23.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/libs/jcommon-1.0.23.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/libs/itextpdf-5.5.8.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/libs/itextpdf-5.5.8.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/libs/itext-xtra-5.5.8.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/libs/itext-xtra-5.5.8.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/libs/xmlworker-5.5.8.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/libs/xmlworker-5.5.8.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/build.properties
===================================================================
--- tmp/org.txm.analec.rcp/build.properties	(revision 0)
+++ tmp/org.txm.analec.rcp/build.properties	(revision 481)
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               icons/,\
+               src/org/txm/macro/,\
+               OSGI-INF/l10n/bundle.properties

Property changes on: tmp/org.txm.analec.rcp/build.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/OSGI-INF/l10n/bundle.properties
===================================================================
--- tmp/org.txm.analec.rcp/OSGI-INF/l10n/bundle.properties	(revision 0)
+++ tmp/org.txm.analec.rcp/OSGI-INF/l10n/bundle.properties	(revision 481)
@@ -0,0 +1,23 @@
+#Properties file for AnalecRCP
+command.label = Import Glozz annotations (clear the current annotations)...
+command.label.0 = Analec Annotations in XML-Analec (TEI) format...
+command.label.1 = Analec Annotations in XML-Glozz format...
+command.name = Load Annotation Structure
+command.name.0 = Edit Annotation Structure
+command.name.1 = Save Annotation Structure
+command.name.2 = Import Glozz model...
+command.name.3 = Load Corpus...
+command.name.4 = Save annotations
+command.name.5 = Load Vue
+command.name.6 = Save Vue
+command.name.7 = Export to Glozz model...
+command.name.8 = Glozz
+command.name.9 = Import Glozz annotations...
+command.name.12 = Export to XML Glozz...
+command.name.13 = Export to XML-TEI-Analec...
+command.name.14 = XML-TEI-Analec
+view.name = Properties
+Bundle-Vendor = Textometrie.org
+Bundle-Name = AnalecRCP
+command.name.15 = Align Glozz annotations with TXM corpus words
+view.name.0 = Search
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/OSGI-INF/l10n/bundle.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/OSGI-INF/l10n/bundle_fr.properties
===================================================================
--- tmp/org.txm.analec.rcp/OSGI-INF/l10n/bundle_fr.properties	(revision 0)
+++ tmp/org.txm.analec.rcp/OSGI-INF/l10n/bundle_fr.properties	(revision 481)
@@ -0,0 +1,19 @@
+#Properties file for AnalecRCP
+command.label = Importer des annotations Glozz (supprime les annotations d�j� existantes)...
+command.label.0 = Annotations Analec au format XML-Analec (TEI)...
+command.label.1 = Annotations Analec au format format XML-Glozz ...
+command.name = Charger une structure d'annotation...
+command.name.0 = Editer la structure d'annotation
+command.name.1 = Sauver la structure d'annotation
+command.name.2 = Importer un mod�le Glozz...
+command.name.3 = Charger le Corpus Analec...
+command.name.4 = Sauver les annotations
+command.name.5 = Charger une Vue
+command.name.6 = Sauver la Vue
+command.name.7 = Exporter vers un mod�le Glozz...
+command.name.8 = Glozz
+command.name.9 = Importer les annotations Glozz...
+command.name.12 = Export XML Glozz...
+command.name.13 = Export XML-TEI-Analec...
+command.name.14 = XML-TEI-Analec
+view.name = Propri�t�s
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/OSGI-INF/l10n/bundle_fr.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/icons/pencil.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/icons/pencil.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/icons/bullet_arrow_up.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/icons/bullet_arrow_up.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/icons/clear.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/icons/clear.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/icons/bullet_arrow_down.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tmp/org.txm.analec.rcp/icons/bullet_arrow_down.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: tmp/org.txm.analec.rcp/plugin.xml
===================================================================
--- tmp/org.txm.analec.rcp/plugin.xml	(revision 0)
+++ tmp/org.txm.analec.rcp/plugin.xml	(revision 481)
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.menus">
+      <menuContribution
+            locationURI="menu:org.eclipse.ui.main.menu?after=menu.tools">
+         <menu
+               id="menu.analec"
+               label="Analec"
+               mnemonic="A">
+            <command
+                  commandId="org.txm.analec.commands.LoadStructureFromGlozz"
+                  style="push">
+               <visibleWhen
+                     checkEnabled="false">
+                  <reference
+                        definitionId="OneCorpusSelected">
+                  </reference>
+               </visibleWhen>
+            </command>
+            <command
+                  commandId="org.txm.analec.commands.EditAnnotationStructure"
+                  style="push">
+               <visibleWhen
+                     checkEnabled="false">
+                  <reference
+                        definitionId="OneCorpusSelected">
+                  </reference>
+               </visibleWhen>
+            </command>
+            <command
+                  commandId="org.txm.analec.commands.SaveCorpus"
+                  style="push">
+               <visibleWhen
+                     checkEnabled="false">
+                  <reference
+                        definitionId="OneCorpusSelected">
+                  </reference>
+               </visibleWhen>
+            </command>
+         </menu>
+      </menuContribution>
+      <menuContribution
+            locationURI="popup:org.txm.rcpapplication.views.CorporaView">
+         <menu
+               id="corpora.menu.analec"
+               label="Analec"
+               mnemonic="A">
+            <command
+                  commandId="org.txm.analec.commands.LoadStructureFromGlozz"
+                  style="push">
+               <visibleWhen
+                     checkEnabled="false">
+                  <reference
+                        definitionId="OneCorpusSelected">
+                  </reference>
+               </visibleWhen>
+            </command>
+            <command
+                  commandId="org.txm.analec.commands.EditAnnotationStructure"
+                  style="push">
+               <visibleWhen
+                     checkEnabled="false">
+                  <reference
+                        definitionId="OneCorpusSelected">
+                  </reference>
+               </visibleWhen>
+            </command>
+            <command
+                  commandId="org.txm.analec.commands.SaveCorpus"
+                  style="push">
+               <visibleWhen
+                     checkEnabled="false">
+                  <reference
+                        definitionId="OneCorpusSelected">
+                  </reference>
+               </visibleWhen>
+            </command>
+         </menu>
+      </menuContribution>
+      <menuContribution
+            locationURI="menu:menu.file.export?after=menu.file.export.exporttei">
+         <command
+               commandId="org.txm.analec.commands.ExportTEICorpus"
+               label="%command.label.0"
+               style="push">
+            <visibleWhen
+                  checkEnabled="false">
+               <reference
+                     definitionId="CanAnnotateWithAnalec">
+               </reference>
+            </visibleWhen>
+         </command>
+         <command
+               commandId="org.txm.analec.commands.ExportGlozzCorpus"
+               label="%command.label.1"
+               style="push">
+            <visibleWhen
+                  checkEnabled="false">
+               <reference
+                     definitionId="CanAnnotateWithAnalec">
+               </reference>
+            </visibleWhen>
+         </command>
+      </menuContribution>
+      <menuContribution
+            locationURI="menu:menu.file.import?before=menu.file.import.separator.software">
+         <command
+               commandId="org.txm.analec.commands.ImportTEICorpus"
+               style="push">
+         </command>
+      </menuContribution>
+      <menuContribution
+            locationURI="menu:menu.file.import?before=menu.file.import.separator.end">
+         <command
+               commandId="org.txm.analec.commands.ImportGlozzCorpus"
+               style="push">
+         </command>
+      </menuContribution>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.LoadStructure"
+            id="org.txm.analec.commands.LoadStructure"
+            name="%command.name">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.EditStructure"
+            id="org.txm.analec.commands.EditAnnotationStructure"
+            name="%command.name.0">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.SaveStructure"
+            id="org.txm.analec.commands.SaveStructure"
+            name="%command.name.1">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.LoadStructureFromGlozz"
+            id="org.txm.analec.commands.LoadStructureFromGlozz"
+            name="%command.name.2">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.LoadCorpus"
+            id="org.txm.analec.commands.LoadCorpus"
+            name="%command.name.3">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.SaveCorpus"
+            id="org.txm.analec.commands.SaveCorpus"
+            name="%command.name.4">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.LoadVue"
+            id="org.txm.analec.commands.LoadVue"
+            name="%command.name.5">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.SaveVue"
+            id="org.txm.analec.commands.SaveVue"
+            name="%command.name.6">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.SaveStructureAsGlozzModel"
+            id="org.txm.analec.commands.SaveStructureAsGlozzModel"
+            name="%command.name.7">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.ImportGlozzCorpus"
+            id="org.txm.analec.commands.ImportGlozzCorpus"
+            name="%command.name.8">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.ImportGlozzAnnotations"
+            id="org.txm.analec.commands.ImportGlozzAnnotations"
+            name="%command.name.9">
+      </command>
+      <command
+            defaultHandler="org.txm.analec.commands.DoInstallStep"
+            id="org.txm.analec.commands.DoInstallStep"
+            name="Install">
+      </command>
+      <command
+            id="AnalecRCP.command2"
+            name="name">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.ExportGlozzCorpus"
+            id="org.txm.analec.commands.ExportGlozzCorpus"
+            name="%command.name.12">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.ExportTEICorpus"
+            id="org.txm.analec.commands.ExportTEICorpus"
+            name="%command.name.13">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.ImportTEICorpus"
+            id="org.txm.analec.commands.ImportTEICorpus"
+            name="%command.name.14">
+      </command>
+      <command
+            categoryId="org.txm.rcpapplication.category.txm"
+            defaultHandler="org.txm.analec.commands.AlignGlozzAnnotationsWithTXMWords"
+            id="org.txm.analec.commands.AlignAnnotationsFromGlozzCorpus"
+            name="%command.name.15">
+      </command>
+   </extension>
+   <extension
+         point="org.txm.synopticeditor.toolbarbutton">
+      <Button
+            class="org.txm.analec.toolbarbutton.StartButton"></Button>
+   </extension>
+   <extension
+         point="org.eclipse.ui.views">
+      <view
+            allowMultiple="false"
+            category="org.txm.rcpapplication"
+            class="org.txm.analec.view.ElementPropertiesView"
+            icon="icons/pencil.png"
+            id="org.txm.analec.view.ElementPropertiesView"
+            name="%view.name"
+            restorable="true">
+      </view>
+      <view
+            allowMultiple="false"
+            category="org.txm.rcpapplication"
+            class="org.txm.analec.view.ElementSearchView"
+            icon="platform:/plugin/org.txm.rcpapplication/icons/functions/Search.png"
+            id="org.txm.analec.view.ElementSearchView"
+            name="%view.name.0"
+            restorable="true">
+      </view>
+   </extension>
+   <extension
+         point="org.txm.rcp.extentionpoint.command">
+      <installcommand
+            class="org.txm.analec.commands.DoInstallStep"></installcommand>
+   </extension>
+   <extension
+         point="org.eclipse.core.expressions.definitions">
+      <definition
+            id="CanAnnotateWithAnalec">
+         <test
+               forcePluginActivation="true"
+               property="org.txm.analec.testers.canAnnotate">
+         </test>
+      </definition>
+   </extension>
+   <extension
+         point="org.eclipse.core.expressions.propertyTesters">
+      <propertyTester
+            class="org.txm.analec.testers.IsCorpusAnnotated"
+            id="org.txm.analec.testers.IsCorpusAnnotated"
+            namespace="org.txm.analec.testers"
+            properties="canAnnotate"
+            type="java.lang.Object">
+      </propertyTester>
+   </extension>
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            category="org.txm.rcp.preferences.UserPreferencePage"
+            class="org.txm.analec.preferences.AnalecPreferencePage"
+            id="org.txm.analec.preferences.AnalecPreferencePage"
+            name="Analec">
+      </page>
+   </extension>
+
+</plugin>

Property changes on: tmp/org.txm.analec.rcp/plugin.xml
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauEditeur.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauEditeur.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauEditeur.java	(revision 481)
@@ -0,0 +1,353 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.text.Document;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+import visuAnalec.Message.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.texte.PanneauTexte.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class PanneauEditeur extends JPanel implements VueListener {
+  private enum Commandes {
+    GESTION_UNITES,
+    GESTION_RELATIONS,
+    GESTION_SCHEMAS,
+    MODIF_TEXTE;
+    private static Commandes getCommande(Class<? extends Element> classe) {
+      if (classe==Unite.class) return GESTION_UNITES;
+      if (classe==Relation.class) return GESTION_RELATIONS;
+      if (classe==Schema.class) return GESTION_SCHEMAS;
+      throw new UnsupportedOperationException("sous-classe non traitée");
+    }
+  }
+  private Vue vue;
+  private PanneauAffTexte panneauTexte;
+  private JPanel panneauOccurrences;
+  private PanneauChamps panneauChamps;
+  private Commandes commandes = null;
+  private HashMap<Commandes, PanneauCommandes> panneauxCommandes =
+          new HashMap<Commandes, PanneauCommandes>();
+  private HashMap<Commandes, String> titresPanneauxCommandes =
+          new HashMap<Commandes, String>();
+  private JDialog fenetreModifTexte;
+  private PanneauModifTexte panneauModifTexte;
+  private PanneauCommandesModifTexte panneauCommandesModifTexte;
+  private String recherche = "";
+  private Element elementCourant;
+
+  public static class ElementMarque {
+    public Element elt;
+    public String id;
+    public TypeMarquage marque;
+    public ElementMarque(Element elt, TypeMarquage marque, String id) {
+      this.elt = elt;
+      this.id = id;
+      this.marque = marque;
+    }
+  }
+
+  public static abstract class PanneauCommandes extends Box {
+    protected Vue vue;
+    protected PanneauAffTexte panneauTexte;
+    PanneauCommandes(Vue vue, PanneauAffTexte panneauTexte) {
+      super(BoxLayout.Y_AXIS);
+      this.vue = vue;
+      this.panneauTexte = panneauTexte;
+    }
+    public Vue getVue() {
+      return vue;
+    }
+    abstract public void reafficher();        // quand la vue n'a pas changé
+    abstract public void reinitialiser();     // quand la vue a changé
+    abstract public void elementSuivant(int sens);
+    abstract public Element elementSelectionne();
+    abstract public void editerElement(Element elt);
+    abstract public void traiterElementEvent(ElementEvent evt);
+    abstract public void traiterSourisEvent(PanneauAffTexte.SourisEvent evt);   // appelée par le panneau AffTexte
+    abstract public ArrayList<ElementMarque> trouverElementsVises(Unite uniteVisee,
+            TypeMarquage marqueUniteVisee, boolean avecId);  // appelée par le panneau AffTexte
+  }
+  public PanneauEditeur(Vue vue) {
+    super(new BorderLayout());
+    this.vue = vue;
+    vue.addEventListener(this);
+    setBorder(new TitledBorder(""));
+    panneauOccurrences = new JPanel(new BorderLayout());
+    panneauTexte = new PanneauAffTexte(vue.getCorpus());
+    panneauOccurrences.add(new JScrollPane(panneauTexte), BorderLayout.CENTER);
+    panneauChamps = new PanneauChamps(this, vue);
+    add(new JSplitPane(JSplitPane.VERTICAL_SPLIT, panneauOccurrences, panneauChamps), BorderLayout.CENTER);
+    // Les différents panneaux de commandes 
+    panneauxCommandes.put(Commandes.GESTION_UNITES,
+            new PanneauCommandesUnites(vue, panneauTexte, panneauChamps));
+    titresPanneauxCommandes.put(Commandes.GESTION_UNITES, "Gestion des unités");
+    panneauxCommandes.put(Commandes.GESTION_RELATIONS,
+            new PanneauCommandesRelations(vue, panneauTexte, panneauChamps));
+    titresPanneauxCommandes.put(Commandes.GESTION_RELATIONS, "Gestion des relations");
+    panneauxCommandes.put(Commandes.GESTION_SCHEMAS,
+            new PanneauCommandesSchemas(vue, panneauTexte, panneauChamps));
+    titresPanneauxCommandes.put(Commandes.GESTION_SCHEMAS, "Gestion des schémas");
+    new GActionClavier(this, "suivant", "F1", "control DOWN") {
+      public void executer() {
+        elementSuivant(1);
+      }
+    };
+    new GActionClavier(this, "précédent", "F2", "control UP") {
+      public void executer() {
+        elementSuivant(-1);
+      }
+    };
+    new GActionClavier(this, "copier", "F3", "control M") {
+      public void executer() {
+        copierElement();
+      }
+    };
+    new GActionClavier(this, "coller", "F4", "control R") {
+      public void executer() {
+        collerElement();
+      }
+    };
+    // La fenêtre modale pour éditer le texte
+    fenetreModifTexte = new JDialog((VisuMain) getTopLevelAncestor(), true);
+    fenetreModifTexte.setUndecorated(true);
+    fenetreModifTexte.getContentPane().setLayout(new BorderLayout());
+    panneauModifTexte = new PanneauModifTexte(vue.getCorpus());
+    fenetreModifTexte.getContentPane().add(new JScrollPane(panneauModifTexte), BorderLayout.CENTER);
+    panneauCommandesModifTexte = new visuAnalec.texte.PanneauCommandesModifTexte(this, vue, panneauModifTexte);
+    panneauModifTexte.setCommandesModifTexte(panneauCommandesModifTexte);
+    fenetreModifTexte.getContentPane().add(panneauCommandesModifTexte, BorderLayout.SOUTH);
+    fenetreModifTexte.setVisible(false);
+    // Panneau initial : gestion des unités
+    changerPanneauCommandes(Commandes.GESTION_UNITES);
+    reinitCommandes();
+
+  }
+  void agencerPanneaux() {
+    JSplitPane split = (JSplitPane) panneauOccurrences.getParent();
+    split.setDividerLocation(2./3);
+    revalidate();
+    repaint();
+  }
+  private void changerPanneauCommandes(Commandes newCommandes) {
+    if (commandes!=null)
+      panneauOccurrences.remove(panneauxCommandes.get(commandes));
+    commandes = newCommandes;
+    panneauOccurrences.add(panneauxCommandes.get(commandes), BorderLayout.NORTH);
+    ((TitledBorder) getBorder()).setTitle(titresPanneauxCommandes.get(commandes));
+    panneauTexte.setCommandes(panneauxCommandes.get(commandes));
+    revalidate();
+    repaint();
+  }
+  private void reinitCommandes() {
+    panneauxCommandes.get(commandes).reinitialiser();
+  }
+  private void elementSuivant(int sens) {
+    panneauxCommandes.get(commandes).elementSuivant(sens);
+  }
+  private void copierElement() {
+    Element elt = panneauxCommandes.get(commandes).elementSelectionne();
+    if (elt!=null) elementCourant = elt;
+  }
+  private void collerElement() {
+    if (elementCourant==null) return;
+    Element elt = panneauxCommandes.get(commandes).elementSelectionne();
+    if (elt==null) return;
+    vue.copierValeurs(elementCourant, elt);
+  }
+  private void reinitCommandes(Element elt) {
+    panneauxCommandes.get(commandes).reinitialiser();
+    panneauxCommandes.get(commandes).editerElement(elt);
+  }
+  private void reaffCommandes() {
+    panneauxCommandes.get(commandes).reafficher();
+  }
+  private void initNewCorpus() {
+    panneauTexte.setTexteVisu();
+    panneauTexte.initAscenseur();
+    colorierTexte();
+    changerPanneauCommandes(Commandes.GESTION_UNITES);
+    reinitCommandes();
+  }
+  private void colorierTexte() {
+    panneauTexte.setAttributsStandard(vue.getStyleTexte());
+    panneauTexte.colorierUnites(vue.getUnitesAColorier());
+  }
+  void initRechercherTexte() {
+    recherche = (String) JOptionPane.showInputDialog(this, "Recherche dans le texte",
+            "Rechercher", JOptionPane.PLAIN_MESSAGE, null, null, recherche);
+    if (recherche==null) recherche = "";
+    if (recherche.isEmpty()) return;
+    panneauTexte.rechercherTexte(recherche);
+  }
+  void rechercherSuivantTexte() {
+    if (recherche.isEmpty()) return;
+    panneauTexte.rechercherTexte(recherche);
+
+  }
+  void initModifierTexte() {
+    ((TitledBorder) getBorder()).setTitle("Modification du texte");
+    repaint();
+    fenetreModifTexte.setSize(panneauOccurrences.getSize());
+    fenetreModifTexte.setLocationRelativeTo(panneauOccurrences);
+    panneauChamps.effacer();
+    panneauModifTexte.init();
+    fenetreModifTexte.setModal(false);
+    fenetreModifTexte.setVisible(true);
+    panneauModifTexte.ajusterAscenseur(panneauTexte);
+    fenetreModifTexte.setVisible(false);
+    fenetreModifTexte.setModal(true);
+    fenetreModifTexte.setVisible(true);
+  }
+  public void finModifTexte() {
+    fenetreModifTexte.setVisible(false);
+    panneauTexte.ajusterAscenseur(panneauModifTexte);
+    if (commandes==null) {
+      changerPanneauCommandes(Commandes.GESTION_UNITES);
+      reinitCommandes();
+    } else {
+      ((TitledBorder) getBorder()).setTitle(titresPanneauxCommandes.get(commandes));
+      reaffCommandes();
+    }
+    repaint();
+  }
+  public void saisirStyleTexte(Vue vue) {
+    VisuStyleTexte.newVisuStyleTexte(this, vue.getStyleTexte());
+  }
+  public void changerStyleTexte(SimpleAttributeSet att) {
+    vue.setStyleTexte(att);
+    panneauTexte.setAttributsStandard(att);
+    panneauModifTexte.setAttributsStandard(att);
+    reaffCommandes();
+  }
+  public Document getTexteFormate() {
+    return panneauTexte.getDocument();
+  }
+  public void editerElement(Element elt) {
+    // typiquement, appelée de l'extérieur par d'autres fenêtres
+    changerPanneauCommandes(Commandes.getCommande(elt.getClass()));
+    reinitCommandes(elt);
+    ((VisuMain) getTopLevelAncestor()).premierPlan();
+  }
+  public void editerUniteChaine(Unite unit, Schema chaine) {
+    // appelée de l'extérieur notamment par visuChaines)
+    changerPanneauCommandes(Commandes.GESTION_SCHEMAS);
+    reinitCommandes();
+    ((PanneauCommandesSchemas) panneauxCommandes.get(commandes)).editerSchemaElement(chaine, unit);
+    ((VisuMain) getTopLevelAncestor()).premierPlan();
+  }
+  public void editerUniteTypeChaine(Unite unit, String typechaine) {
+    // appelée de l'extérieur notamment par visuChaines)
+    changerPanneauCommandes(Commandes.GESTION_SCHEMAS);
+    reinitCommandes();
+    ((PanneauCommandesSchemas) panneauxCommandes.get(commandes)).editerElementTypeSchema(unit, typechaine);
+    ((VisuMain) getTopLevelAncestor()).premierPlan();
+  }
+  void initGestionUnites() {
+    if (vue.getTypesUnitesAVoir().length==0) {
+      JOptionPane.showMessageDialog(getTopLevelAncestor(), "Aucun type d'unités n'est défini dans la vue actuelle",
+              "Saisie d'unités impossible", JOptionPane.ERROR_MESSAGE);
+      return;
+    }
+    changerPanneauCommandes(Commandes.GESTION_UNITES);
+    reinitCommandes();
+  }
+  void initGestionRelations() {
+    if (vue.getTypesRelationsAVoir().length==0) {
+      JOptionPane.showMessageDialog(getTopLevelAncestor(), "Aucun type de relation n'est défini dans la vue actuelle",
+              "Saisie de relations impossible", JOptionPane.ERROR_MESSAGE);
+      return;
+    }
+    changerPanneauCommandes(Commandes.GESTION_RELATIONS);
+    reinitCommandes();
+  }
+  void initGestionSchemas() {
+    if (vue.getTypesSchemasAVoir().length==0) {
+      JOptionPane.showMessageDialog(getTopLevelAncestor(), "Aucun type de schéma n'est défini dans la vue actuelle",
+              "Saisie de schéma impossible", JOptionPane.ERROR_MESSAGE);
+      return;
+    }
+    changerPanneauCommandes(Commandes.GESTION_SCHEMAS);
+    reinitCommandes();
+  }
+  public void traiterVueEvent(VueEvent evt) {
+    switch (evt.getModif()) {
+      case EXTRACTION:
+      case NEW_VUE:
+      case VUE_DEFAUT:
+        colorierTexte();
+        reinitCommandes();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getModif()+" oublié dans un switch");
+    }
+  }
+  public void traiterStructureEvent(StructureEvent evt) {
+    switch (evt.getModif()) {
+      case SUPPR_TYPE:
+      case FUSION_TYPE:
+      case RENOM_TYPE:
+      case AJOUT_TYPE:
+      case AJOUT_TYPE_ET_ELEMENTS:
+        colorierTexte();
+        reinitCommandes();
+        return;
+      case VALEUR_PAR_DEFAUT:
+      case AJOUT_FORME_UNITE:
+      case FUSION_PROP:
+      case RENOM_PROP:
+      case SUPPR_PROP:
+      case AJOUT_PROP:
+      case FUSION_VALEUR:
+      case RENOM_VALEUR:
+      case SUPPR_VALEUR:
+      case AJOUT_VALEUR:
+        colorierTexte();
+        panneauChamps.reafficher();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getModif()+" oublié dans un switch");
+    }
+  }
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        initNewCorpus();
+        return;
+      case NEW_CORPUS:
+        initNewCorpus();
+        return;
+      case MODIF_TEXTE:
+        panneauTexte.setTexteVisu();
+        return;
+      case MODIF_VUE:
+        traiterVueEvent((VueEvent) evt);
+        return;
+      case MODIF_STRUCTURE:
+        traiterStructureEvent((StructureEvent) evt);
+        return;
+      case MODIF_ELEMENT:
+        colorierTexte();
+        panneauxCommandes.get(commandes).traiterElementEvent((ElementEvent) evt);
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauEditeur.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauAffTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauAffTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauAffTexte.java	(revision 481)
@@ -0,0 +1,318 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.PanneauAffTexte.ListenerSourisTexte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import static visuAnalec.texte.PanneauAffTexte.SourisEvent.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class PanneauAffTexte extends PanneauTexte {
+  private PanneauCommandes panneauCommandes;
+  private ListenerSourisTexte sourisListener;
+  protected Marquage marquage = new Marquage(this);
+  public PanneauAffTexte(Corpus corpus) {
+    super(corpus);
+    coloriage = new Coloriage(this);
+    setEditable(false);
+    setSourisListener();
+  }
+  @Override
+  public String getToolTipText() {
+    Point pt = getMousePosition();
+    if (pt == null) return "";
+    Unite[] unitesVisees = getUnitesVisees(marquage, pt);
+    if (unitesVisees.length == 0) return "";
+    ArrayList<String> textes = new ArrayList<String>();
+    ArrayList<String> idsElementsVises = new ArrayList<String>();
+    for (Unite unit : unitesVisees) {
+      String texte = getTexteUnite(unit);
+      for (ElementMarque eltMarque : panneauCommandes.trouverElementsVises(unit,
+              marquage.getMarquage(unit), true)) {
+        idsElementsVises.add(eltMarque.id);
+        textes.add(texte);
+      }
+    }
+    return GVisu.styleIdTooltip(textes, idsElementsVises);
+  }
+  protected void setSourisListener() {
+    sourisListener = new ListenerSourisTexte(this);
+    addMouseListener(sourisListener);
+  }
+  public void setCommandes(PanneauCommandes panneauCommandes) {
+    this.panneauCommandes = panneauCommandes;
+    sourisListener.setCommandes(panneauCommandes);
+  }
+  private void deselecterUnite(Unite unite) {  // utilisé uniquement pour rectifier une borne
+    int debUnite = indexToPosition(unite.getDeb());
+    int finUnite = indexToPosition(unite.getFin());
+    doc.setCharacterAttributes(debUnite, finUnite - debUnite, AttributsStandard, true);
+  }
+  private void selecterUnite(Unite unite) {   // utilisé uniquement pour rectifier une borne
+    int debUnite = indexToPosition(unite.getDeb());
+    int finUnite = indexToPosition(unite.getFin());
+    doc.setCharacterAttributes(debUnite, finUnite - debUnite, SELECTION_1, true);
+  }
+  public void pasDeMarquage() {
+    marquerUnites(marquage, new TypeMarquage[0], null);
+    sourisListener.setEtat(EtatClic.SAISIE);
+  }
+  public void saisir(Unite amontrer, Unite[] lUnites, TypeMarquage type) {
+    TypeMarquage[] typesMarq = {type};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(type, lUnites);
+    marquerUnites(marquage, typesMarq, unites);
+    if (amontrer != null) placerAscenseur(amontrer);
+    sourisListener.setEtat(EtatClic.SAISIE);
+  }
+  public void saisir(Unite amontrer, Unite[] lUnites1, TypeMarquage type1, Unite[] lUnites2, TypeMarquage type2) {
+    TypeMarquage[] typesMarq = {type1, type2};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(type1, lUnites1);
+    unites.put(type2, lUnites2);
+    marquerUnites(marquage, typesMarq, unites);
+    if (amontrer != null) placerAscenseur(amontrer);
+    sourisListener.setEtat(EtatClic.SAISIE);
+  }
+  public void saisir(Unite amontrer, Unite[] lUnites1, TypeMarquage type1,
+          Unite[] lUnites2, TypeMarquage type2, Unite[] lUnites3, TypeMarquage type3) {
+    TypeMarquage[] typesMarq = {type1, type2, type3};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(type1, lUnites1);
+    unites.put(type2, lUnites2);
+    unites.put(type3, lUnites3);
+    marquerUnites(marquage, typesMarq, unites);
+    if (amontrer != null) placerAscenseur(amontrer);
+    sourisListener.setEtat(EtatClic.SAISIE);
+  }
+  public void saisir(Unite amontrer, Unite[] lUnites1, TypeMarquage type1, Unite[] lUnites2, TypeMarquage type2,
+          Unite[] lUnites3, TypeMarquage type3, Unite[] lUnites4, TypeMarquage type4) {
+    TypeMarquage[] typesMarq = {type1, type2, type3, type4};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(type1, lUnites1);
+    unites.put(type2, lUnites2);
+    unites.put(type3, lUnites3);
+    unites.put(type4, lUnites4);
+    marquerUnites(marquage, typesMarq, unites);
+    if (amontrer != null) placerAscenseur(amontrer);
+    sourisListener.setEtat(EtatClic.SAISIE);
+  }
+  public void rectifierBorneUnite(Unite unite) {
+    sourisListener.etatChtBornes(unite);
+  }
+  void changerBornes(Unite unite, int borneGauche, int borneDroite) {
+    corpus.modifBornesUnite(unite, borneGauche, borneDroite);
+  }
+
+  public static class SourisEvent {
+    public enum TypeEvent {
+      SELECT_TEXTE, SELECT_RIEN, SELECT_ELEMENT
+    }
+    private TypeEvent type;
+    private Element elementVise;
+    private TypeMarquage marquageElementVise;
+    private int[] bornesSelectionTexte;
+    protected SourisEvent(TypeEvent type) {
+      this(type, null, null, null);
+    }
+    protected SourisEvent(TypeEvent type, Element elt, TypeMarquage marque) {
+      this(type, elt, marque, null);
+    }
+    protected SourisEvent(TypeEvent type, int[] bornes) {
+      this(type, null, null, bornes);
+    }
+    protected SourisEvent(TypeEvent type, Element elt, TypeMarquage marque, int[] bornes) {
+      this.type = type;
+      marquageElementVise = marque;
+      bornesSelectionTexte = bornes;
+      elementVise = elt;
+    }
+    public TypeEvent getTypeEvent() {
+      return type;
+    }
+    public TypeMarquage getMarquageElementVise() {
+      return marquageElementVise;
+    }
+    public int[] getBornesSelectionTexte() {
+      return bornesSelectionTexte;
+    }
+    public Element getElementVise() {
+      return elementVise;
+    }
+  }
+
+  protected static class ListenerSourisTexte extends MouseAdapter {
+    enum EtatClic {
+      INACTIF,
+      SAISIE,
+      BORNES,
+    }
+    private EtatClic etatClic;
+    private Unite uniteABorner;
+    private PanneauAffTexte panneauTexte;
+    private PanneauCommandes panneauCommandes;
+    private JPopupMenuUnites popupMenuUnites;
+    public ListenerSourisTexte(PanneauAffTexte pTexte) {
+      panneauTexte = pTexte;
+      popupMenuUnites = new JPopupMenuUnites(pTexte);
+    }
+    void setCommandes(PanneauCommandes commandes) {
+      panneauCommandes = commandes;
+      popupMenuUnites.setCommandes(commandes);
+    }
+    void setEtat(EtatClic etat) {
+      this.etatClic = etat;
+    }
+    void etatChtBornes(Unite uniteABorner) {
+      etatClic = EtatClic.BORNES;
+      this.uniteABorner = uniteABorner;
+      int deb = panneauTexte.indexToPosition(uniteABorner.getDeb());
+      int fin = panneauTexte.indexToPosition(uniteABorner.getFin());
+      panneauTexte.doc.setCharacterAttributes(deb, fin - deb, BORNAGE, true);
+    }
+    @Override
+    public void mousePressed(MouseEvent e) {
+      if (e.isPopupTrigger()) mousePopup(e);
+    }
+    @Override
+    public void mouseReleased(MouseEvent e) {
+      try {
+        if (e.isPopupTrigger()) {
+          mousePopup(e);
+          return;
+        }
+        switch (etatClic) {
+          case INACTIF:
+          case BORNES:
+            return;
+          case SAISIE:
+            if (panneauTexte.getSelectedText() != null) panneauCommandes.traiterSourisEvent(new SourisEvent(
+                      TypeEvent.SELECT_TEXTE, panneauTexte.getIndSelection()));
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas non prévu d'étatClic");
+        }
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+    @Override
+    public void mouseClicked(MouseEvent e) {
+      try {
+        if (e.getButton() != MouseEvent.BUTTON1) return;
+        if (e.getClickCount() > 1) return;
+        switch (etatClic) {
+          case INACTIF:  // peut-être inutile ??
+            return;
+          case SAISIE:
+            Unite uniteVisee = panneauTexte.getUniteVisee(panneauTexte.marquage, e.getPoint());
+            if (uniteVisee == null) {
+              panneauCommandes.traiterSourisEvent(new SourisEvent(TypeEvent.SELECT_RIEN));
+              return;
+            }
+            ElementMarque eltM = panneauCommandes.trouverElementsVises(uniteVisee,
+                    panneauTexte.marquage.getMarquage(uniteVisee), false).get(0);
+            panneauCommandes.traiterSourisEvent(new SourisEvent(TypeEvent.SELECT_ELEMENT,
+                    eltM.elt, eltM.marque));
+            return;
+          case BORNES: // à revoir
+            int olddeb = uniteABorner.getDeb();
+            int oldfin = uniteABorner.getFin();
+            int newdeb = olddeb;
+            int newfin = oldfin;
+            int newborne = panneauTexte.positionToIndex(panneauTexte.viewToModel(e.getPoint()));
+            if (2 * newborne < olddeb + oldfin) newdeb = newborne;
+            else newfin = newborne;
+            panneauTexte.deselecterUnite(uniteABorner);
+            panneauTexte.changerBornes(uniteABorner, newdeb, newfin);
+            panneauTexte.selecterUnite(uniteABorner);
+            etatClic = EtatClic.SAISIE;
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas non prévu d'état d'AffTexte");
+        }
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+    public void mousePopup(MouseEvent e) {
+      Unite[] unitesVisees = panneauTexte.getUnitesVisees(panneauTexte.marquage, e.getPoint());
+      if (unitesVisees.length > 0) {
+        popupMenuUnites.reinitialiser(unitesVisees);
+        popupMenuUnites.show(e.getComponent(), e.getX(), e.getY());
+      }
+    }
+  }
+
+  private static class JPopupMenuUnites extends JPopupMenu {
+    private PanneauAffTexte panneauTexte;
+    private PanneauCommandes panneauCommandes;
+    private ArrayList<ElementMarque> elementsMarques = new ArrayList<ElementMarque>();
+    private Element[] elementsVises;
+    private String[] idsElementsVises;
+    private TypeMarquage[] marquesElementsVises;
+    public JPopupMenuUnites(PanneauAffTexte panneauTexte) {
+      super();
+      this.panneauTexte = panneauTexte;
+    }
+    void setCommandes(PanneauCommandes commandes) {
+      panneauCommandes = commandes;
+    }
+    void reinitialiser(Unite[] unitesVisees) {
+      removeAll();
+      elementsMarques.clear();
+      elementsVises = new Element[unitesVisees.length];
+      idsElementsVises = new String[unitesVisees.length];
+      marquesElementsVises = new TypeMarquage[unitesVisees.length];
+      int no = 0;
+      ArrayList<ElementMarque> eltsMARajouter = new ArrayList<ElementMarque>();
+      ArrayList<String> descrsARajouter = new ArrayList<String>();
+      for (Unite unit : unitesVisees) {
+        String texte = panneauTexte.getTexteUnite(unit);
+        ArrayList<TypeMarquage> typesM = panneauTexte.marquage.getMarquages(unit);
+        for (ElementMarque eltM : panneauCommandes.trouverElementsVises(unit, typesM.get(0), true)) {
+          elementsMarques.add(eltM);
+          String descr = GVisu.styleIdPopup(texte, eltM.id);
+          add(new ActionSelectionUnites(descr, no++));
+        }
+        for (TypeMarquage typeM : typesM.subList(1, typesM.size()))
+          for (ElementMarque eltM : panneauCommandes.trouverElementsVises(unit, typeM, true)) {
+            eltsMARajouter.add(eltM);
+            descrsARajouter.add(GVisu.styleIdPopup(texte, eltM.id));
+          }
+      }
+      for (int i = 0; i < eltsMARajouter.size(); i++) {
+        elementsMarques.add(eltsMARajouter.get(i));
+        add(new ActionSelectionUnites(descrsARajouter.get(i), no++));
+      }
+    }
+
+    private class ActionSelectionUnites extends GAction {
+      int no;
+      private ActionSelectionUnites(String descr, int no) {
+        super(descr);
+        this.no = no;
+      }
+      public void executer() {
+        panneauCommandes.traiterSourisEvent(new SourisEvent(TypeEvent.SELECT_ELEMENT,
+                elementsMarques.get(no).elt, elementsMarques.get(no).marque));
+      }
+    }
+  }
+}
+
+      
+

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauAffTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauModifTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauModifTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauModifTexte.java	(revision 481)
@@ -0,0 +1,170 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import java.util.*;
+import javax.swing.event.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class PanneauModifTexte extends PanneauTexte implements DocumentListener {
+  protected static class BorneUnite implements Comparable {
+    public Unite unite;
+    public int pos;
+    public BorneUnite(Unite unite, int pos) {
+      this.unite = unite;
+      this.pos = pos;
+    }
+    public int compareTo(Object obj) {
+      if (obj.getClass() != BorneUnite.class) {
+        throw new ClassCastException("Comparaison impossible : " + obj.toString() +
+                " n'est pas une instance de BorneUnite");
+      }
+      int comp = Integer.signum(pos - (((BorneUnite) obj).pos));
+      if (comp == 0) {
+        comp = -Integer.signum(unite.getFin() - unite.getDeb() - ((BorneUnite) obj).unite.getFin() +
+                ((BorneUnite) obj).unite.getDeb());
+      }
+      return comp;
+    }
+  }
+  private PanneauCommandesModifTexte panneauCommandes;
+  private BorneUnite[] bornesGauches;
+  private BorneUnite[] bornesDroites;
+  public PanneauModifTexte(Corpus corpus) {
+    super(corpus);
+    setEditable(true);
+  }
+  public void setCommandesModifTexte(PanneauCommandesModifTexte panneauCommandes) {
+    this.panneauCommandes = panneauCommandes;
+  }
+  void setBornesModifTexte() {
+    ArrayList<Unite> units = corpus.getToutesUnites();
+    bornesGauches = new BorneUnite[units.size()];
+    bornesDroites = new BorneUnite[units.size()];
+    for (int i = 0; i < units.size(); i++) {
+      Unite unite = units.get(i);
+      bornesGauches[i] = new BorneUnite(unite, unite.getDeb());
+      bornesDroites[i] = new BorneUnite(unite, unite.getFin());
+    }
+    Arrays.sort(bornesGauches);
+    Arrays.sort(bornesDroites);
+
+  }
+  public void init() {
+    doc.removeDocumentListener(this);
+    setTexteVisu();
+    setEditable(true);
+    doc.setParagraphAttributes(0, getText().length(), AttributsStandard, true);
+    doc.setCharacterAttributes(0, getText().length(), AttributsStandard, true);
+    setBornesModifTexte();
+    doc.addDocumentListener(this);
+  }
+  public int preparerValiderModifTexte() {
+    Comparator<BorneUnite> comp = new Comparator<BorneUnite>() {
+      public int compare(BorneUnite b1, BorneUnite b2) {
+        return b1.unite.compareTo(b2.unite);
+      }
+    };
+    Arrays.sort(bornesGauches, comp);
+    Arrays.sort(bornesDroites, comp);
+    int nbSupprimes = 0;
+    for (int i = 0; i < bornesGauches.length; i++) {
+      if (bornesGauches[i].pos == bornesDroites[i].pos) {
+        nbSupprimes++;
+      }
+    }
+    return nbSupprimes;
+  }
+  public void validerModifTexte() {
+    for (int i = 0; i < bornesGauches.length; i++) {
+      Unite unite = bornesGauches[i].unite;
+      if (bornesGauches[i].pos == unite.getDeb() && bornesDroites[i].pos == unite.getFin()) {
+        continue;
+      }
+      if (bornesGauches[i].pos == bornesDroites[i].pos) {
+        corpus.supUnite(unite);
+      } else {
+        corpus.modifBornesUnite(unite, bornesGauches[i].pos, bornesDroites[i].pos);
+      }
+    }
+    setEditable(false);
+    setTexteCorpus();  // Corpus enverra l'événement MODIF_TEXTE à tous les panneaux occurrence
+  }
+  public void insertUpdate(DocumentEvent evt) {
+    try {
+      String texte = getText();
+      int debutInsertion = positionToIndex(evt.getOffset());
+      int lengthInsertion = evt.getLength();
+      int iIns = 0;
+      while (iIns < posNewLines.size() && posNewLines.get(iIns) < evt.getOffset()) {
+        iIns++;
+      }
+      for (int ind = iIns; ind < posNewLines.size(); ind++) {
+        posNewLines.set(ind, posNewLines.get(ind) + evt.getLength());
+      }
+      for (int pos = evt.getOffset(); pos < evt.getOffset() + evt.getLength(); pos++) {
+        if (texte.charAt(pos) == '\n') {
+          lengthInsertion--;
+          posNewLines.add(iIns++, pos);
+        }
+      }
+      shiftDroitBornes(bornesGauches, debutInsertion, lengthInsertion);
+      shiftDroitBornes(bornesDroites, debutInsertion, lengthInsertion);
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  public void removeUpdate(DocumentEvent evt) {
+    try {
+      int debutSuppression = positionToIndex(evt.getOffset());
+      int lengthSuppression = evt.getLength();
+      int iSup = 0;
+      while (iSup < posNewLines.size() && posNewLines.get(iSup) < evt.getOffset()) {
+        iSup++;
+      }
+      while (iSup < posNewLines.size() && posNewLines.get(iSup) < evt.getOffset() + evt.getLength()) {
+        posNewLines.remove(iSup);
+        lengthSuppression--;
+      }
+      for (int ind = iSup; ind < posNewLines.size(); ind++) {
+        posNewLines.set(ind, posNewLines.get(ind) - evt.getLength());
+      }
+      shiftGaucheBornes(bornesGauches, debutSuppression, lengthSuppression);
+      shiftGaucheBornes(bornesDroites, debutSuppression, lengthSuppression);
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  public void changedUpdate(DocumentEvent evt) {
+    // rien à faire
+  }
+  void shiftDroitBornes(BorneUnite[] bornes, int deb, int shift) {
+    for (int i = bornes.length - 1; i >= 0; i--) {
+      if (bornes[i].pos < deb) {
+        return;
+      }
+      bornes[i].pos += shift;
+    }
+  }
+  void shiftGaucheBornes(BorneUnite[] bornes, int deb, int shift) {
+    for (int i = bornes.length - 1; i >= 0; i--) {
+      if (bornes[i].pos <= deb) {
+        return;
+      }
+      if (bornes[i].pos < deb + shift) {
+        bornes[i].pos = deb;
+      } else {
+        bornes[i].pos -= shift;
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauModifTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauTexte.java	(revision 481)
@@ -0,0 +1,542 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import java.awt.*;
+import java.util.*;
+import java.util.ArrayList;
+import javax.swing.*;
+import javax.swing.text.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class PanneauTexte extends JTextPane {
+  final private static Color ROUGE = new Color(0x800000);
+  final private static Color BLEU = new Color(0x000080);
+  final private static Color JAUNE_CLAIR = new Color(0xffffb0);
+  final private static Color JAUNE_TRES_CLAIR = new Color(0xffffe0);
+  final private static Color JAUNE_FONCE = new Color(0xffff60);
+  final private static Color VERT_CLAIR = new Color(0xd8f0ff);
+  final private static Color VERT_FONCE = new Color(0xb0d0ff);
+  final private static Color VIOLET_CLAIR = new Color(0xffd8e0);
+  final private static Color VIOLET_FONCE = new Color(0xffb0c0);
+  final public static SimpleAttributeSet STANDARD_DEFAUT = creerStyleStandardDefaut();
+  final protected static AttributeSet COLORATION_1 = creerCouleurFond(JAUNE_CLAIR);
+  final protected static AttributeSet COLORATION_1_MULTI = creerCouleurFond(JAUNE_FONCE);
+  final protected static AttributeSet COLORATION_2 = creerCouleurFond(VERT_CLAIR);
+  final protected static AttributeSet COLORATION_2_MULTI = creerCouleurFond(VERT_FONCE);
+  final protected static AttributeSet COLORATION_3 = creerCouleurFond(VIOLET_CLAIR);
+  final protected static AttributeSet COLORATION_3_MULTI = creerCouleurFond(VIOLET_FONCE);
+  final protected static AttributeSet SELECTION_1_1 = ajouterCouleurCar(COLORATION_1, BLEU);
+  final protected static AttributeSet SELECTION_1_1_MULTI = ajouterCouleurCar(COLORATION_1_MULTI,
+          BLEU);
+  final protected static AttributeSet SELECTION_1_2 = ajouterCouleurCar(COLORATION_1, ROUGE);
+  final protected static AttributeSet SELECTION_1_2_MULTI = ajouterCouleurCar(COLORATION_1_MULTI,
+          ROUGE);
+  final protected static AttributeSet SELECTION_1 = ajouterCouleurCar(COLORATION_1, ROUGE);
+  final protected static AttributeSet SELECTION_1_MULTI = ajouterCouleurCar(COLORATION_1_MULTI,
+          ROUGE);
+  final protected static AttributeSet SELECTION_2 = ajouterCouleurCar(COLORATION_2, BLEU);
+  final protected static AttributeSet SELECTION_2_MULTI = ajouterCouleurCar(COLORATION_2_MULTI,
+          BLEU);
+  final protected static AttributeSet SELECTION_3 = ajouterCouleurCar(COLORATION_3, ROUGE);
+  final protected static AttributeSet SELECTION_3_MULTI = ajouterCouleurCar(COLORATION_3_MULTI,
+          ROUGE);
+  final protected static AttributeSet BORNAGE = ajouterCouleurCar(COLORATION_1, null);
+  final private static HashMap<Integer, String> NOM_ALIGNEMENT = creerTableauNomsAlignement();
+
+  private static SimpleAttributeSet creerStyleStandardDefaut() {
+    String police;
+    if (Arrays.binarySearch(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(),
+            "Times New Roman")>=0) police = "Times New Roman";
+    else police = "Serif";
+    SimpleAttributeSet att = new SimpleAttributeSet();
+    StyleConstants.setFontFamily(att, police);
+    StyleConstants.setForeground(att, Color.BLACK);
+    StyleConstants.setBackground(att, Color.WHITE);
+    StyleConstants.setFontSize(att, 14);
+    StyleConstants.setBold(att, false);
+    StyleConstants.setItalic(att, false);
+    StyleConstants.setUnderline(att, false);
+    StyleConstants.setAlignment(att, StyleConstants.ALIGN_JUSTIFIED);
+    StyleConstants.setFirstLineIndent(att, 20f);
+    StyleConstants.setSpaceAbove(att, 4f);
+    StyleConstants.setSpaceBelow(att, 0f);
+    StyleConstants.setLeftIndent(att, 10f);
+    StyleConstants.setRightIndent(att, 10f);
+    StyleConstants.setLineSpacing(att, 0.1f);
+    return att;
+  }
+
+  private static HashMap<Integer, String> creerTableauNomsAlignement() {
+    HashMap<Integer, String> tab = new HashMap<Integer, String>();
+    tab.put(StyleConstants.ALIGN_CENTER, "Centré");
+    tab.put(StyleConstants.ALIGN_JUSTIFIED, "Justifié");
+    tab.put(StyleConstants.ALIGN_LEFT, "Gauche");
+    tab.put(StyleConstants.ALIGN_RIGHT, "Droite");
+    return tab;
+  }
+
+  public static String nomAlignement(int code) {
+    return NOM_ALIGNEMENT.get(code);
+  }
+
+  public static String[] nomsAlignement() {
+    String[] noms = NOM_ALIGNEMENT.values().toArray(new String[0]);
+    Arrays.sort(noms);
+    return noms;
+  }
+
+  public static int codeAlignement(String nom) {
+    for (int code : NOM_ALIGNEMENT.keySet()) if (nomAlignement(code).equals(nom))
+        return code;
+    return StyleConstants.ALIGN_JUSTIFIED;
+  }
+
+  private static SimpleAttributeSet creerCouleurFond(Color c) {
+    SimpleAttributeSet att = new SimpleAttributeSet();
+    StyleConstants.setBackground(att, c);
+    return att;
+  }
+
+  private static SimpleAttributeSet ajouterCouleurCar(AttributeSet att0, Color c) {
+    SimpleAttributeSet att = new SimpleAttributeSet(att0);
+    StyleConstants.setBold(att, true);
+    if (c!=null) StyleConstants.setForeground(att, c);
+    return att;
+  }
+
+  public static Color getCouleurFond1() {
+    return StyleConstants.getBackground(COLORATION_1);
+  }
+
+  public static Color getCouleurFond2() {
+    return StyleConstants.getBackground(COLORATION_2);
+  }
+
+  public static Color getCouleurFond3() {
+    return StyleConstants.getBackground(COLORATION_3);
+  }
+
+  public enum TypeMarquage {
+    FOND1(5, COLORATION_1, COLORATION_1_MULTI),
+    FOND1_2(5, COLORATION_1, COLORATION_1_MULTI),
+    FOND2(6, COLORATION_2, COLORATION_2_MULTI),
+    FOND3(7, COLORATION_3, COLORATION_3_MULTI),
+    SELECT1(2, SELECTION_1, SELECTION_1_MULTI),
+    SELECT1_2(1, SELECTION_1_1, SELECTION_1_1_MULTI),
+    SELECT1_3(2, SELECTION_1_2, SELECTION_1_2_MULTI),
+    SELECT2(3, SELECTION_2, SELECTION_2_MULTI),
+    SELECT3(4, SELECTION_3, SELECTION_3_MULTI);
+    protected AttributeSet attribut;
+    protected AttributeSet attributMulti;
+    protected int niveau;
+
+    TypeMarquage(int niv, AttributeSet att, AttributeSet attMulti) {
+      attribut = att;
+      attributMulti = attMulti;
+      niveau = niv;
+    }
+  }
+
+  public static class UniteColoree {
+    public Unite unite;
+    public AttributeSet att;
+
+    public UniteColoree(Unite unite, AttributeSet att) {
+      this.att = att;
+      this.unite = unite;
+    }
+  }
+
+  protected static class Coloriage {
+    private int[][] intervalles;
+    private AttributeSet[] attributIntervalles;
+    private PanneauTexte panneauTexte;
+
+    protected Coloriage(PanneauTexte pTexte) {
+      panneauTexte = pTexte;
+      intervalles = new int[0][];
+      attributIntervalles = new AttributeSet[0];
+    }
+
+    private void creerColoriage(UniteColoree[] unitsCol) {
+      ArrayList<int[]> intervlles = new ArrayList<int[]>();
+      ArrayList<AttributeSet> attIntervalle = new ArrayList<AttributeSet>();
+      for (UniteColoree unitCol : unitsCol) {
+        int deb = panneauTexte.indexToPosition(unitCol.unite.getDeb());
+        int fin = panneauTexte.indexToPosition(unitCol.unite.getFin());
+        intervlles.add(new int[]{deb, fin-deb});
+        attIntervalle.add(unitCol.att);
+      }
+      intervalles = intervlles.toArray(new int[0][]);
+      attributIntervalles = attIntervalle.toArray(new AttributeSet[0]);
+    }
+  }
+
+  protected static class Marquage {
+    private int[][] intervalles;
+    private Unite[][] unitesIntervalles;
+    private AttributeSet[] attributIntervalles;
+    private HashMap<Unite, ArrayList<TypeMarquage>> typesMarquage =
+            new HashMap<Unite, ArrayList<TypeMarquage>>();
+    private PanneauTexte panneauTexte;
+
+    protected Marquage(PanneauTexte pTexte) {
+      panneauTexte = pTexte;
+    }
+    // Ordre de masquage décroissant : si une unité est présente dans plusieurs types de marquage, 
+    // seule sa première mention sera prise en compte (grâce au HashMap typesMarquage)
+
+    void creerMarquage(TypeMarquage[] typesMarq, EnumMap<TypeMarquage, Unite[]> unites) {
+      HashMap<Integer, HashSet<Unite>> debs = new HashMap<Integer, HashSet<Unite>>();
+      HashMap<Integer, HashSet<Unite>> fins = new HashMap<Integer, HashSet<Unite>>();
+      HashSet<Integer> bornes = new HashSet<Integer>();
+      HashMap<Unite, Boolean> multis = new HashMap<Unite, Boolean>();
+      typesMarquage.clear();
+      for (TypeMarquage typeM : typesMarq)
+        for (Unite unit : unites.get(typeM)) {
+          if (!typesMarquage.containsKey(unit)) {
+            typesMarquage.put(unit, new ArrayList<TypeMarquage>());
+            typesMarquage.get(unit).add(typeM);
+            multis.put(unit, false);
+          } else {
+            ArrayList<TypeMarquage> types = typesMarquage.get(unit);
+            if (!types.get(types.size()-1).equals(typeM)) types.add(typeM);
+            else if (types.size()==1) multis.put(unit, true);
+          }
+          int deb = panneauTexte.indexToPosition(unit.getDeb());
+          int fin = panneauTexte.indexToPosition(unit.getFin());
+          bornes.add(deb);
+          bornes.add(fin);
+          if (!debs.containsKey(deb)) debs.put(deb, new HashSet<Unite>());
+          debs.get(deb).add(unit);
+          if (!fins.containsKey(fin)) fins.put(fin, new HashSet<Unite>());
+          fins.get(fin).add(unit);
+        }
+      Integer[] brnes = bornes.toArray(new Integer[0]);
+      Arrays.sort(brnes);
+      ArrayList<Unite> units = new ArrayList<Unite>();
+      ArrayList<int[]> intervlles = new ArrayList<int[]>();
+      ArrayList<Unite[]> unitsIntervalle = new ArrayList<Unite[]>();
+      ArrayList<AttributeSet> attIntervalle = new ArrayList<AttributeSet>();
+      int deb = 0;  // début d'un intervalle
+      int lg = 0;   // longueur d'un intervalle
+      for (int borne : brnes) {
+        if (!units.isEmpty()) {
+          lg = borne-deb;
+          intervlles.add(new int[]{deb, lg});
+          unitsIntervalle.add(ordonnerUnites(units));
+          attIntervalle.add(choisirAttribut(units, multis));
+        }
+        if (debs.containsKey(borne)) for (Unite unit : debs.get(borne))
+            units.add(unit);
+        if (fins.containsKey(borne)) for (Unite unit : fins.get(borne))
+            units.remove(unit);
+        if (!units.isEmpty()) deb = borne;
+      }
+      intervalles = intervlles.toArray(new int[0][]);
+      unitesIntervalles = unitsIntervalle.toArray(new Unite[0][]);
+      attributIntervalles = attIntervalle.toArray(new AttributeSet[0]);
+    }
+
+    private Unite[] ordonnerUnites(ArrayList<Unite> units) {
+      Unite[] unites = new Unite[units.size()];
+      unites[0] = units.get(0);
+      for (int i = 1; i<unites.length; i++) {
+        if (units.get(i).getFin()-units.get(i).getDeb()>=unites[0].getFin()-unites[0].getDeb())
+          unites[i] = units.get(i);
+        else {
+          unites[i] = unites[0];
+          unites[0] = units.get(i);
+        }
+      }
+      return unites;
+    }
+
+    private AttributeSet choisirAttribut(ArrayList<Unite> units, HashMap<Unite, Boolean> multis) {
+      AttributeSet att;
+      if (units.size()==1) {
+        att = multis.get(units.get(0)) ? typesMarquage.get(units.get(0)).get(0).attributMulti : typesMarquage.get(units.get(0)).get(0).attribut;
+      } else {
+        att = typesMarquage.get(units.get(0)).get(0).attributMulti;
+        int niv = typesMarquage.get(units.get(0)).get(0).niveau;
+        for (int i = 1; i<units.size(); i++) {
+          if (typesMarquage.get(units.get(i)).get(0).niveau<niv) {
+            att = typesMarquage.get(units.get(i)).get(0).attributMulti;
+            niv = typesMarquage.get(units.get(i)).get(0).niveau;
+          }
+        }
+      }
+      return att;
+    }
+
+    public Unite[] getUnitesVisees(int pos) {   // peut être améliorée par une recherche dichotomique
+      for (int i = 0; i<intervalles.length; i++) {
+        int[] interv = intervalles[i];
+        if (pos<interv[0]) return new Unite[0];
+        if (pos<interv[0]+interv[1]) return unitesIntervalles[i];
+      }
+      return new Unite[0];
+    }
+
+    public Unite getUniteVisee(int pos) {   // peut être améliorée par une recherche dichotomique
+      Unite[] units = getUnitesVisees(pos);
+      if (units.length==0) return null;
+      return units[0];
+    }
+
+    public TypeMarquage getMarquage(Unite unit) {
+      return typesMarquage.get(unit).get(0);
+    }
+
+    public ArrayList<TypeMarquage> getMarquages(Unite unit) {
+      return typesMarquage.get(unit);
+    }
+  }
+  // Champs de la classe PanneauTexte
+  protected SimpleAttributeSet AttributsStandard;
+  final static String CAR_FIN_PARAGRAPHE = "[\u00b6] ";
+  protected Corpus corpus;
+  protected StyledDocument doc;
+  protected Coloriage coloriage = null;
+  protected ArrayList<Integer> posNewLines = new ArrayList<Integer>();
+
+  public PanneauTexte(Corpus corpus) {
+    super();
+    this.corpus = corpus;
+    AttributsStandard = new SimpleAttributeSet(STANDARD_DEFAUT);
+    doc = getStyledDocument();
+    setText("");
+    ToolTipManager.sharedInstance().registerComponent(this);
+  }
+
+  @Override
+  public JToolTip createToolTip() {
+    JToolTip jt = new JToolTip();
+    jt.setBackground(JAUNE_TRES_CLAIR);
+    return jt;
+  }
+
+  public SimpleAttributeSet getAttributsStandard() {
+    return AttributsStandard;
+  }
+
+  public void setAttributsStandard(SimpleAttributeSet att) {
+    AttributsStandard = att;
+  }
+
+//  private int debParag;
+//  public void setTexteVisu() {
+//    final String texte = corpus.getTexte();
+//    posNewLines.clear();
+//    debParag = 0;
+//    final Integer[] finPars = corpus.getFinParagraphes();
+//    final StringBuffer newTexte = new StringBuffer(texte.length()+finPars.length);
+//    final GMessages.GProgression progression =
+//            new GMessages.GProgression(finPars.length, "paragraphes");
+//    Thread traitement = new Thread() {
+//      @Override
+//      public void run() {
+//        for (int i = 0; i<finPars.length; i++) {
+//          //           if(progression.isCanceled()) break;
+//          newTexte.append(texte.substring(debParag, finPars[i])).append("\n");
+//          posNewLines.add(newTexte.length()-1);
+//          debParag = finPars[i];
+//         progression.setNbTraites(i+1);
+//         }
+//        setText(new String(newTexte));
+//        revalidate();
+//        repaint();
+//      }
+//    };
+//    traitement.start();
+//  }
+//  
+  public void setTexteVisu() {
+    final String texte = corpus.getTexte();
+    posNewLines.clear();
+    int debParag = 0;
+    Integer[] finPars = corpus.getFinParagraphes();
+    StringBuffer newTexte = new StringBuffer(texte.length()+finPars.length);
+    for (int i = 0; i<finPars.length; i++) {
+      //           if(progression.isCanceled()) break;
+      newTexte.append(texte.substring(debParag, finPars[i])).append("\n");
+      posNewLines.add(newTexte.length()-1);
+      debParag = finPars[i];
+    }
+    setText(new String(newTexte));
+    revalidate();
+    repaint();
+  }
+
+  private int getYHautAff() {
+    return ((JViewport) getParent()).getViewPosition().y;
+  }
+
+  private void setYHautAff(int y) {
+    ((JViewport) getParent()).setViewPosition(new Point(0, y));
+  }
+
+  public void initAscenseur() {
+    setYHautAff(0);
+    setCaretPosition(0);
+  }
+
+  public void ajusterAscenseur(PanneauTexte panneau) {
+    setYHautAff(panneau.getYHautAff());
+    setCurseur(panneau.getCaretPosition());
+  }
+
+  public void setCurseur(int pos) {
+    int ymax = getYHautAff()+((JViewport) getParent()).getViewSize().height;
+    pos = Math.max(pos, viewToModel(new Point(0, getYHautAff())));
+    pos = Math.min(pos, viewToModel(new Point(0, ymax)));
+    setCaretPosition(pos);
+  }
+
+  protected void placerAscenseur(Unite unite) {
+    int posdeb = indexToPosition(unite.getDeb());
+    placerAscenseur(posdeb, indexToPosition(unite.getFin()));
+    setCaretPosition(posdeb);
+  }
+
+  protected void placerAscenseur(int posdeb, int posfin) {
+    try {
+      Rectangle rectdeb = modelToView(posdeb);
+      Rectangle rectfin = modelToView(posfin);
+      int hligne = rectdeb.height;
+      int yhaut = rectdeb.y;
+      int ybas = rectfin.y+hligne;
+      int y0 = getYHautAff();
+      int h = ((JViewport) getParent()).getExtentSize().height;
+      if (yhaut<y0||ybas>y0+h) {
+        setYHautAff(Math.max(0, modelToView(posdeb).y-h/3));
+      }
+    } catch (BadLocationException ex) {
+      System.out.println("Erreur dans placerAscenseur : "+ex.getLocalizedMessage());
+     // System.exit(1);
+    }
+  }
+
+  public int[] getIndSelection() {
+    int deb = getSelectionStart();
+    int fin = getSelectionEnd();
+    if (deb==fin) return null;
+    return new int[]{positionToIndex(deb), positionToIndex(fin)};
+  }
+
+  protected int indexToPosition(int ind) {
+    int nbnl = 0;
+    for (int finParag : corpus.getFinParagraphes()) {
+      if (ind<finParag) {
+        break;
+      }
+      nbnl++;
+    }
+    return ind+nbnl;
+  }
+
+  protected int positionToIndex(int pos) {
+    int nbnl = 0;
+    for (int posnl : posNewLines) {
+      if (pos<=posnl) {
+        break;
+      }
+      nbnl++;
+    }
+    return pos-nbnl;
+  }
+
+  public void colorierUnites(UniteColoree[] unitsCol) {
+    coloriage.creerColoriage(unitsCol);
+  }
+  // Ordre de masquage décroissant : si une unité est présente dans plusieurs types de marquage, 
+  // seule sa première mention sera prise en compte 
+
+  protected void marquerUnites(Marquage marquage, TypeMarquage[] typesMarq, EnumMap<TypeMarquage, Unite[]> unites) {
+    doc.setCharacterAttributes(0, getText().length(), AttributsStandard, true);
+    doc.setParagraphAttributes(0, getText().length(), AttributsStandard, true);
+    if (coloriage!=null&&typesMarq.length==0)
+      for (int i = 0; i<coloriage.intervalles.length; i++)
+        doc.setCharacterAttributes(
+                coloriage.intervalles[i][0], coloriage.intervalles[i][1], coloriage.attributIntervalles[i], false);
+    marquage.creerMarquage(typesMarq, unites);
+    for (int i = 0; i<marquage.intervalles.length; i++)
+      doc.setCharacterAttributes(
+              marquage.intervalles[i][0], marquage.intervalles[i][1], marquage.attributIntervalles[i], false);
+  }
+
+  protected Unite getUniteVisee(Marquage marquage, Point pt) {
+    return marquage.getUniteVisee(viewToModel(pt));
+  }
+
+  protected Unite[] getUnitesVisees(Marquage marquage, Point pt) {
+    return marquage.getUnitesVisees(viewToModel(pt));
+  }
+
+//  public static int[] calculerNoParagraphe(Unite[] unites, Integer[] finPar) {
+//    // les unites sont triées
+//    // les numéros de paragraphe commencent à 1 
+//    int[] nosPar = new int[unites.length];
+//    int nopar = 0;
+//    for (int i = 0; i<unites.length; i++) {
+//      while (unites[i].getDeb()>finPar[nopar]) nopar++;
+//      nosPar[i] = nopar+1;
+//    }
+//    return nosPar;
+//  }
+//
+  public static String insereCarFinParagraphe(String texte, Integer[] finPar, int offset) {
+    for (int ind : finPar) {
+      ind -= offset;
+      if (ind<=0) continue;
+      if (ind>=texte.length()) break;
+      texte = texte.substring(0, ind)+PanneauTexte.CAR_FIN_PARAGRAPHE+texte.substring(ind);
+      offset -= CAR_FIN_PARAGRAPHE.length();
+    }
+    return texte;
+  }
+
+  public String getTexteUnite(Unite unit) {  // utilisé pour les tooltips et les popups : à revoir
+    int deb = unit.getDeb();
+    int fin = unit.getFin();
+    return insereCarFinParagraphe(corpus.getTexte().substring(deb, fin), corpus.getFinParagraphes(), deb);
+  }
+
+  protected void setTexteCorpus() {
+    String newTexte = "";
+    ArrayList<Integer> newFinParag = new ArrayList<Integer>();
+    String texte = getText();
+    if (posNewLines.isEmpty()||posNewLines.get(posNewLines.size()-1)!=texte.length()-1) {
+      posNewLines.add(texte.length());
+    }
+    int debParag = 0;
+    for (int posnl : posNewLines) {
+      newTexte += texte.substring(debParag, posnl);
+      newFinParag.add(newTexte.length());
+      debParag = posnl+1;
+    }
+    corpus.modifTexte(newTexte, newFinParag);
+  }
+
+  public void rechercherTexte(String chaine) {
+    getCaret().setSelectionVisible(true);
+    String texte = getText();
+    int pos = texte.indexOf(chaine, getCaretPosition());
+    if (pos<0) pos = texte.indexOf(chaine);
+    if (pos>=0) {
+      placerAscenseur(pos, pos+chaine.length());
+      setCaretPosition(pos);
+      moveCaretPosition(pos+chaine.length());
+    } else moveCaretPosition(getCaretPosition());
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/VisuStyleTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/VisuStyleTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/VisuStyleTexte.java	(revision 481)
@@ -0,0 +1,213 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.text.*;
+import visuAnalec.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu;
+import visuAnalec.util.GVisu.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class VisuStyleTexte extends JFrame {
+  private static VisuStyleTexte instance = null;
+  private PanneauEditeur pEditeur;
+  private SimpleAttributeSet att;
+  JComboBox saisieTaille;
+  JComboBox saisiePolice;
+  JCheckBox saisieGras;
+  JCheckBox saisieItalique;
+  JCheckBox saisieSouligne;
+  CouleurComboBox saisieCouleur;
+  CouleurComboBox saisieFond;
+  JComboBox saisieInterligne;
+  JComboBox saisieEspaceAvant;
+  JComboBox saisieEspaceApres;
+  JComboBox saisieAlignement;
+  JComboBox saisieIndentGauche;
+  JComboBox saisieIndentDroite;
+  JComboBox saisieIndentPrem;
+  public static void newVisuStyleTexte(PanneauEditeur pEditeur, SimpleAttributeSet att) {
+    if (instance != null) instance.dispose();
+    instance = new VisuStyleTexte(pEditeur, att);
+
+  }
+  private VisuStyleTexte(PanneauEditeur pEditeur, SimpleAttributeSet att) {
+    super("Gestion du style du texte");
+    Container fen = pEditeur.getTopLevelAncestor();
+    Point pos = new Point(fen.getX() + 200, fen.getY() + 50);
+    setLocation(pos);
+    this.pEditeur = pEditeur;
+    this.att = att;
+    JPanel pStyleCaracteres = new JPanel(new GridLayout(0, 2, 2, 4));
+    pStyleCaracteres.setBorder(new TitledBorder("Caractères"));
+    pStyleCaracteres.add(new JLabel("Police", JLabel.TRAILING));
+    String[] polices = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
+    saisiePolice = new JComboBox(polices);
+    saisiePolice.setPrototypeDisplayValue("Times New Roman");
+    saisiePolice.setEditable(false);
+    saisiePolice.setSelectedItem(StyleConstants.getFontFamily(att));
+    saisiePolice.setMaximumSize(new Dimension(40, 100));
+    pStyleCaracteres.add(saisiePolice);
+    pStyleCaracteres.add(new JLabel("Taille (pts)", JLabel.TRAILING));
+    saisieTaille = new JComboBox(new String[]{"4", "8", "10", "12", "14", "16", "20"});
+    saisieTaille.setEditable(true);
+    saisieTaille.setSelectedItem(Integer.toString(StyleConstants.getFontSize(att)));
+    pStyleCaracteres.add(saisieTaille);
+    pStyleCaracteres.add(new JLabel("Couleur", JLabel.TRAILING));
+    saisieCouleur = new CouleurComboBox(GVisu.getCouleursEtNoirEtBlanc());
+    saisieCouleur.setEditable(true);
+    saisieCouleur.setSelectedItem(StyleConstants.getForeground(att));
+    pStyleCaracteres.add(saisieCouleur);
+    pStyleCaracteres.add(new JLabel("Surbrillance", JLabel.TRAILING));
+    saisieFond = new CouleurComboBox(GVisu.getCouleursEtNoirEtBlanc());
+    saisieFond.setEditable(true);
+    saisieFond.setSelectedItem(StyleConstants.getBackground(att));
+    pStyleCaracteres.add(saisieFond);
+    pStyleCaracteres.add(new JLabel("Caractères gras", JLabel.TRAILING));
+    saisieGras = new JCheckBox("", StyleConstants.isBold(att));
+    pStyleCaracteres.add(saisieGras);
+    pStyleCaracteres.add(new JLabel("italiques", JLabel.TRAILING));
+    saisieItalique = new JCheckBox("", StyleConstants.isItalic(att));
+   pStyleCaracteres.add(saisieItalique);
+    pStyleCaracteres.add(new JLabel("soulignés", JLabel.TRAILING));
+    saisieSouligne = new JCheckBox("", StyleConstants.isUnderline(att));
+    saisieSouligne.setHorizontalTextPosition(SwingConstants.LEADING);
+    pStyleCaracteres.add(saisieSouligne);
+    JPanel pStyleParagraphes = new JPanel(new GridLayout(0,2,2,4));
+    pStyleParagraphes.setBorder(new TitledBorder("Paragraphes"));
+    pStyleParagraphes.add(new JLabel("Alignement", JLabel.TRAILING));
+    saisieAlignement = new JComboBox(PanneauTexte.nomsAlignement());
+    saisieAlignement.setEditable(false);
+    saisieAlignement.setSelectedItem(PanneauTexte.nomAlignement(StyleConstants.getAlignment(att)));
+    pStyleParagraphes.add(saisieAlignement);
+    pStyleParagraphes.add(new JLabel("Interligne (pts)", JLabel.TRAILING));
+    saisieInterligne = new JComboBox(new String[]{"-0.2", "0", "0.2", "0.5", "1.0", "1.5", "2"});
+    saisieInterligne.setEditable(true);
+    saisieInterligne.setSelectedItem(Float.toString(StyleConstants.getLineSpacing(att)));
+    pStyleParagraphes.add(saisieInterligne);
+    pStyleParagraphes.add(new JLabel("Espacement avant (pts)", JLabel.TRAILING));
+    saisieEspaceAvant = new JComboBox(new String[]{"0.0", "2.0", "5.0", "10.0", "15.0", "20.0"});
+    saisieEspaceAvant.setEditable(true);
+    saisieEspaceAvant.setSelectedItem(Float.toString(StyleConstants.getSpaceAbove(att)));
+    pStyleParagraphes.add(saisieEspaceAvant);
+    pStyleParagraphes.add(new JLabel("après (pts)", JLabel.TRAILING));
+    saisieEspaceApres = new JComboBox(new String[]{"0.0", "2.0", "5.0", "10.0", "15.0", "20.0"});
+    saisieEspaceApres.setEditable(true);
+    saisieEspaceApres.setSelectedItem(Float.toString(StyleConstants.getSpaceBelow(att)));
+    pStyleParagraphes.add(saisieEspaceApres);
+    pStyleParagraphes.add(new JLabel("Retrait gauche (pts)", JLabel.TRAILING));
+    saisieIndentGauche = new JComboBox(new String[]{"0.0", "2.0", "5.0", "10.0", "15.0", "20.0"});
+    saisieIndentGauche.setEditable(true);
+    saisieIndentGauche.setSelectedItem(Float.toString(StyleConstants.getLeftIndent(att)));
+    pStyleParagraphes.add(saisieIndentGauche);
+    pStyleParagraphes.add(new JLabel("droit (pts)", JLabel.TRAILING));
+    saisieIndentDroite = new JComboBox(new String[]{"0.0", "2.0", "5.0", "10.0", "15.0", "20.0"});
+    saisieIndentDroite.setEditable(true);
+    saisieIndentDroite.setSelectedItem(Float.toString(StyleConstants.getRightIndent(att)));
+    pStyleParagraphes.add(saisieIndentDroite);
+    pStyleParagraphes.add(new JLabel("1ère ligne (pts)", JLabel.TRAILING));
+    saisieIndentPrem = new JComboBox(new String[]{"0.0", "2.0", "5.0", "10.0", "15.0", "20.0"});
+    saisieIndentPrem.setEditable(true);
+    saisieIndentPrem.setSelectedItem(Float.toString(StyleConstants.getFirstLineIndent(att)));
+    pStyleParagraphes.add(saisieIndentPrem);
+   Box pSaisieItems = Box.createHorizontalBox();
+   pSaisieItems.add(pStyleCaracteres);
+    pSaisieItems.add(Box.createHorizontalGlue());
+    pSaisieItems.add(pStyleParagraphes);
+   JPanel  pCommandesValidation = new JPanel(new FlowLayout(FlowLayout.CENTER));
+    JButton valideModifs = new JButton(
+            new GAction("Valider") {
+              public void executer() {
+                validerModifs();
+              }
+              ;
+            });
+    JButton annuleModifs = new JButton(
+            new GAction("Annuler") {
+              public void executer() {
+                dispose();
+              }
+              ;
+            });
+    pCommandesValidation.add(valideModifs);
+    pCommandesValidation.add(annuleModifs);
+    // cadre global de la fenêtre
+    JPanel cadre = new JPanel(new BorderLayout());
+    cadre.add(pStyleCaracteres, BorderLayout.WEST);
+   cadre.add(pStyleParagraphes, BorderLayout.EAST);
+    cadre.add(pCommandesValidation, BorderLayout.SOUTH);
+    setContentPane(cadre);
+    pack();
+    setVisible(true);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+      }
+    });
+  }
+  private void validerModifs() {
+    int entierSaisi;
+    float decimalSaisi;
+    StyleConstants.setFontFamily(att, (String) saisiePolice.getSelectedItem());
+    StyleConstants.setForeground(att, (Color) saisieCouleur.getSelectedItem());
+    StyleConstants.setBackground(att, (Color) saisieFond.getSelectedItem());
+    try {
+      entierSaisi = Integer.parseInt((String) saisieTaille.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      entierSaisi = StyleConstants.getFontSize(att);
+    }
+    StyleConstants.setFontSize(att, entierSaisi);
+    StyleConstants.setBold(att, (boolean) saisieGras.isSelected());
+    StyleConstants.setItalic(att, (boolean) saisieItalique.isSelected());
+    StyleConstants.setUnderline(att, (boolean) saisieSouligne.isSelected());
+    StyleConstants.setAlignment(att, PanneauTexte.codeAlignement((String) saisieAlignement.getSelectedItem()));
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieEspaceAvant.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = StyleConstants.getSpaceAbove(att);
+    }
+    StyleConstants.setSpaceAbove(att, decimalSaisi);
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieEspaceApres.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = StyleConstants.getSpaceBelow(att);
+    }
+    StyleConstants.setSpaceBelow(att, decimalSaisi);
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieIndentGauche.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = StyleConstants.getLeftIndent(att);
+    }
+    StyleConstants.setLeftIndent(att, decimalSaisi);
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieIndentDroite.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = StyleConstants.getRightIndent(att);
+    }
+    StyleConstants.setRightIndent(att, decimalSaisi);
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieIndentPrem.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = StyleConstants.getFirstLineIndent(att);
+    }
+    StyleConstants.setFirstLineIndent(att, decimalSaisi);
+    try {
+      decimalSaisi = Float.parseFloat((String) saisieInterligne.getSelectedItem());
+    } catch (NumberFormatException numberFormatException) {
+      decimalSaisi = (Float) StyleConstants.getLineSpacing(att);
+    }
+    StyleConstants.setLineSpacing(att, decimalSaisi);
+    pEditeur.changerStyleTexte(att);
+    dispose();
+  }
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/VisuStyleTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauOccurrences.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauOccurrences.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauOccurrences.java	(revision 481)
@@ -0,0 +1,172 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import visuAnalec.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class PanneauOccurrences extends JTable implements ListSelectionListener {
+  ModeleTableauOcc modele;
+  ModeleTableur modeleTableur;
+  Vue vue;
+  PanneauEditeur pEditeur;
+  Element[] listElt;
+  final static int EMPAN = 80;  // paramètre à saisir (un jour)
+  public PanneauOccurrences(Vue vue, PanneauEditeur pEditeur) {
+    super();
+    modele = new ModeleTableauOcc();
+    setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+    setModel(modele);
+    modeleTableur = new ModeleTableur();
+    getSelectionModel().addListSelectionListener(this);
+    this.vue = vue;
+    this.pEditeur = pEditeur;
+  }
+  public TableModel getModeleTableur() {
+    return modeleTableur;
+  }
+  public void initVide() {
+    listElt = new Element[0];
+    getTableHeader().setVisible(false);
+    modele.clear();
+    modeleTableur.clear();
+  }
+  public void init(Class<? extends Element> classe, String type, Element[] listElt) {
+    this.listElt = listElt;
+    if (listElt.length==0) {
+      initVide();
+      return;
+    }
+    getTableHeader().setVisible(true);
+    String[] ids = vue.getIdListeElements(classe, type, listElt);
+    String[][] concordances = vue.getCorpus().getConcordances(listElt, EMPAN);
+    String[] champs = vue.getNomsChamps(classe, type);
+    String[][] valeurs = vue.getValeursChampsListeElements(champs, listElt);
+    modele.setModele(ids, concordances);
+    modeleTableur.setModele(ids, concordances, champs, valeurs);
+    getColumnModel().getColumn(0).setPreferredWidth(150);
+    getColumnModel().getColumn(1).setMinWidth(1200);
+  }
+  @Override
+  public void valueChanged(ListSelectionEvent evt) {
+    try {
+      if (evt.getValueIsAdjusting()) return;
+      if (evt.getSource().equals(getSelectionModel())) {
+        int row = getSelectedRow();
+        if (row>=0) pEditeur.editerElement(listElt[row]);
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.toString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  private static class ModeleTableauOcc extends AbstractTableModel {
+    final static String STYLE_HTML = "<html>";
+    final static String STYLE_DEB_SELECT =
+            "<span style=\"font-weight:bold; background-color:#FFFF80\">";
+    final static String STYLE_FIN_SELECT = "</span>";
+    String[] ids;
+    String[] extraits;
+    public ModeleTableauOcc() {
+      super();
+      clear();
+    }
+    public int getRowCount() {
+      return ids.length;
+    }
+    public int getColumnCount() {
+      return 2;
+    }
+    @Override
+    public String getColumnName(int columnIndex) {
+      return columnIndex==0 ? "Identifiants" : "Occurrences";
+    }
+    public Object getValueAt(int rowIndex, int columnIndex) {
+      return columnIndex==0 ? ids[rowIndex] : extraits[rowIndex];
+
+    }
+    private void clear() {
+      ids = new String[0];
+    }
+    private void setModele(String[] ids, String[][] concordances) {
+      this.ids = ids;
+      extraits = new String[ids.length];
+      for (int i = 0; i<ids.length; i++)
+        extraits[i] = formerExtrait(concordances[i]);
+      fireTableDataChanged();
+    }
+    private String formerExtrait(String[] concordance) {
+      return STYLE_HTML+concordance[0]+STYLE_DEB_SELECT+concordance[1]
+              +STYLE_FIN_SELECT+concordance[2];
+    }
+  }
+
+  private static class ModeleTableur extends AbstractTableModel {
+    String[] ids;
+    String[][] concordances;
+    String[] champs;
+    String[][] valeurs;
+    public ModeleTableur() {
+      super();
+      clear();
+    }
+    public int getRowCount() {
+      return ids.length;
+    }
+    public int getColumnCount() {
+      return 4+champs.length;
+    }
+    @Override
+    public String getColumnName(int columnIndex) {
+      switch (columnIndex) {
+        case 0:
+          return "Identifiants";
+        case 1:
+          return "Contexte gauche";
+        case 2:
+          return "Elément";
+        case 3:
+          return "Contexte droit";
+        default:
+          return champs[columnIndex-4];
+      }
+    }
+    public Object getValueAt(int rowIndex, int columnIndex) {
+      switch (columnIndex) {
+        case 0:
+          return ids[rowIndex];
+        case 1:
+        case 2:
+        case 3:
+          return concordances[rowIndex][columnIndex-1];
+        default:
+          return valeurs[rowIndex][columnIndex-4];
+      }
+
+    }
+    private void clear() {
+      champs = ids = new String[0];
+    }
+    private void setModele(String[] ids, String[][] concordances,
+            String[] champs, String[][] valeurs) {
+      this.ids = ids;
+      this.concordances = concordances;
+      this.champs = champs;
+      this.valeurs = valeurs;
+      fireTableDataChanged();
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauOccurrences.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauCommandesModifTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauCommandesModifTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauCommandesModifTexte.java	(revision 481)
@@ -0,0 +1,58 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.texte;
+
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.Message.*;
+import visuAnalec.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class PanneauCommandesModifTexte extends Box  {
+  Vue vue;
+  PanneauModifTexte panneauTexte;
+  PanneauEditeur panneauEditeur;
+ public PanneauCommandesModifTexte( PanneauEditeur pEditeur, Vue vue, PanneauModifTexte pTexte) {
+    super(BoxLayout.X_AXIS);
+    this.panneauEditeur = pEditeur;
+    this.vue = vue;
+    this.panneauTexte = pTexte;
+        add(Box.createHorizontalGlue());
+    add( new JButton(new GAction("Valider") {
+      public void executer() {
+        validerModifTexte();
+        panneauEditeur.finModifTexte();
+      }
+    }));
+    add(Box.createHorizontalGlue());
+    add( new JButton(new GAction("Annuler") {
+      public void executer() {
+        panneauEditeur.finModifTexte();
+    }
+    }));
+    add(Box.createHorizontalGlue());
+  }
+ void validerModifTexte() {
+   int nbSupprimes = panneauTexte.preparerValiderModifTexte();
+  if (nbSupprimes > 0) {
+      int rep = JOptionPane.showOptionDialog(getTopLevelAncestor(),
+              "Les modifications du texte vont entraîner la suppression " +
+              (nbSupprimes == 1 ? "d'une unité" : "de " + nbSupprimes + " unités"), "Suppression d'unités",
+              JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+              null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+      if (rep == 1) return;
+    }
+    panneauTexte.validerModifTexte();
+  }
+ }

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauCommandesModifTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauAffChainesTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauAffChainesTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauAffChainesTexte.java	(revision 481)
@@ -0,0 +1,77 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.texte;
+
+import java.awt.event.*;
+import java.util.*;
+import visuAnalec.chaines.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class PanneauAffChainesTexte extends PanneauTexte {
+  private ListenerSourisTexte sourisListener;
+  private VisuChaines visuChaines;
+  private Marquage marquage;
+  public PanneauAffChainesTexte(Corpus corpus, VisuChaines visuChaines) {
+    super(corpus);
+    setEditable(false);
+    this.visuChaines = visuChaines;
+    setSourisListener(visuChaines);
+    marquage = new Marquage(this);
+  }
+  protected void setSourisListener(VisuChaines vChaines) {
+    sourisListener = new ListenerSourisTexte(this, vChaines);
+    addMouseListener(sourisListener);
+  }
+  public void pasDeMarquage() {
+    marquerUnites(marquage, new TypeMarquage[0], null);
+  }
+  public void montrerUnite(Unite unit, TypeMarquage typeSelectUnite) {
+    TypeMarquage[] typesMarq = new TypeMarquage[]{typeSelectUnite};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(typeSelectUnite, new Unite[]{unit});
+    marquerUnites(marquage, typesMarq, unites);
+    placerAscenseur(unit);
+  }
+  public void montrerUnite(Unite unit, TypeMarquage typeSelectUnite, Unite[] unitsChaine,
+          TypeMarquage typeSelectChaine) {
+    TypeMarquage[] typesMarq = new TypeMarquage[]{typeSelectUnite, typeSelectChaine};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(typeSelectUnite, new Unite[]{unit});
+    unites.put(typeSelectChaine, unitsChaine);
+    marquerUnites(marquage, typesMarq, unites);
+    placerAscenseur(unit);
+  }
+  public void colorerUnites(Unite[] units, TypeMarquage typeColorChaines) {
+    TypeMarquage[] typesMarq = new TypeMarquage[]{typeColorChaines};
+    EnumMap<TypeMarquage, Unite[]> unites = new EnumMap<TypeMarquage, Unite[]>(TypeMarquage.class);
+    unites.put(typeColorChaines, units);
+    marquerUnites(marquage, typesMarq, unites);
+  }
+
+  protected static class ListenerSourisTexte extends MouseAdapter {
+    private PanneauAffChainesTexte panneauTexte;
+    private VisuChaines visuChaines;
+    public ListenerSourisTexte(PanneauAffChainesTexte pTexte, VisuChaines vChaines) {
+      this.panneauTexte = pTexte;
+      this.visuChaines = vChaines;
+    }
+    @Override
+    public void mouseClicked(MouseEvent e) {
+ try {
+   Unite uniteVisee = panneauTexte.getUniteVisee(panneauTexte.marquage, e.getPoint());
+      if (uniteVisee == null)  visuChaines.traiterAffTexteClicVide();
+      else  if (e.getClickCount() == 2) visuChaines.traiterAffTexteDoubleClic(uniteVisee);
+     } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+   }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/texte/PanneauAffChainesTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/ModeleChaines.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/ModeleChaines.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/ModeleChaines.java	(revision 481)
@@ -0,0 +1,258 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.chaines;
+
+import java.awt.*;
+import java.util.*;
+import java.util.ArrayList;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class ModeleChaines {
+  static class Chainon {
+    Unite unite;
+    String texte;
+    Schema chaine = null;
+    int nbEltsChaine = 0;
+    String idChaine = "";
+    int noChaine = 0;
+    Chainon(Unite unite, String texte) {
+      this.unite = unite;
+      this.texte = texte;
+    }
+  }
+  private Vue vue;
+  private GChaines panneauGraphique;
+  private Unite[] listeUnites;
+  private HashMap<Unite, Schema> chainesUnitesNonFiltrees =
+          new HashMap<Unite, Schema>();
+  private int[] seuilsValsNbElements = new int[0];
+  private HashMap<Unite, Chainon> chainonsUnites = new HashMap<Unite, Chainon>();
+  private HashMap<Schema, ArrayList<Unite>> unitesChaines =
+          new HashMap<Schema, ArrayList<Unite>>();
+  private HashMap<String, HashSet<String>> valsMasqueesChamp =
+          new HashMap<String, HashSet<String>>();
+  private HashSet<String> valNulleMasqueeChamp = new HashSet<String>();
+  private boolean[] valsMasqueesNbElements = new boolean[0];
+  public ModeleChaines(Vue vue, GChaines panneauGraphique) {
+    this.vue = vue;
+    this.panneauGraphique = panneauGraphique;
+  }
+  Schema getChaine(Unite unit) {
+    return chainonsUnites.get(unit).chaine;
+  }
+  Unite[] getUnites() {
+    return listeUnites;
+  }
+  Unite[] getUnitesChaine(Schema chaine) {
+    ArrayList<Unite> units = unitesChaines.get(chaine);
+    return units.toArray(new Unite[0]);
+  }
+  boolean isMasqueeValChamp(String champ, String val) {
+    return valsMasqueesChamp.containsKey(champ)
+            &&valsMasqueesChamp.get(champ).contains(val);
+  }
+  boolean isMasqueeValNulleChamp(String champ) {
+    return valNulleMasqueeChamp.contains(champ);
+  }
+  boolean isMasqueeValNbElements(int i) {
+    return valsMasqueesNbElements[i];
+  }
+  void demasquerToutesValsChamp(String champ) {
+    valsMasqueesChamp.get(champ).clear();
+    valNulleMasqueeChamp.remove(champ);
+  }
+  void demasquerToutesValsNbElts(String champ) {
+    for (int i = 0; i<valsMasqueesNbElements.length; i++) {
+      valsMasqueesNbElements[i] = false;  
+    }
+  }
+ void masquerAutresValsChamp(String typeunite, String champ, String val) {
+    for(String v: vue.getValeursChamp(Unite.class, typeunite, champ)) 
+      valsMasqueesChamp.get(champ).add(v);
+     valsMasqueesChamp.get(champ).remove(val);
+     valNulleMasqueeChamp.add(champ);
+  }
+ void masquerValChamp(boolean yes, String champ, String val) {
+    if (yes) valsMasqueesChamp.get(champ).add(val);
+    else valsMasqueesChamp.get(champ).remove(val);
+  }
+ void masquerValsNonNullesChamp(String typeunite, String champ) {
+    for(String v: vue.getValeursChamp(Unite.class, typeunite, champ)) 
+      valsMasqueesChamp.get(champ).add(v);
+     valNulleMasqueeChamp.remove(champ);
+  }
+  void masquerValNulleChamp(boolean yes, String champ) {
+    if (yes) valNulleMasqueeChamp.add(champ);
+    else valNulleMasqueeChamp.remove(champ);
+  }
+  void masquerAutresValsNbElts(String champ, int i0) {
+    for (int i = 0; i<valsMasqueesNbElements.length; i++) {
+      valsMasqueesNbElements[i] = i!=i0;  
+    }
+  }
+  void masquerValNbElements(boolean yes, int i) {
+    valsMasqueesNbElements[i] = yes;
+  }
+  void init(String typeChaines, String typeUnites, int[] seuils)
+          throws UnsupportedOperationException {
+    seuilsValsNbElements = seuils;
+    String[] champs = vue.getNomsChamps(Unite.class, typeUnites);
+    valsMasqueesChamp.clear();
+    for (String champ : champs)
+      valsMasqueesChamp.put(champ, new HashSet<String>());
+    valNulleMasqueeChamp.clear();
+    valsMasqueesNbElements = new boolean[seuils.length+3];
+    calculerChainesUnitesNonFiltrees(typeChaines, typeUnites);
+    calculerDonnees(typeChaines, typeUnites);
+  }
+  private void calculerChainesUnitesNonFiltrees(String typeChaines,
+          String typeUnites) throws UnsupportedOperationException {
+    chainesUnitesNonFiltrees.clear();
+    for (Schema chaine : vue.getSchemasAVoir(typeChaines))
+      for (Element elt : chaine.getContenu()) {
+        if (elt.getClass()==Unite.class&&elt.getType().equals(typeUnites)) {
+          if (chainesUnitesNonFiltrees.containsKey(elt)) {
+            throw new UnsupportedOperationException("L'unité "+vue.getIdElement(elt)
+                    +" appartient à deux chaînes : "+vue.getIdElement(chaine)+" et "
+                    +vue.getIdElement(chainesUnitesNonFiltrees.get((Unite) elt)));
+          } else
+            chainesUnitesNonFiltrees.put((Unite) elt, chaine);
+        }
+      }
+  }
+  void modifMasqueVals(String typeChaines, String typeUnites) {
+    calculerDonnees(typeChaines, typeUnites);
+  }
+  private void filtrerListeUnites(String typeUnites, String typeChaines) {
+    Unite[] unites = vue.getUnitesAVoir(typeUnites);
+    Schema[] chaines = vue.getSchemasAVoir(typeChaines);
+    unitesChaines.clear();
+    for (Schema chaine : chaines) unitesChaines.put(chaine, new ArrayList<Unite>());
+    ArrayList<Integer> indFiltrees = new ArrayList<Integer>();
+    String[] champs = vue.getNomsChamps(Unite.class, typeUnites);
+    boolean agarder;
+    for (int i = 0; i<unites.length; i++) {
+      agarder = true;
+      for (String champ : champs) {
+        String val = vue.getValeurChamp(unites[i], champ);
+        if (val.isEmpty()) {
+          if (valNulleMasqueeChamp.contains(champ)) {
+            agarder = false;
+            break;
+          }
+        } else {
+          if (valsMasqueesChamp.get(champ).contains(val)) {
+            agarder = false;
+            break;
+          }
+        }
+      }
+      if (agarder) {
+        indFiltrees.add(i);
+        if (chainesUnitesNonFiltrees.containsKey(unites[i])) {
+          Schema chaine = chainesUnitesNonFiltrees.get(unites[i]);
+          unitesChaines.get(chaine).add(unites[i]);
+        }
+      }
+    }
+    ArrayList<Integer> indIndFiltrees = new ArrayList<Integer>();
+    for(int k=0; k<indFiltrees.size(); k++) {
+      Unite unit = unites[indFiltrees.get(k)];
+      if(chainesUnitesNonFiltrees.containsKey(unit)) {
+        if(!isMasqueeValNbElements(calculerValNbElements(
+                unitesChaines.get(chainesUnitesNonFiltrees.get(unit)).size())))
+          indIndFiltrees.add(k);
+      } else {
+        if(!isMasqueeValNbElements(0)) indIndFiltrees.add(k);
+      }      
+    }
+    listeUnites = new Unite[indIndFiltrees.size()];
+    for (int k = 0; k<listeUnites.length; k++) {
+      listeUnites[k] = unites[indFiltrees.get(indIndFiltrees.get(k))];
+    }
+        for (Schema chaine : chaines) {
+          int nb = unitesChaines.get(chaine).size();
+          if(nb==0||isMasqueeValNbElements(calculerValNbElements(nb)))
+            unitesChaines.remove(chaine);
+        }
+  }
+  private void calculerDonnees(String typeChaines, String typeUnites) {
+     filtrerListeUnites(typeUnites, typeChaines);
+    Chainon[] chainons = new Chainon[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Unite unit = listeUnites[i];
+      chainons[i] = new Chainon(unit, vue.getTexteUnite(unit));
+      if(chainesUnitesNonFiltrees.containsKey(unit)) {
+        Schema chaine = chainesUnitesNonFiltrees.get(unit);
+        chainons[i].chaine = chaine;
+        chainons[i].nbEltsChaine = unitesChaines.get(chaine).size();
+        chainons[i].idChaine = vue.getIdElement(chaine);
+      } 
+      chainonsUnites.put(listeUnites[i], chainons[i]);
+    }
+    HashMap<Schema, Integer> noChaine = new HashMap<Schema, Integer>();
+    int no = 0;
+    for (Schema chaine : vue.getSchemasAVoir(typeChaines)) {
+      if(unitesChaines.containsKey(chaine)) {
+        int nbElts = unitesChaines.get(chaine).size(); 
+       noChaine.put(chaine, nbElts>1 ? ++no : 0);
+    }
+    }
+    for (Unite unit : listeUnites) {
+      Chainon chainon = chainonsUnites.get(unit);
+      if (chainon.chaine!=null) chainon.noChaine = noChaine.get(chainon.chaine);
+    }
+    int[] noPar = vue.getCorpus().calculerNoParagraphe(listeUnites);
+    panneauGraphique.setDonnees(chainons, noPar);
+  }
+  void initVide() {
+    listeUnites = new Unite[0];
+    chainesUnitesNonFiltrees.clear();
+    seuilsValsNbElements = new int[0];
+    chainonsUnites.clear();
+    unitesChaines.clear();
+    panneauGraphique.setDonnees(new Chainon[0], new int[0]);
+    panneauGraphique.setCouleurs(new Color[0]);
+    valNulleMasqueeChamp.clear();
+    valsMasqueesChamp.clear();
+    valsMasqueesNbElements = new boolean[0];
+  }
+  void setChampAffiche(String champ, HashMap<String, Color> couleursValeursChamp) {
+    panneauGraphique.setCouleurs(colorerChamp(champ, couleursValeursChamp));
+  }
+  void setChampAfficheNbElts(Color[] couleurs) {
+    panneauGraphique.setCouleurs(colorerNbElts(couleurs));
+  }
+  private Color[] colorerNbElts(Color[] couleurs) {
+    Color[] couls = new Color[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      if (ch.chaine==null) couls[i] = couleurs[0];
+      else {
+        int nbElts = ch.nbEltsChaine;
+        couls[i] = couleurs[calculerValNbElements(nbElts)];
+      }
+    }
+    return couls;
+  }
+  private Color[] colorerChamp(String champ, HashMap<String, Color> couleursValeursChamp) {
+    Color[] couls = new Color[listeUnites.length];
+    for (int i = 0; i<listeUnites.length; i++) {
+      Chainon ch = chainonsUnites.get(listeUnites[i]);
+      couls[i] = couleursValeursChamp.get(vue.getValeurChamp(ch.unite, champ));
+    }
+    return couls;
+  }
+  private int calculerValNbElements(int nbElts) {
+    return nbElts==1 ? 1 : nbElts<=seuilsValsNbElements[0] ? 2 : 
+            nbElts<=seuilsValsNbElements[1] ? 3 : 4;
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/ModeleChaines.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/GChaines.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/GChaines.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/GChaines.java	(revision 481)
@@ -0,0 +1,252 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.chaines;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.geom.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.chaines.ModeleChaines.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class GChaines extends JPanel {
+  final static Font FONTE_ID = Font.decode("Arial bold 10");
+  final static int RAYON_DISQUES = 6;
+  final static int MARGE_DISQUES = 2;
+  final static int LARGEUR_INTER_CHAINONS = 10;
+  final static int MARGE_DEBUT_LIGNE = 15;
+  final static int HAUTEUR_LIGNES = 80;
+  final static int HAUTEUR_SEGMENT = 40;
+  final static int HAUTEUR_CHAINONS = 60;
+  final static String SYMBOLE_SEGMENT = "§";
+//    final static int hauteurinfLien = 25;
+//    final static int deltahauteurLien = 5;
+//    final static int deltasupArcs = 95;
+//    final static int hauteurinfArcs = 5;
+//  final static int HAUTEUR_PANNEAU = 120;
+  final static String PAS_DE_NUMERO = "~";
+
+  static class GChainon extends JButton {
+    VisuChaines visu;
+    Chainon chainon;
+    public GChainon(Chainon ch, VisuChaines vis) {
+      super();
+      this.visu = vis;
+      this.chainon = ch;
+      Icon d = new DisqueCouleurIcone(Color.WHITE, RAYON_DISQUES, MARGE_DISQUES);
+      setAction(new GAction(null, d) {
+        public void executer() {
+          visu.afficherOccurrences(chainon.unite, chainon.chaine);
+        }
+      });
+      setSize(2*(RAYON_DISQUES+MARGE_DISQUES), 2*(RAYON_DISQUES+MARGE_DISQUES));
+      setBorderPainted(false);
+      String t2 = "<html><div style=\"font-size:11pt\"><span style=\"font-style:italic\">"+chainon.texte
+              +"</span><p>"+chainon.idChaine+"<p>"+chainon.nbEltsChaine+" occurences </div>";
+      setToolTipText(t2);
+      setBackground(Color.WHITE);
+      setFocusPainted(false);
+    }
+    @Override
+    public JToolTip createToolTip() {
+      JToolTip jt = new JToolTip();
+      jt.setBackground(Color.WHITE);
+      return jt;
+    }
+    void changerCouleur(Color couleur) {
+      setIcon(new DisqueCouleurIcone(couleur, RAYON_DISQUES, MARGE_DISQUES));
+    }
+  }
+
+  static class GNoChainon extends JLabel {
+    public GNoChainon(int noChaine) {
+      super(noChaine==0 ? PAS_DE_NUMERO : Integer.toString(noChaine));
+      setFont(FONTE_ID);
+      setSize(getPreferredSize());
+    }
+    void localiser(Point chainonPosition, Dimension chainonTaille) {
+      int x = chainonPosition.x+chainonTaille.width/2-getSize().width/2;
+      int y = chainonPosition.y-getSize().height;
+      setLocation(x, y);
+    }
+  }
+
+  private enum TypeSegment {
+    COMPLET("", ""),
+    DEBUT("", "-"),
+    MILIEU("-", "-"),
+    FIN("-", "");
+    String marqueAvant, marqueApres;
+    private TypeSegment(String avant, String apres) {
+      marqueAvant = avant;
+      marqueApres = apres;
+    }
+  }
+
+  static class GSegment extends JLabel {
+    int xmin, xmax;
+    int ybas, yhaut;
+    int no;
+    TypeSegment type;
+    GSegment(int xmin, int xmax, int ybas, int yhaut, int no, TypeSegment type) {
+      super(type.marqueAvant+SYMBOLE_SEGMENT+Integer.toString(no)+type.marqueApres);
+      setFont(FONTE_ID);
+      this.xmin = xmin;
+      this.xmax = xmax;
+      this.ybas = ybas;
+      this.yhaut = yhaut;
+      this.type = type;
+      setSize(getPreferredSize());
+    }
+    void localiser() {
+      setLocation((xmin+xmax)/2-getSize().width/2, yhaut-getSize().height);
+    }
+    void dessinerTraits(Graphics graphics) {
+      Graphics2D g = (Graphics2D) graphics;
+      g.setColor(Color.BLACK);
+      Point p0 = new Point(xmin, ybas);
+      Point p1 = new Point(xmin, yhaut);
+      Point p2 = new Point(xmax, yhaut);
+      Point p3 = new Point(xmax, ybas);
+      switch (type) {
+        case COMPLET:
+          g.draw(new Line2D.Float(p0, p1));
+          g.draw(new Line2D.Float(p1, p2));
+          g.draw(new Line2D.Float(p2, p3));
+          break;
+        case DEBUT:
+          g.draw(new Line2D.Float(p0, p1));
+          g.draw(new Line2D.Float(p1, p2));
+          break;
+        case FIN:
+          g.draw(new Line2D.Float(p1, p2));
+          g.draw(new Line2D.Float(p2, p3));
+          break;
+        case MILIEU:
+          g.draw(new Line2D.Float(p1, p2));
+          break;
+      }
+    }
+  }
+  /*
+   * Champs de la classeGChaines
+   */
+  VisuChaines visu;
+  Chainon[] chainons = new Chainon[0];
+  int[] noSegments = new int[0];
+  Color[] couleurs = new Color[0];
+  GChainon[] gChainons;
+  ArrayList<GSegment> gSegments = new ArrayList<GSegment>();
+  private int nbChainonsParLigne;
+  GChaines(VisuChaines vc) {
+    super((LayoutManager) null);
+    setBackground(Color.WHITE);
+    this.visu = vc;
+    addMouseListener(new MouseAdapter() {
+      @Override
+      public void mouseClicked(MouseEvent e) {
+        visu.traiterAffTexteClicVide();
+      }
+    });
+  }
+  void setNbChainonsParLigne(int nb) {
+    nbChainonsParLigne = nb;
+    afficher();
+    colorer();
+  }
+  void setDonnees(Chainon[] chainons, int[] noSegments) {
+    this.chainons = chainons;
+    this.noSegments = noSegments;
+    afficher();
+  }
+  private void afficher() {
+    effacerTout();
+    if (chainons.length==0) return;
+    gChainons = new GChainon[chainons.length];
+    int xCourant = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS;
+    int yCourant = 0;
+    GNoChainon gNoChainon;
+    int xminSeg = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS/2+2;
+    GSegment gseg;
+    int xmaxSeg = 0;
+    int xmaxligne = 0;
+    for (int i = 0; i<chainons.length; i++) {
+      gChainons[i] = new GChainon(chainons[i], visu);
+      add(gChainons[i]);
+      gChainons[i].setLocation(xCourant, yCourant+HAUTEUR_CHAINONS);
+      add(gNoChainon = new GNoChainon(chainons[i].noChaine));
+      gNoChainon.localiser(gChainons[i].getLocation(), gChainons[i].getSize());
+      xCourant += gChainons[i].getWidth()+LARGEUR_INTER_CHAINONS;
+      xmaxligne = Math.max(xCourant, xmaxligne);
+      xmaxSeg = xCourant-LARGEUR_INTER_CHAINONS/2-2;
+      if (i+1==chainons.length||noSegments[i+1]>noSegments[i]) {
+        // fin de paragraphe, donc on trace un segment terminal  
+        if (xminSeg>0) {  // le paragraphe a commencé sur cette ligne
+          add(gseg = new GSegment(xminSeg, xmaxSeg, yCourant+HAUTEUR_CHAINONS,
+                  yCourant+HAUTEUR_SEGMENT, noSegments[i], TypeSegment.COMPLET));
+        } else {  // le paragraphe a commencé avant cette ligne
+          xminSeg = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS/2+2;
+          add(gseg = new GSegment(xminSeg, xmaxSeg, yCourant+HAUTEUR_CHAINONS,
+                  yCourant+HAUTEUR_SEGMENT, noSegments[i], TypeSegment.FIN));
+        }
+        gseg.localiser();
+        gSegments.add(gseg);
+        xminSeg = xmaxSeg+4;
+      }
+      if (i+1!=chainons.length&&(i+1)%nbChainonsParLigne==0) {  // on va changer de ligne
+        if (xminSeg>xmaxSeg) {  // ça tombe bien : on change aussi de segment
+          xminSeg = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS/2+2;
+        } else { // ca tombe pas bien : il faut tracer un segment non terminal
+          if (xminSeg>0) { // le paragraphe a commencé sur cette ligne
+            add(gseg = new GSegment(xminSeg, xmaxSeg, yCourant+HAUTEUR_CHAINONS,
+                    yCourant+HAUTEUR_SEGMENT, noSegments[i], TypeSegment.DEBUT));
+          } else {  // le paragraphe a commencé avant cette ligne
+            xminSeg = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS/2+2;
+            add(gseg = new GSegment(xminSeg, xmaxSeg, yCourant+HAUTEUR_CHAINONS,
+                    yCourant+HAUTEUR_SEGMENT, noSegments[i], TypeSegment.MILIEU));
+          }
+          gseg.localiser();
+          gSegments.add(gseg);
+          xminSeg = -1;
+        }
+        xCourant = MARGE_DEBUT_LIGNE+LARGEUR_INTER_CHAINONS;
+        yCourant += HAUTEUR_LIGNES;
+      }
+    }
+    setPreferredSize(new Dimension(xmaxligne+30, yCourant+HAUTEUR_LIGNES+30));
+  }
+  void setCouleurs(Color[] couleurs) {
+    this.couleurs = couleurs;
+    colorer();
+  }
+  private void colorer() {
+    for (int i = 0; i<gChainons.length; i++) {
+      gChainons[i].changerCouleur(couleurs[i]);
+    }
+    revalidate();
+    repaint();
+  }
+  private void effacerTout() {
+    removeAll();
+    gChainons = new GChainon[0];
+    gSegments.clear();
+    repaint();
+  }
+  private void effacer(Graphics graphics) {
+    graphics.setColor(Color.WHITE);
+    graphics.fillRect(0, 0, getWidth(), getHeight());
+  }
+  @Override
+  protected void paintComponent(Graphics graphics) {
+    effacer(graphics);
+    for (GSegment gs : gSegments) gs.dessinerTraits(graphics);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/GChaines.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/VisuChaines.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/VisuChaines.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/VisuChaines.java	(revision 481)
@@ -0,0 +1,352 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.chaines;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.*;
+import visuAnalec.Message.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.texte.PanneauTexte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class VisuChaines extends JFrame implements VueListener, ActionListener {
+  private static int[] seuilsValsNbElts = {3, 10};
+  private static Color[] couleursNbElts = {Color.WHITE, GVisu.getCouleurSansValeur(),
+    GVisu.getCouleur(0), GVisu.getCouleur(3), GVisu.getCouleur(1)};
+  private static String[] labelsNbElements = {
+    "pas de chaîne associée",
+    "chaîne d'un seul chaînon",
+    "chaîne de 2-"+Integer.toString(seuilsValsNbElts[0])+" chaînons",
+    "chaîne de "+Integer.toString(seuilsValsNbElts[0]+1)+"-"
+    +Integer.toString(seuilsValsNbElts[1])+"  chaînons",
+    "chaîne de plus de "+Integer.toString(seuilsValsNbElts[1])+" chaînons"
+  };
+  private Vue vue;
+  private ModeleChaines donneesChaines;
+  private String typeChaines;
+  private String typeUnites;
+  private String[] valsAffichees;
+  private TypeComboBox saisieTypeChaines;
+  private TypeComboBox saisieTypeUnites;
+  private Val0ComboBox saisieChampAffiche;
+  private JComboBox saisieTailleLigne;
+  private JList legendeChampAffiche;
+  private JPopupMenu popupChamp = new JPopupMenu();
+  private GChaines panneauGraphique;
+  private PanneauAffChainesTexte panneauTexte;
+  private PanneauEditeur panneauEditeur;
+  public VisuChaines(Container fenetre, Vue vue, PanneauEditeur pEditeur) {
+    super("Représentation des chaînes");
+    Point pos = new Point(fenetre.getX()+20, fenetre.getY()+20);
+    Dimension dim = new Dimension(fenetre.getWidth(), fenetre.getHeight());
+    setLocation(pos);
+    setSize(dim);
+    this.vue = vue;
+    vue.addEventListener(this);
+    this.panneauEditeur = pEditeur;
+    saisieTypeChaines = new TypeComboBox(Schema.class);
+    saisieTypeChaines.setModele(vue.getTypesSchemasAVoir());
+    saisieTypeChaines.addActionListener(this);
+    saisieTypeUnites = new TypeComboBox(Unite.class);
+    saisieTypeUnites.setModele(vue.getTypesUnitesAVoir());
+    saisieTypeUnites.addActionListener(this);
+    saisieTailleLigne = new JComboBox(
+            new String[]{"<tous>", "10", "20", "30", "40", "50"});
+    saisieTailleLigne.setEditable(true);
+   // saisieTailleLigne.setMaximumSize(getPreferredSize());
+    saisieTailleLigne.addActionListener(this);
+    saisieTypeChaines.setModele(vue.getTypesSchemasAVoir());
+    saisieChampAffiche = new Val0ComboBox("Nombre de chaînons");
+    saisieChampAffiche.addActionListener(this);
+    // Panneau de présentation du graphique
+    JPanel pGraphique = new JPanel(new BorderLayout());
+    Box commandes = Box.createHorizontalBox();
+    commandes.add(Box.createHorizontalGlue());
+    commandes.add(new JLabel("Chaînes : "));
+    commandes.add(saisieTypeChaines);
+    commandes.add(Box.createHorizontalGlue());
+    commandes.add(new JLabel("Unites : "));
+    commandes.add(saisieTypeUnites);
+    commandes.add(Box.createHorizontalGlue());
+    commandes.add(new JLabel("Nb de chainons par ligne : "));
+    commandes.add(saisieTailleLigne);
+    commandes.add(Box.createHorizontalGlue());
+    commandes.add(new JLabel("Champ à afficher : "));
+    commandes.add(saisieChampAffiche);
+    pGraphique.add(commandes, BorderLayout.SOUTH);
+    panneauGraphique = new GChaines(this);
+    JScrollPane scrollGraphique = new JScrollPane(panneauGraphique);
+    pGraphique.add(scrollGraphique, BorderLayout.CENTER);
+    panneauTexte = new PanneauAffChainesTexte(vue.getCorpus(), this);
+    panneauTexte.setTexteVisu();
+    JScrollPane scrollTexte = new JScrollPane(panneauTexte);
+    legendeChampAffiche = new JList();
+    legendeChampAffiche.setCellRenderer(new LegendeCellRenderer());
+    legendeChampAffiche.addMouseListener(new MouseAdapter() {
+      public void mousePressed(MouseEvent e) {
+        check(e);
+      }
+      public void mouseReleased(MouseEvent e) {
+        check(e);
+      }
+      public void check(MouseEvent e) {
+        if (e.isPopupTrigger()) {//if the event shows the menu
+          popupChampInit(legendeChampAffiche.locationToIndex(e.getPoint()));
+          popupChamp.show(legendeChampAffiche, e.getX(), e.getY());
+        }
+      }
+    });
+    JScrollPane scrollLegende = new JScrollPane(legendeChampAffiche);
+    JSplitPane split1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, scrollTexte, scrollLegende);
+    JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, pGraphique, split1);
+    getContentPane().add(split);
+    setVisible(true);
+    split.setDividerLocation(1./3);
+    split1.setDividerLocation(3./4);
+    // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+    // Initialisation
+    saisieTailleLigne.setSelectedIndex(0);
+    saisieTailleLigne.setMaximumSize(getPreferredSize());
+    donneesChaines = new ModeleChaines(vue, panneauGraphique);
+    if (saisieTypeChaines.nbItems()==1) {
+      saisieTypeChaines.setSelection(0);
+      if (saisieTypeUnites.nbItems()==1) saisieTypeUnites.setSelection(0);
+      else saisieTypeUnites.effSelection();
+    } else {
+      saisieTypeChaines.effSelection();
+      saisieTypeUnites.effSelection();
+    }
+  }
+  void afficherOccurrences(Unite unite, Schema chaine) {
+    if (chaine!=null)
+      panneauTexte.montrerUnite(unite, TypeMarquage.SELECT1_2,
+              donneesChaines.getUnitesChaine(chaine), TypeMarquage.SELECT1);
+    else
+      panneauTexte.montrerUnite(unite, TypeMarquage.SELECT2);
+
+  }
+  private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+  }
+  public void traiterEvent(Message evt) { // très grossier : à améliorer
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre chaines présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        fermerFenetre();
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        fermerFenetre();
+        return;
+      case MODIF_ELEMENT:
+//        ElementEvent evtE = (ElementEvent) evt;
+//        if (evtE.getModif() != TypeModifElement.BORNES_UNITE) fermerFenetre();
+        fermerFenetre();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  public void traiterAffTexteDoubleClic(Unite unit) {
+    Schema chaine;
+    if ((chaine = donneesChaines.getChaine(unit))!=null)
+      panneauEditeur.editerUniteChaine(unit, chaine);
+    else
+      panneauEditeur.editerUniteTypeChaine(unit, typeChaines);
+  }
+  public void traiterAffTexteClicVide() {
+    panneauTexte.colorerUnites(donneesChaines.getUnites(), TypeMarquage.FOND1);
+  }
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource().equals(saisieTypeChaines)
+              ||evt.getSource().equals(saisieTypeUnites)) {
+        if (saisieTypeChaines.pasdeSelection()||saisieTypeUnites.pasdeSelection()) {
+          initVide();
+          return;
+        }
+        try {
+          init();
+        } catch (UnsupportedOperationException ex) {
+          GMessages.impossibiliteAction("Erreur de type : "+ex.getMessage());
+          initVide();
+          return;
+        }
+        return;
+      }
+      if (evt.getSource().equals(saisieChampAffiche)) {
+        if (saisieChampAffiche.pasdeSelection()) initCouleursNbElts();
+        else initCouleursChamp(saisieChampAffiche.getSelection());
+        return;
+      }
+      if (evt.getSource().equals(saisieTailleLigne)) {
+        int taille = saisieTailleLigne.getSelectedIndex()==0 ? Integer.MAX_VALUE :
+                Integer.parseInt((String)saisieTailleLigne.getSelectedItem());
+        panneauGraphique.setNbChainonsParLigne(taille);
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  private void initVide() {
+    typeChaines = null;
+    typeUnites = null;
+    donneesChaines.initVide();
+    saisieChampAffiche.setModeleVide();
+    panneauTexte.pasDeMarquage();
+    panneauTexte.setCurseur(0);
+    legendeChampAffiche.setListData(new LegendeLabel[0]);
+  }
+  private void init() throws UnsupportedOperationException {
+    typeChaines = saisieTypeChaines.getTypeSelection();
+    typeUnites = saisieTypeUnites.getTypeSelection();
+    donneesChaines.init(typeChaines, typeUnites, seuilsValsNbElts);
+    initCouleursNbElts();
+    saisieChampAffiche.removeActionListener(this);
+    saisieChampAffiche.setModele(vue.getNomsChamps(Unite.class, typeUnites));
+    saisieChampAffiche.addActionListener(this);
+    panneauTexte.colorerUnites(donneesChaines.getUnites(), TypeMarquage.FOND1);
+  }
+  private void initCouleursNbElts() {
+    donneesChaines.setChampAfficheNbElts(couleursNbElts);
+    legendeChampAffiche.setListData(creerLegendesNbElements());
+  }
+  private LegendeLabel[] creerLegendesNbElements() {
+    LegendeLabel[] legendes = new LegendeLabel[couleursNbElts.length];
+    for (int i = 0; i<legendes.length; i++)
+      legendes[i] = new LegendeLabel(labelsNbElements[i],
+              donneesChaines.isMasqueeValNbElements(i) ? null : couleursNbElts[i]);
+    return legendes;
+  }
+  private void initCouleursChamp(String champ) {
+    valsAffichees = vue.getValeursChamp(Unite.class, typeUnites, champ);
+    HashMap<String, Color> couleursValeursChamp = new HashMap<String, Color>();
+    for (int i = 0, nocolor = 0; i<valsAffichees.length; i++)
+      if (!donneesChaines.isMasqueeValChamp(champ, valsAffichees[i]))
+        couleursValeursChamp.put(valsAffichees[i], GVisu.getCouleur(nocolor++));
+    if (!donneesChaines.isMasqueeValNulleChamp(champ))
+      couleursValeursChamp.put("", GVisu.getCouleurSansValeur());
+    donneesChaines.setChampAffiche(champ, couleursValeursChamp);
+    legendeChampAffiche.setListData(creerLegendesChamp(valsAffichees,
+            couleursValeursChamp));
+  }
+  private LegendeLabel[] creerLegendesChamp(String[] valsAffichees,
+          HashMap<String, Color> couleursValeursChamp) {
+    LegendeLabel[] legendes = new LegendeLabel[valsAffichees.length+1];
+    for (int i = 0; i<valsAffichees.length; i++)
+      legendes[i] = new LegendeLabel(valsAffichees[i],
+              couleursValeursChamp.get(valsAffichees[i]));
+    legendes[valsAffichees.length] = new LegendeLabel("<aucune valeur>",
+            couleursValeursChamp.get(""));
+    return legendes;
+  }
+  private void popupChampInit(final int index) {
+    final boolean masquee;
+    popupChamp.removeAll();
+    if (saisieChampAffiche.pasdeSelection()) {
+      masquee = donneesChaines.isMasqueeValNbElements(index);
+      popupChamp.add(new GAction(masquee ? "Montrer cette valeur" : 
+              "Masquer cette valeur") {
+        public void executer() {
+          modifierStatutValNbElements(masquee, index, false);
+        }
+      });
+      popupChamp.add(new GAction(masquee ? "Montrer toutes les valeurs" : 
+              "Ne montrer que cette valeur") {
+        public void executer() {
+          modifierStatutValNbElements(masquee, index, true);
+        }
+      });
+    } else if (index==valsAffichees.length) {
+      masquee = donneesChaines.isMasqueeValNulleChamp(saisieChampAffiche.getSelection());
+      popupChamp.add(new GAction(masquee ? "Montrer cette valeur" : 
+              "Masquer cette valeur") {
+        public void executer() {
+          modifierStatutValNulleChamp(masquee, false);
+        }
+      });
+     popupChamp.add(new GAction(masquee ? "Montrer toutes les valeurs" : 
+              "Ne montrer que cette valeur") {
+        public void executer() {
+          modifierStatutValNulleChamp(masquee, true);
+        }
+      });
+    } else {
+      masquee = donneesChaines.isMasqueeValChamp(saisieChampAffiche.getSelection(),
+              valsAffichees[index]);
+      popupChamp.add(new GAction(masquee ? "Montrer cette valeur" : 
+              "Masquer cette valeur") {
+        public void executer() {
+          modifierStatutValChamp(masquee, index, false);
+        }
+      });
+      popupChamp.add(new GAction(masquee ? "Montrer toutes les valeurs" : 
+              "Ne montrer que cette valeur") {
+        public void executer() {
+          modifierStatutValChamp(masquee, index, true);
+        }
+      });
+    }
+  }
+  private void modifierStatutValChamp(boolean masquee, int index, boolean tous) {
+    if(!tous) donneesChaines.masquerValChamp(!masquee, 
+            saisieChampAffiche.getSelection(), valsAffichees[index]);
+    else if(masquee) donneesChaines.demasquerToutesValsChamp( 
+            saisieChampAffiche.getSelection());
+    else donneesChaines.masquerAutresValsChamp(typeUnites, 
+            saisieChampAffiche.getSelection(), valsAffichees[index]);
+    donneesChaines.modifMasqueVals(typeChaines, typeUnites);
+    initCouleursChamp(saisieChampAffiche.getSelection());
+    panneauTexte.colorerUnites(donneesChaines.getUnites(), TypeMarquage.FOND1);
+  }
+  private void modifierStatutValNulleChamp(boolean masquee, boolean tous) {
+    if(!tous) donneesChaines.masquerValNulleChamp(!masquee, saisieChampAffiche.getSelection());
+   else if(masquee) donneesChaines.demasquerToutesValsChamp( 
+            saisieChampAffiche.getSelection());
+    else donneesChaines.masquerValsNonNullesChamp(typeUnites, 
+            saisieChampAffiche.getSelection());
+    donneesChaines.modifMasqueVals(typeChaines, typeUnites);
+    initCouleursChamp(saisieChampAffiche.getSelection());
+    panneauTexte.colorerUnites(donneesChaines.getUnites(), TypeMarquage.FOND1);
+  }
+  private void modifierStatutValNbElements(boolean masquee, int index, boolean tous) {
+    if(!tous) donneesChaines.masquerValNbElements(!masquee, index);
+   else if(masquee) donneesChaines.demasquerToutesValsNbElts( 
+            saisieChampAffiche.getSelection());
+    else donneesChaines.masquerAutresValsNbElts( 
+            saisieChampAffiche.getSelection(), index);
+    donneesChaines.modifMasqueVals(typeChaines, typeUnites);
+    initCouleursNbElts();
+    panneauTexte.colorerUnites(donneesChaines.getUnites(), TypeMarquage.FOND1);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/chaines/VisuChaines.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/VisuMain.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/VisuMain.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/VisuMain.java	(revision 481)
@@ -0,0 +1,506 @@
+package visuAnalec;
+
+/**
+ *
+ * @author bernard
+ */
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.io.*;
+import javax.swing.table.TableModel;
+import visuAnalec.Message.*;
+import visuAnalec.chaines.*;
+import visuAnalec.donnees.*;
+import visuAnalec.fichiers.*;
+import visuAnalec.statistiques.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+
+@SuppressWarnings("serial")
+public class VisuMain extends JFrame implements VueListener {
+  private Corpus corpus;
+  private Vue vue;
+  private PanneauEditeur panneauEditeur;
+  private String nomCorpus = "";
+  private String nomVue = "";
+  private static String[] args;
+  VisuMain() {
+    super();
+    corpus = new Corpus();
+    vue = new Vue(corpus);
+    panneauEditeur = new PanneauEditeur(vue);
+    vue.addEventListener(this);
+    // Cadre global de la fenêtre
+    setContentPane(panneauEditeur);
+    // Menus
+    JMenuBar menuBar = new JMenuBar();
+    setJMenuBar(menuBar);
+
+    // Menu corpus
+    JMenu corpusMenu = new JMenu("Documents");
+    menuBar.add(corpusMenu);
+    corpusMenu.add(new GAction("Ouvrir...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersJava.ouvrirCorpusVue(corpus, vue, "");
+        //       System.out.println(corpus.getStructure());
+      }
+    });
+    JMenuItem item;
+    corpusMenu.add(item = new JMenuItem(new GAction("Enregistrer") {
+      public void executer() {
+        if (corpus.isVide()) return;
+        if (!nomCorpus.isEmpty()) {
+          File fichier = Fichiers.getFichierCourant(Fichiers.TypeFichier.DOC_ANALEC);
+          if (FichiersJava.enregistrerCorpus(corpus, fichier)) setTitre();
+        } else if (FichiersJava.enregistrerCorpusSous(corpus)) {
+          nomCorpus = Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC);
+          setTitre();
+        }
+      }
+    }));
+    corpusMenu.add(new GAction("Enregistrer sous...") {
+      public void executer() {
+        if (FichiersJava.enregistrerCorpusSous(corpus)) {
+          nomCorpus = Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC);
+          setTitre();
+        }
+      }
+    });
+    corpusMenu.add(new GAction("Fermer") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+      }
+    });
+    corpusMenu.insertSeparator(corpusMenu.getMenuComponentCount());
+    corpusMenu.add(new GAction("Fusionner des annotations") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        FichiersJava.fusionnerAnnot(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Concaténer deux documents") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        FichiersJava.concatenerDocuments(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Concaténer un corpus") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersJava.concatenerCorpus(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Extraire un type d'un corpus") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        String type = JOptionPane.showInputDialog("Nom du type d'unité à extraire");
+        if (type==null) return;
+        corpus.fermer();
+        FichiersJava.extraireTypeCorpus(type, corpus);
+      }
+    });
+    corpusMenu.insertSeparator(corpusMenu.getMenuComponentCount());
+    corpusMenu.add(new GAction("Importer du texte brut...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        int rep = 0;
+        if (!corpus.getStructure().isVide()) {
+          rep = JOptionPane.showOptionDialog(null, "Utiliser la structure actuelle pour le nouveau document ?",
+                  "Structure déjà présente", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+                  null, new Object[]{"Oui", "Non", "Annuler"}, "Oui");
+          if (rep==2) return;
+        }
+        if (rep==0) corpus.fermerConserverStructure();
+        else corpus.fermer();
+        FichiersTexte.importerTexte(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Importer des données Excel...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersTableur.importerExcel(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Importer des données Syntex...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersSyntex.importerSyntex(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Importer des données Glozz...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersGlozz.importerGlozz(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Exporter des données Glozz...") {
+      public void executer() {
+        FichiersGlozz.exporterGlozz(corpus);
+      }
+    });
+    corpusMenu.add(new GAction("Convertir un corpus Glozz...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersGlozz.convertirCorpusGlozz(corpus);
+      }
+    });
+   corpusMenu.add(new GAction("Exporter un corpus TEI...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersTEI.exporterCorpusTEI(corpus);
+      }
+    });
+   corpusMenu.add(new GAction("Convertir un corpus TEI...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersTEI.convertirCorpusTEI(corpus);
+     }
+    });
+   corpusMenu.add(new GAction("Importer un document CoNLL...") {
+      public void executer() {
+        if (!sauvegarde()) return;
+        corpus.fermer();
+        FichiersCoNLL.importerCoNLL(corpus);
+     }
+    });
+    corpusMenu.insertSeparator(corpusMenu.getMenuComponentCount());
+    corpusMenu.add(new GAction("Quitter") {
+      public void executer() {
+        fermerFenetre();
+      }
+    });
+
+    // Menu structure
+    JMenu structureMenu = new JMenu("Structure");
+    menuBar.add(structureMenu);
+    structureMenu.add(new GAction("Gestion de la structure...") {
+      public void executer() {
+        VisuStructure visuStructure = VisuStructure.newVisuStructure(getContentPane(), corpus);
+        visuStructure.setExtendedState(NORMAL);
+        visuStructure.setVisible(true);
+        visuStructure.agencer();
+      }
+    });
+    structureMenu.add(new GAction("Ouvrir...") {
+      public void executer() {
+        if (!fusionStructure()) return;
+        FichiersJava.ouvrirStructure(corpus);
+      }
+    });
+    structureMenu.add(item = new JMenuItem(new GAction("Enregistrer...") {
+      public void executer() {
+        FichiersJava.enregistrerStructure(corpus);
+        setTitre();
+      }
+    }));
+    structureMenu.add(new GAction("Importer un modèle Glozz...") {
+      public void executer() {
+        if (!fusionStructure()) return;
+        FichiersGlozz.importerModeleGlozz(corpus);
+        //       System.out.println(corpus.getStructure());
+      }
+    });
+    structureMenu.add(new GAction("Exporter un modèle Glozz...") {
+      public void executer() {
+        FichiersGlozz.exporterModeleGlozz(corpus.getStructure());
+      }
+    });
+
+    // Menu vue
+    JMenu vueMenu = new JMenu("Vue");
+    menuBar.add(vueMenu);
+    vueMenu.add(new GAction("Gestion de la vue...") {
+      public void executer() {
+        VisuVue.newVisuVue(getContentPane(), vue);
+      }
+    });
+    vueMenu.add(new GAction("Ouvrir (.ecv)...") {
+      public void executer() {
+        FichiersJava.ouvrirVue(vue);
+      }
+    });
+    vueMenu.add(new GAction("Enregistrer (.ecv)...") {
+      public void executer() {
+        if (FichiersJava.enregistrerVue(vue)) {
+          nomVue = Fichiers.getNomFichierCourant(Fichiers.TypeFichier.VUE);
+          setTitre();
+        }
+      }
+    });
+    vueMenu.add(new GAction("Rétablir la vue par défaut") {
+      public void executer() {
+        nomVue = "";
+        vue.retablirVueParDefaut();
+      }
+    });
+
+    // Menu texte
+    JMenu texteMenu = new JMenu("Texte");
+    menuBar.add(texteMenu);
+    texteMenu.add(new GAction("Modifier le texte") {
+      public void executer() {
+        panneauEditeur.initModifierTexte();
+      }
+    });
+    texteMenu.insertSeparator(texteMenu.getMenuComponentCount());
+    texteMenu.add(item = new JMenuItem(new GAction("Rechercher...") {
+      public void executer() {
+        panneauEditeur.initRechercherTexte();
+      }
+    }));
+    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, ActionEvent.CTRL_MASK));
+    texteMenu.add(item = new JMenuItem(new GAction("Suivant") {
+      public void executer() {
+        panneauEditeur.rechercherSuivantTexte();
+      }
+    }));
+    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, ActionEvent.CTRL_MASK));
+    texteMenu.insertSeparator(texteMenu.getMenuComponentCount());
+    texteMenu.add(new GAction("Style du document...") {
+      public void executer() {
+        panneauEditeur.saisirStyleTexte(vue);
+      }
+    });
+    texteMenu.add(new GAction("Exporter format RTF...") {
+      public void executer() {
+        FichiersTexte.exporterTexteRTF(panneauEditeur);
+      }
+    });
+    texteMenu.add(new GAction("Exporter format HTML...") {
+      public void executer() {
+        FichiersTexte.exporterTexteHTML(panneauEditeur);
+      }
+    });
+
+
+    // Menu unités
+    JMenu unitesMenu = new JMenu("Unités");
+    menuBar.add(unitesMenu);
+    unitesMenu.add(new GAction("Gestion des unités") {
+      public void executer() {
+        panneauEditeur.initGestionUnites();
+      }
+    });
+    unitesMenu.add(new GAction("Export des unités") {
+      public void executer() {
+        String type;
+        String[] types = vue.getTypesUnitesAVoir();
+        if(types==null||types.length==0) return;
+        if(types.length==1) type = types[0];
+        else type = (String) JOptionPane.showInputDialog(VisuMain.this, 
+       "Type des unités à exporter", "Choix du type d'unités",
+       JOptionPane.QUESTION_MESSAGE, null, types, "");
+        if(type==null) return;
+        type = type.trim();
+        if(type.isEmpty()) return;       
+        TableModel donnees = vue.tableauUnites(type);
+        if(donnees!=null)  FichiersTableur.exporterTable(donnees);
+      }
+    });
+    unitesMenu.insertSeparator(unitesMenu.getMenuComponentCount());
+    unitesMenu.add(new GAction("Création d'unités typographiques") {
+      public void executer() {
+        GMessages.pasImplemente();
+      }
+    });
+    unitesMenu.add(new GAction("Création d'unités de constituance") {
+      public void executer() {
+        GMessages.pasImplemente();
+      }
+    });
+
+    // Menu relations
+    JMenu relationsMenu = new JMenu("Relations");
+    menuBar.add(relationsMenu);
+    relationsMenu.add(new GAction("Gestion des relations") {
+      public void executer() {
+        panneauEditeur.initGestionRelations();
+      }
+    });
+    relationsMenu.add(new GAction("Visualisation d'arborescences") {
+      public void executer() {
+        GMessages.pasImplemente();
+      }
+    });
+    relationsMenu.add(new GAction("Saisie d'arborescences") {
+      public void executer() {
+        GMessages.pasImplemente();
+      }
+    });
+    relationsMenu.add(new GAction("Création d'arborescences") {
+      public void executer() {
+        GMessages.pasImplemente();
+      }
+    });
+
+    // Menu schémas
+    JMenu schemasMenu = new JMenu("Schémas");
+    menuBar.add(schemasMenu);
+    schemasMenu.add(new GAction("Gestion des schémas") {
+      public void executer() {
+        panneauEditeur.initGestionSchemas();
+      }
+    });
+    schemasMenu.add(new GAction("Visualisation de chaînes") {
+      public void executer() {
+        new VisuChaines(getContentPane(), vue, panneauEditeur);
+      }
+    });
+
+    // Menu règles
+    JMenu reglesMenu = new JMenu("Règles");
+    menuBar.add(reglesMenu);
+    // Menu Stats
+    JMenu statsMenu = new JMenu("Statistiques");
+    menuBar.add(statsMenu);
+    statsMenu.add(new GAction("Fréquences...") {
+      public void executer() {
+        new VisuStatsFrequences(getContentPane(), vue, panneauEditeur);
+      }
+    });
+    statsMenu.add(new GAction("Corrélations...") {
+      public void executer() {
+        new VisuStatsCorrelations(getContentPane(), vue, panneauEditeur);
+      }
+    });
+    statsMenu.add(new GAction("Représentations géométriques...") {
+      @SuppressWarnings("ResultOfObjectAllocationIgnored")
+      public void executer() {
+        new VisuStatsGeometrie(getContentPane(), vue, panneauEditeur);
+      }
+    });
+    // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+
+  }
+  public void premierPlan() {
+    if ((getExtendedState()&Frame.ICONIFIED)>0) {
+      setExtendedState(getExtendedState()&~Frame.ICONIFIED);
+    }
+    toFront();
+
+  }
+  private void fermerFenetre() {
+    sauvegarde();
+  }
+  boolean sauvegarde() {
+    if (!corpus.isModifie()) return true;
+    int rep = JOptionPane.showOptionDialog(this, "Sauvegarder le document en cours ?",
+            "Document modifié", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+            null, new Object[]{"Oui", "Non", "Annuler"}, "Non");
+    if (rep==2) {
+      return false;
+    }
+    if (rep==0) {
+      FichiersJava.enregistrerCorpusSous(corpus);
+    }
+    return true;
+  }
+  boolean fusionStructure() {
+    if (corpus.getStructure().isVide()) return true;
+    int rep = JOptionPane.showOptionDialog(this, "La nouvelle structure va être fusionnée avec la structure courante",
+            "Structure déjà présente", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+            null, new Object[]{"Poursuivre", "Annuler"}, "Poursuivre");
+    return rep==0;
+  }
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        nomCorpus = "";
+        Fichiers.removeFichierCourant(Fichiers.TypeFichier.DOC_ANALEC);
+        setTitre();
+        return;
+      case NEW_CORPUS:
+        nomCorpus = Fichiers.getNomFichierCourant(Fichiers.TypeFichier.DOC_ANALEC);
+        setTitre();
+        return;
+      case MODIF_VUE:
+        switch (((VueEvent) evt).getModif()) {
+          case VUE_DEFAUT:
+            nomVue = "";
+            setTitre();
+            return;
+          case NEW_VUE:
+            nomVue = Fichiers.getNomFichierCourant(Fichiers.TypeFichier.VUE);
+            setTitre();
+            return;
+          case EXTRACTION:
+            setTitre();
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas "+((VueEvent) evt).getModif()+" oublié dans un switch");
+        }
+      case MODIF_TEXTE:
+      case MODIF_STRUCTURE:
+      case MODIF_ELEMENT:
+        setTitre();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  private void setTitre() {
+    String titre = "Analec 1.5";
+    if (!nomCorpus.isEmpty()) {
+      titre += " : "+nomCorpus;
+      if (corpus.isModifie()) titre += "*";
+      if (nomVue.isEmpty()) {
+        if (vue.isModifiee()) titre += " - vue modifiée*";
+        else titre += " - vue par défaut";
+      } else {
+        titre += " - vue : "+nomVue;
+        if (vue.isModifiee()) titre += "*";
+      }
+    }
+    setTitle(titre);
+  }
+  public static void main(String[] args) {
+    VisuMain.args = args;
+    javax.swing.SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        try {
+          // Fenêtre
+          lancerVisuAnalec();
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    });
+  }
+  public static void lancerVisuAnalec() throws IOException, ClassNotFoundException {
+    // Fenêtre
+    VisuMain fenetre = new VisuMain();
+    fenetre.setTitre();
+    Rectangle rmax = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
+    fenetre.setLocation(50, 50);
+    fenetre.setSize(rmax.width-100, rmax.height-100);
+    fenetre.setVisible(true);
+    fenetre.panneauEditeur.agencerPanneaux();
+    fenetre.traiterArguments(args);
+//    System.out.println(fenetre.corpus.getStructure().toString());
+//   new GMessages.GProgression(fenetre);
+  }
+  private void traiterArguments(String[] args) throws IOException, ClassNotFoundException {
+    if (args.length==0) return;
+    FichiersJava.ouvrirCorpusVue(corpus, vue, args[0]);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/VisuMain.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/VisuStructure.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/VisuStructure.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/VisuStructure.java	(revision 481)
@@ -0,0 +1,682 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.donnees;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.tree.*;
+import visuAnalec.*;
+import visuAnalec.Message.*;
+import visuAnalec.donnees.Corpus.*;
+import visuAnalec.vue.Vue.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.GMessages;
+import visuAnalec.util.GMessages.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class VisuStructure extends JFrame implements CorpusListener {
+	static private VisuStructure instance = null;
+	private Corpus corpus;
+	private Structure structure;
+	private JScrollPane panneauUnites, panneauRelations, panneauSchemas;
+	private HashMap<Class<? extends Element>, ModeleArbreProp> donneesClasse =
+			new HashMap<Class<? extends Element>, ModeleArbreProp>();
+	static public VisuStructure newVisuStructure(Container fenetre, Corpus corpus) {
+		if (instance==null) instance = new VisuStructure(fenetre, corpus);
+		return instance;
+	}
+	static public boolean isOpen() {
+		return instance != null && instance.isVisible();
+	}
+	
+	private VisuStructure(Container fenetre, Corpus corps) {
+		super("Structure des annotations");
+		if (fenetre != null) {
+			Point locFenetre = new Point(fenetre.getX()+20, fenetre.getY()+50);
+			Dimension dimFenetre = new Dimension(fenetre.getWidth(), fenetre.getHeight()-30);
+			setLocation(locFenetre);
+			setSize(dimFenetre);
+		}
+		this.corpus = corps;
+		this.structure = corps.getStructure();
+		corps.addEventListener(this);
+		// Panneau des types d'unités
+		ModeleArbreProp donneesPropUnites = new ModeleArbreProp(structure, Unite.class);
+		JTree arbrePropUnites = new JTree(donneesPropUnites);
+		donneesClasse.put(Unite.class, donneesPropUnites);
+		arbrePropUnites.setRootVisible(true);
+		arbrePropUnites.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+		panneauUnites = new JScrollPane(arbrePropUnites);
+		panneauUnites.setBorder(new TitledBorder("Unités"));
+		// Panneau des types de relations
+		ModeleArbreProp donneesPropRelations = new ModeleArbreProp(structure, Relation.class);
+		JTree arbrePropRelations = new JTree(donneesPropRelations);
+		donneesClasse.put(Relation.class, donneesPropRelations);
+		arbrePropRelations.setRootVisible(true);
+		arbrePropRelations.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+		panneauRelations = new JScrollPane(arbrePropRelations);
+		panneauRelations.setBorder(new TitledBorder("Relations"));
+		// Panneau des types de schémas
+		ModeleArbreProp donneesPropSchemas = new ModeleArbreProp(structure, Schema.class);
+		JTree arbrePropSchemas = new JTree(donneesPropSchemas);
+		donneesClasse.put(Schema.class, donneesPropSchemas);
+		arbrePropSchemas.setRootVisible(true);
+		arbrePropSchemas.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+		panneauSchemas = new JScrollPane(arbrePropSchemas);
+		panneauSchemas.setBorder(new TitledBorder("Schémas"));
+
+		// cadre global de la fenêtre
+		JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panneauUnites,
+				new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+						panneauRelations, panneauSchemas));
+		getContentPane().add(split);
+
+		// Gestion des menus contextuels
+		final JPopupMenuStructure popupMenuStructure = new JPopupMenuStructure();
+
+		MouseListener popupListener = new MouseAdapter() {
+			@Override
+			public void mousePressed(MouseEvent e) {
+				try {
+					if (e.isPopupTrigger()) showPopup(e);
+					else if (e.getClickCount()==2) {
+						JTree arbre = (JTree) e.getComponent();
+						TreePath item = arbre.getPathForLocation(e.getX(), e.getY());
+						if (item==null) return;
+						if (item.getPathCount()!=4) return;
+						ModeleArbreProp donnees = (ModeleArbreProp) arbre.getModel();
+						Class<? extends Element> classe = donnees.classe;
+						DefaultMutableTreeNode noeudType = (DefaultMutableTreeNode) item.getPathComponent(1);
+						DefaultMutableTreeNode noeudProp = (DefaultMutableTreeNode) item.getPathComponent(2);
+						DefaultMutableTreeNode noeudVal = (DefaultMutableTreeNode) item.getPathComponent(3);
+						String type = (String) noeudType.getUserObject();
+						String prop = (String) noeudProp.getUserObject();
+						String val = (String) noeudVal.getUserObject();
+						if (isDefaut(val)) {
+							corpus.modifierValParDefaut(classe, type, prop, "");
+							//             noeudVal.setUserObject(oteDefaut(val));
+						} else {
+							corpus.modifierValParDefaut(classe, type, prop, val);
+							//              for (Enumeration noeuds = noeudProp.children(); noeuds.hasMoreElements();) {
+							//                DefaultMutableTreeNode noeud1 = (DefaultMutableTreeNode) noeuds.nextElement();
+							//                String val1 = (String) noeud1.getUserObject();
+							//                if (isDefaut(val1)) {
+							//                  noeud1.setUserObject(oteDefaut(val1));
+							//                  donnees.nodeChanged(noeudVal);
+							//                  break;
+							//                }
+							//              }
+							////              noeudVal.setUserObject(placeDefaut(val));
+							//             corpus.newValeurDefaut(classe, type, prop, val);
+						}
+						//          donnees.nodeChanged(noeudVal);
+
+					}
+				} catch (Throwable ex) {
+					GMessages.erreurFatale(ex);
+				}
+			}
+			@Override
+			public void mouseReleased(MouseEvent e) {
+				try {
+					if (e.isPopupTrigger()) showPopup(e);
+				} catch (Throwable ex) {
+					GMessages.erreurFatale(ex);
+				}
+			}
+			private void showPopup(MouseEvent e) {
+				JTree arbre = (JTree) e.getComponent();
+				TreePath item = arbre.getPathForLocation(e.getX(), e.getY());
+				if (item==null) return;
+				popupMenuStructure.init(arbre, item);
+				popupMenuStructure.show(e.getComponent(), e.getX(), e.getY());
+			}
+		};
+
+		arbrePropUnites.addMouseListener(popupListener);
+		arbrePropRelations.addMouseListener(popupListener);
+		arbrePropSchemas.addMouseListener(popupListener);
+		// Fermeture de la fenêtre
+		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+		addWindowListener(new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent evt) {
+				fermerFenetre();
+			}
+		});
+
+	}
+	public void agencer() {
+		((JSplitPane) panneauUnites.getParent()).setDividerLocation(1./3);
+		((JSplitPane) panneauRelations.getParent()).setDividerLocation(1./3);
+	}
+	private void fermerFenetre() {
+		corpus.removeEventListener(this);
+		dispose();
+		instance = null;
+	}
+	public void traiterEvent(Message evt) {
+		switch (evt.getType()) {
+		case CLEAR_CORPUS:
+			fermerFenetre();
+			return;
+		case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+			throw new UnsupportedOperationException("Fenêtre stat présente lors d'un message NEW_CORPUS ???");
+		case MODIF_STRUCTURE:
+			StructureEvent evtS = (StructureEvent) evt;
+			ModeleArbreProp donnees = donneesClasse.get(evtS.getClasse());
+			switch (evtS.getModif()) { // pour les modifs ayant lieu en dehors de VisuStructure 
+			case AJOUT_TYPE:
+				donnees.insererNewType(evtS.getArg(0));
+				return;
+			case AJOUT_PROP:
+				donnees.insererNewProp(evtS.getArg(0), evtS.getArg(1));
+				return;
+			case AJOUT_VALEUR:
+				donnees.insererNewValeur(evtS.getArg(0), evtS.getArg(1), evtS.getArg(2));
+				return;
+			case VALEUR_PAR_DEFAUT:
+				donnees.modifierValDefaut(evtS.getArg(0), evtS.getArg(1), evtS.getArg(2));
+				return;
+			default:
+				return;
+			}
+		case MODIF_ELEMENT:
+		case MODIF_TEXTE:
+			return;
+		default:
+			throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+		}
+	}
+	static boolean isDefaut(String val) {
+		return val.startsWith("=>");
+	}
+	static String placeDefaut(String val) {
+		return isDefaut(val) ? val : "=>"+val;
+	}
+	static String oteDefaut(String val) {
+		return isDefaut(val) ? val.substring(2) : val;
+	}
+
+	private class JPopupMenuStructure extends JPopupMenu {
+		void init(JTree arbre, TreePath item) {
+			ModeleArbreProp donnees = (ModeleArbreProp) arbre.getModel();
+			removeAll();
+			int niveau = item.getPathCount();
+			if (niveau<4) {
+				add(new ActionAjouter(donnees.classe, arbre, donnees, item));
+			}
+			if (niveau>1) {
+				if (niveau!=3||!donnees.classe.equals(Unite.class)||!Structure.FORME.equals(
+						((DefaultMutableTreeNode) item.getLastPathComponent()).getUserObject()))
+					add(new ActionRenommer(donnees.classe, donnees, item));
+				add(new ActionSupprimer(donnees.classe, donnees, item));
+			}
+			if (niveau==2&&donnees.classe.equals(Unite.class)
+					&&!donnees.hasForme((DefaultMutableTreeNode) item.getLastPathComponent()))
+				add(new ActionAjouterForme(arbre, donnees, item));
+			if (niveau==3)
+				add(new ActionDispatcher(donnees.classe, arbre, donnees, item));
+		}
+	}
+	static String[] commandesAjout = new String[]{
+		"Ajouter un type",
+		"Ajouter une propriété",
+		"Ajouter une valeur"
+	};
+
+	private class ActionAjouter extends GAction {
+		TreePath item;
+		Class<? extends Element> classe;
+		JTree arbre;
+		ModeleArbreProp donnees;
+		ActionAjouter(Class<? extends Element> classe, JTree arbre, ModeleArbreProp donnees, TreePath item) {
+			super(commandesAjout[item.getPathCount()-1]);
+			this.item = item;
+			this.classe = classe;
+			this.donnees = donnees;
+			this.arbre = arbre;
+		}
+		public void executer() {
+			corpus.removeEventListener(VisuStructure.this);
+			DefaultMutableTreeNode noeud, noeud1, noeud2;
+			noeud = (DefaultMutableTreeNode) item.getLastPathComponent();
+			switch (item.getPathCount()) {
+			case 1: // racine : ajout d'un type
+			String newType =
+			corpus.saisirAjouterType(VisuStructure.this, classe);
+			if (newType!=null) {
+				noeud1 = new DefaultMutableTreeNode(newType, true);
+				donnees.insertNodeInto(noeud1, noeud, 0);
+				arbre.makeVisible(item.pathByAddingChild(noeud1));
+			}
+			break;
+			case 2: // type : ajout d'une prop
+				String newProp =
+				corpus.saisirAjouterProp(VisuStructure.this, classe,
+						(String) noeud.getUserObject());
+				if (newProp!=null) {
+					noeud1 = new DefaultMutableTreeNode(newProp, true);
+					donnees.insertNodeInto(noeud1, noeud, 0);
+					arbre.makeVisible(item.pathByAddingChild(noeud1));
+				}
+				break;
+			case 3: // prop : ajout d'une valeur
+				noeud1 = (DefaultMutableTreeNode) item.getPathComponent(1);
+				String newVal = corpus.saisirAjouterVal(VisuStructure.this, classe,
+						(String) noeud1.getUserObject(), (String) noeud.getUserObject());
+				if (newVal!=null) {
+					noeud2 = new DefaultMutableTreeNode(newVal, false);
+					donnees.insertNodeInto(noeud2, noeud, 0);
+					arbre.makeVisible(item.pathByAddingChild(noeud1));
+				}
+				break;
+			default:
+				throw new UnsupportedOperationException("Cas d'ajout non prévu ");
+			}
+			corpus.addEventListener(VisuStructure.this);
+		}
+	}
+	static String[] commandesRenom = new String[]{
+		"Renommer le type",
+		"Renommer la propriété",
+		"Renommer la valeur"
+	};
+
+	private class ActionRenommer extends GAction {
+		TreePath item;
+		Class<? extends Element> classe;
+		ModeleArbreProp donnees;
+		ActionRenommer(Class<? extends Element> classe, ModeleArbreProp donnees, TreePath item) {
+			super(commandesRenom[item.getPathCount()-2]);
+			this.item = item;
+			this.classe = classe;
+			this.donnees = donnees;
+		}
+		@SuppressWarnings("unchecked")
+		public void executer() {
+			corpus.removeEventListener(VisuStructure.this);
+			DefaultMutableTreeNode noeud, noeud0, noeud1, noeud2;
+			noeud = (DefaultMutableTreeNode) item.getLastPathComponent();
+			switch (item.getPathCount()) {
+			case 2: // type
+				String newType = corpus.saisirRenommerType(VisuStructure.this, classe,
+						(String) noeud.getUserObject());
+				if (newType!=null) {
+					DefaultMutableTreeNode ntypefusion = null;
+					noeud0 = (DefaultMutableTreeNode) item.getPathComponent(0);
+					for (Enumeration<DefaultMutableTreeNode> etype = noeud0.children(); etype.hasMoreElements();) {
+						DefaultMutableTreeNode ntype = etype.nextElement();
+						String type0 = (String) ntype.getUserObject();
+						if (newType.equals(type0)) {
+							ntypefusion = ntype;
+							break;
+						}
+					}
+					if (ntypefusion!=null)
+						donnees.fusionnerType(noeud, ntypefusion);
+					else {
+						noeud.setUserObject(newType);
+						donnees.nodeChanged(noeud);
+					}
+				}
+				break;
+			case 3: // prop
+				noeud1 = (DefaultMutableTreeNode) item.getPathComponent(1);
+				String newProp = corpus.saisirRenommerProp(VisuStructure.this, classe,
+						(String) noeud1.getUserObject(), (String) noeud.getUserObject());
+				if (newProp!=null) {
+					DefaultMutableTreeNode npropfusion = null;
+					for (Enumeration<DefaultMutableTreeNode> eprop = noeud1.children(); eprop.hasMoreElements();) {
+						DefaultMutableTreeNode nprop = eprop.nextElement();
+						String prop0 = (String) nprop.getUserObject();
+						if (newProp.equals(prop0)) {
+							npropfusion = nprop;
+							break;
+						}
+					}
+					if (npropfusion!=null)
+						donnees.fusionnerProp(noeud1, noeud, npropfusion);
+					else {
+						noeud.setUserObject(newProp);
+						donnees.nodeChanged(noeud);
+					}
+				}
+				break;
+			case 4: // val
+				noeud1 = (DefaultMutableTreeNode) item.getPathComponent(1);
+				noeud2 = (DefaultMutableTreeNode) item.getPathComponent(2);
+				String val = (String) noeud.getUserObject();
+				boolean isDefaut = isDefaut(val);
+				if (isDefaut) val = oteDefaut(val);
+				String newVal = corpus.saisirRenommerVal(VisuStructure.this, classe,
+						(String) noeud1.getUserObject(), (String) noeud2.getUserObject(), val);
+				if (newVal!=null) {
+					for (Enumeration<DefaultMutableTreeNode> eval = noeud2.children(); eval.hasMoreElements();) {
+						DefaultMutableTreeNode nval = eval.nextElement();
+						String val0 = (String) nval.getUserObject();
+						if (newVal.equals(isDefaut(val0) ? oteDefaut(val0) : val0)) {
+							isDefaut = isDefaut||isDefaut(val0);
+							donnees.removeNodeFromParent(nval);
+							break;
+						}
+					}
+					if (isDefaut) newVal = placeDefaut(newVal);
+					noeud.setUserObject(newVal);
+					donnees.nodeChanged(noeud);
+				}
+				break;
+			default:
+				throw new UnsupportedOperationException("Cas de renommage non prévu ");
+			}
+			corpus.addEventListener(VisuStructure.this);
+		}
+	}
+	static String[] commandesSuppr = new String[]{
+		"Supprimer le type",
+		"Supprimer la propriété",
+		"Supprimer la valeur"
+	};
+
+	private class ActionSupprimer extends GAction {
+		TreePath item;
+		Class<? extends Element> classe;
+		ModeleArbreProp donnees;
+		ActionSupprimer(Class<? extends Element> classe, ModeleArbreProp donnees, TreePath item) {
+			super(commandesSuppr[item.getPathCount()-2]);
+			this.item = item;
+			this.classe = classe;
+			this.donnees = donnees;
+		}
+		@SuppressWarnings("unchecked")
+		public void executer() {
+			corpus.removeEventListener(VisuStructure.this);
+			DefaultMutableTreeNode noeud, noeud1, noeud2;
+			noeud = (DefaultMutableTreeNode) item.getLastPathComponent();
+			switch (item.getPathCount()) {
+			case 1: // racine
+				return;
+			case 2: // type
+				if (corpus.saisirSupprimerType(VisuStructure.this, classe,
+						(String) noeud.getUserObject())) {
+					donnees.removeNodeFromParent(noeud);
+				}
+				break;
+			case 3: // prop
+				noeud1 = (DefaultMutableTreeNode) item.getPathComponent(1);
+				if (corpus.saisirSupprimerProp(VisuStructure.this, classe,
+						(String) noeud1.getUserObject(), (String) noeud.getUserObject())) {
+					donnees.removeNodeFromParent(noeud);
+				}
+				;
+				break;
+			case 4: // val
+				noeud1 = (DefaultMutableTreeNode) item.getPathComponent(1);
+				noeud2 = (DefaultMutableTreeNode) item.getPathComponent(2);
+				String val = (String) noeud.getUserObject();
+				if (isDefaut(val)) val = oteDefaut(val);
+				if (corpus.saisirSupprimerVal(VisuStructure.this, classe,
+						(String) noeud1.getUserObject(), (String) noeud2.getUserObject(), val)) {
+					donnees.removeNodeFromParent(noeud);
+				}
+				break;
+			default:
+				throw new UnsupportedOperationException("Cas de suppression non prévu ");
+			}
+			corpus.addEventListener(VisuStructure.this);
+		}
+	}
+
+	private class ActionAjouterForme extends GAction {
+		TreePath item;
+		Class<? extends Element> classe;
+		JTree arbre;
+		ModeleArbreProp donnees;
+		ActionAjouterForme(JTree arbre, ModeleArbreProp donnees, TreePath item) {
+			super("Ajouter la forme de surface");
+			this.item = item;
+			this.donnees = donnees;
+			this.arbre = arbre;
+		}
+		@SuppressWarnings("unchecked")
+		public void executer() {
+			corpus.removeEventListener(VisuStructure.this);
+			DefaultMutableTreeNode noeud, noeud1;
+			noeud = (DefaultMutableTreeNode) item.getLastPathComponent();
+			String type = (String) noeud.getUserObject();
+			corpus.ajouterFormeUnite(type);
+			noeud1 = new DefaultMutableTreeNode(Structure.FORME, true);
+			donnees.insertNodeInto(noeud1, noeud, 0);
+			arbre.makeVisible(item.pathByAddingChild(noeud1));
+			corpus.addEventListener(VisuStructure.this);
+			corpus.instancierFormeUnite(type);
+
+		}
+	}
+
+	private class ActionDispatcher extends GAction {
+		TreePath item;
+		Class<? extends Element> classe;
+		JTree arbre;
+		ModeleArbreProp donnees;
+		ActionDispatcher(Class<? extends Element> classe, JTree arbre,
+				ModeleArbreProp donnees, TreePath item) {
+			super("Transformer en types distincts");
+			this.item = item;
+			this.classe = classe;
+			this.donnees = donnees;
+			this.arbre = arbre;
+		}
+		@SuppressWarnings("unchecked")
+		public void executer() {
+			corpus.removeEventListener(VisuStructure.this);
+			DefaultMutableTreeNode noeudprop = (DefaultMutableTreeNode) item.getLastPathComponent();
+			int nbval = noeudprop.getChildCount();
+			String[] vals = new String[nbval];
+			Enumeration<DefaultMutableTreeNode> eval = noeudprop.children();
+			for (int i = 0; i<nbval; i++)
+				vals[i] = (String) eval.nextElement().getUserObject();
+			DefaultMutableTreeNode noeudtype = (DefaultMutableTreeNode) item.getPathComponent(1);
+			int nbprop = noeudtype.getChildCount();
+			String[] props = new String[nbprop-1];
+			String[][] propsvals = new String[nbprop-1][];
+			Enumeration<DefaultMutableTreeNode> eprop = noeudtype.children();
+			for (int i = 0; eprop.hasMoreElements(); i++) {
+				DefaultMutableTreeNode nprop = eprop.nextElement();
+				if (nprop!=noeudprop) {
+					props[i] = (String) nprop.getUserObject();
+					propsvals[i] = new String[nprop.getChildCount()];
+					Enumeration<DefaultMutableTreeNode> epropval = nprop.children();
+					for (int j = 0; epropval.hasMoreElements(); j++)
+						propsvals[i][j] = (String) epropval.nextElement().getUserObject();
+				} else i--;
+			}
+			if (corpus.saisirDispatcherProp(VisuStructure.this, classe,
+					(String) noeudtype.getUserObject(),
+					(String) noeudprop.getUserObject(), vals, props, propsvals))
+				donnees.dispatcherProp(noeudtype, noeudprop, vals, props, propsvals);
+			corpus.addEventListener(VisuStructure.this);
+		}
+	}
+
+	private static class ModeleArbreProp extends DefaultTreeModel {
+		Structure structure;
+		Class<? extends Element> classe;
+		ModeleArbreProp(Structure structure, Class<? extends Element> classe) {
+			super(null, true);
+			this.structure = structure;
+			this.classe = classe;
+			setModele();
+		}
+		private void setModele() {
+			DefaultMutableTreeNode racine = new DefaultMutableTreeNode("TYPES :", true);
+			setRoot(racine);
+			String[] types = structure.getTypes(classe).toArray(new String[0]);
+			Arrays.sort(types);
+			for (String type : types) {
+				DefaultMutableTreeNode ntype =
+						new DefaultMutableTreeNode(type, true);
+				racine.add(ntype);
+				String[] props =
+						structure.getNomsProps(classe, type).toArray(new String[0]);
+				Arrays.sort(props);
+				for (String prop : props) {
+					DefaultMutableTreeNode nprop =
+							new DefaultMutableTreeNode(prop, true);
+					ntype.add(nprop);
+					String[] vals =
+							structure.getValeursProp(classe, type, prop).toArray(new String[0]);
+					Arrays.sort(vals);
+					for (String val : vals) {
+						if (val.equals(structure.getValeurParDefaut(classe, type, prop)))
+							val = placeDefaut(val);
+						DefaultMutableTreeNode nval =
+								new DefaultMutableTreeNode(val, false);
+						nprop.add(nval);
+					}
+				}
+			}
+			reload();
+		}
+		@SuppressWarnings("unchecked")
+		void insererNewType(String type) {
+			DefaultMutableTreeNode racine = (DefaultMutableTreeNode) getRoot();
+			insertNodeInto(new DefaultMutableTreeNode(type, true), racine, 0);
+		}
+		@SuppressWarnings("unchecked")
+		void insererNewProp(String type, String prop) {
+			DefaultMutableTreeNode racine = (DefaultMutableTreeNode) getRoot();
+			DefaultMutableTreeNode ntype = null;
+			for (Enumeration<DefaultMutableTreeNode> etype = racine.children();
+					etype.hasMoreElements();) {
+				ntype = etype.nextElement();
+				if (type.equals(ntype.getUserObject())) break;
+			}
+			insertNodeInto(new DefaultMutableTreeNode(prop, true), ntype, 0);
+		}
+		@SuppressWarnings("unchecked")
+		void insererNewValeur(String type, String prop, String valeur) {
+			DefaultMutableTreeNode racine = (DefaultMutableTreeNode) getRoot();
+			DefaultMutableTreeNode ntype = null;
+			DefaultMutableTreeNode nprop = null;
+			for (Enumeration<DefaultMutableTreeNode> etype = racine.children();
+					etype.hasMoreElements();) {
+				ntype = etype.nextElement();
+				if (type.equals(ntype.getUserObject())) {
+					for (Enumeration<DefaultMutableTreeNode> eprop = ntype.children(); eprop.hasMoreElements();) {
+						nprop = eprop.nextElement();
+						if (prop.equals(nprop.getUserObject())) break;
+					}
+					break;
+				}
+			}
+			insertNodeInto(new DefaultMutableTreeNode(valeur, false), nprop, 0);
+		}
+		@SuppressWarnings("unchecked")
+		void modifierValDefaut(String type, String prop, String valeur) {
+			DefaultMutableTreeNode racine = (DefaultMutableTreeNode) getRoot();
+			DefaultMutableTreeNode ntype = null;
+			DefaultMutableTreeNode nprop = null;
+			DefaultMutableTreeNode nval = null;
+			for (Enumeration<DefaultMutableTreeNode> etype = racine.children(); etype.hasMoreElements();) {
+				ntype = etype.nextElement();
+				if (type.equals(ntype.getUserObject())) {
+					for (Enumeration<DefaultMutableTreeNode> eprop = ntype.children(); eprop.hasMoreElements();) {
+						nprop = eprop.nextElement();
+						if (prop.equals(nprop.getUserObject())) break;
+					}
+					break;
+				}
+			}
+			for (Enumeration<DefaultMutableTreeNode> eval = nprop.children(); eval.hasMoreElements();) {
+				nval = eval.nextElement();
+				String val = (String) nval.getUserObject();
+				if (isDefaut(val)) {
+					nval.setUserObject(oteDefaut(val));
+					nodeChanged(nval);
+				}
+				if (val.equals(valeur)) {
+					nval.setUserObject(placeDefaut(val));
+					nodeChanged(nval);
+				}
+
+			}
+		}
+		void fusionnerType(DefaultMutableTreeNode noeudafusionner,
+				DefaultMutableTreeNode noeudagarder) {
+			removeNodeFromParent(noeudafusionner);
+			noeudagarder.removeAllChildren();
+			String type = (String) noeudagarder.getUserObject();
+			String[] props = structure.getNomsProps(classe, type).toArray(new String[0]);
+			Arrays.sort(props);
+			for (String prop : props) {
+				DefaultMutableTreeNode nprop = new DefaultMutableTreeNode(prop, true);
+				noeudagarder.add(nprop);
+				String[] vals = structure.getValeursProp(classe, type, prop).toArray(new String[0]);
+				Arrays.sort(vals);
+				for (String val : vals) {
+					if (val.equals(structure.getValeurParDefaut(classe, type, prop)))
+						val = placeDefaut(val);
+					DefaultMutableTreeNode nval = new DefaultMutableTreeNode(val, false);
+					nprop.add(nval);
+				}
+			}
+			nodeStructureChanged(noeudagarder);
+		}
+		void fusionnerProp(DefaultMutableTreeNode noeudtype, DefaultMutableTreeNode noeudafusionner,
+				DefaultMutableTreeNode noeudagarder) {
+			removeNodeFromParent(noeudafusionner);
+			noeudagarder.removeAllChildren();
+			String type = (String) noeudtype.getUserObject();
+			String prop = (String) noeudagarder.getUserObject();
+			String[] vals = structure.getValeursProp(classe, type, prop).toArray(new String[0]);
+			Arrays.sort(vals);
+			for (String val : vals) {
+				if (val.equals(structure.getValeurParDefaut(classe, type, prop)))
+					val = placeDefaut(val);
+				DefaultMutableTreeNode nval = new DefaultMutableTreeNode(val, false);
+				noeudagarder.add(nval);
+			}
+			nodeStructureChanged(noeudagarder);
+		}
+		void dispatcherProp(DefaultMutableTreeNode noeudtype,
+				DefaultMutableTreeNode noeudprop, String[] newtypes, String[] props,
+				String[][] propsvals) {
+			removeNodeFromParent(noeudtype);
+			removeNodeFromParent(noeudprop);
+			DefaultMutableTreeNode racine = (DefaultMutableTreeNode) getRoot();
+			DefaultMutableTreeNode ntype = null;
+			DefaultMutableTreeNode nprop = null;
+			for (String type : newtypes) {
+				insertNodeInto(ntype = new DefaultMutableTreeNode(type, true), racine, 0);
+				for (int i = 0; i<props.length; i++) {
+					insertNodeInto(nprop = new DefaultMutableTreeNode(props[i], true),
+							ntype, i);
+					for (int j = 0; j<propsvals[i].length; j++)
+						insertNodeInto(new DefaultMutableTreeNode(oteDefaut(propsvals[i][j]),
+								false), nprop, j);
+
+				}
+
+			}
+		}
+		@SuppressWarnings("unchecked")
+		boolean hasForme(DefaultMutableTreeNode noeudtype) {
+			for (Enumeration<DefaultMutableTreeNode> eprop = noeudtype.children();
+					eprop.hasMoreElements();) {
+				DefaultMutableTreeNode nprop = eprop.nextElement();
+				if (Structure.FORME.equals(nprop.getUserObject())) return true;
+			}
+
+			return false;
+		}
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/VisuStructure.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/Corpus.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/Corpus.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/Corpus.java	(revision 481)
@@ -0,0 +1,1013 @@
+
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.donnees;
+
+import java.awt.*;
+import java.io.*;
+import java.util.*;
+import java.util.ArrayList;
+import javax.swing.*;
+import visuAnalec.*;
+import visuAnalec.elements.*;
+import visuAnalec.Message.*;
+import visuAnalec.texte.PanneauTexte;
+import visuAnalec.util.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class Corpus {
+  public static interface CorpusListener extends EventListener {  // VisuAnalec, Vue et VisuStructure sont les seuls destinaires
+    void traiterEvent(Message e);
+  }
+  private ArrayList<CorpusListener> listeCorrespondants = new ArrayList<CorpusListener>();
+  private boolean modifie = false;
+  private String texte = "";
+  private ArrayList<Integer> finParagraphes = new ArrayList<Integer>();
+  private Structure structure = new Structure();
+  private HashMap<String, ArrayList<Unite>> unites = new HashMap<String, ArrayList<Unite>>();
+  private HashMap<String, ArrayList<Relation>> relations = new HashMap<String, ArrayList<Relation>>();
+  private HashMap<String, ArrayList<Schema>> schemas = new HashMap<String, ArrayList<Schema>>();
+  public void addEventListener(CorpusListener correspondant) {
+    listeCorrespondants.add(correspondant);
+  }
+  public void removeEventListener(CorpusListener correspondant) {
+    listeCorrespondants.remove(correspondant);
+  }
+  public ArrayList<CorpusListener> getListeDesCorrespondants() {
+	  return listeCorrespondants;
+  }
+  private void fireMessage(Message evt) {
+    modifie = !EnumSet.of(TypeMessage.CLEAR_CORPUS, TypeMessage.NEW_CORPUS).
+            contains(evt.getType());
+
+    for (Object corresp : listeCorrespondants.toArray()) {
+      ((CorpusListener) corresp).traiterEvent(evt);
+    }
+  }
+  public Structure getStructure() {
+    return structure;
+  }
+  public String getTexte() {
+    return texte;
+  }
+  public void setTexte(String texte) {
+    this.texte = texte;
+  }
+  public Integer[] getFinParagraphes() {
+    return finParagraphes.toArray(new Integer[0]);
+  }
+  public void setFinParagraphes(ArrayList<Integer> finpars) {
+    finParagraphes = finpars;
+  }
+  public String getTexteUnite(Unite unit) {
+    int deb = unit.getDeb();
+    int fin = unit.getFin();
+    return PanneauTexte.insereCarFinParagraphe(getTexte().substring(deb, fin),
+            getFinParagraphes(), deb);
+  }
+  public void modifTexte(String texte, ArrayList<Integer> finparag) {
+    this.texte = texte;
+    this.finParagraphes = finparag;
+    verifierFormesUnites();
+    fireMessage(new Message(this, TypeMessage.MODIF_TEXTE));
+  }
+  private void verifierFormesUnites() {
+    for (String type : structure.getTypes(Unite.class)) {
+      if (structure.getNomsProps(Unite.class, type).contains(Structure.FORME)) {
+        boolean modif = false;
+        for (Unite unit : getUnites(type)) {
+          String forme = getTexteUnite(unit);
+          if (!forme.equals(unit.getProp(Structure.FORME))) {
+            setValeurPropElement(unit, Structure.FORME, forme);
+          }
+        }
+      }
+    }
+  }
+  public void addFinParagraphe(int ind) {
+    finParagraphes.add(ind);
+  }
+  public void verifierFinParagrapheFinTexte() {
+    if (finParagraphes.isEmpty()
+            ||finParagraphes.get(finParagraphes.size()-1)<texte.length())
+      finParagraphes.add(texte.length());
+  }
+  public void trierFinParagraphes() {
+    Integer[] fins = getFinParagraphes();
+    Arrays.sort(fins);
+    finParagraphes = new ArrayList<Integer>(Arrays.asList(fins));
+  }
+  public void verifierFinParagraphesTypesUnites(String[] types) {
+    // Attention : les fins de paragraphes sont en désordre à la fin de la fonction
+    Integer[] fins = getFinParagraphes();
+    Arrays.sort(fins);
+    ArrayList<Integer> newFinPars = new ArrayList<Integer>();
+    for (String type : types) for (Unite unit : getUnites(type)) {
+        Integer fin = unit.getFin();
+        if (Arrays.binarySearch(fins, fin)<0) newFinPars.add(fin);
+      }
+    finParagraphes.addAll(newFinPars);
+  }
+  public int[] calculerNoParagraphe(Unite[] unites) {
+    // les unites sont triées
+    // les numéros de paragraphe commencent à 1 
+    int[] nosPar = new int[unites.length];
+    Integer[] finPar = getFinParagraphes();
+    Arrays.sort(finPar);
+    int nopar = 0;
+    for (int i = 0; i<unites.length; i++) {
+      while (unites[i].getDeb()>=finPar[nopar]) nopar++;
+      nosPar[i] = nopar+1;
+    }
+    return nosPar;
+  }
+  public String[][] getConcordances(Element[] elts, int empan) {
+    Integer[] finPar = getFinParagraphes();
+    String[][] concordances = new String[elts.length][3];
+    for (int i = 0; i<elts.length; i++) {
+      Unite unite0 = elts[i].getUnite0();
+      int debElt = unite0.getDeb();
+      int finElt = unite0.getFin();
+      int deb;
+      if (debElt-empan>0) {
+        concordances[i][0] = "[...]";
+        deb = debElt-empan;
+      } else {
+        concordances[i][0] = "";
+        deb = 0;
+      }
+      concordances[i][0] += PanneauTexte.insereCarFinParagraphe(
+              texte.substring(deb, debElt), finPar, deb);
+      concordances[i][1] = PanneauTexte.insereCarFinParagraphe(
+              texte.substring(debElt, finElt), finPar, debElt);
+      if (finElt+empan<texte.length()) {
+        concordances[i][2] = PanneauTexte.insereCarFinParagraphe(
+                texte.substring(finElt, finElt+empan), finPar, finElt)+"[...]";
+      } else
+        concordances[i][2] = PanneauTexte.insereCarFinParagraphe(
+                texte.substring(finElt), finPar, finElt);
+    }
+    return concordances;
+  }
+  public Unite addUniteSaisie(String type, int deb, int fin) { // ajout d'une unité saisie
+    Unite unite = new Unite(type, deb, fin);
+    addValeursDefauts(unite);
+    if (!unites.containsKey(type)) {
+      unites.put(type, new ArrayList<Unite>());
+    }
+    unites.get(type).add(unite);
+    fireMessage(new ElementEvent(this, TypeModifElement.AJOUT_UNITE, unite));
+    return unite;
+  }
+  public void addUniteLue(Unite unite) { // ajout d'une unité créée par la lecture d'un corpus: pas de message 
+    // et mise à jour éventuelle de la structure et de la HashMap unites
+    String type = unite.getType();
+    if (type==null||type.isEmpty()) return;
+    structure.majNewElement(unite);
+    if (!unites.containsKey(type)) {
+      unites.put(type, new ArrayList<Unite>());
+    }
+    unites.get(type).add(unite);
+  }
+  public void modifBornesUnite(Unite unite, int deb, int fin) {
+    unite.setDeb(deb);
+    unite.setFin(fin);
+    fireMessage(new ElementEvent(this, TypeModifElement.BORNES_UNITE, unite));
+  }
+  public void supUnite(Unite unite) {
+    String type = unite.getType();
+    unites.get(type).remove(unite);
+    fireMessage(new ElementEvent(this, TypeModifElement.SUP_UNITE, unite));
+    supLiensElement(unite);
+  }
+  public boolean checkPresenceUnite(String type, int deb, int fin) { // pas très efficace
+    if (!unites.containsKey(type)) return false;
+    for (Unite unit : getUnites(type))
+      if (unit.getDeb()==deb&&unit.getFin()==fin) return true;
+    return false;
+
+  }
+  private int checkFusionnerUnites(HashMap<String, ArrayList<Unite>> newunites, HashSet<Unite> unitesAajouter,
+          HashMap<Unite, Unite> unitesAfusionner) {
+    int nbEcrases = 0;
+    for (String type : newunites.keySet()) {
+      if (!unites.containsKey(type)) {
+        unitesAajouter.addAll(newunites.get(type));
+        continue;
+      }
+      for (Unite newunite : newunites.get(type)) {
+        Unite unit = chercherUniteCoincidente(newunite, unites.get(type));
+        if (unit==null) unitesAajouter.add(newunite);
+        else {
+          unitesAfusionner.put(newunite, unit);
+          for (String prop : newunite.getProps().keySet())
+            if (!unit.getProp(prop).isEmpty()&&!newunite.getProp(prop).isEmpty()
+                    &&!unit.getProp(prop).equals(newunite.getProp(prop))) {
+              nbEcrases++;
+              break;
+            }
+        }
+      }
+    }
+    return nbEcrases;
+  }
+  private Unite chercherUniteCoincidente(Unite unite, ArrayList<Unite> lunites) {
+    for (Unite unit : lunites) if (unite.coincide(unit)) return unit;
+    return null;
+  }
+  public void addRelationSaisie(String type, Element elt1, Element elt2) {
+    Relation relation = new Relation(type, elt1, elt2);
+    addValeursDefauts(relation);
+    if (!relations.containsKey(type)) {
+      relations.put(type, new ArrayList<Relation>());
+    }
+    relations.get(type).add(relation);
+    relation.getElt2().addRelationEntrante(relation);
+    relation.getElt1().addRelationSortante(relation);
+    fireMessage(new ElementEvent(this, TypeModifElement.AJOUT_RELATION, relation));
+  }
+  public void addRelationLue(Relation relation) { // ajout d'une relation créée par la lecture d'un corpus: pas de message
+    // et mise à jour éventuelle de la structure et de la HashMap relations
+    String type = relation.getType();
+    if (type==null||type.isEmpty()) return;
+    structure.majNewElement(relation);
+    if (!relations.containsKey(type)) {
+      relations.put(type, new ArrayList<Relation>());
+    }
+    relations.get(type).add(relation);
+    relation.getElt2().addRelationEntrante(relation);
+    relation.getElt1().addRelationSortante(relation);
+  }
+  public void supRelation(Relation rel) {
+    String type = rel.getType();
+    relations.get(type).remove(rel);
+    rel.getElt1().oteRelationSortante(rel);
+    rel.getElt2().oteRelationEntrante(rel);
+    fireMessage(new ElementEvent(this, TypeModifElement.SUP_RELATION, rel));
+    supLiensElement(rel);
+  }
+  private int checkFusionnerRelations(HashMap<String, ArrayList<Relation>> newrels, HashSet<Relation> relsAajouter,
+          HashMap<Relation, Relation> relsAfusionner) {
+    int nbEcrases = 0;
+    for (String type : newrels.keySet()) {
+      if (!relations.containsKey(type)) {
+        relsAajouter.addAll(newrels.get(type));
+        continue;
+      }
+      for (Relation newrel : newrels.get(type)) {
+        Relation rel = chercherRelationCoincidente(newrel, relations.get(type));
+        if (rel==null) relsAajouter.add(newrel);
+        else {
+          relsAfusionner.put(newrel, rel);
+          for (String prop : newrel.getProps().keySet())
+            if (!rel.getProp(prop).isEmpty()&&!newrel.getProp(prop).isEmpty()
+                    &&!rel.getProp(prop).equals(newrel.getProp(prop))) {
+              nbEcrases++;
+              break;
+            }
+        }
+      }
+    }
+    return nbEcrases;
+  }
+  private Relation chercherRelationCoincidente(Relation rel, ArrayList<Relation> lrels) {
+    for (Relation rel1 : lrels) if (rel.coincide(rel1)) return rel1;
+    return null;
+  }
+  private static void fusionnerElementsRelation(Relation relation, HashMap<Unite, Unite> unitesAfusionner,
+          HashMap<Relation, Relation> relationsAfusionner, HashMap<Schema, Schema> schemasAfusionner) {
+    if (relation.getElt1().getClass()==Unite.class&&unitesAfusionner.containsKey(relation.getElt1()))
+      relation.setElt1(unitesAfusionner.get(relation.getElt1()));
+    else if (relation.getElt1().getClass()==Relation.class&&relationsAfusionner.containsKey(relation.getElt1()))
+      relation.setElt1(relationsAfusionner.get(relation.getElt1()));
+    else if (relation.getElt1().getClass()==Schema.class&&schemasAfusionner.containsKey(relation.getElt1()))
+      relation.setElt1(schemasAfusionner.get(relation.getElt1()));
+    if (relation.getElt2().getClass()==Unite.class&&unitesAfusionner.containsKey(relation.getElt2()))
+      relation.setElt2(unitesAfusionner.get(relation.getElt2()));
+    else if (relation.getElt2().getClass()==Relation.class&&relationsAfusionner.containsKey(relation.getElt2()))
+      relation.setElt2(relationsAfusionner.get(relation.getElt2()));
+    else if (relation.getElt2().getClass()==Schema.class&&schemasAfusionner.containsKey(relation.getElt2()))
+      relation.setElt2(schemasAfusionner.get(relation.getElt2()));
+  }
+  public void addSchemaSaisi(String type, Element elt) {
+    Schema schema = new Schema(type);
+    addValeursDefauts(schema);
+    if (!schemas.containsKey(type)) {
+      schemas.put(type, new ArrayList<Schema>());
+    }
+    schemas.get(type).add(schema);
+    if (elt!=null) {
+      schema.ajouter(elt);
+      elt.addSchemaContenant(schema);
+    }
+    fireMessage(new ElementEvent(this, TypeModifElement.AJOUT_SCHEMA, schema));
+  }
+  public void addSchemaLu(Schema schema) {  // ajout d'un schéma créé par la lecture d'un corpus: pas de message
+    // et mise à jour éventuelle de la structure et de la HashMap schemas
+    String type = schema.getType();
+    if (type==null||type.isEmpty()) return;
+    structure.majNewElement(schema);
+    if (!schemas.containsKey(type)) {
+      schemas.put(type, new ArrayList<Schema>());
+    }
+    schemas.get(type).add(schema);
+    for (Element elt : schema.getContenu()) {
+      elt.addSchemaContenant(schema);
+    }
+  }
+  public void ajouterElementSchemaSaisi(Element elt, Schema sch) {
+    if (!sch.ajouter(elt)) {
+      GMessages.impossibiliteAction("Impossible d'ajouter cet élément "
+              +"au schéma courant :\n problème de récursivité infinie");
+    }
+    elt.addSchemaContenant(sch);
+    fireMessage(new ElementEvent(this, TypeModifElement.MODIF_SCHEMA, sch));
+  }
+  public void oterElementSchema(Element elt, Schema sch) {
+    sch.oter(elt);
+    elt.oteSchemaContenant(sch);
+    fireMessage(new ElementEvent(this, TypeModifElement.MODIF_SCHEMA, sch));
+  }
+  public void supSchema(Schema sch) {
+    String type = sch.getType();
+    schemas.get(type).remove(sch);
+    fireMessage(new ElementEvent(this, TypeModifElement.SUP_SCHEMA, sch));
+    supLiensElement(sch);
+  }
+  private int checkFusionnerSchemas(HashMap<String, ArrayList<Schema>> newschs, HashSet<Schema> schsAajouter,
+          HashMap<Schema, Schema> schsAfusionner) {
+    int nbEcrases = 0;
+    for (String type : newschs.keySet()) {
+      if (!schemas.containsKey(type)) {
+        schsAajouter.addAll(newschs.get(type));
+        continue;
+      }
+      for (Schema newsch : newschs.get(type)) {
+        Schema sch = chercherSchemaCoincident(newsch, schemas.get(type));
+        if (sch==null) schsAajouter.add(newsch);
+        else {
+          schsAfusionner.put(newsch, sch);
+          for (String prop : newsch.getProps().keySet())
+            if (!sch.getProp(prop).isEmpty()&&!newsch.getProp(prop).isEmpty()
+                    &&!sch.getProp(prop).equals(newsch.getProp(prop))) {
+              nbEcrases++;
+              break;
+            }
+        }
+      }
+    }
+    return nbEcrases;
+  }
+  private Schema chercherSchemaCoincident(Schema sch, ArrayList<Schema> lschs) {
+    for (Schema sch1 : lschs) if (sch.coincide(sch1)) return sch1;
+    return null;
+  }
+  private static void fusionnerElementsSchema(Schema schema, HashMap<Unite, Unite> unitesAfusionner,
+          HashMap<Relation, Relation> relationsAfusionner, HashMap<Schema, Schema> schemasAfusionner) {
+    for (Element elt : schema.getContenu()) {
+      if (elt.getClass()==Unite.class&&unitesAfusionner.containsKey(elt)) {
+        schema.oter(elt);
+        schema.ajouter(unitesAfusionner.get(elt));
+      } else if (elt.getClass()==Relation.class&&relationsAfusionner.containsKey(elt)) {
+        schema.oter(elt);
+        schema.ajouter(relationsAfusionner.get(elt));
+      } else if (elt.getClass()==Schema.class&&schemasAfusionner.containsKey(elt)) {
+        schema.oter(elt);
+        schema.ajouter(schemasAfusionner.get(elt));
+      }
+    }
+  }
+  private void supLiensElement(Element elt) {
+    ArrayList<Relation> rels = elt.getRelations();
+    for (Relation rel : rels) {
+      supRelation(rel);
+    }
+    ArrayList<Schema> schs = elt.getSchemas();
+    for (Schema sch : schs) {
+      oterElementSchema(elt, sch);
+    }
+  }
+  public void addValeur(Class<? extends Element> classe, String type, String prop, String valeur) {
+    structure.ajouterVal(classe, type, prop, valeur);
+    fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_VALEUR, classe, type, prop, valeur));
+  }
+  public void addValeursDefauts(Element elt) {
+    for (String prop : structure.getNomsProps(elt.getClass(), elt.getType())) {
+      elt.putProp(prop, structure.getValeurParDefaut(elt.getClass(), elt.getType(), prop));
+    }
+  }
+  public void ajouterFormeUnite(String type) {
+    structure.ajouterProp(Unite.class, type, Structure.FORME);
+    fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_FORME_UNITE,
+            Unite.class, type));
+  }
+  public void instancierFormeUnite(String type) {
+    ArrayList<Unite> units = getUnites(type);
+    for (Unite unit : units) {
+      String forme = getTexteUnite(unit);
+      setValeurPropElement(unit, Structure.FORME, forme);
+    }
+  }
+  public void modifierValParDefaut(Class<? extends Element> classe, String type, String prop, String val) {
+    structure.modifierValParDefaut(classe, type, prop, val);
+    if (!val.isEmpty()) instancierParValeurDefaut(classe, type, prop, val);
+    fireMessage(new StructureEvent(this, TypeModifStructure.VALEUR_PAR_DEFAUT, classe, type, prop, val));
+  }
+  private void instancierParValeurDefaut(Class<? extends Element> classe, String type, String prop, String val) {
+    ArrayList<? extends Element> elts = getElements(classe, type);
+    boolean noninstancies = false;
+    for (Element elt : elts) if (elt.getProp(prop).isEmpty()) {
+        noninstancies = true;
+        break;
+      }
+    if (noninstancies&&JOptionPane.showConfirmDialog(null, "Voulez-vous donner "
+            +"cette valeur par défaut aux éléments existants non encore instanciés",
+            "Action optionnelle", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)
+            !=JOptionPane.NO_OPTION)
+      for (Element elt : elts) if (elt.getProp(prop).isEmpty())
+          elt.putProp(prop, val);
+  }
+  public void setValeurPropElement(Element elt, String prop, String newval) {
+    if (newval.isEmpty()) {
+      elt.supProp(prop);
+    } else {
+      if (!structure.getValeursProp(elt.getClass(), elt.getType(), prop).contains(newval)) {
+        addValeur(elt.getClass(), elt.getType(), prop, newval);
+      }
+      elt.putProp(prop, newval);
+    }
+    fireMessage(new ElementEvent(this, TypeModifElement.MODIF_VALEUR, elt, prop, newval));
+
+  }
+  public ArrayList<? extends Element> getElements(Class<? extends Element> classe, String type) {
+    if (classe==Unite.class) return getUnites(type);
+    if (classe==Relation.class) return getRelations(type);
+    if (classe==Schema.class) return getSchemas(type);
+    throw new UnsupportedOperationException("sous-classe non traitée");
+  }
+  public ArrayList<Unite> getUnites(String type) {
+    if (unites.get(type)==null) {
+      return new ArrayList<Unite>();
+    }
+    return unites.get(type);
+  }
+  public ArrayList<Unite> getToutesUnites() {
+    ArrayList<Unite> ttesUnites = new ArrayList<Unite>();
+    for (String type : structure.getTypes(Unite.class)) {
+      ttesUnites.addAll(getUnites(type));
+    }
+    return ttesUnites;
+  }
+  public ArrayList<Relation> getRelations(String type) {
+    if (relations.get(type)==null) {
+      return new ArrayList<Relation>();
+    }
+    return relations.get(type);
+  }
+  public ArrayList<Relation> getToutesRelations() {
+    ArrayList<Relation> ttesRelations = new ArrayList<Relation>();
+    for (String type : structure.getTypes(Relation.class)) {
+      ttesRelations.addAll(getRelations(type));
+    }
+    return ttesRelations;
+  }
+  public ArrayList<Schema> getSchemas(String type) {
+    if (schemas.get(type)==null) {
+      return new ArrayList<Schema>();
+    }
+    return schemas.get(type);
+  }
+  public ArrayList<Schema> getTousSchemas() {
+    ArrayList<Schema> tsSchemas = new ArrayList<Schema>();
+    for (String type : structure.getTypes(Schema.class)) {
+      tsSchemas.addAll(getSchemas(type));
+    }
+    return tsSchemas;
+  }
+// Modifs de la structure provenant de VisuStructure
+  public String saisirAjouterType(Container fenetre, Class<? extends Element> classe) {
+    String newNom = JOptionPane.showInputDialog(fenetre, "Nom du nouveau type ",
+            "Ajouter un type "+GVisu.getNomDeClasse(classe),
+            JOptionPane.PLAIN_MESSAGE);
+    if (newNom==null) return null;
+    newNom = newNom.trim();
+    if (newNom.isEmpty()) return null;
+    if (structure.getTypes(classe).contains(newNom)) {
+      JOptionPane.showMessageDialog(fenetre, "Ajout impossible : le type "+"\""+newNom+"\""+" existe déjà",
+              "Erreur d'ajout de type", JOptionPane.ERROR_MESSAGE);
+      return null;
+    }
+    ajouterType(classe, newNom);
+    fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_TYPE, classe, newNom));
+    return newNom;
+  }
+  private void ajouterType(Class<? extends Element> classe, String type) {
+    structure.ajouterType(classe, type);
+    if (classe==Unite.class) {
+      unites.put(type, new ArrayList<Unite>());
+    } else if (classe==Relation.class) {
+      relations.put(type, new ArrayList<Relation>());
+    } else if (classe==Schema.class) {
+      schemas.put(type, new ArrayList<Schema>());
+    }
+  }
+  public String saisirAjouterProp(Container fenetre, Class<? extends Element> classe, String type) {
+    String newNom = JOptionPane.showInputDialog(fenetre, "Nom de la nouvelle propriété",
+            "Ajouter une propriété au type "+"\""+type+"\"", JOptionPane.PLAIN_MESSAGE);
+    if (newNom==null) return null;
+    newNom = newNom.trim();
+    if (newNom.isEmpty()) return null;
+    if (Structure.FORME.equals(newNom)) {
+      GMessages.impossibiliteAction("Le nom "+Structure.FORME+" est réservé par le système");
+      return null;
+    }
+    if (structure.getNomsProps(classe, type).contains(newNom)) {
+      JOptionPane.showMessageDialog(fenetre, "Ajout impossible :la propriété "+"\""+newNom+"\""+" existe déjà",
+              "Erreur d'ajout de propriété", JOptionPane.ERROR_MESSAGE);
+      return null;
+    }
+    structure.ajouterProp(classe, type, newNom);
+    fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_PROP, classe, type, newNom));
+    return newNom;
+  }
+  public String saisirAjouterVal(Container fenetre, Class<? extends Element> classe, String type, String prop) {
+    String newNom = JOptionPane.showInputDialog(fenetre, "Nom de la nouvelle valeur",
+            "Ajouter une valeur pour la propriété "+"\""+prop+"\"", JOptionPane.PLAIN_MESSAGE);
+    if (newNom==null) return null;
+    newNom = newNom.trim();
+    if (newNom.isEmpty()) return null;
+    if (structure.getValeursProp(classe, type, prop).contains(newNom)) {
+      JOptionPane.showMessageDialog(fenetre, "Ajout impossible : la valeur "+"\""+newNom+"\""+" existe déjà",
+              "Erreur d'ajout de valeur", JOptionPane.ERROR_MESSAGE);
+      return null;
+    }
+    structure.ajouterVal(classe, type, prop, newNom);
+    fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_VALEUR, classe, type, prop, newNom));
+    return newNom;
+  }
+  public String saisirRenommerType(Container fenetre, Class<? extends Element> classe, String oldNom) {
+    String newNom = (String) JOptionPane.showInputDialog(fenetre, "Nouveau nom pour le type "+"\""+oldNom+"\"",
+            "Renommer un type "+GVisu.getNomDeClasse(classe), JOptionPane.PLAIN_MESSAGE, null, null, oldNom);
+    if (newNom==null) return null;
+    newNom = newNom.trim();
+    if (oldNom.equals(newNom)||newNom.isEmpty()) return null;
+    boolean fusion = structure.getTypes(classe).contains(newNom);
+    if (fusion&&!GMessages.confirmationAction("Le type "+"\""+newNom+"\""
+            +" existe déjà. Fusionner les deux types ? ")) return null;
+    if (classe==Unite.class) {
+      if (fusion) unites.get(newNom).addAll(unites.get(oldNom));
+      else unites.put(newNom, unites.get(oldNom));
+      for (Unite unit : unites.get(oldNom)) unit.setType(newNom);
+      unites.remove(oldNom);
+    } else if (classe==Relation.class) {
+      if (fusion) relations.get(newNom).addAll(relations.get(oldNom));
+      else relations.put(newNom, relations.get(oldNom));
+      for (Relation rel : relations.get(oldNom)) {
+        rel.getElt1().oteRelationSortante(rel);
+        rel.getElt2().oteRelationEntrante(rel);
+        rel.setType(newNom);
+        rel.getElt1().addRelationSortante(rel);
+        rel.getElt2().addRelationEntrante(rel);
+      }
+      relations.remove(oldNom);
+    } else if (classe==Schema.class) {
+      if (fusion) schemas.get(newNom).addAll(schemas.get(oldNom));
+      else schemas.put(newNom, schemas.get(oldNom));
+      for (Schema sch : schemas.get(oldNom)) {
+        for (Element elt : sch.getContenu()) elt.oteSchemaContenant(sch);
+        sch.setType(newNom);
+        for (Element elt : sch.getContenu()) elt.addSchemaContenant(sch);
+      }
+      schemas.remove(oldNom);
+    }
+    if (fusion) {
+      structure.fusionnerType(classe, oldNom, newNom);
+      fireMessage(new StructureEvent(this, TypeModifStructure.FUSION_TYPE,
+              classe, oldNom, newNom));
+    } else {
+      structure.renommerType(classe, oldNom, newNom);
+      fireMessage(new StructureEvent(this, TypeModifStructure.RENOM_TYPE,
+              classe, oldNom, newNom));
+    }
+    return newNom;
+  }
+  public String saisirRenommerProp(Container fenetre,
+          Class<? extends Element> classe, String type, String oldNom) {
+    String newNom = (String) JOptionPane.showInputDialog(fenetre, "Nouveau nom pour la propriété "+"\""+oldNom+"\"",
+            "Renommer une propriété du type "+"\""+type+"\"", JOptionPane.PLAIN_MESSAGE, null, null, oldNom);
+    if (newNom==null) return null;
+    newNom = newNom.trim();
+    if (oldNom.equals(newNom)||newNom.isEmpty()) return null;
+    if (Structure.FORME.equals(newNom)) {
+      GMessages.impossibiliteAction("Le nom "+Structure.FORME+" est réservé par le système");
+      return null;
+    }
+    boolean fusion = false;
+    ArrayList<? extends Element> elements = getElements(classe, type);
+    if (structure.getNomsProps(classe, type).contains(newNom)) {
+      int rep = JOptionPane.showOptionDialog(fenetre, "La propriété "+"\""+newNom+"\""+" existe déjà."
+              +" Fusionner les deux propriétés ? ", "Propriété existante",
+              JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+              null, new Object[]{"Oui", "Annuler"}, "Oui");
+      if (rep==1) return null;
+      int nbEcrases = 0;
+      for (Element elt : elements) if (!elt.getProp(newNom).isEmpty()
+                &&!elt.getProp(newNom).equals(elt.getProp(oldNom))) nbEcrases++;
+      if (nbEcrases>0) {
+        int rep1 = JOptionPane.showOptionDialog(fenetre, "L'opération de fusion va écraser l'ancienne valeur de la propriété "
+                +"\""+newNom+"\""+" pour "+nbEcrases+" élément(s)", "Fusion de deux propriétés",
+                JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+                null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+        if (rep1==1) return null;
+      }
+      fusion = true;
+    }
+    if (fusion) structure.fusionnerProp(classe, type, oldNom, newNom);
+    else structure.renommerProp(classe, type, oldNom, newNom);
+    for (Element elt : elements) {
+      String val = elt.getProp(oldNom);
+      if (!val.isEmpty()) elt.putProp(newNom, val);
+      elt.getProps().remove(oldNom);
+    }
+    if (fusion)
+      fireMessage(new StructureEvent(this, TypeModifStructure.FUSION_PROP, classe, type, oldNom, newNom));
+    else
+      fireMessage(new StructureEvent(this, TypeModifStructure.RENOM_PROP, classe, type, oldNom, newNom));
+    return newNom;
+  }
+  public String saisirRenommerVal(Container fenetre, Class<? extends Element> classe, String type,
+          String prop, String oldNom) {
+    String newNom = (String) JOptionPane.showInputDialog(fenetre, "Nouveau nom pour la valeur "+"\""+oldNom+"\"",
+            "Renommer une valeur de la propriété "+"\""+prop+"\"", JOptionPane.PLAIN_MESSAGE, null, null, oldNom);
+    if (newNom==null) return null;
+    newNom = newNom.trim();
+    if (oldNom.equals(newNom)||newNom.isEmpty()) return null;
+    boolean fusion = false;
+    if (structure.getValeursProp(classe, type, prop).contains(newNom)) {
+      int rep = JOptionPane.showOptionDialog(fenetre, "La valeur "+"\""+newNom+"\""+" existe déjà."
+              +" Fusionner les deux valeurs ? ", "Valeur existante",
+              JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+              null, new Object[]{"Oui", "Annuler"}, "Oui");
+      if (rep==1) return null;
+      fusion = true;
+    }
+    structure.renommerVal(classe, type, prop, oldNom, newNom);
+    ArrayList<? extends Element> elements = getElements(classe, type);
+    for (Element elt : elements) {
+      String val = elt.getProp(prop);
+      if (oldNom.equals(val)) {
+        elt.putProp(prop, newNom);
+      }
+    }
+    if (fusion)
+      fireMessage(new StructureEvent(this, TypeModifStructure.FUSION_VALEUR, classe, type, prop, oldNom, newNom));
+    else
+      fireMessage(new StructureEvent(this, TypeModifStructure.RENOM_VALEUR, classe, type, prop, oldNom, newNom));
+    return newNom;
+  }
+  public boolean saisirSupprimerType(Container fenetre, Class<? extends Element> classe, String type) {
+    Element[] elements = new Element[0];
+    if (classe==Unite.class) {
+      if (unites.containsKey(type))
+        elements = unites.get(type).toArray(elements);
+    } else if (classe==Relation.class) {
+      if (unites.containsKey(type))
+        elements = relations.get(type).toArray(elements);
+    } else if (classe==Schema.class) {
+      if (unites.containsKey(type))
+        elements = schemas.get(type).toArray(elements);
+    }
+    if (elements.length>0) {
+      int nbSupprimes = elements.length;
+      int rep = JOptionPane.showOptionDialog(fenetre, "La suppresion du type  "+"\""+type+"\""
+              +" va entraîner la suppression "+(nbSupprimes==1 ? "d'un élément" : "de "+nbSupprimes+" éléments"),
+              "Suppression "+GVisu.getNomDeClasse(classe)+"s",
+              JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+              null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+      if (rep==1) return false;
+      if (classe==Unite.class) {
+        for (Element elt : elements) supUnite((Unite) elt);
+        unites.remove(type);
+      }
+      if (classe==Relation.class) {
+        for (Element elt : elements) supRelation((Relation) elt);
+        relations.remove(type);
+      }
+      if (classe==Schema.class) {
+        for (Element elt : elements) supSchema((Schema) elt);
+        schemas.remove(type);
+      }
+    }
+    structure.supprimerType(classe, type);
+    fireMessage(new StructureEvent(this, TypeModifStructure.SUPPR_TYPE, classe, type));
+    return true;
+  }
+  public boolean saisirSupprimerProp(Container fenetre, Class<? extends Element> classe, String type, String oldNom) {
+    ArrayList<? extends Element> elements = getElements(classe, type);
+    int nbSup = 0;
+    for (Element elt : elements) if (!elt.getProp(oldNom).isEmpty()) nbSup++;
+    if (nbSup>0) {
+      int rep = JOptionPane.showOptionDialog(fenetre, "La propriété "+"\""+oldNom+"\""+" était instanciée pour "
+              +(nbSup==1 ? "un élément" : nbSup+" éléments"), "Suppression d'une propriété",
+              JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+              null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+      if (rep==1) return false;
+    }
+    for (Element elt : elements) elt.supProp(oldNom);
+    structure.supprimerProp(classe, type, oldNom);
+    fireMessage(new StructureEvent(this, TypeModifStructure.SUPPR_PROP, classe, type, oldNom));
+    return true;
+  }
+  public boolean saisirSupprimerVal(Container fenetre, Class<? extends Element> classe, String type,
+          String prop, String oldNom) {
+    ArrayList<? extends Element> elements = getElements(classe, type);
+    int nbSup = 0;
+    for (Element elt : elements) if (oldNom.equals(elt.getProp(prop)))
+        nbSup++;
+    if (nbSup>0) {
+      int rep = JOptionPane.showOptionDialog(fenetre, "La valeur "+"\""+oldNom+"\""+" était attribuée à "
+              +(nbSup==1 ? "un élément" : nbSup+" éléments"), "Suppression d'une valeur",
+              JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+              null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+      if (rep==1) return false;
+    }
+    structure.supprimerVal(classe, type, prop, oldNom);
+    for (Element elt : elements) if (oldNom.equals(elt.getProp(prop)))
+        elt.supProp(prop);
+    fireMessage(new StructureEvent(this, TypeModifStructure.SUPPR_VALEUR, classe, type, prop, oldNom));
+    return true;
+  }
+  public boolean saisirDispatcherProp(Container fenetre,
+          Class<? extends Element> classe, String oldtype, String oldprop,
+          String[] newtypes, String[] props, String[][] propsvals) {
+    HashSet<String> types = structure.getTypes(classe);
+    for (String type : newtypes) if (types.contains(type)) {
+        GMessages.impossibiliteAction("Le type "+type+" existe déjà");
+        return false;
+      }
+    ArrayList<? extends Element> elements = getElements(classe, oldtype);
+    for (Element elt : elements) if (elt.getProp(oldprop).isEmpty()) {
+        GMessages.impossibiliteAction("Certains éléments de type "+oldtype
+                +" ne possèdent pas de valeur pour la propriété "+oldprop);
+        return false;
+      }
+    structure.supprimerType(classe, oldtype);
+    for (String type : newtypes) {
+      structure.ajouterType(classe, type);
+      for (int i = 0; i<props.length; i++) {
+        structure.ajouterProp(classe, type, props[i]);
+        for (String val : propsvals[i])
+          structure.ajouterVal(classe, type, props[i], val);
+      }
+    }
+    if (classe==Unite.class) {
+      for (String type : newtypes) unites.put(type, new ArrayList<Unite>());
+      for (Unite unit : unites.get(oldtype)) {
+        String newtype = unit.getProp(oldprop);
+        unit.supProp(oldprop);
+        unit.setType(newtype);
+        unites.get(newtype).add(unit);
+      }
+      unites.remove(oldtype);
+    } else if (classe==Relation.class) {
+      for (String type : newtypes)
+        relations.put(type, new ArrayList<Relation>());
+      for (Relation rel : relations.get(oldtype)) {
+        String newtype = rel.getProp(oldprop);
+        rel.supProp(oldprop);
+        rel.getElt1().oteRelationSortante(rel);
+        rel.getElt2().oteRelationEntrante(rel);
+        rel.setType(newtype);
+        rel.getElt1().addRelationSortante(rel);
+        rel.getElt2().addRelationEntrante(rel);
+        relations.get(newtype).add(rel);
+      }
+      relations.remove(oldtype);
+    } else if (classe==Schema.class) {
+      for (String type : newtypes) schemas.put(type, new ArrayList<Schema>());
+      for (Schema sch : schemas.get(oldtype)) {
+        String newtype = sch.getProp(oldprop);
+        sch.supProp(oldprop);
+        for (Element elt : sch.getContenu()) elt.oteSchemaContenant(sch);
+        sch.setType(newtype);
+        for (Element elt : sch.getContenu()) elt.addSchemaContenant(sch);
+        schemas.get(newtype).add(sch);
+      }
+      schemas.remove(oldtype);
+    }
+    fireMessage(new StructureEvent(this, TypeModifStructure.SUPPR_TYPE,
+            classe, oldtype));
+    for (String type : newtypes) {
+      fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_TYPE_ET_ELEMENTS,
+              classe, type));
+      for (String prop : props)
+        fireMessage(new StructureEvent(this, TypeModifStructure.AJOUT_PROP,
+                classe, type, prop));
+    }
+    return true;
+  }
+  public void clearAnnot() {
+    finParagraphes.clear();
+    unites.clear();
+    relations.clear();
+    schemas.clear();
+  }
+  public void clearAll() {
+    clearAnnot();
+    structure.clear();
+    texte = "";
+  }
+  public boolean isModifie() {
+    return modifie;
+  }
+  public boolean isVide() {
+    return texte.isEmpty()&&structure.isVide();
+  }
+  public void fermer() {
+    if (isVide()) return;
+    clearAnnot();
+    structure.clear();
+    texte = "";
+    fireMessage(new Message(this, TypeMessage.CLEAR_CORPUS));
+  }
+  public void fermerConserverStructure() {
+    if (texte.isEmpty()) return;
+    clearAnnot();
+    texte = "";
+    fireMessage(new Message(this, TypeMessage.CLEAR_CORPUS));
+  }
+  @SuppressWarnings("unchecked")
+  public void lireJava(ObjectInputStream ois, boolean batch) throws IOException, ClassNotFoundException, ClassCastException {
+    texte = (String) ois.readObject();
+    finParagraphes = (ArrayList<Integer>) ois.readObject();
+    unites = (HashMap<String, ArrayList<Unite>>) ois.readObject();
+    relations = (HashMap<String, ArrayList<Relation>>) ois.readObject();
+    schemas = (HashMap<String, ArrayList<Schema>>) ois.readObject();
+    structure = Structure.lireJava(ois);
+    if (!batch) fireMessage(new Message(this, TypeMessage.NEW_CORPUS));
+  }
+  @SuppressWarnings("unchecked")
+  public void fusionnerAnnotJava(ObjectInputStream ois) throws IOException, ClassNotFoundException, ClassCastException {
+    String texte1 = (String) ois.readObject();
+    ArrayList<Integer> finParagraphes1 = (ArrayList<Integer>) ois.readObject();
+    if (!texte1.equals(texte)||!finParagraphes1.equals(finParagraphes)) {
+      JOptionPane.showMessageDialog(null, "Le texte du corpus à fusionner est différent du texte en cours",
+              "Fusion d'annotations impossible.", JOptionPane.ERROR_MESSAGE);
+      return;
+    }
+    HashMap<String, ArrayList<Unite>> unites1 = (HashMap<String, ArrayList<Unite>>) ois.readObject();
+    HashMap<String, ArrayList<Relation>> relations1 = (HashMap<String, ArrayList<Relation>>) ois.readObject();
+    HashMap<String, ArrayList<Schema>> schemas1 = (HashMap<String, ArrayList<Schema>>) ois.readObject();
+    Structure structure1 = Structure.lireJava(ois);
+    fusionnerStructureLue(structure1);
+    HashSet<Unite> unitesAajouter = new HashSet<Unite>();
+    HashMap<Unite, Unite> unitesAfusionner = new HashMap<Unite, Unite>();
+    int nbUnitesEcrasees = checkFusionnerUnites(unites1, unitesAajouter, unitesAfusionner);
+    HashSet<Relation> relationsAajouter = new HashSet<Relation>();
+    HashMap<Relation, Relation> relationsAfusionner = new HashMap<Relation, Relation>();
+    int nbRelationsEcrasees = checkFusionnerRelations(relations1, relationsAajouter, relationsAfusionner);
+    HashSet<Schema> schemasAajouter = new HashSet<Schema>();
+    HashMap<Schema, Schema> schemasAfusionner = new HashMap<Schema, Schema>();
+    int nbSchemasEcrases = checkFusionnerSchemas(schemas1, schemasAajouter, schemasAfusionner);
+    int nbEcrases = nbUnitesEcrasees+nbRelationsEcrasees+nbSchemasEcrases; // à améliorer
+    if (nbUnitesEcrasees>0||nbRelationsEcrasees>0||nbSchemasEcrases>0) {
+      int rep = JOptionPane.showOptionDialog(null, "L'opération de fusion va écraser d'anciennes valeurs de propriétés "
+              +" pour "+nbEcrases+" élément(s)", "Fusion d'annotations",
+              JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+              null, new Object[]{"Continuer", "Annuler"}, "Continuer");
+      if (rep==1) return;
+    }
+    for (Unite unit : unitesAajouter) addUniteLue(unit);
+    for (Unite unit : unitesAfusionner.keySet())
+      for (String prop : unit.getProps().keySet())
+        unitesAfusionner.get(unit).putProp(prop, unit.getProp(prop));
+    for (Relation rel : relationsAajouter) {
+      fusionnerElementsRelation(rel, unitesAfusionner, relationsAfusionner, schemasAfusionner);
+      addRelationLue(rel);
+    }
+    for (Relation rel : relationsAfusionner.keySet())
+      for (String prop : rel.getProps().keySet())
+        relationsAfusionner.get(rel).putProp(prop, rel.getProp(prop));
+    for (Schema sch : schemasAajouter) {
+      fusionnerElementsSchema(sch, unitesAfusionner, relationsAfusionner, schemasAfusionner);
+      addSchemaLu(sch);
+    }
+    for (Schema sch : schemasAfusionner.keySet())
+      for (String prop : sch.getProps().keySet())
+        unitesAfusionner.get(sch).putProp(prop, sch.getProp(prop));
+    fireMessage(new Message(this, TypeMessage.NEW_CORPUS));
+  }
+  @SuppressWarnings("unchecked")
+  public void concatenerCorpusJava(ObjectInputStream ois) throws IOException, ClassNotFoundException, ClassCastException {
+    String texte1 = (String) ois.readObject();
+    ArrayList<Integer> finParagraphes1 = (ArrayList<Integer>) ois.readObject();
+    int offset = texte.length();
+    texte += texte1;
+    for (int finP : finParagraphes1) finParagraphes.add(finP+offset);
+    verifierFinParagrapheFinTexte();
+    HashMap<String, ArrayList<Unite>> unites1 = (HashMap<String, ArrayList<Unite>>) ois.readObject();
+    HashMap<String, ArrayList<Relation>> relations1 = (HashMap<String, ArrayList<Relation>>) ois.readObject();
+    HashMap<String, ArrayList<Schema>> schemas1 = (HashMap<String, ArrayList<Schema>>) ois.readObject();
+    Structure structure1 = Structure.lireJava(ois);
+    fusionnerStructureLue(structure1);
+    for (String type : unites1.keySet()) for (Unite unit : unites1.get(type)) {
+        unit.setDeb(unit.getDeb()+offset);
+        unit.setFin(unit.getFin()+offset);
+        addUniteLue(unit);
+      }
+    for (String type : relations1.keySet())
+      for (Relation rel : relations1.get(type)) {
+        addRelationLue(rel);
+      }
+    for (String type : schemas1.keySet())
+      for (Schema sch : schemas1.get(type)) {
+        addSchemaLu(sch);
+      }
+  }
+  @SuppressWarnings("unchecked")
+  public void extraireEtConcatenerCorpusJava(ObjectInputStream ois,
+          String nomDocument, String type)
+          throws IOException, ClassNotFoundException, ClassCastException {
+//    System.out.println(nomDocument);
+    String texte1 = (String) ois.readObject();
+    ArrayList<Integer> finParagraphes1 = (ArrayList<Integer>) ois.readObject();
+    HashMap<String, ArrayList<Unite>> unites1 = (HashMap<String, ArrayList<Unite>>) ois.readObject();
+    if (unites1.containsKey(type)) {
+      int indFinPar1 = -1;
+      int offset1 = -1;
+      int offset = -1;
+      for (Unite unit : unites1.get(type)) {
+        int finUnit = unit.getFin();
+        if (indFinPar1<0||finUnit>finParagraphes1.get(indFinPar1)) {
+          do indFinPar1++;
+          while (finUnit>finParagraphes1.get(indFinPar1));
+          offset1 = indFinPar1==0 ? 0 : finParagraphes1.get(indFinPar1-1);
+          offset = texte.length();
+          texte += texte1.substring(offset1, finParagraphes1.get(indFinPar1));
+          finParagraphes.add(texte.length());
+        }
+        unit.setDeb(unit.getDeb()-offset1+offset);
+        unit.setFin(unit.getFin()-offset1+offset);
+        unit.putProp("sourceFile", nomDocument);
+        addUniteLue(unit);
+      }
+    }
+  }
+  public void ecrireJava(ObjectOutputStream oos) throws IOException {
+    oos.writeObject(texte);
+    oos.writeObject(finParagraphes);
+    oos.writeObject(unites);
+    oos.writeObject(relations);
+    oos.writeObject(schemas);
+    structure.ecrireJava(oos);
+    modifie = false;
+  }
+  @SuppressWarnings("unchecked")
+  public void fusionnerStructureLue(Structure structureLue) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class
+    }) {
+      for (String typeLu : structureLue.getTypes(classe)) {
+        if (!structure.getTypes(classe).contains(typeLu))
+          ajouterType(classe, typeLu);
+        for (String propLue : structureLue.getNomsProps(classe, typeLu)) {
+          if (!structure.getNomsProps(classe, typeLu).contains(propLue))
+            structure.ajouterProp(classe, typeLu, propLue);
+          for (String valLue : structureLue.getValeursProp(classe, typeLu, propLue))
+            if (!structure.getValeursProp(classe, typeLu, propLue).contains(valLue))
+              structure.ajouterVal(classe, typeLu, propLue, valLue);
+          String valdefLue = structureLue.getValeurParDefaut(classe, typeLu, propLue);
+          String valdef = structure.getValeurParDefaut(classe, typeLu, propLue);
+          if (!valdefLue.isEmpty()&&!valdefLue.equals(valdef)) {
+            structure.modifierValParDefaut(classe, typeLu, propLue, valdefLue);
+          }
+        }
+      }
+    }
+  }
+  public void ecrireStructureJava(ObjectOutputStream oos) throws IOException {
+    structure.ecrireJava(oos);
+  }
+  public Structure lireStructureJava(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+    return Structure.lireJava(ois);
+  }
+  public void lireTexte(BufferedReader text) throws IOException {
+    String parag;
+    String newtexte = "";
+    ArrayList<Integer> newfinParag = new ArrayList<Integer>();
+    while ((parag = text.readLine())!=null) {
+      newtexte += parag;
+      newfinParag.add(newtexte.length());
+    }
+    texte = newtexte;
+    finParagraphes = newfinParag;
+    fireMessage(new Message(this, TypeMessage.NEW_CORPUS));
+  }
+  public void newCorpusLu() {
+    fireMessage(new Message(this, TypeMessage.NEW_CORPUS));
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/Corpus.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/Structure.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/Structure.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/Structure.java	(revision 481)
@@ -0,0 +1,313 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.donnees;
+
+import java.io.*;
+import java.util.*;
+
+import visuAnalec.elements.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class Structure implements Serializable {
+  public final static String FORME = "#forme#";
+  private HashMap<Class<? extends Element>, HashSet<String>> types =
+          new HashMap<Class<? extends Element>, HashSet<String>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashSet<String>>> nomsProps =
+          new HashMap<Class<? extends Element>, HashMap<String, HashSet<String>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashSet<String>>>> valeursProps =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashSet<String>>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, String>>> valeursParDefaut =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, String>>>();
+
+  @SuppressWarnings("unchecked")
+  public Structure() {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      types.put(classe, new HashSet<String>());
+      nomsProps.put(classe, new HashMap<String, HashSet<String>>());
+      valeursProps.put(classe, new HashMap<String, HashMap<String, HashSet<String>>>());
+      valeursParDefaut.put(classe, new HashMap<String, HashMap<String, String>>());
+    }
+  }
+  
+  public HashSet<String> getSchemas() {
+	  return this.getTypes(Schema.class);
+  }
+  
+  public HashSet<String> getRelations() {
+	  return this.getTypes(Relation.class);
+  }
+  
+  public HashSet<String> getUnites() {
+	  return this.getTypes(Unite.class);
+  }
+  
+  public HashSet<String> getSchemaProperties(String schema_type) {
+	  return getNomsProps(Schema.class, schema_type);
+  }
+  
+  public HashSet<String> getUniteProperties(String schema_type) {
+	  return getNomsProps(Unite.class, schema_type);
+  }
+  
+  public HashSet<String> getRelationProperties(String schema_type) {
+	  return getNomsProps(Relation.class, schema_type);
+  }
+
+  @Override
+  public String toString() {
+    String dump = "STRUCTURE :";
+    dump += "\n\tUNITES : ";
+    dump += "\n\t\tTYPES : ";
+    for (String type : types.get(Unite.class)) {
+      dump += type+"; ";
+    }
+    dump += "\n\t\tNOMSPROP : ";
+    for (String type : nomsProps.get(Unite.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : nomsProps.get(Unite.class).get(type)) {
+        dump += prop+"; ";
+      }
+    }
+    dump += "\n\t\tVALEURSPROP : ";
+    for (String type : valeursProps.get(Unite.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : valeursProps.get(Unite.class).get(type).keySet()) {
+        dump += "\n\t\t\t\t"+prop+" : ";
+        for (String val : valeursProps.get(Unite.class).get(type).get(prop)) {
+          dump += val+"; ";
+        }
+      }
+    }
+
+    dump += "\n\tRELATIONS : ";
+    dump += "\n\t\tTYPES : ";
+    for (String type : types.get(Relation.class)) {
+      dump += type+"; ";
+    }
+    dump += "\n\t\tNOMSPROP : ";
+    for (String type : nomsProps.get(Relation.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : nomsProps.get(Relation.class).get(type)) {
+        dump += prop+"; ";
+      }
+    }
+    dump += "\n\t\tVALEURSPROP : ";
+    for (String type : valeursProps.get(Relation.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : valeursProps.get(Relation.class).get(type).keySet()) {
+        dump += "\n\t\t\t\t"+prop+" : ";
+        for (String val : valeursProps.get(Relation.class).get(type).get(prop)) {
+          dump += val+"; ";
+        }
+      }
+    }
+
+    dump += "\n\tSCHEMAS : ";
+    dump += "\n\t\tTYPES : ";
+    for (String type : types.get(Schema.class)) {
+      dump += type+"; ";
+    }
+    dump += "\n\t\tNOMSPROP : ";
+    for (String type : nomsProps.get(Schema.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : nomsProps.get(Schema.class).get(type)) {
+        dump += prop+"; ";
+      }
+    }
+    dump += "\n\t\tVALEURSPROP : ";
+    for (String type : valeursProps.get(Schema.class).keySet()) {
+      dump += "\n\t\t\t"+type+" : ";
+      for (String prop : valeursProps.get(Schema.class).get(type).keySet()) {
+        dump += "\n\t\t\t\t"+prop+" : ";
+        for (String val : valeursProps.get(Schema.class).get(type).get(prop)) {
+          dump += val+"; ";
+        }
+      }
+    }
+
+
+    return dump;
+  }
+
+  public HashSet<String> getNomsProps(Class<? extends Element> classe, String type) {
+    if (nomsProps.get(classe).containsKey(type)) {
+      return nomsProps.get(classe).get(type);
+    }
+    return new HashSet<String>();
+  }
+
+  public HashSet<String> getValeursProp(Class<? extends Element> classe, String type, String prop) {
+    if (valeursProps.get(classe).containsKey(type)&&valeursProps.get(classe).get(type).containsKey(prop)) {
+      return (valeursProps.get(classe).get(type).get(prop));
+    }
+    return new HashSet<String>();
+  }
+
+  public String getValeurParDefaut(Class<? extends Element> classe, String type, String prop) {
+    if (valeursParDefaut.get(classe).containsKey(type)&&valeursParDefaut.get(classe).get(type).containsKey(prop)) {
+      return (valeursParDefaut.get(classe).get(type).get(prop));
+    }
+    return "";
+  }
+
+  public HashSet<String> getTypes(Class<? extends Element> classe) {
+    return (types.get(classe));
+  }
+
+  public boolean isVide() {
+    for (Class classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      if (!types.get(classe).isEmpty()) return false;
+    }
+    return true;
+  }
+
+  void clear() {
+    for (Class classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      types.get(classe).clear();
+      nomsProps.get(classe).clear();
+      valeursProps.get(classe).clear();
+      valeursParDefaut.get(classe).clear();
+    }
+  }
+
+  public void ajouterVal(Class<? extends Element> classe, String type, String prop, String val) {
+    valeursProps.get(classe).get(type).get(prop).add(val);
+  }
+
+  void renommerVal(Class<? extends Element> classe, String type, String prop, String oldNom, String newNom) {
+    valeursProps.get(classe).get(type).get(prop).add(newNom);
+    valeursProps.get(classe).get(type).get(prop).remove(oldNom);
+    if (oldNom.equals(valeursParDefaut.get(classe).get(type).get(prop))) {
+      valeursParDefaut.get(classe).get(type).put(prop, newNom);
+    }
+  }
+
+  void supprimerVal(Class<? extends Element> classe, String type, String prop, String oldNom) {
+    valeursProps.get(classe).get(type).get(prop).remove(oldNom);
+    if (oldNom.equals(valeursParDefaut.get(classe).get(type).get(prop))) {
+      valeursParDefaut.get(classe).get(type).put(prop, "");
+    }
+  }
+
+  public void modifierValParDefaut(Class<? extends Element> classe, String type, String prop, String val) {
+    valeursParDefaut.get(classe).get(type).put(prop, val);
+  }
+
+  public void ajouterProp(Class<? extends Element> classe, String type, String prop) {
+    nomsProps.get(classe).get(type).add(prop);
+    valeursProps.get(classe).get(type).put(prop, new HashSet<String>());
+    valeursParDefaut.get(classe).get(type).put(prop, "");
+  }
+
+  void renommerProp(Class<? extends Element> classe, String type, String oldNom, String newNom) {
+    nomsProps.get(classe).get(type).add(newNom);
+    nomsProps.get(classe).get(type).remove(oldNom);
+    valeursProps.get(classe).get(type).put(newNom, valeursProps.get(classe).get(type).get(oldNom));
+    valeursProps.get(classe).get(type).remove(oldNom);
+    valeursParDefaut.get(classe).get(type).put(newNom, valeursParDefaut.get(classe).get(type).get(oldNom));
+    valeursParDefaut.get(classe).get(type).remove(oldNom);
+  }
+
+  void fusionnerProp(Class<? extends Element> classe, String type, String oldNom, String newNom) {
+    nomsProps.get(classe).get(type).remove(oldNom);
+    valeursProps.get(classe).get(type).get(newNom).addAll(valeursProps.get(classe).get(type).get(oldNom));
+    valeursProps.get(classe).get(type).remove(oldNom);
+    if (!valeursParDefaut.get(classe).get(type).get(oldNom).isEmpty()) {
+      valeursParDefaut.get(classe).get(type).put(newNom, valeursParDefaut.get(classe).get(type).get(oldNom));
+    }
+    valeursParDefaut.get(classe).get(type).remove(oldNom);
+  }
+
+  void supprimerProp(Class<? extends Element> classe, String type, String prop) {
+    nomsProps.get(classe).get(type).remove(prop);
+    valeursProps.get(classe).get(type).remove(prop);
+    valeursParDefaut.get(classe).get(type).remove(prop);
+  }
+
+  @SuppressWarnings("unchecked")
+  public void ajouterType(Class<? extends Element> classe, String type) {
+    types.get(classe).add(type);
+    nomsProps.get(classe).put(type, new HashSet<String>());
+    valeursProps.get(classe).put(type, new HashMap<String, HashSet<String>>());
+    valeursParDefaut.get(classe).put(type, new HashMap<String, String>());
+  }
+  // }
+
+  void renommerType(Class<? extends Element> classe, String oldType, String newType) {
+    types.get(classe).add(newType);
+    types.get(classe).remove(oldType);
+    nomsProps.get(classe).put(newType, nomsProps.get(classe).get(oldType));
+    nomsProps.get(classe).remove(oldType);
+    valeursProps.get(classe).put(newType, valeursProps.get(classe).get(oldType));
+    valeursProps.get(classe).remove(oldType);
+    valeursParDefaut.get(classe).put(newType, valeursParDefaut.get(classe).get(oldType));
+    valeursParDefaut.get(classe).remove(oldType);
+  }
+
+  void fusionnerType(Class<? extends Element> classe, String oldType, String newType) {
+    types.get(classe).remove(oldType);
+    for (String prop : nomsProps.get(classe).get(oldType)) {
+      if (!nomsProps.get(classe).get(newType).contains(prop))
+        ajouterProp(classe, newType, prop);
+      for (String val : valeursProps.get(classe).get(oldType).get(prop))
+        if (!valeursProps.get(classe).get(newType).get(prop).contains(val))
+          ajouterVal(classe, newType, prop, val);
+      String valdef1 = getValeurParDefaut(classe, oldType, prop);
+      String valdef = getValeurParDefaut(classe, newType, prop);
+      if (!valdef1.isEmpty()&&!valdef1.equals(valdef)) {
+        modifierValParDefaut(classe, newType, prop, valdef1);
+      }
+    }
+    nomsProps.get(classe).remove(oldType);
+    valeursProps.get(classe).remove(oldType);
+    valeursParDefaut.get(classe).remove(oldType);
+
+  }
+
+  void supprimerType(Class<? extends Element> classe, String type) {
+    types.get(classe).remove(type);
+    nomsProps.get(classe).remove(type);
+    valeursProps.get(classe).remove(type);
+    valeursParDefaut.get(classe).remove(type);
+  }
+
+  void majNewElement(Element element) { // appelé par corpus.addUniteLue, addRelationLue, addSchemaLu
+    String type = element.getType();
+    Class<? extends Element> classe = element.getClass();
+    if (!types.get(classe).contains(type)) {
+      ajouterType(classe, type);
+    }
+    HashMap<String, String> props = element.getProps();
+    for (String prop : props.keySet()) {
+      if (!nomsProps.get(classe).get(type).contains(prop)) {
+        ajouterProp(classe, type, prop);
+      }
+      String val = props.get(prop);
+      if (val!=null&&!val.isEmpty()&&!valeursProps.get(classe).get(type).get(prop).contains(val)) {
+        ajouterVal(classe, type, prop, val);
+      }
+    }
+  }
+
+ @SuppressWarnings("unchecked")
+   public static Structure lireJava(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+    Structure structure = new Structure();
+    structure.types = (HashMap<Class<? extends Element>, HashSet<String>>) ois.readObject();
+    structure.nomsProps = (HashMap<Class<? extends Element>, HashMap<String, HashSet<String>>>) ois.readObject();
+    structure.valeursProps = (HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashSet<String>>>>) ois.readObject();
+    structure.valeursParDefaut = (HashMap<Class<? extends Element>, HashMap<String, HashMap<String, String>>>) ois.readObject();
+    return structure;
+  }
+
+  public void ecrireJava(ObjectOutputStream oos) throws IOException {
+    oos.writeObject(types);
+    oos.writeObject(nomsProps);
+    oos.writeObject(valeursProps);
+    oos.writeObject(valeursParDefaut);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/donnees/Structure.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Relation.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Relation.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Relation.java	(revision 481)
@@ -0,0 +1,64 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.elements;
+
+import java.util.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class Relation extends Element {
+  private Element elt1, elt2;
+  public Relation() {
+    super();
+  }
+  public Relation(String type, Element elt1, Element elt2) {
+    super(type);
+    setElt1(elt1);
+    setElt2(elt2);
+  }
+  public Element getElt1() {
+    return elt1;
+  }
+  public void setElt1(Element elt) {
+    elt1 = elt;
+  }
+  public Element getElt2() {
+    return elt2;
+  }
+  public void setElt2(Element elt) {
+    elt2 = elt;
+  }
+  @Override
+  public Element getElementSuivant(Jalon jalon) {
+    switch (jalon.origine) {
+      case ELT_2:
+        if (elt2.getClass()==jalon.classe&&elt2.getType().equals(jalon.type))
+          return elt2;
+        return null;
+      case ELT_1:
+        if (elt1.getClass()==jalon.classe&&elt1.getType().equals(jalon.type))
+          return elt1;
+        return null;
+      default:
+        return super.getElementSuivant(jalon);
+    }
+  }
+  protected HashSet<Unite> getUnitesSousjacentesNonTriees() {
+    HashSet<Unite> units = elt1.getUnitesSousjacentesNonTriees();
+    units.addAll(elt2.getUnitesSousjacentesNonTriees());
+    return units;
+  }
+//  boolean contientSchemaSousJacent(Schema sch) {
+//    return elt1.contientSchemaSousJacent(sch)||elt2.contientSchemaSousJacent(sch);
+//  }
+  public boolean coincide(Element elt) {
+    if (elt.getClass()!=Relation.class) return false;
+    Relation rel = (Relation) elt;
+    return getType().equals(rel.getType())&&elt1.coincide(rel.elt1)&&elt2.coincide(rel.elt2);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Relation.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Schema.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Schema.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Schema.java	(revision 481)
@@ -0,0 +1,83 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.elements;
+
+import java.util.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class Schema extends Element {
+  private HashSet<Element> contenu = new HashSet<Element>();
+  public Schema() {
+    super();
+  }
+  public Schema(String type) {
+    super(type);
+  }
+  public boolean ajouter(Element elt) {
+    // retourne false ssi pb de recursivité
+    if (elt==null) return true;
+    // à remplacer lors d'un chgt de version modifiant la signature de la classe
+// Element par :if (elt.contientSchemaSousJacent(this)) return false;
+    if (contientSchemaSousJacent(elt, this)) return false;
+    contenu.add(elt);
+    return true;
+  }
+  public boolean oter(Element elt) {
+    return contenu.remove(elt);
+  }
+  public HashSet<Element> getContenu() {
+    return contenu;
+  }
+  public boolean contient(Element elt) {
+    return contenu.contains(elt);
+  }
+  protected HashSet<Unite> getUnitesSousjacentesNonTriees() {
+    HashSet<Unite> units = new HashSet<Unite>();
+    for (Element elt : contenu) {
+      units.addAll(elt.getUnitesSousjacentesNonTriees());
+    }
+    return units;
+  }
+//  boolean contientSchemaSousJacent(Schema sch) {
+//    if (coincide(sch)) return true;
+//    for (Element elt : contenu) if (elt.contientSchemaSousJacent(sch))
+//        return true;
+//    return false;
+//  }
+  private static boolean contientSchemaSousJacent(Element elt, Schema sch) {
+    // Solution provisoire en attendant le chgt de version modifiant la signature
+    // de la classe Element
+    if (elt.getClass()==Unite.class) return false;
+    if (elt.getClass()==Relation.class) {
+      Relation rel = (Relation) elt;
+      return contientSchemaSousJacent(rel.getElt1(), sch)
+              ||contientSchemaSousJacent(rel.getElt2(), sch);
+    }
+    if (elt.getClass()==Schema.class) {
+      Schema sch1 = (Schema) elt;
+      if (sch1.coincide(sch)) return true;
+      for (Element elt1 : sch1.contenu) if (contientSchemaSousJacent(elt1, sch))
+          return true;
+      return false;
+    }
+    throw new IllegalArgumentException("Element de classe non identifiée");
+  }
+  public boolean coincide(Element elt) {
+    if (elt.getClass()!=Schema.class) return false;
+    Schema sch = (Schema) elt;
+    if (!getType().equals(sch.getType())) return false;
+    if (contenu.size()!=sch.getContenu().size()) return false;
+    Element[] contenu1 = contenu.toArray(new Element[0]);
+    Arrays.sort(contenu1);
+    Element[] contenu2 = sch.getContenu().toArray(new Element[0]);
+    Arrays.sort(contenu2);
+    for (int i = 0; i<contenu1.length; i++)
+      if (!contenu1[i].coincide(contenu2[i])) return false;
+    return true;
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Schema.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Unite.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Unite.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Unite.java	(revision 481)
@@ -0,0 +1,70 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.elements;
+
+import java.util.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class Unite extends Element implements Comparable {
+  private int deb;
+  private int fin;
+  public Unite() {
+    super();
+  }
+  public Unite(String type, int deb, int fin) {
+    super(type);
+    this.deb = deb;
+    this.fin = fin;
+  }
+  public int getDeb() {
+    return deb;
+  }
+  public void setDeb(int deb) {
+    this.deb = deb;
+  }
+  public int getFin() {
+    return fin;
+  }
+  public void setFin(int fin) {
+    this.fin = fin;
+  }
+//  boolean contientSchemaSousJacent(Schema sch) {
+//    return false;
+//  }
+  public boolean coincide(Element elt) {
+    if (elt.getClass()!=Unite.class) return false;
+    Unite unit = (Unite) elt;
+    return getType().equals(unit.getType())&&deb==unit.deb&&fin==unit.fin;
+  }
+  public int compareTo(Unite unit2) {
+    int comp = Integer.signum(deb-unit2.deb);
+    if (comp==0) {
+      comp = -Integer.signum(fin-unit2.fin);
+      if (comp==0) {
+        comp = getType().compareTo(unit2.getType());
+        if (comp==0) {
+          comp = Integer.signum(hashCode()-unit2.hashCode());
+        }
+      }
+    }
+    return comp;
+  }
+  protected HashSet<Unite> getUnitesSousjacentesNonTriees() {
+    HashSet<Unite> units = new HashSet<Unite>();
+    units.add(this);
+    return units;
+  }
+  @Override
+  public Unite getUnite0() {
+    return this;
+  }
+  @Override
+  public Unite[] getUnitesSousjacentes() {
+    return new Unite[]{this};
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Unite.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Element.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Element.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Element.java	(revision 481)
@@ -0,0 +1,193 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.elements;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.ArrayList;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public abstract class Element implements Serializable, Comparable {
+  private String type;
+  private HashMap<String, String> props = new HashMap<String, String>();
+  private HashMap<String, ArrayList<Relation>> relationsEntrantes = new HashMap<String, ArrayList<Relation>>();
+  private HashMap<String, ArrayList<Relation>> relationsSortantes = new HashMap<String, ArrayList<Relation>>();
+  private HashMap<String, ArrayList<Schema>> schemasContenants = new HashMap<String, ArrayList<Schema>>();
+  Element() {
+  }
+  Element(String type) {
+    this.type = type;
+  }
+  @Override
+  public String toString() {
+    String dump = "ELEMENT "+type;
+    dump += "\n\tPROPS : ";
+    for (String prop : props.keySet()) {
+      dump += "\n\t\t"+prop+" : "+props.get(prop);
+    }
+    dump += "\n\tRELATIONS ENTRANTES : ";
+    for (String typ : relationsEntrantes.keySet()) {
+      dump += "\n\t\t"+typ+" : ";
+      for (Relation rel : relationsEntrantes.get(typ)) {
+        dump += rel.getElt1().getType();
+      }
+    }
+    dump += "\n\tRELATIONS SORTANTES : ";
+    for (String typ : relationsSortantes.keySet()) {
+      dump += "\n\t\t"+typ+" : ";
+      for (Relation rel : relationsSortantes.get(typ)) {
+        dump += rel.getElt2().getType();
+      }
+    }
+    return dump;
+  }
+  public String getType() {
+    return type;
+  }
+  public void setType(String type) {
+    this.type = type;
+  }
+  public HashMap<String, String> getProps() {
+    return props;
+  }
+  public String getProp(String prop) {
+    if (props.get(prop)==null) {
+      return "";
+    }
+    return props.get(prop);
+  }
+  public void putProp(String prop, String valeur) {
+    props.put(prop, valeur);
+  }
+  public void supProp(String prop) {
+    props.remove(prop);
+  }
+  public void addRelationEntrante(Relation rel) {
+    if (!relationsEntrantes.containsKey(rel.getType())) {
+      relationsEntrantes.put(rel.getType(), new ArrayList<Relation>());
+    }
+    relationsEntrantes.get(rel.getType()).add(rel);
+  }
+  public void oteRelationEntrante(Relation rel) {
+    relationsEntrantes.get(rel.getType()).remove(rel);
+  }
+  public void addRelationSortante(Relation rel) {
+    if (!relationsSortantes.containsKey(rel.getType())) {
+      relationsSortantes.put(rel.getType(), new ArrayList<Relation>());
+    }
+    relationsSortantes.get(rel.getType()).add(rel);
+  }
+  public void oteRelationSortante(Relation rel) {
+    relationsSortantes.get(rel.getType()).remove(rel);
+  }
+  public void addSchemaContenant(Schema sch) {
+    if (!schemasContenants.containsKey(sch.getType())) {
+      schemasContenants.put(sch.getType(), new ArrayList<Schema>());
+    }
+    schemasContenants.get(sch.getType()).add(sch);
+  }
+  public void oteSchemaContenant(Schema sch) {
+    schemasContenants.get(sch.getType()).remove(sch);
+  }
+  public ArrayList<Relation> getRelations() {
+    ArrayList<Relation> rels = new ArrayList<Relation>();
+    for (String typerel : relationsEntrantes.keySet()) {
+      rels.addAll(relationsEntrantes.get(typerel));
+    }
+    for (String typerel : relationsSortantes.keySet()) {
+      rels.addAll(relationsSortantes.get(typerel));
+    }
+    return rels;
+  }
+  public ArrayList<Schema> getSchemas() {
+    ArrayList<Schema> schs = new ArrayList<Schema>();
+    for (String typesch : schemasContenants.keySet()) {
+      schs.addAll(schemasContenants.get(typesch));
+    }
+    return schs;
+  }
+  public Element getElementSuivant(Jalon jalon) {
+    switch (jalon.origine) {
+      case ELT_0:
+        return this;
+      case REL_SORTANTE:
+        if (!relationsSortantes.containsKey(jalon.type)||relationsSortantes.get(jalon.type).isEmpty()) {
+          return null;
+        }
+        return relationsSortantes.get(jalon.type).get(0);
+      case REL_ENTRANTE:
+        if (!relationsEntrantes.containsKey(jalon.type)||relationsEntrantes.get(jalon.type).isEmpty()) {
+          return null;
+        }
+        return relationsEntrantes.get(jalon.type).get(0);
+      case SCH_CONTENANT:
+        if (!schemasContenants.containsKey(jalon.type)||schemasContenants.get(jalon.type).isEmpty()) {
+          return null;
+        }
+        return schemasContenants.get(jalon.type).get(0);
+      default:  // les cas ELT_1 et ELT_2 sont traités par la classe Relation
+        throw new UnsupportedOperationException("Pas encore implémenté");
+    }
+  }
+  protected abstract HashSet<Unite> getUnitesSousjacentesNonTriees();
+  public Unite[] getUnitesSousjacentes() { // triées
+    Unite[] units = getUnitesSousjacentesNonTriees().toArray(new Unite[0]);
+    Arrays.sort(units);
+    return units;
+  }
+  public Unite getUnite0() {
+    Unite[] units = getUnitesSousjacentes();
+    if (units.length==0) return null;
+    return units[0];
+  }
+  public static Unite[] getUnites0(Element[] elts) {
+    Unite[] units = new Unite[elts.length];
+    for (int i = 0; i<elts.length; i++) units[i] = elts[i].getUnite0();
+    return units;
+  }
+  public static Unite[] getUnitesSousjacentes(Element[] elts) { // triées : est-ce nécessaire ??
+    ArrayList<Unite> lunits = new ArrayList<Unite>();
+    for (Element elt : elts)
+      lunits.addAll(elt.getUnitesSousjacentesNonTriees());
+    Unite[] units = lunits.toArray(new Unite[0]);
+    Arrays.sort(units);
+    return units;
+  }
+  public static Element trouverElementParUniteSousjacente(Element[] elements, Unite unite) { // prend le premier
+    for (Element elt : elements) {
+      int i = Arrays.binarySearch(elt.getUnitesSousjacentes(), unite);
+      if (i>=0) return elt;
+    }
+    return null;
+  }
+  public static ArrayList<Element> trouverElementsParUniteSousjacente(Element[] elements, Unite unite) {
+    ArrayList<Element> elts = new ArrayList<Element>();
+    for (Element elt : elements) {
+      int i = Arrays.binarySearch(elt.getUnitesSousjacentes(), unite);
+      if (i>=0) elts.add(elt);
+    }
+    return elts;
+  }
+  public int compareTo(Object obj) {
+    if (obj.getClass().getSuperclass()!=Element.class) {
+      throw new ClassCastException("Comparaison impossible : "+obj.toString()+" n'est pas une instance d'Elément");
+    }
+    Unite[] unites1 = getUnitesSousjacentes();
+    Unite[] unites2 = ((Element) obj).getUnitesSousjacentes();
+    int comp;
+    for (int i = 0; i<unites1.length; i++) {
+      if (i==unites2.length) return 1;
+      if ((comp = unites1[i].compareTo(unites2[i]))!=0) return comp;
+    }
+    if (unites1.length<unites2.length) return -1;
+    return Integer.signum(hashCode()-obj.hashCode());
+  }
+  abstract public boolean coincide(Element elt);
+//  abstract boolean contientSchemaSousJacent(Schema sch);
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/elements/Element.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTableur.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTableur.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTableur.java	(revision 481)
@@ -0,0 +1,165 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.TableModel;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.PanneauOccurrences;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class FichiersTableur {
+  public static void importerExcel(Corpus corpus) {
+    BufferedReader enonces = null;
+    BufferedReader annot = null;
+    File fichierCorpus;
+    File fichierAnnot;
+    if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix du fichier des énoncés", Fichiers.TypeFichier.TABLEUR_ENONCES))==null)
+      return;
+    if ((fichierAnnot = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix du fichier des annotations", Fichiers.TypeFichier.TABLEUR_ANNOT))==null)
+      return;
+    try {
+      enonces = new BufferedReader(new InputStreamReader(new FileInputStream(fichierCorpus), "ISO-8859-1"));
+      annot = new BufferedReader(new InputStreamReader(new FileInputStream(fichierAnnot), "ISO-8859-1"));
+      ExcelParser ep = new ExcelParser(corpus);
+      corpus.setTexte(ep.parserEnonces(enonces, 2));
+      ep.parserAnnot(annot, 2, "<*", "*>");
+      corpus.newCorpusLu();
+    } catch (IOException ex) {
+      corpus.fermer();
+      GMessages.impossibiliteAction("Erreur de lecture de fichier : \n"
+              +ex.getLocalizedMessage());
+      return;
+    } finally {
+      try {
+        if (enonces!=null) enonces.close();
+        if (annot!=null) annot.close();
+      } catch (IOException ex) {
+        GMessages.impossibiliteAction("Erreur de fermeture du fichier lu : \n"
+                +ex.getLocalizedMessage());
+      }
+    }
+  }
+  public static void exporterTable(TableModel donnees) {
+    PrintWriter ecrittableur = null;
+    File fichierStats;
+    GCodage codage = new GCodage();
+    if ((fichierStats = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier ?", Fichiers.TypeFichier.TABLEUR_STATS,
+            codage.getContenant()))==null) return;
+    String code = codage.getCode();
+    try {
+      ecrittableur = new PrintWriter(fichierStats, code);
+      ecrireTable(ecrittableur, donnees);
+    } catch (FileNotFoundException ex) {
+      GMessages.impossibiliteAction("Erreur d'écriture de fichier : \n"
+              +"Codage de caractères non pris en charge : "+code);
+    } catch (UnsupportedEncodingException ex) {
+    } finally {
+      if (ecrittableur!=null) ecrittableur.close();
+    }
+  }
+  private static void ecrireTable(PrintWriter ecrittableur, TableModel donnees) {
+    int nbcol = donnees.getColumnCount();
+    for (int j = 0; j<nbcol; j++) {
+      ecrittableur.print(donnees.getColumnName(j));
+      ecrittableur.print(j==nbcol-1 ? '\n' : '\t');
+    }
+    int nblig = donnees.getRowCount();
+    for (int i = 0; i<nblig; i++) for (int j = 0; j<nbcol; j++) {
+        ecrittableur.print(donnees.getValueAt(i, j));
+        ecrittableur.print(j==nbcol-1 ? '\n' : '\t');
+      }
+
+  }
+
+  static class ExcelParser {
+    Corpus corpus;
+    HashMap<String, Unite> enonces;
+    ExcelParser(Corpus corpus) {
+      this.corpus = corpus;
+      this.enonces = new HashMap<String, Unite>();
+    }
+    private String parserEnonces(BufferedReader lEnonces, int nbPropEnonces) throws IOException {
+      String texte = "";
+      String lEnonce;
+      int nbcar = 0;
+      while ((lEnonce = lEnonces.readLine())!=null) {
+        if (lEnonce.trim().isEmpty()) continue;
+        String[] chs = lEnonce.split("\t");
+        if (chs.length!=2+nbPropEnonces) {
+          throw new IOException("Format incorrect de fichier d'énoncés ligne : \n"+lEnonce);
+        }
+        String idEnonce = chs[0].trim();
+        if (enonces.containsKey(idEnonce)) {
+          throw new IOException("Identifant d'énoncés non unique  : "+idEnonce);
+        }
+        String texteEnonce = chs[1].trim();
+        Unite enonce = new Unite("Enoncé", nbcar, nbcar += texteEnonce.length());
+        for (int i = 0; i<nbPropEnonces; i++) {
+          enonce.putProp("Propriété "+i, chs[i+2].trim());
+        }
+        enonces.put(idEnonce, enonce);
+        enonce.putProp("id", idEnonce);
+        corpus.addUniteLue(enonce);
+        corpus.addFinParagraphe(nbcar);
+        texte += texteEnonce;
+      }
+      return texte;
+    }
+    private void parserAnnot(BufferedReader lAnnots, int nbPropAnnots, String bGauche, String bDroite)
+            throws IOException {
+      String lAnnot;
+      while ((lAnnot = lAnnots.readLine())!=null) {
+        if (lAnnot.trim().isEmpty()) continue;
+        String[] chs = lAnnot.split("\t", -1);
+        if (chs.length!=2+nbPropAnnots) {
+          throw new IOException("Format incorrect de fichier d'énoncés ligne : \n"+lAnnot);
+        }
+        String idEnonce = chs[0].trim();
+        String texteEnonceAnnot = chs[1].trim();
+        if (!enonces.containsKey(idEnonce)) {
+          throw new IOException("Identifiant d'énoncés non trouvé : \n"+idEnonce);
+        }
+        int deb = texteEnonceAnnot.indexOf(bGauche);
+        if (texteEnonceAnnot.substring(deb+bGauche.length()).indexOf(bGauche)>=0) {
+          throw new IOException("Plusieurs bornes gauches dans : \n"+texteEnonceAnnot);
+        }
+        String texteEnonce = texteEnonceAnnot.replace(bGauche, "");
+        int fin = texteEnonce.indexOf(bDroite);
+        if (texteEnonce.substring(fin+bDroite.length()).indexOf(bDroite)>=0) {
+          throw new IOException("Plusieurs bornes droites dans : \n"+texteEnonceAnnot);
+        }
+        if (fin<=deb) {
+          throw new IOException("Borne droite précédant la borne gauche dans : \n"+texteEnonceAnnot);
+        }
+        texteEnonce = texteEnonce.replace(bDroite, "");
+        Unite enonce = enonces.get(idEnonce);
+        if (!texteEnonce.equals(corpus.getTexte().substring(enonce.getDeb(), enonce.getFin()))) {
+          throw new IOException("Erreur d'énoncé identifié par "+idEnonce+" : \n"+texteEnonceAnnot
+                  +"Enoncé dans le corpus : "+corpus.getTexte().substring(enonce.getDeb(), enonce.getFin()));
+        }
+        Unite marqueur = new Unite("Marqueur", enonce.getDeb()+deb, enonce.getDeb()+fin);
+        for (int i = 0; i<nbPropAnnots; i++) {
+          marqueur.putProp("Propriété "+i, chs[i+2].trim());
+        }
+        corpus.addUniteLue(marqueur);
+        Relation rel = new Relation("Inclusion", marqueur, enonce);
+        corpus.addRelationLue(rel);
+
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTableur.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersJava.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersJava.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersJava.java	(revision 481)
@@ -0,0 +1,386 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.io.*;
+import javax.swing.*;
+import visuAnalec.donnees.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public abstract class FichiersJava {
+	public static void ouvrirCorpusVue(Corpus corpus, Vue vue, String nomfichier) {
+		File fichierCorpus;
+		if (nomfichier.isEmpty()) {
+			if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR,
+					"Choix du document", Fichiers.TypeFichier.DOC_ANALEC))==null) return;
+		} else {
+			if ((fichierCorpus = Fichiers.trouverFichier(Fichiers.TypeFichier.DOC_ANALEC, nomfichier))==null) {
+				JOptionPane.showMessageDialog(null, "Fichier "+nomfichier+" inexistant dans le répertoire "
+						+Fichiers.getRepertoireCourant(Fichiers.TypeFichier.DOC_ANALEC).getPath(), "Erreur de lecture de fichier",
+						JOptionPane.ERROR_MESSAGE);
+				return;
+			}
+		}
+		if(!ouvrirCorpus(corpus, fichierCorpus, false)) return;
+		File fichierVue = Fichiers.trouverFichier(Fichiers.TypeFichier.VUE, fichierCorpus);
+		if (fichierVue==null) return;
+		ouvrirVue(vue, fichierVue);
+	}
+
+	public static boolean ouvrirCorpus(Corpus corpus, File fichierCorpus, boolean batch) {
+		ObjectInputStream ois = null;
+		try {
+			ois = new ObjectInputStream(new FileInputStream(fichierCorpus));
+			corpus.lireJava(ois, batch);
+		} catch (ClassNotFoundException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le document "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles : "+e,
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (InvalidClassException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le document "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles : "+e,
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (ClassCastException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le document "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles : "+e,
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (IOException e) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, e, "Erreur de lecture de fichier : "+e, JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			try {
+				if (ois!=null) ois.close();
+			} catch (IOException e) {
+				JOptionPane.showMessageDialog(null, e, "Erreur de fermeture de fichier lu : "+e, JOptionPane.ERROR_MESSAGE);
+				return false;
+			}
+			return true;
+		}
+	}
+	public static boolean ouvrirStructure(Corpus corpus) {
+		File fichierStructure;
+		if ((fichierStructure = Fichiers.choisirFichier(Commande.OUVRIR,
+				"Choix de la structure", Fichiers.TypeFichier.STRUCTURE))==null) return false;
+		ObjectInputStream ois = null;
+		try {
+			ois = new ObjectInputStream(new FileInputStream(fichierStructure));
+			Structure structureLue = corpus.lireStructureJava(ois);
+			corpus.fusionnerStructureLue(structureLue);
+			corpus.newCorpusLu();
+		} catch (ClassNotFoundException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire la structure "+fichierStructure.getName()
+					+" : versions d'Analec incompatibles : "+e,
+					"Erreur d'ouverture de fichier .ecs", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (InvalidClassException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire la structure "+fichierStructure.getName()
+					+" : versions d'Analec incompatibles : "+e,
+					"Erreur d'ouverture de fichier .ecs", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (ClassCastException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire la structure "+fichierStructure.getName()
+					+" : versions d'Analec incompatibles : "+e,
+					"Erreur d'ouverture de fichier .ecs", JOptionPane.ERROR_MESSAGE);
+		} catch (IOException e) {
+			JOptionPane.showMessageDialog(null, e, "Erreur de lecture de fichier : "+e, JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			try {
+				if (ois!=null) ois.close();
+			} catch (IOException e) {
+				JOptionPane.showMessageDialog(null, e, "Erreur de fermeture de fichier lu : "+e, JOptionPane.ERROR_MESSAGE);
+			}
+		}
+		return true;
+	}
+
+	public static boolean ouvrirVue(Vue vue, File fichierVue) {
+		ObjectInputStream ois = null;
+		try {
+			ois = new ObjectInputStream(new FileInputStream(fichierVue));
+			if (!vue.lireJava(ois)) {
+				JOptionPane.showMessageDialog(null, "Impossible d'utiliser la vue "+fichierVue.getName()
+						+" : vue incompatible avec le document courant", "Erreur de lecture de fichier .ecv", JOptionPane.ERROR_MESSAGE);
+				if (ois!=null) ois.close();
+				return false;
+			}
+		} catch (InvalidClassException ex) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire la vue "+fichierVue.getName()
+					+" : versions d'Analec incompatibles ", "Erreur d'ouverture de fichier .ecv", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (IOException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (ClassNotFoundException ex) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire la vue "+fichierVue.getName()
+					+" : versions d'Analec incompatibles ", "Erreur d'ouverture de fichier .ecv", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (ClassCastException ex) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire la vue "+fichierVue.getName()
+					+" : versions d'Analec incompatibles ", "Erreur d'ouverture de fichier .ecv", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			try {
+				if (ois!=null) ois.close();
+			} catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+			}
+		}
+		return true;
+	}
+
+	public static boolean ouvrirVue(Vue vue) {
+		File fichierVue;
+		if ((fichierVue = Fichiers.choisirFichier(Commande.OUVRIR,
+				"Choix de la vue", Fichiers.TypeFichier.VUE))==null) return false;
+		return ouvrirVue(vue, fichierVue);
+	}
+
+	public static void fusionnerAnnot(Corpus corpus) {
+		File fichierCorpus;
+		if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR,
+				"Choix du fichier à fusionner", Fichiers.TypeFichier.DOC_ANALEC))==null)
+			return;
+		ObjectInputStream ois = null;
+		try {
+			ois = new ObjectInputStream(new FileInputStream(fichierCorpus));
+			corpus.fusionnerAnnotJava(ois);
+		} catch (ClassNotFoundException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles ",
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return;
+		} catch (ClassCastException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles ",
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return;
+		} catch (InvalidClassException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles ",
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return;
+		} catch (IOException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+			return;
+		} finally {
+			try {
+				if (ois!=null) ois.close();
+			} catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+			}
+		}
+
+	}
+
+	public static void concatenerDocuments(Corpus corpus) {
+		File fichierCorpus;
+		if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR,
+				"Choix du fichier à concaténer", Fichiers.TypeFichier.DOC_ANALEC))==null)
+			return;
+		concatener(fichierCorpus, corpus);
+		corpus.newCorpusLu();
+	}
+
+	public static void concatenerCorpus(final Corpus corpus) {
+		File rep;
+		if ((rep = Fichiers.choisirRepertoire("Choix du répertoire à concaténer"))
+				==null) return;
+		final File[] fics = Fichiers.listerFichiers(rep, Fichiers.TypeFichier.DOC_ANALEC);
+		final GMessages.GProgression progression =
+				new GMessages.GProgression(fics.length, "Concaténation", "fichiers");
+		Thread traitement = new Thread() {
+			@Override
+			public void run() {
+				for (int i = 0; i<fics.length; i++) {
+					if (progression.isCanceled()) break;
+					progression.setNbTraites(i+1);
+					concatener(fics[i], corpus);
+				}
+				corpus.newCorpusLu();
+			}
+		};
+		traitement.start();
+	}
+
+	public static void extraireTypeCorpus(final String type, final Corpus corpus) {
+		File rep;
+		if ((rep = Fichiers.choisirRepertoire("Choix du répertoire à traiter"))==null) return;
+		final  File[] fics = Fichiers.listerFichiers(rep, Fichiers.TypeFichier.DOC_ANALEC);
+		final GMessages.GProgression progression =
+				new GMessages.GProgression(fics.length, "Extraction", "fichiers");
+		Thread traitement = new Thread() {
+			@Override
+			public void run() {
+				for (int i = 0; i<fics.length; i++) {
+					if (progression.isCanceled()) break;
+					progression.setNbTraites(i+1);
+					extraireType(fics[i], Fichiers.extraireNom(fics[i]), type, corpus);        
+				}
+				corpus.newCorpusLu();
+			}
+		};
+		traitement.start();
+	}
+
+	private static void extraireType(File fichierCorpus, String nomDocument,
+			String type, Corpus corpus) {
+		ObjectInputStream ois = null;
+		try {
+			ois = new ObjectInputStream(new FileInputStream(fichierCorpus));
+			corpus.extraireEtConcatenerCorpusJava(ois, nomDocument, type);
+		} catch (ClassNotFoundException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles ",
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return;
+		} catch (ClassCastException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles ",
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return;
+		} catch (InvalidClassException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles ",
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return;
+		} catch (IOException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+			return;
+		} finally {
+			try {
+				if (ois!=null) ois.close();
+			} catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+			}
+		}
+	}
+
+	private static void concatener(File fichierCorpus, Corpus corpus) {
+		ObjectInputStream ois = null;
+		try {
+			ois = new ObjectInputStream(new FileInputStream(fichierCorpus));
+			corpus.concatenerCorpusJava(ois);
+		} catch (ClassNotFoundException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles ",
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return;
+		} catch (ClassCastException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles ",
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return;
+		} catch (InvalidClassException e) {
+			JOptionPane.showMessageDialog(null, "Impossible de lire le corpus "+fichierCorpus.getName()
+					+" : versions d'Analec incompatibles ",
+					"Erreur d'ouverture de fichier .ec", JOptionPane.ERROR_MESSAGE);
+			return;
+		} catch (IOException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+			return;
+		} finally {
+			try {
+				if (ois!=null) ois.close();
+			} catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+			}
+		}
+	}
+
+	public static boolean enregistrerCorpus(Corpus corpus, File fichier) {
+		if (fichier!=null) return ecrireCorpus(corpus, fichier);
+		return false;
+	}
+
+	public static boolean enregistrerCorpusSous(Corpus corpus) {
+		File fichier;
+		if ((fichier = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Nom du fichier corpus", Fichiers.TypeFichier.DOC_ANALEC))==null) return false;
+		return ecrireCorpus(corpus, fichier);
+	}
+
+	public static boolean enregistrerStructure(Corpus corpus) {
+		File fichier;
+		if ((fichier = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Nom du fichier structure", Fichiers.TypeFichier.STRUCTURE))==null) return false;
+		
+		return enregistrerStructure(corpus, fichier);
+	}
+
+	public static boolean enregistrerStructure(Corpus corpus, File fichier) {
+		ObjectOutputStream oos = null;
+		try {
+			oos = new ObjectOutputStream(new FileOutputStream(fichier));
+			corpus.ecrireStructureJava(oos);
+		} catch (IOException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			try {
+				if (oos!=null) oos.close();
+			} catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier écrit", JOptionPane.ERROR_MESSAGE);
+			}
+		}
+		return true;
+	}
+
+	private static boolean ecrireCorpus(Corpus corpus, File fichier) {
+		ObjectOutputStream oos = null;
+		try {
+			oos = new ObjectOutputStream(new FileOutputStream(fichier));
+			corpus.ecrireJava(oos);
+			return true;
+		} catch (IOException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			if (oos!=null) try {
+				oos.close();
+			} catch (IOException ex1) {
+			}
+			return false;
+
+		}
+	}
+
+	public static boolean enregistrerVue(Vue vue) {
+		File fichier;
+		if ((fichier = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Nom du fichier vue", Fichiers.TypeFichier.VUE))==null) return false;
+		return enregistrerVue(vue, fichier);
+	}
+
+	public static boolean enregistrerVue(Vue vue, File fichier) {
+		ObjectOutputStream oos = null;
+		try {
+			oos = new ObjectOutputStream(new FileOutputStream(fichier));
+			vue.ecrireJava(oos);
+		} catch (IOException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			try {
+				if (oos!=null) oos.close();
+				return true;
+			} catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier écrit", JOptionPane.ERROR_MESSAGE);
+				return false;
+			}
+		}
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersJava.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTEI.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTEI.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTEI.java	(revision 481)
@@ -0,0 +1,952 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.awt.*;
+import java.io.*;
+import java.util.*;
+
+import javax.swing.*;
+import javax.xml.parsers.*;
+
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+import visuAnalec.util.GMessages.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public abstract class FichiersTEI {
+	public static void convertirCorpusTEI(final Corpus corpus) {
+		final File ficTEI;
+		final File repJava;
+		if ((ficTEI = Fichiers.choisirFichier(Commande.OUVRIR,
+				"Choix du fichier corpus TEI", TypeFichier.TEI))==null)
+			return;
+		if ((repJava = Fichiers.choisirRepertoire("Choix du répertoire Java"))==null)
+			return;
+		if (!repJava.exists()) {
+			if (!GMessages.confirmationAction("Le répertoire spécifié n'existe pas."
+					+" Voulez-vous le créer ?")) return;
+			if (!repJava.mkdir()) {
+				GMessages.impossibiliteAction("Echec de la création du répertoire");
+				return;
+			}
+		}
+		convertir(ficTEI, repJava, corpus);
+	}
+	private static void convertir(File ficTEI, File repJava, Corpus corpus) {
+		BufferedInputStream tei = null;
+		String nomTEI = Fichiers.extraireNom(ficTEI)+"-";
+		if (Fichiers.existeDebutFichier(repJava, TypeFichier.DOC_ANALEC, nomTEI))
+			if (!GMessages.confirmationAction("Attention! Certains fichiers du "
+					+"répertoire "+repJava.getName()
+					+" risquent d'être écrasés")) return;
+		try {
+			tei = new BufferedInputStream(
+					new ProgressMonitorInputStream(
+							null, "Conversion du corpus TEI "+nomTEI,
+							new FileInputStream(ficTEI)));
+			SAXParserFactory pf = (SAXParserFactory) SAXParserFactory.newInstance();
+			SAXParser sp = pf.newSAXParser();
+			sp.parse(tei, new TEIHandler(corpus, repJava, nomTEI));
+		} catch (IOException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+			return;
+		} catch (ParserConfigurationException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+			return;
+		} catch (SAXException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+			return;
+		} finally {
+			try {
+				if (tei!=null) tei.close();
+			} catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
+			}
+		}
+	}
+
+	static class TEIHandler extends DefaultHandler {
+		File repJava;
+		String nomTEI;
+		Corpus corpus;
+		int noDoc;
+		String texte;
+		ArrayList<Integer> finParagraphes = new ArrayList<Integer>();
+		Balise etatCourant;
+		String typeCourant;
+		HashMap<String, Integer> ancres = new HashMap<String, Integer>();
+		HashMap<Unite, String[]> posUnites = new HashMap<Unite, String[]>();
+		HashMap<String, Element> idElements = new HashMap<String, Element>();
+		HashMap<Relation, String[]> eltsRelations = new HashMap<Relation, String[]>();
+		HashMap<Schema, String[]> eltsSchemas = new HashMap<Schema, String[]>();
+		HashMap<Element, String> propsElements = new HashMap<Element, String>();
+		HashMap<String, HashMap<String, String>> valsprops =
+				new HashMap<String, HashMap<String, String>>();
+		String idPropsEltCourant;
+		String champCourant;
+		String valCourant;
+
+		enum Balise {
+			TEICORPUS, TEIHEADER, TEIHEADER_CORPUS, TEI, TEXT, BODY, P, ANCHOR,
+			BACK, SPANGRP, SPAN, JOINGRP, JOIN, JOINGRP_REL, JOIN_REL,
+			JOINGRP_SCH, JOIN_SCH, FVLIB, FS, F, STRING, DEBUT_DOC, FIN_DOC,
+			AUTRE
+		};
+		static Balise balise(String nomBalise) {
+			try {
+				return Balise.valueOf(nomBalise.replaceAll("\\W", "").toUpperCase());
+			} catch (IllegalArgumentException e) {
+				return Balise.AUTRE;
+			}
+		}
+		TEIHandler(Corpus corpus, File repJava, String nomTEI) {
+			super();
+			this.corpus = corpus;
+			this.repJava = repJava;
+			this.nomTEI = nomTEI;
+		}
+		@Override
+		public void startDocument() {
+			noDoc = 0;
+			etatCourant = Balise.DEBUT_DOC;
+		}
+		@Override
+		public void endDocument() throws SAXNotSupportedException {
+			if (etatCourant!=Balise.FIN_DOC)
+				throw new SAXNotSupportedException("Fin de fichier inattendue");
+		}
+		@Override
+		public void startElement(String uri, String local, String nomBalise,
+				Attributes attributs) throws SAXException {
+			switch (balise(nomBalise)) {
+			case TEICORPUS:
+				if (etatCourant==Balise.DEBUT_DOC) etatCourant = Balise.TEICORPUS;
+				else
+					throw new SAXNotSupportedException("Balise <teiCorpus> mal placée");
+				break;
+			case TEIHEADER:
+				if (etatCourant==Balise.TEICORPUS)
+					etatCourant = Balise.TEIHEADER_CORPUS;
+				else if (etatCourant==Balise.TEI) etatCourant = Balise.TEIHEADER;
+				else
+					throw new SAXNotSupportedException("Balise <teiHeader> mal placée");
+
+				break;
+			case TEI:
+				if (etatCourant==Balise.TEICORPUS) {
+					noDoc++;
+					initCorpus();
+					etatCourant = Balise.TEI;
+				} else
+					throw new SAXNotSupportedException("Balise <tei> mal placée");
+				break;
+			case TEXT:
+				if (etatCourant==Balise.TEI) {
+					etatCourant = Balise.TEXT;
+				} else
+					throw new SAXNotSupportedException("Balise <text> mal placée");
+				break;
+			case BODY:
+				if (etatCourant==Balise.TEXT) {
+					etatCourant = Balise.BODY;
+				} else
+					throw new SAXNotSupportedException("Balise <body> mal placée");
+				break;
+			case P:
+				if (etatCourant==Balise.BODY) {
+					etatCourant = Balise.P;
+				} else
+					throw new SAXNotSupportedException("Balise <p> mal placée");
+				break;
+			case ANCHOR:
+				if ("AnalecDelimiter".equals(attributs.getValue("type"))) {
+					if (etatCourant==Balise.BODY||etatCourant==Balise.P) {
+						ancres.put(attributs.getValue("xml:id"), texte.length());
+					} else
+						throw new SAXNotSupportedException("Balise <anchor> de type "
+								+"\"AnalecDelimiter\" mal placée");
+				}
+				break;
+			case BACK:
+				if (etatCourant==Balise.TEXT) {
+					etatCourant = Balise.BACK;
+				} else
+					throw new SAXNotSupportedException("Balise <back> mal placée");
+				break;
+			case SPANGRP:
+				if ("AnalecUnit".equals(attributs.getValue("type"))) {
+					if (etatCourant==Balise.BACK) {
+						typeCourant = decodeId(attributs.getValue("n"));
+						if (typeCourant.isEmpty())
+							throw new SAXNotSupportedException("Attribut \"n\" d'une balise "
+									+"<spanGrp> de type \"AnalecUnit\" manquant");
+						etatCourant = Balise.SPANGRP;
+					} else
+						throw new SAXNotSupportedException("Balise <spanGrp> "
+								+"de type \"AnalecUnit\" mal placée");
+				}
+				break;
+			case SPAN:
+				if (etatCourant==Balise.SPANGRP) {
+					Unite unit = new Unite();
+					unit.setType(typeCourant);
+					posUnites.put(unit, new String[]{
+							xmlId(attributs.getValue("from")),
+							xmlId(attributs.getValue("to"))});
+					idElements.put(attributs.getValue("xml:id"), unit);
+					propsElements.put(unit, xmlId(attributs.getValue("ana")));
+					etatCourant = Balise.SPAN;
+				}
+				break;
+			case JOINGRP:
+				if ("AnalecRelation".equals(attributs.getValue("type"))) {
+					if (etatCourant==Balise.BACK) {
+						typeCourant = decodeId(attributs.getValue("n"));
+						if (typeCourant.isEmpty())
+							throw new SAXNotSupportedException("Attribut \"n\" d'une balise "
+									+"<joinGrp> de type \"AnalecRelation\" manquant");
+						etatCourant = Balise.JOINGRP_REL;
+					} else
+						throw new SAXNotSupportedException("Balise <joinGrp> "
+								+"de type \"AnalecRelation\" mal placée");
+				} else if ("AnalecSchema".equals(attributs.getValue("type"))) {
+					if (etatCourant==Balise.BACK) {
+						typeCourant = decodeId(attributs.getValue("n"));
+						if (typeCourant.isEmpty())
+							throw new SAXNotSupportedException("Attribut \"n\" d'une balise "
+									+"<joinGrp> de type \"AnalecSchema\" manquant");
+						etatCourant = Balise.JOINGRP_SCH;
+					} else
+						throw new SAXNotSupportedException("Balise <joinGrp> "
+								+"de type \"AnalecSchema\" mal placée");
+				}
+
+				break;
+			case JOIN:
+				if (etatCourant==Balise.JOINGRP_REL) {
+					Relation rel = new Relation();
+					rel.setType(typeCourant);
+					eltsRelations.put(rel, splitIds(attributs.getValue("target")));
+					idElements.put(attributs.getValue("xml:id"), rel);
+					propsElements.put(rel, xmlId(attributs.getValue("ana")));
+					etatCourant = Balise.JOIN_REL;
+				} else if (etatCourant==Balise.JOINGRP_SCH) {
+					Schema sch = new Schema();
+					sch.setType(typeCourant);
+					eltsSchemas.put(sch, splitIds(attributs.getValue("target")));
+					idElements.put(attributs.getValue("xml:id"), sch);
+					propsElements.put(sch, xmlId(attributs.getValue("ana")));
+					etatCourant = Balise.JOIN_SCH;
+				}
+				break;
+			case FVLIB:
+				if ("AnalecElementProperties".equals(attributs.getValue("n"))) {
+					if (etatCourant==Balise.BACK) {
+						etatCourant = Balise.FVLIB;
+					} else
+						throw new SAXNotSupportedException("Balise <fvLib> "
+								+"de type \"AnalecElementProperties\" mal placée");
+				}
+				break;
+			case FS:
+				if (etatCourant==Balise.FVLIB) {
+					idPropsEltCourant = attributs.getValue("xml:id");
+					valsprops.put(idPropsEltCourant, new HashMap<String, String>());
+					etatCourant = Balise.FS;
+				}
+				break;
+			case F:
+				if (etatCourant==Balise.FS) {
+					champCourant = decodeId(attributs.getValue("name"));
+					if (champCourant.isEmpty())
+						throw new SAXNotSupportedException("Attribut \"name\" "
+								+ "d'une balise <f> dans le <fvLib> de type"
+								+ " \"AnalecElementProperties\" manquant");
+
+					etatCourant = Balise.F;
+				}
+				break;
+			case STRING:
+				if (etatCourant==Balise.F) {
+					valCourant = "";
+					etatCourant = Balise.STRING;
+				}
+				break;
+			}
+		}
+		private String xmlId(String id) {
+			if (id==null||id.isEmpty()||id.charAt(0)!='#') return null;
+			return id.substring(1);
+		}
+		private String[] splitIds(String ids) {
+			if(ids.isEmpty()) return new String[0];
+			String[] idsplit = ids.split("\\s+");
+			for (int i = 0; i<idsplit.length; i++) {
+				idsplit[i] = xmlId(idsplit[i]);
+			}
+			return idsplit;
+		}
+		@Override
+		public void endElement(String uri, String local, String nomBalise) throws SAXException {
+			String type = "";
+			switch (balise(nomBalise)) {
+			case TEICORPUS:
+				if (etatCourant==Balise.TEICORPUS) etatCourant = Balise.FIN_DOC;
+				else
+					throw new SAXNotSupportedException("Balise </teiCorpus> mal placée");
+				break;
+			case TEIHEADER:
+				if (etatCourant==Balise.TEIHEADER_CORPUS)
+					etatCourant = Balise.TEICORPUS;
+				else if (etatCourant==Balise.TEIHEADER) etatCourant = Balise.TEI;
+				else
+					throw new SAXNotSupportedException("Balise </teiHeader> mal placée");
+				break;
+			case TEI:
+				if (etatCourant==Balise.TEI) {
+					remplirCorpus();
+					if (!ecrireFichier()) throw new SAXException("Erreur d'écriture "
+							+"du fichier "+nomTEI+noDoc+".ec");
+					etatCourant = Balise.TEICORPUS;
+				} else
+					throw new SAXNotSupportedException("Balise </tei> mal placée");
+				break;
+			case TEXT:
+				if (etatCourant==Balise.TEXT) etatCourant = Balise.TEI;
+				else
+					throw new SAXNotSupportedException("Balise </text> mal placée");
+				break;
+			case BODY:
+				if (etatCourant==Balise.BODY) {
+					corpus.setTexte(texte);
+					corpus.setFinParagraphes(finParagraphes);
+					etatCourant = Balise.TEXT;
+				} else
+					throw new SAXNotSupportedException("Balise </body> mal placée");
+				break;
+			case P:
+				if (etatCourant==Balise.P) {
+					finParagraphes.add(texte.length());
+					etatCourant = Balise.BODY;
+				}
+				break;
+			case BACK:
+				if (etatCourant==Balise.BACK) etatCourant = Balise.TEXT;
+				else
+					throw new SAXNotSupportedException("Balise </back> mal placée");
+				break;
+			case SPANGRP:
+				if (etatCourant==Balise.SPANGRP) etatCourant = Balise.BACK;
+				break;
+			case SPAN:
+				if (etatCourant==Balise.SPAN) etatCourant = Balise.SPANGRP;
+				break;
+			case JOINGRP:
+				if (etatCourant==Balise.JOINGRP_REL||etatCourant==Balise.JOINGRP_SCH)
+					etatCourant = Balise.BACK;
+				break;
+			case JOIN:
+				if (etatCourant==Balise.JOIN_REL) etatCourant = Balise.JOINGRP_REL;
+				else if (etatCourant==Balise.JOIN_SCH)
+					etatCourant = Balise.JOINGRP_SCH;
+				break;
+			case FVLIB:
+				if (etatCourant==Balise.FVLIB) etatCourant = Balise.BACK;
+				break;
+			case FS:
+				if (etatCourant==Balise.FS) etatCourant = Balise.FVLIB;
+				break;
+			case F:
+				if (etatCourant==Balise.F) etatCourant = Balise.FS;
+				break;
+			case STRING:
+				if (etatCourant==Balise.STRING) {
+					valsprops.get(idPropsEltCourant).put(champCourant, valCourant);
+					etatCourant = Balise.F;
+				}
+				break;
+			}
+		}
+		@Override
+		public void characters(char[] ch, int start, int taille) throws SAXException {
+			if (etatCourant==Balise.P)
+				texte += decodeTexte(new String(ch, start, taille));
+			if (etatCourant==Balise.STRING)
+				valCourant += decodeTexte(new String(ch, start, taille));
+		}
+		private static String decodeTexte(String ch) {
+			return ch.replaceAll("&amp;", "&").replaceAll("&lt;", "<").
+					replaceAll("&gt;", ">").replaceAll("&quot;", "\"").
+					replaceAll("&apos;", "\'").replaceAll("[\\t\\n\\r\\f]", "");
+		}
+		private static String decodeId(String ch) {
+			if (ch==null||ch.isEmpty()) return "";
+			String id = ch.charAt(0)=='_' ? ch.substring(1) : ch;
+			return id.replaceAll("_", " ");
+		}
+		private void initCorpus() {
+			corpus.clearAll();
+			texte = "";
+			finParagraphes.clear();
+			ancres.clear();
+			posUnites.clear();
+			eltsRelations.clear();
+			eltsSchemas.clear();
+			idElements.clear();
+			propsElements.clear();
+			valsprops.clear();
+		}
+		private void remplirCorpus() throws SAXNotSupportedException {
+			for (Unite unit : posUnites.keySet()) {
+				String[] pos = posUnites.get(unit);
+				if (pos[0]==null||!ancres.containsKey(pos[0])
+						||pos[1]==null||!ancres.containsKey(pos[1]))
+					throw new SAXNotSupportedException("Pas trouvé d'ancrage pour "
+							+"une unité de type "+unit.getType());
+				unit.setDeb(ancres.get(pos[0]));
+				unit.setFin(ancres.get(pos[1]));
+				String idProps = propsElements.get(unit);
+				if (idProps==null||!valsprops.containsKey(idProps))
+					throw new SAXNotSupportedException("Pas trouvé de propriétés pour "
+							+"une unité de type "+unit.getType());
+				HashMap<String, String> props = valsprops.get(idProps);
+				for (String champ : props.keySet())
+					unit.putProp(champ, props.get(champ));
+				corpus.addUniteLue(unit);
+			}
+			for (Relation rel : eltsRelations.keySet()) {
+				String[] idElts = eltsRelations.get(rel);
+				if (idElts.length!=2) {
+					throw new SAXNotSupportedException("Une relation de type "
+							+rel.getType()+" n'a pas deux termes");
+				}
+				if (idElts[0]==null||!idElements.containsKey(idElts[0])
+						||idElts[1]==null||!idElements.containsKey(idElts[1])) {
+					throw new SAXNotSupportedException("Errreur d'identification de termes "
+							+" pour une relation de type "+rel.getType());
+				}
+				rel.setElt1(idElements.get(idElts[0]));
+				rel.setElt2(idElements.get(idElts[1]));
+				String idProps = propsElements.get(rel);
+				if (idProps==null||!valsprops.containsKey(idProps))
+					throw new SAXNotSupportedException("Pas trouvé de propriétés pour "
+							+"une relation de type "+rel.getType());
+				HashMap<String, String> props = valsprops.get(idProps);
+				for (String champ : props.keySet())
+					rel.putProp(champ, props.get(champ));
+				corpus.addRelationLue(rel);
+			}
+			for (Schema sch : eltsSchemas.keySet()) {
+				String[] idElts = eltsSchemas.get(sch);
+				for (String idElt : idElts) {
+					if (idElt==null||!idElements.containsKey(idElt)) {
+						throw new SAXNotSupportedException("Errreur d'identification de termes "
+								+" pour un schema de type "+sch.getType());
+					}
+					sch.ajouter(idElements.get(idElt));
+				}
+				String idProps = propsElements.get(sch);
+				if (idProps==null||!valsprops.containsKey(idProps))
+					throw new SAXNotSupportedException("Pas trouvé de propriétés pour "
+							+"un schéma de type "+sch.getType());
+				HashMap<String, String> props = valsprops.get(idProps);
+				for (String champ : props.keySet())
+					sch.putProp(champ, props.get(champ));
+				corpus.addSchemaLu(sch);
+			}
+		}
+		private boolean ecrireFichier() {
+			return FichiersJava.enregistrerCorpus(corpus, Fichiers.creerFichier(
+					repJava, TypeFichier.DOC_ANALEC, nomTEI+noDoc));
+		}
+	}
+	public final static String TYPE_INFOS_META_DOCUMENTS = "Titre";
+	public final static String CHAMP_NON_RENSEIGNE = "non renseigné";
+	public final static String DEFAUT_TITRE_CORPUS = "";
+	public final static String DEFAUT_ANNOTATEURS = "";
+	public final static String DEFAUT_EDITEUR = "";
+	public final static String DEFAUT_SOURCE_CORPUS = "";
+	public static boolean exporterCorpusTEI(final Corpus corpus) {
+		File repJava;
+		final File ficTEI;
+		final File[] fics = Fichiers.choisirCorpus("Choix du répertoire Java",
+				TypeFichier.CORPUS_ANALEC);
+		if (fics.length==0) return false;
+
+		final HashMap<String, String> infosCorpus = new HashMap<String, String>();
+		saisirInfosCorpus(infosCorpus);
+		if ((ficTEI = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Nom du fichier TEI", Fichiers.TypeFichier.TEI))==null) return false;
+		final PrintWriter teiWriter;
+		try {
+			teiWriter = new PrintWriter(ficTEI, "UTF-8");
+		} catch (FileNotFoundException ex) {
+			GMessages.impossibiliteAction("Pas de fichier TEI ? ");
+
+			return false;
+		} catch (UnsupportedEncodingException ex) {
+			GMessages.impossibiliteAction("Pas de codage UTF-8 ?");
+			return false;
+		}
+		final TEIPrinter teiPrinter = new TEIPrinter(corpus, teiWriter);
+		final GMessages.GProgression progression =
+				new GMessages.GProgression(fics.length, "Conversion", "fichiers");
+		Thread traitement = new Thread() {
+			@Override
+			public void run() {
+				try {
+					teiPrinter.ecrireEnteteCorpus(infosCorpus);
+					for (int i = 0; i<fics.length; i++) {
+						if (progression.isCanceled()) break;
+						progression.setNbTraites(i+1);
+						File ficJava = fics[i];
+						if (FichiersJava.ouvrirCorpus(corpus, ficJava, true))
+							teiPrinter.ecrireDocument(Fichiers.extraireNom(ficJava));
+					}
+					corpus.fermer();
+					teiPrinter.ecrireFinCorpus();
+					teiWriter.close();
+				} catch (Throwable ex) {
+					GMessages.erreurFatale(ex);
+
+				}
+			}
+		};
+		traitement.start();
+		try {
+			traitement.join();
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+			return false;
+		}
+		return true;
+	}
+
+	private static boolean saisirInfosCorpus(HashMap<String, String> infosCorpus) {
+		final boolean[] pvalide = new boolean[1];
+		SaisieInfos fenetre = new SaisieInfos(pvalide, infosCorpus);
+		return pvalide[0];
+	}
+
+	private static class SaisieInfos extends JDialog {
+		private SaisieInfos(final boolean[] pvalide,
+				final HashMap<String, String> infosCorpus) {
+			super((JFrame) null, "Informations sur le corpus", true);
+			JPanel cadre = new JPanel(new BorderLayout());
+			setContentPane(cadre);
+			Rectangle rmax = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
+			int largeur = Math.min(rmax.width-100, 600);
+			int hauteur = Math.min(rmax.height-100, 400);
+			Point locFenetre = new Point((rmax.x+rmax.width)/2-largeur/2,
+					(rmax.y+rmax.height)/2-hauteur/2);
+			Dimension dimFenetre = new Dimension(largeur, hauteur);
+			setLocation(locFenetre);
+			setSize(dimFenetre);
+			setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
+			int hauteurCars = cadre.getFontMetrics(cadre.getFont()).getHeight()+5;
+			final JTextField champTitre = new JTextField(40);
+			champTitre.setMaximumSize(new Dimension(500, hauteurCars));
+			champTitre.setText(DEFAUT_TITRE_CORPUS);
+			final JTextField champAnnot = new JTextField(40);
+			champAnnot.setMaximumSize(new Dimension(500, hauteurCars));
+			champAnnot.setText(DEFAUT_ANNOTATEURS);
+			final JTextField champEditeur = new JTextField(40);
+			champEditeur.setMaximumSize(new Dimension(500, hauteurCars));
+			champEditeur.setText(DEFAUT_EDITEUR);
+			final JTextField champSource = new JTextField(40);
+			champSource.setMaximumSize(new Dimension(500, hauteurCars));
+			champSource.setText(DEFAUT_SOURCE_CORPUS);
+			Box box = Box.createVerticalBox();
+			box.add(Box.createVerticalGlue());
+			Box boxTitre = Box.createHorizontalBox();
+			boxTitre.add(Box.createHorizontalGlue());
+			boxTitre.add(new JLabel("Titre du corpus"));
+			boxTitre.add(Box.createHorizontalStrut(5));
+			boxTitre.add(champTitre);
+			boxTitre.add(Box.createHorizontalGlue());
+			box.add(boxTitre);
+			box.add(Box.createVerticalGlue());
+			Box boxAnnot = Box.createHorizontalBox();
+			boxAnnot.add(Box.createHorizontalGlue());
+			boxAnnot.add(new JLabel("Annotateurs"));
+			boxAnnot.add(Box.createHorizontalStrut(5));
+			boxAnnot.add(champAnnot);
+			boxAnnot.add(Box.createHorizontalGlue());
+			box.add(boxAnnot);
+			box.add(Box.createVerticalGlue());
+			Box boxEditeur = Box.createHorizontalBox();
+			boxEditeur.add(Box.createHorizontalGlue());
+			boxEditeur.add(new JLabel("Editeur"));
+			boxEditeur.add(Box.createHorizontalStrut(5));
+			boxEditeur.add(champEditeur);
+			boxEditeur.add(Box.createHorizontalGlue());
+			box.add(boxEditeur);
+			box.add(Box.createVerticalGlue());
+			Box boxSource = Box.createHorizontalBox();
+			boxSource.add(Box.createHorizontalGlue());
+			boxSource.add(new JLabel("Description du corpus"));
+			boxSource.add(Box.createHorizontalStrut(5));
+			boxSource.add(champSource);
+			boxSource.add(Box.createHorizontalGlue());
+			box.add(boxSource);
+			box.add(Box.createVerticalGlue());
+			add(box);
+			JButton valideModifs = new JButton(
+					new GAction("Valider") {
+						@Override
+						public void executer() {
+							pvalide[0] = true;
+							infosCorpus.put("Titre", champTitre.getText());
+							infosCorpus.put("Annot", champAnnot.getText());
+							infosCorpus.put("Editeur", champEditeur.getText());
+							infosCorpus.put("Source", champSource.getText());
+							dispose();
+						}
+						;
+					});
+			JButton annuleModifs = new JButton(
+					new GAction("Annuler") {
+						@Override
+						public void executer() {
+							pvalide[0] = false;
+							dispose();
+						}
+						;
+					});
+			Box boutons = Box.createHorizontalBox();
+			boutons.add(Box.createGlue());
+			boutons.add(valideModifs, Box.CENTER_ALIGNMENT);
+			boutons.add(Box.createHorizontalStrut(5));
+			boutons.add(annuleModifs, Box.CENTER_ALIGNMENT);
+			boutons.add(Box.createGlue());
+			add(boutons, BorderLayout.SOUTH);
+			setVisible(
+					true);
+
+		}
+	}
+
+	static private class TEIPrinter {
+		static private class Delimiteur implements Comparable<Delimiteur> {
+			private String id;
+			private int taille; // signé : négatif pour les délimiteurs de fin
+			private Delimiteur(String id, int taille) {
+				this.id = id;
+				this.taille = taille;
+			}
+			public int compareTo(Delimiteur d) {
+				if (taille!=d.taille) {
+					if (taille<0&&d.taille<0||taille>0&&d.taille>0)
+						return d.taille-taille;
+					else return taille-d.taille;
+				} else return taille>0 ? -d.id.compareTo(id) : d.id.compareTo(id);
+			}
+		}
+		private Corpus corpus;
+		private PrintWriter writer;
+		private String titreCorpus, annot, editeur, sourceCorpus;
+		private HashMap<String, ArrayList<Unite>> unites =
+				new HashMap<String, ArrayList<Unite>>();
+		private HashMap<String, ArrayList<Relation>> relations =
+				new HashMap<String, ArrayList<Relation>>();
+		private HashMap<String, ArrayList<Schema>> schemas =
+				new HashMap<String, ArrayList<Schema>>();
+		private HashMap<Element, String> ids = new HashMap<Element, String>();
+		private HashMap<String, String> encodeName = new HashMap<String, String>();
+		private HashMap<Integer, ArrayList<Delimiteur>> delimiteurs =
+				new HashMap<Integer, ArrayList<Delimiteur>>();
+		TEIPrinter(Corpus corpus, PrintWriter writer) {
+			this.corpus = corpus;
+			this.writer = writer;
+		}
+		private void ecrireEnteteCorpus(HashMap<String, String> infosCorpus) {
+			titreCorpus = traiterSaisie(infosCorpus.get("Titre"));
+			annot = traiterSaisie(infosCorpus.get("Annot"));
+			editeur = traiterSaisie(infosCorpus.get("Editeur"));
+			sourceCorpus = traiterSaisie(infosCorpus.get("Source"));
+			writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
+			writer.println("<teiCorpus xmlns=\"http://www.tei-c.org/ns/1.0\">");
+			writer.println(" <teiHeader>");
+			writer.println("<fileDesc>");
+			writer.println("<titleStmt>");
+			writer.println("<title>"+titreCorpus+"</title>");
+			writer.println("<respStmt>");
+			writer.println("<resp>annotated by</resp>");
+			writer.println("<name>"+annot+"</name>");
+			writer.println("</respStmt>");
+			writer.println("</titleStmt>");
+			writer.println("<publicationStmt>");
+			writer.println("<publisher>"+editeur+"</publisher>");
+			writer.println("</publicationStmt>");
+			writer.println("<sourceDesc>");
+			writer.println("<bibl>"+sourceCorpus+"</bibl>");
+			writer.println("</sourceDesc>");
+			writer.println("</fileDesc>");
+			writer.println("</teiHeader>");
+		}
+		private void ecrireFinCorpus() {
+			writer.println("</teiCorpus>");
+		}
+		private void preparerDonnees() {
+			unites.clear();
+			relations.clear();
+			schemas.clear();
+			ids.clear();
+			encodeName.clear();
+			delimiteurs.clear();
+			String codeType = "";
+			for (String type : corpus.getStructure().getTypes(Unite.class)) {
+				Unite[] units = corpus.getUnites(type).toArray(new Unite[0]);
+				Arrays.sort(units);
+				if (units.length>0) {
+					unites.put(type, new ArrayList<Unite>());
+					codeType = encodeId(type);
+					encodeName.put(type, codeType);
+					for (String prop : corpus.getStructure().getNomsProps(Unite.class, type))
+						encodeName.put(prop, encodeId(prop));
+				}
+				for (int no = 0; no<units.length; no++) {
+					Unite unit = units[no];
+					String id = "u-"+codeType+"-"+(no+1);
+					ids.put(unit, id);
+					unites.get(type).add(unit);
+					int taille = unit.getFin()-unit.getDeb();
+					Delimiteur del = new Delimiteur(id, taille);
+					addDel(unit.getDeb(), del);
+					if (taille>0) {
+						del = new Delimiteur(id, -taille);
+						addDel(unit.getFin(), del);
+					}
+				}
+			}
+			for (String type : corpus.getStructure().getTypes(Relation.class)) {
+				Relation[] rels = corpus.getRelations(type).toArray(new Relation[0]);
+				Arrays.sort(rels);
+				if (rels.length>0) {
+					relations.put(type, new ArrayList<Relation>());
+					codeType = encodeId(type);
+					encodeName.put(type, codeType);
+					for (String prop : corpus.getStructure().getNomsProps(Relation.class, type))
+						encodeName.put(prop, encodeId(prop));
+
+				}
+				for (int no = 0; no<rels.length; no++) {
+					Relation rel = rels[no];
+					String id = "r-"+codeType+"-"+(no+1);
+					ids.put(rel, id);
+					relations.get(type).add(rel);
+				}
+			}
+			for (String type : corpus.getStructure().getTypes(Schema.class)) {
+				Schema[] schs = corpus.getSchemas(type).toArray(new Schema[0]);
+				Arrays.sort(schs);
+				if (schs.length>0) {
+					schemas.put(type, new ArrayList<Schema>());
+					codeType = encodeId(type);
+					encodeName.put(type, codeType);
+					for (String prop : corpus.getStructure().getNomsProps(Schema.class, type))
+						encodeName.put(prop, encodeId(prop));
+				}
+				for (int no = 0; no<schs.length; no++) {
+					Schema sch = schs[no];
+					String id = "s-"+codeType+"-"+(no+1);
+					ids.put(sch, id);
+					schemas.get(type).add(sch);
+				}
+			}
+			int deb = 0;
+			for (int fin : corpus.getFinParagraphes()) {
+				int taille = fin-deb;
+				Delimiteur del = new Delimiteur("p", taille);
+				addDel(deb, del);
+				if (taille>0) {
+					del = new Delimiteur("p", -taille);
+					addDel(fin, del);
+				}
+				deb = fin;
+			}
+		}
+		private void addDel(int pos, Delimiteur del) {
+			if (!delimiteurs.containsKey(pos))
+				delimiteurs.put(pos, new ArrayList<Delimiteur>());
+			delimiteurs.get(pos).add(del);
+		}
+		private void ecrireDocument(String nomfic) {
+			preparerDonnees();
+			writer.println("<TEI>");
+			ecrireEntete(nomfic);
+			writer.println("<text>");
+			ecrireTexte();
+			ecrireAnnot();
+			writer.println("</text>");
+			writer.println("</TEI>");
+		}
+		private void ecrireEntete(String nomfic) {
+			String titre = "";
+			String auteur = "";
+			String source = "";
+			if (!corpus.getUnites(TYPE_INFOS_META_DOCUMENTS).isEmpty()) {
+				Unite infos = corpus.getUnites(TYPE_INFOS_META_DOCUMENTS).get(0);
+				titre = encodeTexte(infos.getProp("titre"));
+				auteur = encodeTexte(infos.getProp("auteur"));
+				source = encodeTexte(infos.getProp("source"));
+			}
+			if (titre.isEmpty()) titre = nomfic;
+			if (auteur.isEmpty()) auteur = CHAMP_NON_RENSEIGNE;
+			if (source.isEmpty()) source = CHAMP_NON_RENSEIGNE;
+			writer.println("<teiHeader>");
+			writer.println("<fileDesc>");
+			writer.println("<titleStmt>");
+			writer.println("<title>"+titre+"</title>");
+			writer.println("<author>"+auteur+"</author>");
+			writer.println("<respStmt>");
+			writer.println("<resp>annotated by</resp>");
+			writer.println("<name>"+annot+"</name>");
+			writer.println("</respStmt>");
+			writer.println("</titleStmt>");
+			writer.println("<publicationStmt>");
+			writer.println("<publisher>"+editeur+"</publisher>");
+			writer.println("</publicationStmt>");
+			writer.println("<sourceDesc>");
+			writer.println("<bibl>"+source+"</bibl>");
+			writer.println("</sourceDesc>");
+			writer.println("</fileDesc>");
+			writer.println("</teiHeader>");
+		}
+		private void ecrireTexte() {
+			writer.println("<body>");
+			Integer[] pos = delimiteurs.keySet().toArray(new Integer[0]);
+			Arrays.sort(pos);
+			ecrireDel(delimiteurs.get(0));
+			int deb = 0;
+			for (int i = 1; i<pos.length; i++) {
+				int fin = pos[i];
+				writer.print(encodeTexte(corpus.getTexte().substring(deb, fin)));
+				ecrireDel(delimiteurs.get(fin));
+				deb = fin;
+			}
+			writer.println("</body>");
+		}
+		private void ecrireDel(ArrayList<Delimiteur> delims) {
+			Delimiteur[] dels = delims.toArray(new Delimiteur[0]);
+			Arrays.sort(dels);
+			for (Delimiteur del : dels) {
+				if (del.id.equals("p")) {
+					if (del.taille>0)
+						writer.println("<p>");
+					else {
+						writer.println();
+						if (del.taille<0) writer.println("</p>");
+						else writer.println("<p/>");
+					}
+				} else {
+					String ancre1 = "<anchor xml:id=\""+del.id;
+					String ancre2 = "\" type=\"AnalecDelimiter\" subtype=\"Unit";
+					if (del.taille>0)
+						writer.print(ancre1+"-start"+ancre2+"Start\"/>");
+					else if (del.taille<0)
+						writer.print(ancre1+"-end"+ancre2+"End\"/>");
+					else {  // ne devrait pas se produire : une unité de taille nulle
+						writer.print(ancre1+"-start"+ancre2+"Start\"/>");
+						writer.print(ancre1+"-end"+ancre2+"End\"/>");
+					}
+				}
+			}
+		}
+		private void ecrireAnnot() {
+			writer.println("<back>");
+			for (String type : unites.keySet()) {
+				writer.println("<spanGrp type=\"AnalecUnit\""
+						+" n=\""+encodeName.get(type)+"\">");
+				for (Unite unit : unites.get(type)) ecrireUnite(unit);
+				writer.println("</spanGrp>");
+			}
+			for (String type : relations.keySet()) {
+				writer.println("<joinGrp type=\"AnalecRelation\""
+						+" n=\""+encodeName.get(type)+"\">");
+				for (Relation rel : relations.get(type)) ecrireRelation(rel);
+				writer.println("</joinGrp>");
+			}
+			for (String type : schemas.keySet()) {
+				writer.println("<joinGrp type=\"AnalecSchema\""
+						+" n=\""+encodeName.get(type)+"\">");
+				for (Schema sch : schemas.get(type)) ecrireSchema(sch);
+				writer.println("</joinGrp>");
+			}
+			writer.println("<fvLib n=\"AnalecElementProperties\">");
+			for (String type : unites.keySet())
+				for (Unite unit : unites.get(type)) ecrireProps(unit);
+			for (String type : relations.keySet())
+				for (Relation rel : relations.get(type)) ecrireProps(rel);
+			for (String type : schemas.keySet())
+				for (Schema sch : schemas.get(type)) ecrireProps(sch);
+			writer.println("</fvLib>");
+			writer.println("</back>");
+		}
+		private void ecrireUnite(Unite unit) {
+			String id = ids.get(unit);
+			writer.println("<span xml:id=\""+id+"\"");
+			writer.println("from=\"#"+id+"-start\" to=\"#"+id+"-end\"");
+			writer.println("ana=\"#"+id+"-fs\"/>");
+		}
+		private void ecrireRelation(Relation rel) {
+			String id = ids.get(rel);
+			writer.println("<join xml:id=\""+ids.get(rel)+"\"");
+			writer.println("target=\"#"+ids.get(rel.getElt1())
+					+" #"+ids.get(rel.getElt2())+"\"");
+			writer.println("ana=\"#"+id+"-fs\"/>");
+		}
+		private void ecrireSchema(Schema sch) {
+			String id = ids.get(sch);
+			writer.println("<join xml:id=\""+ids.get(sch)+"\"");
+			writer.print("target=\"");
+			for (Element elt : sch.getContenu())
+				writer.print("#"+ids.get(elt)+" ");
+			writer.println("\"");
+			writer.println("ana=\"#"+id+"-fs\"/>");
+		}
+		private void ecrireProps(Element elt) {
+			writer.println("<fs xml:id=\""+ids.get(elt)+"-fs\">");
+			HashMap<String, String> props = elt.getProps();
+			for (String nom : props.keySet()) {
+				if (props.get(nom)!=null)
+					writer.println("<f name=\""+encodeName.get(nom)+"\"><string>"
+							+encodeTexte(props.get(nom))+"</string></f>");
+			}
+			writer.println("</fs>");
+		}
+		private static String encodeTexte(String ch) {
+			return ch.replaceAll("&", "&amp;").replaceAll("<", "&lt;").
+					replaceAll(">", "&gt;").replaceAll("\"", "&quot;").
+					replaceAll("\'", "&apos;");
+		}
+		final static String interdits = "[!\\\"#\\$%&'\\(\\)\\*+,/;<=>\\?"
+				+"@\\[\\\\\\]\\^`\\{\\|\\}\\~]";
+		private static String encodeId(String ch) {
+			String id = ch.replaceAll("\\s", "_");
+			if (id.matches("[-\\.0-9];*")) id = '_'+id;
+			id = id.replaceAll(interdits, "\u00b7");
+			if (id.length()>2&&id.substring(0, 3).equalsIgnoreCase("xml")) id = '_'+id;
+			return id;
+		}
+		private static String traiterSaisie(String ch) {
+			if (ch==null) return CHAMP_NON_RENSEIGNE;
+			if (ch.trim().isEmpty()) return CHAMP_NON_RENSEIGNE;
+			return encodeTexte(ch);
+		}
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTEI.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/ProgressMonitorDemo.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/ProgressMonitorDemo.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/ProgressMonitorDemo.java	(revision 481)
@@ -0,0 +1,173 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+/*
+ * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle or the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */ 
+
+
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import java.beans.*;
+import java.util.Random;
+
+public class ProgressMonitorDemo extends JPanel
+                                 implements ActionListener,
+                                            PropertyChangeListener {
+
+    private ProgressMonitor progressMonitor;
+    private JButton startButton;
+    private JTextArea taskOutput;
+    private Task task;
+
+    class Task extends SwingWorker<Void, Void> {
+        @Override
+        public Void doInBackground() {
+            Random random = new Random();
+            int progress = 0;
+            setProgress(0);
+            try {
+                Thread.sleep(1000);
+                while (progress < 100 && !isCancelled()) {
+                    //Sleep for up to one second.
+                    Thread.sleep(random.nextInt(1000));
+                    //Make random progress.
+                    progress += random.nextInt(10);
+                    setProgress(Math.min(progress, 100));
+                }
+            } catch (InterruptedException ignore) {}
+            return null;
+        }
+
+        @Override
+        public void done() {
+            Toolkit.getDefaultToolkit().beep();
+            startButton.setEnabled(true);
+            progressMonitor.setProgress(0);
+        }
+    }
+
+    public ProgressMonitorDemo() {
+        super(new BorderLayout());
+
+        //Create the demo's UI.
+        startButton = new JButton("Start");
+        startButton.setActionCommand("start");
+        startButton.addActionListener(this);
+
+        taskOutput = new JTextArea(5, 20);
+        taskOutput.setMargin(new Insets(5,5,5,5));
+        taskOutput.setEditable(false);
+
+        add(startButton, BorderLayout.PAGE_START);
+        add(new JScrollPane(taskOutput), BorderLayout.CENTER);
+        setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+
+    }
+
+
+    /**
+     * Invoked when the user presses the start button.
+     */
+    public void actionPerformed(ActionEvent evt) {
+        progressMonitor = new ProgressMonitor(ProgressMonitorDemo.this,
+                                  "Running a Long Task",
+                                  "", 0, 100);
+        progressMonitor.setProgress(0);
+        task = new Task();
+        task.addPropertyChangeListener(this);
+        task.execute();
+        startButton.setEnabled(false);
+    }
+
+    /**
+     * Invoked when task's progress property changes.
+     */
+    public void propertyChange(PropertyChangeEvent evt) {
+        if ("progress" == evt.getPropertyName() ) {
+            int progress = (Integer) evt.getNewValue();
+            progressMonitor.setProgress(progress);
+            String message =
+                String.format("Completed %d%%.\n", progress);
+            progressMonitor.setNote(message);
+            taskOutput.append(message);
+            if (progressMonitor.isCanceled() || task.isDone()) {
+                Toolkit.getDefaultToolkit().beep();
+                if (progressMonitor.isCanceled()) {
+                    task.cancel(true);
+                    taskOutput.append("Task canceled.\n");
+                } else {
+                    taskOutput.append("Task completed.\n");
+                }
+                startButton.setEnabled(true);
+            }
+        }
+
+    }
+
+    /**
+     * Create the GUI and show it.  For thread safety,
+     * this method should be invoked from the
+     * event-dispatching thread.
+     */
+    private static void createAndShowGUI() {
+        //Create and set up the window.
+        JFrame frame = new JFrame("ProgressMonitorDemo");
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+        //Create and set up the content pane.
+        JComponent newContentPane = new ProgressMonitorDemo();
+        newContentPane.setOpaque(true); //content panes must be opaque
+        frame.setContentPane(newContentPane);
+
+        //Display the window.
+        frame.pack();
+        frame.setVisible(true);
+    }
+
+    public static void main(String[] args) {
+        //Schedule a job for the event-dispatching thread:
+        //creating and showing this application's GUI.
+        javax.swing.SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                createAndShowGUI();
+            }
+        });
+    }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/ProgressMonitorDemo.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersGlozz.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersGlozz.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersGlozz.java	(revision 481)
@@ -0,0 +1,731 @@
+package visuAnalec.fichiers;
+
+import java.io.*;
+import java.util.*;
+
+import javax.swing.*;
+import javax.xml.parsers.*;
+
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public abstract class FichiersGlozz {
+	public static void convertirCorpusGlozz(final Corpus corpus) {
+		File repGlozz;
+		final File repJava;
+		if ((repGlozz = Fichiers.choisirRepertoire("Choix du répertoire Glozz"))==null)
+			return;
+		if ((repJava = Fichiers.choisirRepertoire("Choix du répertoire Java"))==null)
+			return;
+		if (!repJava.exists()) {
+			if (!GMessages.confirmationAction("Le répertoire spécifié n'existe pas."
+					+" Voulez-vous le créer ?")) return;
+			if (!repJava.mkdir()) {
+				GMessages.impossibiliteAction("Echec de la création du répertoire");
+				return;
+			}
+		}
+		final File[] fics = Fichiers.listerFichiers(repGlozz, Fichiers.TypeFichier.GLOZZ_CORPUS);
+		final GMessages.GProgression progression =
+				new GMessages.GProgression(fics.length, "Conversion", "fichiers");
+		Thread traitement = new Thread() {
+			@Override
+			public void run() {
+				try {
+					for (int i = 0; i<fics.length; i++) {
+						if (progression.isCanceled()) break;
+						progression.setNbTraites(i+1);
+						File fichierCorpus = fics[i];
+						File fichierAnnot = Fichiers.trouverFichier(TypeFichier.GLOZZ_ANNOT, fichierCorpus);
+						if (fichierAnnot==null) continue;
+						importer(fichierCorpus, fichierAnnot, corpus);
+						FichiersJava.enregistrerCorpus(corpus, Fichiers.creerFichier(repJava, TypeFichier.DOC_ANALEC, fichierCorpus));
+						//          corpus.fermer();
+					}
+					corpus.fermer();
+				} catch (Throwable ex) {
+					GMessages.erreurFatale(ex);
+				}
+			}
+		};
+		traitement.start();
+	}
+	
+	public static boolean importerGlozz(Corpus corpus, File fichierCorpus, File fichierAnnot) {
+		if (!importer(fichierCorpus, fichierAnnot, corpus)) {
+			return false;
+		}
+		corpus.newCorpusLu();
+		
+		return true;
+	}
+	
+	/**
+	 * 
+	 * @param corpus
+	 */
+	public static boolean importerGlozz(Corpus corpus) {
+		File fichierCorpus;
+		File fichierAnnot;
+		if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR,
+				"Choix du fichier corpus", Fichiers.TypeFichier.GLOZZ_CORPUS))==null)
+			return false;
+		if ((fichierAnnot = Fichiers.choisirFichier(Commande.OUVRIR,
+				"Choix du fichier annotations", Fichiers.TypeFichier.GLOZZ_ANNOT))==null)
+			return false;
+		
+		return importerGlozz(corpus, fichierCorpus, fichierAnnot);
+	}
+	
+	/**
+	 * 
+	 * @param fichierCorpus ac file (txt)
+	 * @param fichierAnnot aa file (annotations)
+	 * 
+	 * @param corpus
+	 */
+	private static boolean importer(File fichierCorpus, File fichierAnnot, Corpus corpus) {
+		BufferedReader text = null;
+		BufferedInputStream annot = null;
+		try {
+			text = new BufferedReader(new InputStreamReader(new FileInputStream(fichierCorpus), "UTF-8"));
+			annot = new BufferedInputStream(new FileInputStream(fichierAnnot));
+			corpus.setTexte(text.readLine());
+			SAXParserFactory pf = (SAXParserFactory) SAXParserFactory.newInstance();
+			SAXParser sp = pf.newSAXParser();
+			sp.parse(annot, new GlozzHandler(corpus));
+		} catch (IOException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (ParserConfigurationException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (SAXException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			try {
+				if (text!=null) text.close();
+				if (annot!=null) annot.close();
+			} catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
+			}
+		}
+		return true;
+	}
+	
+	public static boolean importerModeleGlozz(Corpus corpus, File fichierModele) {
+		BufferedInputStream modele = null;
+		
+		try {
+			modele = new BufferedInputStream(new FileInputStream(fichierModele));
+			SAXParserFactory pf = (SAXParserFactory) SAXParserFactory.newInstance();
+			SAXParser sp = pf.newSAXParser();
+			Structure structureLue = new Structure();
+			sp.parse(modele, new ModeleGlozzHandler(structureLue));
+			corpus.fusionnerStructureLue(structureLue);
+			corpus.newCorpusLu();
+		} catch (IOException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (ParserConfigurationException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (SAXException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			try {
+				if (modele!=null) modele.close();
+			} catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
+			}
+		}
+		return true;
+	}
+	
+	public static boolean importerModeleGlozz(Corpus corpus) {
+		File fichierModele;
+		if ((fichierModele = Fichiers.choisirFichier(Commande.OUVRIR,
+				"Choix du fichier modèle", Fichiers.TypeFichier.GLOZZ_MODELE))==null)
+			return false;
+		
+		return importerModeleGlozz(corpus, fichierModele);
+	}
+	
+	public static boolean exporterGlozz(Corpus corpus) {
+		PrintWriter text = null;
+		PrintWriter annot = null;
+		PrintWriter model = null;
+		File fichierCorpus;
+		File fichierAnnot;
+		File fichierModel;
+		if ((fichierCorpus = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Nom du fichier corpus", Fichiers.TypeFichier.GLOZZ_CORPUS))==null) return false;
+		if ((fichierAnnot = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Nom du fichier annotations", Fichiers.TypeFichier.GLOZZ_ANNOT))==null)
+			return false;
+		try {
+			text = new PrintWriter(fichierCorpus, "UTF-8");
+			annot = new PrintWriter(fichierAnnot, "UTF-8");
+			text.print(corpus.getTexte());
+			GlozzPrinter gp = new GlozzPrinter(corpus, annot);
+			gp.ecrireAnnot();
+		} catch (FileNotFoundException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (UnsupportedEncodingException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			if (text!=null) text.close();
+			if (annot!=null) annot.close();
+		}
+		if ((fichierModel = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Exporter aussi le modèle ?", Fichiers.TypeFichier.GLOZZ_MODELE))==null)
+			return true;
+		try {
+			model = new PrintWriter(fichierModel, "UTF-8");
+			ModelGlozzPrinter gp = new ModelGlozzPrinter(corpus.getStructure(), model);
+			gp.ecrireModel();
+		} catch (FileNotFoundException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (UnsupportedEncodingException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			if (model!=null) model.close();
+		}
+		return true;
+	}
+	
+	public static boolean exporterModeleGlozz(Structure structure) {
+		PrintWriter model = null;
+		File fichierModel;
+		if ((fichierModel = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Nom du fichier modèle ?", Fichiers.TypeFichier.GLOZZ_MODELE))==null)
+			return false;
+		try {
+			model = new PrintWriter(fichierModel, "UTF-8");
+			ModelGlozzPrinter gp = new ModelGlozzPrinter(structure, model);
+			gp.ecrireModel();
+		} catch (FileNotFoundException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} catch (UnsupportedEncodingException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		} finally {
+			if (model!=null) model.close();
+		}
+		return true;
+	}
+
+	static class GlozzHandler extends DefaultHandler {
+		Corpus corpus;
+		Balise etatCourant = null;
+		Element elementCourant = null;
+		String champCourant = null;
+		String valCourant = null;
+		HashMap<String, Element> elements = new HashMap<String, Element>();
+		ArrayList<Relation> relations = new ArrayList<Relation>();
+		HashMap<Relation, ArrayList<String>> idTermes = new HashMap<Relation, ArrayList<String>>();
+		ArrayList<Schema> schemas = new ArrayList<Schema>();
+		HashMap<Schema, ArrayList<String>> idContenus = new HashMap<Schema, ArrayList<String>>();
+
+		public static enum Balise {
+			ANNOTATIONS, UNIT, RELATION, SCHEMA, METADATA, AUTHOR, CREATIONDATE,
+			LASTMODIFIER, LASTMODIFICATIONDATE, CHARACTERISATION, TYPE, FEATURESET,
+			FEATURE, POSITIONING, START, END, SINGLEPOSITION, TERM,
+			EMBEDDEDUNIT, EMBEDDEDRELATION, EMBEDDEDSCHEMA,
+			FLAG, COMMENT, ANNOTATIONMODEL, UNITS, VALUE
+		};
+		static Balise balise(String nomBalise) {
+			return Balise.valueOf(nomBalise.replaceAll("\\W", "").toUpperCase());
+		}
+		GlozzHandler(Corpus corpus) {
+			super();
+			this.corpus = corpus;
+		}
+		@Override
+		public void startDocument() {
+			corpus.clearAnnot();
+		}
+		@Override
+		public void endDocument() throws SAXNotSupportedException {
+			for (Relation rel : relations) {
+				ArrayList<String> idterms = idTermes.get(rel);
+				if (idterms.size()!=2) {
+					throw new SAXNotSupportedException("Une relation de type "+rel.getType()+" n'a pas deux termes");
+				}
+				if (elements.get(idterms.get(0))==null) {
+					throw new SAXNotSupportedException("Terme inconnu id = "+idterms.get(0)
+							+" pour une relation de type "+rel.getType());
+				}
+				rel.setElt1(elements.get(idterms.get(0)));
+				if (elements.get(idterms.get(1))==null) {
+					throw new SAXNotSupportedException("Terme inconnu id = "+idterms.get(1)
+							+" pour une relation de type "+rel.getType());
+				}
+				rel.setElt2(elements.get(idterms.get(1)));
+				corpus.addRelationLue(rel);
+			}
+			for (Schema sch : schemas) {
+				for (String id : idContenus.get(sch)) {
+					if (elements.get(id)==null) {
+						throw new SAXNotSupportedException("Contenu inconnu id = "+id
+								+" pour un schéma de type "+sch.getType());
+					}
+					sch.ajouter(elements.get(id));
+				}
+				corpus.addSchemaLu(sch);
+			}
+			corpus.verifierFinParagraphesTypesUnites(new String[]{
+					"title", "subTitle", "sectionTitle", "subSectionTitle",
+					"subSubSectionTitle", "subSubSubSectionTitle", "quote", "listItem"});
+			corpus.trierFinParagraphes();
+			corpus.verifierFinParagrapheFinTexte();
+		}
+		@Override
+		public void startElement(String uri, String local, String nomBalise, Attributes attributs) throws SAXException {
+			if (etatCourant==Balise.FLAG) return;
+			switch (balise(nomBalise)) {
+			case FLAG:
+				etatCourant = Balise.FLAG;
+				break;
+			case UNIT:
+				elementCourant = new Unite();
+				elements.put(attributs.getValue("id"), elementCourant);
+				break;
+			case RELATION:
+				elementCourant = new Relation();
+				elements.put(attributs.getValue("id"), elementCourant);
+				idTermes.put((Relation) elementCourant, new ArrayList<String>());
+				break;
+			case SCHEMA:
+				elementCourant = new Schema();
+				elements.put(attributs.getValue("id"), elementCourant);
+				idContenus.put((Schema) elementCourant, new ArrayList<String>());
+				break;
+			case TYPE:
+				etatCourant = Balise.TYPE;
+				valCourant = "";
+				break;
+			case FEATURE:
+				etatCourant = Balise.FEATURE;
+				champCourant = attributs.getValue("name");
+				valCourant = "";
+				break;
+			case START:
+				etatCourant = Balise.START;
+				break;
+			case END:
+				etatCourant = Balise.END;
+				break;
+			case SINGLEPOSITION:
+				if (elementCourant.getClass()!=Unite.class) {
+					throw new SAXNotSupportedException("La balise singlePosition ne peut être utilisée que pour des unités");
+				}
+				if (elementCourant.getType().equals("paragraph")) {
+					if (etatCourant==Balise.END) {
+						corpus.addFinParagraphe(Integer.parseInt(attributs.getValue("index")));
+					}
+				} else {
+					switch (etatCourant) {
+					case START:
+						((Unite) elementCourant).setDeb(Integer.parseInt(attributs.getValue("index")));
+						break;
+					case END:
+						((Unite) elementCourant).setFin(Integer.parseInt(attributs.getValue("index")));
+						break;
+					}
+				}
+				break;
+			case TERM:
+				if (elementCourant.getClass()!=Relation.class)
+					throw new SAXNotSupportedException("La balise term ne peut être utilisée que pour des relations");
+				idTermes.get((Relation) elementCourant).add(attributs.getValue("id"));
+				break;
+
+			case EMBEDDEDUNIT:
+			case EMBEDDEDRELATION:
+			case EMBEDDEDSCHEMA:
+				if (elementCourant.getClass()!=Schema.class)
+					throw new SAXNotSupportedException(
+							"Les balises embedded ne peuvent être utilisées que pour des schémas");
+				idContenus.get((Schema) elementCourant).add(attributs.getValue("id"));
+				break;
+			}
+		}
+		@Override
+		public void endElement(String uri, String local, String nomBalise) throws SAXException {
+			if (etatCourant==Balise.FLAG) {
+				if (balise(nomBalise)==Balise.FLAG) etatCourant = null;
+				return;
+			}
+			String type = "";
+			switch (balise(nomBalise)) {
+			case UNIT:
+				type = elementCourant.getType();
+				if (type==null||type.isEmpty())
+					throw new SAXNotSupportedException("Pas trouvé de type pour cette unité");
+				if (!type.equals("paragraph")) {
+					corpus.addUniteLue((Unite) elementCourant);
+					elementCourant = null;
+				}
+				break;
+			case RELATION:
+				type = elementCourant.getType();
+				if (type==null||type.isEmpty())
+					throw new SAXNotSupportedException("Pas trouvé de type pour cette relation");
+				relations.add((Relation) elementCourant);
+				elementCourant = null;
+				break;
+			case SCHEMA:
+				type = elementCourant.getType();
+				if (type==null||type.isEmpty())
+					throw new SAXNotSupportedException("Pas trouvé de type pour ce shéma");
+				schemas.add((Schema) elementCourant);
+				elementCourant = null;
+				break;
+			case TYPE:
+				elementCourant.setType(valCourant);
+				valCourant = null;
+				etatCourant = null;
+				break;
+			case FEATURE:
+				elementCourant.putProp(champCourant, valCourant);
+				etatCourant = null;
+				champCourant = null;
+				valCourant = null;
+				break;
+			case START:
+				etatCourant = null;
+				break;
+			case END:
+				etatCourant = null;
+				break;
+			}
+		}
+		@Override
+		public void characters(char[] ch, int start, int taille) throws SAXException {
+			if (etatCourant==null||!EnumSet.of(Balise.TYPE, Balise.FEATURE).contains(etatCourant)) {
+				return;
+			}
+			valCourant += new String(ch, start, taille);
+		}
+	}
+
+	static class ModeleGlozzHandler extends DefaultHandler {
+		Structure structure;
+		boolean listeValeurs = false;
+		Class<? extends Element> classeCourante = Unite.class;  // par défaut : balise <units> sous-entendue 
+		String typeCourant = null;
+		String champCourant = null;
+		String valeurCourante = null;
+
+		public static enum Balise {
+			ANNOTATIONMODEL, UNITS, RELATIONS, SCHEMAS, TYPE, FEATURESET,
+			FEATURE, POSSIBLEVALUES, VALUE
+		};
+		static Balise balise(String nomBalise) throws SAXNotRecognizedException {
+			try {
+				return Balise.valueOf(nomBalise.replaceAll("\\W", "").toUpperCase());
+			} catch (Exception e) {
+				throw new SAXNotRecognizedException("Balise non reconnue : "+nomBalise);
+			}
+		}
+		ModeleGlozzHandler(Structure structure) {
+			super();
+			this.structure = structure;
+		}
+		@Override
+		public void startDocument() {
+		}
+		@Override
+		public void endDocument() throws SAXNotSupportedException {
+		}
+		@Override
+		public void startElement(String uri, String local, String nomBalise, Attributes attributs) throws SAXException {
+			String valdef = null;
+			switch (balise(nomBalise)) {
+			case UNITS:
+				classeCourante = Unite.class;
+				break;
+			case RELATIONS:
+				classeCourante = Relation.class;
+				break;
+			case SCHEMAS:
+				classeCourante = Schema.class;
+				break;
+			case TYPE:
+				typeCourant = attributs.getValue("name");
+				if (typeCourant==null||typeCourant.isEmpty())
+					throw new SAXNotSupportedException("Nom de type absent");
+				structure.ajouterType(classeCourante, typeCourant);
+				break;
+			case FEATURE:
+				if (typeCourant==null||typeCourant.isEmpty())
+					throw new SAXNotSupportedException("Nom de type absent");
+				champCourant = attributs.getValue("name");
+				if (champCourant==null||champCourant.isEmpty())
+					throw new SAXNotSupportedException("Nom de type absent");
+				structure.ajouterProp(classeCourante, typeCourant, champCourant);
+				break;
+			case POSSIBLEVALUES:
+				if (typeCourant==null||typeCourant.isEmpty()||champCourant==null||champCourant.isEmpty())
+					throw new SAXNotSupportedException("Nom de type ou de feature absent");
+				listeValeurs = true;
+				valdef = attributs.getValue("default");
+				if (valdef!=null&&!valdef.isEmpty())
+					structure.modifierValParDefaut(classeCourante, typeCourant, champCourant, valdef);
+				break;
+			case VALUE:
+				if (listeValeurs) valeurCourante = "";
+				valdef = attributs.getValue("default");
+				if (valdef!=null&&!valdef.isEmpty()) {
+					if (typeCourant==null||typeCourant.isEmpty()||champCourant==null||champCourant.isEmpty())
+						throw new SAXNotSupportedException("Nom de type ou de feature absent");
+					structure.ajouterVal(classeCourante, typeCourant, champCourant, valdef);
+					structure.modifierValParDefaut(classeCourante, typeCourant, champCourant, valdef);
+				}
+				break;
+			}
+		}
+		@Override
+		public void endElement(String uri, String local, String nomBalise) throws SAXException {
+			switch (balise(nomBalise)) {
+			case POSSIBLEVALUES:
+				listeValeurs = false;
+				break;
+			case VALUE:
+				if (listeValeurs&&valeurCourante!=null&&!valeurCourante.isEmpty())
+					structure.ajouterVal(classeCourante, typeCourant, champCourant, valeurCourante);
+				break;
+			}
+		}
+		@Override
+		public void characters(char[] ch, int start, int taille) throws SAXException {
+			if (listeValeurs) {
+				valeurCourante += new String(ch, start, taille);
+			}
+		}
+	}
+
+	static class GlozzPrinter {
+		Corpus corpus;
+		PrintWriter annot;
+		HashMap<Element, String> idDates = new HashMap<Element, String>();
+		String idAuteur = "analec0.2";
+		String idDateParagraphes = "0";
+		String idParagraphes = idAuteur+"_"+idDateParagraphes;
+		GlozzPrinter(Corpus corpus, PrintWriter annot) {
+			this.corpus = corpus;
+			this.annot = annot;
+			attribueIdDates();
+		}
+		void attribueIdDates() {
+			long idDate = (new Date()).getTime();
+			for (Unite unite : corpus.getToutesUnites()) {
+				idDates.put(unite, Long.toString(idDate++));
+			}
+			for (Relation relation : corpus.getToutesRelations()) {
+				idDates.put(relation, Long.toString(idDate++));
+			}
+			for (Schema schema : corpus.getTousSchemas()) {
+				idDates.put(schema, Long.toString(idDate++));
+			}
+		}
+		String getId(Element elt) {
+			return idAuteur+"_"+idDates.get(elt);
+		}
+		void ecrireAnnot() {
+			annot.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
+			annot.println("<annotations>");
+			ecrireFinParagraphes();
+			ecrireUnites();
+			ecrireRelations();
+			ecrireSchemas();
+			annot.println("</annotations>");
+		}
+		private void ecrireFinParagraphes() {
+			int deb = 0;
+			for (int fin : corpus.getFinParagraphes()) {
+				ecrireUnite("paragraph", idAuteur, idDateParagraphes, idParagraphes, new HashMap<String, String>(), deb, fin);
+				deb = fin;
+			}
+		}
+		private void ecrireUnites() {
+			for (Unite unit : corpus.getToutesUnites()) {
+				ecrireUnite(unit.getType(), idAuteur, idDates.get(unit), getId(unit), unit.getProps(), unit.getDeb(), unit.getFin());
+			}
+		}
+		private void ecrireRelations() {
+			for (Relation rel : corpus.getToutesRelations()) {
+				ecrireRelation(rel.getType(), idAuteur, idDates.get(rel), getId(rel), rel.getProps(), rel.getElt1(), rel.getElt2());
+			}
+		}
+		private void ecrireSchemas() {
+			for (Schema sch : corpus.getTousSchemas()) {
+				ecrireSchema(sch.getType(), idAuteur, idDates.get(sch), getId(sch), sch.getProps(), sch.getContenu());
+			}
+		}
+		private void ecrireUnite(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, int deb, int fin) {
+			annot.println("<unit id=\""+id+"\">");
+			ecrireMetadata(idAuteur, idDate);
+			ecrireProps(type, props);
+			ecrirePos(deb, fin);
+			annot.println("</unit>");
+		}
+		private void ecrireRelation(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, Element elt1, Element elt2) {
+			annot.println("<relation id=\""+id+"\">");
+			ecrireMetadata(idAuteur, idDate);
+			ecrireProps(type, props);
+			ecrireRel(elt1, elt2);
+			annot.println("</relation>");
+		}
+		private void ecrireSchema(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, HashSet<Element> elts) {
+			annot.println("<schema id=\""+id+"\">");
+			ecrireMetadata(idAuteur, idDate);
+			ecrireProps(type, props);
+			ecrireSch(elts);
+			annot.println("</schema>");
+		}
+		private void ecrireMetadata(String idAuteur, String id) {
+			annot.println("<metadata>");
+			annot.println("<author>"+idAuteur+"</author>");
+			annot.println("<creation-date>"+id+"</creation-date>");
+			annot.println("</metadata>");
+		}
+		private void ecrireProps(String type, HashMap<String, String> props) {
+			annot.println("<characterisation>");
+			annot.println("<type>"+encodeXMLTexte(type)+"</type>");
+			if (props.isEmpty()) {
+				annot.println("<featureSet/>");
+			} else {
+				annot.println("<featureSet>");
+				for (String prop : props.keySet()) {
+					if (props.get(prop)!=null) {
+						annot.println("<feature name =\""+encodeXMLTexte(prop)+"\">"
+								+encodeXMLTexte(props.get(prop))+"</feature>");
+					}
+				}
+				annot.println("</featureSet>");
+
+			}
+			annot.println("</characterisation>");
+		}
+		private void ecrirePos(int deb, int fin) {
+			annot.println("<positioning>");
+			annot.println("<start>");
+			annot.println("<singlePosition index = \""+deb+"\"/>");
+			annot.println("</start>");
+			annot.println("<end>");
+			annot.println("<singlePosition index = \""+fin+"\"/>");
+			annot.println("</end>");
+			annot.println("</positioning>");
+		}
+		private void ecrireRel(Element elt1, Element elt2) {
+			annot.println("<positioning>");
+			annot.println("<term id = \""+getId(elt1)+"\"/>");
+			annot.println("<term id = \""+getId(elt2)+"\"/>");
+			annot.println("</positioning>");
+		}
+		private void ecrireSch(HashSet<Element> elts) {
+			annot.println("<positioning>");
+			for (Element elt : elts) {
+				Class classe = elt.getClass();
+				if (classe==Unite.class) {
+					annot.print("<embedded-unit ");
+				}
+				if (classe==Relation.class) {
+					annot.print("<embedded-relation ");
+				}
+				if (classe==Schema.class) {
+					annot.print("<embedded-schema ");
+				}
+				annot.println("id = \""+getId(elt)+"\"/>");
+			}
+			annot.println("</positioning>");
+		}
+	}
+
+	static class ModelGlozzPrinter {
+		Structure structure;
+		PrintWriter model;
+		ModelGlozzPrinter(Structure structure, PrintWriter model) {
+			this.structure = structure;
+			this.model = model;
+		}
+		void ecrireModel() {
+			model.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
+			model.println("<annotationModel>");
+			ecrireUnites();
+			ecrireRelations();
+			ecrireSchemas();
+			model.println("</annotationModel>");
+		}
+		private void ecrireUnites() {
+			model.println("<units>");
+			for (String type : structure.getTypes(Unite.class))
+				ecrireType(Unite.class, type);
+			model.println("</units>");
+		}
+		private void ecrireRelations() {
+			model.println("<relations>");
+			for (String type : structure.getTypes(Relation.class))
+				ecrireType(Relation.class, type);
+			model.println("</relations>");
+		}
+		private void ecrireSchemas() {
+			model.println("<schemas>");
+			for (String type : structure.getTypes(Schema.class))
+				ecrireType(Schema.class, type);
+			model.println("</schemas>");
+		}
+		private void ecrireType(Class<? extends Element> classe, String type) {
+			model.print("<type name=\""+encodeXMLTexte(type)+"\"");
+			if (classe==Relation.class) model.print(" oriented=\"true\"");
+			model.println(">");
+			model.println("<featureSet>");
+			for (String prop : structure.getNomsProps(classe, type))
+				ecrireProp(classe, type, prop);
+			model.println("</featureSet>");
+			model.println("</type>");
+		}
+		private void ecrireProp(Class<? extends Element> classe, String type, String prop) {
+			model.println("<feature name=\""+encodeXMLTexte(prop)+"\">");
+			if (structure.getValeursProp(classe, type, prop).isEmpty()) {
+				model.println("<value type=\"free\" default=\"\" />");
+			} else {
+				model.println("<possibleValues default = \""
+						+structure.getValeurParDefaut(classe, type, prop)+"\">");
+				for (String val : structure.getValeursProp(classe, type, prop))
+					model.println("<value>"+encodeXMLTexte(val)+"</value>");
+				model.println("</possibleValues>");
+			}
+			model.println("</feature>");
+
+		}
+	}
+	static String encodeXMLTexte(String ch) {
+		//    return ch;
+		return ch.replaceAll("&", "&amp;").replaceAll("<", "&lt;").
+				replaceAll(">", "&gt;").replaceAll("\"", "&quot;").
+				replaceAll("\'", "&apos;");
+	}
+
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersGlozz.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersGraphique.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersGraphique.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersGraphique.java	(revision 481)
@@ -0,0 +1,195 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.awt.*;
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class FichiersGraphique {
+
+  public static class CercleColore {
+
+    public int cx, cy, r;
+    public Color couleur;
+  }
+
+  public static interface GraphiqueExport {
+
+    public Dimension initExport();
+
+    public Rectangle getCadre();
+
+    public CercleColore[] getCerclesColores();
+  }
+
+  public static void exporterGraphiqueSVG(GraphiqueExport donnees) {
+    PrintWriter sortie = null;
+    File fichierGraphique;
+    if ((fichierGraphique = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier ?", Fichiers.TypeFichier.GRAPHIQUE_SVG)) == null) return;
+    try {
+      sortie = new PrintWriter(fichierGraphique, "UTF-8");
+      ecrireSVG(sortie, donnees);
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier",
+              JOptionPane.ERROR_MESSAGE);
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier",
+              JOptionPane.ERROR_MESSAGE);
+    } finally {
+      if (sortie != null) sortie.close();
+    }
+  }
+
+  public static void ecrireSVG(PrintWriter sortie, GraphiqueExport donnees) {
+    sortie.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+    sortie.println("<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"");
+    Dimension dim = donnees.initExport();
+    sortie.println("x=\"0px\" y=\"0px\" width=\"" + dim.width
+            + "px\" height=\"" + dim.height + "px\">");
+    Rectangle cadre = donnees.getCadre();
+    if (cadre != null)
+      sortie.println("<rect x=\"" + cadre.x + "\" y=\"" + cadre.y
+              + "\" fill=\"none\" stroke=\"#000000\" width=\"" + cadre.width
+              + "\" height=\"" + cadre.height + "\"/>");
+    CercleColore[] cercles = donnees.getCerclesColores();
+    for (CercleColore cercle : cercles)
+      sortie.println("<ellipse cx=\"" + cercle.cx + "\" cy=\""
+              + cercle.cy + "\" fill=\"" + ecritCouleurSVG(cercle.couleur)
+              + "\" stroke=\"#000000\" rx=\"" + cercle.r
+              + "\" ry=\"" + cercle.r + "\"/>");
+
+    sortie.println("</svg>");
+  }
+
+  private static String ecritCouleurSVG(Color c) {
+    String res = "#";
+    res += Integer.toHexString(c.getRGB()).substring(2);
+    return res;
+  }
+
+  public static void exporterGraphiqueEMF(GraphiqueExport donnees) {
+    FileChannel canal = null;
+    FileOutputStream sortie = null;
+    File fichierGraphique;
+    if ((fichierGraphique = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier ?", Fichiers.TypeFichier.GRAPHIQUE_EMF)) == null) return;
+    try {
+      sortie = new FileOutputStream(fichierGraphique);
+      canal = sortie.getChannel();
+      ByteBuffer buff = ecrireEMF(donnees);
+      canal.write(buff);
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier",
+              JOptionPane.ERROR_MESSAGE);
+    } finally {
+      if (canal != null)
+        try {
+          canal.close();
+        } catch (IOException ex) {
+          JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier",
+                  JOptionPane.ERROR_MESSAGE);
+        }
+      if (sortie != null)
+        try {
+          sortie.close();
+        } catch (IOException ex) {
+          JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier",
+                  JOptionPane.ERROR_MESSAGE);
+        }
+    }
+  }
+
+  private static ByteBuffer ecrireEMF(GraphiqueExport donnees) {
+    ArrayList<Integer> dessin = new ArrayList<Integer>();
+        Dimension dim = donnees.initExport();
+    int nbrecords = 0;
+    dessin.add(1); // header
+    dessin.add(88); // taille du header 
+    dessin.addAll(Arrays.asList(0, 0, dim.width, dim.height)); 
+                                                   // taille du graphique en px 
+    dessin.addAll(Arrays.asList(0, 0, dim.width*32, dim.height*32)); 
+                                                  // taille en 0.01 mm (px * 32)
+    dessin.add(0x464D4520); // signature (" EMF" à l'endroit!!) 
+    dessin.add(0x00010000); // version 
+    int indTailles = dessin.size();  // endroit où mettre les tailles 
+    dessin.addAll(Arrays.asList(0, 0)); // taille du fichier, nb records : remplis à la fin
+    dessin.add(2); // nbobjs : pen et brush
+    dessin.addAll(Arrays.asList(0, 0));   //taille et offset de la description
+    dessin.add(0); // nb d'entrees de palette 
+    dessin.addAll(Arrays.asList(1024, 768, 320, 240)); // taille du device en px et en mm
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x11, 0xC, 0x8));  // mapmode : 0x8 (anisotropique)
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x12, 0xC, 0x1));  // bkmode : 0x1 (transparent)
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0xA, 0x10, 0, 0));  // setWindowOrgEx: 0,0
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0xC, 0x10, 0, 0));  // setViewPortOrgEx: 0,0
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x9, 0x10, dim.width, dim.height));  // setWindowExtEx
+    nbrecords++; // setWindowExtEx: 0,0
+    dessin.addAll(Arrays.asList(0xB, 0x10, dim.width, dim.height));  // setViewPortExtEx
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x27, 0x18, 1, 1, 0, 0));  // createBrushIndirect : 
+    nbrecords++;                                        //1 (NoObj) 1 (BS_NULL) 0 0
+    dessin.addAll(Arrays.asList(0x25, 0xC, 1));  // selectObject 1
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x5F, 0x34, 2, 0, 0, 0, 0, 0x12200, 0x4, 0, 0, 0, 0));
+    // extCreatePen : 2 (NoObj) 0 0 0 0 (absence de DIB) 
+    // 0x12200 (PS_GEOMETRIC, JOIN_MITER, ENDCAP_FLAT) 
+    // 0x4 (largeur) 0 (BS_NULL) 0 (Color) 0 (BrushHatch) 0 (numStyleEntries)     
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x25, 0xC, 2));  // selectObject 2
+    nbrecords++;
+      Rectangle cadre = donnees.getCadre();
+    if (cadre != null) {
+  
+    dessin.addAll(Arrays.asList(0x2B, 0x18, cadre.x, cadre.y, 
+            cadre.x+cadre.width, cadre.y+cadre.height));  //  Rectangle
+    nbrecords++;
+    }
+ CercleColore[] cercles = donnees.getCerclesColores();
+   for (CercleColore cercle : cercles) {
+//      sortie.println("<ellipse cx=\"" + cercle.cx + "\" cy=\""
+//              + cercle.cy + "\" fill=\"" + ecritCouleurSVG(cercle.couleur)
+//              + "\" stroke=\"#000000\" rx=\"" + cercle.r
+//              + "\" ry=\"" + cercle.r + "\"/>");
+    dessin.addAll(Arrays.asList(0x28, 0xC, 1));  // deleteObject 1
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x27, 0x18, 1, 0, ecritCouleurEMF(cercle.couleur), 0));  
+    nbrecords++;      // createBrushIndirect : 1 (NoObj) 0 (BS_SOLID) Color (0BGR) 0
+    dessin.addAll(Arrays.asList(0x25, 0xC, 1));  // selectObject 1
+    nbrecords++;
+    dessin.addAll(Arrays.asList(0x2A, 0x18, cercle.cx-cercle.r, cercle.cy-cercle.r,
+            cercle.cx+cercle.r, cercle.cy+cercle.r));  //  Ellipse
+    nbrecords++;
+   }
+    dessin.addAll(Arrays.asList(0xE, 0x14, 0, 0, 0x14));  //  EOF 0xE 
+    nbrecords++;                                      //+ taille (20?) et offset palette
+    dessin.set(indTailles++, dessin.size() * 4);
+    dessin.set(indTailles, nbrecords);
+    ByteBuffer buff = ByteBuffer.allocate(dessin.size() * 4).order(ByteOrder.LITTLE_ENDIAN);
+    buff.clear();
+    for (int n : dessin) buff.putInt(n);
+    buff.flip();
+    return buff;
+  }
+    private static int ecritCouleurEMF(Color c) {
+    return c.getRed() | (c.getGreen()<<8) | (c.getBlue()<<16);
+  }
+
+
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersGraphique.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersCoNLL.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersCoNLL.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersCoNLL.java	(revision 481)
@@ -0,0 +1,212 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public abstract class FichiersCoNLL {
+  static final String TYPE_UNITES = "Token";
+  static final String TYPE_RELATION = "Dependency";
+  static final String TYPE_RELATION_PROJ = "Projective Dependency";
+  static final String PROP_LEMME = "Lemma";
+  static final String PROP_C_POS = "C-POS";
+  static final String PROP_POS = "POS";
+  static final String PROP_TRAITS = "Features";
+  static final String PROP_REL = "Function";
+  public static void importerCoNLL(Corpus corpus) {
+    BufferedReader in = null;
+    File ficCoNLL;
+    GCodage codage = new GCodage();
+    if ((ficCoNLL = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix du fichier CoNLL", TypeFichier.CONLL))==null)
+      return;
+    try {
+      in = new BufferedReader(new InputStreamReader(
+              new FileInputStream(ficCoNLL), "UTF-8"));
+      CoNLLParser parseur = new CoNLLParser(corpus);
+      parseur.parser(in);
+      corpus.newCorpusLu();
+    } catch (IOException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      try {
+        if (in!=null) in.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
+      }
+    }
+  }
+
+  static class CoNLLParser {
+    private Corpus corpus;
+    private String texte="";
+    private ArrayList<String> noHeads = new ArrayList<String>();
+    private ArrayList<String> depRels = new ArrayList<String>();
+    private ArrayList<String> noPHeads = new ArrayList<String>();
+    private ArrayList<String> pDepRels = new ArrayList<String>();
+    private ArrayList<Unite> units = new ArrayList<Unite>();
+    private HashMap<String, Integer> noTokenUnits = new HashMap<String, Integer>();
+    CoNLLParser(Corpus corpus) {
+      this.corpus = corpus;
+    }
+    private void parser(BufferedReader in) throws IOException {
+      String ligne;
+      int noligne = 0;
+      while (true) {
+        ligne = in.readLine();
+        if (ligne==null) {
+          finDocument(noligne);
+          break;
+        }
+        noligne++;
+        if (ligne.trim().isEmpty()) finPhrase(noligne);
+        else parserToken(ligne, noligne);
+      }
+    }
+    private void parserToken(String ligne, int noligne) throws IOException {
+      String ch;
+      String[] items = ligne.split("\\t");
+      if (items.length!=10)
+        throw new CoNLLException("Nombre de colonnes incorrect ("
+                +items.length+")", noligne);
+      Unite unit = new Unite();
+      unit.setType(TYPE_UNITES);
+      units.add(unit);
+      // champ ID
+      ch = items[0].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de numéro de token", noligne);
+      noTokenUnits.put(ch, units.size()-1);
+      // champ FORM
+      ch = items[1].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de token", noligne);
+      if (isPonct1(ch)) texte = texte.trim();
+      unit.setDeb(texte.length());
+      texte += ch;
+      unit.setFin(texte.length());
+      if (!isPonct2(ch)) texte += " ";
+      // champ LEMMA    
+      ch = items[2].replace('_', ' ').trim();
+      if (!ch.isEmpty())
+        unit.putProp(PROP_LEMME, ch);
+      // champ CPOSTAG
+      ch = items[3].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de C-POS", noligne);
+      unit.putProp(PROP_C_POS, ch);
+      // champ POSTAG
+      ch = items[4].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de POS", noligne);
+      unit.putProp(PROP_POS, ch);
+      // champ FEATS
+      ch = items[5].replace('_', ' ').trim();
+      if (!ch.isEmpty()) {
+        String[] chs = ch.split("\\|");
+        String traits = "";
+        for (String trait : chs) {
+          String[] attval = trait.split("=");
+          if (attval.length==2)
+            unit.putProp(attval[0].trim(), attval[1].trim());
+          else {
+            if (!traits.isEmpty()) traits += '|';
+            traits += trait;
+          }
+        }
+        if (!traits.isEmpty())
+          unit.putProp(PROP_TRAITS, traits);
+      }
+      // champ HEAD
+      ch = items[6].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de HEAD", noligne);
+      noHeads.add(ch);
+      // champ DEPREL
+      ch = items[7].replace('_', ' ').trim();
+      if (ch.isEmpty())
+        throw new CoNLLException("Pas trouvé de DEP-REL", noligne);
+      depRels.add(ch);
+      // champ PHEAD
+      ch = items[8].replace('_', ' ').trim();
+      noPHeads.add(ch);
+      // champ PDEPREL
+      ch = items[9].replace('_', ' ').trim();
+      pDepRels.add(ch);
+    }
+    static private boolean isPonct1(String ch) {
+      if (ch.length()!=1) return false;
+      return ".,;:)]}!?'".contains(ch);
+    }
+    static private boolean isPonct2(String ch) {
+      if (ch.length()!=1) return false;
+      return "([{'".contains(ch);
+    }
+    private void finPhrase(int noligne) throws CoNLLException {
+      for (Unite unit : units) corpus.addUniteLue(unit);
+      for (int i = 0; i<units.size(); i++) {
+        Unite unit = units.get(i);
+        String nohead = noHeads.get(i);
+        String deprel = depRels.get(i);
+        if (!nohead.equals("0")) {
+          Integer k = noTokenUnits.get(nohead);
+          if (k==null)
+            throw new CoNLLException("Erreur de numéro de token de HEAD : "
+                    +nohead+" sur l'une des lignes précédentes", noligne);
+          Relation rel = new Relation(TYPE_RELATION, units.get(i), units.get(k));
+          if (deprel.isEmpty())
+            throw new CoNLLException("Pas trouvé de DEP-REL"
+                    +" sur l'une des lignes précédentes", noligne);
+          rel.putProp(PROP_REL, deprel);
+          corpus.addRelationLue(rel);
+          nohead = noPHeads.get(i);
+          deprel = pDepRels.get(i);
+          if (!nohead.isEmpty()&&!nohead.equals("0")) {
+            k = noTokenUnits.get(nohead);
+            if (k==null)
+              throw new CoNLLException("Erreur de numéro de token de P-HEAD : "
+                      +nohead+" sur l'une des lignes précédentes", noligne);
+            rel = new Relation(TYPE_RELATION_PROJ, units.get(i), units.get(k));
+            if (deprel.isEmpty())
+              throw new CoNLLException("Pas trouvé de P-DEP-REL"
+                      +" sur l'une des lignes précédentes", noligne);
+            rel.putProp(PROP_REL, deprel);
+            corpus.addRelationLue(rel);
+          }
+        }
+      }
+      units.clear();
+      noTokenUnits.clear();
+      noHeads.clear();
+      depRels.clear();
+      noPHeads.clear();
+      pDepRels.clear();
+    }
+    private void finDocument(int noligne) throws IOException {
+      finPhrase(noligne);
+      texte = texte.trim();
+      corpus.setTexte(texte);
+      corpus.addFinParagraphe(texte.length());
+    }
+
+    static class CoNLLException extends IOException {
+      public CoNLLException(String ex, int noligne) {
+        super("Erreur de syntaxe ligne "+noligne+" :\n"+ex);
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersCoNLL.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTexte.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTexte.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTexte.java	(revision 481)
@@ -0,0 +1,283 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.awt.*;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.text.rtf.*;
+import visuAnalec.PanneauEditeur;
+import visuAnalec.donnees.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public abstract class FichiersTexte {
+  public static void importerTexte(Corpus corpus) {
+    BufferedReader fluxIn = null;
+    File fichier;
+    GCodage codage = new GCodage();
+    if ((fichier = Fichiers.choisirFichier(Commande.OUVRIR,
+            "Choix du corpus", Fichiers.TypeFichier.TEXTE, codage.getContenant())) == null) return;
+    String code = codage.getCode();
+    try {
+      fluxIn = new BufferedReader(new InputStreamReader(new FileInputStream(fichier), code));
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, "Codage de caractères non pris en charge : " + code,
+              "Erreur d'ouverture de fichier texte", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'ouverture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    }
+    try {
+      corpus.lireTexte(fluxIn);
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      try {
+        if (fluxIn != null) fluxIn.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier lu", JOptionPane.ERROR_MESSAGE);
+        return;
+      }
+    }
+  }
+  public static void exporterTexteRTF(PanneauEditeur pEditeur) {
+    FileOutputStream fluxOut = null;
+    FiltreCorrectionRTFOutputStream filtre = null;
+    File fichierCorpus;
+    if ((fichierCorpus = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier texte", Fichiers.TypeFichier.TEXTE_RTF)) == null) return;
+    try {
+      fluxOut = new FileOutputStream(fichierCorpus);
+      filtre = new FiltreCorrectionRTFOutputStream(fluxOut);
+      Document doc = pEditeur.getTexteFormate();
+      RTFEditorKit editeur = new RTFEditorKit();
+      editeur.write(filtre, doc, 0, doc.getLength());
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (BadLocationException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      if (fluxOut != null) try {
+          fluxOut.close();
+        } catch (IOException ex) {
+          JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+  }
+
+  private static class FiltreCorrectionRTFOutputStream extends FilterOutputStream {
+    // Note: Windows versions of Word have never supported \cbN, 
+    //but it can be emulated by the control word sequence 
+    // \chshdng0\chcbpatN.
+    private final static char[] CodeCouleurFondcorrect = "\\chshdng0\\chcbpat".toCharArray();
+    private final static char[] CodeUnicodecorrect = "\\'".toCharArray();
+    private int etat;
+    private int[] buffer;
+    private int pt = 0;
+    private FiltreCorrectionRTFOutputStream(OutputStream out) {
+      super(out);
+      pt = etat = 0;
+      buffer = new int[10];
+    }
+    @Override
+    public void write(int car) throws IOException {
+      switch (etat) {
+        case 0:
+          if (car == '\\') {
+            buffer[pt++] = car;
+            etat = 1;
+          } else out.write(car);
+          return;
+        case 1:
+          if (car == 'c') {  // debut d'une couleur de fond : etats 2, 3, 4
+            buffer[pt++] = car;
+            etat = 2;
+          } else if (car == 'u') {  // début d'un caractère unicode non décodé : etats 5, 6
+            buffer[pt++] = car;
+            etat = 5;
+          } else raz(car);
+          return;
+        case 2:
+          if (car == 'b') {
+            buffer[pt++] = car;
+            etat = 3;
+
+          } else raz(car);
+          return;
+        case 3:
+          if (car >= '0' && car <= '9') {
+            buffer[pt++] = car;
+            etat = 4;
+          } else raz(car);
+          return;
+        case 4:
+          if (car >= '0' && car <= '9') buffer[pt++] = car;
+          else correctionCouleurFond(car);
+          return;
+        case 5:
+          if (car >= '0' && car <= '9') {
+            buffer[pt++] = car;
+            etat = 6;
+          } else raz(car);
+          return;
+        case 6:
+          if (car >= '0' && car <= '9') buffer[pt++] = car;
+          else if (car == ' ') etat = 7;
+          else raz(car);
+          return;
+        case 7:
+          if (car == '?') correctionUnicode();
+          else raz(car);
+          return;
+        default:
+          throw new UnsupportedOperationException("Etat " + etat + " non prévu");
+      }
+    }
+    private void raz(int b) throws IOException {
+      for (int pt0 = 0; pt0 < pt; pt0++) out.write(buffer[pt0]);
+      pt = etat = 0;
+      write(b);
+    }
+    private void correctionCouleurFond(int b) throws IOException {
+      for (int c : CodeCouleurFondcorrect) out.write(c);
+      for (int pt0 = 3; pt0 < pt; pt0++) out.write(buffer[pt0]);
+      pt = etat = 0;
+      write(b);
+    }
+    private void correctionUnicode() throws IOException {
+      for (int c : CodeUnicodecorrect) out.write(c);
+      int n = 0;
+      for (int pt0 = 2; pt0 < pt; pt0++) n = 10 * n + (buffer[pt0] - '0');
+      String nhex = Integer.toHexString(n % 256);
+      if (nhex.length() == 1) out.write('0');
+      out.write(nhex.charAt(0));
+      if (nhex.length() == 2) out.write(nhex.charAt(1));
+      pt = etat = 0;
+    }
+  }
+  public static void exporterTexteHTML(PanneauEditeur pEditeur) {
+    FileWriter fluxOut = null;
+//   FiltreCorrectionRTFOutputStream filtre = null;
+    File fichierCorpus;
+    if ((fichierCorpus = Fichiers.choisirFichier(Commande.ENREGISTRER,
+            "Nom du fichier texte", Fichiers.TypeFichier.TEXTE_HTML)) == null) return;
+    try {
+      fluxOut = new FileWriter(fichierCorpus);
+      Document doc = pEditeur.getTexteFormate();
+      HTMLWriterCorrige htmlWriter = new HTMLWriterCorrige(fluxOut, (StyledDocument) doc);
+      htmlWriter.write();
+    } catch (FileNotFoundException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (UnsupportedEncodingException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (IOException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } catch (BadLocationException ex) {
+      JOptionPane.showMessageDialog(null, ex, "Erreur d'encodage de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      if (fluxOut != null)
+        try {
+          fluxOut.close();
+        } catch (IOException ex) {
+          JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture de fichier", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+  }
+
+  private static class HTMLWriterCorrige extends AbstractWriter {
+    public HTMLWriterCorrige(Writer w, StyledDocument doc) {
+      super(w, doc);
+    }
+    @Override
+    protected void write() throws IOException, BadLocationException {
+      write("<html>\n");
+      ElementIterator it = getElementIterator();
+      Element elt;
+      it.first();  // le premier (la racine) n'a pas l'info intéressante)
+      if((elt = it.next()) != null) writeTagBody(elt.getAttributes());
+      while(elt!=null) {
+        if (elt.isLeaf()) {
+          writeSpan(elt.getAttributes(), getText(elt));
+        }
+        elt = it.next();
+      }       
+      write("</body>\n");
+      write("</html>\n");
+    }
+    private void writeTagBody(AttributeSet attr) throws IOException {
+      write("<body style=\" ");
+      write("font-family: " + StyleConstants.getFontFamily(attr));
+      write("; font-size: " + StyleConstants.getFontSize(attr) + "pt");
+      write("; font-style: " + (StyleConstants.isItalic(attr) ? "italic" : "normal"));
+      write("; font-weight: " + (StyleConstants.isBold(attr) ? "bold" : "normal"));
+      write("; text-decoration: " + (StyleConstants.isUnderline(attr) ? "underline" : "none"));
+      write("; color: ");
+      writeColor(StyleConstants.getForeground(attr));
+      write("; background-color: ");
+      writeColor(StyleConstants.getBackground(attr));
+      write("\">\n");
+    }
+    private void writeSpan(AttributeSet attr, String texte) throws IOException {
+      write("<span style=\" ");
+      write("; font-style: " + (StyleConstants.isItalic(attr) ? "italic" : ""));
+      write("; font-weight: " + (StyleConstants.isBold(attr) ? "bold" : ""));
+      write("; text-decoration: " + (StyleConstants.isUnderline(attr) ? "underline" : ""));
+      write("; color: ");
+      writeColor(StyleConstants.getForeground(attr));
+      write("; background-color: ");
+      writeColor(StyleConstants.getBackground(attr));
+      write("\">");
+      for(int i=0; i<texte.length(); i++) writeCar(texte.charAt(i));
+      write("</span>\n");
+    }
+    private void writeColor(Color couleur) throws IOException {
+      write('#');
+      String str = Integer.toHexString(couleur.getRed() % 256);
+      if (str.length() == 1) write('0');
+      write(str.charAt(0));
+      if (str.length() == 2) write(str.charAt(1));
+      str = Integer.toHexString(couleur.getGreen() % 256);
+      if (str.length() == 1) write('0');
+      write(str.charAt(0));
+      if (str.length() == 2) write(str.charAt(1));
+      str = Integer.toHexString(couleur.getBlue() % 256);
+      if (str.length() == 1) write('0');
+      write(str.charAt(0));
+      if (str.length() == 2) write(str.charAt(1));
+    }
+
+  private void writeCar(char car) throws IOException {
+    switch(car) {
+      case '\n': write("<p>"); return;
+      case '"': write("&quot;");return;
+      case'<': write("&lt;");return;
+      case'>': write("&gt;");return;
+      default:
+        if(car>128) write("&#"+(car%256)+";");
+        else write(car);
+    }   
+   }   
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersTexte.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersSyntex.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersSyntex.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersSyntex.java	(revision 481)
@@ -0,0 +1,152 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.fichiers;
+
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.donnees.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.util.Fichiers.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class FichiersSyntex {
+  public static void importerSyntex(Corpus corpus) {
+    BufferedReader analyse = null;
+    File fichierCorpus;
+    GCodage codage = new GCodage();
+    if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR, "Choix du fichier de résultats d'analyse syntaxique",
+            Fichiers.TypeFichier.SYNTEX, codage.getContenant())) == null) return;
+    String code = codage.getCode();
+    int cadence = 1; 
+    try {
+      analyse = new BufferedReader(new InputStreamReader(new FileInputStream(fichierCorpus), code));
+      SyntexParser sp = new SyntexParser(corpus);
+      sp.parser(analyse, cadence);
+      corpus.newCorpusLu();
+    } catch (IOException ex) {
+      corpus.fermer();
+      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+      return;
+    } finally {
+      try {
+        if (analyse != null) analyse.close();
+      } catch (IOException ex) {
+        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
+      }
+    }
+  }
+
+  static class SyntexParser {
+    Corpus corpus;
+    String texte;
+    SyntexParser(Corpus corpus) {
+      this.corpus = corpus;
+      texte = "";
+    }
+    private void parser(BufferedReader anasynt, int cadence) throws IOException {
+      String ligne;
+      int natLigne = 0;
+      int nophr = 0;
+      Schema phr = null;
+      String txt = null;
+      while ((ligne = anasynt.readLine()) != null) {
+        if (ligne.trim().isEmpty()) continue;
+        switch (natLigne) {
+          case 0:
+            phr = parserSEQ(ligne);
+            break;
+          case 1:
+            txt = parserTXT(ligne);
+            texte += txt;
+            corpus.addFinParagraphe(texte.length());
+            break;
+          case 2:
+            if (++nophr % cadence == 0) {
+              parserETIQ(ligne, phr, texte.length() - txt.length());
+            }
+            break;
+        }
+        natLigne = ++natLigne % 3;
+      }
+      if (natLigne > 0) throw new IOException("Fin de fichier prématurée");
+      corpus.setTexte(texte);
+    }
+    private Schema parserSEQ(String ligne) throws IOException {
+      if (!ligne.startsWith("<SEQ id=")) throw new IOException("SEQ attendu ligne :\n" + ligne);
+      Schema phr = new Schema("Phrase");
+      phr.putProp("id", ligne.substring(8, ligne.indexOf(';')));
+      return phr;
+    }
+    private String parserTXT(String ligne) throws IOException {
+      if (!ligne.startsWith("<TXT>")) throw new IOException("TXT attendu ligne :\n" + ligne);
+      return supBlancs(ligne.substring(5));
+    }
+    private String supBlancs(String txt) {
+      return txt.replaceAll("([\\'\\(\\-\\{\\[]) ", "$1").replaceAll(" ([\\.\\,\\-\\)\\%\\}\\]])", "$1");
+    }
+    private void parserETIQ(String ligne, Schema phr, int offset) throws IOException {
+      if (!ligne.startsWith("<ETIQ>")) throw new IOException("ETIQ attendu ligne :\n" + ligne);
+      String[] etiqs = ligne.substring(6).split("\t");
+      Unite[] units = new Unite[etiqs.length];
+      for (int i = 0; i < units.length; i++) units[i] = new Unite();
+      ArrayList<Relation> rels = new ArrayList<Relation>();
+      for (int i = 0; i < units.length; i++) {
+        String[] data = etiqs[i].split("\\|", -1);
+        if (data.length < 5) throw new IOException("Nombre de champs insuffisant pour " + etiqs[i]);
+        if (Integer.parseInt(data[3]) != i + 1) throw new IOException("Problème de numérotation pour " + etiqs[i]);
+        data[2] = supBlancs(data[2]);
+        while (texte.charAt(offset) == ' ') offset++;
+        if (!texte.startsWith(data[2], offset)) throw new IOException("Attendu : " + data[2] +
+                  " au début de la chaîne\n" + texte.substring(offset));
+        units[i].setType(typeSyntex(data[0]));
+        units[i].setDeb(offset);
+        units[i].setFin(offset += data[2].length());
+        units[i].putProp("Catégorie Syntex", data[0]);
+        units[i].putProp("Lemme", data[1]);
+        if (data[4].isEmpty()) continue;
+        String[] ascs = data[4].split(",");
+        for (String asc : ascs) {
+          String[] dataAsc = asc.split(";");
+          int noAsc = Integer.parseInt(dataAsc[1]);
+          if (noAsc <= 0 || noAsc > units.length)
+            throw new IOException("Problème de numérotation pour l'ascendant de " + etiqs[i]);
+          Relation rel = new Relation("Dépendance", units[i], units[noAsc - 1]);
+          rel.putProp("Fonction syntex", dataAsc[0]);
+          rels.add(rel);
+        }
+      }
+      for (Unite unit : units) {
+        corpus.addUniteLue(unit);
+        phr.ajouter(unit);
+      }
+      for (Relation rel : rels) {  
+        corpus.addRelationLue(rel);
+        phr.ajouter(rel);
+      }
+      corpus.addSchemaLu(phr);
+    }
+    private String typeSyntex(String catSyntex) throws IOException {
+      if (catSyntex.startsWith("Adj")) return "Adjectif";
+      if (catSyntex.startsWith("Adv")) return "Adverbe";
+      if (catSyntex.startsWith("CCoord") || catSyntex.startsWith("TypoCoord")) return "Coordonnant";
+      if (catSyntex.equals("CSub")) return "Subordonnant";
+      if (catSyntex.startsWith("Det")) return "Déterminant";
+      if (catSyntex.equals("Elim")) return "Interjection";
+      if (catSyntex.startsWith("Nom") || catSyntex.equals("NUM")) return "Nom";
+      if (catSyntex.startsWith("Pp") || catSyntex.startsWith("V")) return "Verbe";
+      if (catSyntex.startsWith("Prep")) return "Préposition";
+      if (catSyntex.equals("Pro")) return "Pronom";
+      if (catSyntex.equals("ProRel")) return "Relatif";
+      if (catSyntex.equals("Typo")) return "Ponctuation";
+      throw new IOException("Catégorie syntex non reconnue : " + catSyntex);
+    }
+  }
+}
+  

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/fichiers/FichiersSyntex.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/util/Tableaux.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/util/Tableaux.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/util/Tableaux.java	(revision 481)
@@ -0,0 +1,86 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.util;
+
+import java.util.*;
+import visuAnalec.elements.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public abstract class Tableaux {
+  public static int compterValeursVraies(boolean[] bls) {
+    int nb = 0;
+    for(boolean b: bls) if(b) nb++;
+    return nb;
+  }
+  public static String[] insererString(String[] strs, String str) {
+    // renvoie un tableau trié
+    String[] strs1 = insererStringEnTete(strs, str);
+    Arrays.sort(strs1);
+    return strs1;
+  }
+  public static String[] insererStringEnTete(String[] strs, String str) {
+    String[] strs1 = new String[strs.length + 1];
+    System.arraycopy(strs, 0, strs1, 1, strs.length);
+    strs1[0] = str;
+    return strs1;
+  }
+  static String[] oterString(String[] strs, String str) {
+    // strs doit être triée
+    int ind = Arrays.binarySearch(strs, str);
+    if (ind < 0) return strs;
+    return oterString(strs, ind);
+  }
+  public static String[] oterString(String[] strs, int ind) {
+    String[] strs1 = new String[strs.length - 1];
+    System.arraycopy(strs, 0, strs1, 0, ind);
+    System.arraycopy(strs, ind + 1, strs1, ind, strs.length - ind - 1);
+    return strs1;
+  }
+  public static String[] oterStrings(String[] strs, ArrayList<Integer> inds) {
+    //  inds doit être croissant
+    String[] strs1 = new String[strs.length - inds.size()];
+    inds.add(strs.length);
+    System.arraycopy(strs, 0, strs1, 0, inds.get(0));
+    for (int i = 1; i < inds.size(); i++)
+      System.arraycopy(strs, inds.get(i - 1) + 1, strs1, inds.get(i - 1) - i + 1, inds.get(i) - inds.get(i - 1) - 1);
+    return strs1;
+  }
+//  public static String[][] oterStrings(String[][] strs, ArrayList<Integer> inds1, ArrayList<Integer> inds2) {
+//    //  inds1 et inds2 doivent être de même taille
+//    String[] strs1 = new String[strs.length - inds.size()];
+//    inds.add(strs.length);
+//    System.arraycopy(strs, 0, strs1, 0, inds.get(0));
+//    for (int i = 1; i < inds.size(); i++)
+//      System.arraycopy(strs, inds.get(i - 1) + 1, strs1, inds.get(i - 1) - i + 1, inds.get(i) - inds.get(i - 1) - 1);
+//    return strs1;
+//  }
+  public static Element[] insererElementEnTete(Element[] elts, Element elt) {
+    Element[] elts1 = new Element[elts.length + 1];
+    System.arraycopy(elts, 0, elts1, 1, elts.length);
+    elts1[0] = elt;
+    return elts1;
+  }
+  public static Element[] oterElements(Element[] elts, ArrayList<Integer> inds) {
+    //  inds doit être croissant
+    Element[] elts1 = new Element[elts.length - inds.size()];
+    inds.add(elts.length);
+    System.arraycopy(elts, 0, elts1, 0, inds.get(0));
+    for (int i = 1; i < inds.size(); i++)
+      System.arraycopy(elts, inds.get(i - 1) + 1, elts1, inds.get(i - 1) - i + 1, inds.get(i) - inds.get(i - 1) - 1);
+    return elts1;
+  }
+  public static Relation[] oterRelations(Relation[] elts, ArrayList<Integer> inds) {
+    //  inds doit être croissant
+    Relation[] elts1 = new Relation[elts.length - inds.size()];
+    inds.add(elts.length);
+    System.arraycopy(elts, 0, elts1, 0, inds.get(0));
+    for (int i = 1; i < inds.size(); i++)
+      System.arraycopy(elts, inds.get(i - 1) + 1, elts1, inds.get(i - 1) - i + 1, inds.get(i) - inds.get(i - 1) - 1);
+    return elts1;
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/util/Tableaux.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/util/Fichiers.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/util/Fichiers.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/util/Fichiers.java	(revision 481)
@@ -0,0 +1,327 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.util;
+
+import java.awt.*;
+import java.beans.*;
+import java.io.*;
+import java.util.*;
+import java.util.prefs.Preferences;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.filechooser.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public abstract class Fichiers {
+  public enum TypeFichier {
+    DOC_ANALEC("Document Analec", "ec"),
+    CORPUS_ANALEC("Fichiers Analec", "ec"),
+    STRUCTURE("Structure Analec", "ecs"),
+    VUE("Vue Analec", "ecv"),
+    TABLEUR_STATS("Tableur format texte (séparateur : tabulation)", "txt"),
+    GRAPHIQUE_SVG("Graphique vectoriel format svg", "svg"),
+    GRAPHIQUE_EMF("Graphique vectoriel format emf", "emf"),
+    GLOZZ_CORPUS("Corpus Glozz", "ac"),
+    GLOZZ_ANNOT("Annotations Glozz", "aa"),
+    GLOZZ_MODELE("Modèle Glozz", "aam"),
+    SYNTEX("Résultats Syntex", "anasynt"),
+    TABLEUR_ENONCES("Table des énoncés", "txt"),
+    TABLEUR_ANNOT("Table des annotations", "txt"),
+    TEI("Corpus format TEI", "xml"),
+    RHAPS("Corpus Rhapsodie format tabulaire", "tabular"),
+    CONLL("Document format CoNLL", "out"),
+    TEXTE("Texte brut", "txt"),
+    TEXTE_RTF("Texte format RTF", "rtf"),
+    TEXTE_HTML("Texte format HTML", "html");
+    String ext;
+    String nom;
+    TypeFichier(String nom, String ext) {
+      this.nom = nom;
+      this.ext = ext;
+    }
+    public String getNom() {
+      return nom;
+    }
+    public String getExtension() {
+      return ext;
+    }
+    public boolean importCorpus() {
+      return EnumSet.of(TypeFichier.TEXTE, TypeFichier.GLOZZ_CORPUS, TypeFichier.SYNTEX).contains(this);
+    }
+    public boolean resultats() {
+      return EnumSet.of(TypeFichier.TABLEUR_STATS, TypeFichier.GRAPHIQUE_SVG, TypeFichier.GRAPHIQUE_EMF).contains(this);
+    }
+  }
+
+  public enum Commande {
+    OUVRIR("Ouvrir"),
+    ENREGISTRER("Enregistrer");
+    String label;
+    Commande(String label) {
+      this.label = label;
+    }
+    public String getLabel() {
+      return label;
+    }
+  }
+
+  public static class FiltreExt implements java.io.FileFilter {
+    private TypeFichier type;
+    public FiltreExt(TypeFichier type) {
+      this.type = type;
+    }
+    public boolean accept(File fic) {
+      return type.getExtension().equals(getExtension(fic));
+    }
+  }
+  // Variables de classe
+  private static Preferences pref = Preferences.userNodeForPackage(Fichiers.class);
+  private static File repertoireCourantCorpus = new File(pref.get("repertoire", System.getProperty("user.dir")));
+  private static EnumMap<TypeFichier, File> fichiersCourants = new EnumMap<TypeFichier, File>(TypeFichier.class);
+  static {
+    String nomfic = pref.get("nomCorpus", "");
+    if (!nomfic.isEmpty())
+      fichiersCourants.put(TypeFichier.DOC_ANALEC, new File(repertoireCourantCorpus, nomfic+'.'+TypeFichier.DOC_ANALEC.getExtension()));
+  }
+  public static File trouverFichier(TypeFichier type, String nomFichier) {
+    File fichier = new File(repertoireCourantCorpus, nomFichier);
+    if (!getExtension(fichier).equals(type.getExtension()))
+      fichier = changerExtension(fichier, type.getExtension());
+    if (!fichier.exists()) return null;
+    majFichiersCourants(type, fichier);
+    return fichier;
+  }
+  public static File trouverFichier(TypeFichier type, File oldfichier) {
+    File fichier = changerExtension(oldfichier, type.getExtension());
+    if (!fichier.exists()) return null;
+    majFichiersCourants(type, fichier);
+    return fichier;
+  }
+  public static File creerFichier(File rep, TypeFichier type, File oldfichier) {
+    return ajouterExtension(new File(rep, extraireNom(oldfichier)), type.getExtension());
+  }
+  public static File creerFichier(File rep, TypeFichier type, String nom) {
+    return ajouterExtension(new File(rep, nom), type.getExtension());
+  }
+  public static File getRepertoireCourant(TypeFichier type) {
+    if (fichiersCourants.containsKey(type))
+      return fichiersCourants.get(type).getParentFile();
+    return repertoireCourantCorpus;
+  }
+  public static File getFichierCourant(TypeFichier type) {
+    if (fichiersCourants.containsKey(type)) return fichiersCourants.get(type);
+    return null;
+  }
+  public static String getNomFichierCourant(TypeFichier type) {
+    if (fichiersCourants.containsKey(type))
+      return extraireNom(fichiersCourants.get(type));
+    return "";
+  }
+  public static void removeFichierCourant(TypeFichier type) {
+    fichiersCourants.remove(type);
+  }
+  private static void majFichiersCourants(TypeFichier type, File fichier) {
+    fichiersCourants.put(type, fichier);
+    if (type==TypeFichier.GLOZZ_CORPUS) {
+      fichiersCourants.put(TypeFichier.GLOZZ_ANNOT, changerExtension(fichier, TypeFichier.GLOZZ_ANNOT.ext));
+      fichiersCourants.put(TypeFichier.GLOZZ_MODELE, changerExtension(fichier, TypeFichier.GLOZZ_MODELE.ext));
+    }
+    if (type==TypeFichier.DOC_ANALEC) {
+      repertoireCourantCorpus = fichier.getParentFile();
+      pref.put("repertoire", repertoireCourantCorpus.getPath());
+      pref.put("nomCorpus", extraireNom(fichier));
+    }
+
+  }
+  // Utilitaires de manipulation de noms de fichiers
+  private static File ajouterExtension(File fichier, String extension) {
+    String nom = fichier.getName();
+    return new File(fichier.getParentFile(), nom+"."+extension);
+  }
+  private static File changerExtension(File fichier, String extension) {
+    String nom = fichier.getName();
+    int ind = nom.lastIndexOf('.');
+    if (ind>=0) nom = nom.substring(0, ind);
+    return new File(fichier.getParentFile(), nom+"."+extension);
+  }
+  public static String extraireNom(File fichier) {
+    if (fichier==null) return null;
+    String nom = fichier.getName();
+    int ind = nom.lastIndexOf('.');
+    if (ind<0) return nom;
+    else return nom.substring(0, ind);
+  }
+  private static String getExtension(File fichier) {
+    String nom = fichier.getName();
+    int ind = nom.lastIndexOf('.');
+    if (ind>=0) return nom.substring(ind+1);
+    return "";
+  }
+  public static File[] listerFichiers(File rep, TypeFichier type) {
+    return rep.listFiles(new FiltreExt(type));
+  }
+  public static boolean existeDebutFichier(File rep, TypeFichier type, 
+          String debut) {
+    File[] fics = listerFichiers(rep, type);
+    for (int i = 0; i<fics.length; i++) 
+      if(extraireNom(fics[i]).startsWith(debut)) return true;
+    return false;
+  }
+  // Choix des fichiers
+  public static File choisirFichier(Commande commande, String titre, TypeFichier type) {
+    return choisirFichier(commande, titre, type, null);
+  }
+  public static File choisirFichier(Commande commande, String titre, TypeFichier type, JComponent complement) {
+    JFileChooser choixFichier = new JFileChooser();
+    choixFichier.resetChoosableFileFilters();
+    choixFichier.setFileFilter(new FileNameExtensionFilter(type.getNom(), type.getExtension()));
+    choixFichier.setDialogTitle(titre);
+    if (complement!=null) choixFichier.setAccessory(complement);
+    choixFichier.setCurrentDirectory(getRepertoireCourant(type));
+    File fichierPropose;
+    if (type.resultats()) {
+      String nom = extraireNom(getFichierCourant(TypeFichier.DOC_ANALEC));
+      if (nom==null) fichierPropose = null;
+      else fichierPropose = new File(getRepertoireCourant(type), nom+"_res");
+    } else {
+      fichierPropose = getFichierCourant(type);
+    }
+    if (fichierPropose!=null) {
+      if (commande==Commande.OUVRIR&&!fichierPropose.exists()) {
+        fichierPropose = new File(getRepertoireCourant(type), "*."+type.getExtension());
+      }
+      choixFichier.setSelectedFile(fichierPropose);
+    }
+    int reponse = choixFichier.showDialog(null, commande.getLabel());
+    if (reponse!=JFileChooser.APPROVE_OPTION) return null;
+    File fichierChoisi = choixFichier.getSelectedFile();
+    if (commande==Commande.ENREGISTRER) {
+      if (!getExtension(fichierChoisi).equals(type.getExtension()))
+        fichierChoisi = ajouterExtension(fichierChoisi, type.getExtension());
+      if (fichierChoisi.exists()) {
+        int rep = JOptionPane.showOptionDialog(null, "Remplacer "+fichierChoisi.getName()+" ?",
+                "Fichier existant", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+                null, new Object[]{"Remplacer", "Annuler"}, "Remplacer");
+        if (rep==1) return null;
+      }
+    }
+    majFichiersCourants(type, fichierChoisi);
+    if (commande==Commande.OUVRIR&&type.importCorpus())
+      fichiersCourants.remove(TypeFichier.DOC_ANALEC);
+    return fichierChoisi;
+  }
+  public static File choisirRepertoire(String titre) {
+    JFileChooser choixRep = new JFileChooser();
+    choixRep.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+    choixRep.setAcceptAllFileFilterUsed(false);
+    choixRep.setFileFilter(new FileNameExtensionFilter("Répertoire", "*"));
+    choixRep.setDialogTitle(titre);
+    choixRep.setCurrentDirectory(repertoireCourantCorpus);
+    int reponse = choixRep.showDialog(null, "Sélectionner");
+    if (reponse!=JFileChooser.APPROVE_OPTION) return null;
+    return choixRep.getSelectedFile();
+  }
+  public static File[] choisirCorpus(String titre, TypeFichier type) {
+    JFileChooser choixFichier = new JFileChooser();
+    FilesystemFilter filtre = new FilesystemFilter(type.getExtension(), "", false);
+    choixFichier.addPropertyChangeListener(new SelectFics(choixFichier, filtre));
+    choixFichier.resetChoosableFileFilters();
+    choixFichier.setFileFilter(new FileNameExtensionFilter(
+            type.getNom(), type.getExtension()));
+    choixFichier.setDialogTitle(titre);
+    choixFichier.setMultiSelectionEnabled(true);
+    File rep = getRepertoireCourant(type);
+    choixFichier.setCurrentDirectory(rep);
+    int reponse = choixFichier.showDialog(null, "Choisir");
+    if (reponse!=JFileChooser.APPROVE_OPTION) return new File[0];
+    File[] fics = choixFichier.getSelectedFiles();
+    if (fics==null||fics.length==0) return new File[0];
+    majFichiersCourants(TypeFichier.CORPUS_ANALEC, fics[0]);
+    return fics;
+  }
+
+  static class FilesystemFilter extends javax.swing.filechooser.FileFilter
+          implements FilenameFilter {
+    private String[] extensions;
+    private String description;
+    private boolean accepteReps;
+    public FilesystemFilter(String extension, String description,
+            boolean accepteReps) {
+      this(new String[]{extension}, description, accepteReps);
+    }
+    public FilesystemFilter(String[] extensions, String description,
+            final boolean accepteReps) {
+      this.extensions = extensions;
+      this.description = description;
+      this.accepteReps = accepteReps;
+    }
+    public boolean accept(File rep, String nom) {
+      return accept(new File(rep, nom));
+    }
+    public boolean accept(final File fic) {
+      if (fic.isDirectory()&&accepteReps) return true;
+      for (int i = 0; i<this.extensions.length; i++)
+        if (fic.getName().endsWith(this.extensions[i])) return true;
+      return false;
+    }
+    public String getDescription() {
+      return this.description;
+    }
+ }
+ public static class SelectFics implements PropertyChangeListener{
+    JFileChooser choix;
+    FilesystemFilter filtre;
+    SelectFics(JFileChooser choix, FilesystemFilter filtre) {
+      this.choix = choix;
+      this.filtre = filtre;
+    }
+    @Override
+       public void propertyChange(PropertyChangeEvent e) {
+        if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(e.getPropertyName())) {
+           choix.setSelectedFiles(choix.getCurrentDirectory().listFiles(filtre));
+        }
+    }
+  }
+
+  public static class GCodage {
+    JPanel contenant;
+    JComboBox saisieCodage;
+    public GCodage() {
+      saisieCodage = new JComboBox(new String[]{
+                "Microsoft (windows-1252)",
+                "UTF-8 (unicode 8 bits)",
+                "UTF-16 (unicode 16 bits)",
+                "ISO-8859-1 (latin-1)",
+                "<autre (à saisir)>"
+              });
+      saisieCodage.setEditable(true);
+      saisieCodage.setSelectedIndex(0);
+      contenant = new JPanel(new BorderLayout());
+      contenant.setBorder(new TitledBorder("Codage des caractères"));
+      contenant.add(saisieCodage, BorderLayout.NORTH);
+      contenant.add(new JPanel(), BorderLayout.CENTER);
+    }
+    public JComponent getContenant() {
+      return contenant;
+    }
+    public String getCode() {
+      switch (saisieCodage.getSelectedIndex()) {
+        case 0:
+          return "windows-1252";
+        case 1:
+          return "UTF-8";
+        case 2:
+          return "UTF-16";
+        case 3:
+          return "ISO-8859-1";
+        default:
+          return (String) saisieCodage.getSelectedItem();
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/util/Fichiers.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/util/GVisu.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/util/GVisu.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/util/GVisu.java	(revision 481)
@@ -0,0 +1,512 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.util;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.ArrayList;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.GMessages.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public abstract class GVisu {
+  public static class TitreBarre extends JLabel {
+    public TitreBarre(String titre) {
+      super(titre);
+    }
+    public TitreBarre(String titre, Color couleur) {
+      super(titre);
+      setOpaque(true);
+      setBackground(couleur);
+    }
+  }
+
+  public static abstract class Boutons {
+    public static void setDefaut(JButton bouton, boolean oui) {
+      ((JFrame) bouton.getTopLevelAncestor()).getRootPane().setDefaultButton(oui ? bouton : null);
+      if (oui) bouton.requestFocusInWindow();
+    }
+  }
+  public static String styleIdPopup(String texte, String id) {
+    if (texte.length()>35)
+      texte = texte.substring(0, 18)+" [...] "+texte.substring(texte.length()-8);
+    return "<html>"+id+" (<span style=\"font-style:italic \">"+texte+"</span>)";
+  }
+  public static String styleIdTooltip(ArrayList<String> textes, ArrayList<String> ids) {
+    String tooltip = "<html>";
+    for (int i = 0; i<textes.size(); i++) {
+      String texte = textes.get(i);
+      if (texte.length()>35)
+        texte = texte.substring(0, 18)+" [...] "+texte.substring(texte.length()-8);
+      tooltip += "<p>"+ids.get(i)+" (<span style=\"font-style:italic \">"+texte+"</span>)";
+    }
+    return tooltip;
+  }
+  public static String styleDef(String nom) {
+    return "<html><span style=\"color:gray\"> &lt <span style=\"font-style:italic \">"
+            +nom+"</span> &gt";
+  }
+  private final static Font STYLE_COMBO = Font.decode("Arial plain 12");
+
+  public enum SensSpinnerBinaire {
+    SUIVANT, PRECEDENT
+  }
+
+  public static class ModeleSpinnerBinaire extends AbstractSpinnerModel {
+    private SensSpinnerBinaire sens;
+    public Object getValue() {
+      return sens;
+    }
+    public void setValue(Object value) {
+      sens = (SensSpinnerBinaire) value;
+      fireStateChanged();
+    }
+    public Object getNextValue() {
+      return SensSpinnerBinaire.PRECEDENT;
+    }
+    public Object getPreviousValue() {
+      return SensSpinnerBinaire.SUIVANT;
+    }
+  }
+  private static Dimension dimZero = new Dimension(20, 20);
+  private static Insets insetsZero = new Insets(0, 0, 0, 0);
+
+  public static class ElementComboBox extends Box implements ActionListener, ChangeListener {
+    private ArrayList<ActionListener> listeCorrespondants = new ArrayList<ActionListener>();
+    public JComboBox combo;
+    private JButton zero;
+    private JSpinner spin;
+    public Element[] elements;  // liste triée
+    public ElementComboBox() {
+      super(BoxLayout.X_AXIS);
+      zero = new JButton(new GAction("0") {
+        public void executer() {
+          effSelection();
+        }
+      });
+      zero.setMargin(insetsZero);
+      zero.setPreferredSize(dimZero);
+      spin = new JSpinner(new ModeleSpinnerBinaire());
+      spin.setEditor(new JLabel());
+      spin.addChangeListener(this);
+      combo = new JComboBox();
+      combo.setEditable(false);
+      combo.setFont(STYLE_COMBO);
+      combo.addActionListener(this);
+      add(combo);
+      add(spin);
+      add(zero);
+      setModeleVide();
+    }
+    public void addActionListener(ActionListener correspondant) {
+      listeCorrespondants.add(correspondant);
+    }
+    public void removeActionListener(ActionListener correspondant) {
+      listeCorrespondants.remove(correspondant);
+    }
+    public void actionPerformed(ActionEvent evt) {
+      try {
+        evt.setSource(this);
+        for (Object corresp : listeCorrespondants.toArray()) {
+          ((ActionListener) corresp).actionPerformed(evt);
+        }
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+    public void setModeleVide() {
+      combo.setModel(new DefaultComboBoxModel(new String[]{styleDef("identifiant")}));
+      elements = new Element[0];
+      setMaximumSize(getPreferredSize());
+    }
+    public void setModele(Element[] elts, String[] ids) {
+      // elts doit être trié et en correspondance avec ids
+      combo.setModel(new DefaultComboBoxModel(Tableaux.insererStringEnTete(ids, styleDef("identifiant"))));
+      elements = elts;
+      setMaximumSize(getPreferredSize());
+    }
+    public Element[] getElements() {
+      return elements;
+    }
+    public void gotoPrecedent() {
+      int index;
+      if ((index = combo.getSelectedIndex())==0) index = combo.getItemCount();
+      combo.setSelectedIndex(index-1);
+    }
+    public void gotoSuivant() {
+      int index = combo.getSelectedIndex()+1;
+      if (index==combo.getItemCount()) index = 0;
+      combo.setSelectedIndex(index);
+    }
+    public boolean pasdeSelection() {
+      return combo.getSelectedIndex()<1;
+    }
+    public Element getSelection() {
+      if (combo.getSelectedIndex()>0)
+        return elements[combo.getSelectedIndex()-1];
+      return null;
+    }
+    public void effSelection() {
+      combo.setSelectedIndex(0);
+    }
+    public void setSelection(Element elt) {
+      int no = Arrays.binarySearch(elements, elt);
+      if (no<0)
+        throw new ArrayIndexOutOfBoundsException("Element à sélectionner absent");
+      combo.setSelectedIndex(no+1);
+    }
+    public String getIdElement(Element elt) {
+      int no = Arrays.binarySearch(elements, elt);
+      if (no<0)
+        throw new ArrayIndexOutOfBoundsException("Element recherché absent");
+      return ((String) combo.getItemAt(no+1));
+
+    }
+    public void stateChanged(ChangeEvent e) {
+      try {
+        switch ((SensSpinnerBinaire) spin.getValue()) {
+          case SUIVANT:
+            gotoSuivant();
+            return;
+          case PRECEDENT:
+            gotoPrecedent();
+            return;
+        }
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+  }
+
+  public static class Val0ComboBox extends JComboBox {
+    private String[] vals;
+    private String val0;
+    public Val0ComboBox(String val0) {
+      super();
+      this.val0 = val0;
+      setEditable(false);
+      setFont(STYLE_COMBO);
+      setModeleVide();
+    }
+    public void setModeleVide() {
+      setModel(new DefaultComboBoxModel(new String[]{styleDef(val0)}));
+      vals = new String[0];
+      setMaximumSize(getPreferredSize());
+    }
+    public void setModele(String[] types) {
+      setModel(new DefaultComboBoxModel(Tableaux.insererStringEnTete(types, styleDef(val0))));
+      this.vals = types;
+      setMaximumSize(getPreferredSize());
+    }
+    public boolean pasdeSelection() {
+      return getSelectedIndex()<1;
+    }
+    public int nbItems() {
+      return vals.length;
+    }
+    public String getSelection() {
+      if (getSelectedIndex()>0) return vals[getSelectedIndex()-1];
+      return null;
+    }
+    public void effSelection() {
+      setSelectedIndex(0);
+    }
+    public void setSelection(String type) {
+      setSelectedItem(type);
+    }
+    public void setSelection(int i) {
+      setSelectedIndex(i+1);
+    }
+  }
+  public static String getNomClasse(Class<? extends Element> classe) {
+    if (classe==Element.class) return "élément";
+    else if (classe==Unite.class) return "unité";
+    else if (classe==Relation.class) return "relation";
+    else if (classe==Schema.class) return "schéma";
+    else
+      throw new UnsupportedOperationException("Sous-classe inconnue pour getNomClasse()");
+  }
+  public static String getNomDeClasse(Class<? extends Element> classe) {
+    if (classe==Element.class) return "d'élément";
+    else if (classe==Unite.class) return "d'unité";
+    else if (classe==Relation.class) return "de relation";
+    else if (classe==Schema.class) return "de schéma";
+    else
+      throw new UnsupportedOperationException("Sous-classe inconnue pour getNomTypedeClasse()");
+  }
+  public static String getNomDeLaClasse(Element elt) {
+    Class<? extends Element> classe = elt.getClass();
+    if (classe==Unite.class) return "de l'unité";
+    else if (classe==Relation.class) return "de la relation";
+    else if (classe==Schema.class) return "du schéma";
+    else
+      throw new UnsupportedOperationException("Sous-classe inconnue pour getNomTypedeClasse()");
+  }
+  public static Class<? extends Element> getClasse(String classeType) {
+    if (classeType==null) return null;
+    if (classeType.startsWith("REL-")) return Relation.class;
+    if (classeType.startsWith("SCH-")) return Schema.class;
+    return Unite.class;
+  }
+  public static String getType(String classeType) {
+    if (classeType==null) return null;
+    if (classeType.startsWith("REL-")) return classeType.substring(4);
+    if (classeType.startsWith("SCH-")) return classeType.substring(4);
+    return classeType;
+  }
+  private static String getClasseType(Class<? extends Element> classe, String type) {
+    if (classe==Unite.class) return type;
+    else if (classe==Relation.class) return "REL-"+type;
+    else if (classe==Schema.class) return "SCH-"+type;
+    else
+      throw new UnsupportedOperationException("Sous-classe inconnue pour getClasseType()");
+  }
+  public static String[] getClassesTypes(String[] typesUnit, String[] typesRel, String[] typesSch) {
+    String[] types = Arrays.copyOf(typesUnit, typesUnit.length+typesRel.length+typesSch.length);
+    for (int i = 0; i<typesRel.length; i++)
+      types[i+typesUnit.length] = "REL-"+typesRel[i];
+    for (int i = 0; i<typesSch.length; i++)
+      types[i+typesUnit.length+typesRel.length] = "SCH-"+typesSch[i];
+    return types;
+  }
+
+  public static class TypeComboBox extends Val0ComboBox {
+    private Class<? extends Element> classe;
+    public TypeComboBox(Class<? extends Element> classe) {
+      super("type "+getNomDeClasse(classe));
+      this.classe = classe;
+    }
+    @Override
+    public void setModele(String[] types) {
+      if (this.classe==Element.class)
+        throw new UnsupportedOperationException("pas pour la classe Element");
+      super.setModele(types);
+    }
+    public void setModele(String[] typesUnites, String[] typesRelations, String[] typesSchemas) {
+      if (this.classe!=Element.class)
+        throw new UnsupportedOperationException("uniquement pour la classe Element");
+      super.setModele(getClassesTypes(typesUnites, typesRelations, typesSchemas));
+    }
+    public String getTypeSelection() {
+      String classetype = getSelection();
+      if (classetype==null) return null;
+      if (classe==Element.class) return getType(classetype);
+      return classetype;
+    }
+    public Class<? extends Element> getClasseSelection() {
+      String classetype = getSelection();
+      if (classetype==null) return null;
+      if (classe==Element.class) return getClasse(classetype);
+      return classe;
+    }
+    public void setSelection(Class<? extends Element> classe, String type) {
+      if (this.classe!=Element.class)
+        throw new UnsupportedOperationException("uniquement pour la classe Element");
+      super.setSelection(getClasseType(classe, type));
+    }
+    @Override
+    public void setSelection(String type) {
+      if (this.classe==Element.class)
+        throw new UnsupportedOperationException("pas pour la classe Element");
+      super.setSelection(type);
+    }
+  }
+  private final static Color[] couleursEtNoirEtBlanc = new Color[]{Color.BLACK, Color.WHITE, Color.YELLOW,
+    Color.RED, Color.BLUE, Color.ORANGE, Color.GREEN, Color.CYAN, Color.MAGENTA, Color.PINK
+  };
+  private final static Color[] couleurs = new Color[]{Color.YELLOW, Color.RED, Color.BLUE,
+    Color.ORANGE, Color.GREEN, Color.CYAN, Color.MAGENTA, Color.PINK
+  };
+  public static Color[] getCouleursEtNoirEtBlanc() {
+    return couleursEtNoirEtBlanc;
+  }
+  public static Color getCouleur(int i) {
+    Color c = couleurs[i%couleurs.length];
+    for (int n = 0; n<i/couleurs.length; n++) {
+      float[] rgb = c.getRGBColorComponents(null);
+      c = new Color(0.499f+rgb[0]/3, 0.499f+rgb[1]/3, 0.499f+rgb[2]/3);
+    }
+    return c;
+  }
+  public static Color getCouleurSansValeur() {
+    return Color.LIGHT_GRAY;
+  }
+
+  public static class DisqueCouleurIcone implements Icon {
+    private Color couleur;
+    int rayon;
+    int marge;
+    public DisqueCouleurIcone(Color couleur, int rayon, int marge) {
+      this.couleur = couleur;
+      this.rayon = rayon;
+      this.marge = marge;
+    }
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+      if (couleur==null) {
+        g.setColor(Color.BLACK);
+        g.drawLine(x+3*marge, y+3*marge, x+2*rayon-marge, y+2*rayon-marge);
+        g.drawLine(x+3*marge, y+2*rayon-marge, x+2*rayon-marge, y+3*marge);
+      } else {
+        g.setColor(couleur);
+        g.fillOval(x+marge, y+marge, 2*rayon, 2*rayon);
+        g.setColor(Color.BLACK);
+        g.drawOval(x+marge, y+marge, 2*rayon, 2*rayon);
+      }
+    }
+    public int getIconWidth() {
+      return 2*rayon+2*marge;
+    }
+    public int getIconHeight() {
+      return 2*rayon+2*marge;
+    }
+  }
+
+  public static class LegendeLabel {
+    String texte;
+    Icon icone;
+    public LegendeLabel(String texte, Color couleur) {
+      this.texte = texte;
+      this.icone = new DisqueCouleurIcone(couleur, 6, 2);
+    }
+  }
+
+  public static class LegendeCellRenderer extends JLabel implements ListCellRenderer {
+    public LegendeCellRenderer() {
+      setIconTextGap(12);
+    }
+    public Component getListCellRendererComponent(JList list, Object value,
+            int index, boolean isSelected, boolean cellHasFocus) {
+      LegendeLabel label = (LegendeLabel) value;
+      setText(label.texte);
+      setIcon(label.icone);
+      return this;
+    }
+  }
+
+  public static class RectangleCouleurIcone implements Icon {
+    private Color couleur;
+    private int largeur;
+    private int hauteur;
+    private int marge;
+    private boolean select;
+    public RectangleCouleurIcone(Color couleur, int largeur, int hauteur, int marge, boolean select) {
+      this.couleur = couleur;
+      this.largeur = largeur;
+      this.hauteur = hauteur;
+      this.marge = marge;
+      this.select = select;
+    }
+    void setCouleur(Color c) {
+      couleur = c;
+    }
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+      g.setColor(couleur);
+      g.fillRect(x+marge, y+marge, largeur, hauteur);
+      if (select) {
+        g.setColor(Color.BLACK);
+        g.drawRect(x+marge, y+marge, largeur, hauteur);
+      }
+    }
+    public int getIconWidth() {
+      return largeur+2*marge;
+    }
+    public int getIconHeight() {
+      return hauteur+2*marge;
+    }
+  }
+
+  public static class CouleurCellRenderer extends JLabel implements ListCellRenderer, TableCellRenderer {
+    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
+            boolean cellHasFocus) {
+      if (index==list.getModel().getSize()-1||index<0) {
+        setText(index<0 ? "" : styleDef("autre"));
+        setIcon(null);
+      } else {
+        setText(null);
+        setIcon(new RectangleCouleurIcone((Color) value, 40, 10, 2, isSelected));
+      }
+      return this;
+    }
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+      setText(null);
+      setIcon(new RectangleCouleurIcone((Color) value, 80, 10, 2, true));
+      return this;
+    }
+  }
+
+  public static class CouleurComboBoxEditor implements ComboBoxEditor {
+    CouleurComboBox comboBox;
+    RectangleCouleurIcone icone;
+    JLabel editeur;
+    Color couleur;
+    public CouleurComboBoxEditor(CouleurComboBox cb) {
+      comboBox = cb;
+      editeur = new JLabel(icone = new RectangleCouleurIcone(null, 80, 10, 2, true));
+    }
+    public Component getEditorComponent() {
+      return editeur;
+    }
+    private void init(Color couleur) {
+      this.couleur = couleur;
+      icone.setCouleur(couleur);
+    }
+    public void setItem(Object anObject) {
+      if (anObject==null) {
+        Color c = JColorChooser.showDialog(editeur, "Choix de la couleur", couleur);
+        if (c!=null) couleur = c;
+      } else couleur = (Color) anObject;
+      icone.setCouleur(couleur);
+      comboBox.setSelectedItem(couleur);
+    }
+    public Object getItem() {
+      return couleur;
+    }
+    public void selectAll() {
+    }
+    public void addActionListener(ActionListener l) {
+    }
+    public void removeActionListener(ActionListener l) {
+    }
+  }
+
+  public static class CouleurComboBox extends JComboBox {
+    public CouleurComboBox(Color[] couleurs) {
+      super(couleurs);
+      addItem(null);
+      setRenderer(new CouleurCellRenderer());
+      setEditor(new CouleurComboBoxEditor(this));
+      setMaximumRowCount(couleurs.length+1);
+    }
+  }
+
+  public static class CouleurTableEditor extends AbstractCellEditor implements TableCellEditor, ActionListener {
+    private CouleurComboBox comboBox;
+    private Color couleur;
+    public CouleurTableEditor(Color[] couleurs) {
+      comboBox = new CouleurComboBox(couleurs);
+      comboBox.setEditable(true);
+      comboBox.addActionListener(this);
+    }
+    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+      couleur = (Color) value;
+      comboBox.getEditor().setItem(value);
+      return comboBox;
+    }
+    public Object getCellEditorValue() {
+      return couleur;
+    }
+    public void actionPerformed(ActionEvent e) {
+      couleur = (Color) comboBox.getSelectedItem();
+      fireEditingStopped();
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/util/GVisu.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/util/GMessages.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/util/GMessages.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/util/GMessages.java	(revision 481)
@@ -0,0 +1,99 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.util;
+
+import java.awt.event.*;
+import javax.swing.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class GMessages {
+  public static boolean confirmationAction(String texte) {
+    return (JOptionPane.showConfirmDialog(null, texte, "Confirmation d'action",
+            JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE)
+            !=JOptionPane.CANCEL_OPTION);
+  }
+
+  public static void pasImplemente() {
+    JOptionPane.showMessageDialog(null, "Désolé, cette fonctionnalité n'est pas encore implémentée",
+            "Patience...", JOptionPane.INFORMATION_MESSAGE);
+    return;
+  }
+
+  public static void impossibiliteAction(String texte) {
+    JOptionPane.showMessageDialog(null, texte,
+            "Désolé...", JOptionPane.INFORMATION_MESSAGE);
+    return;
+  }
+
+  public static void erreurFatale(Throwable ex) {
+    String message = "<center><b>Désolé pour ce bug... Vous allez devoir relancer Analec.</b></center>"
+            +"<i><br>Veuillez recopier  le message d'erreur ci-dessous et l'envoyer au concepteur du logiciel"
+            +" <br>en précisant les conditions dans lequel ce bug s'est produit</i>";
+    String erreur = "<p>"+ex.toString();
+    for (StackTraceElement tr : ex.getStackTrace())
+      if (tr.getClassName().startsWith("visuAnalec")||tr.getClassName().startsWith("JamaPlus") )
+        erreur += "<br>"+tr.getClassName()+" : "+tr.getMethodName()+" ligne "+tr.getLineNumber();
+    JEditorPane dialogue = new JEditorPane("text/html", message+erreur);
+    JOptionPane.showMessageDialog(null, dialogue, "Oups !", JOptionPane.ERROR_MESSAGE);
+    //System.exit(1);
+  }
+
+  public abstract static class GAction extends AbstractAction {
+    public GAction(String nom) {
+      super(nom);
+    }
+
+    public GAction(String nom, Icon icone) {
+      super(nom, icone);
+    }
+
+    public abstract void executer();
+
+    public void actionPerformed(ActionEvent evt) {
+      try {
+        executer();
+      } catch (Throwable ex) {
+        erreurFatale(ex);
+      }
+    }
+  }
+
+  public abstract static class GActionClavier extends GAction {
+    public GActionClavier(JComponent composant, String nom, String... touches) {
+      super(nom);
+      for(String touche: touches) {
+        composant.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
+                KeyStroke.getKeyStroke(touche), nom);
+      }
+      composant.getActionMap().put(nom, this);
+    }
+  }
+  public static class GProgression extends ProgressMonitor  {
+    private int compteur;
+    private String elementsTraites;
+
+    public GProgression(int max, String traitement, String elementsTraites) {
+      super(null, traitement + " en cours", "Démarrage", 0, max);
+      this.elementsTraites = elementsTraites;
+//      setMillisToPopup(0);
+      compteur = 0;
+     }
+
+    public void setNbTraites(int nb) {
+      compteur = nb;
+      SwingUtilities.invokeLater(new MiseAJour());
+    }
+
+    class MiseAJour implements Runnable {
+      public void run() {
+        setProgress(compteur);
+        setNote(compteur +" "+ elementsTraites + " traités");
+      }
+    }
+  }
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/util/GMessages.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesRelations.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesRelations.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesRelations.java	(revision 481)
@@ -0,0 +1,756 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.ArrayList;
+import javax.swing.*;
+import visuAnalec.Message.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.texte.PanneauAffTexte.*;
+import visuAnalec.texte.PanneauTexte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class PanneauCommandesRelations extends PanneauCommandes implements ActionListener {
+  private PanneauChamps panneauChamps;
+  private TypeComboBox saisieTypeRelations;
+  private ElementComboBox saisieRelation;
+  private TypeComboBox saisieTypeElt1;
+  private ElementComboBox saisieElt1;
+  private TypeComboBox saisieTypeElt2;
+  private ElementComboBox saisieElt2;
+  private JButton creeRelation;
+  private JButton supprimeRelation;
+  private JButton creeUniteElt1;
+  private JButton creeUniteElt2;
+  private boolean uniteCreeElt1 = true; // pour la création d'unités en cours de route
+  private int[] bornesSelectTexte;
+  /*
+  
+   * CREATION PAR LE PANNEAU EDITEUR
+   */
+  PanneauCommandesRelations(Vue vue, PanneauAffTexte pTexte, PanneauChamps pChamps) {
+    super(vue, pTexte);
+    JToolBar barre1 = new JToolBar();
+    barre1.setPreferredSize(new Dimension(0, 22));
+    barre1.setAlignmentX(0.0f);
+    //    barre1.setFloatable(false);
+    add(barre1);
+    JToolBar barre2 = new JToolBar();
+//    barre2.setBackground(PanneauTexte.getCouleurFond2());
+    barre2.setPreferredSize(new Dimension(0, 22));
+    barre2.setAlignmentX(0.0f);
+//     barre2.setFloatable(false);
+    add(barre2);
+    JToolBar barre3 = new JToolBar();
+    barre3.setPreferredSize(new Dimension(0, 22));
+    barre3.setAlignmentX(0.0f);
+//    barre3.setBackground(PanneauTexte.getCouleurFond2());
+//     barre3.setFloatable(false);
+    add(barre3);
+
+    panneauChamps = pChamps;
+    saisieTypeRelations = new TypeComboBox(Relation.class);
+    saisieTypeRelations.addActionListener(this);
+    saisieRelation = new ElementComboBox();
+    saisieRelation.addActionListener(this);
+    saisieTypeElt1 = new TypeComboBox(Element.class);
+    saisieTypeElt1.addActionListener(this);
+    saisieElt1 = new ElementComboBox();
+    saisieElt1.addActionListener(this);
+    saisieTypeElt2 = new TypeComboBox(Element.class);
+    saisieTypeElt2.addActionListener(this);
+    saisieElt2 = new ElementComboBox();
+    saisieElt2.addActionListener(this);
+    creeRelation = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerRelation();
+      }
+    });
+    supprimeRelation = new JButton(new GAction("Supprimer") {
+      public void executer() {
+        supprimerRelation();
+      }
+    });
+    creeUniteElt1 = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerUniteElt1();
+      }
+    });
+    creeUniteElt2 = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerUniteElt2();
+      }
+    });
+    barre1.addSeparator();
+    barre1.add(new TitreBarre("  Relation :  ", PanneauTexte.getCouleurFond1()));
+    barre1.addSeparator();
+    barre1.add(saisieTypeRelations);
+    barre1.add(saisieRelation);
+    barre1.addSeparator();
+    barre1.add(creeRelation);
+    barre1.addSeparator();
+    barre1.add(supprimeRelation);
+    barre2.addSeparator();
+    barre2.add(new TitreBarre("Elément 1 : ", PanneauTexte.getCouleurFond2()));
+    barre2.addSeparator();
+    barre2.add(saisieTypeElt1);
+    barre2.add(saisieElt1);
+    barre2.addSeparator();
+    barre2.add(creeUniteElt1);
+    barre3.addSeparator();
+    barre3.add(new TitreBarre("Elément 2 : ", PanneauTexte.getCouleurFond3()));
+    barre3.addSeparator();
+    barre3.add(saisieTypeElt2);
+    barre3.add(saisieElt2);
+    barre3.addSeparator();
+    barre3.add(creeUniteElt2);
+  }
+
+  /*
+   * COMMANDES UTILISEES PAR LE PANNEAU EDITEUR
+   */
+  public void reinitialiser() {
+    // typiquement, appelé par le panneau éditeur à la suite d'une modif de vue ou de structure
+    saisieTypeRelations.removeActionListener(this);
+    saisieTypeRelations.setModele(vue.getTypesRelationsAVoir());
+    saisieTypeRelations.effSelection();
+    saisieTypeRelations.addActionListener(this);
+    saisieTypeElt1.removeActionListener(this);
+    saisieTypeElt1.setModele(vue.getTypes(Unite.class), vue.getTypes(Relation.class), vue.getTypes(Schema.class));
+    saisieTypeElt1.effSelection();
+    saisieTypeElt1.addActionListener(this);
+    saisieTypeElt2.removeActionListener(this);
+    saisieTypeElt2.setModele(vue.getTypes(Unite.class), vue.getTypes(Relation.class), vue.getTypes(Schema.class));
+    saisieTypeElt2.effSelection();
+    saisieTypeElt2.addActionListener(this);
+    initSaisieRelation();
+    initSaisieElt1();
+    initSaisieElt2();
+    etatSelectRien();
+    revalidate();
+    repaint();
+  }
+  public void reafficher() {
+    // potentiellement appelé par le panneau éditeur ?
+    // appelé aussi par  traiterElementEvent
+    if (saisieRelation.pasdeSelection()) {
+      initSaisieRelation();
+      if (saisieElt1.pasdeSelection()) {
+        initSaisieElt1();
+        if (saisieElt2.pasdeSelection()) {
+          initSaisieElt2();
+          etatSelectRien();
+        } else {
+          Element elt2Courant = saisieElt2.getSelection();
+          initSaisieElt2(elt2Courant);
+          etatSelectElt2(elt2Courant);
+        }
+      } else {
+        Element elt1Courant = saisieElt1.getSelection();
+        initSaisieElt1(elt1Courant);
+        if (saisieElt2.pasdeSelection()) {
+          initSaisieElt2();
+          etatSelectElt1(elt1Courant);
+
+        } else {
+          Element elt2Courant = saisieElt2.getSelection();
+          initSaisieElt2(elt2Courant);
+          etatSelectElts(elt1Courant, elt2Courant);
+        }
+      }
+    } else {
+      Relation relCourant = (Relation) saisieRelation.getSelection();
+      initSaisieRelation(relCourant);
+      initSaisieElt1(relCourant.getElt1());
+      initSaisieElt2(relCourant.getElt2());
+      etatSelectRel(relCourant);
+    }
+  }
+  public void elementSuivant(int sens) {
+    if (sens>0) saisieRelation.gotoSuivant();
+    else saisieRelation.gotoPrecedent();
+  }
+ public Element elementSelectionne() {
+    if (saisieRelation.pasdeSelection()) return null;
+    return saisieRelation.getSelection();
+  }
+  public void editerElement(Element elt) {
+    // appelé par le panneauEditeur : elt est forcément une relation
+    if (elt.getClass()!=Relation.class)
+      throw new UnsupportedOperationException("Erreur : classe incorrecte");
+    editerRelation((Relation) elt);
+  }
+  public void traiterElementEvent(ElementEvent evt) {
+    switch (evt.getModif()) {
+      case AJOUT_RELATION:
+        Relation rel = (Relation) evt.getElement();
+        editerRelation(rel);
+        return;
+      case SUP_RELATION:
+        if (evt.getElement()==saisieRelation.getSelection()) {
+          initSaisieRelation();
+          initSaisieElt1();
+          initSaisieElt2();
+          etatSelectRien();
+        } else {
+          reafficher();
+        }
+        return;
+      case AJOUT_UNITE:
+        Unite unit = (Unite) evt.getElement();
+        boolean chgEtat = false;
+        if (!saisieTypeElt1.pasdeSelection()&&saisieTypeElt1.getClasseSelection()==Unite.class
+                &&saisieTypeElt1.getTypeSelection().equals(unit.getType())) {
+          initSaisieElt1(uniteCreeElt1 ? unit : null);
+          chgEtat = true;
+        }
+        if (!saisieTypeElt2.pasdeSelection()&&saisieTypeElt2.getClasseSelection()==Unite.class
+                &&saisieTypeElt2.getTypeSelection().equals(unit.getType())) {
+          initSaisieElt2(uniteCreeElt1 ? null : unit);
+          chgEtat = true;
+        }
+        if (chgEtat) {
+          if (uniteCreeElt1) etatSelectElt1(unit);
+          else etatSelectElt2(unit);
+          uniteCreeElt1 = true;
+        }
+        return;
+      case SUP_UNITE:
+      case BORNES_UNITE:
+      case AJOUT_SCHEMA:
+      case MODIF_SCHEMA:
+      case SUP_SCHEMA:
+      case MODIF_VALEUR:
+        reafficher();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getModif()+" oublié dans un switch");
+    }
+  }
+  public void editerRelation(Relation rel) {
+    // appelé  par traiterElementEvent, 
+    // et aussi directement par le panneau éditeur quand il est sollicité par d'autres fenêtres
+    if (!rel.getType().equals(saisieTypeRelations.getTypeSelection())) {
+      saisieTypeRelations.removeActionListener(this);
+      saisieTypeRelations.setSelection(rel.getType());
+      saisieTypeRelations.addActionListener(this);
+    }
+    initSaisieRelation(rel);
+    saisieRelation.setSelection(rel);
+  }
+  public ArrayList<ElementMarque> trouverElementsVises(Unite uniteVisee, TypeMarquage marqueUniteVisee,
+          boolean avecId) {
+    ArrayList<ElementMarque> eltsMarques = new ArrayList<ElementMarque>();
+    ArrayList<Element> eltsVises;
+    Element eltVise;
+    switch (marqueUniteVisee) {
+      case FOND1:
+        eltsVises = Element.trouverElementsParUniteSousjacente(saisieRelation.getElements(), uniteVisee);
+        for (Element elt : eltsVises)
+          eltsMarques.add(new ElementMarque(
+                  elt, marqueUniteVisee, avecId ? saisieRelation.getIdElement(elt) : null));
+        return eltsMarques;
+      case FOND2:
+        eltsVises = Element.trouverElementsParUniteSousjacente(saisieElt1.getElements(), uniteVisee);
+        for (Element elt : eltsVises)
+          eltsMarques.add(new ElementMarque(
+                  elt, marqueUniteVisee, avecId ? saisieElt1.getIdElement(elt) : null));
+        return eltsMarques;
+      case FOND3:
+        eltsVises = Element.trouverElementsParUniteSousjacente(saisieElt2.getElements(), uniteVisee);
+        for (Element elt : eltsVises)
+          eltsMarques.add(new ElementMarque(
+                  elt, marqueUniteVisee, avecId ? saisieElt2.getIdElement(elt) : null));
+        return eltsMarques;
+      case SELECT2:
+      case SELECT1_2:
+        eltVise = saisieElt1.getSelection();
+        eltsMarques.add(new ElementMarque(
+                eltVise, marqueUniteVisee, avecId ? saisieElt1.getIdElement(eltVise) : null));
+        return eltsMarques;
+      case SELECT3:
+      case SELECT1_3:
+        eltVise = saisieElt2.getSelection();
+        eltsMarques.add(new ElementMarque(
+                eltVise, marqueUniteVisee, avecId ? saisieElt2.getIdElement(eltVise) : null));
+        return eltsMarques;
+      default:
+        throw new UnsupportedOperationException("Marquage non prévu : "+marqueUniteVisee);
+
+    }
+  }
+
+  /*
+   * ACTIONS DE L'UTILISATEUR : CHANGEMENTS D'ETAT
+   */
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource()==saisieTypeRelations) {
+        initSaisieRelation();
+        if (saisieElt1.pasdeSelection()) {
+          if (saisieElt2.pasdeSelection()) etatSelectRien();
+          else etatSelectElt2(saisieElt2.getSelection());
+        } else {
+          if (saisieElt2.pasdeSelection())
+            etatSelectElt1(saisieElt1.getSelection());
+          else
+            checkEtatSelectElts(saisieElt1.getSelection(), saisieElt2.getSelection());
+        }
+        return;
+      }
+      if (evt.getSource()==saisieTypeElt1) {
+        forceEffSelectRel();
+        initSaisieElt1();
+        if (saisieElt2.pasdeSelection()) etatSelectRien();
+        else etatSelectElt2(saisieElt2.getSelection());
+        return;
+      }
+      if (evt.getSource()==saisieTypeElt2) {
+        forceEffSelectRel();
+        initSaisieElt2();
+        if (saisieElt1.pasdeSelection()) etatSelectRien();
+        else etatSelectElt1(saisieElt1.getSelection());
+        return;
+      }
+      if (evt.getSource()==saisieRelation) {
+        if (saisieRelation.pasdeSelection()) {
+          if (saisieElt1.pasdeSelection()) {
+            if (saisieElt2.pasdeSelection()) etatSelectRien();
+            else etatSelectElt2(saisieElt2.getSelection());
+          } else {
+            if (saisieElt2.pasdeSelection())
+              etatSelectElt1(saisieElt1.getSelection());
+            else
+              etatSelectElts(saisieElt1.getSelection(), saisieElt2.getSelection());
+          }
+        } else {
+          forceEtatSelectRel((Relation) saisieRelation.getSelection());
+        }
+        return;
+      }
+      if (evt.getSource()==saisieElt1) {
+        if (!saisieRelation.pasdeSelection()) {
+          saisieRelation.removeActionListener(this);
+          saisieRelation.effSelection();
+          saisieRelation.addActionListener(this);
+          saisieElt2.removeActionListener(this);
+          saisieElt2.effSelection();
+          saisieElt2.addActionListener(this);
+        }
+        if (saisieElt1.pasdeSelection()) {
+          if (saisieElt2.pasdeSelection()) etatSelectRien();
+          else etatSelectElt2(saisieElt2.getSelection());
+        } else {
+          if (saisieElt2.pasdeSelection())
+            etatSelectElt1(saisieElt1.getSelection());
+          else
+            checkEtatSelectElts(saisieElt1.getSelection(), saisieElt2.getSelection());
+        }
+        return;
+      }
+      if (evt.getSource()==saisieElt2) {
+        if (!saisieRelation.pasdeSelection()) {
+          saisieRelation.removeActionListener(this);
+          saisieRelation.effSelection();
+          saisieRelation.addActionListener(this);
+          saisieElt1.removeActionListener(this);
+          saisieElt1.effSelection();
+          saisieElt1.addActionListener(this);
+        }
+        if (saisieElt2.pasdeSelection()) {
+          if (saisieElt1.pasdeSelection()) etatSelectRien();
+          else etatSelectElt1(saisieElt1.getSelection());
+        } else {
+          if (saisieElt1.pasdeSelection())
+            etatSelectElt2(saisieElt2.getSelection());
+          else
+            checkEtatSelectElts(saisieElt1.getSelection(), saisieElt2.getSelection());
+        }
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  @Override
+  public void traiterSourisEvent(SourisEvent evt) {
+    switch (evt.getTypeEvent()) {
+      case SELECT_RIEN:
+        saisieElt1.removeActionListener(this);
+        saisieElt1.effSelection();
+        saisieElt1.addActionListener(this);
+        saisieElt2.removeActionListener(this);
+        saisieElt2.effSelection();
+        saisieElt2.addActionListener(this);
+        saisieRelation.removeActionListener(this);
+        saisieRelation.effSelection();
+        saisieRelation.addActionListener(this);
+        etatSelectRien();
+        return;
+      case SELECT_ELEMENT:
+        switch (evt.getMarquageElementVise()) {
+          case FOND1:
+            saisieRelation.setSelection(evt.getElementVise());
+            return;
+          case FOND2:
+            saisieElt1.setSelection(evt.getElementVise());
+            return;
+          case FOND3:
+            saisieElt2.setSelection(evt.getElementVise());
+            return;
+          case SELECT2:
+          case SELECT1_2:
+            forceEffSelectElt2();
+            return;
+          case SELECT3:
+          case SELECT1_3:
+            forceEffSelectElt1();
+            return;
+        }
+        return;
+      case SELECT_TEXTE:
+        if (!saisieElt1.pasdeSelection()&&!saisieElt2.pasdeSelection()) {
+          saisieElt1.removeActionListener(this);
+          saisieElt1.effSelection();
+          saisieElt1.addActionListener(this);
+          saisieElt2.removeActionListener(this);
+          saisieElt2.effSelection();
+          saisieElt2.addActionListener(this);
+          saisieRelation.removeActionListener(this);
+          saisieRelation.effSelection();
+          saisieRelation.addActionListener(this);
+        }
+        bornesSelectTexte = evt.getBornesSelectionTexte();
+        etatSelectTexte();
+        return;
+    }
+    throw new UnsupportedOperationException("Evénement non prévu : "+evt.getTypeEvent());
+  }
+  /*
+   * ACTIONS DE L'UTILISATEUR : BOUTONS
+   */
+  private void creerRelation() {
+    vue.getCorpus().addRelationSaisie((String) saisieTypeRelations.getTypeSelection(),
+            saisieElt1.getSelection(), saisieElt2.getSelection());
+  }
+  private void supprimerRelation() {
+    if (!GMessages.confirmationAction("Supprimer la relation sélectionnée ?"))
+      return;
+    vue.getCorpus().supRelation((Relation) saisieRelation.getSelection());
+  }
+  private void creerUniteElt1() {
+    if (vue.getCorpus().checkPresenceUnite(saisieTypeElt1.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1])
+            &&!GMessages.confirmationAction("Dupliquer cette unité  ?")) return;
+    uniteCreeElt1 = true;
+    vue.getCorpus().addUniteSaisie(saisieTypeElt1.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1]);
+  }
+  private void creerUniteElt2() {
+    if (vue.getCorpus().checkPresenceUnite(saisieTypeElt2.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1])
+            &&!GMessages.confirmationAction("Dupliquer cette unité  ?")) return;
+    uniteCreeElt1 = false;
+    vue.getCorpus().addUniteSaisie(saisieTypeElt2.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1]);
+  }
+
+  /* 
+   * GESTION INTERNE
+   */
+  private void etatSelectRien() {   // rien n'est sélectionné
+    if (saisieTypeRelations.pasdeSelection()) {
+      if (saisieTypeElt1.pasdeSelection()) {
+        if (saisieTypeElt2.pasdeSelection()) panneauTexte.pasDeMarquage();
+        else
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+      } else {
+        if (saisieTypeElt2.pasdeSelection())
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2);
+        else
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2,
+                  Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+      }
+    } else {
+      if (saisieTypeElt1.pasdeSelection()) {
+        if (saisieTypeElt2.pasdeSelection())
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(saisieRelation.getElements()), TypeMarquage.FOND1);
+        else
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(filtreElt2((Relation[]) saisieRelation.getElements())), TypeMarquage.FOND1,
+                  Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+      } else {
+        if (saisieTypeElt2.pasdeSelection())
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(filtreElt1((Relation[]) saisieRelation.getElements())), TypeMarquage.FOND1,
+                  Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2);
+        else
+          panneauTexte.saisir(null,
+                  Element.getUnitesSousjacentes(filtreElts((Relation[]) saisieRelation.getElements())), TypeMarquage.FOND1,
+                  Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2,
+                  Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+      }
+    }
+    panneauChamps.effacer();
+    creeRelation.setEnabled(false);
+    supprimeRelation.setEnabled(false);
+    creeUniteElt1.setEnabled(false);
+    creeUniteElt2.setEnabled(false);
+  }
+  private void etatSelectTexte() {   // du texte est sélectionné
+    if (saisieElt1.pasdeSelection()) {
+      if (saisieElt2.pasdeSelection()) panneauTexte.pasDeMarquage();
+      else
+        panneauTexte.saisir(null,
+                saisieElt2.getSelection().getUnitesSousjacentes(), TypeMarquage.SELECT3);
+    } else {
+      if (saisieElt2.pasdeSelection())
+        panneauTexte.saisir(null,
+                saisieElt1.getSelection().getUnitesSousjacentes(), TypeMarquage.SELECT2);
+      else // au moins un des 2 elt n'est pas sélectionné
+        throw new UnsupportedOperationException("Cas non prévu");
+    }
+    panneauChamps.effacer();
+    creeRelation.setEnabled(false);
+    supprimeRelation.setEnabled(false);
+    if (!saisieTypeElt1.pasdeSelection()&&saisieTypeElt1.getClasseSelection()==Unite.class
+            &&saisieElt1.pasdeSelection())
+      creeUniteElt1.setEnabled(true);
+    if (!saisieTypeElt2.pasdeSelection()&&saisieTypeElt2.getClasseSelection()==Unite.class
+            &&saisieElt2.pasdeSelection())
+      creeUniteElt2.setEnabled(true);
+  }
+  private void etatSelectElt1(Element elt1) { // seul Elt1 a été choisi
+    if (saisieTypeElt2.pasdeSelection()) {
+      if (saisieTypeRelations.pasdeSelection())
+        panneauTexte.saisir(elt1.getUnite0(), elt1.getUnitesSousjacentes(), TypeMarquage.SELECT2);
+      else
+        panneauTexte.saisir(elt1.getUnite0(), elt1.getUnitesSousjacentes(), TypeMarquage.SELECT2,
+                Element.getUnitesSousjacentes(filtreElt1((Relation[]) saisieRelation.getElements(), elt1)),
+                TypeMarquage.FOND1);
+    } else {
+      if (saisieTypeRelations.pasdeSelection())
+        panneauTexte.saisir(elt1.getUnite0(), elt1.getUnitesSousjacentes(), TypeMarquage.SELECT2,
+                Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+      else
+        panneauTexte.saisir(elt1.getUnite0(), elt1.getUnitesSousjacentes(), TypeMarquage.SELECT2,
+                Element.getUnitesSousjacentes(filtreElt1(filtreElt2((Relation[]) saisieRelation.getElements()), elt1)),
+                TypeMarquage.FOND1,
+                Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+    }
+    panneauChamps.afficher(elt1);
+    creeRelation.setEnabled(false);
+    supprimeRelation.setEnabled(false);
+    creeUniteElt1.setEnabled(false);
+    creeUniteElt2.setEnabled(false);
+  }
+  private void etatSelectElt2(Element elt2) {  // seul Elt2 a été choisi
+    if (saisieTypeElt1.pasdeSelection()) {
+      if (saisieTypeRelations.pasdeSelection())
+        panneauTexte.saisir(elt2.getUnite0(), elt2.getUnitesSousjacentes(), TypeMarquage.SELECT3);
+      else
+        panneauTexte.saisir(elt2.getUnite0(), elt2.getUnitesSousjacentes(), TypeMarquage.SELECT3,
+                Element.getUnitesSousjacentes(filtreElt2((Relation[]) saisieRelation.getElements(), elt2)),
+                TypeMarquage.FOND1);
+    } else {
+      if (saisieTypeRelations.pasdeSelection())
+        panneauTexte.saisir(elt2.getUnite0(), elt2.getUnitesSousjacentes(), TypeMarquage.SELECT3,
+                Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2);
+      else
+        panneauTexte.saisir(elt2.getUnite0(), elt2.getUnitesSousjacentes(), TypeMarquage.SELECT3,
+                Element.getUnitesSousjacentes(filtreElt2(filtreElt1((Relation[]) saisieRelation.getElements()), elt2)),
+                TypeMarquage.FOND1,
+                Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2);
+    }
+    panneauChamps.afficher(elt2);
+    creeRelation.setEnabled(false);
+    supprimeRelation.setEnabled(false);
+    creeUniteElt1.setEnabled(false);
+    creeUniteElt2.setEnabled(false);
+  }
+  private void etatSelectElts(Element elt1, Element elt2) { // Elt1 et Elt2 ont été choisis et ils ne forment pas encore de relation
+    panneauTexte.saisir(elt1.getUnite0(), elt1.getUnitesSousjacentes(), TypeMarquage.SELECT2,
+            elt2.getUnitesSousjacentes(), TypeMarquage.SELECT3);
+    panneauChamps.effacer();
+    if (!saisieTypeRelations.pasdeSelection()) {
+      creeRelation.setEnabled(true);
+//      Boutons.setDefaut(creeRelation, true);
+    }
+    supprimeRelation.setEnabled(false);
+    creeUniteElt1.setEnabled(false);
+    creeUniteElt2.setEnabled(false);
+  }
+  private void etatSelectRel(Relation rel) {  // une relation est sélectionnée
+    panneauTexte.saisir(rel.getElt1().getUnite0(),
+            rel.getElt1().getUnitesSousjacentes(), TypeMarquage.SELECT1_2,
+            rel.getElt2().getUnitesSousjacentes(), TypeMarquage.SELECT1_3);
+//            Element.getUnitesSousjacentes(saisieElt1.getElements()), TypeMarquage.FOND2,
+//            Element.getUnitesSousjacentes(saisieElt2.getElements()), TypeMarquage.FOND3);
+    panneauChamps.afficher(rel);
+    creeRelation.setEnabled(false);
+    supprimeRelation.setEnabled(true);
+    creeUniteElt1.setEnabled(false);
+    creeUniteElt2.setEnabled(false);
+  }
+  private Relation[] filtreElt1(Relation[] relations) {
+    Class classe = saisieTypeElt1.getClasseSelection();
+    String type = saisieTypeElt1.getTypeSelection();
+    ArrayList<Integer> indsAOter = new ArrayList<Integer>();
+    for (int i = 0; i<relations.length; i++) {
+      Element elt1 = relations[i].getElt1();
+      if (elt1.getClass()!=classe||!elt1.getType().equals(type))
+        indsAOter.add(i);
+    }
+    return Tableaux.oterRelations(relations, indsAOter);
+  }
+  private Relation[] filtreElt1(Relation[] relations, Element elt1) {
+    ArrayList<Relation> rels = new ArrayList<Relation>();
+    for (Relation rel : relations) if (elt1==rel.getElt1()) rels.add(rel);
+    return rels.toArray(new Relation[0]);
+  }
+  private Relation[] filtreElt2(Relation[] relations) {
+    Class classe = saisieTypeElt2.getClasseSelection();
+    String type = saisieTypeElt2.getTypeSelection();
+    ArrayList<Integer> indsAOter = new ArrayList<Integer>();
+    for (int i = 0; i<relations.length; i++) {
+      Element elt2 = relations[i].getElt2();
+      if (elt2.getClass()!=classe||!elt2.getType().equals(type))
+        indsAOter.add(i);
+    }
+    return Tableaux.oterRelations(relations, indsAOter);
+  }
+  private Relation[] filtreElt2(Relation[] relations, Element elt2) {
+    ArrayList<Relation> rels = new ArrayList<Relation>();
+    for (Relation rel : relations) if (elt2==rel.getElt2()) rels.add(rel);
+    return rels.toArray(new Relation[0]);
+  }
+  private Relation[] filtreElts(Relation[] relations) {
+    Class classe1 = saisieTypeElt1.getClasseSelection();
+    String type1 = saisieTypeElt1.getTypeSelection();
+    Class classe2 = saisieTypeElt2.getClasseSelection();
+    String type2 = saisieTypeElt2.getTypeSelection();
+    ArrayList<Integer> indsAOter = new ArrayList<Integer>();
+    for (int i = 0; i<relations.length; i++) {
+      Element elt1 = relations[i].getElt1();
+      Element elt2 = relations[i].getElt2();
+      if (elt1.getClass()!=classe1||!elt1.getType().equals(type1)
+              ||elt2.getClass()!=classe2||!elt2.getType().equals(type2))
+        indsAOter.add(i);
+    }
+    return Tableaux.oterRelations(relations, indsAOter);
+  }
+  private void checkEtatSelectElts(Element elt1, Element elt2) {
+    if (!saisieTypeRelations.pasdeSelection())
+      for (Relation rel : (Relation[]) saisieRelation.getElements()) {
+        if (rel.getElt1()==elt1&&rel.getElt2()==elt2) {
+          saisieRelation.setSelection(rel);
+          return;
+        }
+      }
+    etatSelectElts(elt1, elt2);
+  }
+  private void forceEtatSelectRel(Relation rel) {
+    if (saisieTypeElt1.pasdeSelection()||saisieTypeElt1.getClasseSelection()!=rel.getElt1().getClass()
+            ||!saisieTypeElt1.getTypeSelection().equals(rel.getElt1().getType())) {
+      saisieTypeElt1.removeActionListener(this);
+      saisieTypeElt1.setSelection(rel.getElt1().getClass(), rel.getElt1().getType());
+      saisieTypeElt1.addActionListener(this);
+    }
+    initSaisieElt1(rel.getElt1());
+    if (saisieTypeElt2.pasdeSelection()||saisieTypeElt2.getClasseSelection()!=rel.getElt2().getClass()
+            ||!saisieTypeElt2.getTypeSelection().equals(rel.getElt2().getType())) {
+      saisieTypeElt2.removeActionListener(this);
+      saisieTypeElt2.setSelection(rel.getElt2().getClass(), rel.getElt2().getType());
+      saisieTypeElt2.addActionListener(this);
+    }
+    initSaisieElt2(rel.getElt2());
+    etatSelectRel(rel);
+  }
+  private void forceEffSelectElt1() {
+    if (saisieElt1.pasdeSelection()) return;
+    if (!saisieRelation.pasdeSelection()) {
+      saisieRelation.removeActionListener(this);
+      saisieRelation.effSelection();
+      saisieRelation.addActionListener(this);
+    }
+    saisieElt1.effSelection();
+  }
+  private void forceEffSelectElt2() {
+    if (saisieElt2.pasdeSelection()) return;
+    if (!saisieRelation.pasdeSelection()) {
+      saisieRelation.removeActionListener(this);
+      saisieRelation.effSelection();
+      saisieRelation.addActionListener(this);
+    }
+    saisieElt2.effSelection();
+  }
+  private void forceEffSelectRel() {
+    if (saisieRelation.pasdeSelection()) return;
+    saisieRelation.removeActionListener(this);
+    saisieRelation.effSelection();
+    saisieRelation.addActionListener(this);
+  }
+  private void initSaisieRelation(Relation rel) {
+    saisieRelation.removeActionListener(this);
+    if (saisieTypeRelations.pasdeSelection()) saisieRelation.setModeleVide();
+    else {
+      String type0 = saisieTypeRelations.getTypeSelection();
+      Relation[] relations = vue.getRelationsAVoir(type0);
+      saisieRelation.setModele(relations, vue.getIdRelations(type0, relations));
+    }
+    if (rel==null) saisieRelation.effSelection();
+    else saisieRelation.setSelection(rel);
+    saisieRelation.addActionListener(this);
+    saisieRelation.revalidate();
+  }
+  private void initSaisieRelation() {
+    initSaisieRelation(null);
+  }
+  private void initSaisieElt1(Element elt1) {
+    saisieElt1.removeActionListener(this);
+    if (saisieTypeElt1.pasdeSelection()) saisieElt1.setModeleVide();
+    else {
+      Class<? extends Element> classe = saisieTypeElt1.getClasseSelection();
+      String type = saisieTypeElt1.getTypeSelection();
+      saisieElt1.setModele(vue.getElements(classe, type), vue.getIdElements(classe, type));
+    }
+    if (elt1==null) saisieElt1.effSelection();
+    else saisieElt1.setSelection(elt1);
+    saisieElt1.addActionListener(this);
+    saisieElt1.revalidate();
+  }
+  private void initSaisieElt1() {
+    initSaisieElt1(null);
+  }
+  private void initSaisieElt2(Element elt2) {
+    saisieElt2.removeActionListener(this);
+    if (saisieTypeElt2.pasdeSelection()) saisieElt2.setModeleVide();
+    else {
+      Class<? extends Element> classe = saisieTypeElt2.getClasseSelection();
+      String type = saisieTypeElt2.getTypeSelection();
+      saisieElt2.setModele(vue.getElements(classe, type), vue.getIdElements(classe, type));
+    }
+
+    if (elt2==null) saisieElt2.effSelection();
+    else saisieElt2.setSelection(elt2);
+    saisieElt2.addActionListener(this);
+    saisieElt2.revalidate();
+  }
+  private void initSaisieElt2() {
+    initSaisieElt2(null);
+  }
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesRelations.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVueColoriage.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVueColoriage.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVueColoriage.java	(revision 481)
@@ -0,0 +1,434 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.vue;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.ArrayList;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+import javax.swing.tree.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class VisuVueColoriage extends JPanel implements TreeWillExpandListener {
+  private VisuVue visuVue;
+  private int indexTab;
+  private Vue vue;
+  private JTable tableauValeursAColorier;
+  private JTree arbreValeursAChoisir;
+  private JPopupMenuValeur popupMenuValeur;
+  private Class<? extends Element> classeSelected;
+  private String typeSelected;
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> stylesElements;
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> stylesValeursElements;
+  private JPanel panneauValeursChoisies;
+  private JPanel panneauValeursAChoisir;
+  VisuVueColoriage(VisuVue visuVue, Vue vue,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> stylesElements,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> stylesValeursElements) {
+    super(new BorderLayout());
+    this.visuVue = visuVue;
+    this.vue = vue;
+    this.champsAVoir = champsAVoir;
+    this.adressesAVoir = adressesAVoir;
+    this.stylesElements = stylesElements;
+    this.stylesValeursElements = stylesValeursElements;
+    classeSelected = null;
+    typeSelected = null;
+//    // Panneau des valeurs choisies à colorier
+    panneauValeursChoisies = new JPanel();
+    // Le tableau des valeurs à colorier
+    ModeleTableauValeursAColorier donneesValeursAColorier = new ModeleTableauValeursAColorier();
+    tableauValeursAColorier = new JTable(donneesValeursAColorier);
+    GVisu.CouleurTableEditor couleurcombo =
+            new GVisu.CouleurTableEditor(GVisu.getCouleursEtNoirEtBlanc());
+    tableauValeursAColorier.setDefaultEditor(Color.class, couleurcombo);
+    tableauValeursAColorier.setDefaultRenderer(Color.class, new GVisu.CouleurCellRenderer());
+    popupMenuValeur = new JPopupMenuValeur();
+    popupMenuValeur.add(new ActionSupprimerValeur());
+
+    MouseListener popupListener = new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {
+        maybeShowPopup(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        maybeShowPopup(e);
+      }
+      private void maybeShowPopup(MouseEvent e) {
+        try {
+          if (e.isPopupTrigger()) {
+            int rg = popupMenuValeur.rang;
+            popupMenuValeur.rang = tableauValeursAColorier.rowAtPoint(e.getPoint());
+            ((JMenuItem) (popupMenuValeur.getSubElements()[0])).setText("supprimer ce coloriage");
+            popupMenuValeur.show(e.getComponent(), e.getX(), e.getY());
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    };
+    tableauValeursAColorier.addMouseListener(popupListener);
+    tableauValeursAColorier.addKeyListener(new KeyAdapter() {
+      @Override
+      public void keyPressed(KeyEvent e) {
+        try {
+          if (e.getKeyCode()==KeyEvent.VK_DELETE&&tableauValeursAColorier.getSelectedRowCount()==1) {
+            ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).supprimerRangee(
+                    tableauValeursAColorier.getSelectedRow());
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    });
+    JScrollPane scroll2 = new JScrollPane(tableauValeursAColorier);
+    scroll2.setBorder(new TitledBorder("Elements à colorier"));
+    panneauValeursChoisies.add(scroll2, BorderLayout.CENTER);
+    // Panneau des valeurs à choisir
+    panneauValeursAChoisir = new JPanel(new BorderLayout());
+    // L'arbre des champs à extraire
+    ModeleArbreValeursAChoisir donneesValeursAChoisir =
+            new ModeleArbreValeursAChoisir(vue, champsAVoir, adressesAVoir);
+    arbreValeursAChoisir = new JTree(donneesValeursAChoisir);
+    arbreValeursAChoisir.addTreeWillExpandListener(this);
+    MouseListener ml2 = new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {
+        try {
+          TreePath selPath = arbreValeursAChoisir.getPathForLocation(e.getX(), e.getY());
+          if (selPath!=null&&e.getClickCount()==2) {
+            NoeudValeurAChoisir noeud = (NoeudValeurAChoisir) selPath.getLastPathComponent();
+            if (noeud.getAllowsChildren()) return;
+            else ajouterValeur(noeud.champ, noeud.valeur);
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    };
+    arbreValeursAChoisir.addMouseListener(ml2);
+    JScrollPane scroll3 = new JScrollPane(arbreValeursAChoisir);
+    scroll3.setBorder(new TitledBorder("Choix de nouvelles valeurs à colorier"));
+    panneauValeursAChoisir.add(scroll3, BorderLayout.CENTER);
+    // Dimensionnement 
+    add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panneauValeursChoisies, panneauValeursAChoisir),
+            BorderLayout.CENTER);
+  }
+//    void agencerPanneaux() {
+//        JSplitPane split = (JSplitPane) panneauValeursChoisies.getParent();
+//    split.setDividerLocation(2. / 3);
+//    revalidate();
+//    repaint();
+//    }
+  public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
+    NoeudValeurAChoisir noeud = (NoeudValeurAChoisir) event.getPath().getLastPathComponent();
+    if (noeud.isLeaf()) {
+      ModeleArbreValeursAChoisir donnees = (ModeleArbreValeursAChoisir) arbreValeursAChoisir.getModel();
+      donnees.setSousArbre(noeud);
+    }
+  }
+  public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
+    return;
+  }
+  void setTypeSelected(Class<? extends Element> classe, String type) {
+    classeSelected = classe;
+    typeSelected = type;
+    ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).reinitialiser();
+    ((ModeleArbreValeursAChoisir) arbreValeursAChoisir.getModel()).setModele(classeSelected, typeSelected);
+  }
+  private void ajouterValeur(String champ, String valeur) {
+    if (champ.isEmpty())
+      ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).ajouterTousAColorier();
+    else
+      ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).ajouterValeurAColorier(champ, valeur);
+  }
+  void reinitialiser() {
+    ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).reinitialiser();
+    ((ModeleArbreValeursAChoisir) arbreValeursAChoisir.getModel()).setModele(classeSelected, typeSelected);
+  }
+  private static final String[] nomsColonnes = new String[]{
+    "Champ",
+    "Valeur",
+    "<html><span style=\"font-weight:900 \">Gras</span>",
+    "<html><span style=\"font-style:italic \">Italique</span>",
+    "<html><span style=\"text-decoration:underline \">Souligné</span>",
+    "<html><span style=\"color:red \">Couleur</span>",
+    "<html><span style=\"background-color:yellow \">Fond</span>",};
+  private static final Class[] classesColonnes = new Class[]{
+    String.class, String.class, Boolean.class, Boolean.class, Boolean.class, Color.class, Color.class
+  };
+
+  private class ModeleTableauValeursAColorier extends AbstractTableModel {
+    private ArrayList<String> champs = new ArrayList<String>();
+    private ArrayList<String> valeurs = new ArrayList<String>();
+    private ArrayList<Boolean> gras = new ArrayList<Boolean>();
+    private ArrayList<Boolean> italiques = new ArrayList<Boolean>();
+    private ArrayList<Boolean> soulignes = new ArrayList<Boolean>();
+    private ArrayList<Color> couleurs = new ArrayList<Color>();
+    private ArrayList<Color> fonds = new ArrayList<Color>();
+    private void reinitialiser() {
+      viderTableau();
+      AttributeSet att;
+      if (typeSelected!=null) {
+        if (stylesElements.get(classeSelected).containsKey(typeSelected)) {
+          att = stylesElements.get(classeSelected).get(typeSelected);
+          ajouterRangee("", "", att);
+        }
+        if (stylesValeursElements.get(classeSelected).containsKey(typeSelected))
+          for (String champ : stylesValeursElements.get(classeSelected).get(typeSelected).keySet())
+            for (String valeur : stylesValeursElements.get(classeSelected).get(typeSelected).get(champ).keySet()) {
+              att = stylesValeursElements.get(classeSelected).get(typeSelected).get(champ).get(valeur);
+              ajouterRangee(champ, valeur, att);
+            }
+        fireTableDataChanged();
+      }
+    }
+    private void viderTableau() {
+      champs.clear();
+      valeurs.clear();
+      gras.clear();
+      italiques.clear();
+      soulignes.clear();
+      couleurs.clear();
+      fonds.clear();
+    }
+    private void ajouterTousAColorier() {
+      if (!champs.isEmpty()&&champs.get(0).isEmpty()) return;
+      stylesElements.get(classeSelected).put(typeSelected, new SimpleAttributeSet());
+      insererRangee(0, "", "", vue.getStyleTexte());
+      fireTableDataChanged();
+    }
+    private void ajouterValeurAColorier(String champ, String valeur) {
+      for (int i = 0; i<champs.size(); i++)
+        if (champs.get(i).equals(champ)&&valeurs.get(i).equals(valeur)) return;
+      if (!stylesValeursElements.get(classeSelected).containsKey(typeSelected))
+        stylesValeursElements.get(classeSelected).put(typeSelected, new HashMap<String, HashMap<String, SimpleAttributeSet>>());
+      if (!stylesValeursElements.get(classeSelected).get(typeSelected).containsKey(champ))
+        stylesValeursElements.get(classeSelected).get(typeSelected).put(champ, new HashMap<String, SimpleAttributeSet>());
+      stylesValeursElements.get(classeSelected).get(typeSelected).get(champ).put(valeur, new SimpleAttributeSet());
+      ajouterRangee(champ, valeur, vue.getStyleTexte());
+      fireTableDataChanged();
+    }
+    private void ajouterRangee(String champ, String valeur, AttributeSet att) {
+      insererRangee(champs.size(), champ, valeur, att);
+    }
+    private void insererRangee(int row, String champ, String valeur, AttributeSet att) {
+      SimpleAttributeSet att0 = vue.getStyleTexte();
+      champs.add(row, champ);
+      valeurs.add(row, valeur);
+      if (att.isDefined(StyleConstants.Bold))
+        gras.add(row, StyleConstants.isBold(att));
+      else gras.add(row, StyleConstants.isBold(att0));
+      if (att.isDefined(StyleConstants.Italic))
+        italiques.add(row, StyleConstants.isItalic(att));
+      else italiques.add(row, StyleConstants.isItalic(att0));
+      if (att.isDefined(StyleConstants.Underline))
+        soulignes.add(row, StyleConstants.isUnderline(att));
+      else soulignes.add(row, StyleConstants.isUnderline(att0));
+      if (att.isDefined(StyleConstants.Foreground))
+        couleurs.add(row, StyleConstants.getForeground(att));
+      else couleurs.add(row, StyleConstants.getForeground(att0));
+      if (att.isDefined(StyleConstants.Background))
+        fonds.add(row, StyleConstants.getBackground(att));
+      else fonds.add(row, StyleConstants.getBackground(att0));
+      fireTableDataChanged();
+    }
+    void supprimerRangee(int row) {
+      if (champs.get(row).isEmpty())
+        stylesElements.get(classeSelected).remove(typeSelected);
+      else
+        stylesValeursElements.get(classeSelected).get(typeSelected).get(champs.get(row)).remove(valeurs.get(row));
+      champs.remove(row);
+      valeurs.remove(row);
+      gras.remove(row);
+      italiques.remove(row);
+      soulignes.remove(row);
+      couleurs.remove(row);
+      fonds.remove(row);
+
+      fireTableDataChanged();
+    }
+    public int getColumnCount() {
+      return nomsColonnes.length;
+    }
+    public int getRowCount() {
+      return (valeurs.size());
+    }
+    public Object getValueAt(int row, int col) {
+      switch (col) {
+        case 0:
+          if (champs.get(row).isEmpty()) return GVisu.styleDef("tous");
+          return champs.get(row);
+        case 1:
+          if (champs.get(row).isEmpty()) return GVisu.styleDef("toutes");
+          return valeurs.get(row);
+        case 2:
+          return gras.get(row);
+        case 3:
+          return italiques.get(row);
+        case 4:
+          return soulignes.get(row);
+        case 5:
+          return couleurs.get(row);
+        case 6:
+          return fonds.get(row);
+        default:
+          throw new IndexOutOfBoundsException();
+      }
+    }
+    @Override
+    public String getColumnName(int col) {
+      return nomsColonnes[col];
+    }
+    @Override
+    public Class getColumnClass(int col) {
+      return classesColonnes[col];
+    }
+    @Override
+    public boolean isCellEditable(int row, int col) {
+      return col>1;
+    }
+    @Override
+    public void setValueAt(Object aValue, int row, int col) {
+      Boolean valbool;
+      Color valcoul;
+      SimpleAttributeSet att = champs.get(row).isEmpty() ? stylesElements.get(classeSelected).get(typeSelected) : stylesValeursElements.get(classeSelected).get(typeSelected).get(champs.get(row)).get(valeurs.get(row));
+      SimpleAttributeSet att0 = vue.getStyleTexte();
+      switch (col) {
+        case 2:
+          valbool = (Boolean) aValue;
+          gras.set(row, valbool);
+          if (StyleConstants.isBold(att0)==valbool)
+            att.removeAttribute(StyleConstants.Bold);
+          else StyleConstants.setBold(att, valbool);
+          break;
+        case 3:
+          valbool = (Boolean) aValue;
+          italiques.set(row, valbool);
+          if (StyleConstants.isItalic(att0)==valbool)
+            att.removeAttribute(StyleConstants.Italic);
+          else StyleConstants.setItalic(att, valbool);
+          break;
+        case 4:
+          valbool = (Boolean) aValue;
+          soulignes.set(row, valbool);
+          if (StyleConstants.isUnderline(att0)==valbool)
+            att.removeAttribute(StyleConstants.Underline);
+          else StyleConstants.setUnderline(att, valbool);
+          break;
+        case 5:
+          valcoul = (Color) aValue;
+          couleurs.set(row, valcoul);
+          if (StyleConstants.getForeground(att0)==valcoul)
+            att.removeAttribute(StyleConstants.Foreground);
+          else StyleConstants.setForeground(att, valcoul);
+          break;
+        case 6:
+          valcoul = (Color) aValue;
+          fonds.set(row, valcoul);
+          if (StyleConstants.getBackground(att0)==valcoul)
+            att.removeAttribute(StyleConstants.Background);
+          else StyleConstants.setBackground(att, valcoul);
+          break;
+        default:
+          throw new IndexOutOfBoundsException("col = "+col);
+      }
+      fireTableCellUpdated(row, col);
+    }
+  }
+
+  private static class JPopupMenuValeur extends JPopupMenu {
+    int rang = -1;
+  }
+
+  private class ActionSupprimerValeur extends AbstractAction {
+    ActionSupprimerValeur() {
+      super("supprimer le champ");
+    }
+    public void actionPerformed(ActionEvent e) {
+      try {
+        int rg = ((JPopupMenuValeur) ((JMenuItem) e.getSource()).getParent()).rang;
+        ((ModeleTableauValeursAColorier) tableauValeursAColorier.getModel()).supprimerRangee(rg);
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+  }
+
+  private static class ModeleArbreValeursAChoisir extends DefaultTreeModel {
+    HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champs;
+    HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adresses;
+    Vue vue;
+    ModeleArbreValeursAChoisir(Vue vue, HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAvoir,
+            HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir) {
+      super(null, true);
+      this.champs = champsAvoir;
+      this.adresses = adressesAVoir;
+      this.vue = vue;
+    }
+    void setModele(Class<? extends Element> classeRacine, String typeRacine) {
+      if (typeRacine==null) {
+        setRoot(null);
+      } else {
+        NoeudValeurAChoisir racine = new NoeudValeurAChoisir(
+                classeRacine, typeRacine, null, null);
+        setRoot(racine);
+        setSousArbre(racine);
+      }
+      reload();
+    }
+    void setSousArbre(NoeudValeurAChoisir noeud) {
+      if (noeud.champ==null) {
+        noeud.add(new NoeudValeurAChoisir(noeud.classe, noeud.type, "", GVisu.styleDef("tous les éléments")));
+        for (String champ : champs.get(noeud.classe).get(noeud.type))
+          noeud.add(new NoeudValeurAChoisir(noeud.classe, noeud.type, champ, null));
+      } else {
+        int nochamp = champs.get(noeud.classe).get(noeud.type).indexOf(noeud.champ);
+        for (String valeur : vue.getValeursProp(adresses.get(noeud.classe).get(noeud.type).get(nochamp)))
+          noeud.add(new NoeudValeurAChoisir(noeud.classe, noeud.type, noeud.champ, valeur));
+      }
+    }
+  }
+
+  private static class NoeudValeurAChoisir extends DefaultMutableTreeNode {
+    Class<? extends Element> classe;
+    String type;
+    String champ;
+    String valeur;
+    NoeudValeurAChoisir(Class<? extends Element> classe, String type, String champ, String valeur) {
+      super();
+      this.classe = classe;
+      this.type = type;
+      this.champ = champ;
+      this.valeur = valeur;
+      setAllowsChildren(valeur==null);
+
+    }
+    @Override
+    public String toString() {
+      if (champ==null) return type;
+      if (valeur==null) return champ;
+      return valeur;
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVueColoriage.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/Vue.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/Vue.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/Vue.java	(revision 481)
@@ -0,0 +1,1297 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.vue;
+
+import JamaPlus.*;
+import java.io.*;
+import java.util.*;
+import java.util.ArrayList;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableModel;
+import javax.swing.text.SimpleAttributeSet;
+import visuAnalec.*;
+import visuAnalec.util.*;
+import visuAnalec.Message.*;
+import visuAnalec.elements.*;
+import visuAnalec.donnees.*;
+import visuAnalec.donnees.Corpus.*;
+import visuAnalec.texte.PanneauTexte;
+import visuAnalec.texte.PanneauTexte.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class Vue implements CorpusListener {
+  public static interface VueListener extends EventListener {
+    void traiterEvent(Message e);     // relaie les messages de Corpus + envoie ses propres messages (VueEvent)
+  }
+
+  public static class Adresse implements Serializable {
+    ArrayList<Jalon> chemin;
+    String prop;
+    Adresse(Adresse adresse, String prop) {
+      this.prop = prop;
+      this.chemin = new ArrayList<Jalon>(adresse.chemin);
+    }
+    Adresse(Adresse adresse, Jalon jalon) {
+      this.prop = null;
+      ArrayList<Jalon> chemin1 = new ArrayList<Jalon>(adresse.chemin);
+      chemin1.add(jalon);
+      this.chemin = chemin1;
+    }
+    Adresse(Adresse adresse) {
+      this.prop = adresse.prop;
+      this.chemin = new ArrayList<Jalon>();
+      for (Jalon jalon : adresse.chemin) this.chemin.add(new Jalon(jalon));
+    }
+    Adresse(Jalon jalon, String prop) {
+      this.prop = prop;
+      chemin = new ArrayList<Jalon>(Arrays.asList(jalon));
+    }
+    Adresse(Jalon jalon) {
+      this.prop = null;
+      chemin = new ArrayList<Jalon>(Arrays.asList(jalon));
+    }
+    int getLongueur() {
+      return chemin.size();
+    }
+    Jalon getLastJalon() {
+      return chemin.get(chemin.size()-1);
+    }
+    void renommer(Class<? extends Element> classe, String oldType, String newType) {
+      for (Jalon jalon : chemin)
+        if (jalon.classe==classe&&jalon.type.equals(oldType))
+          jalon.type = newType;
+    }
+    boolean contient(Class<? extends Element> classe, String type) {
+      for (Jalon jalon : chemin) {
+        if (jalon.classe==classe&&jalon.type.equals(type)) return true;
+      }
+      return false;
+    }
+    @Override
+    public String toString() {
+      String nom = "";
+      for (Jalon jalon : chemin) {
+        nom += jalon;
+      }
+      nom += ": "+prop;
+      return nom;
+    }
+  }
+
+  public static class Jalon implements Serializable {
+    public enum Origine {
+      ELT_0, ELT_1, ELT_2, REL_SORTANTE, REL_ENTRANTE, SCH_CONTENANT
+    }
+    /**
+     * L'origine d'un jalon indique d'où ce jalon provient :
+     * ELT_0 est  un jalon de classe quelconque qui est toujours le premier jalon d'une adresse complète. 
+     * ELT_1 et ELT_2 sont des jalons de classe quelconque qui proviennent d'un jalon précédent de classe Relation  
+     * REL_S et REL_E sont des jalons de classe Relation qui proviennent d'un jalon précédent de classe quelconque
+     * SCH_C est un jalon de classe Schema qui provient d'un jalon précédent de classe quelconque
+     */
+    public Origine origine;
+    public Class<? extends Element> classe;
+    public String type;
+    Jalon(Origine origine, Class<? extends Element> classe, String type) {
+      this.classe = classe;
+      this.origine = origine;
+      this.type = type;
+    }
+    Jalon(Jalon jalon) {
+      this.classe = jalon.classe;
+      this.origine = jalon.origine;
+      this.type = jalon.type;
+    }
+    @Override
+    public String toString() {
+      switch (origine) {
+        case SCH_CONTENANT:
+          return "{"+type;
+        case REL_ENTRANTE:
+          return "<"+type+"<";
+        case REL_SORTANTE:
+          return ">"+type+">";
+        case ELT_0:
+          return type;
+        case ELT_1:
+          return type;
+        case ELT_2:
+          return type;
+        default:
+          return "ERREUR!!";
+      }
+    }
+  }
+  /** 
+   * Champs de la classe Vue :
+   * Données spécifiant la vue: 
+   *   - typesA voir, champs, adresses, modifiables
+   *   - champsId
+   * (ce sont les seuls champs à sauvegarder et à recharger) 
+   * Le champ unitesAVoir est un raccourci pour éviter de retrier chaque fois les données correspondantes de Corpus
+   */
+  private ArrayList<VueListener> listeCorrespondants = new ArrayList<VueListener>();
+  private Corpus corpus;
+  private boolean modifiee = false;
+  ;
+  // types d'éléments à voir pour chaque classe
+  private HashMap<Class<? extends Element>, String[]> typesAVoir =
+          new HashMap<Class<? extends Element>, String[]>();
+  // champs en ordre (niveau et position) pour chaque type d'éléments à voir pour chaque classe 
+  private HashMap<Class<? extends Element>, HashMap<String, String[][]>> champspos =
+          new HashMap<Class<? extends Element>, HashMap<String, String[][]>>();
+  // adresse pour chaque champ pour chaque  type d'élément à voir pour chaque classe
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Adresse>>> adresses =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Adresse>>>();
+  // modifiabilité pour chaque champ pour chaque  type d'élément à voir pour chaque classe
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> modifiables =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>>();
+  // champ choisi comme identifiant (s'il existe) pour chaque type de chaque classe
+  private HashMap<Class<? extends Element>, HashMap<String, String>> champsId =
+          new HashMap<Class<? extends Element>, HashMap<String, String>>();
+// style pour tout le texte
+  private SimpleAttributeSet styleTexte;
+  // style (s'il existe) pour chaque type de chaque classe
+  private HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> stylesElements =
+          new HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>>();
+  // style (s'il existe) pour chaque valeur de chaque champ de chaque type de chaque classe
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> stylesValeursElements =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>>();
+  // unites par type d'unites à voir
+  private HashMap<String, Unite[]> unitesAVoir = new HashMap<String, Unite[]>();
+  /* Constructeur de la classe Vue */
+  @SuppressWarnings("unchecked")
+  public Vue(Corpus corpus) {
+    this.corpus = corpus;
+    corpus.addEventListener(this);
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      typesAVoir.put(classe, new String[0]);
+      champspos.put(classe, new HashMap<String, String[][]>());
+      adresses.put(classe, new HashMap<String, HashMap<String, Adresse>>());
+      modifiables.put(classe, new HashMap<String, HashMap<String, Boolean>>());
+      champsId.put(classe, new HashMap<String, String>());
+      stylesElements.put(classe, new HashMap<String, SimpleAttributeSet>());
+      stylesValeursElements.put(classe, new HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>());
+    }
+    this.styleTexte = new SimpleAttributeSet(PanneauTexte.STANDARD_DEFAUT);
+  }
+  public void addEventListener(VueListener correspondant) {
+    listeCorrespondants.add(correspondant);
+  }
+  public void removeEventListener(VueListener correspondant) {
+    listeCorrespondants.remove(correspondant);
+  }
+  private void fireMessage(Message evt) {
+    for (Object corresp : listeCorrespondants.toArray()) {
+      ((VueListener) corresp).traiterEvent(evt);
+    }
+  }
+  public boolean isModifiee() {
+    return modifiee;
+  }
+  public void ecrireJava(ObjectOutputStream oos) throws IOException {
+    oos.writeObject(typesAVoir);
+    oos.writeObject(champspos);
+    oos.writeObject(adresses);
+    oos.writeObject(modifiables);
+    oos.writeObject(champsId);
+    oos.writeObject(styleTexte);
+    oos.writeObject(stylesElements);
+    oos.writeObject(stylesValeursElements);
+    modifiee = false;
+  }
+  @SuppressWarnings("unchecked")
+  public boolean lireJava(ObjectInputStream ois) throws IOException, ClassNotFoundException, ClassCastException {
+    HashMap<Class<? extends Element>, String[]> typesAVoirLus =
+            (HashMap<Class<? extends Element>, String[]>) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, String[][]>> champsposLus =
+            (HashMap<Class<? extends Element>, HashMap<String, String[][]>>) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Adresse>>> adressesLues =
+            (HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Adresse>>>) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> modifablesLus =
+            (HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>>) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, String>> champsIdLus =
+            (HashMap<Class<? extends Element>, HashMap<String, String>>) ois.readObject();
+    SimpleAttributeSet styleTexteLu = (SimpleAttributeSet) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> stylesElementsLus =
+            (HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>>) ois.readObject();
+    HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> stylesValeursElementsLus =
+            (HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>>) ois.readObject();
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      for (String type : typesAVoirLus.get(classe)) {
+        if (!corpus.getStructure().getTypes(classe).contains(type))
+          return false;
+      }
+    }
+    // En prévision d'une compatibilité ascendante
+    boolean suite = false;
+    try {
+      suite = ois.readBoolean();
+    } catch (EOFException eOFException) {
+    }
+    if (suite) {
+      System.out.println("Il y a d'autres objets dans le .ecv");
+    }
+    typesAVoir = typesAVoirLus;
+    champspos = champsposLus;
+    adresses = adressesLues;
+    modifiables = modifablesLus;
+    champsId = champsIdLus;
+    styleTexte = styleTexteLu;
+    stylesElements = stylesElementsLus;
+    stylesValeursElements = stylesValeursElementsLus;
+    unitesAVoir.clear();
+    modifiee = false;
+    for (String type : typesAVoir.get(Unite.class)) majUnitesAVoir(type);
+    fireMessage(new VueEvent(this, TypeModifVue.NEW_VUE));
+    return true;
+  }
+  public void traiterEvent(Message evt) { // Messages de corpus
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        initVueParDefaut();
+        fireMessage(evt);
+        return;
+      case NEW_CORPUS:
+        initVueParDefaut();
+        fireMessage(evt);
+        return;
+      case MODIF_TEXTE:
+        fireMessage(evt);
+        return;
+      case MODIF_ELEMENT:
+        ElementEvent evtE = (ElementEvent) evt;
+        switch (evtE.getModif()) {
+          case AJOUT_UNITE:
+            if (!unitesAVoir.containsKey(evtE.getElement().getType())) return;
+            majUnitesAVoir(evtE.getElement().getType());
+            fireMessage(evt);
+            return;
+          case SUP_UNITE:
+            if (!unitesAVoir.containsKey(evtE.getElement().getType())) return;
+            majUnitesAVoir(evtE.getElement().getType());
+            fireMessage(evt);
+            return;
+          case AJOUT_RELATION:
+          case AJOUT_SCHEMA:
+          case SUP_RELATION:
+          case SUP_SCHEMA:
+          case BORNES_UNITE:
+          case MODIF_SCHEMA:
+          case MODIF_VALEUR:
+            fireMessage(evt);
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas "+evtE.getModif()+" oublié dans un switch");
+        }
+      case MODIF_STRUCTURE:
+        StructureEvent evtS = (StructureEvent) evt;
+        switch (evtS.getModif()) {
+          case FUSION_TYPE:
+            fusionnerType(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1));
+            fireMessage(evt);
+            return;
+          case RENOM_TYPE:
+            renommerType(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1));
+            fireMessage(evt);
+            return;
+          case AJOUT_TYPE:
+            ajouterType(evtS.getClasse(), evtS.getArg());
+            fireMessage(evt);
+            return;
+          case AJOUT_TYPE_ET_ELEMENTS:
+            ajouterType(evtS.getClasse(), evtS.getArg());
+            if (evtS.getClasse()==Unite.class&&unitesAVoir.containsKey(evtS.getArg()))
+              majUnitesAVoir(evtS.getArg());
+            fireMessage(evt);
+            return;
+          case SUPPR_TYPE:
+            supprimerType(evtS.getClasse(), evtS.getArg());
+            fireMessage(evt);
+            return;
+          case AJOUT_PROP:
+            ajouterProp(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1));
+            fireMessage(evt);
+            return;
+          case AJOUT_FORME_UNITE:
+            ajouterFormeUnite(evtS.getArg(0));
+            fireMessage(evt);
+            return;
+          case FUSION_PROP:
+            fusionnerProp(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1), evtS.getArg(2));
+            fireMessage(evt);
+            return;
+          case RENOM_PROP:
+            renommerProp(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1), evtS.getArg(2));
+            fireMessage(evt);
+            return;
+          case SUPPR_PROP:
+            supprimerProp(evtS.getClasse(), evtS.getArg(0), evtS.getArg(1));
+            fireMessage(evt);
+            return;
+          case RENOM_VALEUR:
+          case FUSION_VALEUR:
+          case SUPPR_VALEUR:
+          case AJOUT_VALEUR:
+            fireMessage(evt);
+            return;
+          case VALEUR_PAR_DEFAUT:
+            fireMessage(evt);
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas "+evtS.getModif()+" oublié dans un switch");
+        }
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  @SuppressWarnings("unchecked")
+  private void initVueParDefaut() {
+    unitesAVoir.clear();
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      String[] types = getTypes(classe);
+      Arrays.sort(types);
+      typesAVoir.put(classe, types);
+      champspos.get(classe).clear();
+      adresses.get(classe).clear();
+      champsId.get(classe).clear();
+      styleTexte = new SimpleAttributeSet(PanneauTexte.STANDARD_DEFAUT);
+      stylesElements.get(classe).clear();
+      stylesValeursElements.get(classe).clear();
+      for (String type : typesAVoir.get(classe)) {
+        Jalon jalon0 = new Jalon(Jalon.Origine.ELT_0, classe, type);
+        String[] chps = getNomsProps(new Adresse(jalon0));
+        champspos.get(classe).put(type, new String[1][]);
+        champspos.get(classe).get(type)[0] = chps;
+        adresses.get(classe).put(type, new HashMap<String, Adresse>());
+        modifiables.get(classe).put(type, new HashMap<String, Boolean>());
+        for (String chp : chps) {
+          adresses.get(classe).get(type).put(chp, new Adresse(jalon0, chp));
+          modifiables.get(classe).get(type).put(chp, true);
+        }
+        if (classe==Unite.class) majUnitesAVoir(type);
+      }
+    }
+    modifiee = false;
+    fireMessage(new VueEvent(this, TypeModifVue.VUE_DEFAUT));
+
+  }
+  private void majUnitesAVoir(String typeUnite) {
+    Unite[] unts = corpus.getUnites(typeUnite).toArray(new Unite[0]);
+    Arrays.sort(unts);
+    unitesAVoir.put(typeUnite, unts);
+  }
+  public void retablirVueParDefaut() {
+    initVueParDefaut();
+  }
+  public void setStyleTexte(SimpleAttributeSet att) {
+    styleTexte = att;
+  }
+  public SimpleAttributeSet getStyleTexte() {
+    return styleTexte;
+  }
+  public void modifierVueParSaisie(
+          HashMap<Class<? extends Element>, HashMap<String, Boolean>> newIsTypesAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> newAdressesAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> newChampsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, String>> newChampsId,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> newModifables,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> newPositionsChamps,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> newNiveauxChamps,
+          HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> newStylesElements,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> newStylesValeursElements) {
+    setTypesAVoir(newIsTypesAVoir);
+    setChampsAdresses(newChampsAVoir, newAdressesAVoir, newPositionsChamps, newNiveauxChamps);
+    setChampsModifiables(newChampsAVoir, newModifables);
+    setChampsId(newChampsId);
+    setStylesElements(newStylesElements);
+    setStylesValeursElements(newStylesValeursElements);
+    unitesAVoir.clear();
+    for (String typeUnite : typesAVoir.get(Unite.class))
+      majUnitesAVoir(typeUnite);
+    modifiee = true;
+    fireMessage(new VueEvent(this, TypeModifVue.EXTRACTION));
+  }
+  @SuppressWarnings("unchecked")
+  private void setTypesAVoir(HashMap<Class<? extends Element>, HashMap<String, Boolean>> isAVoir) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      ArrayList<String> types = new ArrayList<String>();
+      for (String type : getTypes(classe)) if (isAVoir.get(classe).get(type))
+          types.add(type);
+      typesAVoir.put(classe, types.toArray(new String[0]));
+    }
+  }
+  @SuppressWarnings("unchecked")
+  private void setChampsAdresses(
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> positionsChamps,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> niveauxChamps) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      adresses.get(classe).clear();
+      for (int i = 0; i<typesAVoir.get(classe).length; i++) {
+        String type = typesAVoir.get(classe)[i];
+        ArrayList<String> chps = champsAVoir.get(classe).get(type);
+        adresses.get(classe).put(type, new HashMap<String, Adresse>());
+        for (int j = 0; j<chps.size(); j++)
+          adresses.get(classe).get(type).put(chps.get(j), adressesAVoir.get(classe).get(type).get(j));
+        champspos.get(classe).put(type, ordonnerChamps(chps, niveauxChamps.get(classe).get(type),
+                positionsChamps.get(classe).get(type)));
+      }
+    }
+  }
+  private String[][] insererChamp(String[][] chpsenordre, String newchp) {
+    if (chpsenordre.length==0) {
+      String[][] chps = new String[1][1];
+      chps[0][0] = newchp;
+      return chps;
+    }
+    String[] chs1 = new String[chpsenordre[0].length+1];
+    chs1[0] = newchp;
+    System.arraycopy(chpsenordre[0], 0, chs1, 1, chpsenordre[0].length);
+    chpsenordre[0] = chs1;
+    return chpsenordre;
+  }
+  private String[][] ordonnerChamps(ArrayList<String> chps, HashMap<String, Integer> nivx, HashMap<String, Integer> poss) {
+    HashMap<Integer, HashMap<Integer, ArrayList<String>>> chpstries =
+            new HashMap<Integer, HashMap<Integer, ArrayList<String>>>();
+    for (String ch : chps) {
+      int niv = nivx.get(ch);
+      if (!chpstries.containsKey(niv))
+        chpstries.put(niv, new HashMap<Integer, ArrayList<String>>());
+      int pos = poss.get(ch);
+      if (!chpstries.get(niv).containsKey(pos))
+        chpstries.get(niv).put(pos, new ArrayList<String>());
+      chpstries.get(niv).get(pos).add(ch);
+    }
+    Integer[] niveaux = chpstries.keySet().toArray(new Integer[0]);
+    Arrays.sort(niveaux);
+    String[][] chpsenordre = new String[niveaux.length][];
+    int niveauenordre = 0;
+    for (int niv : niveaux) {
+      Integer[] positions = chpstries.get(niv).keySet().toArray(new Integer[0]);
+      Arrays.sort(positions);
+      int nbch = 0;
+      for (int pos : positions) nbch += chpstries.get(niv).get(pos).size();
+      chpsenordre[niveauenordre] = new String[nbch];
+      int positionenordre = 0;
+      for (int pos : positions) {
+        String[] chs = chpstries.get(niv).get(pos).toArray(new String[0]);
+        Arrays.sort(chs);
+        for (String ch : chs)
+          chpsenordre[niveauenordre][positionenordre++] = ch;
+      }
+      niveauenordre++;
+    }
+    return chpsenordre;
+  }
+  @SuppressWarnings("unchecked")
+  private void setChampsModifiables(HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> newChampsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> newModifables) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      modifiables.get(classe).clear();
+      for (int i = 0; i<typesAVoir.get(classe).length; i++) {
+        String type = typesAVoir.get(classe)[i];
+        modifiables.get(classe).put(type, new HashMap<String, Boolean>());
+        for (String chp : newChampsAVoir.get(classe).get(type))
+          modifiables.get(classe).get(type).put(chp, newModifables.get(classe).get(type).get(chp));
+      }
+    }
+  }
+  @SuppressWarnings("unchecked")
+  private void setChampsId(HashMap<Class<? extends Element>, HashMap<String, String>> newChampsId) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      champsId.get(classe).clear();
+      champsId.get(classe).putAll(newChampsId.get(classe));
+    }
+  }
+  @SuppressWarnings("unchecked")
+  private void setStylesElements(HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> newStylesElements) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      stylesElements.get(classe).clear();
+      stylesElements.get(classe).putAll(newStylesElements.get(classe));
+    }
+  }
+  @SuppressWarnings("unchecked")
+  private void setStylesValeursElements(HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> newStylesValeursElements) {
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      stylesValeursElements.get(classe).clear();
+      stylesValeursElements.get(classe).putAll(newStylesValeursElements.get(classe));
+    }
+  }
+  public Corpus getCorpus() {
+    return corpus;
+  }
+  public String[] getTypes(Class<? extends Element> classe) {
+    String[] types = corpus.getStructure().getTypes(classe).toArray(new String[0]);
+    Arrays.sort(types);
+    return types;
+  }
+  @SuppressWarnings("unchecked")
+  public HashMap<Class<? extends Element>, HashMap<String, Boolean>> isTypesAVoir() {
+    HashMap<Class<? extends Element>, HashMap<String, Boolean>> isAVoir =
+            new HashMap<Class<? extends Element>, HashMap<String, Boolean>>();
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      isAVoir.put(classe, new HashMap<String, Boolean>());
+      for (String type : getTypes(classe)) isAVoir.get(classe).put(type, false);
+      for (String type : typesAVoir.get(classe))
+        isAVoir.get(classe).put(type, true);
+    }
+    return isAVoir;
+  }
+  String[] getTypesAVoir(Class<? extends Element> classe) {
+    return typesAVoir.get(classe);
+  }
+  public String[] getTypesUnitesAVoir() {
+    return getTypesAVoir(Unite.class);
+  }
+  public String[] getTypesRelationsAVoir() {
+    return getTypesAVoir(Relation.class);
+  }
+  public String[] getTypesSchemasAVoir() {
+    return getTypesAVoir(Schema.class);
+  }
+  public String getChampId(Class<? extends Element> classe, String type) {
+    return champsId.get(classe).get(type);
+  }
+  public SimpleAttributeSet getStyleElements(Class<? extends Element> classe, String type) {
+    return stylesElements.get(classe).get(type);
+  }
+  public HashMap<String, HashMap<String, SimpleAttributeSet>> getStyleValeursElements(
+          Class<? extends Element> classe, String type) {
+    return stylesValeursElements.get(classe).get(type);
+  }
+  public String[][] getChamps(Class<? extends Element> classe, String type) {
+    if (champspos.get(classe).containsKey(type)) {
+      return champspos.get(classe).get(type);
+    } else {
+      return new String[0][];
+    }
+  }
+  public String[] getNomsChamps(Class<? extends Element> classe, String type) {
+    return getListeChamps(classe, type).toArray(new String[0]);
+  }
+  ArrayList<String> getListeChamps(Class<? extends Element> classe, String type) {
+    // utilisé aussi par VisuVue
+    ArrayList<String> lchps = new ArrayList<String>();
+    if (champspos.get(classe).containsKey(type))
+      for (String[] champsniveau : champspos.get(classe).get(type))
+        lchps.addAll(Arrays.asList(champsniveau));
+    return lchps;
+  }
+  static String trouveNomChampParDefaut(Adresse ad, ArrayList<String> chps) {
+    String nom;
+    if (ad.chemin.size()==1) {
+      nom = ad.prop;
+      while (chps.contains(nom)) nom += "-0";
+      return nom;
+    }
+    for (int i = 1; true; i++) {
+      nom = ad.prop+"-"+i;
+      if (!chps.contains(nom)) {
+        return nom;
+      }
+    }
+  }
+  String[] getNomsProps(Adresse adresse) {
+    String[] props;
+    Jalon jalon = adresse.getLastJalon();
+    props = corpus.getStructure().getNomsProps(jalon.classe, jalon.type).toArray(new String[0]);
+    Arrays.sort(props);
+    return props;
+  }
+  String[] getValeursProp(Adresse adresse) {
+    String[] vals;
+    Jalon jalon = adresse.getLastJalon();
+    vals = corpus.getStructure().getValeursProp(jalon.classe, jalon.type, adresse.prop).toArray(new String[0]);
+    Arrays.sort(vals);
+    return vals;
+  }
+  @SuppressWarnings("unchecked")
+  Jalon[] getNextJalonsPotentiels(Adresse adresse) {
+    ArrayList<Jalon> nextJalons = new ArrayList<Jalon>();
+    Jalon jalon = adresse.getLastJalon();
+    switch (jalon.origine) {
+      case REL_ENTRANTE:
+        for (Class<? extends Element> cl : new Class[]{Unite.class, Relation.class, Schema.class}) {
+          for (String typeRel : getTypes(cl)) {
+            nextJalons.add(new Jalon(Jalon.Origine.ELT_1, cl, typeRel));
+          }
+        }
+        break;
+      case REL_SORTANTE:
+        for (Class<? extends Element> cl : new Class[]{Unite.class, Relation.class, Schema.class}) {
+          for (String typeRel : getTypes(cl)) {
+            nextJalons.add(new Jalon(Jalon.Origine.ELT_2, cl, typeRel));
+          }
+        }
+        break;
+      default:
+        for (String typeRel : getTypes(Relation.class)) {
+          nextJalons.add(new Jalon(Jalon.Origine.REL_SORTANTE, Relation.class, typeRel));
+        }
+        for (String typeRel : getTypes(Relation.class)) {
+          nextJalons.add(new Jalon(Jalon.Origine.REL_ENTRANTE, Relation.class, typeRel));
+        }
+        for (String typeSch : getTypes(Schema.class)) {
+          nextJalons.add(new Jalon(Jalon.Origine.SCH_CONTENANT, Schema.class, typeSch));
+        }
+        break;
+    }
+    return nextJalons.toArray(new Jalon[0]);
+  }
+  Adresse getAdresseChamps(Class<? extends Element> classe, String type, String nomChamp) {
+    if (adresses.get(classe).containsKey(type)) {
+      return adresses.get(classe).get(type).get(nomChamp);
+    } else {
+      return null;
+    }
+  }
+  public boolean isChampModifiable(Class<? extends Element> classe, String type, String champ) {
+    return modifiables.get(classe).get(type).get(champ);
+  }
+  public HashMap<String, Integer> getPositionsChampsAVoir(Class<? extends Element> classe, String type) {
+    HashMap<String, Integer> positions = new HashMap<String, Integer>();
+    if (champspos.get(classe).containsKey(type)) {
+      for (String[] champsniveau : champspos.get(classe).get(type)) {
+        int i = 0;
+        for (String ch : champsniveau) positions.put(ch, i++);
+      }
+    }
+    return positions;
+  }
+  public HashMap<String, Integer> getNiveauxChampsAVoir(Class<? extends Element> classe, String type) {
+    HashMap<String, Integer> niveaux = new HashMap<String, Integer>();
+    if (champspos.get(classe).containsKey(type)) {
+      int i = 0;
+      for (String[] champsniveau : champspos.get(classe).get(type)) {
+        for (String ch : champsniveau) niveaux.put(ch, i);
+        i++;
+      }
+    }
+    return niveaux;
+  }
+  public String[] getValeursChamp(Class<? extends Element> classe, String type, String champ) {
+    Adresse adresse = getAdresseChamps(classe, type, champ);
+    if (adresse==null) {
+      return new String[0];
+    }
+    return getValeursProp(adresse);
+  }
+  public String getValeurChamp(Element element, String champ) {
+    Adresse adresse = getAdresseChamps(element.getClass(), element.getType(), champ);
+    if (adresse==null) {
+      return "";
+    }
+    Element elt = element;
+    for (Jalon jalon : adresse.chemin) {
+      if ((elt = elt.getElementSuivant(jalon))==null) return "";
+    }
+    return elt.getProp(adresse.prop);
+  }
+  public boolean setValeurChamp(Element element, String champ, String newval) {
+    Adresse adresse = getAdresseChamps(element.getClass(), element.getType(), champ);
+    Element elt = element;
+    for (Jalon jalon : adresse.chemin) {
+      elt = elt.getElementSuivant(jalon);
+      if (elt==null) return false;
+    }
+    corpus.setValeurPropElement(elt, adresse.prop, newval);
+    return true;
+  }
+  public void copierValeurs(Element eltSource, Element eltCible) {
+    Class<? extends Element> classe = eltSource.getClass();
+    if (eltCible.getClass()!=classe) return;
+    String type = eltSource.getType();
+    if (!eltCible.getType().equals(type)) return;
+    for (String champ : getListeChamps(classe, type))
+      if (isChampModifiable(classe, type, champ))
+        setValeurChamp(eltCible, champ, getValeurChamp(eltSource, champ));
+  }
+  private void ajouterType(Class<? extends Element> classe, String newType) {
+
+//      ArrayList<String> typs = new ArrayList<String>(Arrays.asList(typesUnitesAVoir));
+//      typs.add(newType);
+//      typesUnitesAVoir = typs.toArray(new String[0]);
+//      Arrays.sort(typesUnitesAVoir);
+    typesAVoir.put(classe, Tableaux.insererString(typesAVoir.get(classe), newType));
+    champspos.get(classe).put(newType, new String[0][]);
+    adresses.get(classe).put(newType, new HashMap<String, Adresse>());
+    if (classe==Unite.class) unitesAVoir.put(newType, new Unite[0]);
+    modifiables.get(classe).put(newType, new HashMap<String, Boolean>());
+  }
+  private void renommerType(Class<? extends Element> classe, String oldType, String newType) {
+    for (Class<? extends Element> cl : adresses.keySet())
+      for (String type : adresses.get(cl).keySet())
+        for (String chp : adresses.get(cl).get(type).keySet()) {
+          adresses.get(cl).get(type).get(chp).renommer(classe, oldType, newType);
+        }
+    int ind = Arrays.binarySearch(typesAVoir.get(classe), oldType);
+    if (ind>=0) {
+      typesAVoir.get(classe)[ind] = newType;
+      Arrays.sort(typesAVoir.get(classe));
+      champspos.get(classe).put(newType, champspos.get(classe).get(oldType));
+      champspos.get(classe).remove(oldType);
+      adresses.get(classe).put(newType, adresses.get(classe).get(oldType));
+      adresses.get(classe).remove(oldType);
+      if (champsId.get(classe).containsKey(oldType)) {
+        champsId.get(classe).put(newType, champsId.get(classe).get(oldType));
+        champsId.get(classe).remove(oldType);
+      }
+      modifiables.get(classe).put(newType, modifiables.get(classe).get(oldType));
+      if (classe==Unite.class) {
+        unitesAVoir.put(newType, unitesAVoir.get(oldType));
+        unitesAVoir.remove(oldType);
+      }
+      if (stylesElements.get(classe).containsKey(oldType)) {
+        stylesElements.get(classe).put(newType, stylesElements.get(classe).get(oldType));
+        stylesElements.get(classe).remove(oldType);
+      }
+      if (stylesValeursElements.get(classe).containsKey(oldType)) {
+        stylesValeursElements.get(classe).put(newType, stylesValeursElements.get(classe).get(oldType));
+        stylesValeursElements.get(classe).remove(oldType);
+      }
+    }
+  }
+  private void fusionnerType(Class<? extends Element> classe, String oldType, String newType) {
+    int indold = Arrays.binarySearch(typesAVoir.get(classe), oldType);
+    if (indold>=0) {
+      int indnew = Arrays.binarySearch(typesAVoir.get(classe), newType);
+      if (indnew>=0) {
+        ArrayList<String> chpsnewtype = getListeChamps(classe, newType);
+        HashMap<String, Integer> nivxnewtype = getNiveauxChampsAVoir(classe, newType);
+        HashMap<String, Integer> possnewtype = getPositionsChampsAVoir(classe, newType);
+        for (String chpoldtype : getListeChamps(classe, oldType)) {
+          Adresse adroldtype = adresses.get(classe).get(oldType).get(chpoldtype);
+          String nomchamp = trouveNomChampParDefaut(adroldtype, chpsnewtype);
+          adresses.get(classe).get(newType).put(nomchamp, adroldtype);
+          chpsnewtype.add(nomchamp);
+          nivxnewtype.put(nomchamp, getNiveauxChampsAVoir(classe, oldType).get(chpoldtype));
+          possnewtype.put(nomchamp, getPositionsChampsAVoir(classe, oldType).get(chpoldtype));
+          modifiables.get(classe).get(newType).put(nomchamp, modifiables.get(classe).get(oldType).get(chpoldtype));
+          if (stylesValeursElements.get(classe).containsKey(oldType)&&stylesValeursElements.get(classe).get(oldType).containsKey(chpoldtype)) {
+            if (!stylesValeursElements.get(classe).containsKey(newType))
+              stylesValeursElements.get(classe).put(newType, new HashMap<String, HashMap<String, SimpleAttributeSet>>());
+            stylesValeursElements.get(classe).get(newType).put(nomchamp,
+                    stylesValeursElements.get(classe).get(oldType).get(chpoldtype));
+          }
+        }
+        champspos.get(classe).put(newType, ordonnerChamps(chpsnewtype, nivxnewtype, possnewtype));
+      }
+      typesAVoir.put(classe, Tableaux.oterString(typesAVoir.get(classe), indold));
+      champspos.get(classe).remove(oldType);
+      adresses.get(classe).remove(oldType);
+      champsId.get(classe).remove(oldType);
+      modifiables.get(classe).remove(oldType);
+      stylesElements.get(classe).remove(oldType);
+      stylesValeursElements.get(classe).remove(oldType);
+      if (classe==Unite.class) {
+        majUnitesAVoir(newType);
+        unitesAVoir.remove(oldType);
+      }
+    }
+    for (Class<? extends Element> cl : typesAVoir.keySet())
+      for (String typ : typesAVoir.get(cl)) {
+        ArrayList<String> chpsASup = new ArrayList<String>();
+        ArrayList<String> chps = getListeChamps(cl, typ);
+        HashMap<String, Integer> nivx = getNiveauxChampsAVoir(cl, typ);
+        HashMap<String, Integer> poss = getPositionsChampsAVoir(cl, typ);
+        for (String ch : chps) {
+          Adresse ad = adresses.get(cl).get(typ).get(ch);
+          if (ad.contient(classe, oldType)) {
+            Adresse ad1 = new Adresse(ad);
+            ad1.renommer(classe, oldType, newType);
+            boolean dejala = false;
+            for (String ch1 : chps)
+              if (adresses.get(cl).get(typ).get(ch1).toString().equals(ad1.toString())) {
+                dejala = true;
+                break;
+              }
+            if (!dejala) adresses.get(cl).get(typ).put(ch, ad1);
+            else {
+              chpsASup.add(ch);
+              if (ch.equals(champsId.get(cl).get(typ)))
+                champsId.get(cl).remove(typ);
+              modifiables.get(cl).get(typ).remove(ch);
+              if (stylesValeursElements.get(cl).containsKey(typ))
+                stylesValeursElements.get(cl).get(typ).remove(ch);
+              nivx.remove(ch);
+              poss.remove(ch);
+            }
+          }
+        }
+        chps.removeAll(chpsASup);
+        for (String ch : chpsASup) adresses.get(cl).get(typ).remove(ch);
+        champspos.get(cl).put(typ, ordonnerChamps(chps, nivx, poss));
+      }
+  }
+  private void supprimerType(Class<? extends Element> classe, String type) {
+    int ind = Arrays.binarySearch(typesAVoir.get(classe), type);
+    if (ind>=0) {
+      typesAVoir.put(classe, Tableaux.oterString(typesAVoir.get(classe), ind));
+      champspos.get(classe).remove(type);
+      adresses.get(classe).remove(type);
+      if (classe==Unite.class) unitesAVoir.remove(type);
+    }
+    champsId.get(classe).remove(type);
+    modifiables.get(classe).remove(type);
+    stylesElements.get(classe).remove(type);
+    stylesValeursElements.get(classe).remove(type);
+    for (Class<? extends Element> cl : typesAVoir.keySet())
+      for (String typ : typesAVoir.get(cl)) {
+        ArrayList<String> chpsASup = new ArrayList<String>();
+        ArrayList<String> chps = getListeChamps(cl, typ);
+        HashMap<String, Integer> nivx = getNiveauxChampsAVoir(cl, typ);
+        HashMap<String, Integer> poss = getPositionsChampsAVoir(cl, typ);
+        for (String ch : chps)
+          if (adresses.get(cl).get(typ).get(ch).contient(classe, type)) {
+            chpsASup.add(ch);
+            adresses.get(cl).get(typ).remove(ch);
+            if (ch.equals(champsId.get(cl).get(typ)))
+              champsId.get(cl).remove(typ);
+            modifiables.get(cl).get(typ).remove(ch);
+            if (stylesValeursElements.get(cl).containsKey(typ))
+              stylesValeursElements.get(cl).get(typ).remove(ch);
+            nivx.remove(ch);
+            poss.remove(ch);
+          }
+        chps.removeAll(chpsASup);
+        champspos.get(cl).put(typ, ordonnerChamps(chps, nivx, poss));
+      }
+  }
+  private void ajouterProp(Class<? extends Element> classe, String type, String prop) {
+    if (Arrays.binarySearch(typesAVoir.get(classe), type)>=0) {
+      Adresse ad = new Adresse(new Jalon(Jalon.Origine.ELT_0, classe, type), prop);
+      String newchp = trouveNomChampParDefaut(ad, getListeChamps(classe, type));
+      champspos.get(classe).put(type, insererChamp(champspos.get(classe).get(type), newchp));
+      adresses.get(classe).get(type).put(newchp, ad);
+      modifiables.get(classe).get(type).put(newchp, true);
+    }
+  }
+  private void ajouterFormeUnite(String type) {
+    if (Arrays.binarySearch(typesAVoir.get(Unite.class), type)>=0) {
+      Adresse ad = new Adresse(new Jalon(Jalon.Origine.ELT_0, Unite.class, type), Structure.FORME);
+      champspos.get(Unite.class).put(type, insererChamp(champspos.get(Unite.class).get(type), Structure.FORME));
+      adresses.get(Unite.class).get(type).put(Structure.FORME, ad);
+      modifiables.get(Unite.class).get(type).put(Structure.FORME, false);
+    }
+  }
+  private void renommerProp(Class<? extends Element> classe, String type, String oldNom, String newNom) {
+    // on ne change que les adresses : on ne renomme les champs que dans certains cas (cf. renommerChamp appelé à la fin)
+    for (Class<? extends Element> cl : adresses.keySet())
+      for (String typ : adresses.get(cl).keySet())
+        for (String chp : adresses.get(cl).get(typ).keySet()) {
+          if (adresses.get(cl).get(typ).get(chp).getLastJalon().classe==classe
+                  &&type.equals(adresses.get(cl).get(typ).get(chp).getLastJalon().type)
+                  &&oldNom.equals(adresses.get(cl).get(typ).get(chp).prop)) {
+            adresses.get(cl).get(typ).get(chp).prop = newNom;
+          }
+        }
+    renommerChamp(classe, type, oldNom, newNom);
+  }
+  private void renommerChamp(Class<? extends Element> classe, String type, String oldNom, String newNom) {
+    // renomme aussi le champ quand la correspondance prop<=>champ est directe (notamment dans la vue par défaut)
+    if (!champspos.get(classe).containsKey(type))
+      throw new IllegalArgumentException();
+    String[][] chps = champspos.get(classe).get(type);
+    if (!adresses.get(classe).get(type).containsKey(oldNom))
+      throw new IllegalArgumentException();
+    if (adresses.get(classe).get(type).get(oldNom).getLongueur()>1) return;
+    if (!adresses.get(classe).get(type).get(oldNom).prop.equals(oldNom)) return;
+    boolean fait = false;
+    for (int niv = 0; niv<chps.length; niv++) {
+      for (int pos = 0; pos<chps[niv].length; pos++)
+        if (chps[niv][pos].equals(oldNom)) {
+          chps[niv][pos] = newNom;
+          fait = true;
+          break;
+        }
+      if (fait) break;
+    }
+    if (!fait) throw new IllegalArgumentException();
+    adresses.get(classe).get(type).put(newNom, adresses.get(classe).get(type).get(oldNom));
+    adresses.get(classe).get(type).remove(oldNom);
+    modifiables.get(classe).get(type).put(newNom, modifiables.get(classe).get(type).get(oldNom));
+    modifiables.get(classe).get(type).remove(oldNom);
+    if (champsId.get(classe).containsKey(type)&&champsId.get(classe).get(type).equals(oldNom))
+      champsId.get(classe).put(type, newNom);
+    if (stylesValeursElements.get(classe).containsKey(type)
+            &&stylesValeursElements.get(classe).get(type).containsKey(oldNom)) {
+      stylesValeursElements.get(classe).get(type).put(newNom,
+              stylesValeursElements.get(classe).get(type).get(oldNom));
+      stylesValeursElements.get(classe).get(type).remove(oldNom);
+    }
+  }
+  private void fusionnerProp(Class<? extends Element> classe, String type, String oldNom, String newNom) {
+    // pour le moment, on se contente de supprimer tous les champs qui utilisent l'ancienne prop
+    // c'est un peu grossier...
+    supprimerProp(classe, type, oldNom);
+  }
+  private void supprimerProp(Class<? extends Element> classe, String type, String prop) {
+    // on parcourt tous les champs et les adresses correspondantes
+    for (Class<? extends Element> cl : typesAVoir.keySet())
+      for (String typ : typesAVoir.get(cl)) {
+        ArrayList<String> chpsASup = new ArrayList<String>();
+        ArrayList<String> chps = getListeChamps(cl, typ);
+        HashMap<String, Integer> nivx = getNiveauxChampsAVoir(cl, typ);
+        HashMap<String, Integer> poss = getPositionsChampsAVoir(cl, typ);
+        for (String ch : chps) {
+          Adresse ad = adresses.get(cl).get(typ).get(ch);
+          if (ad.getLastJalon().classe==classe&&type.equals(ad.getLastJalon().type)&&prop.equals(ad.prop)) {
+            chpsASup.add(ch);
+            adresses.get(cl).get(typ).remove(ch);
+            modifiables.get(cl).get(typ).remove(ch);
+            if (ch.equals(champsId.get(cl).get(typ)))
+              champsId.get(cl).remove(typ);
+            if (stylesValeursElements.get(cl).containsKey(typ))
+              stylesValeursElements.get(cl).get(typ).remove(ch);
+            nivx.remove(ch);
+            poss.remove(ch);
+          }
+        }
+        chps.removeAll(chpsASup);
+        champspos.get(cl).put(typ, ordonnerChamps(chps, nivx, poss));
+      }
+  }
+  public Unite[] getUnites(String type) {
+    Unite[] units = corpus.getUnites(type).toArray(new Unite[0]);
+    Arrays.sort(units);
+    return units;
+  }
+  public Unite[] getUnitesAVoir(String type) {
+    if (unitesAVoir.get(type)==null) {
+      return new Unite[0];
+    }
+    return unitesAVoir.get(type);
+  }
+  public Relation[] getRelations(String type) {
+    Relation[] rels = corpus.getRelations(type).toArray(new Relation[0]);
+    Arrays.sort(rels);
+    return rels;
+  }
+  public Relation[] getRelationsAVoir(String type) {
+    // Pour l'instant, toutes les relations de ce type, mais ça peut changer avec la mise en place des sélections
+    // nécessitera peut-être la mise en place d'une variable relationsAVoir (comme pour les unités) 
+    Relation[] rels = corpus.getRelations(type).toArray(new Relation[0]);
+    Arrays.sort(rels);
+    return rels;
+  }
+  public Schema[] getSchemas(String type) {
+    Schema[] schs = corpus.getSchemas(type).toArray(new Schema[0]);
+    Arrays.sort(schs);
+    return schs;
+  }
+  public Schema[] getSchemasAVoir(String type) {
+    // Pour l'instant, tous les schémas de ce type, mais ça peut changer avec la mise en place des sélections
+    // nécessitera peut-être la mise en place d'une variable schemasAVoir (comme pour les unités) 
+    Schema[] schs = corpus.getSchemas(type).toArray(new Schema[0]);
+    Arrays.sort(schs);
+    return schs;
+  }
+  public Element[] getElements(Class<? extends Element> classe, String type) {
+    if (classe==Unite.class) return getUnites(type);
+    if (classe==Relation.class) return getRelations(type);
+    if (classe==Schema.class) return getSchemas(type);
+    throw new UnsupportedOperationException("sous-classe non traitée");
+  }
+  public Element[] getElementsAVoir(Class<? extends Element> classe, String type) {
+    if (classe==Unite.class) return getUnitesAVoir(type);
+    if (classe==Relation.class) return getRelationsAVoir(type);
+    if (classe==Schema.class) return getSchemasAVoir(type);
+    throw new UnsupportedOperationException("sous-classe non traitée");
+  }
+  public String getTexteUnite(Unite unit) {  // utilisé par ModeleChaines et par ModeleStatsGeometrie - à revoir : pas très efficace
+    return corpus.getTexteUnite(unit);
+  }
+  public String getIdElement(Element elt) {  // utilisé  par PanneauOccurrences
+    String type = elt.getType();
+    Class<? extends Element> classe = elt.getClass();
+    String champId = getChampId(classe, type);
+    String id;
+    if (champId!=null) {
+      id = getValeurChamp(elt, champId);
+      if (!id.isEmpty()) return id;
+    }
+    Element[] listeElts = getElements(classe, type);
+    if (listeElts==null) return "";
+    int no = Arrays.binarySearch(listeElts, elt);
+    if (no<0) return "";
+    return type+"-"+Integer.toString(no+1);
+  }
+  private String[] getIdElements(Class<? extends Element> classe, String type,
+          Element[] eltsCorpus, Element[] eltsATraiter) {
+    // eltsATraiter doit être  trié ; s'il est null, on prend toutes les éléments du corpus de ce type 
+    String champId = getChampId(classe, type);
+    String[] ids = new String[eltsATraiter==null ? eltsCorpus.length : eltsATraiter.length];
+    String id;
+    int i = 0;
+    for (int no = 0; no<eltsCorpus.length; no++) {
+      if (eltsATraiter==null||eltsATraiter[i]==eltsCorpus[no]) {
+        id = champId==null ? "" : getValeurChamp(eltsCorpus[no], champId);
+        ids[i++] = id.isEmpty() ? type+"-"+Integer.toString(no+1) : id;
+      }
+    }
+    return ids;
+  }
+  public String[] getIdUnites(String type) {  // toutes les unités du corpus de ce type 
+    return getIdElements(Unite.class, type, getUnites(type), null);
+  }
+  public String[] getIdUnites(String type, Unite[] unites) {    // unites doit être  trié 
+    return getIdElements(Unite.class, type, getUnites(type), unites);
+  }
+  public String[] getIdRelations(String type) {  // toutes les relations du corpus de ce type 
+    return getIdElements(Relation.class, type, getRelations(type), null);
+  }
+  public String[] getIdRelations(String type, Relation[] relations) {   // relations doit être  trié 
+    return getIdElements(Relation.class, type, getRelations(type), relations);
+  }
+  public String[] getIdSchemas(String type) {  // tous les schémas du corpus de ce type 
+    return getIdElements(Schema.class, type, getSchemas(type), null);
+  }
+  public String[] getIdSchemas(String type, Schema[] schemas) {    // schemas doit être  trié 
+    return getIdElements(Schema.class, type, getSchemas(type), schemas);
+  }
+  public String[] getIdElements(Class<? extends Element> classe, String type) {
+    if (classe==Relation.class) return getIdRelations(type);
+    if (classe==Schema.class) return getIdSchemas(type);
+    return getIdUnites(type);
+  }
+  /**
+   * Fonction pour le coloriage
+   */
+  public UniteColoree[] getUnitesAColorier() {
+    ArrayList<UniteColoree> unites = new ArrayList<UniteColoree>();
+    for (Class<? extends Element> classe : stylesElements.keySet())
+      for (String type : stylesElements.get(classe).keySet()) {
+        for (Unite unit : Element.getUnitesSousjacentes(getElementsAVoir(classe, type)))
+          unites.add(new UniteColoree(unit, stylesElements.get(classe).get(type)));
+      }
+    for (Class<? extends Element> classe : stylesValeursElements.keySet())
+      for (String type : stylesValeursElements.get(classe).keySet())
+        for (String champ : stylesValeursElements.get(classe).get(type).keySet())
+          for (String valeur : stylesValeursElements.get(classe).get(type).get(champ).keySet()) {
+            for (Unite unit : Element.getUnitesSousjacentes(getElementsAVoirValeurChamp(classe, type, champ, valeur)))
+              unites.add(new UniteColoree(unit, stylesValeursElements.get(classe).get(type).get(champ).get(valeur)));
+          }
+    return unites.toArray(new UniteColoree[0]);
+  }
+  public Element[] getElementsAVoirValeurChamp(Class<? extends Element> classe,
+          String type, String champ, String valeur) {
+    ArrayList<Element> elts = new ArrayList<Element>();
+    for (Element elt : getElementsAVoir(classe, type))
+      if (valeur.equals(getValeurChamp(elt, champ))) elts.add(elt);
+    return elts.toArray(new Element[0]);
+  }
+  /**
+   * Fonctions de comptage pour les stats
+   */
+  public int getNbElementsAVoir(Class<? extends Element> classe, String type) {
+    return getElementsAVoir(classe, type).length;
+  }
+  public HashMap<String, Integer> compterOccurrencesFiltrees(Class<? extends Element> classe,
+          String type, String champCible, String champFiltre, String[] valeursChampFiltre) {
+    HashMap<String, Integer> compte = initCompte(classe, type, champCible);
+    for (Element elt : getElementsAVoir(classe, type)) {
+      String valCible = getValeurChamp(elt, champCible);
+      if (champFiltre==null) {
+        compte.put(valCible, compte.get(valCible)+1);
+      } else {
+        String valfiltre = getValeurChamp(elt, champFiltre);
+        for (Object valchfiltre : valeursChampFiltre) {
+          if (valfiltre.equals(valchfiltre)) {
+            compte.put(valCible, compte.get(valCible)+1);
+            break;
+          }
+        }
+      }
+    }
+    return compte;
+  }
+  public HashMap<String, HashMap<String, Integer>> compterOccurrencesCorrelees(
+          Class<? extends Element> classe, String type, String champ1, String champ2) {
+    HashMap<String, HashMap<String, Integer>> compte = new HashMap<String, HashMap<String, Integer>>();
+    for (String val : getValeursChamp(classe, type, champ1)) {
+      compte.put(val, initCompte(classe, type, champ2));
+    }
+    compte.put("", initCompte(classe, type, champ2));
+    for (Element elt : getElementsAVoir(classe, type)) {
+      String val1 = getValeurChamp(elt, champ1);
+      String val2 = getValeurChamp(elt, champ2);
+      compte.get(val1).put(val2, compte.get(val1).get(val2)+1);
+    }
+    return compte;
+  }
+  private HashMap<String, Integer> initCompte(Class<? extends Element> classe, String type, String champ) {
+    HashMap<String, Integer> hm = new HashMap<String, Integer>();
+    for (String val : getValeursChamp(classe, type, champ)) {
+      hm.put(val, 0);
+    }
+    hm.put("", 0);
+    return hm;
+  }
+  public Element[] getDoubleSelectionOccurrences(Class<? extends Element> classe, String type,
+          String champ1, String[] valeurs1, String champ2, String[] valeurs2) {
+    ArrayList<Element> aliste = new ArrayList<Element>();
+    for (Element elt : getElementsAVoir(classe, type)) {
+      if (verifierContrainteFiltre(elt, champ1, valeurs1)&&verifierContrainteFiltre(elt, champ2, valeurs2)) {
+        aliste.add(elt);
+      }
+    }
+    Element[] res = aliste.toArray(new Element[0]);
+    Arrays.sort(res);
+    return res;
+  }
+  private boolean verifierContrainteFiltre(Element elt, String champ, String[] valeurs) {
+    if (champ==null) {
+      return true;
+    }
+    String valeur = getValeurChamp(elt, champ);
+    for (String val : valeurs) {
+      if (val.equals(valeur)) {
+        return true;
+      }
+    }
+    return false;
+  }
+  public Matrix getMatrice(Class<? extends Element> classe, String type, String[] champsSelect, Element[] eltsSelect) {
+    HashMap<String, HashMap<String, Integer>> numeros = new HashMap<String, HashMap<String, Integer>>();
+    int nb = 0;
+    for (String champ : champsSelect) {
+      numeros.put(champ, new HashMap<String, Integer>());
+      numeros.get(champ).put("", nb++);
+      for (String val : getValeursChamp(classe, type, champ)) {
+        numeros.get(champ).put(val, nb++);
+      }
+    }
+    double[][] matrice = new double[eltsSelect.length][nb];
+    for (int i = 0; i<eltsSelect.length; i++) {
+      for (String champ : champsSelect) {
+        matrice[i][numeros.get(champ).get(getValeurChamp(eltsSelect[i], champ))] = 1.;
+      }
+    }
+    return new Matrix(matrice, eltsSelect.length, nb);
+  }
+  public SparseMatrix getMatriceCreuse(Class<? extends Element> classe, String type,
+          String[] champsSelect, Element[] eltsSelect) {
+    HashMap<String, HashMap<String, Integer>> numeros =
+            new HashMap<String, HashMap<String, Integer>>();
+    int nb = 0;
+    for (String champ : champsSelect) {
+      numeros.put(champ, new HashMap<String, Integer>());
+      numeros.get(champ).put("", nb++);
+      for (String val : getValeursChamp(classe, type, champ))
+        numeros.get(champ).put(val, nb++);
+    }
+//    double[][] matrice = new double[eltsSelect.length][nb];
+    ArrayList<Integer> rows = new ArrayList<Integer>();
+    ArrayList<Integer> cols = new ArrayList<Integer>();
+    for (int i = 0; i<eltsSelect.length; i++)
+      for (String champ : champsSelect) {
+        rows.add(i);
+        cols.add(numeros.get(champ).get(getValeurChamp(eltsSelect[i], champ)));
+      }
+    return new SparseMatrix(eltsSelect.length, nb, rows, cols, 1);
+  }
+
+  public static class TripletValTypique {
+    public String champ;
+    public String valeur;
+    public float pourcentage;
+    public TripletValTypique(String champ, String valeur, float pourcentage) {
+      this.champ = champ;
+      this.valeur = valeur;
+      this.pourcentage = pourcentage;
+    }
+  }
+  public TripletValTypique[] getValTypiques(Class<? extends Element> classe,
+          String type, Element[] elts) {
+    ArrayList<String> chps = new ArrayList<String>();
+    ArrayList<String> vals = new ArrayList<String>();
+    ArrayList<Float> pcts = new ArrayList<Float>();
+    HashMap<String, Integer> compte = new HashMap<String, Integer>();
+    int total = elts.length;
+    for (String champ : getListeChamps(classe, type)) {
+      compte.clear();
+      for (Element elt : elts) {
+        String val = getValeurChamp(elt, champ);
+        if (val.isEmpty()) continue;
+        if (compte.containsKey(val)) compte.put(val, compte.get(val)+1);
+        else compte.put(val, 1);
+      }
+      for (String val : compte.keySet()) if (2*compte.get(val)>total) {
+          chps.add(champ);
+          vals.add(val);
+          pcts.add(((float) compte.get(val))/total);
+          break;
+        }
+    }
+    TripletValTypique[] triplets = new TripletValTypique[chps.size()];
+    for (int i = 0; i<chps.size(); i++)
+      triplets[i] = new TripletValTypique(chps.get(i), vals.get(i), pcts.get(i));
+    return triplets;
+  }
+  public String[] getIdListeElements(Class<? extends Element> classe,
+          String type, Element[] elts) {
+    return getIdElements(classe, type, elts, null);
+  }
+  public String[][] getValeursChampsListeElements(String[] champs, Element[] elts) {
+    String[][] valeurs = new String[elts.length][champs.length];
+    for (int i = 0; i<elts.length; i++) for (int j = 0; j<champs.length; j++)
+        valeurs[i][j] = getValeurChamp(elts[i], champs[j]);
+    return valeurs;
+  }
+  public TableModel tableauUnites(String type) {
+    if (getUnitesAVoir(type).length==0) return null;
+    return new TableUnites(type, this);
+  }
+
+  static public class TableUnites extends AbstractTableModel {
+    String type;
+    Vue vue;
+    Unite[] unites;
+    String[] champs;
+    TableUnites(String type, Vue vue) {
+      super();
+      this.type = type;
+      this.vue = vue;
+    }
+    public int getRowCount() {
+      return vue.getUnitesAVoir(type).length;
+    }
+    public int getColumnCount() {
+      return vue.getNomsChamps(Unite.class, type).length+3;
+    }
+    @Override
+    public String getColumnName(int col) {
+      switch (col) {
+        case 0:
+          return "#Id";
+        case 1:
+          return "From";
+        case 2:
+          return "To";
+        default:
+          return vue.getNomsChamps(Unite.class, type)[col-3];
+      }
+    }
+    public Object getValueAt(int row, int col) {
+      switch (col) {
+        case 0:
+          return row+1;
+        case 1:
+          return vue.getUnitesAVoir(type)[row].getDeb();
+        case 2:
+          return vue.getUnitesAVoir(type)[row].getFin();
+        default:
+          return vue.getValeurChamp(
+                  vue.getUnitesAVoir(type)[row],
+                  vue.getNomsChamps(Unite.class, type)[col-3]);
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/Vue.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVuePresentation.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVuePresentation.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVuePresentation.java	(revision 481)
@@ -0,0 +1,163 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.vue;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import visuAnalec.donnees.Structure;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class VisuVuePresentation extends JPanel implements ActionListener {
+  private VisuVue visuVue;
+  private Vue vue;
+  private JTable tableauChampsAVoir;
+  private JComboBox saisieChampId;
+  private Class<? extends Element> classeSelected;
+  private String typeSelected;
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> modifiabiliteChampsAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> niveauxChampsAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> positionsChampsAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, String>> champsId;
+  VisuVuePresentation(VisuVue visuVue, Vue vue,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, String>> champsId,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> modifiabiliteChampsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> niveauxChampsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> positionsChampsAVoir) {
+    super(new BorderLayout());
+    this.visuVue = visuVue;
+    this.vue = vue;
+    this.champsAVoir = champsAVoir;
+    this.champsId = champsId;
+    this.modifiabiliteChampsAVoir = modifiabiliteChampsAVoir;
+    this.niveauxChampsAVoir = niveauxChampsAVoir;
+    this.positionsChampsAVoir = positionsChampsAVoir;
+    classeSelected = null;
+    typeSelected = null;
+    // Panneau du champ identifiant
+    saisieChampId = new JComboBox();
+    saisieChampId.setEditable(false);
+    saisieChampId.addActionListener(this);
+    JPanel panneauChampId = new JPanel();
+    panneauChampId.add(new JLabel("Choix d'un champ identifiant"));
+    panneauChampId.add(saisieChampId);
+    add(panneauChampId, BorderLayout.NORTH);
+    // Le tableau des champs à visualiser
+    ModeleTableauChampsAVoir donneesChampsAVoir = new ModeleTableauChampsAVoir();
+    tableauChampsAVoir = new JTable(donneesChampsAVoir);
+    JScrollPane scroll2 = new JScrollPane(tableauChampsAVoir);
+    JPanel panneauChampsAVoir = new JPanel();
+    panneauChampsAVoir.add(scroll2);
+    add(panneauChampsAVoir, BorderLayout.CENTER);
+  }
+  void setTypeSelected(Class<? extends Element> classe, String type) {
+    classeSelected = classe;
+    typeSelected = type;
+    reinitialiser();
+  }
+  void reinitialiser() {
+    ((ModeleTableauChampsAVoir) tableauChampsAVoir.getModel()).fireTableDataChanged();
+    saisieChampId.removeActionListener(this);
+    if (typeSelected==null) saisieChampId.setModel(new DefaultComboBoxModel());
+    else {
+      String[] champs = champsAVoir.get(classeSelected).get(typeSelected).toArray(new String[0]);
+      champs = Tableaux.insererStringEnTete(champs, "<aucun>");
+      saisieChampId.setModel(new DefaultComboBoxModel(champs));
+      if (champsId.get(classeSelected).containsKey(typeSelected))
+        saisieChampId.setSelectedItem(champsId.get(classeSelected).get(typeSelected));
+      else saisieChampId.setSelectedIndex(0);
+    }
+    saisieChampId.addActionListener(this);
+  }
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource()==saisieChampId) {
+        if (saisieChampId.getSelectedIndex()==0)
+          champsId.get(classeSelected).remove(typeSelected);
+        else
+          champsId.get(classeSelected).put(typeSelected, (String) saisieChampId.getSelectedItem());
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  private static final String[] nomsColonnes = new String[]{
+    "<html><span style=\"font-weight:900 \">Champ</span>",
+    "<html><span style=\"font-weight:900 \">Niveau</span>",
+    "<html><span style=\"font-weight:900 \">Position</span>",
+    "<html><span style=\"font-weight:900 \">Modifiable ?</span>"
+  };
+  private static final Class[] classesColonnes = new Class[]{String.class, Integer.class, Integer.class, Boolean.class};
+
+  private class ModeleTableauChampsAVoir extends AbstractTableModel {
+    public int getColumnCount() {
+      return nomsColonnes.length;
+    }
+    public int getRowCount() {
+      return (typeSelected==null||!champsAVoir.get(classeSelected).containsKey(typeSelected)) ? 0 : champsAVoir.get(classeSelected).get(typeSelected).size();
+    }
+    public Object getValueAt(int row, int col) {
+      String champ = champsAVoir.get(classeSelected).get(typeSelected).get(row);
+      switch (col) {
+        case 0:
+          return champ;
+        case 1:
+          return niveauxChampsAVoir.get(classeSelected).get(typeSelected).get(champ);
+        case 2:
+          return positionsChampsAVoir.get(classeSelected).get(typeSelected).get(champ);
+        case 3:
+          return modifiabiliteChampsAVoir.get(classeSelected).get(typeSelected).get(champ);
+        default:
+          throw new IndexOutOfBoundsException();
+      }
+    }
+    @Override
+    public String getColumnName(int col) {
+      return nomsColonnes[col];
+    }
+    @Override
+    public Class getColumnClass(int col) {
+      return classesColonnes[col];
+    }
+    @Override
+    public boolean isCellEditable(int row, int col) {
+      if (col==3&&classeSelected==Unite.class) {
+        String champ = champsAVoir.get(classeSelected).get(typeSelected).get(row);
+        String prop = visuVue.getPropChamp(classeSelected, typeSelected, champ);
+        if (Structure.FORME.equals(prop)) return false;
+      }
+      return col>0;
+    }
+    @Override
+    public void setValueAt(Object aValue, int row, int col) {
+      String champ = champsAVoir.get(classeSelected).get(typeSelected).get(row);
+      switch (col) {
+        case 1:
+          niveauxChampsAVoir.get(classeSelected).get(typeSelected).put(champ, (Integer) aValue);
+          return;
+        case 2:
+          positionsChampsAVoir.get(classeSelected).get(typeSelected).put(champ, (Integer) aValue);
+          return;
+        case 3:
+          modifiabiliteChampsAVoir.get(classeSelected).get(typeSelected).put(champ, (Boolean) aValue);
+          return;
+        default:
+          throw new IndexOutOfBoundsException();
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVuePresentation.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVue.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVue.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVue.java	(revision 481)
@@ -0,0 +1,430 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.vue;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.SimpleAttributeSet;
+import visuAnalec.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class VisuVue extends JFrame implements VueListener, ListSelectionListener, ChangeListener {
+  static private VisuVue instance = null;
+  private Vue vue;
+  // Les données spécifiant la vue (échangées avec vue à l'initialisation et à la validation)
+  private HashMap<Class<? extends Element>, HashMap<String, Boolean>> isTypesAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, Boolean>>();
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> niveauxChampsAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>> positionsChampsAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Integer>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>> modifiabiliteChampsAVoir =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, Boolean>>>();
+  private HashMap<Class<? extends Element>, HashMap<String, String>> champsId =
+          new HashMap<Class<? extends Element>, HashMap<String, String>>();
+  private HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>> stylesElements =
+          new HashMap<Class<? extends Element>, HashMap<String, SimpleAttributeSet>>();
+  private HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>> stylesValeursElements =
+          new HashMap<Class<? extends Element>, HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>>();  // le tableau des types à voir
+  private JTable tableauTypes;
+  private JTabbedPane panneauTabule;
+  VisuVueExtraction visuVueExtraction;
+  VisuVuePresentation visuVuePresentation;
+  VisuVueColoriage visuVueColoriage;
+
+  static public void newVisuVue(Container fenetre, Vue vue) {
+    if (instance!=null) instance.fermerFenetre();
+    instance = new VisuVue(fenetre, vue);
+  }
+
+  @SuppressWarnings("unchecked")
+  private VisuVue(Container fenetre, Vue vue) {
+    super("Gestion de la vue");
+    Point locFenetre = new Point(fenetre.getX()+20, fenetre.getY()+50);
+    Dimension dimFenetre = new Dimension(fenetre.getWidth(), fenetre.getHeight()-30);
+    setLocation(locFenetre);
+    setSize(dimFenetre);
+    this.vue = vue;
+    vue.addEventListener(this);
+    // initialisation des données spécifiant la vue
+    for (Class<? extends Element> classe : new Class[]{Unite.class, Relation.class, Schema.class}) {
+      isTypesAVoir.put(classe, new HashMap<String, Boolean>());
+      for (String type : vue.getTypes(classe))
+        isTypesAVoir.get(classe).put(type, false);
+      for (String type : vue.getTypesAVoir(classe))
+        isTypesAVoir.get(classe).put(type, true);
+      champsAVoir.put(classe, new HashMap<String, ArrayList<String>>());
+      adressesAVoir.put(classe, new HashMap<String, ArrayList<Adresse>>());
+      positionsChampsAVoir.put(classe, new HashMap<String, HashMap<String, Integer>>());
+      niveauxChampsAVoir.put(classe, new HashMap<String, HashMap<String, Integer>>());
+      modifiabiliteChampsAVoir.put(classe, new HashMap<String, HashMap<String, Boolean>>());
+      for (String type : vue.getTypes(classe)) {
+        champsAVoir.get(classe).put(type, new ArrayList<String>());
+        adressesAVoir.get(classe).put(type, new ArrayList<Adresse>());
+        niveauxChampsAVoir.get(classe).put(type, new HashMap<String, Integer>());
+        positionsChampsAVoir.get(classe).put(type, new HashMap<String, Integer>());
+        modifiabiliteChampsAVoir.get(classe).put(type, new HashMap<String, Boolean>());
+      }
+      for (String type : vue.getTypesAVoir(classe)) {
+        champsAVoir.get(classe).put(type, vue.getListeChamps(classe, type));
+        for (String nom : vue.getNomsChamps(classe, type))
+          adressesAVoir.get(classe).get(type).add(vue.getAdresseChamps(classe, type, nom));
+      }
+      champsId.put(classe, new HashMap<String, String>());
+      for (String type : vue.getTypesAVoir(classe))
+        if (vue.getChampId(classe, type)!=null)
+          champsId.get(classe).put(type, vue.getChampId(classe, type));
+      for (String type : vue.getTypesAVoir(classe)) {
+        positionsChampsAVoir.get(classe).put(type, vue.getPositionsChampsAVoir(classe, type));
+        niveauxChampsAVoir.get(classe).put(type, vue.getNiveauxChampsAVoir(classe, type));
+        modifiabiliteChampsAVoir.get(classe).put(type, new HashMap<String, Boolean>());
+        for (String champ : vue.getNomsChamps(classe, type))
+          modifiabiliteChampsAVoir.get(classe).get(type).put(champ, vue.isChampModifiable(classe, type, champ));
+      }
+      stylesElements.put(classe, new HashMap<String, SimpleAttributeSet>());
+      for (String type : vue.getTypesAVoir(classe))
+        if (vue.getStyleElements(classe, type)!=null)
+          stylesElements.get(classe).put(type, vue.getStyleElements(classe, type));
+      stylesValeursElements.put(classe, new HashMap<String, HashMap<String, HashMap<String, SimpleAttributeSet>>>());
+      for (String type : vue.getTypesAVoir(classe))
+        if (vue.getStyleValeursElements(classe, type)!=null)
+          stylesValeursElements.get(classe).put(type, vue.getStyleValeursElements(classe, type));
+    }
+    // Tableau des types d'éléments à visualiser
+    Box panneauTypes = Box.createVerticalBox();
+
+    panneauTypes.add(Box.createVerticalGlue());
+    ModeleTableauTypes donneesTypes = new ModeleTableauTypes();
+    tableauTypes = new JTable(donneesTypes) {
+      @Override
+      public boolean isCellSelected(int row, int col) {
+        if (col==1) {
+          return false;
+        }
+        String classeType = ((ModeleTableauTypes) getModel()).classesTypes[row];
+        return isRowSelected(row)&&isTypesAVoir.get(GVisu.getClasse(classeType)).get(GVisu.getType(classeType));
+      }
+    };
+
+    tableauTypes.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+    tableauTypes.getSelectionModel().addListSelectionListener(this);
+
+    JScrollPane scroll1 = new JScrollPane(tableauTypes);
+
+    scroll1.setBorder(
+            new TitledBorder("Types d'éléments à visualiser"));
+    panneauTypes.add(scroll1);
+    // les boutons de validation
+
+    panneauTypes.add(Box.createVerticalGlue());
+    JPanel pCommandesValidation = new JPanel(new FlowLayout());
+    JButton valideModifs = new JButton(
+            new GAction("Valider") {
+              public void executer() {
+                validerModifVue();
+              }
+            ;
+    });
+
+    JButton annuleModifs = new JButton(
+            new GAction("Annuler") {
+              public void executer() {
+                annulerModifVue();
+              }
+            ;
+
+    });
+    pCommandesValidation.add(valideModifs, CENTER_ALIGNMENT);
+
+    pCommandesValidation.add(annuleModifs, CENTER_ALIGNMENT);
+
+    panneauTypes.add(pCommandesValidation);
+    // Les panneaux tabulés Extraction, Sélection, Présentation, Coloriage
+    panneauTabule = new JTabbedPane();
+
+    panneauTabule.addChangeListener(
+            this);
+    visuVueExtraction = new VisuVueExtraction(this, vue, champsAVoir, adressesAVoir);
+
+    panneauTabule.add(
+            "Extraction de propriétés", visuVueExtraction);
+    visuVuePresentation = new VisuVuePresentation(this, vue, champsAVoir, champsId,
+            modifiabiliteChampsAVoir, niveauxChampsAVoir, positionsChampsAVoir);
+
+    panneauTabule.add(
+            "Présentation des champs", visuVuePresentation);
+    visuVueColoriage = new VisuVueColoriage(this, vue, champsAVoir, adressesAVoir,
+            stylesElements, stylesValeursElements);
+
+    panneauTabule.add(
+            "Coloriage d'éléments", visuVueColoriage);
+    // cadre global de la fenêtre
+    JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panneauTypes, panneauTabule);
+
+    setContentPane(split);
+
+    setVisible(
+            true);
+    split.setDividerLocation(
+            0.25);
+//    visuVueExtraction.agencerPanneaux();
+//
+    // initialisation de la sélection d'un premier type à voir (si possible)
+
+
+    for (int i = 0;
+            i<donneesTypes.getRowCount();
+            i++) {
+      if ((Boolean) donneesTypes.getValueAt(i, 1)) {
+        tableauTypes.setRowSelectionInterval(i, i);
+        tableauTypes.setColumnSelectionInterval(0, 0);
+        break;
+      }
+    }
+    // Fermeture de la fenêtre
+
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+
+    addWindowListener(
+            new WindowAdapter() {
+              @Override
+              public void windowClosing(WindowEvent evt) {
+                confirmerFermerFenetre();
+              }
+            });
+  }
+
+  public void stateChanged(ChangeEvent evt) {
+    if (((JTabbedPane) evt.getSource())!=panneauTabule) return;
+    try {
+      switch (panneauTabule.getSelectedIndex()) {
+        case 0:
+          return;
+        case 1:
+          visuVuePresentation.reinitialiser();
+          return;
+        case 2:
+          visuVueColoriage.reinitialiser();
+          return;
+        default:
+          throw new IndexOutOfBoundsException();
+      }
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  private void validerModifVue() {
+    vue.modifierVueParSaisie(isTypesAVoir, adressesAVoir, champsAVoir, champsId, modifiabiliteChampsAVoir,
+            positionsChampsAVoir, niveauxChampsAVoir, stylesElements, stylesValeursElements);
+  }
+
+  private void annulerModifVue() {
+    fermerFenetre();
+  }
+
+  void ajouterChamp(Class<? extends Element> classe, String type, Adresse ad) {
+    String champ = Vue.trouveNomChampParDefaut(ad, champsAVoir.get(classe).get(type));
+    champsAVoir.get(classe).get(type).add(champ);
+    adressesAVoir.get(classe).get(type).add(ad);
+    modifiabiliteChampsAVoir.get(classe).get(type).put(champ, ad.getLongueur()==1);
+    positionsChampsAVoir.get(classe).get(type).put(champ, 0);
+    niveauxChampsAVoir.get(classe).get(type).put(champ, 0);
+  }
+
+  void renommerChamp(Class<? extends Element> classe, String type, int rg, String newNom) {
+    String oldNom = champsAVoir.get(classe).get(type).get(rg);
+    champsAVoir.get(classe).get(type).set(rg, newNom);
+    if (champsId.get(classe).containsKey(type)&&oldNom.equals(champsId.get(classe).get(type))) {
+      champsId.get(classe).put(type, newNom);
+    }
+    modifiabiliteChampsAVoir.get(classe).get(type).put(newNom,
+            modifiabiliteChampsAVoir.get(classe).get(type).get(oldNom));
+    modifiabiliteChampsAVoir.get(classe).get(type).remove(oldNom);
+    positionsChampsAVoir.get(classe).get(type).put(newNom,
+            positionsChampsAVoir.get(classe).get(type).get(oldNom));
+    positionsChampsAVoir.get(classe).get(type).remove(oldNom);
+    niveauxChampsAVoir.get(classe).get(type).put(newNom,
+            niveauxChampsAVoir.get(classe).get(type).get(oldNom));
+    niveauxChampsAVoir.get(classe).get(type).remove(oldNom);
+    if (stylesValeursElements.get(classe).containsKey(type)
+            &&stylesValeursElements.get(classe).get(type).containsKey(oldNom)) {
+      stylesValeursElements.get(classe).get(type).
+              put(newNom, stylesValeursElements.get(classe).get(type).get(oldNom));
+      stylesValeursElements.get(classe).get(type).remove(oldNom);
+    }
+  }
+
+  void supprimerChamp(Class<? extends Element> classe, String type, int rg) {
+    String oldNom = champsAVoir.get(classe).get(type).get(rg);
+    champsAVoir.get(classe).get(type).remove(rg);
+    adressesAVoir.get(classe).get(type).remove(rg);
+    if (champsId.get(classe).containsKey(type)&&oldNom.equals(champsId.get(classe).get(type))) {
+      champsId.get(classe).remove(type);
+      modifiabiliteChampsAVoir.get(classe).get(type).remove(oldNom);
+      positionsChampsAVoir.get(classe).get(type).remove(oldNom);
+      niveauxChampsAVoir.get(classe).get(type).remove(oldNom);
+      if (stylesValeursElements.get(classe).containsKey(type)
+              &&stylesValeursElements.get(classe).get(type).containsKey(oldNom)) {
+        stylesValeursElements.get(classe).get(type).remove(oldNom);
+      }
+    }
+  }
+  String getPropChamp(Class<? extends Element> classe, String type, String champ) {
+    ArrayList<String> champs = champsAVoir.get(classe).get(type);
+    if(champs==null) return "";
+    int ind = champs.indexOf(champ);
+    if(ind<0) return "";
+     String prop = adressesAVoir.get(classe).get(type).get(ind).prop;
+     if(prop==null) return "";
+     return prop;
+   
+  }
+
+  public void valueChanged(ListSelectionEvent evt) {
+    if ((ListSelectionModel) evt.getSource()!=tableauTypes.getSelectionModel())
+      return;
+    try {
+      if (evt.getValueIsAdjusting()) {
+        return;
+      }
+      int row = ((ListSelectionModel) evt.getSource()).getMinSelectionIndex();
+      if (row<0) {
+        visuVueExtraction.setTypeSelected(null, null);
+        visuVuePresentation.setTypeSelected(null, null);
+        visuVueColoriage.setTypeSelected(null, null);
+      } else {
+        String classeType = ((ModeleTableauTypes) tableauTypes.getModel()).classesTypes[row];
+        Class<? extends Element> classeSelected = GVisu.getClasse(classeType);
+        String typeSelected = GVisu.getType(classeType);
+        if (isTypesAVoir.get(classeSelected).get(typeSelected)) {
+          visuVueExtraction.setTypeSelected(classeSelected, typeSelected);
+          visuVuePresentation.setTypeSelected(classeSelected, typeSelected);
+          visuVueColoriage.setTypeSelected(classeSelected, typeSelected);
+        } else {
+          visuVueExtraction.setTypeSelected(null, null);
+          visuVuePresentation.setTypeSelected(null, null);
+          visuVueColoriage.setTypeSelected(null, null);
+        }
+      }
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre vue présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        return;
+      case MODIF_VUE:
+        fermerFenetre();  // ferme même si la modif vient d'ici
+        return;
+      case MODIF_STRUCTURE:
+        fermerFenetre();
+        return;
+      case MODIF_ELEMENT:
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+
+  private void confirmerFermerFenetre() {
+    try {
+      int rep = JOptionPane.showOptionDialog(this, "Valider les modifications ?",
+              "Fermeture de la fenêtre \"Structure des annotations\"", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+              null, new Object[]{"Oui", "Non", "Annuler"}, "Non");
+      if (rep==2) {
+        return;
+      }
+      if (rep==0) {
+        validerModifVue();
+      }
+      annulerModifVue();
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+
+
+  }
+
+  private class ModeleTableauTypes extends AbstractTableModel {
+    String[] classesTypes;
+
+    private ModeleTableauTypes() {
+      super();
+      classesTypes = GVisu.getClassesTypes(vue.getTypes(Unite.class), vue.getTypes(Relation.class), vue.getTypes(Schema.class));
+    }
+
+    public int getColumnCount() {
+      return 2;
+    }
+
+    public int getRowCount() {
+      return classesTypes.length;
+    }
+
+    public Object getValueAt(int row, int col) {
+      String classeType = classesTypes[row];
+      return col==0 ? classeType : isTypesAVoir.get(GVisu.getClasse(classeType)).get(GVisu.getType(classeType));
+    }
+
+    @Override
+    public String getColumnName(int col) {
+      return col==0 ? "Types d'éléments" : "à voir";
+    }
+
+    @Override
+    public Class getColumnClass(int col) {
+      return col==0 ? String.class : Boolean.class;
+    }
+
+    @Override
+    public boolean isCellEditable(int row, int col) {
+      return col==1;
+    }
+
+    @Override
+    public void setValueAt(Object aValue, int row, int col) {
+      if (col==1) {
+        String classeType = classesTypes[row];
+        isTypesAVoir.get(GVisu.getClasse(classeType)).put(GVisu.getType(classeType), (Boolean) aValue);
+        tableauTypes.clearSelection();  // important : à faire même quand aValue est vrai
+        // pour que l'événement "ListSelection change" soit émis dans tous les cas
+        if ((Boolean) aValue) {
+          tableauTypes.setRowSelectionInterval(row, row);
+          tableauTypes.setColumnSelectionInterval(0, 0);
+        }
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVue.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVueExtraction.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVueExtraction.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVueExtraction.java	(revision 481)
@@ -0,0 +1,243 @@
+package visuAnalec.vue;
+
+import java.awt.BorderLayout;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.TreeExpansionEvent;
+import javax.swing.event.TreeWillExpandListener;
+import javax.swing.table.*;
+import javax.swing.tree.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class VisuVueExtraction extends JPanel implements TreeWillExpandListener {
+  private VisuVue visuVue;
+  private Vue vue;
+  private JTable tableauChampsAVoir;
+  private JTree arbreChampsAExtraire;
+  private JPopupMenuChamp popupMenuChamp;
+  private Class<? extends Element> classeSelected;
+  private String typeSelected;
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir;
+  private HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir;
+  private JPanel panneauChampsExtraits;
+  private JPanel panneauAExtraire;
+  VisuVueExtraction(VisuVue visuVue, Vue vue,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<String>>> champsAVoir,
+          HashMap<Class<? extends Element>, HashMap<String, ArrayList<Adresse>>> adressesAVoir) {
+    super(new BorderLayout());
+    this.visuVue = visuVue;
+    this.vue = vue;
+    this.champsAVoir = champsAVoir;
+    this.adressesAVoir = adressesAVoir;
+    classeSelected = null;
+    typeSelected = null;
+//    // Panneau des champs extraits à visualiser
+  panneauChampsExtraits =new JPanel(new BorderLayout());
+    // Le tableau des champs à visualiser
+    ModeleTableauChampsAVoir donneesChampsAVoir = new ModeleTableauChampsAVoir();
+    tableauChampsAVoir = new JTable(donneesChampsAVoir);
+    popupMenuChamp = new JPopupMenuChamp();
+    popupMenuChamp.add(new ActionSupprimerChamp());
+
+    MouseListener popupListener = new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {
+        maybeShowPopup(e);
+      }
+      @Override
+      public void mouseReleased(MouseEvent e) {
+        maybeShowPopup(e);
+      }
+      private void maybeShowPopup(MouseEvent e) {
+        try {
+          if (e.isPopupTrigger()) {
+            popupMenuChamp.rang = tableauChampsAVoir.rowAtPoint(e.getPoint());
+            ((JMenuItem) (popupMenuChamp.getSubElements()[0])).setText("supprimer le champ \"" +
+                    tableauChampsAVoir.getValueAt(popupMenuChamp.rang, 0) + "\"");
+            popupMenuChamp.show(e.getComponent(), e.getX(), e.getY());
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    };
+    tableauChampsAVoir.addMouseListener(popupListener);
+    tableauChampsAVoir.addKeyListener(new KeyAdapter() {
+      @Override
+      public void keyPressed(KeyEvent e) {
+        try {
+          if (e.getKeyCode() == KeyEvent.VK_DELETE && tableauChampsAVoir.getSelectedRowCount() == 1) {
+            ((ModeleTableauChampsAVoir) tableauChampsAVoir.getModel()).supprimerChamp(tableauChampsAVoir.getSelectedRow());
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    });
+    JScrollPane scroll2 = new JScrollPane(tableauChampsAVoir);
+    scroll2.setBorder(new TitledBorder("Propriétés à visualiser"));
+    panneauChampsExtraits.add(scroll2, BorderLayout.CENTER);
+
+    // Panneau des champs à extraire
+    panneauAExtraire = new JPanel(new BorderLayout());
+    ModeleArbreChampsAExtraire donneesChampsAExtraire = new ModeleArbreChampsAExtraire(vue);
+    arbreChampsAExtraire = new JTree(donneesChampsAExtraire);
+    arbreChampsAExtraire.addTreeWillExpandListener(this);
+    MouseListener ml2 = new MouseAdapter() {
+      @Override
+      public void mousePressed(MouseEvent e) {
+        try {
+          TreePath selPath = arbreChampsAExtraire.getPathForLocation(e.getX(), e.getY());
+          if (selPath != null && e.getClickCount() == 2) {
+            NoeudChampAExtraire noeud = (NoeudChampAExtraire) selPath.getLastPathComponent();
+            if (noeud.getAllowsChildren()) return;
+            else ajouterChamp(noeud.getAdresse());
+          }
+        } catch (Throwable ex) {
+          GMessages.erreurFatale(ex);
+        }
+      }
+    };
+    arbreChampsAExtraire.addMouseListener(ml2);
+    JScrollPane scroll3 = new JScrollPane(arbreChampsAExtraire);
+    scroll3.setBorder(new TitledBorder("Extraction de nouvelles propriétés à visualiser"));
+    panneauAExtraire.add(scroll3, BorderLayout.CENTER);
+      // Dimensionnement 
+    add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,panneauChampsExtraits, panneauAExtraire),
+            BorderLayout.CENTER);
+  }
+//  void agencerPanneaux() {
+//        JSplitPane split = (JSplitPane) panneauChampsExtraits.getParent();
+//    split.setDividerLocation(2. / 3);
+//    revalidate();
+//    repaint();
+//  }
+  public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
+    NoeudChampAExtraire noeud = (NoeudChampAExtraire) event.getPath().getLastPathComponent();
+    if(noeud.isLeaf()) {
+      ModeleArbreChampsAExtraire donnees = (ModeleArbreChampsAExtraire) arbreChampsAExtraire.getModel();
+     donnees.setSousArbre(noeud);
+    }
+  }
+  public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
+    return;
+  }
+  void setTypeSelected(Class<? extends Element> classe, String type) {
+    classeSelected = classe;
+    typeSelected = type;
+    ((ModeleTableauChampsAVoir) tableauChampsAVoir.getModel()).fireTableDataChanged();
+    ((ModeleArbreChampsAExtraire) arbreChampsAExtraire.getModel()).setModele(classeSelected, typeSelected);
+  }
+  private void ajouterChamp(Adresse ad) {
+     for (Adresse ad0 : adressesAVoir.get(classeSelected).get(typeSelected)) {
+      if (ad.toString().equals(ad0.toString())) {
+        JOptionPane.showMessageDialog(tableauChampsAVoir.getTopLevelAncestor(),
+                "Ajout impossible : le champ d'adresse  " + ad.toString() + " existe déjà",
+                "Erreur d'ajout de champ", JOptionPane.ERROR_MESSAGE);
+        return;
+      }
+    }
+    visuVue.ajouterChamp(classeSelected, typeSelected, ad);
+    ((ModeleTableauChampsAVoir) tableauChampsAVoir.getModel()).fireTableDataChanged();
+  }
+
+  private class ModeleTableauChampsAVoir extends AbstractTableModel {
+    public int getColumnCount() {
+      return 2;
+    }
+    public int getRowCount() {
+      return (typeSelected == null || !champsAVoir.get(classeSelected).containsKey(typeSelected)) ? 0 : 
+        champsAVoir.get(classeSelected).get(typeSelected).size();
+    }
+    public Object getValueAt(int row, int col) {
+      return col == 0 ? champsAVoir.get(classeSelected).get(typeSelected).get(row) : 
+        adressesAVoir.get(classeSelected).get(typeSelected).get(row).toString();
+    }
+    @Override
+    public String getColumnName(int col) {
+      return col == 0 ? "Noms abrégés des champs" : "Noms complets des propriétés";
+    }
+    @Override
+    public boolean isCellEditable(int row, int col) {
+      return col == 0;
+    }
+    @Override
+    public void setValueAt(Object aValue, int row, int col) {
+      if (col != 0)   throw new IndexOutOfBoundsException();
+    visuVue.renommerChamp(classeSelected, typeSelected, row,  (String) aValue);
+    }
+    void supprimerChamp(int row) {
+      visuVue.supprimerChamp(classeSelected, typeSelected,row);
+      fireTableDataChanged();
+    }
+  }
+
+  private static class JPopupMenuChamp extends JPopupMenu {
+    int rang = -1;
+  }
+
+  private class ActionSupprimerChamp extends AbstractAction {
+    ActionSupprimerChamp() {
+      super("supprimer le champ");
+    }
+    public void actionPerformed(ActionEvent e) {
+      try {
+        int rg = ((JPopupMenuChamp) ((JMenuItem) e.getSource()).getParent()).rang;
+        ((ModeleTableauChampsAVoir) tableauChampsAVoir.getModel()).supprimerChamp(rg);
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+  }
+
+  private static class ModeleArbreChampsAExtraire extends DefaultTreeModel {
+    Vue vue;
+    ModeleArbreChampsAExtraire(Vue vue) {
+      super(null, true);
+      this.vue = vue;
+    }
+    void setModele(Class<? extends Element> classeRacine, String typeRacine) {
+      if (typeRacine == null) {
+        setRoot(null);
+      } else {
+        NoeudChampAExtraire racine = new NoeudChampAExtraire(
+                new Adresse(new Jalon(Jalon.Origine.ELT_0, classeRacine, typeRacine)));
+        setRoot(racine);
+        setSousArbre(racine);
+      }
+      reload();
+    }
+    void setSousArbre(NoeudChampAExtraire noeud) {
+      Adresse adresse = noeud.getAdresse();
+      for (String prop : vue.getNomsProps(adresse)) {
+        noeud.add(new NoeudChampAExtraire(new Adresse(adresse, prop)));
+      }
+      Jalon[] jalons = vue.getNextJalonsPotentiels(adresse);
+      for (Jalon jalon : jalons) {
+        noeud.add(new NoeudChampAExtraire(new Adresse(adresse, jalon)));
+      }
+    }
+  }
+
+  private static class NoeudChampAExtraire extends DefaultMutableTreeNode {
+    NoeudChampAExtraire(Adresse adresse) {
+      super(adresse, adresse.prop == null);
+    }
+    Adresse getAdresse() {
+      return (Adresse) getUserObject();
+    }
+    @Override
+    public String toString() {
+      if (getAdresse().prop == null) return getAdresse().getLastJalon().toString();
+      return getAdresse().prop;
+    }
+  }
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/vue/VisuVueExtraction.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesSchemas.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesSchemas.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesSchemas.java	(revision 481)
@@ -0,0 +1,524 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.Message.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.texte.PanneauAffTexte.*;
+import visuAnalec.texte.PanneauTexte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class PanneauCommandesSchemas extends PanneauCommandes implements ActionListener {
+  private PanneauChamps panneauChamps;
+  private TypeComboBox saisieTypeSchemas;
+  private ElementComboBox saisieSchema;
+  private TypeComboBox saisieTypeElt;
+  private ElementComboBox saisieElt;
+  private JButton creeSchema;
+  private JButton supprimeSchema;
+  private JButton ajouteElement;
+  private JButton oteElement;
+  private JButton creeUniteElt;
+  private int[] bornesSelectTexte;
+  /*
+  
+   * CREATION PAR LE PANNEAU EDITEUR
+   */
+  PanneauCommandesSchemas(Vue vue, PanneauAffTexte pTexte, PanneauChamps pChamps) {
+    super(vue, pTexte);
+    JToolBar barre1 = new JToolBar();
+    barre1.setPreferredSize(new Dimension(0, 22));
+//    barre1.setBackground(PanneauTexte.getCouleurFond1());
+    barre1.setAlignmentX(0.0f);
+    //    barre1.setFloatable(false);
+    add(barre1);
+    JToolBar barre2 = new JToolBar();
+    barre2.setPreferredSize(new Dimension(0, 22));
+//    barre2.setBackground(PanneauTexte.getCouleurFond2());
+    barre2.setAlignmentX(0.0f);
+//     barre2.setFloatable(false);
+    add(barre2);
+    panneauChamps = pChamps;
+    saisieTypeSchemas = new TypeComboBox(Schema.class);
+    saisieTypeSchemas.addActionListener(this);
+    saisieSchema = new ElementComboBox();
+    saisieSchema.addActionListener(this);
+    saisieTypeElt = new TypeComboBox(Element.class);
+    saisieTypeElt.addActionListener(this);
+    saisieElt = new ElementComboBox();
+    saisieElt.addActionListener(this);
+    creeSchema = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerSchema();
+      }
+    });
+    supprimeSchema = new JButton(new GAction("Supprimer") {
+      public void executer() {
+        supprimerSchema();
+      }
+    });
+    ajouteElement = new JButton(new GAction("Ajouter") {
+      public void executer() {
+        ajouterElement();
+      }
+    });
+    oteElement = new JButton(new GAction("Oter") {
+      public void executer() {
+        oterElement();
+      }
+    });
+    creeUniteElt = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerUniteElt();
+      }
+    });
+    barre1.addSeparator();
+    barre1.add(new TitreBarre("Schéma : ", PanneauTexte.getCouleurFond1()));
+    barre1.addSeparator();
+    barre1.add(saisieTypeSchemas);
+    barre1.add(saisieSchema);
+    barre1.addSeparator();
+    barre1.add(creeSchema);
+    barre1.addSeparator();
+    barre1.add(supprimeSchema);
+    barre2.addSeparator();
+    barre2.add(new TitreBarre("Elément : ", PanneauTexte.getCouleurFond2()));
+    barre2.addSeparator();
+    barre2.add(saisieTypeElt);
+    barre2.add(saisieElt);
+    barre2.addSeparator();
+    barre2.add(ajouteElement);
+    barre2.add(oteElement);
+    barre2.add(creeUniteElt);
+  }
+
+  /*
+   * COMMANDES UTILISEES PAR LE PANNEAU EDITEUR
+   */
+  public void reinitialiser() {
+    // typiquement, appelé par le panneau éditeur à la suite d'une modif de vue ou de structure
+    saisieTypeSchemas.removeActionListener(this);
+    saisieTypeSchemas.setModele(vue.getTypesSchemasAVoir());
+    saisieTypeSchemas.effSelection();
+    saisieTypeSchemas.addActionListener(this);
+    saisieTypeElt.removeActionListener(this);
+    saisieTypeElt.setModele(vue.getTypes(Unite.class), vue.getTypes(Relation.class), vue.getTypes(Schema.class));
+    saisieTypeElt.effSelection();
+    saisieTypeElt.addActionListener(this);
+    initSaisieSchema();
+    initSaisieElt();
+    etatSelectRien();
+    revalidate();
+    repaint();
+  }
+  public void reafficher() {
+    // potentiellement appelé par le panneau éditeur ?
+    // appelé aussi par  traiterElementEvent
+    if (saisieSchema.pasdeSelection()) {
+      initSaisieSchema();
+      if (saisieElt.pasdeSelection()) {
+        initSaisieElt();
+        etatSelectRien();
+      } else {
+        Element eltCourant = saisieElt.getSelection();
+        initSaisieElt(eltCourant);
+        etatSelectElt(eltCourant);
+      }
+    } else {
+      Schema schCourant = (Schema) saisieSchema.getSelection();
+      initSaisieSchema(schCourant);
+      if (saisieElt.pasdeSelection()) {
+        initSaisieElt();
+        etatSelectSchema(schCourant);
+      } else {
+        Element eltCourant = saisieElt.getSelection();
+        initSaisieElt(eltCourant);
+        etatSelectSchemaElt(schCourant, eltCourant);
+      }
+    }
+  }
+   public void elementSuivant(int sens) {
+    if (sens>0) saisieSchema.gotoSuivant();
+    else saisieSchema.gotoPrecedent();
+  }
+ public Element elementSelectionne() {
+    if (saisieSchema.pasdeSelection()) return null;
+    return saisieSchema.getSelection();
+  }
+  public void editerElement(Element elt) {
+    // appelé par le panneauEditeur : elt est forcément un schéma
+    if (elt.getClass() != Schema.class) throw new UnsupportedOperationException("Erreur : classe incorrecte");
+    editerSchema((Schema) elt);
+  }
+  public void traiterElementEvent(ElementEvent evt) {
+    switch (evt.getModif()) {
+      case AJOUT_SCHEMA:
+      case MODIF_SCHEMA:
+        Schema sch = (Schema) evt.getElement();
+        editerSchema(sch);
+        return;
+      case SUP_SCHEMA:
+        if (evt.getElement() == saisieSchema.getSelection()) {
+          initSaisieSchema();
+          initSaisieElt();
+          etatSelectRien();
+        } else {
+          reafficher();
+        }
+        return;
+      case AJOUT_UNITE:
+        if (saisieTypeElt.getClasseSelection() == Unite.class ||
+                evt.getElement().getType().equals(saisieTypeElt.getTypeSelection())) {
+          initSaisieElt(evt.getElement());
+        }
+        reafficher();
+        return;
+      case SUP_UNITE:
+      case SUP_RELATION:
+      case BORNES_UNITE:
+      case AJOUT_RELATION:
+      case MODIF_VALEUR:
+        reafficher();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas " + evt.getModif() + " oublié dans un switch");
+    }
+  }
+  public void editerSchema(Schema sch) {
+    // appelé  par traiterElementEvent, 
+    // et aussi directement par le panneau éditeur quand il est sollicité par d'autres fenêtres
+    if (!sch.getType().equals(saisieTypeSchemas.getTypeSelection())) {
+      saisieTypeSchemas.removeActionListener(this);
+      saisieTypeSchemas.setSelection(sch.getType());
+      saisieTypeSchemas.addActionListener(this);
+    }
+    initSaisieSchema(sch);
+    saisieSchema.setSelection(sch);
+  }
+  public void editerSchemaElement(Schema sch, Element elt) {
+    // appelé  par le panneau éditeur  sollicité par VisuChaines 
+    if (!sch.getType().equals(saisieTypeSchemas.getTypeSelection())) {
+      saisieTypeSchemas.removeActionListener(this);
+      saisieTypeSchemas.setSelection(sch.getType());
+      saisieTypeSchemas.addActionListener(this);
+    }
+    initSaisieSchema(sch);
+    forceElt(elt);
+  }
+ public void editerElementTypeSchema(Element elt, String typesch) {
+    // appelé  par le panneau éditeur  sollicité par VisuChaines 
+    if (!typesch.equals(saisieTypeSchemas.getTypeSelection())) {
+      saisieTypeSchemas.removeActionListener(this);
+      saisieTypeSchemas.setSelection(typesch);
+      saisieTypeSchemas.addActionListener(this);
+    }
+    initSaisieSchema();
+    forceElt(elt);
+  }
+  public ArrayList<ElementMarque> trouverElementsVises(Unite uniteVisee, TypeMarquage marqueUniteVisee,
+          boolean avecId) {
+    ArrayList<ElementMarque> eltsMarques = new ArrayList<ElementMarque>();
+    ArrayList<Element> eltsVises;
+    Element eltVise;
+    switch (marqueUniteVisee) {
+      case FOND1:
+        eltsVises = Element.trouverElementsParUniteSousjacente(saisieSchema.getElements(), uniteVisee);
+        for (Element elt : eltsVises) eltsMarques.add(new ElementMarque(
+                  elt, marqueUniteVisee, avecId ? saisieSchema.getIdElement(elt) : null));
+        return eltsMarques;
+      case FOND1_2:
+      case FOND2:
+        eltsVises = Element.trouverElementsParUniteSousjacente(saisieElt.getElements(), uniteVisee);
+        for (Element elt : eltsVises) eltsMarques.add(new ElementMarque(
+                  elt, marqueUniteVisee, avecId ? saisieElt.getIdElement(elt) : null));
+        return eltsMarques;
+      case SELECT1:
+        eltVise = saisieSchema.getSelection();
+        eltsMarques.add(new ElementMarque(
+                  eltVise, marqueUniteVisee, avecId ? saisieSchema.getIdElement(eltVise) : null));
+        return eltsMarques;
+      case SELECT1_2:
+      case SELECT2:
+        eltVise = saisieElt.getSelection();
+        eltsMarques.add(new ElementMarque(
+                eltVise, marqueUniteVisee, avecId ? saisieElt.getIdElement(eltVise) : null));
+        return eltsMarques;       
+      default:
+        throw new UnsupportedOperationException("Marquage non prévu : " + marqueUniteVisee);
+
+    }
+  }
+  /*
+   * ACTIONS DE L'UTILISATEUR : CHANGEMENTS D'ETAT
+   */
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource() == saisieTypeSchemas) {
+        initSaisieSchema();
+        if (saisieElt.pasdeSelection()) etatSelectRien();
+        else etatSelectElt(saisieElt.getSelection());
+        return;
+      }
+      if (evt.getSource() == saisieTypeElt) {
+        initSaisieElt();
+        if (saisieSchema.pasdeSelection()) etatSelectRien();
+        else etatSelectSchema((Schema) saisieSchema.getSelection());
+        return;
+      }
+      if (evt.getSource() == saisieSchema) {
+        if (saisieSchema.pasdeSelection()) {
+          if (saisieElt.pasdeSelection()) etatSelectRien();
+          else etatSelectElt(saisieElt.getSelection());
+        } else {
+          if (saisieElt.pasdeSelection()) etatSelectSchema((Schema) saisieSchema.getSelection());
+          else etatSelectSchemaElt((Schema) saisieSchema.getSelection(), saisieElt.getSelection());
+        }
+        return;
+      }
+      if (evt.getSource() == saisieElt) {
+        if (saisieElt.pasdeSelection()) {
+          if (saisieSchema.pasdeSelection()) etatSelectRien();
+          else etatSelectSchema((Schema) saisieSchema.getSelection());
+        } else {
+          if (saisieSchema.pasdeSelection()) etatSelectElt(saisieElt.getSelection());
+          else etatSelectSchemaElt((Schema) saisieSchema.getSelection(), saisieElt.getSelection());
+        }
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : " + evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  @Override
+  public void traiterSourisEvent(SourisEvent evt) {
+    switch (evt.getTypeEvent()) {
+      case SELECT_RIEN:
+        saisieElt.removeActionListener(this);
+        saisieElt.effSelection();
+        saisieElt.addActionListener(this);
+        saisieSchema.effSelection();
+        return;
+      case SELECT_ELEMENT:
+        switch (evt.getMarquageElementVise()) {
+          case SELECT1:
+            forceElt(evt.getElementVise());
+            return;
+          case SELECT2:
+          case SELECT1_2:
+            saisieSchema.effSelection();
+            return;
+          case FOND1:
+            saisieSchema.setSelection(evt.getElementVise());
+            return;
+          case FOND2:
+          case FOND1_2:
+            saisieElt.setSelection(evt.getElementVise());
+            return;
+          default:
+            throw new UnsupportedOperationException("Marquage non prévu : " + evt.getTypeEvent());
+        }
+      case SELECT_TEXTE:
+        saisieElt.removeActionListener(this);
+        saisieElt.effSelection();
+        saisieElt.addActionListener(this);
+        saisieSchema.removeActionListener(this);
+        saisieSchema.effSelection();
+        saisieSchema.addActionListener(this);
+        bornesSelectTexte = evt.getBornesSelectionTexte();
+        etatSelectTexte();
+        return;
+    }
+    throw new UnsupportedOperationException("Evénement non prévu : " + evt.getTypeEvent());
+  }
+
+  /*
+   * ACTIONS DE L'UTILISATEUR : BOUTONS
+   */
+  private void creerSchema() {
+    vue.getCorpus().addSchemaSaisi(saisieTypeSchemas.getTypeSelection(), saisieElt.getSelection());
+  }
+  private void creerUniteElt() {
+    if (vue.getCorpus().checkPresenceUnite(saisieTypeElt.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1]) &&
+            !GMessages.confirmationAction("Dupliquer cette unité  ?")) return;
+    vue.getCorpus().addUniteSaisie(saisieTypeElt.getTypeSelection(),  bornesSelectTexte[0], bornesSelectTexte[1]);
+  }
+  private void supprimerSchema() {
+    if (!GMessages.confirmationAction("Supprimer le schéma sélectionné ?")) return;
+    vue.getCorpus().supSchema((Schema) saisieSchema.getSelection());
+  }
+  private void ajouterElement() {
+    vue.getCorpus().ajouterElementSchemaSaisi(saisieElt.getSelection(), (Schema) saisieSchema.getSelection());
+  }
+  private void oterElement() {
+    vue.getCorpus().oterElementSchema(saisieElt.getSelection(), (Schema) saisieSchema.getSelection());
+  }
+
+  /* 
+   * GESTION INTERNE
+   */
+  private void etatSelectRien() { // ni Sch ni Elt n'ont été saisis
+    if (saisieTypeElt.pasdeSelection()) {
+      if (saisieTypeSchemas.pasdeSelection()) panneauTexte.pasDeMarquage();
+      else panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieSchema.getElements()), TypeMarquage.FOND1);
+    } else {
+      if (saisieTypeSchemas.pasdeSelection()) panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieElt.getElements()), TypeMarquage.FOND2);
+      else panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieSchema.getElements()), TypeMarquage.FOND1,
+                Element.getUnitesSousjacentes(saisieElt.getElements()), TypeMarquage.FOND2);
+    }
+    panneauChamps.effacer();
+    creeSchema.setEnabled(false);
+    supprimeSchema.setEnabled(false);
+    ajouteElement.setEnabled(false);
+    oteElement.setEnabled(false);
+    creeUniteElt.setEnabled(false);
+  }
+  private void etatSelectTexte() { // du texte a été sélectionné
+    if (saisieTypeElt.pasdeSelection()) {
+      if (saisieTypeSchemas.pasdeSelection()) panneauTexte.pasDeMarquage();
+      else panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieSchema.getElements()), TypeMarquage.FOND1);
+    } else {
+      if (saisieTypeSchemas.pasdeSelection()) panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieElt.getElements()), TypeMarquage.FOND2);
+      else panneauTexte.saisir(null,
+                Element.getUnitesSousjacentes(saisieSchema.getElements()), TypeMarquage.FOND1,
+                Element.getUnitesSousjacentes(saisieElt.getElements()), TypeMarquage.FOND2);
+    }
+    panneauChamps.effacer();
+    creeSchema.setEnabled(false);
+    supprimeSchema.setEnabled(false);
+    ajouteElement.setEnabled(false);
+    oteElement.setEnabled(false);
+    if (!saisieTypeElt.pasdeSelection() && saisieTypeElt.getClasseSelection() == Unite.class)
+      creeUniteElt.setEnabled(true);
+  }
+  private void etatSelectElt(Element elt) {  // seul Elt a été choisi 
+    if (saisieTypeSchemas.pasdeSelection()) panneauTexte.saisir(elt.getUnite0(),
+              elt.getUnitesSousjacentes(), TypeMarquage.SELECT2);
+    else panneauTexte.saisir(elt.getUnite0(), elt.getUnitesSousjacentes(), TypeMarquage.SELECT2,
+              Element.getUnitesSousjacentes(saisieSchema.getElements()), TypeMarquage.FOND1);
+    panneauChamps.afficher(elt);
+    if (!saisieTypeSchemas.pasdeSelection()) {
+      creeSchema.setEnabled(true);
+      Boutons.setDefaut(creeSchema, true);
+    }
+    supprimeSchema.setEnabled(false);
+    ajouteElement.setEnabled(false);
+    oteElement.setEnabled(false);
+    creeUniteElt.setEnabled(false);
+  }
+  private void etatSelectSchema(Schema sch) { // seul Sch a été choisi
+    if (saisieTypeElt.pasdeSelection()) panneauTexte.saisir(sch.getUnite0(),
+              sch.getUnitesSousjacentes(), TypeMarquage.SELECT1);
+    else panneauTexte.saisir(sch.getUnite0(),
+              sch.getUnitesSousjacentes(), TypeMarquage.SELECT1,
+              Element.getUnitesSousjacentes(filtreSch(saisieElt.getElements(), (Schema[])saisieSchema.getElements())),
+              TypeMarquage.FOND1_2,
+              Element.getUnitesSousjacentes(saisieElt.getElements()), TypeMarquage.FOND2);
+    panneauChamps.afficher(sch);
+    creeSchema.setEnabled(false);
+    supprimeSchema.setEnabled(true);
+    ajouteElement.setEnabled(false);
+    oteElement.setEnabled(false);
+    creeUniteElt.setEnabled(false);
+  }
+  private void etatSelectSchemaElt(Schema sch, Element elt) {
+    if (sch.contient(elt)) etatSelectSchemaEltInterne(sch, elt);
+    else etatSelectSchemaEltExterne(sch, elt);
+  }
+  private void etatSelectSchemaEltInterne(Schema sch, Element elt) {
+    panneauTexte.saisir(elt.getUnite0(),
+            elt.getUnitesSousjacentes(), TypeMarquage.SELECT1_2,
+            sch.getUnitesSousjacentes(), TypeMarquage.SELECT1);
+    panneauChamps.afficher(elt);
+    creeSchema.setEnabled(false);
+    ajouteElement.setEnabled(false);
+    if (sch.getContenu().size() > 1) {
+      oteElement.setEnabled(true);
+      supprimeSchema.setEnabled(false);
+    } else {
+      oteElement.setEnabled(false);
+      supprimeSchema.setEnabled(true);
+    }
+    creeUniteElt.setEnabled(false);
+  }
+  private void etatSelectSchemaEltExterne(Schema sch, Element elt) {
+    panneauTexte.saisir(elt.getUnite0(),
+            sch.getUnitesSousjacentes(), TypeMarquage.SELECT1,
+            elt.getUnitesSousjacentes(), TypeMarquage.SELECT2);
+    panneauChamps.afficher(sch);
+    creeSchema.setEnabled(false);
+    supprimeSchema.setEnabled(false);
+    ajouteElement.setEnabled(true);
+    oteElement.setEnabled(false);
+    creeUniteElt.setEnabled(false);
+  }
+  private void forceElt(Element elt) {
+    if (saisieTypeElt.getClasseSelection() != elt.getClass() || !elt.getType().equals(saisieTypeElt.getTypeSelection())) {
+      saisieTypeElt.removeActionListener(this);
+      saisieTypeElt.setSelection(elt.getClass(), elt.getType());
+      saisieTypeElt.addActionListener(this);
+      initSaisieElt();
+    }
+    saisieElt.setSelection(elt);
+  }
+  private Element[] filtreSch(Element[] elts, Schema[] schs) {
+    ArrayList<Element> elts1 = new ArrayList<Element>();
+    for (Element elt : elts) for(Schema sch: schs) if(sch.getContenu().contains(elt)) {
+      elts1.add(elt);
+      break;
+    }
+    return elts1.toArray(new Element[0]);
+  }
+  private void initSaisieSchema(Schema sch) {
+    saisieSchema.removeActionListener(this);
+    if (saisieTypeSchemas.pasdeSelection()) saisieSchema.setModeleVide();
+    else {
+      String type0 = saisieTypeSchemas.getTypeSelection();
+      Schema[] schemas = vue.getSchemasAVoir(type0);
+      saisieSchema.setModele(schemas, vue.getIdSchemas(type0, schemas));
+    }
+    if (sch == null) saisieSchema.effSelection();
+    else saisieSchema.setSelection(sch);
+    saisieSchema.addActionListener(this);
+    saisieSchema.revalidate();
+  }
+  private void initSaisieSchema() {
+    initSaisieSchema(null);
+  }
+  private void initSaisieElt(Element elt) {
+    saisieElt.removeActionListener(this);
+    if (saisieTypeElt.pasdeSelection()) saisieElt.setModeleVide();
+    else {
+      Class<? extends Element> classe = saisieTypeElt.getClasseSelection();
+      String type = saisieTypeElt.getTypeSelection();
+      saisieElt.setModele(vue.getElements(classe, type), vue.getIdElements(classe, type));
+    }
+    if (elt == null) saisieElt.effSelection();
+    else saisieElt.setSelection(elt);
+    saisieElt.addActionListener(this);
+    saisieElt.revalidate();
+  }
+  private void initSaisieElt() {
+    initSaisieElt(null);
+  }
+}
\ No newline at end of file

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesSchemas.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsCorrelations.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsCorrelations.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsCorrelations.java	(revision 481)
@@ -0,0 +1,146 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import visuAnalec.elements.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class ModeleStatsCorrelations extends AbstractTableModel {
+  private String[] valeursChamp2;
+  private String[] valeursChamp1;
+  private int[][] nbOcc;
+  private int[] totauxChamp1;
+  private int[] totauxChamp2;
+  private int totalTotaux;
+  public ModeleStatsCorrelations() {
+    super();
+    initialise();
+  }
+  private void initialise() {
+    valeursChamp2 = new String[0];
+    valeursChamp1 = new String[0];
+    nbOcc = new int[1][1];
+    totauxChamp1 = new int[1];
+    totauxChamp2 = new int[1];
+    totalTotaux = 0;
+  }
+  public int getRowCount() {
+    return valeursChamp2.length + 2;
+  }
+  public int getColumnCount() {
+    return valeursChamp1.length + 3;
+  }
+  @Override
+  public String getColumnName(int col) {
+    return col == 0 ? "" : col == valeursChamp1.length + 2 ? "TOTAL" : col == valeursChamp1.length + 1 ? "<aucune valeur>" : valeursChamp1[col - 1];
+  }
+  public Object getValueAt(int row, int col) {
+    if (col == 0) {
+      return row == valeursChamp2.length + 1 ? "TOTAL" : row == valeursChamp2.length ? "<aucune valeur>" : valeursChamp2[row];
+    } else if (col == valeursChamp1.length + 2) {
+      return row == valeursChamp2.length + 1 ? totalTotaux : totauxChamp1[row];
+    } else {
+      return row == valeursChamp2.length + 1 ? totauxChamp2[col - 1] : nbOcc[row][col - 1];
+    }
+  }
+  Element[] getListeElementsSelected(Integer[] rows, Integer[] cols, Vue vue, Class<? extends Element> classe, 
+          String type, String champ1, String champ2) {
+    HashSet<Element> liste = new HashSet<Element>();
+    for (int i = 0; i < rows.length; i++) {
+      if(cols[i]==0) continue;
+      if (rows[i] == valeursChamp2.length + 1) {
+        if (cols[i] == valeursChamp1.length + 2) {
+          return vue.getElementsAVoir(classe, type);
+        } else {
+          String[] val1 = cols[i] == valeursChamp1.length + 1 ? new String[]{""} : new String[]{valeursChamp1[cols[i] - 1]};
+          liste.addAll(Arrays.asList(vue.getDoubleSelectionOccurrences(classe, type,champ1, val1, null, null)));
+        }
+      } else {
+        String[] val2 = rows[i] == valeursChamp2.length ? new String[]{""} : new String[]{valeursChamp2[rows[i]]};
+        if (cols[i] == valeursChamp1.length + 2) {
+          liste.addAll(Arrays.asList(vue.getDoubleSelectionOccurrences(classe, type, champ2, val2, null, null)));
+        } else {
+          String[] val1 = cols[i] == valeursChamp1.length + 1 ? new String[]{""} : new String[]{valeursChamp1[cols[i] - 1]};
+          liste.addAll(Arrays.asList(vue.getDoubleSelectionOccurrences(classe, type, champ2, val2, champ1, val1)));
+
+        }
+      }
+    }
+    Element[] tab = liste.toArray(new Element[0]);
+    Arrays.sort(tab);
+    return tab;
+  }
+  void setModele(Vue vue, Class<? extends Element> classe, String type, String champ1, String champ2) {
+    if (classe == null) {
+      setModeleVide();
+      return;
+    }
+    valeursChamp1 = champ1 == null ? new String[0] : vue.getValeursChamp(classe, type, champ1);
+    valeursChamp2 = champ2 == null ? new String[0] : vue.getValeursChamp(classe, type, champ2);
+    nbOcc = new int[valeursChamp2.length + 1][valeursChamp1.length + 1];
+    totauxChamp1 = new int[valeursChamp2.length + 1];
+    totauxChamp2 = new int[valeursChamp1.length + 1];
+    HashMap<String, HashMap<String, Integer>> compte =
+            vue.compterOccurrencesCorrelees(classe, type, champ1, champ2);
+    totalTotaux = 0;
+    for (int col = 0; col < valeursChamp1.length + 1; col++) {
+      HashMap<String, Integer> hm = compte.get(col == valeursChamp1.length ? "" : valeursChamp1[col]);
+      for (int row = 0; row < valeursChamp2.length + 1; row++) {
+        nbOcc[row][col] = hm.get(row == valeursChamp2.length ? "" : valeursChamp2[row]);
+        totauxChamp2[col] += nbOcc[row][col];
+        totauxChamp1[row] += nbOcc[row][col];
+        totalTotaux += nbOcc[row][col];
+      }
+    }
+    fireTableStructureChanged();
+  }
+  private void setModeleVide() {
+    initialise();
+    fireTableDataChanged();
+  }
+}
+
+class CorrelationsRenderer extends DefaultTableCellRenderer {
+  ModeleStatsCorrelations donnees;
+  static Color GRIS_CLAIR = new Color(0.95f, 0.95f, 0.95f);
+  static Color BLEU_CLAIR = new Color(0.9f, 0.9f, 1.0f);
+  public CorrelationsRenderer(ModeleStatsCorrelations donnees) {
+    this.donnees = donnees;
+  }
+  @Override
+  public Component getTableCellRendererComponent(JTable table, Object value,
+          boolean isSelected, boolean hasFocus, int row, int col) {
+    int colTotal = donnees.getColumnCount() - 1;
+    int rowTotal = donnees.getRowCount() - 1;
+    int totalTotaux = (Integer) donnees.getValueAt(rowTotal, colTotal);
+    setBackground(Color.WHITE);
+    setHorizontalTextPosition(JLabel.CENTER);
+    if (col == colTotal || row == rowTotal) {
+      setBackground(BLEU_CLAIR);
+    } else if (col == 0) {
+      setBackground(GRIS_CLAIR);
+      setHorizontalTextPosition(JLabel.LEFT);
+    } else if (totalTotaux > 0) {
+      int c = (Integer) donnees.getValueAt(row, col);
+      float m = ((Integer) donnees.getValueAt(row, colTotal)) * ((Integer) donnees.getValueAt(rowTotal, col)) /
+              totalTotaux * 1.0f;
+      if (c / m > 1.0f) {
+        float corr = Math.min(c / m - 1.0f, 2.0f) * 0.4f;
+        setBackground(new Color(1.0f, 1.0f - corr, 1.0f - corr));
+      }
+    }
+    return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
+  }
+}
+
+

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsCorrelations.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsCorrelations.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsCorrelations.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsCorrelations.java	(revision 481)
@@ -0,0 +1,251 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import visuAnalec.*;
+import visuAnalec.Message.*;
+import visuAnalec.elements.*;
+import visuAnalec.fichiers.*;
+import visuAnalec.texte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class VisuStatsCorrelations extends JFrame
+        implements VueListener, ActionListener, ListSelectionListener {
+  private Vue vue;
+  private ModeleStatsCorrelations donneesCorrelations = new ModeleStatsCorrelations();
+  private Class<? extends Element> classe;
+  private String type;
+  private String champ1;
+  private String champ2;
+  private TypeComboBox saisieTypeElements;
+  private JComboBox saisieChamp1 = new JComboBox();
+  private JComboBox saisieChamp2 = new JComboBox();
+  private JTable tableau;
+  private PanneauOccurrences panneauOccurrences;
+  public VisuStatsCorrelations(Container fenetre, Vue vue, PanneauEditeur pEditeur) {
+    super("Corrélations");
+    Point pos = new Point(fenetre.getX()+20, fenetre.getY()+50);
+    Dimension dim = new Dimension(fenetre.getWidth(), fenetre.getHeight()-30);
+    setLocation(pos);
+    setSize(dim);
+    this.vue = vue;
+    vue.addEventListener(this);
+    // Panneau des commandes
+    Box panneauCommandes = Box.createVerticalBox();
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieType = new JPanel(new FlowLayout());
+    pSaisieType.setBorder(new TitledBorder("Eléments"));
+    saisieTypeElements = new TypeComboBox(Element.class);
+    saisieTypeElements.setModele(vue.getTypesUnitesAVoir(), vue.getTypesRelationsAVoir(),
+            vue.getTypesSchemasAVoir());
+    saisieTypeElements.setMaximumRowCount(saisieTypeElements.getModel().getSize());
+    saisieTypeElements.setEditable(false);
+    saisieTypeElements.addActionListener(this);
+    pSaisieType.add(saisieTypeElements, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieType);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieChamp1 = new JPanel(new FlowLayout());
+    pSaisieChamp1.setBorder(new TitledBorder("Champ 1 (horizontal)"));
+    saisieChamp1.setEditable(false);
+    saisieChamp1.addActionListener(this);
+    pSaisieChamp1.add(saisieChamp1, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieChamp1);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieChamp2 = new JPanel(new FlowLayout());
+    pSaisieChamp2.setBorder(new TitledBorder("Champ 2 (vertical)"));
+    saisieChamp2.setEditable(false);
+    saisieChamp2.addActionListener(this);
+    pSaisieChamp2.add(saisieChamp2, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieChamp2);
+    panneauCommandes.add(Box.createVerticalGlue());
+    // Panneau du tableau de résultats
+    JPanel panneauAfficheTableau = new JPanel(new BorderLayout());
+    panneauAfficheTableau.setBorder(new TitledBorder("Résultats"));
+    tableau = new JTable(donneesCorrelations);
+    tableau.setDefaultRenderer(Number.class, new CorrelationsRenderer(donneesCorrelations));
+    tableau.setDefaultRenderer(Object.class, new CorrelationsRenderer(donneesCorrelations));
+    tableau.setName("tableauCorrelations");
+    tableau.setCellSelectionEnabled(true);
+    tableau.setRowHeight(40);
+    tableau.getTableHeader().setPreferredSize(new Dimension(tableau.getPreferredSize().width, 40));
+    tableau.getSelectionModel().addListSelectionListener(this);
+    JScrollPane scroll1 = new JScrollPane(tableau);
+    panneauAfficheTableau.add(scroll1, BorderLayout.CENTER);
+    JPanel pExporterCorrelations = new JPanel(new FlowLayout());
+    JButton exporterCorrelations = new JButton(new GAction("Exporter le tableau") {
+      public void executer() {
+        FichiersTableur.exporterTable(donneesCorrelations);
+      }
+    });
+    pExporterCorrelations.add(exporterCorrelations, CENTER_ALIGNMENT);
+    panneauAfficheTableau.add(pExporterCorrelations, BorderLayout.SOUTH);
+    panneauAfficheTableau.setPreferredSize(new Dimension(
+            getWidth()-panneauCommandes.getPreferredSize().width,
+            panneauCommandes.getPreferredSize().height));
+    // Panneau de visualisation des occurrences
+    panneauOccurrences = new PanneauOccurrences(vue, pEditeur);
+    JScrollPane scrollPanneauOccurrences = new JScrollPane(panneauOccurrences);
+    scrollPanneauOccurrences.setBorder(new TitledBorder("Visualisation des occurrences"));
+    JButton exporterConcordances = new JButton(
+            new GAction("Exporter les concordances") {
+              public void executer() {
+                FichiersTableur.exporterTable(panneauOccurrences.getModeleTableur());
+              }
+            });
+    JPanel pExporterConcordances = new JPanel(new FlowLayout());
+    pExporterConcordances.add(exporterConcordances, CENTER_ALIGNMENT);
+    // cadre global de la fenêtre
+    JPanel bas = new JPanel(new BorderLayout());
+    bas.add(scrollPanneauOccurrences, BorderLayout.CENTER);
+    bas.add(pExporterConcordances, BorderLayout.SOUTH);
+    JSplitPane haut = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+            panneauCommandes, panneauAfficheTableau);
+    JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, haut, bas);
+    getContentPane().add(split);
+    setVisible(true);
+    split.setDividerLocation(2./3);
+    // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+    // Initialisation
+    saisieTypeElements.effSelection();
+    afficherOccurrences();
+  }
+  private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+  }
+  private void initSaisieChamps() {
+    for (JComboBox saisieChamp : new JComboBox[]{saisieChamp1, saisieChamp2}) {
+      saisieChamp.removeActionListener(this);
+      saisieChamp.removeAllItems();
+      if (classe!=null) for (String ch : vue.getNomsChamps(classe, type))
+          saisieChamp.addItem(ch);
+      saisieChamp.setSelectedIndex(-1);
+      saisieChamp.addActionListener(this);
+    }
+    champ1 = champ2 = null;
+  }
+  void afficherOccurrences() {
+    ArrayList<Integer> rows = new ArrayList<Integer>();
+    ArrayList<Integer> cols = new ArrayList<Integer>();
+    for (int row : tableau.getSelectedRows()) {
+      for (int col : tableau.getSelectedColumns()) {
+        if (tableau.isCellSelected(row, col)) {
+          rows.add(row);
+          cols.add(col);
+        }
+      }
+    }
+    panneauOccurrences.init(classe, type,
+            donneesCorrelations.getListeElementsSelected(rows.toArray(new Integer[0]),
+            cols.toArray(new Integer[0]), vue, classe, type, champ1, champ2));
+  }
+  void changerDonnees() {
+    donneesCorrelations.setModele(vue, classe, type, champ1, champ2);
+  }
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre stat présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        afficherOccurrences();
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        switch (((StructureEvent) evt).getModif()) {
+          case AJOUT_VALEUR:
+          case RENOM_VALEUR:
+          case FUSION_VALEUR:
+          case SUPPR_VALEUR:
+          case AJOUT_FORME_UNITE:
+          case VALEUR_PAR_DEFAUT:
+            changerDonnees();
+            return;
+          case AJOUT_TYPE:  // à affiner : trop brutal
+          case AJOUT_TYPE_ET_ELEMENTS:
+          case RENOM_TYPE:
+          case FUSION_TYPE:
+          case SUPPR_TYPE:
+          case AJOUT_PROP:
+          case RENOM_PROP:
+          case FUSION_PROP:
+          case SUPPR_PROP:
+            fermerFenetre();
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+        }
+      case MODIF_ELEMENT:
+        ElementEvent evtE = (ElementEvent) evt;
+        if (evtE.getModif()!=TypeModifElement.BORNES_UNITE) changerDonnees();
+        else afficherOccurrences();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource().equals(saisieTypeElements)) {
+        classe = saisieTypeElements.getClasseSelection();
+        type = saisieTypeElements.getTypeSelection();
+        initSaisieChamps();
+        changerDonnees();
+        return;
+      }
+      if (evt.getSource().equals(saisieChamp1)) {
+        champ1 = (String) saisieChamp1.getSelectedItem();
+        changerDonnees();
+        return;
+      }
+      if (evt.getSource().equals(saisieChamp2)) {
+        champ2 = (String) saisieChamp2.getSelectedItem();
+        changerDonnees();
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.toString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  public void valueChanged(ListSelectionEvent evt) {
+    try {
+      if (evt.getValueIsAdjusting())
+        return;
+      if (evt.getSource().equals(tableau.getSelectionModel())) {
+        afficherOccurrences();
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.toString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsCorrelations.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/GPlanAFC.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/GPlanAFC.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/GPlanAFC.java	(revision 481)
@@ -0,0 +1,420 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+import JamaPlus.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.geom.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.plaf.*;
+import visuAnalec.elements.*;
+import visuAnalec.fichiers.FichiersGraphique.*;
+import visuAnalec.statistiques.ModeleStatsGeometrie.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class GPlanAFC extends JComponent
+        implements DonneesGrapheListener, MouseListener, GraphiqueExport {
+
+  private static class Ellipse {
+
+    double xcentre, ycentre;
+    double grandAxe, petitAxe;
+    double xrotation, yrotation;
+
+    private Ellipse(double xc, double yc, double ga, double pa, double xr, double yr) {
+      xcentre = xc;
+      ycentre = yc;
+      petitAxe = pa;
+      grandAxe = ga;
+      xrotation = xr;
+      yrotation = yr;
+    }
+  }
+  private final static int marge = 20;
+  private final static int delta = 1;
+  private final static int bord = marge - delta;
+  private final static int rayon = 3;
+  private final static int epaisseurSelection = 3;
+  private final static double epsilon = 0.0001;
+  private final static BasicStroke ligneEpaisse = new BasicStroke(epaisseurSelection);
+  private final static BasicStroke ligneFine = new BasicStroke();
+  private final static int dimExport = 500;
+  private double xRange, yRange, xMin, yMin;
+  private double[] xPts, yPts;
+  private int nbPts;
+  private Color[] couleurs;
+  private boolean[] etatPts;
+  private Rectangle[] rects;
+  private Ellipse ellipse;
+  private ModeleStatsGeometrie donnees;
+  private JPopupMenu menu;
+  private double echelleExport;  // pour exporter le graphique
+
+  GPlanAFC(ModeleStatsGeometrie donnees) {
+    super();
+    this.donnees = donnees;
+    donnees.addEventListener(this);
+    addMouseListener(this);
+    menu = new JPopupMenu();
+    menu.add(new GAction("Tout déselectionner") {
+
+      public void executer() {
+        deselectionnerTout();
+      }
+    });
+    menu.add(new GAction("Entourer la sélection") {
+
+      public void executer() {
+        entourerSelection();
+      }
+    });
+    menu.add(new GAction("Supprimer les points") {
+
+      public void executer() {
+        supprimerPts();
+      }
+    });
+    ToolTipManager.sharedInstance().registerComponent(this);
+  }
+
+  @Override
+  public JToolTip createToolTip() {
+    JToolTip jt = new JToolTip();
+//    jt.setBackground(JAUNE_TRES_CLAIR);
+    return jt;
+  }
+
+  public void traiterEvent(DonneesGrapheEvent evt) {
+    switch (evt.getType()) {
+      case NEW_DONNEES:
+      case MODIF_DONNEES:
+        setPts(donnees.getPts());
+        couleurs = new Color[donnees.getPts().getRowDimension()];
+        Arrays.fill(couleurs, GVisu.getCouleurSansValeur());
+        etatPts = donnees.getEtatsChoixtPts();
+        clearEllipse();
+        repaint();
+        return;
+      case NEW_COORDS:
+        setPts(donnees.getPts());
+        repaint();
+        return;
+      case CLEAR_DONNEES:
+        clearPts();
+        repaint();
+        return;
+      case NEW_COULEURS:
+        couleurs = donnees.getCouleurs();
+        repaint();
+        return;
+      case NEW_SELECT_PTS:
+        etatPts = donnees.getEtatsChoixtPts();
+        repaint();
+        return;
+      default:
+        throw new UnsupportedOperationException("cas " + evt.getType() + " non traité");
+    }
+  }
+
+  public void mouseClicked(MouseEvent e) {
+    try {
+      ArrayList<Integer> nos = getPts(getMousePosition());
+      if (!nos.isEmpty() && e.getButton() == MouseEvent.BUTTON1) {
+        clearEllipse();
+        donnees.majPtsChoisis(nos);
+      }
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  public void mousePressed(MouseEvent e) {
+    try {
+      if (e.isPopupTrigger()) {
+        showPopup(e);
+      }
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  public void mouseReleased(MouseEvent e) {
+    try {
+      if (e.isPopupTrigger()) {
+        showPopup(e);
+      }
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+
+  private void showPopup(MouseEvent e) {
+    menu.show(e.getComponent(), e.getX(), e.getY());
+  }
+
+  public void mouseEntered(MouseEvent e) {
+  }
+
+  public void mouseExited(MouseEvent e) {
+  }
+
+  @Override
+  public String getToolTipText() {
+    Point pt = getMousePosition();
+    if (pt == null) return "";
+    ArrayList<Integer> nopts = getPts(pt);
+    if (nopts.isEmpty()) return "";
+    ArrayList<ArrayList<String>> textesEtIds = donnees.getTexteIdElements(nopts);
+    return GVisu.styleIdTooltip(textesEtIds.get(0), textesEtIds.get(1));
+  }
+
+  private void deselectionnerTout() {
+    donnees.setPtsChoisis(new ArrayList<Integer>());
+    clearEllipse();
+  }
+
+  private void entourerSelection() {
+    ArrayList<Integer> nos = setEllipse(donnees.getPts(), donnees.getEtatsChoixtPts());
+    donnees.setPtsChoisis(nos);
+  }
+
+  private void supprimerPts() {
+    int nb = Tableaux.compterValeursVraies(donnees.getEtatsChoixtPts());
+    if (nb == 0) return;
+    if (!GMessages.confirmationAction("Supprimer " + nb
+            + " élément(s) de la représentation ?")) return;
+    donnees.supPtsChoisis();
+  }
+
+  private void setPts(Matrix Pts) {
+    nbPts = Pts.getRowDimension();
+    if (nbPts == 0) {
+      clearPts();
+      return;
+    }
+    xMin = Pts.minColumn(0);
+    yMin = Pts.minColumn(1);
+    xRange = Pts.maxColumn(0) - xMin;
+    yRange = Pts.maxColumn(1) - yMin;
+    xPts = new double[nbPts];
+    yPts = new double[nbPts];
+    rects = new Rectangle[nbPts];
+    for (int i = 0; i < nbPts; i++) {
+      xPts[i] = Pts.get(i, 0) - xMin;
+      yPts[i] = Pts.get(i, 1) - yMin;
+    }
+    ellipse = null;
+  }
+
+  private void clearPts() {
+    nbPts = 0;
+    xRange = 0;
+    yRange = 0;
+    xPts = new double[0];
+    yPts = new double[0];
+    rects = new Rectangle[0];
+    ellipse = null;
+  }
+
+  private void setEtatPts(boolean[] etats) {
+    etatPts = etats;
+  }
+
+  private void setCouleurs(Color[] couleurs) {
+    this.couleurs = couleurs;
+  }
+
+  private ArrayList<Integer> setEllipse(Matrix Pts, boolean[] aentourer) {
+    ArrayList<Integer> listenos = new ArrayList<Integer>();
+    for (int i = 0; i < aentourer.length; i++) if (aentourer[i])
+        listenos.add(i);
+    if (listenos.isEmpty()) return listenos;
+    Matrix PtsEntoures = getPtsUniqueCoord(Pts, listenos);
+    SingularValueDecomposition svd = new SingularValueDecomposition(PtsEntoures.columnCovariance());
+    Matrix C = PtsEntoures.columnMean();
+    double xcentre = C.get(0, 0);
+    double ycentre = C.get(0, 1);
+    Matrix U = svd.getU();
+    double xrotation = U.get(0, 0);
+    double yrotation = U.get(0, 1);
+    double[] s = svd.getSingularValues();
+    Matrix OPts = Pts.firstLineMinus(C).times(U);
+    double[] d2Pts = new double[nbPts];
+    double maxd2Pts = 0;
+    if (s[1] > epsilon) {  // cas général
+      for (int i = 0; i < nbPts; i++) {
+        d2Pts[i] = (OPts.get(i, 0) * OPts.get(i, 0)) / s[0]
+                + (OPts.get(i, 1) * OPts.get(i, 1)) / s[1];
+        if (aentourer[i]) maxd2Pts = Math.max(maxd2Pts, d2Pts[i]);
+      }
+      listenos.clear();
+      for (int i = 0; i < nbPts; i++) if (d2Pts[i] <= maxd2Pts) listenos.add(i);
+    } else if (s[0] > epsilon) { // tous les points sont alignés
+      for (int i = 0; i < nbPts; i++) {
+        d2Pts[i] = (OPts.get(i, 0) * OPts.get(i, 0)) / s[0];
+        if (aentourer[i]) maxd2Pts = Math.max(maxd2Pts, d2Pts[i]);
+      }
+      listenos.clear();
+      for (int i = 0; i < nbPts; i++)
+        if (Math.abs(OPts.get(i, 1)) < epsilon && d2Pts[i] <= maxd2Pts)
+          listenos.add(i);
+    }  // si tous les points sont confondus : on garde listenos et max2Pts=0
+    double r = Math.sqrt(maxd2Pts);
+    double grandaxe = r * Math.sqrt(s[0]);
+    double petitaxe = r * Math.sqrt(s[1]);
+    ellipse = new Ellipse(xcentre - xMin, ycentre - yMin,
+            grandaxe, petitaxe, xrotation, yrotation);
+    return listenos;
+  }
+
+  private void clearEllipse() {
+    ellipse = null;
+  }
+
+  private ArrayList<Integer> getPts(Point pt) {
+    ArrayList<Integer> nos = new ArrayList<Integer>();
+    for (int no = 0; no < nbPts; no++) {
+      if (rects[no].contains(pt)) {
+        nos.add(no);
+      }
+    }
+    return nos;
+  }
+
+  private static Matrix getPtsUniqueCoord(Matrix Pts, ArrayList<Integer> nos) {
+    ArrayList<Integer> noselects = new ArrayList<Integer>();
+    double dx, dy;
+    for (int i : nos) {
+      boolean unique = true;
+      for (int i1 : noselects) {
+        dx = Pts.get(i, 0) - Pts.get(i1, 0);
+        dy = Pts.get(i, 1) - Pts.get(i1, 1);
+        if (dx * dx + dy * dy < epsilon) {
+          unique = false;
+          break;
+        }
+      }
+      if (unique) noselects.add(i);
+    }
+    int[] nosels = new int[noselects.size()];
+    for (int i = 0; i < nosels.length; i++) nosels[i] = noselects.get(i);
+    return Pts.getMatrix(nosels, 0, 1);
+  }
+
+  @Override
+  public void paintComponent(Graphics g0) {
+    if (nbPts == 0) return;
+    Graphics2D g = (Graphics2D) g0;
+    double echelle;
+    int x0, y0, xrg, yrg, x, y;
+    Dimension dim = getSize();
+    if (xRange == 0 && yRange == 0) {
+      x0 = (int) Math.round((dim.width) / 2.0);
+      xrg = 0;
+      y0 = (int) Math.round((dim.height) / 2.0);
+      yrg = 0;
+      echelle = 0;
+    } else if (xRange == 0) {   // impossible en fait : xRange >= yRange
+      x0 = (int) Math.round((dim.width) / 2.0);
+      xrg = 0;
+      y0 = marge;
+      echelle = (dim.height - 2 * marge) / yRange;
+      yrg = (int) Math.round(yRange * echelle);
+    } else if (yRange == 0) {
+      echelle = (dim.width - 2 * marge) / xRange;
+      xrg = (int) Math.round(xRange * echelle);
+      x0 = marge;
+      yrg = 0;
+      y0 = (int) Math.round((dim.height) / 2.0);
+    } else {
+      double echx = (dim.width - 2 * marge) / xRange;
+      double echy = (dim.height - 2 * marge) / yRange;
+      if (echx < echy) {
+        echelle = echx;
+        xrg = (int) Math.round(xRange * echelle);
+        yrg = (int) Math.round(yRange * echelle);
+        x0 = marge;
+        y0 = (int) Math.round((dim.height - yrg) / 2.0);
+      } else {
+        echelle = echy;
+        xrg = (int) Math.round(xRange * echelle);
+        yrg = (int) Math.round(yRange * echelle);
+        x0 = (int) Math.round((dim.width - xrg) / 2.0);
+        y0 = marge;
+      }
+    }
+    g.drawRect(x0 - bord, y0 - bord, xrg + 2 * bord, yrg + 2 * bord);
+    for (int i = 0; i < nbPts; i++) {
+      x = x0 + (int) Math.round(echelle * xPts[i]);
+      y = y0 + (int) Math.round(echelle * yPts[i]);
+      g.setColor(couleurs[i]);
+      rects[i] = new Rectangle(x - rayon, y - rayon, 2 * rayon, 2 * rayon);
+      g.fillOval(x - rayon - 1, y - rayon - 1, 2 * rayon + 2, 2 * rayon + 2);
+      g.setStroke(etatPts[i] ? ligneEpaisse : ligneFine);
+      g.setColor(Color.BLACK);
+      int epais = etatPts[i] ? epaisseurSelection - 1 : 0;
+      g.drawOval(x - (rayon + epais), y - (rayon + epais), 2 * (rayon + epais), 2 * (rayon + epais));
+    }
+    if (ellipse == null) return;
+    double xc = x0 + ellipse.xcentre * echelle;
+    double yc = y0 + ellipse.ycentre * echelle;
+    double ga = ellipse.grandAxe * echelle + rayon + epaisseurSelection - 1;
+    double pa = ellipse.petitAxe * echelle + rayon + epaisseurSelection - 1;
+    Ellipse2D.Double ell = new Ellipse2D.Double(xc - ga, yc - pa, 2 * ga, 2 * pa);
+    g.setStroke(ligneFine);
+    g.draw(AffineTransform.getRotateInstance(ellipse.xrotation, ellipse.yrotation, xc, yc).
+            createTransformedShape(ell));
+  }
+
+  public Dimension initExport() {
+    if (nbPts == 0) return new Dimension(dimExport, dimExport);
+    if (xRange == 0 && yRange == 0) {
+      echelleExport = 0;
+      return new Dimension(2 * marge, 2 * marge);
+    } else if (xRange == 0) { // impossible, en fait
+      echelleExport = dimExport / yRange;
+      return new Dimension(2 * marge, dimExport + 2 * marge);
+    } else if (yRange == 0) {
+      echelleExport = dimExport / xRange;
+      return new Dimension(dimExport + 2 * marge, 2 * marge);
+    } else {
+      echelleExport = dimExport / xRange;
+      return new Dimension(dimExport + 2 * marge,
+              ((int) Math.round(yRange * echelleExport)) + 2 * marge);
+    }
+  }
+
+  public Rectangle getCadre() {
+    if (nbPts == 0) return null;
+    if (xRange == 0 && yRange == 0)
+      return new Rectangle(delta, delta, 2 * bord, 2 * bord);
+    else if (xRange == 0)
+      return new Rectangle(delta, delta, 2 * bord, dimExport + 2 * bord);
+    else if (yRange == 0)
+      return new Rectangle(delta, delta, dimExport + 2 * bord, 2 * bord);
+    else
+      return new Rectangle(delta, delta, dimExport + 2 * bord,
+              ((int) Math.round(yRange * echelleExport)) + 2 * bord);
+  }
+
+  public CercleColore[] getCerclesColores() {
+    CercleColore[] cercles = new CercleColore[nbPts];
+    for (int i = 0; i < nbPts; i++) {
+      cercles[i] = new CercleColore();
+      cercles[i].cx = marge + (int) Math.round(echelleExport * xPts[i]);
+      cercles[i].cy = marge + (int) Math.round(echelleExport * yPts[i]);
+      cercles[i].couleur = couleurs[i];
+      cercles[i].r = rayon;
+    }
+    return cercles;
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/GPlanAFC.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/GBarres.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/GBarres.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/GBarres.java	(revision 481)
@@ -0,0 +1,101 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package visuAnalec.statistiques;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.plaf.*;
+import visuAnalec.util.GMessages;
+
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class GBarres extends JComponent implements TableModelListener {
+
+  ModeleStatsFrequences modele;
+  BarresPainter painter;
+
+  GBarres(ModeleStatsFrequences modele) {
+    super();
+    setUI(painter = new BarresPainter());
+    this.modele = modele;
+//    System.out.println("---\nCréation : " + getPreferredSize() + " -> " + getSize());
+
+
+  }
+
+  public void tableChanged(TableModelEvent evt) {
+    try {
+      ArrayList<Float> longueurs = new ArrayList<Float>();
+      ArrayList<String> noms = new ArrayList<String>();
+      for (int i = 0; i < modele.getRowCount() - 1; i++) {
+        if ((Integer) modele.getValueAt(i, 1) > 0) {
+          longueurs.add((Float) modele.getValueAt(i, 2));
+          noms.add((String) modele.getValueAt(i, 0));
+        }
+      }
+//    System.out.println(noms + "\n" + getPreferredSize() + " -> " + getSize());
+      painter.setLongueursBarres(longueurs.toArray(new Float[0]));
+      painter.setNomsBarres(noms.toArray(new String[0]));
+      repaint();
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+}
+class BarresPainter extends ComponentUI {
+
+  private String[] nomsBarres = new String[0];
+  private Float[] longueursBarres = new Float[0];
+  static BarresPainter barresUI = new BarresPainter();
+  private Color[] couleurs = new Color[]{Color.BLUE, Color.CYAN, Color.GREEN, Color.MAGENTA,
+    Color.RED, Color.YELLOW, Color.LIGHT_GRAY, Color.ORANGE, Color.PINK
+  };
+  private int margeX = 5;
+  private int interligneY = 5;
+
+  void setLongueursBarres(Float[] longueurs) {
+    longueursBarres = longueurs;
+  }
+
+  void setNomsBarres(String[] noms) {
+    nomsBarres = noms;
+  }
+
+  @Override
+  public void paint(Graphics g, JComponent c) {
+    Dimension dim = c.getSize();
+//    System.out.println(dim);
+    int hauteurMin = g.getFontMetrics().getHeight() + 2;
+    int nbBarres = nomsBarres.length;
+    g.setColor(Color.BLACK);
+    g.drawLine(margeX, interligneY, margeX, 2 * interligneY + (hauteurMin + interligneY) * nbBarres);
+    int largeurMaxTexte = 0;
+    for (int i = 0; i < nbBarres; i++) {
+      largeurMaxTexte = Math.max(largeurMaxTexte,
+              SwingUtilities.computeStringWidth(g.getFontMetrics(), nomsBarres[i]));
+    }
+    for (int i = 0; i < nbBarres; i++) {
+      int y = interligneY + (hauteurMin + interligneY) * i;
+      int longueur = Math.round((dim.width - largeurMaxTexte) * longueursBarres[i] / 100);
+      g.setColor(Color.LIGHT_GRAY); // couleurs[i % couleurs.length]);
+      g.fillRect(margeX, y, longueur, hauteurMin);
+      g.setColor(Color.BLACK);
+      g.drawRect(margeX, y, longueur, hauteurMin);
+      g.drawString(nomsBarres[i], 2 * margeX + longueur, y + hauteurMin);
+    }
+  }
+
+  public static ComponentUI createUI(JComponent c) {
+    return barresUI;
+  }
+}
+
+

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/GBarres.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsFrequences.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsFrequences.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsFrequences.java	(revision 481)
@@ -0,0 +1,90 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+//import donnees.*;
+import java.util.*;
+import javax.swing.table.*;
+import visuAnalec.elements.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class ModeleStatsFrequences extends AbstractTableModel {
+  private String[] nomsValeurs;
+  private int[] nbOcc;
+  private String[] nomsColonnes;
+  private int totalOcc;
+ public ModeleStatsFrequences() {
+    super();
+    initialise();
+  }
+private void initialise() {
+    nomsValeurs = new String[0];
+    nbOcc = new int[]{0};
+    nomsColonnes = new String[]{"", "Nb d'occurrences", "Fréquence (%)"};
+    totalOcc = 0;
+  }
+  public int getRowCount() {
+    return nomsValeurs.length + 2;
+  }
+  public int getColumnCount() {
+    return 3;
+  }
+  @Override
+  public String getColumnName(int col) {
+    return nomsColonnes[col];
+  }
+  public Object getValueAt(int row, int col) {
+    switch (col) {
+      case 0:
+        return row == nomsValeurs.length + 1 ? "TOTAL" : row == nomsValeurs.length ? "<aucune valeur>" : nomsValeurs[row];
+      case 1:
+        return row == nomsValeurs.length + 1 ? totalOcc : nbOcc[row];
+      case 2:
+        return row == nomsValeurs.length + 1 ? 100.0f : Math.round(nbOcc[row] * 10000.0f / totalOcc) / 100.0f;
+      default:
+        return null;
+    }
+  }
+  Element[] getListeElementsRowsSelected(int[] rows, Vue vue, Class<? extends Element> classe, String type,
+          String champCible, String champFiltre, String[] valeursChampFiltre) {
+    if (rows.length == 0 || classe==null) return (new Unite[0]);
+    ArrayList<String> vals = new ArrayList<String>();
+    for (int row : rows) {
+      if (row == nomsValeurs.length + 1) {
+        return vue.getDoubleSelectionOccurrences(classe, type, null, vals.toArray(new String[0]), 
+                champFiltre, valeursChampFiltre);
+      }
+      vals.add(row == nomsValeurs.length ? "" : nomsValeurs[row]);
+    }
+    return vue.getDoubleSelectionOccurrences(classe, type, champCible, vals.toArray(new String[0]), 
+            champFiltre, valeursChampFiltre);
+  }
+  private void setModeleVide() {
+    initialise();
+    fireTableDataChanged();
+  }
+  void setModele(Vue vue, Class<? extends Element> classe, String type, String champCible,
+          String champFiltre, String[] valeursChampFiltre) {
+    if (classe==null || champCible == null || vue.getNbElementsAVoir(classe, type) == 0) {
+      setModeleVide();
+      return;
+    }
+    nomsValeurs = vue.getValeursChamp(classe, type, champCible);
+    nbOcc = new int[nomsValeurs.length + 1];
+    HashMap<String, Integer> compte =
+            vue.compterOccurrencesFiltrees(classe, type, champCible, champFiltre, valeursChampFiltre);
+    totalOcc = 0;
+    for (int row = 0; row < nomsValeurs.length + 1; row++) {
+      nbOcc[row] = compte.get(row == nomsValeurs.length ? "" : nomsValeurs[row]);
+      totalOcc += nbOcc[row];
+    }
+    fireTableDataChanged();
+  }
+}
+

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsFrequences.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsGeometrie.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsGeometrie.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsGeometrie.java	(revision 481)
@@ -0,0 +1,188 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+import JamaPlus.*;
+import java.awt.*;
+import java.util.*;
+import java.util.ArrayList;
+import visuAnalec.elements.*;
+import visuAnalec.vue.*;
+
+public class ModeleStatsGeometrie {
+  public enum TypeEventDonneesGraphe {
+    NEW_DONNEES,
+    MODIF_DONNEES,
+    CLEAR_DONNEES,
+    NEW_COORDS,
+    NEW_COULEURS,
+    NEW_SELECT_PTS
+  }
+
+  public interface DonneesGrapheListener extends EventListener {
+    void traiterEvent(DonneesGrapheEvent e);
+  }
+
+  public class DonneesGrapheEvent extends EventObject {
+    private TypeEventDonneesGraphe type;
+    DonneesGrapheEvent(Object source, TypeEventDonneesGraphe type) {
+      super(source);
+      this.type = type;
+    }
+    public TypeEventDonneesGraphe getType() {
+      return type;
+    }
+  }
+  private ArrayList<DonneesGrapheListener> listeCorrespondants = new ArrayList<DonneesGrapheListener>();
+  void addEventListener(DonneesGrapheListener correspondant) {
+    listeCorrespondants.add(correspondant);
+  }
+  void removeEventListener(DonneesGrapheListener correspondant) {
+    listeCorrespondants.remove(correspondant);
+  }
+  private void fireDonneesGrapheEvent(DonneesGrapheEvent evt) {
+    for (Object corresp : listeCorrespondants.toArray()) {
+      ((DonneesGrapheListener) corresp).traiterEvent(evt);
+    }
+  }
+  private Vue vue;
+  private Class<? extends Element> classe;
+  private String type;
+  private String[] champsPertinents;
+  private Element[] elementsRetenus;
+  private Matrix Pts;
+  private Color[] couleursPts;
+  private ArrayList<Integer> nosPtsChoisis;
+  public Class<? extends Element> getClasseElements() {
+    return classe;
+  }
+  public String getTypeElements() {
+    return type;
+  }
+  public Matrix getPts() {
+    return Pts;
+  }
+  public Color[] getCouleurs() {
+    return couleursPts;
+  }
+  public boolean[] getEtatsChoixtPts() {
+    boolean[] etats = new boolean[elementsRetenus.length];
+    for (int no : nosPtsChoisis) {
+      etats[no] = true;
+    }
+    return etats;
+  }
+  public ArrayList<ArrayList<String>> getTexteIdElements(ArrayList<Integer> nos) {
+    ArrayList<ArrayList<String>> textesIds = new ArrayList<ArrayList<String>>();
+    ArrayList<String> textes = new ArrayList<String>();
+    ArrayList<String> ids = new ArrayList<String>();
+    for (int i = 0; i<nos.size(); i++) {
+      Element elt = elementsRetenus[nos.get(i)];
+      textes.add(vue.getTexteUnite(elt.getUnite0()));
+      ids.add(vue.getIdElement(elt));
+    }
+    textesIds.add(textes);
+    textesIds.add(ids);
+    return textesIds;
+  }
+  public Element[] getListeElementsChoisis() {
+    Element[] liste = new Element[nosPtsChoisis.size()];
+    for (int i = 0; i<liste.length; i++) {
+      liste[i] = elementsRetenus[nosPtsChoisis.get(i)];
+    }
+    Arrays.sort(liste);
+    return liste;
+  }
+//  public Unite getDerniereUniteChoisie() {
+//    if (nosPtsChoisis.isEmpty()) {
+//      return null;
+//    }
+//    return unitesSelectionnees[nosPtsChoisis.get(nosPtsChoisis.size() - 1)];
+//  }
+  void initialise(Vue vue, Class<? extends Element> classe, String type) {
+    this.vue = vue;
+    this.type = type;
+    this.classe = classe;
+    if (classe==null) {
+      champsPertinents = new String[0];
+      elementsRetenus = new Element[0];
+      Pts = null;
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.CLEAR_DONNEES));
+      return;
+    }
+    champsPertinents = vue.getNomsChamps(classe, type);
+    elementsRetenus = vue.getElementsAVoir(classe, type);
+    if (calculerCoord()) {
+      nosPtsChoisis = new ArrayList<Integer>();
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.NEW_DONNEES));
+    } else {
+      Pts = null;
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.CLEAR_DONNEES));
+    }
+  }
+  void majChampsSelect(String[] champsSelect) {
+    champsPertinents = champsSelect;
+    if (champsSelect.length>0&&calculerCoord()) {
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.NEW_COORDS));
+    } else {
+      Pts = null;
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.CLEAR_DONNEES));
+    }
+  }
+  void majChampAffiche(String champAffiche, HashMap<String, Color> couleurValeur) {
+    couleursPts = new Color[elementsRetenus.length];
+    for (int i = 0; i<elementsRetenus.length; i++) {
+      couleursPts[i] = couleurValeur.get(vue.getValeurChamp(elementsRetenus[i], champAffiche));
+    }
+    fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.NEW_COULEURS));
+  }
+  boolean calculerCoord() {
+//    Matrix mat = vue.getMatrice(classe, type, champsPertinents, elementsRetenus);
+    SparseMatrix mat = vue.getMatriceCreuse(classe, type, champsPertinents, elementsRetenus);
+    Matrix CP = mat.afc().getCP();
+    if (CP==null) return false;
+    if (CP.getColumnDimension()<2) {
+      Pts = new Matrix(elementsRetenus.length, 2);
+      if (CP.getColumnDimension()==1)
+        Pts.setMatrix(0, elementsRetenus.length-1, 0, 0, CP);
+    } else {
+      Pts = CP.getMatrix(0, elementsRetenus.length-1, 0, 1);
+    }
+    return true;
+  }
+  void setPtsChoisis(ArrayList<Integer> nos) {
+    nosPtsChoisis = nos;
+    fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.NEW_SELECT_PTS));
+  }
+  void majPtsChoisis(ArrayList<Integer> nos) {
+    for (Integer no : nos) {
+      if (nosPtsChoisis.contains(no)) {
+        nosPtsChoisis.remove(no);
+      } else {
+        nosPtsChoisis.add(no);
+      }
+    }
+    fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.NEW_SELECT_PTS));
+  }
+  void supPtsChoisis() {
+    ArrayList<Element> EltsSelects = new ArrayList<Element>(
+            Arrays.asList(elementsRetenus));
+    for (Integer no : nosPtsChoisis) {
+      EltsSelects.remove(elementsRetenus[no]);
+    }
+    elementsRetenus = EltsSelects.toArray(new Element[0]);
+    if (calculerCoord()) {
+      nosPtsChoisis = new ArrayList<Integer>();
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.MODIF_DONNEES));
+    } else {
+      Pts = null;
+      fireDonneesGrapheEvent(new DonneesGrapheEvent(this, TypeEventDonneesGraphe.CLEAR_DONNEES));
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/ModeleStatsGeometrie.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsFrequences.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsFrequences.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsFrequences.java	(revision 481)
@@ -0,0 +1,278 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+import visuAnalec.texte.PanneauOccurrences;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import visuAnalec.*;
+import visuAnalec.Message.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.elements.*;
+import visuAnalec.fichiers.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class VisuStatsFrequences extends JFrame
+        implements VueListener, ActionListener, ListSelectionListener {
+  private Vue vue;
+  private ModeleStatsFrequences donneesFrequences = new ModeleStatsFrequences();
+  private Class<? extends Element> classe;
+  private String type;
+  private String champEtudie;
+  private String champFiltre;
+  private String[] valeursChampFiltre;
+  private TypeComboBox saisieTypeElements;
+  private JComboBox saisieChampEtudie = new JComboBox();
+  private JComboBox saisieChampFiltre = new JComboBox();
+  private JList saisieValeursChampFiltre = new JList();
+  private JTable tableau;
+  private PanneauOccurrences panneauOccurrences;
+  public VisuStatsFrequences(Container fenetre, Vue vue, PanneauEditeur pEditeur) {
+    super("Fréquences");
+    Point pos = new Point(fenetre.getX()+20, fenetre.getY()+50);
+    Dimension dim = new Dimension(fenetre.getWidth(), fenetre.getHeight()-30);
+    setLocation(pos);
+    setSize(dim);
+    this.vue = vue;
+    vue.addEventListener(this);
+
+    // Panneau des commandes
+    Box panneauCommandes = Box.createVerticalBox();
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieType = new JPanel(new FlowLayout());
+    pSaisieType.setBorder(new TitledBorder("Eléments"));
+    saisieTypeElements = new TypeComboBox(Element.class);
+    saisieTypeElements.setModele(vue.getTypesUnitesAVoir(), vue.getTypesRelationsAVoir(),
+            vue.getTypesSchemasAVoir());
+    saisieTypeElements.setEditable(false);
+    saisieTypeElements.setMaximumRowCount(saisieTypeElements.getModel().getSize());
+    saisieTypeElements.addActionListener(this);
+    pSaisieType.add(saisieTypeElements, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieType);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieChamp = new JPanel(new FlowLayout());
+    pSaisieChamp.setBorder(new TitledBorder("Champ à analyser"));
+    saisieChampEtudie.setEditable(false);
+    saisieChampEtudie.addActionListener(this);
+    pSaisieChamp.add(saisieChampEtudie, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieChamp);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieFiltre = new JPanel(new BorderLayout());
+    pSaisieFiltre.setBorder(new TitledBorder("Filtre"));
+    saisieChampFiltre.setEditable(false);
+    saisieChampFiltre.addActionListener(this);
+    pSaisieFiltre.add(saisieChampFiltre, BorderLayout.NORTH);
+    saisieValeursChampFiltre.addListSelectionListener(this);
+    pSaisieFiltre.add(new JScrollPane(saisieValeursChampFiltre), BorderLayout.CENTER);
+    panneauCommandes.add(pSaisieFiltre);
+    panneauCommandes.add(Box.createVerticalGlue());
+    // Panneau du tableau de résultats
+    JPanel panneauAfficheTableau = new JPanel(new BorderLayout());
+    panneauAfficheTableau.setBorder(new TitledBorder("Résultats"));
+    tableau = new JTable(donneesFrequences);
+    tableau.getSelectionModel().addListSelectionListener(this);
+    JScrollPane scrollTableau = new JScrollPane(tableau);
+    panneauAfficheTableau.add(scrollTableau, BorderLayout.CENTER);
+    JPanel pExporterFrequences = new JPanel(new FlowLayout());
+    JButton exporterFrequences = new JButton(new GAction("Exporter le tableau") {
+      public void executer() {
+        FichiersTableur.exporterTable(donneesFrequences);
+      }
+    });
+    pExporterFrequences.add(exporterFrequences, CENTER_ALIGNMENT);
+    panneauAfficheTableau.add(pExporterFrequences, BorderLayout.SOUTH);
+//    panneauAfficheTableau.setPreferredSize(new Dimension(
+//            Math.round((dim.width - panneauCommandes.getPreferredSize().width) / 2),
+//            panneauCommandes.getPreferredSize().height));
+    // Panneau de l'affichage graphique
+    GBarres panneauAfficheBarres = new GBarres(donneesFrequences);
+    JScrollPane scrollPanneauBarres = new JScrollPane(panneauAfficheBarres);
+    scrollPanneauBarres.setBorder(new TitledBorder("Graphique"));
+    scrollPanneauBarres.setPreferredSize(scrollTableau.getPreferredSize());
+    donneesFrequences.addTableModelListener(panneauAfficheBarres);
+    // Panneau de visualisation des occurrences
+    panneauOccurrences = new PanneauOccurrences(vue, pEditeur);
+    JScrollPane scrollPanneauOccurrences = new JScrollPane(panneauOccurrences);
+    scrollPanneauOccurrences.setBorder(
+            new TitledBorder("Visualisation des occurrences"));
+    JButton exporterConcordances = new JButton(
+            new GAction("Exporter les concordances") {
+              public void executer() {
+                FichiersTableur.exporterTable(panneauOccurrences.getModeleTableur());
+              }
+            });
+    JPanel pExporterConcordances = new JPanel(new FlowLayout());
+    pExporterConcordances.add(exporterConcordances, CENTER_ALIGNMENT);
+    // cadre global de la fenêtre
+    JPanel haut = new JPanel(new BorderLayout());
+    haut.add(panneauCommandes, BorderLayout.WEST);
+    haut.add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panneauAfficheTableau, panneauAfficheBarres),
+            BorderLayout.CENTER);
+    JPanel bas = new JPanel(new BorderLayout());
+    bas.add(scrollPanneauOccurrences, BorderLayout.CENTER);
+    bas.add(pExporterConcordances, BorderLayout.SOUTH);
+    JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, haut, bas);
+    setContentPane(split);
+    setVisible(true);
+    split.setDividerLocation(2./3);
+    // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+    // Initialisation
+    saisieTypeElements.effSelection();
+    afficherOccurrences();
+  }
+  private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+  }
+  private void initSaisieChampEtudie() {
+    saisieChampEtudie.removeActionListener(this);
+    saisieChampEtudie.removeAllItems();
+    if (classe!=null) for (String ch : vue.getNomsChamps(classe, type))
+        saisieChampEtudie.addItem(ch);
+    saisieChampEtudie.setSelectedIndex(-1);
+    champEtudie = null;
+    saisieChampEtudie.addActionListener(this);
+  }
+  private void initSaisieChampFiltre() {
+    saisieChampFiltre.removeActionListener(this);
+    saisieChampFiltre.removeAllItems();
+    saisieChampFiltre.addItem("<pas de filtre>");
+    if (classe!=null) for (String ch : vue.getNomsChamps(classe, type))
+        saisieChampFiltre.addItem(ch);
+    saisieChampFiltre.setSelectedIndex(0);
+    champFiltre = null;
+    saisieChampFiltre.addActionListener(this);
+  }
+  private void initSaisieValeursChampFiltre() {
+    saisieValeursChampFiltre.removeListSelectionListener(this);
+    if (champFiltre==null) {
+      saisieValeursChampFiltre.setListData(new String[0]);
+    } else {
+      saisieValeursChampFiltre.setListData(vue.getValeursChamp(classe, type, champFiltre));
+    }
+    saisieValeursChampFiltre.setSelectedIndex(-1);
+    saisieValeursChampFiltre.addListSelectionListener(this);
+  }
+  void afficherOccurrences() {
+    panneauOccurrences.init(classe, type, donneesFrequences.getListeElementsRowsSelected(tableau.getSelectedRows(), vue, classe,
+            type, champEtudie, champFiltre, valeursChampFiltre));
+  }
+  void changerDonnees() {
+    Object[] vals = saisieValeursChampFiltre.getSelectedValues();
+    valeursChampFiltre = new String[vals.length];
+    for (int i = 0; i<vals.length; i++) {
+      valeursChampFiltre[i] = (String) vals[i];
+    }
+    donneesFrequences.setModele(vue, classe, type, champEtudie, champFiltre, valeursChampFiltre);
+  }
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre stat présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        afficherOccurrences();
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        switch (((StructureEvent) evt).getModif()) {
+          case AJOUT_VALEUR:
+          case RENOM_VALEUR:
+          case FUSION_VALEUR:
+          case SUPPR_VALEUR:
+          case VALEUR_PAR_DEFAUT:
+          case AJOUT_FORME_UNITE:
+            changerDonnees();
+            return;
+          case AJOUT_TYPE:  // à affiner : trop brutal
+          case AJOUT_TYPE_ET_ELEMENTS:
+          case RENOM_TYPE:
+          case FUSION_TYPE:
+          case SUPPR_TYPE:
+          case AJOUT_PROP:
+          case RENOM_PROP:
+          case FUSION_PROP:
+          case SUPPR_PROP:
+            fermerFenetre();
+            return;
+          default:
+            throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+        }
+      case MODIF_ELEMENT:
+        ElementEvent evtE = (ElementEvent) evt;
+        if (evtE.getModif()!=TypeModifElement.BORNES_UNITE) changerDonnees();
+        else afficherOccurrences();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource().equals(saisieTypeElements)) {
+        classe = saisieTypeElements.getClasseSelection();
+        type = saisieTypeElements.getTypeSelection();
+        initSaisieChampEtudie();
+        initSaisieChampFiltre();
+        changerDonnees();
+        return;
+      }
+      if (evt.getSource().equals(saisieChampEtudie)) {
+        champEtudie = (String) saisieChampEtudie.getSelectedItem();
+        changerDonnees();
+        return;
+      }
+      if (evt.getSource().equals(saisieChampFiltre)) {
+        int ind = saisieChampFiltre.getSelectedIndex();
+        if (ind==0) champFiltre = null;
+        else champFiltre = (String) saisieChampFiltre.getSelectedItem();
+        initSaisieValeursChampFiltre();
+        changerDonnees();
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  public void valueChanged(ListSelectionEvent evt) {
+    try {
+      if (evt.getValueIsAdjusting()) return;
+      if (evt.getSource().equals(saisieValeursChampFiltre)) {
+        changerDonnees();
+        return;
+      }
+      if (evt.getSource().equals(tableau.getSelectionModel())) {
+        afficherOccurrences();
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.toString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsFrequences.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsGeometrie.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsGeometrie.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsGeometrie.java	(revision 481)
@@ -0,0 +1,364 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec.statistiques;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.table.*;
+import visuAnalec.*;
+import visuAnalec.Message.*;
+import visuAnalec.elements.*;
+import visuAnalec.fichiers.*;
+import visuAnalec.statistiques.ModeleStatsGeometrie.*;
+import visuAnalec.texte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+import visuAnalec.vue.Vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class VisuStatsGeometrie extends JFrame implements VueListener, ActionListener, DonneesGrapheListener {
+  private Vue vue;
+  private ModeleStatsGeometrie donneesGraphe = new ModeleStatsGeometrie();
+  private GPlanAFC panneauAfficheGraphe;
+  private Class<? extends Element> classe;
+  private String type;
+  private String[] listeChampsSelectionnes;
+  private String champAffiche;
+  private TypeComboBox saisieTypeElements;
+  private JList saisieChampsSelectionnes = new JList();
+  private JComboBox saisieChampAffiche = new JComboBox();
+  private JList legendeChampAffiche = new JList();
+  private PanneauOccurrences panneauOccurrences;
+  public VisuStatsGeometrie(Container fenetre, Vue vue, PanneauEditeur pEditeur) {
+    super("Représentations géométriques");
+    Point pos = new Point(fenetre.getX()+20, fenetre.getY()+20);
+    Dimension dim = new Dimension(fenetre.getWidth(), fenetre.getHeight());
+    setLocation(pos);
+    setSize(dim);
+    this.vue = vue;
+    vue.addEventListener(this);
+
+    // Panneau des commandes
+    Box panneauCommandes = Box.createVerticalBox();
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieType = new JPanel(new FlowLayout());
+    pSaisieType.setBorder(new TitledBorder("Eléments"));
+    saisieTypeElements = new TypeComboBox(Element.class);
+    saisieTypeElements.setModele(vue.getTypesUnitesAVoir(), vue.getTypesRelationsAVoir(),
+            vue.getTypesSchemasAVoir());
+    saisieTypeElements.setEditable(false);
+    saisieTypeElements.addActionListener(this);
+    pSaisieType.add(saisieTypeElements, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieType);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pSaisieSelection = new JPanel(new FlowLayout());
+    pSaisieSelection.setBorder(new TitledBorder("Champs pertinents"));
+    pSaisieSelection.add(saisieChampsSelectionnes, CENTER_ALIGNMENT);
+    panneauCommandes.add(pSaisieSelection);
+    panneauCommandes.add(Box.createVerticalGlue());
+    JPanel pAfficherGraphe = new JPanel(new FlowLayout());
+    JButton afficherGraphe = new JButton(new GAction("Mettre à jour le graphe") {
+      public void executer() {
+        Object[] valSelect = saisieChampsSelectionnes.getSelectedValues();
+        String[] chs = new String[valSelect.length];
+        for (int i = 0; i<valSelect.length; i++) {
+          chs[i] = (String) valSelect[i];
+        }
+        donneesGraphe.majChampsSelect(chs);
+      }
+    });
+    pAfficherGraphe.add(afficherGraphe, CENTER_ALIGNMENT);
+    panneauCommandes.add(pAfficherGraphe);
+    panneauCommandes.add(Box.createVerticalGlue());
+
+    // Panneau du graphe
+    JPanel panneauAfficheGraphique = new JPanel(new BorderLayout());
+    panneauAfficheGraphique.setBorder(new TitledBorder("Graphique"));
+    panneauAfficheGraphique.setPreferredSize(new Dimension(
+            Math.round((getWidth()-panneauCommandes.getPreferredSize().width)/2),
+            panneauCommandes.getPreferredSize().height));
+    panneauAfficheGraphe = new GPlanAFC(donneesGraphe);
+    JScrollPane scroll1 = new JScrollPane(panneauAfficheGraphe);
+    panneauAfficheGraphique.add(scroll1, BorderLayout.CENTER);
+    JPanel pExporterGraphique = new JPanel(new FlowLayout());
+    JButton exporterGraphiqueSVG = new JButton(
+            new GAction("<html> Exporter le graphique<br>en format xml (.svg)") {
+              public void executer() {
+                FichiersGraphique.exporterGraphiqueSVG(panneauAfficheGraphe);
+              }
+            });
+    JButton exporterGraphiqueEMF = new JButton(
+            new GAction("<html> Exporter le graphique<br>vers MS-Office (.emf)") {
+              public void executer() {
+                FichiersGraphique.exporterGraphiqueEMF(panneauAfficheGraphe);
+              }
+            });
+    //  exporterGraphiqueEMF.setText("<htlm> Exporter le graphique<br>vers MS-Office (.emf)");
+    pExporterGraphique.add(exporterGraphiqueSVG, CENTER_ALIGNMENT);
+    pExporterGraphique.add(exporterGraphiqueEMF, CENTER_ALIGNMENT);
+    panneauAfficheGraphique.add(pExporterGraphique, BorderLayout.SOUTH);
+
+    // Panneau champ affiché 
+    Box panneauChampAffiche = Box.createVerticalBox();
+    panneauChampAffiche.add(Box.createVerticalGlue());
+    JPanel pChampAffiche = new JPanel(new BorderLayout());
+    pChampAffiche.setBorder(new TitledBorder("Champ à afficher"));
+    saisieChampAffiche.setEditable(false);
+    saisieChampAffiche.addActionListener(this);
+    pChampAffiche.add(saisieChampAffiche, BorderLayout.NORTH);
+    legendeChampAffiche.setCellRenderer(new LegendeCellRenderer());
+    pChampAffiche.add(legendeChampAffiche, BorderLayout.CENTER);
+    panneauChampAffiche.add(pChampAffiche);
+
+    // Panneau valeurs typiques 
+    JPanel panneauValTypiques = new JPanel(new BorderLayout());
+    panneauValTypiques.setBorder(new TitledBorder("Valeurs typiques"));
+    JLabel affNbElements = new JLabel("", JLabel.CENTER);
+    panneauValTypiques.add(affNbElements, BorderLayout.NORTH);
+    ModeleValTypiques donneesValTypiques =
+            new ModeleValTypiques(vue, donneesGraphe, affNbElements);
+    donneesGraphe.addEventListener(donneesValTypiques);
+    JTable tableauValTypiques = new JTable(donneesValTypiques);
+    JScrollPane scrollChampAffiche = new JScrollPane(tableauValTypiques);
+    panneauValTypiques.add(scrollChampAffiche, BorderLayout.CENTER);
+
+    // Panneau de visualisation des occurrences
+    panneauOccurrences = new PanneauOccurrences(vue, pEditeur);
+    JScrollPane scrollPanneauOccurrences = new JScrollPane(panneauOccurrences);
+    scrollPanneauOccurrences.setBorder(new TitledBorder("Visualisation des occurrences"));
+      JButton exporterConcordances = new JButton(
+            new GAction("Exporter les concordances") {
+      public void executer() {
+       FichiersTableur.exporterTable(panneauOccurrences.getModeleTableur());
+      }
+    });
+    JPanel pExporterConcordances = new JPanel(new FlowLayout());
+    pExporterConcordances.add(exporterConcordances, CENTER_ALIGNMENT); 
+
+    donneesGraphe.addEventListener(this);  // pour lancer afficheOccurrences
+
+    // cadre global de la fenêtre
+    JSplitPane split1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+            panneauChampAffiche, panneauValTypiques);
+    JSplitPane split2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+            panneauAfficheGraphique, split1);
+    JSplitPane split3 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+            panneauCommandes, split2);
+    JPanel bas = new JPanel(new BorderLayout());
+    bas.add(scrollPanneauOccurrences, BorderLayout.CENTER);
+    bas.add(pExporterConcordances, BorderLayout.SOUTH);
+    JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
+            split3, bas);
+    getContentPane().add(split);
+    setVisible(true);
+    split3.setDividerLocation(0.15);
+    split2.setDividerLocation(0.4);
+    split1.setDividerLocation(0.3);
+    split.setDividerLocation(2./3);
+
+    // Fermeture de la fenêtre
+    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent evt) {
+        fermerFenetre();
+      }
+    });
+
+    // Initialisation
+    saisieTypeElements.effSelection();
+  }
+  private void fermerFenetre() {
+    vue.removeEventListener(this);
+    dispose();
+  }
+  void initSaisieChampsSelectionnes() {
+    if (classe==null) {
+      listeChampsSelectionnes = new String[0];
+      saisieChampsSelectionnes.setListData(listeChampsSelectionnes);
+    } else {
+      listeChampsSelectionnes = vue.getNomsChamps(classe, type);
+      saisieChampsSelectionnes.setListData(listeChampsSelectionnes);
+      saisieChampsSelectionnes.addSelectionInterval(0, listeChampsSelectionnes.length-1);
+    }
+  }
+  void initSaisieChampAffiche() {
+    saisieChampAffiche.removeAllItems();
+    if (classe!=null) {
+      for (String ch : vue.getNomsChamps(classe, type)) {
+        saisieChampAffiche.addItem(ch);
+      }
+    }
+    saisieChampAffiche.setSelectedIndex(-1);
+    champAffiche = null;
+    initLegendeChampAffiche();
+  }
+  void initLegendeChampAffiche() {
+    legendeChampAffiche.setListData(new LegendeLabel[0]);
+    HashMap<String, Color> couleurValeur = new HashMap<String, Color>();
+    couleurValeur.put("", GVisu.getCouleurSansValeur());
+    donneesGraphe.majChampAffiche(champAffiche, couleurValeur);
+  }
+  void majCouleursChampAffiche() {
+    String[] vals = classe==null ? new String[0] : vue.getValeursChamp(classe, type, champAffiche);
+    HashMap<String, Color> couleurValeur = new HashMap<String, Color>();
+    LegendeLabel[] legende = new LegendeLabel[vals.length+1];
+    for (int i = 0; i<vals.length; i++) {
+      legende[i] = new LegendeLabel(vals[i], GVisu.getCouleur(i));
+      couleurValeur.put(vals[i], GVisu.getCouleur(i));
+    }
+    legende[vals.length] = new LegendeLabel("<aucune valeur>", GVisu.getCouleurSansValeur());
+    couleurValeur.put("", GVisu.getCouleurSansValeur());
+    legendeChampAffiche.setListData(legende);
+    donneesGraphe.majChampAffiche(champAffiche, couleurValeur);
+  }
+  public void traiterEvent(Message evt) {
+    switch (evt.getType()) {
+      case CLEAR_CORPUS:
+        fermerFenetre();
+        return;
+      case NEW_CORPUS:  // impossible en principe : CLEAR_CORPUS a détruit la fenêtre
+        throw new UnsupportedOperationException("Fenêtre stat présente lors d'un message NEW_CORPUS ???");
+      case MODIF_TEXTE:
+        return;
+      case MODIF_VUE:
+        fermerFenetre();
+        return;
+      case MODIF_STRUCTURE:
+        fermerFenetre();
+        return;
+      case MODIF_ELEMENT:
+        ElementEvent evtE = (ElementEvent) evt;
+        if (evtE.getModif()!=TypeModifElement.BORNES_UNITE) {
+          fermerFenetre();
+        }
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getType()+" oublié dans un switch");
+    }
+  }
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource().equals(saisieTypeElements)) {
+        classe = saisieTypeElements.getClasseSelection();
+        type = saisieTypeElements.getTypeSelection();
+        donneesGraphe.initialise(vue, classe, type);
+        initSaisieChampsSelectionnes();
+        initSaisieChampAffiche();
+        return;
+      }
+      if (evt.getSource().equals(saisieChampAffiche)) {
+        champAffiche = (String) saisieChampAffiche.getSelectedItem();
+        majCouleursChampAffiche();
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "
+              +evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  public void traiterEvent(DonneesGrapheEvent evt) {
+    switch (evt.getType()) {
+      case NEW_DONNEES:
+      case CLEAR_DONNEES:
+        panneauOccurrences.initVide();
+        return;
+      case MODIF_DONNEES:
+        panneauOccurrences.initVide();
+        majCouleursChampAffiche();
+        return;
+      case NEW_SELECT_PTS:
+        panneauOccurrences.init(classe, type,
+                donneesGraphe.getListeElementsChoisis());
+        return;
+      case NEW_COORDS:
+      case NEW_COULEURS:
+        return;
+      default:
+        throw new UnsupportedOperationException("cas "+evt.getType()
+                +" non traité dans un switch");
+    }
+  }
+
+  static class ModeleValTypiques extends AbstractTableModel
+          implements DonneesGrapheListener {
+    String[] nomsColonnes;
+    Vue.TripletValTypique[] triplets;
+    ModeleStatsGeometrie donnees;
+    Vue vue;
+    JLabel affNbElts;
+    public ModeleValTypiques(Vue vue, ModeleStatsGeometrie donnees, JLabel affNbElts) {
+      super();
+      this.donnees = donnees;
+      this.vue = vue;
+      this.affNbElts = affNbElts;
+      initialise();
+    }
+    private void initialise() {
+      nomsColonnes = new String[]{"Champ", "Valeur", "Pourcentage"};
+      setModeleVide();
+    }
+    private void setModeleVide() {
+      triplets = new Vue.TripletValTypique[0];
+      affNbElts.setText("Pas d'élément sélectionné");
+      fireTableDataChanged();
+    }
+    private void setModele(Class<? extends Element> classe, String type, Element[] elts) {
+      triplets = vue.getValTypiques(classe, type, elts);
+      affNbElts.setText(elts.length==1 ? "Un seul élément sélectionné"
+              : elts.length+" éléments sélectionnés");
+      fireTableDataChanged();
+    }
+    public int getRowCount() {
+      return triplets.length;
+    }
+    public int getColumnCount() {
+      return 3;
+    }
+    @Override
+    public String getColumnName(int col) {
+      return nomsColonnes[col];
+    }
+    public Object getValueAt(int row, int col) {
+      switch (col) {
+        case 0:
+          return triplets[row].champ;
+        case 1:
+          return triplets[row].valeur;
+        case 2:
+          return Math.round(triplets[row].pourcentage*10000)/100.0f;
+        default:
+          return null;
+      }
+    }
+    public void traiterEvent(DonneesGrapheEvent evt) {
+      switch (evt.getType()) {
+        case NEW_DONNEES:
+        case CLEAR_DONNEES:
+        case MODIF_DONNEES:
+          setModeleVide();
+          return;
+        case NEW_SELECT_PTS:
+          setModele(donnees.getClasseElements(), donnees.getTypeElements(),
+                  donnees.getListeElementsChoisis());
+          return;
+        case NEW_COORDS:
+        case NEW_COULEURS:
+          return;
+        default:
+          throw new UnsupportedOperationException("cas "+evt.getType()+" non traité dans un switch");
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/statistiques/VisuStatsGeometrie.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauChamps.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauChamps.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauChamps.java	(revision 481)
@@ -0,0 +1,138 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import visuAnalec.elements.*;
+import visuAnalec.util.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class PanneauChamps extends JPanel {
+  ArrayList<GChamp> champs = new ArrayList<GChamp>();
+  private Vue vue;
+  private Element element = null;
+  private Class<? extends Element> classe = null;
+  private String type = null;
+  private JPanel cadre;
+  public PanneauChamps(PanneauEditeur pEdit, Vue vue) {
+    super(new BorderLayout());
+    setBorder(new TitledBorder("Champs"));
+    cadre = new JPanel(new GridLayout(0, 1));
+    JScrollPane scroll = new JScrollPane(cadre);
+    add(scroll, BorderLayout.CENTER);
+    this.vue = vue;
+  }
+  void reafficher() {
+    if (element == null) return;
+    type = null;
+    afficher(element);
+  }
+  void afficher(Element elt) {
+    this.element = elt;
+    if (elt.getClass() != classe || !elt.getType().equals(type)) {
+      type = elt.getType();
+      classe = elt.getClass();
+      afficherTouslesChamps();
+    }
+    ((TitledBorder) getBorder()).setTitle("Champs " + GVisu.getNomDeLaClasse(elt) + " :  \"" +
+            vue.getIdElement(elt) + "\"");
+    for (GChamp gc : champs) {
+      gc.afficher(elt);
+    }
+    revalidate();
+    repaint();
+  }
+  void effacer() {
+    cadre.removeAll();
+    type = null;
+    element = null;
+    ((TitledBorder) getBorder()).setTitle("Champs");
+    revalidate();
+    repaint();
+  }
+  private void afficherTouslesChamps() {
+    cadre.removeAll();
+    champs.clear();
+
+    int niveau = 0;
+    for (String[] champsniveau : vue.getChamps(classe, type)) {
+      JPanel panneauniveau = new JPanel();
+ //     panneauniveau.setBorder(new TitledBorder("Niveau " + ++niveau));
+      for (String champ : champsniveau) {
+        GChamp gc = new GChamp(vue, classe, type, champ);
+        champs.add(gc);
+        panneauniveau.add(gc);
+      }
+      cadre.add(panneauniveau);
+    }
+  }
+
+  private static class GChamp extends JPanel implements ActionListener {
+    JComboBox afficheValeurChamp;
+    Vue vue;
+    Class<? extends Element> classe;
+    String type;
+    String champ;
+    Element element = null;
+    GChamp(Vue vue, Class<? extends Element> classe, String type, String champ) {
+      super();
+      this.vue = vue;
+      this.classe = classe;
+      this.type = type;
+      this.champ = champ;
+      Box groupe = Box.createVerticalBox();
+      Box titre = Box.createHorizontalBox();
+      titre.add(Box.createHorizontalGlue());
+      JLabel label = new JLabel(champ, JLabel.CENTER);
+ //     label.setPreferredSize(new Dimension(50, 10));
+      titre.add(label);
+      titre.add(Box.createHorizontalGlue());
+      groupe.add(titre);
+      groupe.add(Box.createVerticalStrut(2));
+      afficheValeurChamp = new JComboBox(vue.getValeursChamp(classe, type, champ));
+      afficheValeurChamp.setEditable(vue.isChampModifiable(classe, type, champ));
+      afficheValeurChamp.addActionListener(this);
+      groupe.add(afficheValeurChamp);
+      add(groupe);
+    }
+    void afficher(Element elt) {
+      this.element = elt;
+      afficheValeurChamp.removeActionListener(this);
+      String val = vue.getValeurChamp(elt, champ);
+      if (val.isEmpty()) afficheValeurChamp.setSelectedIndex(-1);
+      else afficheValeurChamp.setSelectedItem(val);
+      afficheValeurChamp.addActionListener(this);
+    }
+    public void actionPerformed(ActionEvent evt) {
+      try {
+        if (!afficheValeurChamp.isEditable()) {
+          JOptionPane.showMessageDialog(getTopLevelAncestor(), "Champ non modifiable pour ce type d'éléments",
+                  "Modification impossible", JOptionPane.ERROR_MESSAGE);
+          afficher(element);
+          return;
+        }
+        String newval = ((String) afficheValeurChamp.getSelectedItem());
+        if (newval == null) newval = "";
+        else newval = newval.trim();
+        if (!vue.setValeurChamp(element, champ, newval)) {
+          JOptionPane.showMessageDialog(getTopLevelAncestor(), "Champ non défini pour cet élément",
+                  "Saisie de valeur de champ impossible", JOptionPane.ERROR_MESSAGE);
+          afficher(element);
+        }
+      } catch (Throwable ex) {
+        GMessages.erreurFatale(ex);
+      }
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauChamps.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/Message.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/Message.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/Message.java	(revision 481)
@@ -0,0 +1,148 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.util.*;
+import visuAnalec.elements.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class Message extends EventObject {
+  public enum TypeMessage {
+    CLEAR_CORPUS,
+    NEW_CORPUS,
+    MODIF_TEXTE,
+    MODIF_ELEMENT,
+    MODIF_STRUCTURE,
+    MODIF_VUE
+  }
+
+  public enum TypeModifElement {
+    AJOUT_UNITE,
+    SUP_UNITE,
+    BORNES_UNITE,
+    AJOUT_RELATION,
+    SUP_RELATION,
+    AJOUT_SCHEMA,
+    MODIF_SCHEMA,
+    SUP_SCHEMA,
+    MODIF_VALEUR,
+  }
+
+  public enum TypeModifStructure {
+    AJOUT_TYPE_ET_ELEMENTS,
+    AJOUT_TYPE,
+    AJOUT_PROP,
+    AJOUT_FORME_UNITE,
+    AJOUT_VALEUR,
+    RENOM_TYPE,
+    RENOM_PROP,
+    RENOM_VALEUR,
+    FUSION_TYPE,
+    FUSION_PROP,
+    FUSION_VALEUR,
+    SUPPR_TYPE,
+    SUPPR_PROP,
+    SUPPR_VALEUR,
+    VALEUR_PAR_DEFAUT,
+  }
+
+  public enum TypeModifVue {
+    EXTRACTION,
+    NEW_VUE,
+    VUE_DEFAUT,
+  }
+  TypeMessage type;
+  public Message(Object source, TypeMessage type) {
+    super(source);
+    this.type = type;
+  }
+  public TypeMessage getType() {
+    return type;
+  }
+
+  public static class VueEvent extends Message {
+    private TypeModifVue modif;
+    private Unite unite;
+    private String[] args;
+    public VueEvent(Object source, TypeModifVue modif, String... args) {
+      super(source, TypeMessage.MODIF_VUE);
+      this.modif = modif;
+      this.args = args;
+    }
+    public VueEvent(Object source, TypeModifVue modif, Unite unite, String... args) {
+      super(source, TypeMessage.MODIF_VUE);
+      this.unite = unite;
+      this.modif = modif;
+      this.args = args;
+    }
+    public TypeModifVue getModif() {
+      return modif;
+    }
+    public Unite getUnite() {
+      return unite;
+    }
+    public String getArg() {
+      return args[0];
+    }
+    public String getArg(int i) {
+      return args[i];
+    }
+  }
+
+  public static class ElementEvent extends Message {
+    private TypeModifElement modif;
+    private Element element;
+    private String[] args;
+    public ElementEvent(Object source, TypeModifElement modif, Element element, String... args) {
+      super(source, TypeMessage.MODIF_ELEMENT);
+      this.modif = modif;
+      this.element = element;
+      this.args = args;
+    }
+    public TypeModifElement getModif() {
+      return modif;
+    }
+    public Element getElement() {
+      return element;
+    }
+    public String getArg() {
+      return args[0];
+    }
+    public String getArg(int i) {
+      return args[i];
+    }
+  }
+
+  public static class StructureEvent extends Message {
+    private TypeModifStructure modif;
+    private Class<? extends Element> classe;
+    private String[] args;
+    public StructureEvent(Object source, TypeModifStructure modif, Class<? extends Element> classe, String... args) {
+      super(source, TypeMessage.MODIF_STRUCTURE);
+      this.modif = modif;
+      this.classe = classe;
+      this.args = args;
+    }
+    public TypeModifStructure getModif() {
+      return modif;
+    }
+    public Class<? extends Element> getClasse() {
+      return classe;
+    }
+    public String getArg() {
+      return args[0];
+    }
+    public String getArg(int i) {
+      return args[i];
+    }
+  }
+}
+
+
+
+

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/Message.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesUnites.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesUnites.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesUnites.java	(revision 481)
@@ -0,0 +1,276 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package visuAnalec;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import visuAnalec.Message.*;
+import visuAnalec.PanneauEditeur.*;
+import visuAnalec.elements.*;
+import visuAnalec.texte.*;
+import visuAnalec.texte.PanneauAffTexte.*;
+import visuAnalec.texte.PanneauTexte.*;
+import visuAnalec.util.*;
+import visuAnalec.util.GMessages.*;
+import visuAnalec.util.GVisu.*;
+import visuAnalec.vue.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class PanneauCommandesUnites extends PanneauCommandes implements ActionListener {
+  private PanneauChamps panneauChamps;
+  public TypeComboBox saisieTypeUnites;
+  private ElementComboBox saisieUnite;
+  private JButton creeUnite;
+  private JButton supprimeUnite;
+  private JButton rectifieBorne;
+  private int[] bornesSelectTexte;
+
+  /*
+   * CREATION PAR LE PANNEAU EDITEUR
+   */
+  PanneauCommandesUnites(Vue vue, PanneauAffTexte pTexte, PanneauChamps pChamps) {
+    super(vue, pTexte);
+    JToolBar barre1 = new JToolBar("Gestion des unités");
+    barre1.setPreferredSize(new Dimension(0, 22));
+//    barre1.setBackground(PanneauTexte.getCouleurFond1());
+    barre1.setAlignmentX(0.0f);
+    add(barre1);
+    panneauChamps = pChamps;
+    saisieTypeUnites = new TypeComboBox(Unite.class);
+    saisieTypeUnites.addActionListener(this);
+    saisieUnite = new ElementComboBox();
+    saisieUnite.addActionListener(this);
+    creeUnite = new JButton(new GAction("Créer") {
+      public void executer() {
+        creerUnite();
+      }
+    });
+    supprimeUnite = new JButton(new GAction("Supprimer") {
+      public void executer() {
+        supprimerUnite();
+      }
+    });
+    rectifieBorne = new JButton(new GAction("Rectifier une borne") {
+      public void executer() {
+        modifierBorne();
+      }
+    });
+    barre1.addSeparator();
+    barre1.add(new TitreBarre("Unité : ", PanneauTexte.getCouleurFond1()));
+    barre1.addSeparator();
+    barre1.add(saisieTypeUnites);
+    barre1.add(saisieUnite);
+    barre1.addSeparator();
+    barre1.add(creeUnite);
+    barre1.addSeparator();
+    barre1.add(supprimeUnite);
+    barre1.addSeparator();
+    barre1.add(rectifieBorne);
+  }
+
+  /*
+   * COMMANDES UTILISEES PAR LE PANNEAU EDITEUR
+   */
+  public void reinitialiser() {
+    // typiquement, appelé par le panneau éditeur à la suite d'une modif de vue ou de structure
+    saisieTypeUnites.removeActionListener(this);
+    saisieTypeUnites.setModele(vue.getTypesUnitesAVoir());
+    saisieTypeUnites.effSelection();
+    saisieTypeUnites.addActionListener(this);
+    supprimeUnite.setEnabled(false);
+    rectifieBorne.setEnabled(false);
+    initSaisieUnite();
+    etatSelectRien();
+    revalidate();
+    repaint();
+  }
+  public void reafficher() {
+    // potentiellement appelé par le panneau éditeur ?
+    // appelé aussi par  traiterElementEvent
+    if (saisieUnite.pasdeSelection()) {
+      initSaisieUnite();
+      etatSelectRien();
+    } else {
+      Unite uniteCourante = (Unite) saisieUnite.getSelection();
+      initSaisieUnite(uniteCourante);
+      etatSelectUnite(uniteCourante);
+    }
+  }
+  public void elementSuivant(int sens) {
+    if (sens>0) saisieUnite.gotoSuivant();
+    else saisieUnite.gotoPrecedent();
+  }
+  public Element elementSelectionne() {
+    if (saisieUnite.pasdeSelection()) return null;
+    return saisieUnite.getSelection();
+  }
+  public void editerElement(Element elt) {
+    // appelé par le panneauEditeur : elt est forcément une unité
+    if (elt.getClass()!=Unite.class)
+      throw new UnsupportedOperationException("Erreur : classe incorrecte");
+    editerUnite((Unite) elt);
+  }
+  public ArrayList<ElementMarque> trouverElementsVises(Unite uniteVisee, TypeMarquage marqueUniteVisee,
+          boolean avecId) {
+    ArrayList<ElementMarque> eltsMarques = new ArrayList<ElementMarque>();
+    eltsMarques.add(new ElementMarque(uniteVisee, marqueUniteVisee,
+            avecId ? saisieUnite.getIdElement(uniteVisee) : null));
+    return eltsMarques;
+  }
+  public void traiterElementEvent(ElementEvent evt) {
+    // relayé par le panneau éditeur 
+    switch (evt.getModif()) {
+      case AJOUT_UNITE:
+        Unite unite = (Unite) evt.getElement();
+        editerUnite(unite);
+        return;
+      case SUP_UNITE:
+        if (evt.getElement()==saisieUnite.getSelection()) {
+          initSaisieUnite();
+          etatSelectRien();
+        } else {
+          reafficher();
+        }
+        return;
+      case BORNES_UNITE:
+        return;  // traité directement par le panneau Texte : à revoir ?
+      case AJOUT_RELATION:
+      case AJOUT_SCHEMA:
+      case SUP_RELATION:
+      case MODIF_SCHEMA:
+      case SUP_SCHEMA:
+      case MODIF_VALEUR:
+        reafficher();
+        return;
+      default:
+        throw new UnsupportedOperationException("Cas "+evt.getModif()+" oublié dans un switch");
+    }
+  }
+  void editerUnite(Unite unite) {
+    // appelé  par traiterElementEvent, 
+    // et aussi directement par le panneau éditeur quand il est sollicité par d'autres fenêtres
+    if (!unite.getType().equals(saisieTypeUnites.getTypeSelection())) {
+      saisieTypeUnites.removeActionListener(this);
+      saisieTypeUnites.setSelection(unite.getType());
+      saisieTypeUnites.addActionListener(this);
+    }
+    initSaisieUnite(unite);
+    etatSelectUnite(unite);
+  }
+  /*
+   * ACTIONS DE L'UTILISATEUR : CHANGEMENTS D'ETAT
+   */
+  public void actionPerformed(ActionEvent evt) {
+    try {
+      if (evt.getSource()==saisieTypeUnites) {
+        initSaisieUnite();
+        if (bornesSelectTexte==null) etatSelectRien();
+        else {
+          panneauTexte.getCaret().setSelectionVisible(true);
+          etatSelectTexte();
+        }
+        return;
+      }
+      if (evt.getSource()==saisieUnite) {
+        if (saisieUnite.pasdeSelection()) etatSelectRien();
+        else etatSelectUnite((Unite) saisieUnite.getSelection());
+        return;
+      }
+      throw new UnsupportedOperationException("Evénement non prévu : "+evt.paramString());
+    } catch (Throwable ex) {
+      GMessages.erreurFatale(ex);
+    }
+  }
+  @Override
+  public void traiterSourisEvent(SourisEvent evt) {
+    switch (evt.getTypeEvent()) {
+      case SELECT_RIEN:
+        saisieUnite.effSelection();
+        bornesSelectTexte = null;
+        return;
+      case SELECT_TEXTE:
+        saisieUnite.removeActionListener(this);
+        saisieUnite.effSelection();
+        saisieUnite.addActionListener(this);
+        bornesSelectTexte = evt.getBornesSelectionTexte();
+        etatSelectTexte();
+        return;
+      case SELECT_ELEMENT:
+        saisieUnite.setSelection(evt.getElementVise());
+        bornesSelectTexte = null;
+        return;
+    }
+    throw new UnsupportedOperationException("Evénement non prévu : "+evt.getTypeEvent());
+  }
+  /*
+   * ACTIONS DE L'UTILISATEUR : BOUTONS
+   */
+  private void creerUnite() {
+    if (vue.getCorpus().checkPresenceUnite(saisieTypeUnites.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1])
+            &&!GMessages.confirmationAction("Dupliquer cette unité  ?")) return;
+    vue.getCorpus().addUniteSaisie(saisieTypeUnites.getTypeSelection(), bornesSelectTexte[0], bornesSelectTexte[1]);
+  }
+  private void supprimerUnite() {
+    if (!GMessages.confirmationAction("Supprimer l'unité sélectionnée ?"))
+      return;
+    vue.getCorpus().supUnite((Unite) saisieUnite.getSelection());
+  }
+  private void modifierBorne() {
+    panneauTexte.rectifierBorneUnite((Unite) saisieUnite.getSelection());
+  }
+  /* 
+   * GESTION INTERNE
+   */
+  private void etatSelectUnite(Unite unite) {  // une unité est sélectionnée
+    panneauTexte.saisir(unite, new Unite[]{unite}, TypeMarquage.SELECT1);
+    //           (Unite[]) saisieUnite.getElements(), TypeMarquage.FOND1);
+    panneauChamps.afficher(unite);
+    creeUnite.setEnabled(false);
+    supprimeUnite.setEnabled(true);
+    rectifieBorne.setEnabled(true);
+  }
+  private void etatSelectRien() {  // rien n'est sélectionné
+    if (saisieTypeUnites.pasdeSelection()) panneauTexte.pasDeMarquage();
+    else
+      panneauTexte.saisir(null, (Unite[]) saisieUnite.getElements(), TypeMarquage.FOND1);
+    panneauChamps.effacer();
+    creeUnite.setEnabled(false);
+    supprimeUnite.setEnabled(false);
+    rectifieBorne.setEnabled(false);
+  }
+  private void etatSelectTexte() {    // du texte est sélectionné
+    panneauTexte.pasDeMarquage();
+//    if (saisieTypeUnites.pasdeSelection()) panneauTexte.pasDeMarquage();
+//    else panneauTexte.saisir(null, (Unite[]) saisieUnite.getElements(), TypeMarquage.FOND1);
+    panneauChamps.effacer();
+    if (!saisieTypeUnites.pasdeSelection()) {
+      creeUnite.setEnabled(true);
+//      Boutons.setDefaut(creeUnite, true);
+    }
+    supprimeUnite.setEnabled(false);
+    rectifieBorne.setEnabled(false);
+  }
+  private void initSaisieUnite(Unite unit) {
+    saisieUnite.removeActionListener(this);
+    if (saisieTypeUnites.pasdeSelection()) saisieUnite.setModeleVide();
+    else {
+      String type0 = saisieTypeUnites.getTypeSelection();
+      Unite[] unites = vue.getUnitesAVoir(type0);
+      saisieUnite.setModele(unites, vue.getIdUnites(type0, unites));
+    }
+    if (unit==null) saisieUnite.effSelection();
+    else saisieUnite.setSelection(unit);
+    saisieUnite.addActionListener(this);
+    saisieUnite.revalidate();
+  }
+  private void initSaisieUnite() {
+    initSaisieUnite(null);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/visuAnalec/PanneauCommandesUnites.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseAFC.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseAFC.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseAFC.java	(revision 481)
@@ -0,0 +1,82 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus;
+
+import JamaPlus.SparseSVD.SparseSVDException;
+
+/**
+ /**
+ *
+ * SparseAFC analyse factorielle des correspondances (matrices creuses)
+ * mat :  matrice binaire (0. ou 1.) profil des lignes (un individu par ligne, un caractère par colonne)
+ * CP: composantes principales,
+ * VP: valeurs d'inertie, 
+ * CG: centres de gravité des CP contenant un même caractère (non calculé dans cette version)
+ * [p,q] = size(mat); p:nb de lignes, q:nb de col
+ * 
+ * @author Bernard Victorri
+ */
+public class SparseAFC {
+  private double[][] CP;
+  private double[] VP;
+  private int p, q, n;
+
+  SparseAFC(SparseMatrix Arg) throws SparseSVDException {
+    SparseMatrix mat = Arg.copy();
+    mat.nulColumnSuppression();
+    p = mat.getRowDimension();
+    q = mat.getColumnDimension();
+    n = Math.min(Math.min(p, q), 5); 
+    // n : nombre de composantes principales espérées (pas plus de 5)
+    if (n == 0) return;
+    if (n == 1) {
+      CP = new double[p][1];
+      VP = new double[1];
+      return;
+    }
+    double f = mat.elementSum();
+    if (f == 0) return;
+    mat = mat.timesEquals(1 / f);
+    Matrix r = mat.lineSum();
+    Matrix r1 = r.arrayInverse();
+    Matrix r2 = r.arraySqrt();
+    Matrix r3 = r2.arrayInverse();
+    Matrix c = mat.columnSum();
+    Matrix c1 = c.arrayInverse();
+    Matrix c2 = c.arraySqrt();
+    Matrix c3 = c2.arrayInverse();
+    mat = mat.firstColumnTimesEqual(r3);
+    mat = mat.firstLineTimesEqual(c3);
+    SparseSVD svd = mat.svd(n);
+    Matrix cp = svd.getU();
+    Matrix vp = new Matrix(svd.getSingularValues(), 1);
+    n = vp.getColumnDimension();   
+    // peut-être moins de composantes principales effectivement calculées
+     if (n == 0) return;
+    if (n == 1) {
+      CP = new double[p][1];
+      VP = new double[1];
+      return;
+    }
+    cp = cp.getMatrix(0, p - 1, 1, n - 1);
+    cp = cp.firstColumnTimesEqual(r2);
+    vp = vp.getMatrix(0, 0, 1, n - 1);
+    cp = cp.firstLineTimesEqual(vp);
+    cp.fixColumnSigns();
+    cp = cp.firstColumnTimesEqual(r1);
+    CP = cp.getArray();
+    VP = vp.getColumnPackedCopy();
+  }
+
+  public Matrix getCP() {
+    if (CP == null) return null;
+    return new Matrix(CP, p, n - 1);
+  }
+
+  public double[] getVP() {
+    return VP;
+  }
+}
+

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseAFC.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/AFC.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/AFC.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/AFC.java	(revision 481)
@@ -0,0 +1,70 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus;
+
+/**
+ *
+ * AFC analyse factorielle des correspondances (optimisé mémoire)
+ * mat :  matrice binaire (0. ou 1.) profil des lignes (un individu par ligne, un caractère par colonne)
+ * CP: composantes principales,
+ * VP: valeurs d'inertie, 
+ * CG: centres de gravité des CP contenant un même caractère (non calculé dans cette version)
+ * [p,q] = size(mat); p:nb de lignes, q:nb de col
+ * 
+ * @author Bernard Victorri
+ */
+public class AFC {
+
+  private double[][] CP;
+  private double[] VP;
+  private int p, q, n;
+
+  AFC(Matrix Arg) {
+    Matrix mat = Arg.copy();
+    mat = mat.nulColumnSuppression();
+    p = mat.getRowDimension();
+    q = mat.getColumnDimension();
+    n = Math.min(Math.min(p, q), 5); // n : nombre de composantes principales calculées
+    if (n == 0) return;
+    if (n == 1) {
+      CP = new double[p][1];
+      VP = new double[1];
+      return;
+    }
+    double f = mat.elementSum();
+    if (f == 0) return;
+    mat = mat.timesEquals(1 / f);
+    Matrix r = mat.lineSum();
+    Matrix r1 = r.arrayInverse();
+    Matrix r2 = r.arraySqrt();
+    Matrix r3 = r2.arrayInverse();
+    Matrix c = mat.columnSum();
+    Matrix c1 = c.arrayInverse();
+    Matrix c2 = c.arraySqrt();
+    Matrix c3 = c2.arrayInverse();
+    mat = mat.firstColumnTimesEqual(r3);
+    mat = mat.firstLineTimesEqual(c3);
+    SingularValueDecomposition svd = mat.svd();
+    Matrix cp = svd.getU();
+    Matrix vp = new Matrix(svd.getSingularValues(), 1);
+    cp = cp.getMatrix(0, p - 1, 1, n - 1);
+    cp = cp.firstColumnTimesEqual(r2);
+    vp = vp.getMatrix(0, 0, 1, n - 1);
+    cp = cp.firstLineTimesEqual(vp);
+    cp.fixColumnSigns();
+    cp = cp.firstColumnTimesEqual(r1);
+    CP = cp.getArray();
+    VP = vp.getColumnPackedCopy();
+  }
+
+  public Matrix getCP() {
+    if (CP == null) return null;
+    return new Matrix(CP, p, n - 1);
+  }
+
+  public double[] getVP() {
+    return VP;
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/AFC.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseSVD.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseSVD.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseSVD.java	(revision 481)
@@ -0,0 +1,920 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus;
+
+import JamaPlus.util.*;
+import java.util.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class SparseSVD {  // based on code adapted from SVDLIBC - svdLAS2 (adapted from SVDPACKC)
+  private boolean transpose; // si transposition de la matrice en entrée
+  private int rows, cols, dim; // nb rows, nb cols, nb de val sing. désirées
+  // (après transposition éventuelle)
+  private double[][] Ut; // (d x m) transpose of left singular vectors (rows of Ut)
+  private double[][] Vt; // (d x n) transpose of right singular vectors (rows of Vt)
+  private double[] S; // d singular values
+  /* Constantes */
+  private final static int MAXLL = 2; // ??
+  private final static double[] END = {-1e-30, 1e-30};
+  private final static double EPS = Machine.eps(); // precision de la machine
+  private final static double RAD_EPS = Math.sqrt(EPS);
+  private final static double RAD34_EPS = RAD_EPS*Math.sqrt(RAD_EPS);
+  private final static double KAPPA = Math.max(RAD34_EPS, 1e-6);
+  private double EPS1;  // = precision * sqrt(nbcols)
+  /* Variables de travail : mémoire à libérer en fin de calcul */
+  private double[] alph;  // diagonale de la matrice tridiagonale T
+  private double[] bet; // éléments hors-diagonale de T
+  private double[] ritz; // valeurs propres de la  projection de A'A sur l'espace de Krylov
+  private double[] bnd; // a vérifier : initialisation (127) nécessaire ?? 
+  private double[] rj ;
+  private  double[] qj;
+  private  double[] qj1;
+  private  double[] pj ;
+  private  double[] pj1;
+  private  double[] wk;
+   private   double[] eta; 
+  private  double[] oldeta; 
+
+
+//    private static int irandom = 0;  // deboguage : à supprimer
+
+  private static class Storage {  // store Lanczos vectors q(j) 
+    private double[][] P, Q;  // P supplementary storage for j < MAXLL (j= 0 or 1)
+
+    private Storage(int nb, int maxll) {
+      P = new double[maxll][];
+      Q = new double[nb][];
+    }
+
+    private void storeP(int n, int j, double[] p) {
+      if (P[j]==null) P[j] = new double[n];
+      System.arraycopy(p, 0, P[j], 0, n);
+    }
+
+    private void storeQ(int n, int j, double[] q) {
+      if (Q[j]==null) Q[j] = new double[n];
+      System.arraycopy(q, 0, Q[j], 0, n);
+    }
+
+    private void retrieveP(int n, int j, double[] p) {
+      System.arraycopy(P[j], 0, p, 0, n);
+    }
+
+    private void retrieveQ(int n, int j, double[] q) {
+      System.arraycopy(Q[j], 0, q, 0, n);
+    }
+  }
+  private Storage storage;
+
+ public enum CodeSVDException {
+   DIM_OUT_OF_BOUNDS ("Nombre de valeurs singulières désirées invalide"),
+   FIRST_STEP_FAILURE("Impossible d'initialiser le premier pas de calcul"),
+   CONVERGENCE_FAILURE("Echec de convergence ");
+   String message;
+  CodeSVDException(String message) {
+   this.message = message;
+ }
+ }
+  public static class SparseSVDException extends Exception { // Erreurs
+    private CodeSVDException code;
+    private int k;
+
+    private SparseSVDException(CodeSVDException code, int k) {
+      super();
+      this.code = code;
+      this.k = k;
+    }
+
+    public CodeSVDException getCode() {
+      return code;
+    }
+
+    public int getK() {
+      return k;
+    }
+
+    @Override
+    public String getMessage() {
+      return super.getMessage()+"\ncode = "+getCode().message +", n = "+getK();
+    }
+  }
+
+  public SparseSVD(SparseMatrix spm, int d) throws SparseSVDException {
+    int iter = Math.min(spm.getRowDimension(), spm.getColumnDimension()); // nb d'itérations 
+    if (d<=0 || d>iter)
+      throw new SparseSVDException(CodeSVDException.DIM_OUT_OF_BOUNDS, d);
+    dim = d;
+    transpose = spm.getColumnDimension()>=spm.getRowDimension()*1.2;
+    SparseMatrix A = transpose ? spm.transpose() : spm.copy();
+    rows = A.getRowDimension();
+    cols = A.getColumnDimension();
+    EPS1 = EPS*Math.sqrt(cols);
+    alph = new double[iter];  // diagonale de la matrice tridiagonale T
+    bet = new double[iter+1]; // éléments hors-diagonale de T
+    ritz = new double[iter+1];
+    bnd = new double[iter+1]; // a vérifier : initialisation (127) nécessaire ?? 
+    storage = new Storage(iter, MAXLL);
+    // Calcul de la matrice tridiagonale 
+    int[] steps_neig_ = lanso(A, iter);
+    Ut = new double[dim][rows];
+    Vt = new double[dim][cols];
+    S = new double[dim];
+    // Calcul des  vecteurs propres
+    //  nsig  : nb de val. propres "kappa-acceptables"
+    int nsig = ritvec(A, steps_neig_);
+    if (nsig<dim) dim = nsig;  // moins de valeurs obtenues que demandées
+    // libère la mémoire
+    storage = null;
+    alph =  bet = ritz = bnd = null;
+
+  }
+
+  private int[] lanso(SparseMatrix A, int iter) throws SparseSVDException {
+    // Calcul de la matrice tridiagonale
+    int neig = 0;
+    // espace de travail
+    rj = new double[cols];
+    qj = new double[cols];
+     qj1 = new double[cols];
+     pj = new double[cols];
+     pj1 = new double[cols];
+     wk = new double[cols];
+    // step one 
+    double[] rnm_tol_ = stpone(A, cols); // initialise rmn et tol
+     eta = new double[iter]; // orthogonality estimate of Lanczos vectors
+    oldeta = new double[iter];
+    if (rnm_tol_[0]==0) {
+      ritz[0] = alph[0];
+      storage.storeQ(cols, 0, qj);
+      return new int[]{0, 1}; // steps = 0 et neig = 1
+    }
+    eta[0] = oldeta[0] = EPS1;
+    boolean[] enough_ = {false}; // flag de sortie de boucle
+    int steps = 0; // j = steps
+    int[] ll_ = {0};  // 0, 1 or 2 initial Lanczos vectors in local orthog.
+    int first = 1;
+    int last = Math.min(dim+Math.max(8, dim), iter);  // = iter dans notre version
+    int i, l;
+    int intro = 0;
+    while (!enough_[0]) {
+      steps = lanczos_step(A, first, last, 
+              ll_, enough_, rnm_tol_, cols);
+      steps = enough_[0] ? steps-1 : last-1;
+      first = steps+1;
+      bet[first] = rnm_tol_[0];
+      // analyse T
+      l = 0;
+      for (int id2 = 0; id2<steps; id2++) {
+        if (l>steps) break;
+        for (i = l; i<=steps; i++) if (bet[i+1]==0) break;
+        if (i>steps) i = steps;
+        // now i is at the end of an unreduced submatrix
+        DoubleArraysPlus.copyReverse(i-l+1, alph, l, ritz, l);
+        DoubleArraysPlus.copyReverse(i-l, bet, l+1, wk, l+1);
+        imtqlb(i-l+1, l, ritz, wk, bnd);
+        for (int id3 = l; id3<=i; id3++)
+          bnd[id3] = rnm_tol_[0]*Math.abs(bnd[id3]);
+        l = i+1;
+      }
+      // sort eigenvalues into increasing order
+      DoubleArraysPlus.sort2(ritz, bnd, steps+1, 0);
+      // massage error bounds for very close ritz values 
+      neig = error_bound(enough_, END[0], END[1], steps, rnm_tol_[1]);
+      // should we stop? 
+      if (neig<dim) {
+        if (neig==0) {
+          last = first+9;
+          intro = first;
+        } else {
+          last = first+Math.max(3, 1+((steps-intro)*(dim-neig))/neig);
+        }
+        last = Math.min(last, iter);
+      } else {
+        enough_[0] = true;
+      }
+      enough_[0] = enough_[0]||first>=iter;
+    }
+    storage.storeQ(cols, steps, qj);
+    // libère la mémoire
+     rj = qj =  qj1 = pj =  pj1 =  wk = null;
+     eta = oldeta = null;
+    return new int[]{steps, neig};
+  }
+
+  private double[] stpone(SparseMatrix A,  int n)
+          throws SparseSVDException {
+    /*  stp-one performs the first step of the Lanczos algorithm.  It also
+    does a step of extended local re-orthogonalization.
+    Arguments 
+    (input)
+    n      dimension of the eigenproblem for matrix B
+    (output)
+    wptr   array of pointers that point to work space that contains
+    wptr[0]             r[j]
+    wptr[1]             q[j]
+    wptr[2]             q[j-1]
+    wptr[3]             p
+    wptr[4]             p[j-1]
+    alph             diagonal elements of matrix T 
+    throw a SparseSVDException(-1) if the choice of initial vector (startv) failed
+     */
+    // get initial normalized vector; default is random 
+    startv0(A, n);
+    System.arraycopy(pj, 0, qj, 0, n);
+    // take the first step   
+    A.opb(pj, rj);
+    alph[0] = DoubleArraysPlus.dot(rj, pj);
+    for (int i = 0; i<n; i++) rj[i] -= alph[0]*qj[i];
+    /* extended local reorthogonalization */
+    double t = DoubleArraysPlus.dot(rj, pj);
+    for (int i = 0; i<n; i++) rj[i] -= t*qj[i];
+    alph[0] += t;
+    System.arraycopy(rj, 0, pj1, 0, n);
+    double rnm = Math.sqrt(DoubleArraysPlus.dot(pj1, pj1));
+    double tol = RAD_EPS*(rnm+Math.abs(alph[0]));
+    return new double[]{rnm, tol};
+  }
+
+//  private static double random2() {
+//    double x = 0.11*(++irandom);
+//    return x-Math.floor(x);
+//  }
+//
+private void startv0(SparseMatrix A, int n)
+          throws SparseSVDException {
+    /* startv delivers a starting normalized vector in r, 
+     * and throws a SparseSVDException(-1) if no starting vector can be found.
+    Parameters 
+    (input)
+    n      dimension of the eigenproblem matrix B
+    wptr   array of pointers that point to work space
+    step      starting index for a Lanczos run
+    (output)
+    wptr   array of pointers that point to work space that contains
+    r[j], q[j], q[j-1], p[j], p[j-1]
+     */
+// get initial vector; default is random
+    double rnm2 = 0;
+    Random random = new Random(918273);
+    for (int id = 0; id<3; id++) {
+      for (int i = 0; i<n; i++) wk[i]  = random.nextDouble(); 
+      // apply operator to put r in range (essential if m singular)
+      A.opb(wk, pj);
+      rnm2 = DoubleArraysPlus.dot(pj, pj);
+      if (rnm2>0) break;
+    }
+    // normalize
+    if (rnm2<=0) throw new SparseSVDException(CodeSVDException.FIRST_STEP_FAILURE, 0);
+    rnm2 = 1/Math.sqrt(rnm2);
+    for (int i = 0; i<n; i++) pj[i] *= rnm2;
+  }
+
+  private int lanczos_step(SparseMatrix A, int first, int last,int[] ll_,   
+          boolean[] enough_, double[] rnm_tol_, int n) throws SparseSVDException {
+    /*   embodies a single Lanczos step
+    Arguments 
+    (input)
+    n        dimension of the eigenproblem for matrix B
+    first    start of index through loop				      
+    last     end of index through loop				     
+    wptr	    array of pointers pointing to work space		    
+    alf	    array to hold diagonal of the tridiagonal matrix T
+    eta      orthogonality estimate of Lanczos vectors at step j   
+    oldeta   orthogonality estimate of Lanczos vectors at step j-1
+    bet      array to hold off-diagonal of T                     
+    ll       number of intitial Lanczos vectors in local orthog. 
+    (has value of 0, 1 or 2)			
+    enough   stop flag			
+     */
+    int j;
+    double t;
+    double mid[];
+    for (j = first; j<last; j++) {
+      mid = qj1;
+      qj1 = qj;
+      qj = mid;
+      mid = pj;
+      pj = pj1;
+      pj1 = mid;
+      storage.storeQ(n, j-1, qj1);
+      if (j-1<MAXLL) storage.storeP(n, j-1, pj1);
+      bet[j] = rnm_tol_[0];
+
+      // restart if invariant subspace is found 
+      if (bet[j]==0) {
+        rnm_tol_[0] = startv(A, j, n);
+        if (rnm_tol_[0]==0) enough_[0] = true;
+      }
+      if (enough_[0]) {
+        /* added by Doug... */
+        /* These lines fix a bug that occurs with low-rank matrices */
+        mid = qj1;
+        qj1 = qj;
+        qj = mid;
+        /* ...added by Doug */
+        break;
+      }
+      /* take a lanczos step */
+      t = 1.0/rnm_tol_[0];
+      for (int i = 0; i<n; i++) qj[i] = t*rj[i];
+      for (int i = 0; i<n; i++) pj[i] *= t;
+      A.opb(pj, rj);
+      for (int i = 0; i<n; i++) rj[i] -= rnm_tol_[0]*qj1[i];
+      alph[j] = DoubleArraysPlus.dot(rj, pj);
+      for (int i = 0; i<n; i++) rj[i] -= alph[j]*qj[i];
+      /* orthogonalize against initial lanczos vectors */
+      if (j<=MAXLL&&(Math.abs(alph[j-1])>4.0*Math.abs(alph[j])))
+        ll_[0] = j;
+      for (int i = 0; i<Math.min(ll_[0], j-1); i++) {
+        storage.retrieveP(n, i, wk);
+        t = DoubleArraysPlus.dot(wk, rj);
+        storage.retrieveQ(n, i, wk);
+        for (int ii = 0; ii<n; ii++) rj[ii] -= t*wk[ii];
+        oldeta[i] = eta[i] = EPS1;
+      }
+      /* extended local reorthogonalization */
+      t = DoubleArraysPlus.dot(rj, pj1);
+      for (int i = 0; i<n; i++) rj[i] -= t*qj1[i];
+      if (bet[j]>0) bet[j] += t;
+      t = DoubleArraysPlus.dot(rj, pj);
+      for (int i = 0; i<n; i++) rj[i] -= t*qj[i];
+      alph[j] += t;
+      System.arraycopy(rj, 0, pj1, 0, n);
+      rnm_tol_[0] = Math.sqrt(DoubleArraysPlus.dot(rj, pj1));
+      rnm_tol_[1] = RAD_EPS*(bet[j]+Math.abs(alph[j])+rnm_tol_[0]);
+      /* update the orthogonality bounds */
+      ortbnd(j, rnm_tol_[0]);
+      /* restore the orthogonality state when needed */
+      purge(n, ll_[0], j, rnm_tol_);
+      if (rnm_tol_[0]<=rnm_tol_[1]) rnm_tol_[0] = 0;
+    }
+    return j;
+  }
+
+  private double startv(SparseMatrix A, int step, int n)
+          throws SparseSVDException {
+    /* startv delivers a starting vector in r and returns |r|; it returns 
+    zero if the range is spanned, and throws a SparseSVDException(-1) if no starting 
+    vector within range of operator can be found.
+    Parameters 
+    (input)
+    n      dimension of the eigenproblem matrix B
+    wptr   array of pointers that point to work space
+    step      starting index for a Lanczos run
+    (output)
+    wptr   array of pointers that point to work space that contains
+    r[j], q[j], q[j-1], p[j], p[j-1]
+     */
+// get initial vector; default is random
+    double rnm2 = DoubleArraysPlus.dot(rj, rj);
+    Random random = new Random(918273+step);
+    for (int id = 0; id<3; id++) {
+      for (int i = 0; i<n; i++) rj[i] = random.nextDouble();
+      System.arraycopy(rj, 0, pj, 0, n);
+      // apply operator to put r in range (essential if m singular)
+      A.opb(pj, rj);
+      System.arraycopy(rj, 0, pj, 0, n);
+      rnm2 = DoubleArraysPlus.dot(rj, pj);
+      if (rnm2>0) break;
+    }
+    if (rnm2<=0) throw new SparseSVDException(CodeSVDException.FIRST_STEP_FAILURE, 0);
+    double t;
+    for (int j = 0; j<step; j++) {
+      storage.retrieveQ(n, j, wk);
+      t = -DoubleArraysPlus.dot(pj, wk);
+      for (int i = 0; i<n; i++) rj[i] += t*wk[i];
+    }
+    // make sure q[step] is orthogonal to q[step-1] 
+    t = DoubleArraysPlus.dot(pj1, rj);
+    for (int i = 0; i<n; i++) rj[i] -= t*qj1[i];
+    System.arraycopy(rj, 0, pj, 0, n);
+    t = DoubleArraysPlus.dot(pj, rj);
+    if (t<=EPS*rnm2) rnm2 = 0;
+    else rnm2 = t;
+    return Math.sqrt(rnm2);
+  }
+
+  private void ortbnd(int step, double rnm) {
+    /*  updates the eta recurrence
+    Arguments 
+    (input)
+    alf      array to hold diagonal of the tridiagonal matrix T         
+    eta      orthogonality estimate of Lanczos vectors at step j        
+    oldeta   orthogonality estimate of Lanczos vectors at step j-1     
+    bet      array to hold off-diagonal of T                          
+    n        dimension of the eigenproblem for matrix B		    
+    j        dimension of T					  
+    rnm	    norm of the next residual vector			 
+    eps1	    roundoff estimate for dot product of two unit vectors
+    (output)
+    eta      orthogonality estimate of Lanczos vectors at step j+1     
+    oldeta   orthogonality estimate of Lanczos vectors at step j        
+     */
+    if (step<1) return;
+    if (rnm!=0) {
+      if (step>1)
+        oldeta[0] = (bet[1]*eta[1]+(alph[0]-alph[step])*eta[0]
+                -bet[step]*oldeta[0])/rnm+EPS1;
+      for (int i = 1; i<=step-2; i++)
+        oldeta[i] = (bet[i+1]*eta[i+1]+(alph[i]-alph[step])*eta[i]
+                +bet[i]*eta[i-1]-bet[step]*oldeta[i])/rnm+EPS1;
+    }
+    oldeta[step-1] = EPS1;
+    double t;
+    for (int i = 0; i<step; i++) {
+      t = oldeta[i];
+      oldeta[i] = eta[i];
+      eta[i] = t;
+    }
+    eta[step] = EPS1;
+  }
+
+  private void purge(int n, int ll, int step, double[] rnm_tol_) {
+    /*
+    purge examines the state of orthogonality between the new Lanczos
+    vector and the previous ones to decide whether re-orthogonalization 
+    should be performed
+    Arguments 
+    (input)
+    n        dimension of the eigenproblem for matrix B		       
+    ll       number of intitial Lanczos vectors in local orthog.       
+    r        residual vector to become next Lanczos vector            
+    q        current Lanczos vector			           
+    ra       previous Lanczos vector
+    qa       previous Lanczos vector
+    wrk      temporary vector to hold the previous Lanczos vector
+    eta      state of orthogonality between r and prev. Lanczos vectors 
+    oldeta   state of orthogonality between q and prev. Lanczos vectors
+    j        current Lanczos step				     
+    (output)
+    r	    residual vector orthogonalized against previous Lanczos 
+    vectors
+    q        current Lanczos vector orthogonalized against previous ones    
+     */
+    if (step<ll+2) return;
+    int k = DoubleArraysPlus.indAbsMax(step-(ll+1), eta, ll);
+    if (Math.abs(eta[k])<=RAD_EPS) return;
+    double REPS1 = EPS1/RAD_EPS;
+    double t;
+    for (int iteration = 0; iteration<2; iteration++) {
+      if (rnm_tol_[0]<=rnm_tol_[1]) break;
+      /* bring in a lanczos vector t and orthogonalize both 
+       * r and q against it */
+      double tq = 0;
+      double tr = 0;
+      for (int i = ll; i<step; i++) {
+        storage.retrieveQ(n, i, wk);
+        t = -DoubleArraysPlus.dot(pj, wk);
+        tq += Math.abs(t);
+        for (int ii = 0; ii<n; ii++) qj[ii] += t*wk[ii];
+        t = -DoubleArraysPlus.dot(pj1, wk);
+        tr += Math.abs(t);
+        for (int ii = 0; ii<n; ii++) rj[ii] += t*wk[ii];
+      }
+      System.arraycopy(qj, 0, pj, 0, n);
+      t = -DoubleArraysPlus.dot(rj, pj);
+      tr += Math.abs(t);
+      for (int i = 0; i<n; i++) rj[i] += t*qj[i];
+      System.arraycopy(rj, 0, pj1, 0, n);
+      rnm_tol_[0] = Math.sqrt(DoubleArraysPlus.dot(pj1, rj));
+      if (tq<=REPS1&&tr<=REPS1*rnm_tol_[0]) break;
+    }
+    for (int i = ll; i<=step; i++) {
+      eta[i] = EPS1;
+      oldeta[i] = EPS1;
+    }
+  }
+
+  private static void imtqlb(int n, int i0, double[] d, double[] e, double[] bnd)
+          throws SparseSVDException {
+    /*   imtqlb() finds the eigenvalues of a symmetric tridiagonal
+    matrix by the implicit QL method.
+    Arguments 
+    (input)
+    n      order of the symmetric tridiagonal matrix   
+    d      contains the diagonal elements of the input matrix           
+    e      contains the subdiagonal elements of the input matrix in its
+    last n-1 positions.  e[0] is arbitrary
+    i0   starting index for the 3 vectors
+    (elements with index < i0 or >= i0+n are preserved)
+    (output)
+    d      contains the eigenvalues in ascending order.  if an error
+    exit is made, the eigenvalues are correct and ordered for
+    indices 0,1,...ierr, but may not be the smallest eigenvalues.
+    e      has been destroyed.					    
+    throws a SparseSVDException(j) if the j-th eigenvalue has
+    not been determined after 30 iterations.		    
+     */
+    if (n==1) return;
+    bnd[i0] = 1;
+    for (int i = i0+1; i<i0+n; i++) {
+      bnd[i] = 0;
+      e[i-1] = e[i];
+    }
+    e[i0+n-1] = 0;
+    for (int l = i0; l<i0+n; l++) {
+      for (int iteration = 0; iteration<=30; iteration++) {
+        double p = d[l];
+        double f = bnd[l];
+        int m;
+        for (m = l; m<i0+n-1; m++) { // test de convergence
+          double test = Math.abs(d[m])+Math.abs(d[m+1]);
+          if (test+Math.abs(e[m])==test) break;
+        }
+        if (m==l) {
+          d[l] = p;
+          bnd[l] = f;
+          /* order the eigenvalues */
+          DoubleArraysPlus.sort2(d, bnd, l-i0+1, i0);
+          break;
+        } else {
+          if (iteration==30) throw new SparseSVDException(CodeSVDException.CONVERGENCE_FAILURE, l);
+          /*........ form shift ........*/
+          double g = (d[l+1]-p)/(2.0*e[l]);
+          double r = Math.hypot(g, 1);
+          g = d[m]-p+e[l]/(g+Math.copySign(r, g));
+          double s = 1;
+          double c = 1;
+          p = 0;
+          boolean underflow = false;
+          for (int i = m-1; i>=l; i--) {
+            f = s*e[i];
+            double b = c*e[i];
+            r = Math.hypot(f, g);
+            e[i+1] = r;
+            if (r==0) {
+              /*........ recover from underflow .........*/
+              underflow = true;
+              d[i+1] -= p;
+              e[m] = 0.0;
+              break;
+            }
+            s = f/r;
+            c = g/r;
+            g = d[i+1]-p;
+            r = (d[i]-g)*s+2*c*b;
+            p = s*r;
+            d[i+1] = g+p;
+            g = c*r-b;
+            f = bnd[i+1];
+            bnd[i+1] = s*bnd[i]+c*f;
+            bnd[i] = c*bnd[i]-s*f;
+          }
+
+          if (!underflow) {
+            d[l] -= p;
+            e[l] = g;
+            e[m] = 0.0;
+          }
+        }
+      }
+    }
+  }
+
+  private int error_bound(boolean[] enough_, double endl, double endr,
+          int step, double tol) {
+    /*
+    massages error bounds for very close ritz values by placing 
+    a gap between them.  The error bounds are then refined to reflect this.
+    Arguments 
+    (input)
+    endl     left end of interval containing unwanted eigenvalues
+    endr     right end of interval containing unwanted eigenvalues
+    ritz     array to store the ritz values
+    bnd      array to store the error bounds
+    enough   stop flag
+     */
+    int mid = DoubleArraysPlus.indAbsMax(step+1, bnd, 1);
+
+    for (int i = step; i>mid; i--)
+      if (Math.abs(ritz[i-1]-ritz[i])<RAD34_EPS*Math.abs(ritz[i]))
+        if (bnd[i]>tol&&bnd[i-1]>tol) {
+          bnd[i-1] = Math.hypot(bnd[i], bnd[i-1]);
+          bnd[i] = 0;
+        }
+    for (int i = 1; i<mid; i++)
+      if (Math.abs(ritz[i+1]-ritz[i])<RAD34_EPS*Math.abs(ritz[i]))
+        if (bnd[i]>tol&&bnd[i+1]>tol) {
+          bnd[i+1] = Math.hypot(bnd[i], bnd[i+1]);
+          bnd[i] = 0.0;
+        }
+    /* refine the error bounds */
+    int neig = 0;
+    double gapl = ritz[step]-ritz[0];
+    for (int i = 0; i<=step; i++) {
+      double gap = gapl;
+      if (i<step) gapl = ritz[i+1]-ritz[i];
+      gap = Math.min(gap, gapl);
+      if (gap>bnd[i]) bnd[i] *= (bnd[i]/gap);
+      if (bnd[i]<=16.0*EPS*Math.abs(ritz[i])) {
+        neig++;
+        if (!enough_[0]) enough_[0] = endl<ritz[i]&&ritz[i]<endr;
+      }
+    }
+    return neig;
+  }
+
+  private int ritvec0(SparseMatrix A, int[] steps_neig_) throws SparseSVDException {
+
+    int js, jsq, i, k, /*size,*/ id2, tmp, nsig, x;
+    double[] s, xv2;
+    double tmp0, tmp1, xnorm;
+    double[] w1 = Vt[0];
+    double[] w2 = new double[cols];
+
+    js = steps_neig_[0]+1;
+    jsq = js*js;
+    /*size = sizeof(double) * n;*/
+
+    s = new double[jsq];
+    xv2 = new double[cols];
+
+    /* initialize s to an identity matrix */
+    for (i = 0; i<jsq; i += (js+1)) s[i] = 1.0;
+    DoubleArraysPlus.copyReverse(js, alph, 0, w1, 0);
+    DoubleArraysPlus.copyReverse(steps_neig_[0], bet, 1, w2, 1);
+
+    /* on return from imtql2(), w1 contains eigenvalues in ascending 
+     * order and s contains the corresponding eigenvectors */
+    double[][] z = new double[js][js];
+    for (int r = 0; r<js; r++) for (int c = 0; c<js; c++) z[r][c] = s[r*js+c];
+    imtql2(js, js, w1, w2, z);
+    for (int r = 0; r<js; r++) for (int c = 0; c<js; c++) s[r*js+c] = z[r][c];
+
+
+    /*fwrite((char *)&n, sizeof(n), 1, fp_out2);
+    fwrite((char *)&js, sizeof(js), 1, fp_out2);
+    fwrite((char *)&kappa, sizeof(kappa), 1, fp_out2);*/
+    /*id = 0;*/
+    nsig = 0;
+    x = 0;
+    id2 = jsq-js;
+    for (k = 0; k<js; k++) {
+      tmp = id2;
+      if (bnd[k]<=KAPPA*Math.abs(ritz[k])&&k>js-steps_neig_[1]-1) {
+        if (--x<0) x = dim-1;
+        w1 = Vt[x];
+        for (i = 0; i<cols; i++) w1[i] = 0.0;
+        for (i = 0; i<js; i++) {
+          storage.retrieveQ(cols, i, w2);
+          for (int ii = 0; ii<cols; ii++) w1[ii] += s[tmp]*w2[ii];
+          tmp -= js;
+        }
+        /*fwrite((char *)w1, size, 1, fp_out2);*/
+
+        /* store the w1 vector row-wise in array xv1;   
+         * size of xv1 is (steps+1) * (nrow+ncol) elements 
+         * and each vector, even though only ncol long,
+         * will have (nrow+ncol) elements in xv1.      
+         * It is as if xv1 is a 2-d array (steps+1) by     
+         * (nrow+ncol) and each vector occupies a row  */
+
+        /* j is the index in the R arrays, which are sorted by high to low 
+        singular values. */
+
+        /*for (i = 0; i < n; i++) R->Vt->value[x]xv1[id++] = w1[i];*/
+        /*id += nrow;*/
+        nsig++;
+      }
+      id2++;
+    }
+    s = null;
+
+    /* Rotate the singular vectors and values. */
+    /* x is now the location of the highest singular value. */
+    DoubleArraysPlus.rotateArray(Vt, x);
+    dim = Math.min(dim, nsig);
+    for (x = 0; x<dim; x++) {
+      /* multiply by matrix B first */
+      A.opb(Vt[x], xv2);
+      tmp0 = DoubleArraysPlus.dot(Vt[x], xv2);
+      for (int ii = 0; ii<cols; ii++) xv2[ii] -= tmp0*Vt[x][ii];
+      tmp0 = Math.sqrt(tmp0);
+      xnorm = Math.sqrt(DoubleArraysPlus.dot(xv2, xv2));
+
+      /* multiply by matrix A to get (scaled) left s-vector */
+      A.opa(Vt[x], Ut[x]);
+      tmp1 = 1.0/tmp0;
+      for (int ii = 0; ii<rows; ii++) Ut[x][ii] *= tmp1;
+      xnorm *= tmp1;
+      bnd[i] = xnorm;
+      S[x] = tmp0;
+    }
+
+    xv2 = w2 = null;
+    return nsig;
+    /* multiply by matrix A to get (scaled) left s-vector */
+
+  }
+
+  private int ritvec(SparseMatrix A, int[] steps_neig_) throws SparseSVDException {
+    //  computes the singular vectors of matrix A	       *
+/*  Parameters
+    (input)
+    nrow       number of rows of A
+    steps      number of Lanczos iterations performed
+    fp_out2    pointer to unformatted output file
+    n	      dimension of matrix A
+    kappa      relative accuracy of ritz values acceptable as 
+    eigenvalues of A'A
+    ritz       array of ritz values
+    bnd        array of error bounds
+    alf        array of diagonal elements of the tridiagonal matrix T
+    bet        array of off-diagonal elements of T
+    w1, w2     work space
+    (output)
+    xv1        array of eigenvectors of A'A (right singular vectors of A)
+    ierr	      error code
+    0 for normal return from imtql2()
+    k if convergence did not occur for k-th eigenvalue in
+    imtql2()
+    nsig       number of accepted ritz values based on kappa
+    (local)
+    s	      work array which is initialized to the identity matrix
+    of order (j + 1) upon calling imtql2().  After the call,
+    s contains the orthonormal eigenvectors of the symmetric 
+    tridiagonal matrix T
+     */
+    // int n = cols;
+
+    double[] w1 = Vt[0];
+    double[] w2 = new double[cols];
+    int js = steps_neig_[0]+1;
+    double[][] s = new double[js][js];
+    double[] xv2 = new double[cols];
+    /* initialize s to an identity matrix */
+    for (int i = 0; i<js; i++) s[i][i] = 1;
+    DoubleArraysPlus.copyReverse(js, alph, 0, w1, 0);
+    DoubleArraysPlus.copyReverse(steps_neig_[0], bet, 1, w2, 1);
+    /* on return from imtql2(), w1 contains eigenvalues in ascending 
+     * order and s contains the corresponding eigenvectors */
+    imtql2(js, js, w1, w2, s);
+    int nsig = 0;
+    int x = 0;
+    for (int k = 0; k<js; k++) {
+      if (bnd[k]<=KAPPA*Math.abs(ritz[k])&&k>js-steps_neig_[1]-1) {
+        if (--x<0) x = dim-1;
+        w1 = Vt[x];
+        for (int i = 0; i<cols; i++) w1[i] = 0;
+        for (int i = 0; i<js; i++) {
+          storage.retrieveQ(cols, i, w2);
+          for (int ii = 0; ii<cols; ii++) w1[ii] += s[k][js-1-i]*w2[ii];
+        }
+        /*fwrite((char *)w1, size, 1, fp_out2);*/
+
+        /* store the w1 vector row-wise in array xv1;   
+         * size of xv1 is (steps+1) * (nrow+ncol) elements 
+         * and each vector, even though only ncol long,
+         * will have (nrow+ncol) elements in xv1.      
+         * It is as if xv1 is a 2-d array (steps+1) by     
+         * (nrow+ncol) and each vector occupies a row  */
+
+        /* j is the index in the R arrays, which are sorted by high to low 
+        singular values. */
+
+        /*for (i = 0; i < n; i++) R->Vt->value[x]xv1[id++] = w1[i];*/
+        /*id += nrow;*/
+        nsig++;
+      }
+    }
+    s = null;  // libère la mémoire
+  /* Rotate the singular vectors and values. */
+    /* x is now the location of the highest singular value. */
+    DoubleArraysPlus.rotateArray(Vt, x);
+    int d = Math.min(dim, nsig);
+    for (x = 0; x<d; x++) {
+      /* multiply by matrix B first */
+      A.opb(Vt[x], xv2);
+      double tmp0 = DoubleArraysPlus.dot(Vt[x], xv2);
+      for (int i = 0; i<cols; i++) xv2[i] -= tmp0*Vt[x][i];
+      tmp0 = Math.sqrt(tmp0);
+      double xnorm = Math.sqrt(DoubleArraysPlus.dot(xv2, xv2));
+      /* multiply by matrix A to get (scaled) left s-vector */
+      A.opa(Vt[x], Ut[x]);
+      double tmp1 = 1/tmp0;
+      for (int i = 0; i<rows; i++) Ut[x][i] *= tmp1;
+      xnorm *= tmp1;
+      //   bnd[i] = xnorm; bizarre ??
+      S[x] = tmp0;
+    }
+    xv2 = w2 = null;
+    return nsig;
+  }
+
+  private static void imtql2(int nm, int n, double d[], double[] e, double[][] z)
+          throws SparseSVDException {
+    /*   imtqlb() finds the eigenvalues  and eigenvectors of a symmetric tridiagonal
+    matrix by the implicit QL method.
+    Arguments 
+    (input)
+    nm     row dimension of the symmetric tridiagonal matrix   
+    n      order of the symmetric tridiagonal matrix   
+    d      contains the diagonal elements of the input matrix           
+    e      contains the subdiagonal elements of the input matrix in its
+    last n-1 positions.  e[0] is arbitrary
+    z      contains the identity matrix
+    (output)
+    d      contains the eigenvalues in ascending order.  if an error
+    exit is made, the eigenvalues are correct but unordered for
+    indices 0,1,...ierr.
+    e      has been destroyed.					    
+    z      contains orthonormal eigenvectors of the symmetric   
+    tridiagonal (or full) matrix.  if an error exit is made,
+    z contains the eigenvectors associated with the stored 
+    eigenvalues.					
+    throws a SparseSVDException(j) if the j-th eigenvalue has
+    not been determined after 30 iterations.		    
+     */
+    if (n==1) return;
+    for (int i = 1; i<n; i++) e[i-1] = e[i];
+    e[n-1] = 0.0;
+    int nnm = n*nm;
+    for (int l = 0; l<n; l++) {
+      /* look for small sub-diagonal element */
+      for (int iteration = 0; iteration<=30; iteration++) {
+        double p = d[l];
+        int m;
+        for (m = l; m<n-1; m++) {// test de convergence
+          double test = Math.abs(d[m])+Math.abs(d[m+1]);
+          if (test+Math.abs(e[m])==test) break;
+        }
+        if (m==l) break;
+        /* set error -- no convergence to an eigenvalue after
+         * 30 iterations. */
+        if (iteration==30) throw new SparseSVDException(CodeSVDException.CONVERGENCE_FAILURE, l);
+        /* form shift */
+        double g = (d[l+1]-p)/(2*e[l]);
+        double r = Math.hypot(g, 1);
+        g = d[m]-p+e[l]/(g+Math.copySign(r, g));
+        double s = 1;
+        double c = 1;
+        p = 0;
+        boolean underflow = false;
+        for (int i = m-1; i>=l; i--) {
+          double f = s*e[i];
+          double b = c*e[i];
+          r = Math.hypot(f, g);
+          e[i+1] = r;
+          if (r==0) {
+            /*........ recover from underflow .........*/
+            underflow = true;
+            d[i+1] -= p;
+            e[m] = 0.0;
+            break;
+          }
+          s = f/r;
+          c = g/r;
+          g = d[i+1]-p;
+          r = (d[i]-g)*s+2*c*b;
+          p = s*r;
+          d[i+1] = g+p;
+          g = c*r-b;
+          /* form vector */
+          for (int k = 0; k<nm; k++) {
+            f = z[i+1][k];
+            z[i+1][k] = s*z[i][k]+c*f;
+            z[i][k] = c*z[i][k]-s*f;
+          }
+        }
+        if (!underflow) {
+          d[l] -= p;
+          e[l] = g;
+          e[m] = 0.0;
+        }
+      }
+    }
+    /* order the eigenvalues and corresponding eigenvectors */
+    DoubleArraysPlus.sort2(d, z, n, 0);
+  }
+
+  /* ------------------------
+  Public Methods
+   * ------------------------ */
+  /** Return the left singular vectors
+  @return     U
+   */
+  public Matrix getU() {
+    return transpose ? (new Matrix(Vt, dim, cols)).transpose()
+            : (new Matrix(Ut, dim, rows)).transpose();
+  }
+
+  /** Return the right singular vectors
+  @return     V
+   */
+  public Matrix getV() {
+    return transpose ? (new Matrix(Ut, dim, rows)).transpose()
+            : (new Matrix(Vt, dim, cols)).transpose();
+  }
+
+  /** Return the one-dimensional array of singular values
+  @return     diagonal of S.
+   */
+  public double[] getSingularValues() {
+    return Arrays.copyOfRange(S, 0, dim);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseSVD.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/LUDecomposition.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/LUDecomposition.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/LUDecomposition.java	(revision 481)
@@ -0,0 +1,311 @@
+package JamaPlus;
+
+   /** LU Decomposition.
+   <P>
+   For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
+   unit lower triangular matrix L, an n-by-n upper triangular matrix U,
+   and a permutation vector piv of length m so that A(piv,:) = L*U.
+   If m < n, then L is m-by-m and U is m-by-n.
+   <P>
+   The LU decompostion with pivoting always exists, even if the matrix is
+   singular, so the constructor will never fail.  The primary use of the
+   LU decomposition is in the solution of square systems of simultaneous
+   linear equations.  This will fail if isNonsingular() returns false.
+   */
+
+public class LUDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Array for internal storage of decomposition.
+   @serial internal array storage.
+   */
+   private double[][] LU;
+
+   /** Row and column dimensions, and pivot sign.
+   @serial column dimension.
+   @serial row dimension.
+   @serial pivot sign.
+   */
+   private int m, n, pivsign; 
+
+   /** Internal storage of pivot vector.
+   @serial pivot vector.
+   */
+   private int[] piv;
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** LU Decomposition
+   @param  A   Rectangular matrix
+   @return     Structure to access L, U and piv.
+   */
+
+   public LUDecomposition (Matrix A) {
+
+   // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
+
+      LU = A.getArrayCopy();
+      m = A.getRowDimension();
+      n = A.getColumnDimension();
+      piv = new int[m];
+      for (int i = 0; i < m; i++) {
+         piv[i] = i;
+      }
+      pivsign = 1;
+      double[] LUrowi;
+      double[] LUcolj = new double[m];
+
+      // Outer loop.
+
+      for (int j = 0; j < n; j++) {
+
+         // Make a copy of the j-th column to localize references.
+
+         for (int i = 0; i < m; i++) {
+            LUcolj[i] = LU[i][j];
+         }
+
+         // Apply previous transformations.
+
+         for (int i = 0; i < m; i++) {
+            LUrowi = LU[i];
+
+            // Most of the time is spent in the following dot product.
+
+            int kmax = Math.min(i,j);
+            double s = 0.0;
+            for (int k = 0; k < kmax; k++) {
+               s += LUrowi[k]*LUcolj[k];
+            }
+
+            LUrowi[j] = LUcolj[i] -= s;
+         }
+   
+         // Find pivot and exchange if necessary.
+
+         int p = j;
+         for (int i = j+1; i < m; i++) {
+            if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) {
+               p = i;
+            }
+         }
+         if (p != j) {
+            for (int k = 0; k < n; k++) {
+               double t = LU[p][k]; LU[p][k] = LU[j][k]; LU[j][k] = t;
+            }
+            int k = piv[p]; piv[p] = piv[j]; piv[j] = k;
+            pivsign = -pivsign;
+         }
+
+         // Compute multipliers.
+         
+         if (j < m & LU[j][j] != 0.0) {
+            for (int i = j+1; i < m; i++) {
+               LU[i][j] /= LU[j][j];
+            }
+         }
+      }
+   }
+
+/* ------------------------
+   Temporary, experimental code.
+   ------------------------ *\
+
+   \** LU Decomposition, computed by Gaussian elimination.
+   <P>
+   This constructor computes L and U with the "daxpy"-based elimination
+   algorithm used in LINPACK and MATLAB.  In Java, we suspect the dot-product,
+   Crout algorithm will be faster.  We have temporarily included this
+   constructor until timing experiments confirm this suspicion.
+   <P>
+   @param  A             Rectangular matrix
+   @param  linpackflag   Use Gaussian elimination.  Actual value ignored.
+   @return               Structure to access L, U and piv.
+   *\
+
+   public LUDecomposition (Matrix A, int linpackflag) {
+      // Initialize.
+      LU = A.getArrayCopy();
+      m = A.getRowDimension();
+      n = A.getColumnDimension();
+      piv = new int[m];
+      for (int i = 0; i < m; i++) {
+         piv[i] = i;
+      }
+      pivsign = 1;
+      // Main loop.
+      for (int k = 0; k < n; k++) {
+         // Find pivot.
+         int p = k;
+         for (int i = k+1; i < m; i++) {
+            if (Math.abs(LU[i][k]) > Math.abs(LU[p][k])) {
+               p = i;
+            }
+         }
+         // Exchange if necessary.
+         if (p != k) {
+            for (int j = 0; j < n; j++) {
+               double t = LU[p][j]; LU[p][j] = LU[k][j]; LU[k][j] = t;
+            }
+            int t = piv[p]; piv[p] = piv[k]; piv[k] = t;
+            pivsign = -pivsign;
+         }
+         // Compute multipliers and eliminate k-th column.
+         if (LU[k][k] != 0.0) {
+            for (int i = k+1; i < m; i++) {
+               LU[i][k] /= LU[k][k];
+               for (int j = k+1; j < n; j++) {
+                  LU[i][j] -= LU[i][k]*LU[k][j];
+               }
+            }
+         }
+      }
+   }
+
+\* ------------------------
+   End of temporary code.
+ * ------------------------ */
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Is the matrix nonsingular?
+   @return     true if U, and hence A, is nonsingular.
+   */
+
+   public boolean isNonsingular () {
+      for (int j = 0; j < n; j++) {
+         if (LU[j][j] == 0)
+            return false;
+      }
+      return true;
+   }
+
+   /** Return lower triangular factor
+   @return     L
+   */
+
+   public Matrix getL () {
+      Matrix X = new Matrix(m,n);
+      double[][] L = X.getArray();
+      for (int i = 0; i < m; i++) {
+         for (int j = 0; j < n; j++) {
+            if (i > j) {
+               L[i][j] = LU[i][j];
+            } else if (i == j) {
+               L[i][j] = 1.0;
+            } else {
+               L[i][j] = 0.0;
+            }
+         }
+      }
+      return X;
+   }
+
+   /** Return upper triangular factor
+   @return     U
+   */
+
+   public Matrix getU () {
+      Matrix X = new Matrix(n,n);
+      double[][] U = X.getArray();
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            if (i <= j) {
+               U[i][j] = LU[i][j];
+            } else {
+               U[i][j] = 0.0;
+            }
+         }
+      }
+      return X;
+   }
+
+   /** Return pivot permutation vector
+   @return     piv
+   */
+
+   public int[] getPivot () {
+      int[] p = new int[m];
+      for (int i = 0; i < m; i++) {
+         p[i] = piv[i];
+      }
+      return p;
+   }
+
+   /** Return pivot permutation vector as a one-dimensional double array
+   @return     (double) piv
+   */
+
+   public double[] getDoublePivot () {
+      double[] vals = new double[m];
+      for (int i = 0; i < m; i++) {
+         vals[i] = (double) piv[i];
+      }
+      return vals;
+   }
+
+   /** Determinant
+   @return     det(A)
+   @exception  IllegalArgumentException  Matrix must be square
+   */
+
+   public double det () {
+      if (m != n) {
+         throw new IllegalArgumentException("Matrix must be square.");
+      }
+      double d = (double) pivsign;
+      for (int j = 0; j < n; j++) {
+         d *= LU[j][j];
+      }
+      return d;
+   }
+
+   /** Solve A*X = B
+   @param  B   A Matrix with as many rows as A and any number of columns.
+   @return     X so that L*U*X = B(piv,:)
+   @exception  IllegalArgumentException Matrix row dimensions must agree.
+   @exception  RuntimeException  Matrix is singular.
+   */
+
+   public Matrix solve (Matrix B) {
+      if (B.getRowDimension() != m) {
+         throw new IllegalArgumentException("Matrix row dimensions must agree.");
+      }
+      if (!this.isNonsingular()) {
+         throw new RuntimeException("Matrix is singular.");
+      }
+
+      // Copy right hand side with pivoting
+      int nx = B.getColumnDimension();
+      Matrix Xmat = B.getMatrix(piv,0,nx-1);
+      double[][] X = Xmat.getArray();
+
+      // Solve L*Y = B(piv,:)
+      for (int k = 0; k < n; k++) {
+         for (int i = k+1; i < n; i++) {
+            for (int j = 0; j < nx; j++) {
+               X[i][j] -= X[k][j]*LU[i][k];
+            }
+         }
+      }
+      // Solve U*X = Y;
+      for (int k = n-1; k >= 0; k--) {
+         for (int j = 0; j < nx; j++) {
+            X[k][j] /= LU[k][k];
+         }
+         for (int i = 0; i < k; i++) {
+            for (int j = 0; j < nx; j++) {
+               X[i][j] -= X[k][j]*LU[i][k];
+            }
+         }
+      }
+      return Xmat;
+   }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/LUDecomposition.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/util/DoubleArraysPlus.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/util/DoubleArraysPlus.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/util/DoubleArraysPlus.java	(revision 481)
@@ -0,0 +1,97 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus.util;
+
+import java.util.*;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class DoubleArraysPlus {
+  public static void copyReverse(int length, double[] src, int srcStart,
+          double[] dest, int destStart) {
+    destStart += length-1;
+    for (int i = 0; i<length; i++) dest[destStart-i] = src[srcStart+i];
+  }
+
+   private static class Couple implements Comparable<Couple> {
+    double x1;
+    Object x2;
+
+    public int compareTo(Couple c) {
+      return Double.compare(x1, c.x1);
+    }
+  }
+
+  public static void sort2(double[] a1, double[] a2, int n, int istart) {
+    // sort the first n elements of a1 and a2, starting at index istart,
+    // in increasing order for a1 
+    // (elements with indexes < istart or > istart + n preserved) 
+    Couple[] cs = new Couple[n];
+    for (int i = 0; i<n; i++) {
+      cs[i] = new Couple();
+      cs[i].x1 = a1[i+istart];
+      cs[i].x2 = a2[i+istart];
+    }
+    Arrays.sort(cs);
+    for (int i = 0; i<n; i++) {
+      a1[i+istart] = cs[i].x1;
+      a2[i+istart] = (Double) cs[i].x2;
+    }
+  }
+ public static void sort2(double[] a1, double[][] a2, int n, int istart) {
+    // sort the first n elements of a1 and a2[] (lines of array a2)
+//    starting at index istart, in increasing order for a1
+    // (elements with index < istart or > istart + n preserved) 
+    Couple[] cs = new Couple[n];
+    for (int i = 0; i<n; i++) {
+      cs[i] = new Couple();
+      cs[i].x1 = a1[i+istart];
+      cs[i].x2 = a2[i+istart];
+    }
+    Arrays.sort(cs);
+    for (int i = 0; i<n; i++) {
+      a1[i+istart] = cs[i].x1;
+      a2[i+istart] = (double[]) cs[i].x2;
+    }
+  }
+
+  public static int indAbsMax(int n, double x[], int istart) {
+    // finds the index of element having maximum absolute value 
+    // among the first n elements of x starting at index istart
+    if (n<1||istart<0||istart+n>x.length)
+      throw new ArrayIndexOutOfBoundsException();
+    if (n==1) return (istart);
+    double max = Math.abs(x[istart]);
+    int imax = istart;
+    for (int i = istart+1; i<istart+n; i++) {
+      double ax = Math.abs(x[i]);
+      if (ax>max) {
+        max = ax;
+        imax = i;
+      }
+    }
+    return imax;
+  }
+
+  public static double dot(double[] x, double[] y) {
+    // dot product of vectors x and y
+    int n = x.length;
+    if (n!=y.length) throw new IllegalArgumentException();
+    double res = 0;
+    for (int i = 0; i<n; i++) res += x[i]*y[i];
+    return res;
+  }
+  public static void rotateArray(double[][] a, int x) {
+    // permutation circulaire des lignes de la matrice a
+    // plaçant la ligne x en tête
+  double[][] b =new double[a.length-x][];
+ System.arraycopy(a, x, b, 0, b.length);
+ System.arraycopy(a, 0, a, b.length, a.length-b.length);
+ System.arraycopy(b, 0, a, 0, b.length);
+     }
+
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/util/DoubleArraysPlus.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/util/Machine.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/util/Machine.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/util/Machine.java	(revision 481)
@@ -0,0 +1,143 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus.util;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class Machine {
+
+    /***********************************************************************
+     *                                                                     *
+     *				machar()			       *
+     *                                                                     *
+     ***********************************************************************/
+    /***********************************************************************
+    
+    Description
+    -----------
+    
+    This function is a partial translation of a Fortran-77 subroutine 
+    written by W. J. Cody of Argonne National Laboratory.
+    It dynamically determines the listed machine parameters of the
+    floating-point arithmetic.  According to the documentation of
+    the Fortran code, "the determination of the first three uses an
+    extension of an algorithm due to M. Malcolm, ACM 15 (1972), 
+    pp. 949-951, incorporating some, but not all, of the improvements
+    suggested by M. Gentleman and S. Marovich, CACM 17 (1974), 
+    pp. 276-277."  The complete Fortran version of this translation is
+    documented in W. J. Cody, "Machar: a Subroutine to Dynamically 
+    Determine Determine Machine Parameters," TOMS 14, December, 1988.
+    
+    
+    Parameters reported 
+    -------------------
+    
+    ibeta     the radix for the floating-point representation       
+    it        the number of base ibeta digits in the floating-point
+    significand					 
+    irnd      0 if floating-point addition chops		      
+    1 if floating-point addition rounds, but not in the 
+    ieee style					
+    2 if floating-point addition rounds in the ieee style
+    3 if floating-point addition chops, and there is    
+    partial underflow				
+    4 if floating-point addition rounds, but not in the
+    ieee style, and there is partial underflow    
+    5 if floating-point addition rounds in the ieee style,
+    and there is partial underflow                   
+    machep    the largest negative integer such that              
+    1.0+float(ibeta)**machep .ne. 1.0, except that 
+    machep is bounded below by  -(it+3)          
+    negeps    the largest negative integer such that          
+    1.0-float(ibeta)**negeps .ne. 1.0, except that 
+    negeps is bounded below by  -(it+3)	       
+    
+     ***********************************************************************/
+    public static double eps(/*int res[]*/) {
+        int ibeta, it, irnd, machep, negep;
+        double beta, betain, betah, a, b = 0, ZERO, ONE, TWO, temp, tempa, temp1;
+        int i, itemp;
+
+        ONE = (double) 1;
+        TWO = ONE + ONE;
+        ZERO = ONE - ONE;
+
+        a = ONE;
+        temp1 = ONE;
+        while (temp1 - ONE == ZERO) {
+            a += a;
+            temp = a + ONE;
+            temp1 = temp - a;
+            b += a; /* to prevent icc compiler error */
+        }
+        b = ONE;
+        itemp = 0;
+        while (itemp == 0) {
+            b += b;
+            temp = a + b;
+            itemp = (int) (temp - a);
+        }
+        ibeta = itemp;
+        beta = (double) ibeta;
+
+        it = 0;
+        b = ONE;
+        temp1 = ONE;
+        while (temp1 - ONE == ZERO) {
+            it++;
+            b *= beta;
+            temp = b + ONE;
+            temp1 = temp - b;
+        }
+        irnd = 0;
+        betah = beta / TWO;
+        temp = a + betah;
+        if (temp - a != ZERO) irnd = 1;
+        tempa = a + beta;
+        temp = tempa + betah;
+        if ((irnd == 0) && (temp - tempa != ZERO)) irnd = 2;
+
+        negep = it + 3;
+        betain = ONE / beta;
+        a = ONE;
+        for (i = 0; i < negep; i++) a *= betain;
+        b = a;
+        temp = ONE - a;
+        while (temp - ONE == ZERO) {
+            a *= beta;
+            negep--;
+            temp = ONE - a;
+        }
+        negep = -(negep);
+
+        machep = -(it) - 3;
+        a = b;
+        temp = ONE + a;
+        while (temp - ONE == ZERO) {
+            a *= beta;
+            machep += 1;
+            temp = ONE + a;
+        }
+//        res[0] = ibeta;
+//        res[1] = it;
+//        res[2] = irnd;
+//        res[3] = machep;
+//        res[4] = negep;
+        return a;
+    }
+
+    static public void main(String[] args) {
+        int[] res = new int[5];
+//        double precision = eps(res);
+//        System.out.println("eps = " + precision);
+        System.out.println("ibeta = " + res[0]);
+        System.out.println("it = " + res[1]);
+        System.out.println("irnd = " + res[2]);
+        System.out.println("machep = " + res[3]);
+        System.out.println("negep = " + res[4]);
+    }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/util/Machine.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/CholeskyDecomposition.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/CholeskyDecomposition.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/CholeskyDecomposition.java	(revision 481)
@@ -0,0 +1,199 @@
+package JamaPlus;
+
+   /** Cholesky Decomposition.
+   <P>
+   For a symmetric, positive definite matrix A, the Cholesky decomposition
+   is an lower triangular matrix L so that A = L*L'.
+   <P>
+   If the matrix is not symmetric or positive definite, the constructor
+   returns a partial decomposition and sets an internal flag that may
+   be queried by the isSPD() method.
+   */
+
+public class CholeskyDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Array for internal storage of decomposition.
+   @serial internal array storage.
+   */
+   private double[][] L;
+
+   /** Row and column dimension (square matrix).
+   @serial matrix dimension.
+   */
+   private int n;
+
+   /** Symmetric and positive definite flag.
+   @serial is symmetric and positive definite flag.
+   */
+   private boolean isspd;
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** Cholesky algorithm for symmetric and positive definite matrix.
+   @param  A   Square, symmetric matrix.
+   @return     Structure to access L and isspd flag.
+   */
+
+   public CholeskyDecomposition (Matrix Arg) {
+
+
+     // Initialize.
+      double[][] A = Arg.getArray();
+      n = Arg.getRowDimension();
+      L = new double[n][n];
+      isspd = (Arg.getColumnDimension() == n);
+      // Main loop.
+      for (int j = 0; j < n; j++) {
+         double[] Lrowj = L[j];
+         double d = 0.0;
+         for (int k = 0; k < j; k++) {
+            double[] Lrowk = L[k];
+            double s = 0.0;
+            for (int i = 0; i < k; i++) {
+               s += Lrowk[i]*Lrowj[i];
+            }
+            Lrowj[k] = s = (A[j][k] - s)/L[k][k];
+            d = d + s*s;
+            isspd = isspd & (A[k][j] == A[j][k]); 
+         }
+         d = A[j][j] - d;
+         isspd = isspd & (d > 0.0);
+         L[j][j] = Math.sqrt(Math.max(d,0.0));
+         for (int k = j+1; k < n; k++) {
+            L[j][k] = 0.0;
+         }
+      }
+   }
+
+/* ------------------------
+   Temporary, experimental code.
+ * ------------------------ *\
+
+   \** Right Triangular Cholesky Decomposition.
+   <P>
+   For a symmetric, positive definite matrix A, the Right Cholesky
+   decomposition is an upper triangular matrix R so that A = R'*R.
+   This constructor computes R with the Fortran inspired column oriented
+   algorithm used in LINPACK and MATLAB.  In Java, we suspect a row oriented,
+   lower triangular decomposition is faster.  We have temporarily included
+   this constructor here until timing experiments confirm this suspicion.
+   *\
+
+   \** Array for internal storage of right triangular decomposition. **\
+   private transient double[][] R;
+
+   \** Cholesky algorithm for symmetric and positive definite matrix.
+   @param  A           Square, symmetric matrix.
+   @param  rightflag   Actual value ignored.
+   @return             Structure to access R and isspd flag.
+   *\
+
+   public CholeskyDecomposition (Matrix Arg, int rightflag) {
+      // Initialize.
+      double[][] A = Arg.getArray();
+      n = Arg.getColumnDimension();
+      R = new double[n][n];
+      isspd = (Arg.getColumnDimension() == n);
+      // Main loop.
+      for (int j = 0; j < n; j++) {
+         double d = 0.0;
+         for (int k = 0; k < j; k++) {
+            double s = A[k][j];
+            for (int i = 0; i < k; i++) {
+               s = s - R[i][k]*R[i][j];
+            }
+            R[k][j] = s = s/R[k][k];
+            d = d + s*s;
+            isspd = isspd & (A[k][j] == A[j][k]); 
+         }
+         d = A[j][j] - d;
+         isspd = isspd & (d > 0.0);
+         R[j][j] = Math.sqrt(Math.max(d,0.0));
+         for (int k = j+1; k < n; k++) {
+            R[k][j] = 0.0;
+         }
+      }
+   }
+
+   \** Return upper triangular factor.
+   @return     R
+   *\
+
+   public Matrix getR () {
+      return new Matrix(R,n,n);
+   }
+
+\* ------------------------
+   End of temporary code.
+ * ------------------------ */
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Is the matrix symmetric and positive definite?
+   @return     true if A is symmetric and positive definite.
+   */
+
+   public boolean isSPD () {
+      return isspd;
+   }
+
+   /** Return triangular factor.
+   @return     L
+   */
+
+   public Matrix getL () {
+      return new Matrix(L,n,n);
+   }
+
+   /** Solve A*X = B
+   @param  B   A Matrix with as many rows as A and any number of columns.
+   @return     X so that L*L'*X = B
+   @exception  IllegalArgumentException  Matrix row dimensions must agree.
+   @exception  RuntimeException  Matrix is not symmetric positive definite.
+   */
+
+   public Matrix solve (Matrix B) {
+      if (B.getRowDimension() != n) {
+         throw new IllegalArgumentException("Matrix row dimensions must agree.");
+      }
+      if (!isspd) {
+         throw new RuntimeException("Matrix is not symmetric positive definite.");
+      }
+
+      // Copy right hand side.
+      double[][] X = B.getArrayCopy();
+      int nx = B.getColumnDimension();
+
+	      // Solve L*Y = B;
+	      for (int k = 0; k < n; k++) {
+	        for (int j = 0; j < nx; j++) {
+	           for (int i = 0; i < k ; i++) {
+	               X[k][j] -= X[i][j]*L[k][i];
+	           }
+	           X[k][j] /= L[k][k];
+	        }
+	      }
+	
+	      // Solve L'*X = Y;
+	      for (int k = n-1; k >= 0; k--) {
+	        for (int j = 0; j < nx; j++) {
+	           for (int i = k+1; i < n ; i++) {
+	               X[k][j] -= X[i][j]*L[i][k];
+	           }
+	           X[k][j] /= L[k][k];
+	        }
+	      }
+      
+      
+      return new Matrix(X,n,nx);
+   }
+}
+

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/CholeskyDecomposition.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/SingularValueDecomposition.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/SingularValueDecomposition.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/SingularValueDecomposition.java	(revision 481)
@@ -0,0 +1,556 @@
+package JamaPlus;
+import JamaPlus.util.*;
+
+   /** Singular Value Decomposition.
+   <P>
+   For an m-by-n matrix A with m >= n, the singular value decomposition is
+   an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and
+   an n-by-n orthogonal matrix V so that A = U*S*V'.
+   <P>
+   The singular values, sigma[k] = S[k][k], are ordered so that
+   sigma[0] >= sigma[1] >= ... >= sigma[n-1].
+   <P>
+   The singular value decompostion always exists, so the constructor will
+   never fail.  The matrix condition number and the effective numerical
+   rank can be computed from this decomposition.
+   */
+
+public class SingularValueDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Arrays for internal storage of U and V.
+   @serial internal storage of U.
+   @serial internal storage of V.
+   */
+   private double[][] U, V;
+
+   /** Array for internal storage of singular values.
+   @serial internal storage of singular values.
+   */
+   private double[] s;
+
+   /** Row and column dimensions.
+   @serial row dimension.
+   @serial column dimension.
+   */
+   private int m, n;
+   
+   private boolean transpose; // pour éviter les bugs quand m<n (cf.ci-dessous) 
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** Construct the singular value decomposition
+   @param A    Rectangular matrix
+   @return     Structure to access U, S and V.
+   */
+
+   public SingularValueDecomposition (Matrix Arg) {
+
+      // Derived from LINPACK code.
+      // Initialize.
+      /* Apparently the failing cases are only a proper subset of (m<n), 
+	 so let's not throw error.  Correct fix to come later?
+      if (m<n) {
+	  throw new IllegalArgumentException("Jama SVD only works for m >= n"); }
+      */
+      /* 
+       * Une façon très simple de contourner le problème ci-dessus :
+       * si m < n on transpose A
+       * (ce qui revient à échanger U et V, S restant inchangé)
+       */
+   transpose = Arg.getColumnDimension()>Arg.getRowDimension();
+    Matrix M = transpose ? Arg.transpose() : Arg.copy();
+  
+     double[][] A = M.getArray();
+      m = M.getRowDimension();
+      n = M.getColumnDimension();
+
+      s = new double [n];
+      U = new double [m][n];
+      V = new double [n][n];
+      double[] e = new double [n];
+      double[] work = new double [m];
+      boolean wantu = true;
+      boolean wantv = true;
+
+      // Reduce A to bidiagonal form, storing the diagonal elements
+      // in s and the super-diagonal elements in e.
+
+      int nct = Math.min(m-1,n);
+      int nrt = Math.max(0,Math.min(n-2,m));
+      for (int k = 0; k < Math.max(nct,nrt); k++) {
+         if (k < nct) {
+
+            // Compute the transformation for the k-th column and
+            // place the k-th diagonal in s[k].
+            // Compute 2-norm of k-th column without under/overflow.
+            s[k] = 0;
+            for (int i = k; i < m; i++) {
+               s[k] = Math.hypot(s[k],A[i][k]);
+            }
+            if (s[k] != 0.0) {
+               if (A[k][k] < 0.0) {
+                  s[k] = -s[k];
+               }
+               for (int i = k; i < m; i++) {
+                  A[i][k] /= s[k];
+               }
+               A[k][k] += 1.0;
+            }
+            s[k] = -s[k];
+         }
+         for (int j = k+1; j < n; j++) {
+            if ((k < nct) & (s[k] != 0.0))  {
+
+            // Apply the transformation.
+
+               double t = 0;
+               for (int i = k; i < m; i++) {
+                  t += A[i][k]*A[i][j];
+               }
+               t = -t/A[k][k];
+               for (int i = k; i < m; i++) {
+                  A[i][j] += t*A[i][k];
+               }
+            }
+
+            // Place the k-th row of A into e for the
+            // subsequent calculation of the row transformation.
+
+            e[j] = A[k][j];
+         }
+         if (wantu & (k < nct)) {
+
+            // Place the transformation in U for subsequent back
+            // multiplication.
+
+            for (int i = k; i < m; i++) {
+               U[i][k] = A[i][k];
+            }
+         }
+         if (k < nrt) {
+
+            // Compute the k-th row transformation and place the
+            // k-th super-diagonal in e[k].
+            // Compute 2-norm without under/overflow.
+            e[k] = 0;
+            for (int i = k+1; i < n; i++) {
+               e[k] = Math.hypot(e[k],e[i]);
+            }
+            if (e[k] != 0.0) {
+               if (e[k+1] < 0.0) {
+                  e[k] = -e[k];
+               }
+               for (int i = k+1; i < n; i++) {
+                  e[i] /= e[k];
+               }
+               e[k+1] += 1.0;
+            }
+            e[k] = -e[k];
+            if ((k+1 < m) & (e[k] != 0.0)) {
+
+            // Apply the transformation.
+
+               for (int i = k+1; i < m; i++) {
+                  work[i] = 0.0;
+               }
+               for (int j = k+1; j < n; j++) {
+                  for (int i = k+1; i < m; i++) {
+                     work[i] += e[j]*A[i][j];
+                  }
+               }
+               for (int j = k+1; j < n; j++) {
+                  double t = -e[j]/e[k+1];
+                  for (int i = k+1; i < m; i++) {
+                     A[i][j] += t*work[i];
+                  }
+               }
+            }
+            if (wantv) {
+
+            // Place the transformation in V for subsequent
+            // back multiplication.
+
+               for (int i = k+1; i < n; i++) {
+                  V[i][k] = e[i];
+               }
+            }
+         }
+      }
+
+      // Set up the final bidiagonal matrix or order p.
+
+      int p = Math.min(n,m+1);
+      if (nct < n) {
+         s[nct] = A[nct][nct];
+      }
+      if (m < p) {
+         s[p-1] = 0.0;
+      }
+      if (nrt+1 < p) {
+         e[nrt] = A[nrt][p-1];
+      }
+      e[p-1] = 0.0;
+
+      // If required, generate U.
+
+      if (wantu) {
+         for (int j = nct; j < n; j++) {
+            for (int i = 0; i < m; i++) {
+               U[i][j] = 0.0;
+            }
+            U[j][j] = 1.0;
+         }
+         for (int k = nct-1; k >= 0; k--) {
+            if (s[k] != 0.0) {
+               for (int j = k+1; j < n; j++) {
+                  double t = 0;
+                  for (int i = k; i < m; i++) {
+                     t += U[i][k]*U[i][j];
+                  }
+                  t = -t/U[k][k];
+                  for (int i = k; i < m; i++) {
+                     U[i][j] += t*U[i][k];
+                  }
+               }
+               for (int i = k; i < m; i++ ) {
+                  U[i][k] = -U[i][k];
+               }
+               U[k][k] = 1.0 + U[k][k];
+               for (int i = 0; i < k-1; i++) {
+                  U[i][k] = 0.0;
+               }
+            } else {
+               for (int i = 0; i < m; i++) {
+                  U[i][k] = 0.0;
+               }
+               U[k][k] = 1.0;
+            }
+         }
+      }
+
+      // If required, generate V.
+
+      if (wantv) {
+         for (int k = n-1; k >= 0; k--) {
+            if ((k < nrt) & (e[k] != 0.0)) {
+               for (int j = k+1; j < n; j++) {
+                  double t = 0;
+                  for (int i = k+1; i < n; i++) {
+                     t += V[i][k]*V[i][j];
+                  }
+                  t = -t/V[k+1][k];
+                  for (int i = k+1; i < n; i++) {
+                     V[i][j] += t*V[i][k];
+                  }
+               }
+            }
+            for (int i = 0; i < n; i++) {
+               V[i][k] = 0.0;
+            }
+            V[k][k] = 1.0;
+         }
+      }
+
+      // Main iteration loop for the singular values.
+
+      int pp = p-1;
+      int iter = 0;
+      double eps = Math.pow(2.0,-52.0);
+      double tiny = Math.pow(2.0,-966.0);
+      while (p > 0) {
+         int k,kase;
+
+         // Here is where a test for too many iterations would go.
+
+         // This section of the program inspects for
+         // negligible elements in the s and e arrays.  On
+         // completion the variables kase and k are set as follows.
+
+         // kase = 1     if s(p) and e[k-1] are negligible and k<p
+         // kase = 2     if s(k) is negligible and k<p
+         // kase = 3     if e[k-1] is negligible, k<p, and
+         //              s(k), ..., s(p) are not negligible (qr step).
+         // kase = 4     if e(p-1) is negligible (convergence).
+
+         for (k = p-2; k >= -1; k--) {
+            if (k == -1) {
+               break;
+            }
+            if (Math.abs(e[k]) <=
+                  tiny + eps*(Math.abs(s[k]) + Math.abs(s[k+1]))) {
+               e[k] = 0.0;
+               break;
+            }
+         }
+         if (k == p-2) {
+            kase = 4;
+         } else {
+            int ks;
+            for (ks = p-1; ks >= k; ks--) {
+               if (ks == k) {
+                  break;
+               }
+               double t = (ks != p ? Math.abs(e[ks]) : 0.) + 
+                          (ks != k+1 ? Math.abs(e[ks-1]) : 0.);
+               if (Math.abs(s[ks]) <= tiny + eps*t)  {
+                  s[ks] = 0.0;
+                  break;
+               }
+            }
+            if (ks == k) {
+               kase = 3;
+            } else if (ks == p-1) {
+               kase = 1;
+            } else {
+               kase = 2;
+               k = ks;
+            }
+         }
+         k++;
+
+         // Perform the task indicated by kase.
+
+         switch (kase) {
+
+            // Deflate negligible s(p).
+
+            case 1: {
+               double f = e[p-2];
+               e[p-2] = 0.0;
+               for (int j = p-2; j >= k; j--) {
+                  double t = Math.hypot(s[j],f);
+                  double cs = s[j]/t;
+                  double sn = f/t;
+                  s[j] = t;
+                  if (j != k) {
+                     f = -sn*e[j-1];
+                     e[j-1] = cs*e[j-1];
+                  }
+                  if (wantv) {
+                     for (int i = 0; i < n; i++) {
+                        t = cs*V[i][j] + sn*V[i][p-1];
+                        V[i][p-1] = -sn*V[i][j] + cs*V[i][p-1];
+                        V[i][j] = t;
+                     }
+                  }
+               }
+            }
+            break;
+
+            // Split at negligible s(k).
+
+            case 2: {
+               double f = e[k-1];
+               e[k-1] = 0.0;
+               for (int j = k; j < p; j++) {
+                  double t = Math.hypot(s[j],f);
+                  double cs = s[j]/t;
+                  double sn = f/t;
+                  s[j] = t;
+                  f = -sn*e[j];
+                  e[j] = cs*e[j];
+                  if (wantu) {
+                     for (int i = 0; i < m; i++) {
+                        t = cs*U[i][j] + sn*U[i][k-1];
+                        U[i][k-1] = -sn*U[i][j] + cs*U[i][k-1];
+                        U[i][j] = t;
+                     }
+                  }
+               }
+            }
+            break;
+
+            // Perform one qr step.
+
+            case 3: {
+
+               // Calculate the shift.
+   
+               double scale = Math.max(Math.max(Math.max(Math.max(
+                       Math.abs(s[p-1]),Math.abs(s[p-2])),Math.abs(e[p-2])), 
+                       Math.abs(s[k])),Math.abs(e[k]));
+               double sp = s[p-1]/scale;
+               double spm1 = s[p-2]/scale;
+               double epm1 = e[p-2]/scale;
+               double sk = s[k]/scale;
+               double ek = e[k]/scale;
+               double b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
+               double c = (sp*epm1)*(sp*epm1);
+               double shift = 0.0;
+               if ((b != 0.0) | (c != 0.0)) {
+                  shift = Math.sqrt(b*b + c);
+                  if (b < 0.0) {
+                     shift = -shift;
+                  }
+                  shift = c/(b + shift);
+               }
+               double f = (sk + sp)*(sk - sp) + shift;
+               double g = sk*ek;
+   
+               // Chase zeros.
+   
+               for (int j = k; j < p-1; j++) {
+                  double t = Math.hypot(f,g);
+                  double cs = f/t;
+                  double sn = g/t;
+                  if (j != k) {
+                     e[j-1] = t;
+                  }
+                  f = cs*s[j] + sn*e[j];
+                  e[j] = cs*e[j] - sn*s[j];
+                  g = sn*s[j+1];
+                  s[j+1] = cs*s[j+1];
+                  if (wantv) {
+                     for (int i = 0; i < n; i++) {
+                        t = cs*V[i][j] + sn*V[i][j+1];
+                        V[i][j+1] = -sn*V[i][j] + cs*V[i][j+1];
+                        V[i][j] = t;
+                     }
+                  }
+                  t = Math.hypot(f,g);
+                  cs = f/t;
+                  sn = g/t;
+                  s[j] = t;
+                  f = cs*e[j] + sn*s[j+1];
+                  s[j+1] = -sn*e[j] + cs*s[j+1];
+                  g = sn*e[j+1];
+                  e[j+1] = cs*e[j+1];
+                  if (wantu && (j < m-1)) {
+                     for (int i = 0; i < m; i++) {
+                        t = cs*U[i][j] + sn*U[i][j+1];
+                        U[i][j+1] = -sn*U[i][j] + cs*U[i][j+1];
+                        U[i][j] = t;
+                     }
+                  }
+               }
+               e[p-2] = f;
+               iter = iter + 1;
+            }
+            break;
+
+            // Convergence.
+
+            case 4: {
+
+               // Make the singular values positive.
+   
+               if (s[k] <= 0.0) {
+                  s[k] = (s[k] < 0.0 ? -s[k] : 0.0);
+                  if (wantv) {
+                     for (int i = 0; i <= pp; i++) {
+                        V[i][k] = -V[i][k];
+                     }
+                  }
+               }
+   
+               // Order the singular values.
+   
+               while (k < pp) {
+                  if (s[k] >= s[k+1]) {
+                     break;
+                  }
+                  double t = s[k];
+                  s[k] = s[k+1];
+                  s[k+1] = t;
+                  if (wantv && (k < n-1)) {
+                     for (int i = 0; i < n; i++) {
+                        t = V[i][k+1]; V[i][k+1] = V[i][k]; V[i][k] = t;
+                     }
+                  }
+                  if (wantu && (k < m-1)) {
+                     for (int i = 0; i < m; i++) {
+                        t = U[i][k+1]; U[i][k+1] = U[i][k]; U[i][k] = t;
+                     }
+                  }
+                  k++;
+               }
+               iter = 0;
+               p--;
+            }
+            break;
+         }
+      }
+   }
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Return the left singular vectors
+   @return     U
+   */
+
+   public Matrix getU () {
+      return transpose ? new Matrix(V,n,n) : new Matrix(U,m,n);
+   }
+
+   /** Return the right singular vectors
+   @return     V
+   */
+
+   public Matrix getV () {
+      return transpose ? new Matrix(U,m,n) : new Matrix(V,n,n);
+   }
+
+   /** Return the one-dimensional array of singular values
+   @return     diagonal of S.
+   */
+
+   public double[] getSingularValues () {
+      return s;
+   }
+
+   /** Return the diagonal matrix of singular values
+   @return     S
+   */
+
+   public Matrix getS () {
+      Matrix X = new Matrix(n,n);
+      double[][] S = X.getArray();
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            S[i][j] = 0.0;
+         }
+         S[i][i] = this.s[i];
+      }
+      return X;
+   }
+
+   /** Two norm
+   @return     max(S)
+   */
+
+   public double norm2 () {
+      return s[0];
+   }
+
+   /** Two norm condition number
+   @return     max(S)/min(S)
+   */
+
+   public double cond () {
+      return s[0]/s[Math.min(m,n)-1];
+   }
+
+   /** Effective numerical matrix rank
+   @return     Number of nonnegligible singular values.
+   */
+
+   public int rank () {
+      double eps = Math.pow(2.0,-52.0);
+      double tol = Math.max(m,n)*s[0]*eps;
+      int r = 0;
+      for (int i = 0; i < s.length; i++) {
+         if (s[i] > tol) {
+            r++;
+         }
+      }
+      return r;
+   }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/SingularValueDecomposition.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/SingularValueDecomposition.java0
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/SingularValueDecomposition.java0	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/SingularValueDecomposition.java0	(revision 481)
@@ -0,0 +1,547 @@
+package JamaPlus;
+import JamaPlus.util.*;
+
+   /** Singular Value Decomposition.
+   <P>
+   For an m-by-n matrix A with m >= n, the singular value decomposition is
+   an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and
+   an n-by-n orthogonal matrix V so that A = U*S*V'.
+   <P>
+   The singular values, sigma[k] = S[k][k], are ordered so that
+   sigma[0] >= sigma[1] >= ... >= sigma[n-1].
+   <P>
+   The singular value decompostion always exists, so the constructor will
+   never fail.  The matrix condition number and the effective numerical
+   rank can be computed from this decomposition.
+   */
+
+public class SingularValueDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Arrays for internal storage of U and V.
+   @serial internal storage of U.
+   @serial internal storage of V.
+   */
+   private double[][] U, V;
+
+   /** Array for internal storage of singular values.
+   @serial internal storage of singular values.
+   */
+   private double[] s;
+
+   /** Row and column dimensions.
+   @serial row dimension.
+   @serial column dimension.
+   */
+   private int m, n;
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** Construct the singular value decomposition
+   @param A    Rectangular matrix
+   @return     Structure to access U, S and V.
+   */
+
+   public SingularValueDecomposition (Matrix Arg) {
+
+      // Derived from LINPACK code.
+      // Initialize.
+      double[][] A = Arg.getArrayCopy();
+      m = Arg.getRowDimension();
+      n = Arg.getColumnDimension();
+
+      /* Apparently the failing cases are only a proper subset of (m<n), 
+	 so let's not throw error.  Correct fix to come later?
+      if (m<n) {
+	  throw new IllegalArgumentException("Jama SVD only works for m >= n"); }
+      */
+      int nu = Math.min(m,n);
+      s = new double [Math.min(m+1,n)];
+      U = new double [m][nu];
+      V = new double [n][n];
+      double[] e = new double [n];
+      double[] work = new double [m];
+      boolean wantu = true;
+      boolean wantv = true;
+
+      // Reduce A to bidiagonal form, storing the diagonal elements
+      // in s and the super-diagonal elements in e.
+
+      int nct = Math.min(m-1,n);
+      int nrt = Math.max(0,Math.min(n-2,m));
+      for (int k = 0; k < Math.max(nct,nrt); k++) {
+         if (k < nct) {
+
+            // Compute the transformation for the k-th column and
+            // place the k-th diagonal in s[k].
+            // Compute 2-norm of k-th column without under/overflow.
+            s[k] = 0;
+            for (int i = k; i < m; i++) {
+               s[k] = Math.hypot(s[k],A[i][k]);
+            }
+            if (s[k] != 0.0) {
+               if (A[k][k] < 0.0) {
+                  s[k] = -s[k];
+               }
+               for (int i = k; i < m; i++) {
+                  A[i][k] /= s[k];
+               }
+               A[k][k] += 1.0;
+            }
+            s[k] = -s[k];
+         }
+         for (int j = k+1; j < n; j++) {
+            if ((k < nct) & (s[k] != 0.0))  {
+
+            // Apply the transformation.
+
+               double t = 0;
+               for (int i = k; i < m; i++) {
+                  t += A[i][k]*A[i][j];
+               }
+               t = -t/A[k][k];
+               for (int i = k; i < m; i++) {
+                  A[i][j] += t*A[i][k];
+               }
+            }
+
+            // Place the k-th row of A into e for the
+            // subsequent calculation of the row transformation.
+
+            e[j] = A[k][j];
+         }
+         if (wantu & (k < nct)) {
+
+            // Place the transformation in U for subsequent back
+            // multiplication.
+
+            for (int i = k; i < m; i++) {
+               U[i][k] = A[i][k];
+            }
+         }
+         if (k < nrt) {
+
+            // Compute the k-th row transformation and place the
+            // k-th super-diagonal in e[k].
+            // Compute 2-norm without under/overflow.
+            e[k] = 0;
+            for (int i = k+1; i < n; i++) {
+               e[k] = Math.hypot(e[k],e[i]);
+            }
+            if (e[k] != 0.0) {
+               if (e[k+1] < 0.0) {
+                  e[k] = -e[k];
+               }
+               for (int i = k+1; i < n; i++) {
+                  e[i] /= e[k];
+               }
+               e[k+1] += 1.0;
+            }
+            e[k] = -e[k];
+            if ((k+1 < m) & (e[k] != 0.0)) {
+
+            // Apply the transformation.
+
+               for (int i = k+1; i < m; i++) {
+                  work[i] = 0.0;
+               }
+               for (int j = k+1; j < n; j++) {
+                  for (int i = k+1; i < m; i++) {
+                     work[i] += e[j]*A[i][j];
+                  }
+               }
+               for (int j = k+1; j < n; j++) {
+                  double t = -e[j]/e[k+1];
+                  for (int i = k+1; i < m; i++) {
+                     A[i][j] += t*work[i];
+                  }
+               }
+            }
+            if (wantv) {
+
+            // Place the transformation in V for subsequent
+            // back multiplication.
+
+               for (int i = k+1; i < n; i++) {
+                  V[i][k] = e[i];
+               }
+            }
+         }
+      }
+
+      // Set up the final bidiagonal matrix or order p.
+
+      int p = Math.min(n,m+1);
+      if (nct < n) {
+         s[nct] = A[nct][nct];
+      }
+      if (m < p) {
+         s[p-1] = 0.0;
+      }
+      if (nrt+1 < p) {
+         e[nrt] = A[nrt][p-1];
+      }
+      e[p-1] = 0.0;
+
+      // If required, generate U.
+
+      if (wantu) {
+         for (int j = nct; j < nu; j++) {
+            for (int i = 0; i < m; i++) {
+               U[i][j] = 0.0;
+            }
+            U[j][j] = 1.0;
+         }
+         for (int k = nct-1; k >= 0; k--) {
+            if (s[k] != 0.0) {
+               for (int j = k+1; j < nu; j++) {
+                  double t = 0;
+                  for (int i = k; i < m; i++) {
+                     t += U[i][k]*U[i][j];
+                  }
+                  t = -t/U[k][k];
+                  for (int i = k; i < m; i++) {
+                     U[i][j] += t*U[i][k];
+                  }
+               }
+               for (int i = k; i < m; i++ ) {
+                  U[i][k] = -U[i][k];
+               }
+               U[k][k] = 1.0 + U[k][k];
+               for (int i = 0; i < k-1; i++) {
+                  U[i][k] = 0.0;
+               }
+            } else {
+               for (int i = 0; i < m; i++) {
+                  U[i][k] = 0.0;
+               }
+               U[k][k] = 1.0;
+            }
+         }
+      }
+
+      // If required, generate V.
+
+      if (wantv) {
+         for (int k = n-1; k >= 0; k--) {
+            if ((k < nrt) & (e[k] != 0.0)) {
+               for (int j = k+1; j < nu; j++) {
+                  double t = 0;
+                  for (int i = k+1; i < n; i++) {
+                     t += V[i][k]*V[i][j];
+                  }
+                  t = -t/V[k+1][k];
+                  for (int i = k+1; i < n; i++) {
+                     V[i][j] += t*V[i][k];
+                  }
+               }
+            }
+            for (int i = 0; i < n; i++) {
+               V[i][k] = 0.0;
+            }
+            V[k][k] = 1.0;
+         }
+      }
+
+      // Main iteration loop for the singular values.
+
+      int pp = p-1;
+      int iter = 0;
+      double eps = Math.pow(2.0,-52.0);
+      double tiny = Math.pow(2.0,-966.0);
+      while (p > 0) {
+         int k,kase;
+
+         // Here is where a test for too many iterations would go.
+
+         // This section of the program inspects for
+         // negligible elements in the s and e arrays.  On
+         // completion the variables kase and k are set as follows.
+
+         // kase = 1     if s(p) and e[k-1] are negligible and k<p
+         // kase = 2     if s(k) is negligible and k<p
+         // kase = 3     if e[k-1] is negligible, k<p, and
+         //              s(k), ..., s(p) are not negligible (qr step).
+         // kase = 4     if e(p-1) is negligible (convergence).
+
+         for (k = p-2; k >= -1; k--) {
+            if (k == -1) {
+               break;
+            }
+            if (Math.abs(e[k]) <=
+                  tiny + eps*(Math.abs(s[k]) + Math.abs(s[k+1]))) {
+               e[k] = 0.0;
+               break;
+            }
+         }
+         if (k == p-2) {
+            kase = 4;
+         } else {
+            int ks;
+            for (ks = p-1; ks >= k; ks--) {
+               if (ks == k) {
+                  break;
+               }
+               double t = (ks != p ? Math.abs(e[ks]) : 0.) + 
+                          (ks != k+1 ? Math.abs(e[ks-1]) : 0.);
+               if (Math.abs(s[ks]) <= tiny + eps*t)  {
+                  s[ks] = 0.0;
+                  break;
+               }
+            }
+            if (ks == k) {
+               kase = 3;
+            } else if (ks == p-1) {
+               kase = 1;
+            } else {
+               kase = 2;
+               k = ks;
+            }
+         }
+         k++;
+
+         // Perform the task indicated by kase.
+
+         switch (kase) {
+
+            // Deflate negligible s(p).
+
+            case 1: {
+               double f = e[p-2];
+               e[p-2] = 0.0;
+               for (int j = p-2; j >= k; j--) {
+                  double t = Math.hypot(s[j],f);
+                  double cs = s[j]/t;
+                  double sn = f/t;
+                  s[j] = t;
+                  if (j != k) {
+                     f = -sn*e[j-1];
+                     e[j-1] = cs*e[j-1];
+                  }
+                  if (wantv) {
+                     for (int i = 0; i < n; i++) {
+                        t = cs*V[i][j] + sn*V[i][p-1];
+                        V[i][p-1] = -sn*V[i][j] + cs*V[i][p-1];
+                        V[i][j] = t;
+                     }
+                  }
+               }
+            }
+            break;
+
+            // Split at negligible s(k).
+
+            case 2: {
+               double f = e[k-1];
+               e[k-1] = 0.0;
+               for (int j = k; j < p; j++) {
+                  double t = Math.hypot(s[j],f);
+                  double cs = s[j]/t;
+                  double sn = f/t;
+                  s[j] = t;
+                  f = -sn*e[j];
+                  e[j] = cs*e[j];
+                  if (wantu) {
+                     for (int i = 0; i < m; i++) {
+                        t = cs*U[i][j] + sn*U[i][k-1];
+                        U[i][k-1] = -sn*U[i][j] + cs*U[i][k-1];
+                        U[i][j] = t;
+                     }
+                  }
+               }
+            }
+            break;
+
+            // Perform one qr step.
+
+            case 3: {
+
+               // Calculate the shift.
+   
+               double scale = Math.max(Math.max(Math.max(Math.max(
+                       Math.abs(s[p-1]),Math.abs(s[p-2])),Math.abs(e[p-2])), 
+                       Math.abs(s[k])),Math.abs(e[k]));
+               double sp = s[p-1]/scale;
+               double spm1 = s[p-2]/scale;
+               double epm1 = e[p-2]/scale;
+               double sk = s[k]/scale;
+               double ek = e[k]/scale;
+               double b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
+               double c = (sp*epm1)*(sp*epm1);
+               double shift = 0.0;
+               if ((b != 0.0) | (c != 0.0)) {
+                  shift = Math.sqrt(b*b + c);
+                  if (b < 0.0) {
+                     shift = -shift;
+                  }
+                  shift = c/(b + shift);
+               }
+               double f = (sk + sp)*(sk - sp) + shift;
+               double g = sk*ek;
+   
+               // Chase zeros.
+   
+               for (int j = k; j < p-1; j++) {
+                  double t = Math.hypot(f,g);
+                  double cs = f/t;
+                  double sn = g/t;
+                  if (j != k) {
+                     e[j-1] = t;
+                  }
+                  f = cs*s[j] + sn*e[j];
+                  e[j] = cs*e[j] - sn*s[j];
+                  g = sn*s[j+1];
+                  s[j+1] = cs*s[j+1];
+                  if (wantv) {
+                     for (int i = 0; i < n; i++) {
+                        t = cs*V[i][j] + sn*V[i][j+1];
+                        V[i][j+1] = -sn*V[i][j] + cs*V[i][j+1];
+                        V[i][j] = t;
+                     }
+                  }
+                  t = Math.hypot(f,g);
+                  cs = f/t;
+                  sn = g/t;
+                  s[j] = t;
+                  f = cs*e[j] + sn*s[j+1];
+                  s[j+1] = -sn*e[j] + cs*s[j+1];
+                  g = sn*e[j+1];
+                  e[j+1] = cs*e[j+1];
+                  if (wantu && (j < m-1)) {
+                     for (int i = 0; i < m; i++) {
+                        t = cs*U[i][j] + sn*U[i][j+1];
+                        U[i][j+1] = -sn*U[i][j] + cs*U[i][j+1];
+                        U[i][j] = t;
+                     }
+                  }
+               }
+               e[p-2] = f;
+               iter = iter + 1;
+            }
+            break;
+
+            // Convergence.
+
+            case 4: {
+
+               // Make the singular values positive.
+   
+               if (s[k] <= 0.0) {
+                  s[k] = (s[k] < 0.0 ? -s[k] : 0.0);
+                  if (wantv) {
+                     for (int i = 0; i <= pp; i++) {
+                        V[i][k] = -V[i][k];
+                     }
+                  }
+               }
+   
+               // Order the singular values.
+   
+               while (k < pp) {
+                  if (s[k] >= s[k+1]) {
+                     break;
+                  }
+                  double t = s[k];
+                  s[k] = s[k+1];
+                  s[k+1] = t;
+                  if (wantv && (k < n-1)) {
+                     for (int i = 0; i < n; i++) {
+                        t = V[i][k+1]; V[i][k+1] = V[i][k]; V[i][k] = t;
+                     }
+                  }
+                  if (wantu && (k < m-1)) {
+                     for (int i = 0; i < m; i++) {
+                        t = U[i][k+1]; U[i][k+1] = U[i][k]; U[i][k] = t;
+                     }
+                  }
+                  k++;
+               }
+               iter = 0;
+               p--;
+            }
+            break;
+         }
+      }
+   }
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Return the left singular vectors
+   @return     U
+   */
+
+   public Matrix getU () {
+      return new Matrix(U,m,Math.min(m+1,n));
+   }
+
+   /** Return the right singular vectors
+   @return     V
+   */
+
+   public Matrix getV () {
+      return new Matrix(V,n,n);
+   }
+
+   /** Return the one-dimensional array of singular values
+   @return     diagonal of S.
+   */
+
+   public double[] getSingularValues () {
+      return s;
+   }
+
+   /** Return the diagonal matrix of singular values
+   @return     S
+   */
+
+   public Matrix getS () {
+      Matrix X = new Matrix(n,n);
+      double[][] S = X.getArray();
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            S[i][j] = 0.0;
+         }
+         S[i][i] = this.s[i];
+      }
+      return X;
+   }
+
+   /** Two norm
+   @return     max(S)
+   */
+
+   public double norm2 () {
+      return s[0];
+   }
+
+   /** Two norm condition number
+   @return     max(S)/min(S)
+   */
+
+   public double cond () {
+      return s[0]/s[Math.min(m,n)-1];
+   }
+
+   /** Effective numerical matrix rank
+   @return     Number of nonnegligible singular values.
+   */
+
+   public int rank () {
+      double eps = Math.pow(2.0,-52.0);
+      double tol = Math.max(m,n)*s[0]*eps;
+      int r = 0;
+      for (int i = 0; i < s.length; i++) {
+         if (s[i] > tol) {
+            r++;
+         }
+      }
+      return r;
+   }
+}
Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/QRDecomposition.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/QRDecomposition.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/QRDecomposition.java	(revision 481)
@@ -0,0 +1,218 @@
+package JamaPlus;
+import JamaPlus.util.*;
+
+/** QR Decomposition.
+<P>
+   For an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n
+   orthogonal matrix Q and an n-by-n upper triangular matrix R so that
+   A = Q*R.
+<P>
+   The QR decompostion always exists, even if the matrix does not have
+   full rank, so the constructor will never fail.  The primary use of the
+   QR decomposition is in the least squares solution of nonsquare systems
+   of simultaneous linear equations.  This will fail if isFullRank()
+   returns false.
+*/
+
+public class QRDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Array for internal storage of decomposition.
+   @serial internal array storage.
+   */
+   private double[][] QR;
+
+   /** Row and column dimensions.
+   @serial column dimension.
+   @serial row dimension.
+   */
+   private int m, n;
+
+   /** Array for internal storage of diagonal of R.
+   @serial diagonal of R.
+   */
+   private double[] Rdiag;
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** QR Decomposition, computed by Householder reflections.
+   @param A    Rectangular matrix
+   @return     Structure to access R and the Householder vectors and compute Q.
+   */
+
+   public QRDecomposition (Matrix A) {
+      // Initialize.
+      QR = A.getArrayCopy();
+      m = A.getRowDimension();
+      n = A.getColumnDimension();
+      Rdiag = new double[n];
+
+      // Main loop.
+      for (int k = 0; k < n; k++) {
+         // Compute 2-norm of k-th column without under/overflow.
+         double nrm = 0;
+         for (int i = k; i < m; i++) {
+            nrm = Math.hypot(nrm,QR[i][k]);
+         }
+
+         if (nrm != 0.0) {
+            // Form k-th Householder vector.
+            if (QR[k][k] < 0) {
+               nrm = -nrm;
+            }
+            for (int i = k; i < m; i++) {
+               QR[i][k] /= nrm;
+            }
+            QR[k][k] += 1.0;
+
+            // Apply transformation to remaining columns.
+            for (int j = k+1; j < n; j++) {
+               double s = 0.0; 
+               for (int i = k; i < m; i++) {
+                  s += QR[i][k]*QR[i][j];
+               }
+               s = -s/QR[k][k];
+               for (int i = k; i < m; i++) {
+                  QR[i][j] += s*QR[i][k];
+               }
+            }
+         }
+         Rdiag[k] = -nrm;
+      }
+   }
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Is the matrix full rank?
+   @return     true if R, and hence A, has full rank.
+   */
+
+   public boolean isFullRank () {
+      for (int j = 0; j < n; j++) {
+         if (Rdiag[j] == 0)
+            return false;
+      }
+      return true;
+   }
+
+   /** Return the Householder vectors
+   @return     Lower trapezoidal matrix whose columns define the reflections
+   */
+
+   public Matrix getH () {
+      Matrix X = new Matrix(m,n);
+      double[][] H = X.getArray();
+      for (int i = 0; i < m; i++) {
+         for (int j = 0; j < n; j++) {
+            if (i >= j) {
+               H[i][j] = QR[i][j];
+            } else {
+               H[i][j] = 0.0;
+            }
+         }
+      }
+      return X;
+   }
+
+   /** Return the upper triangular factor
+   @return     R
+   */
+
+   public Matrix getR () {
+      Matrix X = new Matrix(n,n);
+      double[][] R = X.getArray();
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            if (i < j) {
+               R[i][j] = QR[i][j];
+            } else if (i == j) {
+               R[i][j] = Rdiag[i];
+            } else {
+               R[i][j] = 0.0;
+            }
+         }
+      }
+      return X;
+   }
+
+   /** Generate and return the (economy-sized) orthogonal factor
+   @return     Q
+   */
+
+   public Matrix getQ () {
+      Matrix X = new Matrix(m,n);
+      double[][] Q = X.getArray();
+      for (int k = n-1; k >= 0; k--) {
+         for (int i = 0; i < m; i++) {
+            Q[i][k] = 0.0;
+         }
+         Q[k][k] = 1.0;
+         for (int j = k; j < n; j++) {
+            if (QR[k][k] != 0) {
+               double s = 0.0;
+               for (int i = k; i < m; i++) {
+                  s += QR[i][k]*Q[i][j];
+               }
+               s = -s/QR[k][k];
+               for (int i = k; i < m; i++) {
+                  Q[i][j] += s*QR[i][k];
+               }
+            }
+         }
+      }
+      return X;
+   }
+
+   /** Least squares solution of A*X = B
+   @param B    A Matrix with as many rows as A and any number of columns.
+   @return     X that minimizes the two norm of Q*R*X-B.
+   @exception  IllegalArgumentException  Matrix row dimensions must agree.
+   @exception  RuntimeException  Matrix is rank deficient.
+   */
+
+   public Matrix solve (Matrix B) {
+      if (B.getRowDimension() != m) {
+         throw new IllegalArgumentException("Matrix row dimensions must agree.");
+      }
+      if (!this.isFullRank()) {
+         throw new RuntimeException("Matrix is rank deficient.");
+      }
+      
+      // Copy right hand side
+      int nx = B.getColumnDimension();
+      double[][] X = B.getArrayCopy();
+
+      // Compute Y = transpose(Q)*B
+      for (int k = 0; k < n; k++) {
+         for (int j = 0; j < nx; j++) {
+            double s = 0.0; 
+            for (int i = k; i < m; i++) {
+               s += QR[i][k]*X[i][j];
+            }
+            s = -s/QR[k][k];
+            for (int i = k; i < m; i++) {
+               X[i][j] += s*QR[i][k];
+            }
+         }
+      }
+      // Solve R*X = Y;
+      for (int k = n-1; k >= 0; k--) {
+         for (int j = 0; j < nx; j++) {
+            X[k][j] /= Rdiag[k];
+         }
+         for (int i = 0; i < k; i++) {
+            for (int j = 0; j < nx; j++) {
+               X[i][j] -= X[k][j]*QR[i][k];
+            }
+         }
+      }
+      return (new Matrix(X,n,nx).getMatrix(0,n-1,0,nx-1));
+   }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/QRDecomposition.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/EigenvalueDecomposition.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/EigenvalueDecomposition.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/EigenvalueDecomposition.java	(revision 481)
@@ -0,0 +1,955 @@
+package JamaPlus;
+import JamaPlus.util.*;
+
+/** Eigenvalues and eigenvectors of a real matrix. 
+<P>
+    If A is symmetric, then A = V*D*V' where the eigenvalue matrix D is
+    diagonal and the eigenvector matrix V is orthogonal.
+    I.e. A = V.times(D.times(V.transpose())) and 
+    V.times(V.transpose()) equals the identity matrix.
+<P>
+    If A is not symmetric, then the eigenvalue matrix D is block diagonal
+    with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues,
+    lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda].  The
+    columns of V represent the eigenvectors in the sense that A*V = V*D,
+    i.e. A.times(V) equals V.times(D).  The matrix V may be badly
+    conditioned, or even singular, so the validity of the equation
+    A = V*D*inverse(V) depends upon V.cond().
+**/
+
+public class EigenvalueDecomposition implements java.io.Serializable {
+
+/* ------------------------
+   Class variables
+ * ------------------------ */
+
+   /** Row and column dimension (square matrix).
+   @serial matrix dimension.
+   */
+   private int n;
+
+   /** Symmetry flag.
+   @serial internal symmetry flag.
+   */
+   private boolean issymmetric;
+
+   /** Arrays for internal storage of eigenvalues.
+   @serial internal storage of eigenvalues.
+   */
+   private double[] d, e;
+
+   /** Array for internal storage of eigenvectors.
+   @serial internal storage of eigenvectors.
+   */
+   private double[][] V;
+
+   /** Array for internal storage of nonsymmetric Hessenberg form.
+   @serial internal storage of nonsymmetric Hessenberg form.
+   */
+   private double[][] H;
+
+   /** Working storage for nonsymmetric algorithm.
+   @serial working storage for nonsymmetric algorithm.
+   */
+   private double[] ort;
+
+/* ------------------------
+   Private Methods
+ * ------------------------ */
+
+   // Symmetric Householder reduction to tridiagonal form.
+
+   private void tred2 () {
+
+   //  This is derived from the Algol procedures tred2 by
+   //  Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+   //  Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+   //  Fortran subroutine in EISPACK.
+
+      for (int j = 0; j < n; j++) {
+         d[j] = V[n-1][j];
+      }
+
+      // Householder reduction to tridiagonal form.
+   
+      for (int i = n-1; i > 0; i--) {
+   
+         // Scale to avoid under/overflow.
+   
+         double scale = 0.0;
+         double h = 0.0;
+         for (int k = 0; k < i; k++) {
+            scale = scale + Math.abs(d[k]);
+         }
+         if (scale == 0.0) {
+            e[i] = d[i-1];
+            for (int j = 0; j < i; j++) {
+               d[j] = V[i-1][j];
+               V[i][j] = 0.0;
+               V[j][i] = 0.0;
+            }
+         } else {
+   
+            // Generate Householder vector.
+   
+            for (int k = 0; k < i; k++) {
+               d[k] /= scale;
+               h += d[k] * d[k];
+            }
+            double f = d[i-1];
+            double g = Math.sqrt(h);
+            if (f > 0) {
+               g = -g;
+            }
+            e[i] = scale * g;
+            h = h - f * g;
+            d[i-1] = f - g;
+            for (int j = 0; j < i; j++) {
+               e[j] = 0.0;
+            }
+   
+            // Apply similarity transformation to remaining columns.
+   
+            for (int j = 0; j < i; j++) {
+               f = d[j];
+               V[j][i] = f;
+               g = e[j] + V[j][j] * f;
+               for (int k = j+1; k <= i-1; k++) {
+                  g += V[k][j] * d[k];
+                  e[k] += V[k][j] * f;
+               }
+               e[j] = g;
+            }
+            f = 0.0;
+            for (int j = 0; j < i; j++) {
+               e[j] /= h;
+               f += e[j] * d[j];
+            }
+            double hh = f / (h + h);
+            for (int j = 0; j < i; j++) {
+               e[j] -= hh * d[j];
+            }
+            for (int j = 0; j < i; j++) {
+               f = d[j];
+               g = e[j];
+               for (int k = j; k <= i-1; k++) {
+                  V[k][j] -= (f * e[k] + g * d[k]);
+               }
+               d[j] = V[i-1][j];
+               V[i][j] = 0.0;
+            }
+         }
+         d[i] = h;
+      }
+   
+      // Accumulate transformations.
+   
+      for (int i = 0; i < n-1; i++) {
+         V[n-1][i] = V[i][i];
+         V[i][i] = 1.0;
+         double h = d[i+1];
+         if (h != 0.0) {
+            for (int k = 0; k <= i; k++) {
+               d[k] = V[k][i+1] / h;
+            }
+            for (int j = 0; j <= i; j++) {
+               double g = 0.0;
+               for (int k = 0; k <= i; k++) {
+                  g += V[k][i+1] * V[k][j];
+               }
+               for (int k = 0; k <= i; k++) {
+                  V[k][j] -= g * d[k];
+               }
+            }
+         }
+         for (int k = 0; k <= i; k++) {
+            V[k][i+1] = 0.0;
+         }
+      }
+      for (int j = 0; j < n; j++) {
+         d[j] = V[n-1][j];
+         V[n-1][j] = 0.0;
+      }
+      V[n-1][n-1] = 1.0;
+      e[0] = 0.0;
+   } 
+
+   // Symmetric tridiagonal QL algorithm.
+   
+   private void tql2 () {
+
+   //  This is derived from the Algol procedures tql2, by
+   //  Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+   //  Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+   //  Fortran subroutine in EISPACK.
+   
+      for (int i = 1; i < n; i++) {
+         e[i-1] = e[i];
+      }
+      e[n-1] = 0.0;
+   
+      double f = 0.0;
+      double tst1 = 0.0;
+      double eps = Math.pow(2.0,-52.0);
+      for (int l = 0; l < n; l++) {
+
+         // Find small subdiagonal element
+   
+         tst1 = Math.max(tst1,Math.abs(d[l]) + Math.abs(e[l]));
+         int m = l;
+         while (m < n) {
+            if (Math.abs(e[m]) <= eps*tst1) {
+               break;
+            }
+            m++;
+         }
+   
+         // If m == l, d[l] is an eigenvalue,
+         // otherwise, iterate.
+   
+         if (m > l) {
+            int iter = 0;
+            do {
+               iter = iter + 1;  // (Could check iteration count here.)
+   
+               // Compute implicit shift
+   
+               double g = d[l];
+               double p = (d[l+1] - g) / (2.0 * e[l]);
+               double r = Math.hypot(p,1.0);
+               if (p < 0) {
+                  r = -r;
+               }
+               d[l] = e[l] / (p + r);
+               d[l+1] = e[l] * (p + r);
+               double dl1 = d[l+1];
+               double h = g - d[l];
+               for (int i = l+2; i < n; i++) {
+                  d[i] -= h;
+               }
+               f = f + h;
+   
+               // Implicit QL transformation.
+   
+               p = d[m];
+               double c = 1.0;
+               double c2 = c;
+               double c3 = c;
+               double el1 = e[l+1];
+               double s = 0.0;
+               double s2 = 0.0;
+               for (int i = m-1; i >= l; i--) {
+                  c3 = c2;
+                  c2 = c;
+                  s2 = s;
+                  g = c * e[i];
+                  h = c * p;
+                  r = Math.hypot(p,e[i]);
+                  e[i+1] = s * r;
+                  s = e[i] / r;
+                  c = p / r;
+                  p = c * d[i] - s * g;
+                  d[i+1] = h + s * (c * g + s * d[i]);
+   
+                  // Accumulate transformation.
+   
+                  for (int k = 0; k < n; k++) {
+                     h = V[k][i+1];
+                     V[k][i+1] = s * V[k][i] + c * h;
+                     V[k][i] = c * V[k][i] - s * h;
+                  }
+               }
+               p = -s * s2 * c3 * el1 * e[l] / dl1;
+               e[l] = s * p;
+               d[l] = c * p;
+   
+               // Check for convergence.
+   
+            } while (Math.abs(e[l]) > eps*tst1);
+         }
+         d[l] = d[l] + f;
+         e[l] = 0.0;
+      }
+     
+      // Sort eigenvalues and corresponding vectors.
+   
+      for (int i = 0; i < n-1; i++) {
+         int k = i;
+         double p = d[i];
+         for (int j = i+1; j < n; j++) {
+            if (d[j] < p) {
+               k = j;
+               p = d[j];
+            }
+         }
+         if (k != i) {
+            d[k] = d[i];
+            d[i] = p;
+            for (int j = 0; j < n; j++) {
+               p = V[j][i];
+               V[j][i] = V[j][k];
+               V[j][k] = p;
+            }
+         }
+      }
+   }
+
+   // Nonsymmetric reduction to Hessenberg form.
+
+   private void orthes () {
+   
+      //  This is derived from the Algol procedures orthes and ortran,
+      //  by Martin and Wilkinson, Handbook for Auto. Comp.,
+      //  Vol.ii-Linear Algebra, and the corresponding
+      //  Fortran subroutines in EISPACK.
+   
+      int low = 0;
+      int high = n-1;
+   
+      for (int m = low+1; m <= high-1; m++) {
+   
+         // Scale column.
+   
+         double scale = 0.0;
+         for (int i = m; i <= high; i++) {
+            scale = scale + Math.abs(H[i][m-1]);
+         }
+         if (scale != 0.0) {
+   
+            // Compute Householder transformation.
+   
+            double h = 0.0;
+            for (int i = high; i >= m; i--) {
+               ort[i] = H[i][m-1]/scale;
+               h += ort[i] * ort[i];
+            }
+            double g = Math.sqrt(h);
+            if (ort[m] > 0) {
+               g = -g;
+            }
+            h = h - ort[m] * g;
+            ort[m] = ort[m] - g;
+   
+            // Apply Householder similarity transformation
+            // H = (I-u*u'/h)*H*(I-u*u')/h)
+   
+            for (int j = m; j < n; j++) {
+               double f = 0.0;
+               for (int i = high; i >= m; i--) {
+                  f += ort[i]*H[i][j];
+               }
+               f = f/h;
+               for (int i = m; i <= high; i++) {
+                  H[i][j] -= f*ort[i];
+               }
+           }
+   
+           for (int i = 0; i <= high; i++) {
+               double f = 0.0;
+               for (int j = high; j >= m; j--) {
+                  f += ort[j]*H[i][j];
+               }
+               f = f/h;
+               for (int j = m; j <= high; j++) {
+                  H[i][j] -= f*ort[j];
+               }
+            }
+            ort[m] = scale*ort[m];
+            H[m][m-1] = scale*g;
+         }
+      }
+   
+      // Accumulate transformations (Algol's ortran).
+
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            V[i][j] = (i == j ? 1.0 : 0.0);
+         }
+      }
+
+      for (int m = high-1; m >= low+1; m--) {
+         if (H[m][m-1] != 0.0) {
+            for (int i = m+1; i <= high; i++) {
+               ort[i] = H[i][m-1];
+            }
+            for (int j = m; j <= high; j++) {
+               double g = 0.0;
+               for (int i = m; i <= high; i++) {
+                  g += ort[i] * V[i][j];
+               }
+               // Double division avoids possible underflow
+               g = (g / ort[m]) / H[m][m-1];
+               for (int i = m; i <= high; i++) {
+                  V[i][j] += g * ort[i];
+               }
+            }
+         }
+      }
+   }
+
+
+   // Complex scalar division.
+
+   private transient double cdivr, cdivi;
+   private void cdiv(double xr, double xi, double yr, double yi) {
+      double r,d;
+      if (Math.abs(yr) > Math.abs(yi)) {
+         r = yi/yr;
+         d = yr + r*yi;
+         cdivr = (xr + r*xi)/d;
+         cdivi = (xi - r*xr)/d;
+      } else {
+         r = yr/yi;
+         d = yi + r*yr;
+         cdivr = (r*xr + xi)/d;
+         cdivi = (r*xi - xr)/d;
+      }
+   }
+
+
+   // Nonsymmetric reduction from Hessenberg to real Schur form.
+
+   private void hqr2 () {
+   
+      //  This is derived from the Algol procedure hqr2,
+      //  by Martin and Wilkinson, Handbook for Auto. Comp.,
+      //  Vol.ii-Linear Algebra, and the corresponding
+      //  Fortran subroutine in EISPACK.
+   
+      // Initialize
+   
+      int nn = this.n;
+      int n = nn-1;
+      int low = 0;
+      int high = nn-1;
+      double eps = Math.pow(2.0,-52.0);
+      double exshift = 0.0;
+      double p=0,q=0,r=0,s=0,z=0,t,w,x,y;
+   
+      // Store roots isolated by balanc and compute matrix norm
+   
+      double norm = 0.0;
+      for (int i = 0; i < nn; i++) {
+         if (i < low | i > high) {
+            d[i] = H[i][i];
+            e[i] = 0.0;
+         }
+         for (int j = Math.max(i-1,0); j < nn; j++) {
+            norm = norm + Math.abs(H[i][j]);
+         }
+      }
+   
+      // Outer loop over eigenvalue index
+   
+      int iter = 0;
+      while (n >= low) {
+   
+         // Look for single small sub-diagonal element
+   
+         int l = n;
+         while (l > low) {
+            s = Math.abs(H[l-1][l-1]) + Math.abs(H[l][l]);
+            if (s == 0.0) {
+               s = norm;
+            }
+            if (Math.abs(H[l][l-1]) < eps * s) {
+               break;
+            }
+            l--;
+         }
+       
+         // Check for convergence
+         // One root found
+   
+         if (l == n) {
+            H[n][n] = H[n][n] + exshift;
+            d[n] = H[n][n];
+            e[n] = 0.0;
+            n--;
+            iter = 0;
+   
+         // Two roots found
+   
+         } else if (l == n-1) {
+            w = H[n][n-1] * H[n-1][n];
+            p = (H[n-1][n-1] - H[n][n]) / 2.0;
+            q = p * p + w;
+            z = Math.sqrt(Math.abs(q));
+            H[n][n] = H[n][n] + exshift;
+            H[n-1][n-1] = H[n-1][n-1] + exshift;
+            x = H[n][n];
+   
+            // Real pair
+   
+            if (q >= 0) {
+               if (p >= 0) {
+                  z = p + z;
+               } else {
+                  z = p - z;
+               }
+               d[n-1] = x + z;
+               d[n] = d[n-1];
+               if (z != 0.0) {
+                  d[n] = x - w / z;
+               }
+               e[n-1] = 0.0;
+               e[n] = 0.0;
+               x = H[n][n-1];
+               s = Math.abs(x) + Math.abs(z);
+               p = x / s;
+               q = z / s;
+               r = Math.sqrt(p * p+q * q);
+               p = p / r;
+               q = q / r;
+   
+               // Row modification
+   
+               for (int j = n-1; j < nn; j++) {
+                  z = H[n-1][j];
+                  H[n-1][j] = q * z + p * H[n][j];
+                  H[n][j] = q * H[n][j] - p * z;
+               }
+   
+               // Column modification
+   
+               for (int i = 0; i <= n; i++) {
+                  z = H[i][n-1];
+                  H[i][n-1] = q * z + p * H[i][n];
+                  H[i][n] = q * H[i][n] - p * z;
+               }
+   
+               // Accumulate transformations
+   
+               for (int i = low; i <= high; i++) {
+                  z = V[i][n-1];
+                  V[i][n-1] = q * z + p * V[i][n];
+                  V[i][n] = q * V[i][n] - p * z;
+               }
+   
+            // Complex pair
+   
+            } else {
+               d[n-1] = x + p;
+               d[n] = x + p;
+               e[n-1] = z;
+               e[n] = -z;
+            }
+            n = n - 2;
+            iter = 0;
+   
+         // No convergence yet
+   
+         } else {
+   
+            // Form shift
+   
+            x = H[n][n];
+            y = 0.0;
+            w = 0.0;
+            if (l < n) {
+               y = H[n-1][n-1];
+               w = H[n][n-1] * H[n-1][n];
+            }
+   
+            // Wilkinson's original ad hoc shift
+   
+            if (iter == 10) {
+               exshift += x;
+               for (int i = low; i <= n; i++) {
+                  H[i][i] -= x;
+               }
+               s = Math.abs(H[n][n-1]) + Math.abs(H[n-1][n-2]);
+               x = y = 0.75 * s;
+               w = -0.4375 * s * s;
+            }
+
+            // MATLAB's new ad hoc shift
+
+            if (iter == 30) {
+                s = (y - x) / 2.0;
+                s = s * s + w;
+                if (s > 0) {
+                    s = Math.sqrt(s);
+                    if (y < x) {
+                       s = -s;
+                    }
+                    s = x - w / ((y - x) / 2.0 + s);
+                    for (int i = low; i <= n; i++) {
+                       H[i][i] -= s;
+                    }
+                    exshift += s;
+                    x = y = w = 0.964;
+                }
+            }
+   
+            iter = iter + 1;   // (Could check iteration count here.)
+   
+            // Look for two consecutive small sub-diagonal elements
+   
+            int m = n-2;
+            while (m >= l) {
+               z = H[m][m];
+               r = x - z;
+               s = y - z;
+               p = (r * s - w) / H[m+1][m] + H[m][m+1];
+               q = H[m+1][m+1] - z - r - s;
+               r = H[m+2][m+1];
+               s = Math.abs(p) + Math.abs(q) + Math.abs(r);
+               p = p / s;
+               q = q / s;
+               r = r / s;
+               if (m == l) {
+                  break;
+               }
+               if (Math.abs(H[m][m-1]) * (Math.abs(q) + Math.abs(r)) <
+                  eps * (Math.abs(p) * (Math.abs(H[m-1][m-1]) + Math.abs(z) +
+                  Math.abs(H[m+1][m+1])))) {
+                     break;
+               }
+               m--;
+            }
+   
+            for (int i = m+2; i <= n; i++) {
+               H[i][i-2] = 0.0;
+               if (i > m+2) {
+                  H[i][i-3] = 0.0;
+               }
+            }
+   
+            // Double QR step involving rows l:n and columns m:n
+   
+            for (int k = m; k <= n-1; k++) {
+               boolean notlast = (k != n-1);
+               if (k != m) {
+                  p = H[k][k-1];
+                  q = H[k+1][k-1];
+                  r = (notlast ? H[k+2][k-1] : 0.0);
+                  x = Math.abs(p) + Math.abs(q) + Math.abs(r);
+                  if (x != 0.0) {
+                     p = p / x;
+                     q = q / x;
+                     r = r / x;
+                  }
+               }
+               if (x == 0.0) {
+                  break;
+               }
+               s = Math.sqrt(p * p + q * q + r * r);
+               if (p < 0) {
+                  s = -s;
+               }
+               if (s != 0) {
+                  if (k != m) {
+                     H[k][k-1] = -s * x;
+                  } else if (l != m) {
+                     H[k][k-1] = -H[k][k-1];
+                  }
+                  p = p + s;
+                  x = p / s;
+                  y = q / s;
+                  z = r / s;
+                  q = q / p;
+                  r = r / p;
+   
+                  // Row modification
+   
+                  for (int j = k; j < nn; j++) {
+                     p = H[k][j] + q * H[k+1][j];
+                     if (notlast) {
+                        p = p + r * H[k+2][j];
+                        H[k+2][j] = H[k+2][j] - p * z;
+                     }
+                     H[k][j] = H[k][j] - p * x;
+                     H[k+1][j] = H[k+1][j] - p * y;
+                  }
+   
+                  // Column modification
+   
+                  for (int i = 0; i <= Math.min(n,k+3); i++) {
+                     p = x * H[i][k] + y * H[i][k+1];
+                     if (notlast) {
+                        p = p + z * H[i][k+2];
+                        H[i][k+2] = H[i][k+2] - p * r;
+                     }
+                     H[i][k] = H[i][k] - p;
+                     H[i][k+1] = H[i][k+1] - p * q;
+                  }
+   
+                  // Accumulate transformations
+   
+                  for (int i = low; i <= high; i++) {
+                     p = x * V[i][k] + y * V[i][k+1];
+                     if (notlast) {
+                        p = p + z * V[i][k+2];
+                        V[i][k+2] = V[i][k+2] - p * r;
+                     }
+                     V[i][k] = V[i][k] - p;
+                     V[i][k+1] = V[i][k+1] - p * q;
+                  }
+               }  // (s != 0)
+            }  // k loop
+         }  // check convergence
+      }  // while (n >= low)
+      
+      // Backsubstitute to find vectors of upper triangular form
+
+      if (norm == 0.0) {
+         return;
+      }
+   
+      for (n = nn-1; n >= 0; n--) {
+         p = d[n];
+         q = e[n];
+   
+         // Real vector
+   
+         if (q == 0) {
+            int l = n;
+            H[n][n] = 1.0;
+            for (int i = n-1; i >= 0; i--) {
+               w = H[i][i] - p;
+               r = 0.0;
+               for (int j = l; j <= n; j++) {
+                  r = r + H[i][j] * H[j][n];
+               }
+               if (e[i] < 0.0) {
+                  z = w;
+                  s = r;
+               } else {
+                  l = i;
+                  if (e[i] == 0.0) {
+                     if (w != 0.0) {
+                        H[i][n] = -r / w;
+                     } else {
+                        H[i][n] = -r / (eps * norm);
+                     }
+   
+                  // Solve real equations
+   
+                  } else {
+                     x = H[i][i+1];
+                     y = H[i+1][i];
+                     q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
+                     t = (x * s - z * r) / q;
+                     H[i][n] = t;
+                     if (Math.abs(x) > Math.abs(z)) {
+                        H[i+1][n] = (-r - w * t) / x;
+                     } else {
+                        H[i+1][n] = (-s - y * t) / z;
+                     }
+                  }
+   
+                  // Overflow control
+   
+                  t = Math.abs(H[i][n]);
+                  if ((eps * t) * t > 1) {
+                     for (int j = i; j <= n; j++) {
+                        H[j][n] = H[j][n] / t;
+                     }
+                  }
+               }
+            }
+   
+         // Complex vector
+   
+         } else if (q < 0) {
+            int l = n-1;
+
+            // Last vector component imaginary so matrix is triangular
+   
+            if (Math.abs(H[n][n-1]) > Math.abs(H[n-1][n])) {
+               H[n-1][n-1] = q / H[n][n-1];
+               H[n-1][n] = -(H[n][n] - p) / H[n][n-1];
+            } else {
+               cdiv(0.0,-H[n-1][n],H[n-1][n-1]-p,q);
+               H[n-1][n-1] = cdivr;
+               H[n-1][n] = cdivi;
+            }
+            H[n][n-1] = 0.0;
+            H[n][n] = 1.0;
+            for (int i = n-2; i >= 0; i--) {
+               double ra,sa,vr,vi;
+               ra = 0.0;
+               sa = 0.0;
+               for (int j = l; j <= n; j++) {
+                  ra = ra + H[i][j] * H[j][n-1];
+                  sa = sa + H[i][j] * H[j][n];
+               }
+               w = H[i][i] - p;
+   
+               if (e[i] < 0.0) {
+                  z = w;
+                  r = ra;
+                  s = sa;
+               } else {
+                  l = i;
+                  if (e[i] == 0) {
+                     cdiv(-ra,-sa,w,q);
+                     H[i][n-1] = cdivr;
+                     H[i][n] = cdivi;
+                  } else {
+   
+                     // Solve complex equations
+   
+                     x = H[i][i+1];
+                     y = H[i+1][i];
+                     vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
+                     vi = (d[i] - p) * 2.0 * q;
+                     if (vr == 0.0 & vi == 0.0) {
+                        vr = eps * norm * (Math.abs(w) + Math.abs(q) +
+                        Math.abs(x) + Math.abs(y) + Math.abs(z));
+                     }
+                     cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
+                     H[i][n-1] = cdivr;
+                     H[i][n] = cdivi;
+                     if (Math.abs(x) > (Math.abs(z) + Math.abs(q))) {
+                        H[i+1][n-1] = (-ra - w * H[i][n-1] + q * H[i][n]) / x;
+                        H[i+1][n] = (-sa - w * H[i][n] - q * H[i][n-1]) / x;
+                     } else {
+                        cdiv(-r-y*H[i][n-1],-s-y*H[i][n],z,q);
+                        H[i+1][n-1] = cdivr;
+                        H[i+1][n] = cdivi;
+                     }
+                  }
+   
+                  // Overflow control
+
+                  t = Math.max(Math.abs(H[i][n-1]),Math.abs(H[i][n]));
+                  if ((eps * t) * t > 1) {
+                     for (int j = i; j <= n; j++) {
+                        H[j][n-1] = H[j][n-1] / t;
+                        H[j][n] = H[j][n] / t;
+                     }
+                  }
+               }
+            }
+         }
+      }
+   
+      // Vectors of isolated roots
+   
+      for (int i = 0; i < nn; i++) {
+         if (i < low | i > high) {
+            for (int j = i; j < nn; j++) {
+               V[i][j] = H[i][j];
+            }
+         }
+      }
+   
+      // Back transformation to get eigenvectors of original matrix
+   
+      for (int j = nn-1; j >= low; j--) {
+         for (int i = low; i <= high; i++) {
+            z = 0.0;
+            for (int k = low; k <= Math.min(j,high); k++) {
+               z = z + V[i][k] * H[k][j];
+            }
+            V[i][j] = z;
+         }
+      }
+   }
+
+
+/* ------------------------
+   Constructor
+ * ------------------------ */
+
+   /** Check for symmetry, then construct the eigenvalue decomposition
+   @param A    Square matrix
+   @return     Structure to access D and V.
+   */
+
+   public EigenvalueDecomposition (Matrix Arg) {
+      double[][] A = Arg.getArray();
+      n = Arg.getColumnDimension();
+      V = new double[n][n];
+      d = new double[n];
+      e = new double[n];
+
+      issymmetric = true;
+      for (int j = 0; (j < n) & issymmetric; j++) {
+         for (int i = 0; (i < n) & issymmetric; i++) {
+            issymmetric = (A[i][j] == A[j][i]);
+         }
+      }
+
+      if (issymmetric) {
+         for (int i = 0; i < n; i++) {
+            for (int j = 0; j < n; j++) {
+               V[i][j] = A[i][j];
+            }
+         }
+   
+         // Tridiagonalize.
+         tred2();
+   
+         // Diagonalize.
+         tql2();
+
+      } else {
+         H = new double[n][n];
+         ort = new double[n];
+         
+         for (int j = 0; j < n; j++) {
+            for (int i = 0; i < n; i++) {
+               H[i][j] = A[i][j];
+            }
+         }
+   
+         // Reduce to Hessenberg form.
+         orthes();
+   
+         // Reduce Hessenberg to real Schur form.
+         hqr2();
+      }
+   }
+
+/* ------------------------
+   Public Methods
+ * ------------------------ */
+
+   /** Return the eigenvector matrix
+   @return     V
+   */
+
+   public Matrix getV () {
+      return new Matrix(V,n,n);
+   }
+
+   /** Return the real parts of the eigenvalues
+   @return     real(diag(D))
+   */
+
+   public double[] getRealEigenvalues () {
+      return d;
+   }
+
+   /** Return the imaginary parts of the eigenvalues
+   @return     imag(diag(D))
+   */
+
+   public double[] getImagEigenvalues () {
+      return e;
+   }
+
+   /** Return the block diagonal eigenvalue matrix
+   @return     D
+   */
+
+   public Matrix getD () {
+      Matrix X = new Matrix(n,n);
+      double[][] D = X.getArray();
+      for (int i = 0; i < n; i++) {
+         for (int j = 0; j < n; j++) {
+            D[i][j] = 0.0;
+         }
+         D[i][i] = d[i];
+         if (e[i] > 0) {
+            D[i][i+1] = e[i];
+         } else if (e[i] < 0) {
+            D[i][i-1] = e[i];
+         }
+      }
+      return X;
+   }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/EigenvalueDecomposition.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseMatrix.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseMatrix.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseMatrix.java	(revision 481)
@@ -0,0 +1,271 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package JamaPlus;
+
+import JamaPlus.SparseSVD.SparseSVDException;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Bernard Victorri
+ */
+public class SparseMatrix {
+  private int m, n, nnz;
+  private int[] colpts, rowinds;
+  private double[] vals;
+  private double[] tempRow;  // stockage temporaire pour certains calculs (opb)
+
+  public SparseMatrix(int m, int n) { // null matrix
+    this.m = m;
+    this.n = n;
+    nnz = 0;
+    colpts = new int[n+1];
+    rowinds = new int[0];
+    vals = new double[0];
+  }
+
+   private static class Triple implements Comparable<Triple> {
+    int row;
+    int col;
+    double val;
+
+    private Triple(int row, int col, double val) {
+      this.row = row;
+      this.col = col;
+      this.val = val;
+    }
+    private Triple(int row, int col) {
+      this.row = row;
+      this.col = col;
+    }
+    public int compareTo(Triple t) {
+      int res = col - t.col;
+      if(res==0) res = row - t.row;
+      return res;
+    }
+  }
+
+ public SparseMatrix(int m, int n, ArrayList<Integer> rows, ArrayList<Integer> cols,
+          ArrayList<Double> values) {
+    this.m = m;
+    this.n = n;
+    nnz = rows.size();
+    if (nnz!=cols.size()||nnz!=rows.size())
+      throw new ArrayIndexOutOfBoundsException(
+              "Size of lines, cols and values don't agree");
+    colpts = new int[n+1];
+    rowinds = new int[nnz];
+    vals = new double[nnz];
+    Triple[] triples = new Triple[nnz];
+    for(int i=0; i<nnz; i++) 
+     triples[i] = new Triple(rows.get(i), cols.get(i), values.get(i));    
+    Arrays.sort(triples);
+    colpts[0] = 0;
+    int c = 0;
+    for(int i=0; i<nnz; i++) {
+      if(i>0 && triples[i].row == triples[i-1].row && triples[i].col == triples[i-1].col) 
+        throw new ArrayIndexOutOfBoundsException(
+              "Two values with same row and column numbers");
+      while(c<triples[i].col) colpts[++c] = i;
+      rowinds[i] = triples[i].row;
+      vals[i] = triples[i].val;
+    }
+    while(c<n) colpts[++c] = nnz;
+  }
+
+public SparseMatrix(int m, int n, ArrayList<Integer> rows, ArrayList<Integer> cols,
+          double value) {
+    this.m = m;
+    this.n = n;
+    nnz = rows.size();
+    if (nnz!=cols.size()||nnz!=rows.size())
+      throw new ArrayIndexOutOfBoundsException(
+              "Size of lines, cols and values don't agree");
+    colpts = new int[n+1];
+    rowinds = new int[nnz];
+        vals = new double[nnz];
+    Triple[] triples = new Triple[nnz];
+    for(int i=0; i<nnz; i++) 
+     triples[i] = new Triple(rows.get(i), cols.get(i));    
+    Arrays.sort(triples);
+    colpts[0] = 0;
+    int c = 0;
+    for(int i=0; i<nnz; i++) {
+      if(i>0 && triples[i].row == triples[i-1].row && triples[i].col == triples[i-1].col) 
+        throw new ArrayIndexOutOfBoundsException(
+              "Two values with same row and column numbers");
+      while(c<triples[i].col) colpts[++c] = i;
+      rowinds[i] = triples[i].row;
+      vals[i] = value;
+    }
+    while(c<n) colpts[++c] = nnz;
+  }
+
+  private SparseMatrix(int m, int n, int nnz, int[] colpts, int[] rowinds, double[] vals) {
+    this.m = m;
+    this.n = n;
+    this.nnz = nnz;
+    this.colpts = colpts;
+    this.rowinds = rowinds;
+    this.vals = vals;
+  }
+
+  public SparseMatrix(Matrix mat) {  // convert a dense matrix
+    m = mat.getRowDimension();
+    n = mat.getColumnDimension();
+    long nbval = mat.getNumberNonZeroValues();
+    if (nbval>Integer.MAX_VALUE) throw new ArrayIndexOutOfBoundsException(
+              "Number of non-zero values exceeds 32 bits integer");
+    nnz = (int) nbval;
+    colpts = new int[n+1];
+    rowinds = new int[nnz];
+    vals = new double[nnz];
+    int nval = 0;
+    for (int j = 0; j<n; j++) {
+      colpts[j] = nval;
+      for (int i = 0; i<m; i++) if (mat.get(i, j)!=0) {
+          rowinds[nval] = i;
+          vals[nval++] = mat.get(i, j);
+        }
+    }
+    colpts[n] = nnz;
+  }
+
+  public SparseMatrix copy() {
+    int[] colpts1 = new int[n+1];
+    int[] rowinds1 = new int[nnz];
+    double[] vals1 = new double[nnz];
+    System.arraycopy(colpts, 0, colpts1, 0, n+1);
+    System.arraycopy(rowinds, 0, rowinds1, 0, nnz);
+    System.arraycopy(vals, 0, vals1, 0, nnz);
+    return new SparseMatrix(m, n, nnz, colpts1, rowinds1, vals1);
+  }
+
+  public int getRowDimension() {
+    return m;
+  }
+
+  public int getColumnDimension() {
+    return n;
+  }
+
+  public double get(int i, int j) {
+    try {
+      for (int nval = colpts[j]; nval<colpts[j+1]; nval++)
+        if (rowinds[nval]==i) return vals[nval];
+      return 0;
+    } catch (ArrayIndexOutOfBoundsException ex) {
+      throw new ArrayIndexOutOfBoundsException("Sparse matrix : "
+              +ex.getLocalizedMessage());
+    }
+  }
+
+  public SparseMatrix transpose() {
+    int[] colpts1 = new int[m+1];
+    int[] rowinds1 = new int[nnz];
+    double[] vals1 = new double[nnz];
+    for (int v = 0; v<nnz; v++) colpts1[rowinds[v]]++;  // nnz in each row
+    colpts1[m] = nnz-colpts1[m-1];
+    for (int r = m-1; r>0; r--)
+      colpts1[r] = colpts1[r+1]-colpts1[r-1]; // starting point of the previous row
+    colpts1[0] = 0;
+    int i = 0;
+    for (int c = 0; c<n; c++) while (i<colpts[c+1]) {
+        int j = colpts1[rowinds[i]+1]++;  // j : index of the value in the new vectors
+        rowinds1[j] = c;
+        vals1[j] = vals[i++];
+      }
+    return new SparseMatrix(n, m, nnz, colpts1, rowinds1, vals1);
+  }
+
+  public void nulColumnSuppression() {
+    ArrayList<Integer> colpts1 = new ArrayList<Integer>();
+    colpts1.add(0);
+    for (int i = 0; i<n; i++) if (colpts[i+1]>colpts[i])
+        colpts1.add(colpts[i+1]);
+    n = colpts1.size()-1;
+    colpts = new int[n+1];
+    for (int i = 0; i<=n; i++) colpts[i] = colpts1.get(i);
+  }
+
+  public double elementSum() {
+    double s = 0;
+    for (int i = 0; i<nnz; i++) s += vals[i];
+
+    return s;
+  }
+
+  public Matrix lineSum() {
+    double[] S = new double[m];
+    for (int i = 0; i<nnz; i++) S[rowinds[i]] += vals[i];
+
+    return new Matrix(S, m);
+  }
+
+  public Matrix columnSum() {
+    double[] S = new double[n];
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        S[i] += vals[j];
+
+    return new Matrix(S, 1);
+  }
+
+  public SparseMatrix timesEquals(double s) {
+    for (int i = 0; i<nnz; i++) {
+      vals[i] *= s;
+    }
+    return this;
+  }
+
+  public SparseMatrix firstColumnTimesEqual(Matrix B) {
+    double[][] A = B.getArray();
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        vals[j] *= A[rowinds[j]][0];
+    return this;
+  }
+
+  public SparseMatrix firstLineTimesEqual(Matrix B) {
+    double[][] A = B.getArray();
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        vals[j] *= A[0][i];
+    return this;
+  }
+
+  public void opa(double x[], double y[]) {
+    // Computes y = Ax (x et y : length n)
+    Arrays.fill(y, 0);
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        y[rowinds[j]] += vals[j]*x[i];
+  }
+
+  public void opb(double x[], double y[]) {
+    // Computes y = A'Ax (x et y : length n)
+    if (tempRow==null) tempRow = new double[m];
+    else Arrays.fill(tempRow, 0);
+    Arrays.fill(y, 0);
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        tempRow[rowinds[j]] += vals[j]*x[i];
+    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
+        y[i] += vals[j]*tempRow[rowinds[j]];
+  }
+
+  public SparseSVD svd(int dim) throws SparseSVD.SparseSVDException {
+    return new SparseSVD(this, dim);
+  }
+
+  /** Analyse factorielle de correspondances
+  @return     Analyse factorielle de correspondances
+  @see Analyse factorielle de correspondances
+   */
+  public SparseAFC afc() {
+    try {
+      return new SparseAFC(this);
+    } catch (SparseSVDException ex) {
+      return null;
+    }
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/SparseMatrix.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src matt/JamaPlus/Matrix.java
===================================================================
--- tmp/org.txm.analec.rcp/src matt/JamaPlus/Matrix.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src matt/JamaPlus/Matrix.java	(revision 481)
@@ -0,0 +1,1221 @@
+package JamaPlus;
+
+import java.text.NumberFormat;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+import java.io.PrintWriter;
+import java.io.BufferedReader;
+import java.io.StreamTokenizer;
+import JamaPlus.util.*;
+import java.util.ArrayList;
+
+/**
+Jama = Java Matrix class.
+<P>
+The Java Matrix Class provides the fundamental operations of numerical
+linear algebra.  Various constructors create Matrices from two dimensional
+arrays of double precision floating point numbers.  Various "gets" and
+"sets" provide access to submatrices and matrix elements.  Several methods 
+implement basic matrix arithmetic, including matrix addition and
+multiplication, matrix norms, and element-by-element array operations.
+Methods for reading and printing matrices are also included.  All the
+operations in this version of the Matrix Class involve real matrices.
+Complex matrices may be handled in a future version.
+<P>
+Five fundamental matrix decompositions, which consist of pairs or triples
+of matrices, permutation vectors, and the like, produce results in five
+decomposition classes.  These decompositions are accessed by the Matrix
+class to compute solutions of simultaneous linear equations, determinants,
+inverses and other matrix functions.  The five decompositions are:
+<P><UL>
+<LI>Cholesky Decomposition of symmetric, positive definite matrices.
+<LI>LU Decomposition of rectangular matrices.
+<LI>QR Decomposition of rectangular matrices.
+<LI>Singular Value Decomposition of rectangular matrices.
+<LI>Eigenvalue Decomposition of both symmetric and nonsymmetric square matrices.
+</UL>
+<DL>
+<DT><B>Example of use:</B></DT>
+<P>
+<DD>Solve a linear system A x = b and compute the residual norm, ||b - A x||.
+<P><PRE>
+double[][] vals = {{1.,2.,3},{4.,5.,6.},{7.,8.,10.}};
+Matrix A = new Matrix(vals);
+Matrix b = Matrix.random(3,1);
+Matrix x = A.solve(b);
+Matrix r = A.times(x).minus(b);
+double rnorm = r.normInf();
+</PRE></DD>
+</DL>
+
+@author The MathWorks, Inc. and the National Institute of Standards and Technology.
+@version 5 August 1998
+ */
+public class Matrix implements Cloneable, java.io.Serializable {
+
+  /* ------------------------
+  Class variables
+   * ------------------------ */
+  /** Array for internal storage of elements.
+  @serial internal array storage.
+   */
+  private double[][] A;
+  /** Row and column dimensions.
+  @serial row dimension.
+  @serial column dimension.
+   */
+  private int m, n;
+
+  /* ------------------------
+  Constructors
+   * ------------------------ */
+  /** Construct an m-by-n matrix of zeros. 
+  @param m    Number of rows.
+  @param n    Number of colums.
+   */
+  public Matrix(int m, int n) {
+    this.m = m;
+    this.n = n;
+    A = new double[m][n];
+  }
+
+  /** Construct an m-by-n constant matrix.
+  @param m    Number of rows.
+  @param n    Number of colums.
+  @param s    Fill the matrix with this scalar value.
+   */
+  public Matrix(int m, int n, double s) {
+    this.m = m;
+    this.n = n;
+    A = new double[m][n];
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = s;
+      }
+    }
+  }
+
+  /** Construct a matrix from a 2-D array.
+  @param A    Two-dimensional array of doubles.
+  @exception  IllegalArgumentException All rows must have the same length
+  @see        #constructWithCopy
+   */
+  public Matrix(double[][] A) {
+    m = A.length;
+    n = A[0].length;
+    for (int i = 0; i < m; i++) {
+      if (A[i].length != n) {
+        throw new IllegalArgumentException("All rows must have the same length.");
+      }
+    }
+    this.A = A;
+  }
+
+  /** Construct a matrix quickly without checking arguments.
+  @param A    Two-dimensional array of doubles.
+  @param m    Number of rows.
+  @param n    Number of colums.
+   */
+  public Matrix(double[][] A, int m, int n) {
+    this.A = A;
+    this.m = m;
+    this.n = n;
+  }
+
+  /** Construct a matrix from a one-dimensional packed array
+  @param vals One-dimensional array of doubles, packed by columns (ala Fortran).
+  @param m    Number of rows.
+  @exception  IllegalArgumentException Array length must be a multiple of m.
+   */
+  public Matrix(double vals[], int m) {
+    this.m = m;
+    n = (m != 0 ? vals.length / m : 0);
+    if (m * n != vals.length) {
+      throw new IllegalArgumentException("Array length must be a multiple of m.");
+    }
+    A = new double[m][n];
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = vals[i + j * m];
+      }
+    }
+  }
+
+  /* ------------------------
+  Public Methods
+   * ------------------------ */
+  /** Construct a matrix from a copy of a 2-D array.
+  @param A    Two-dimensional array of doubles.
+  @exception  IllegalArgumentException All rows must have the same length
+   */
+  public static Matrix constructWithCopy(double[][] A) {
+    int m = A.length;
+    int n = A[0].length;
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      if (A[i].length != n) {
+        throw new IllegalArgumentException("All rows must have the same length.");
+      }
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** Make a deep copy of a matrix
+   */
+  public Matrix copy() {
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      System.arraycopy(A[i], 0, C[i], 0, n);
+    }
+    return X;
+  }
+
+  /** Clone the Matrix object.
+   */
+  public Object clone() {
+    return this.copy();
+  }
+
+  /** Access the internal two-dimensional array.
+  @return     Pointer to the two-dimensional array of matrix elements.
+   */
+  public double[][] getArray() {
+    return A;
+  }
+
+  /** Copy the internal two-dimensional array.
+  @return     Two-dimensional array copy of matrix elements.
+   */
+  public double[][] getArrayCopy() {
+    double[][] C = new double[m][n];
+    for (int i = 0; i < m; i++) {
+      System.arraycopy(A[i], 0, C[i], 0, n);
+    }
+    return C;
+  }
+
+  /** Make a one-dimensional column packed copy of the internal array.
+  @return     Matrix elements packed in a one-dimensional array by columns.
+   */
+  public double[] getColumnPackedCopy() {
+    double[] vals = new double[m * n];
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        vals[i + j * m] = A[i][j];
+      }
+    }
+    return vals;
+  }
+
+  /** Make a one-dimensional row packed copy of the internal array.
+  @return     Matrix elements packed in a one-dimensional array by rows.
+   */
+  public double[] getRowPackedCopy() {
+    double[] vals = new double[m * n];
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        vals[i * n + j] = A[i][j];
+      }
+    }
+    return vals;
+  }
+
+  /** Get row dimension.
+  @return     m, the number of rows.
+   */
+  public int getRowDimension() {
+    return m;
+  }
+
+  /** Get column dimension.
+  @return     n, the number of columns.
+   */
+  public int getColumnDimension() {
+    return n;
+  }
+
+  /** Get a single element.
+  @param i    Row index.
+  @param j    Column index.
+  @return     A(i,j)
+  @exception  ArrayIndexOutOfBoundsException
+   */
+  public double get(int i, int j) {
+    return A[i][j];
+  }
+
+  /** Get a submatrix.
+  @param i0   Initial row index
+  @param i1   Final row index
+  @param j0   Initial column index
+  @param j1   Final column index
+  @return     A(i0:i1,j0:j1)
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public Matrix getMatrix(int i0, int i1, int j0, int j1) {
+    Matrix X = new Matrix(i1 - i0 + 1, j1 - j0 + 1);
+    double[][] B = X.getArray();
+    try {
+      for (int i = i0; i <= i1; i++) {
+        for (int j = j0; j <= j1; j++) {
+          B[i - i0][j - j0] = A[i][j];
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+    return X;
+  }
+
+  /** Get a submatrix.
+  @param r    Array of row indices.
+  @param c    Array of column indices.
+  @return     A(r(:),c(:))
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public Matrix getMatrix(int[] r, int[] c) {
+    Matrix X = new Matrix(r.length, c.length);
+    double[][] B = X.getArray();
+    try {
+      for (int i = 0; i < r.length; i++) {
+        for (int j = 0; j < c.length; j++) {
+          B[i][j] = A[r[i]][c[j]];
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+    return X;
+  }
+
+  /** Get a submatrix.
+  @param i0   Initial row index
+  @param i1   Final row index
+  @param c    Array of column indices.
+  @return     A(i0:i1,c(:))
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public Matrix getMatrix(int i0, int i1, int[] c) {
+    Matrix X = new Matrix(i1 - i0 + 1, c.length);
+    double[][] B = X.getArray();
+    try {
+      for (int i = i0; i <= i1; i++) {
+        for (int j = 0; j < c.length; j++) {
+          B[i - i0][j] = A[i][c[j]];
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+    return X;
+  }
+
+  /** Get a submatrix.
+  @param r    Array of row indices.
+  @param i0   Initial column index
+  @param i1   Final column index
+  @return     A(r(:),j0:j1)
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public Matrix getMatrix(int[] r, int j0, int j1) {
+    Matrix X = new Matrix(r.length, j1 - j0 + 1);
+    double[][] B = X.getArray();
+    try {
+      for (int i = 0; i < r.length; i++) {
+        for (int j = j0; j <= j1; j++) {
+          B[i][j - j0] = A[r[i]][j];
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+    return X;
+  }
+
+  /** Set a single element.
+  @param i    Row index.
+  @param j    Column index.
+  @param s    A(i,j).
+  @exception  ArrayIndexOutOfBoundsException
+   */
+  public void set(int i, int j, double s) {
+    A[i][j] = s;
+  }
+
+  /** Set a submatrix.
+  @param i0   Initial row index
+  @param i1   Final row index
+  @param j0   Initial column index
+  @param j1   Final column index
+  @param X    A(i0:i1,j0:j1)
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public void setMatrix(int i0, int i1, int j0, int j1, Matrix X) {
+    try {
+      for (int i = i0; i <= i1; i++) {
+        for (int j = j0; j <= j1; j++) {
+          A[i][j] = X.get(i - i0, j - j0);
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+  }
+
+  /** Set a submatrix.
+  @param r    Array of row indices.
+  @param c    Array of column indices.
+  @param X    A(r(:),c(:))
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public void setMatrix(int[] r, int[] c, Matrix X) {
+    try {
+      for (int i = 0; i < r.length; i++) {
+        for (int j = 0; j < c.length; j++) {
+          A[r[i]][c[j]] = X.get(i, j);
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+  }
+
+  /** Set a submatrix.
+  @param r    Array of row indices.
+  @param j0   Initial column index
+  @param j1   Final column index
+  @param X    A(r(:),j0:j1)
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public void setMatrix(int[] r, int j0, int j1, Matrix X) {
+    try {
+      for (int i = 0; i < r.length; i++) {
+        for (int j = j0; j <= j1; j++) {
+          A[r[i]][j] = X.get(i, j - j0);
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+  }
+
+  /** Set a submatrix.
+  @param i0   Initial row index
+  @param i1   Final row index
+  @param c    Array of column indices.
+  @param X    A(i0:i1,c(:))
+  @exception  ArrayIndexOutOfBoundsException Submatrix indices
+   */
+  public void setMatrix(int i0, int i1, int[] c, Matrix X) {
+    try {
+      for (int i = i0; i <= i1; i++) {
+        for (int j = 0; j < c.length; j++) {
+          A[i][c[j]] = X.get(i - i0, j);
+        }
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
+    }
+  }
+
+  /** Matrix transpose.
+  @return    A'
+   */
+  public Matrix transpose() {
+    Matrix X = new Matrix(n, m);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[j][i] = A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** One norm
+  @return    maximum column sum.
+   */
+  public double norm1() {
+    double f = 0;
+    for (int j = 0; j < n; j++) {
+      double s = 0;
+      for (int i = 0; i < m; i++) {
+        s += Math.abs(A[i][j]);
+      }
+      f = Math.max(f, s);
+    }
+    return f;
+  }
+
+  /** Two norm
+  @return    maximum singular value.
+   */
+  public double norm2() {
+    return (new SingularValueDecomposition(this).norm2());
+  }
+
+  /** Infinity norm
+  @return    maximum row sum.
+   */
+  public double normInf() {
+    double f = 0;
+    for (int i = 0; i < m; i++) {
+      double s = 0;
+      for (int j = 0; j < n; j++) {
+        s += Math.abs(A[i][j]);
+      }
+      f = Math.max(f, s);
+    }
+    return f;
+  }
+
+  /** Frobenius norm
+  @return    sqrt of sum of squares of all elements.
+   */
+  public double normF() {
+    double f = 0;
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        f = Math.hypot(f, A[i][j]);
+      }
+    }
+    return f;
+  }
+
+  /**  Unary minus
+  @return    -A
+   */
+  public Matrix uminus() {
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = -A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** C = A + B
+  @param B    another matrix
+  @return     A + B
+   */
+  public Matrix plus(Matrix B) {
+    checkMatrixDimensions(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] + B.A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** A = A + B
+  @param B    another matrix
+  @return     A + B
+   */
+  public Matrix plusEquals(Matrix B) {
+    checkMatrixDimensions(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = A[i][j] + B.A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** C = A - B
+  @param B    another matrix
+  @return     A - B
+   */
+  public Matrix minus(Matrix B) {
+    checkMatrixDimensions(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] - B.A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** A = A - B
+  @param B    another matrix
+  @return     A - B
+   */
+  public Matrix minusEquals(Matrix B) {
+    checkMatrixDimensions(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = A[i][j] - B.A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** Element-by-element multiplication, C = A.*B
+  @param B    another matrix
+  @return     A.*B
+   */
+  public Matrix arrayTimes(Matrix B) {
+    checkMatrixDimensions(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] * B.A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** Element-by-element multiplication in place, A = A.*B
+  @param B    another matrix
+  @return     A.*B
+   */
+  public Matrix arrayTimesEquals(Matrix B) {
+    checkMatrixDimensions(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = A[i][j] * B.A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** Element-by-element right division, C = A./B
+  @param B    another matrix
+  @return     A./B
+   */
+  public Matrix arrayRightDivide(Matrix B) {
+    checkMatrixDimensions(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] / B.A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** Element-by-element right division in place, A = A./B
+  @param B    another matrix
+  @return     A./B
+   */
+  public Matrix arrayRightDivideEquals(Matrix B) {
+    checkMatrixDimensions(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = A[i][j] / B.A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** Element-by-element left division, C = A.\B
+  @param B    another matrix
+  @return     A.\B
+   */
+  public Matrix arrayLeftDivide(Matrix B) {
+    checkMatrixDimensions(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = B.A[i][j] / A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** Element-by-element left division in place, A = A.\B
+  @param B    another matrix
+  @return     A.\B
+   */
+  public Matrix arrayLeftDivideEquals(Matrix B) {
+    checkMatrixDimensions(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = B.A[i][j] / A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** Multiply a matrix by a scalar, C = s*A
+  @param s    scalar
+  @return     s*A
+   */
+  public Matrix times(double s) {
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = s * A[i][j];
+      }
+    }
+    return X;
+  }
+
+  /** Multiply a matrix by a scalar in place, A = s*A
+  @param s    scalar
+  @return     replace A by s*A
+   */
+  public Matrix timesEquals(double s) {
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] = s * A[i][j];
+      }
+    }
+    return this;
+  }
+
+  /** Linear algebraic matrix multiplication, A * B
+  @param B    another matrix
+  @return     Matrix product, A * B
+  @exception  IllegalArgumentException Matrix inner dimensions must agree.
+   */
+  public Matrix times(Matrix B) {
+    if (B.m != n) {
+      throw new IllegalArgumentException("Matrix inner dimensions must agree.");
+    }
+    Matrix X = new Matrix(m, B.n);
+    double[][] C = X.getArray();
+    double[] Bcolj = new double[n];
+    for (int j = 0; j < B.n; j++) {
+      for (int k = 0; k < n; k++) {
+        Bcolj[k] = B.A[k][j];
+      }
+      for (int i = 0; i < m; i++) {
+        double[] Arowi = A[i];
+        double s = 0;
+        for (int k = 0; k < n; k++) {
+          s += Arowi[k] * Bcolj[k];
+        }
+        C[i][j] = s;
+      }
+    }
+    return X;
+  }
+
+  /** LU Decomposition
+  @return     LUDecomposition
+  @see LUDecomposition
+   */
+  public LUDecomposition lu() {
+    return new LUDecomposition(this);
+  }
+
+  /** QR Decomposition
+  @return     QRDecomposition
+  @see QRDecomposition
+   */
+  public QRDecomposition qr() {
+    return new QRDecomposition(this);
+  }
+
+  /** Cholesky Decomposition
+  @return     CholeskyDecomposition
+  @see CholeskyDecomposition
+   */
+  public CholeskyDecomposition chol() {
+    return new CholeskyDecomposition(this);
+  }
+
+  /** Singular Value Decomposition
+  @return     SingularValueDecomposition
+  @see SingularValueDecomposition
+   */
+  public SingularValueDecomposition svd() {
+    return new SingularValueDecomposition(this);
+  }
+
+  /** Eigenvalue Decomposition
+  @return     EigenvalueDecomposition
+  @see EigenvalueDecomposition
+   */
+  public EigenvalueDecomposition eig() {
+    return new EigenvalueDecomposition(this);
+  }
+
+  /** Solve A*X = B
+  @param B    right hand side
+  @return     solution if A is square, least squares solution otherwise
+   */
+  public Matrix solve(Matrix B) {
+    return (m == n ? (new LUDecomposition(this)).solve(B) : (new QRDecomposition(this)).solve(B));
+  }
+
+  /** Solve X*A = B, which is also A'*X' = B'
+  @param B    right hand side
+  @return     solution if A is square, least squares solution otherwise.
+   */
+  public Matrix solveTranspose(Matrix B) {
+    return transpose().solve(B.transpose());
+  }
+
+  /** Matrix inverse or pseudoinverse
+  @return     inverse(A) if A is square, pseudoinverse otherwise.
+   */
+  public Matrix inverse() {
+    return solve(identity(m, m));
+  }
+
+  /** Matrix determinant
+  @return     determinant
+   */
+  public double det() {
+    return new LUDecomposition(this).det();
+  }
+
+  /** Matrix rank
+  @return     effective numerical rank, obtained from SVD.
+   */
+  public int rank() {
+    return new SingularValueDecomposition(this).rank();
+  }
+
+  /** Matrix condition (2 norm)
+  @return     ratio of largest to smallest singular value.
+   */
+  public double cond() {
+    return new SingularValueDecomposition(this).cond();
+  }
+
+  /** Matrix trace.
+  @return     sum of the diagonal elements.
+   */
+  public double trace() {
+    double t = 0;
+    for (int i = 0; i < Math.min(m, n); i++) {
+      t += A[i][i];
+    }
+    return t;
+  }
+
+  /** Generate matrix with random elements
+  @param m    Number of rows.
+  @param n    Number of colums.
+  @return     An m-by-n matrix with uniformly distributed random elements.
+   */
+  public static Matrix random(int m, int n) {
+    Matrix A = new Matrix(m, n);
+    double[][] X = A.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        X[i][j] = Math.random();
+      }
+    }
+    return A;
+  }
+
+  /** Generate identity matrix
+  @param m    Number of rows.
+  @param n    Number of colums.
+  @return     An m-by-n matrix with ones on the diagonal and zeros elsewhere.
+   */
+  public static Matrix identity(int m, int n) {
+    Matrix A = new Matrix(m, n);
+    double[][] X = A.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        X[i][j] = (i == j ? 1.0 : 0.0);
+      }
+    }
+    return A;
+  }
+
+  /** Print the matrix to stdout.   Line the elements up in columns
+   * with a Fortran-like 'Fw.d' style format.
+  @param w    Column width.
+  @param d    Number of digits after the decimal.
+   */
+  public void print(int w, int d) {
+    print(new PrintWriter(System.out, true), w, d);
+  }
+
+  /** Print the matrix to the output stream.   Line the elements up in
+   * columns with a Fortran-like 'Fw.d' style format.
+  @param output Output stream.
+  @param w      Column width.
+  @param d      Number of digits after the decimal.
+   */
+  public void print(PrintWriter output, int w, int d) {
+    DecimalFormat format = new DecimalFormat();
+    format.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
+    format.setMinimumIntegerDigits(1);
+    format.setMaximumFractionDigits(d);
+    format.setMinimumFractionDigits(d);
+    format.setGroupingUsed(false);
+    print(output, format, w + 2);
+  }
+
+  /** Print the matrix to stdout.  Line the elements up in columns.
+   * Use the format object, and right justify within columns of width
+   * characters.
+   * Note that is the matrix is to be read back in, you probably will want
+   * to use a NumberFormat that is set to US Locale.
+  @param format A  Formatting object for individual elements.
+  @param width     Field width for each column.
+  @see java.text.DecimalFormat#setDecimalFormatSymbols
+   */
+  public void print(NumberFormat format, int width) {
+    print(new PrintWriter(System.out, true), format, width);
+  }
+
+  // DecimalFormat is a little disappointing coming from Fortran or C's printf.
+  // Since it doesn't pad on the left, the elements will come out different
+  // widths.  Consequently, we'll pass the desired column width in as an
+  // argument and do the extra padding ourselves.
+  /** Print the matrix to the output stream.  Line the elements up in columns.
+   * Use the format object, and right justify within columns of width
+   * characters.
+   * Note that is the matrix is to be read back in, you probably will want
+   * to use a NumberFormat that is set to US Locale.
+  @param output the output stream.
+  @param format A formatting object to format the matrix elements 
+  @param width  Column width.
+  @see java.text.DecimalFormat#setDecimalFormatSymbols
+   */
+  public void print(PrintWriter output, NumberFormat format, int width) {
+    output.println();  // start on new line.
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        String s = format.format(A[i][j]); // format the number
+        int padding = Math.max(1, width - s.length()); // At _least_ 1 space
+        for (int k = 0; k < padding; k++) {
+          output.print(' ');
+        }
+        output.print(s);
+      }
+      output.println();
+    }
+    output.println();   // end with blank line.
+  }
+
+  /** Read a matrix from a stream.  The format is the same the print method,
+   * so printed matrices can be read back in (provided they were printed using
+   * US Locale).  Elements are separated by
+   * whitespace, all the elements for each row appear on a single line,
+   * the last row is followed by a blank line.
+  @param input the input stream.
+   */
+  @SuppressWarnings("unchecked")
+  public static Matrix read(BufferedReader input) throws java.io.IOException {
+    StreamTokenizer tokenizer = new StreamTokenizer(input);
+
+    // Although StreamTokenizer will parse numbers, it doesn't recognize
+    // scientific notation (E or D); however, Double.valueOf does.
+    // The strategy here is to disable StreamTokenizer's number parsing.
+    // We'll only get whitespace delimited words, EOL's and EOF's.
+    // These words should all be numbers, for Double.valueOf to parse.
+
+    tokenizer.resetSyntax();
+    tokenizer.wordChars(0, 255);
+    tokenizer.whitespaceChars(0, ' ');
+    tokenizer.eolIsSignificant(true);
+    java.util.Vector v = new java.util.Vector();
+
+    // Ignore initial empty lines
+    while (tokenizer.nextToken() == StreamTokenizer.TT_EOL);
+    if (tokenizer.ttype == StreamTokenizer.TT_EOF) {
+      throw new java.io.IOException("Unexpected EOF on matrix read.");
+    }
+    do {
+      v.addElement(Double.valueOf(tokenizer.sval)); // Read & store 1st row.
+    } while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
+
+    int n = v.size();  // Now we've got the number of columns!
+    double row[] = new double[n];
+    for (int j = 0; j < n; j++) // extract the elements of the 1st row.
+    {
+      row[j] = ((Double) v.elementAt(j)).doubleValue();
+    }
+    v.removeAllElements();
+    v.addElement(row);  // Start storing rows instead of columns.
+    while (tokenizer.nextToken() == StreamTokenizer.TT_WORD) {
+      // While non-empty lines
+      v.addElement(row = new double[n]);
+      int j = 0;
+      do {
+        if (j >= n) {
+          throw new java.io.IOException("Row " + v.size() + " is too long.");
+        }
+        row[j++] = Double.valueOf(tokenizer.sval).doubleValue();
+      } while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
+      if (j < n) {
+        throw new java.io.IOException("Row " + v.size() + " is too short.");
+      }
+    }
+    int m = v.size();  // Now we've got the number of rows.
+    double[][] A = new double[m][];
+    v.copyInto(A);  // copy the rows out of the vector
+    return new Matrix(A);
+  }
+
+
+  /* ------------------------
+  Private Methods
+   * ------------------------ */
+  /** Check if size(A) == size(B) **/
+  private void checkMatrixDimensions(Matrix B) {
+    if (B.m != m || B.n != n) {
+      throw new IllegalArgumentException("Matrix dimensions must agree.");
+    }
+  }
+
+  /* ---------------------------------
+  Quelques méthodes supplémentaires
+   * ---------------------------------*/
+  private void checkLineDimension(Matrix B) {
+    if (B.m != m) {
+      throw new IllegalArgumentException("Matrix line dimension must agree.");
+    }
+  }
+
+  private void checkColumnDimension(Matrix B) {
+    if (B.n != n) {
+      throw new IllegalArgumentException("Matrix column dimension must agree.");
+    }
+  }
+
+  public long getNumberNonZeroValues() {
+    long nnz = 0;
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        if (A[i][j] != 0) nnz++;
+      }
+    }
+    return nnz;
+  }
+
+  public double minColumn(int j) {
+    double min = Double.POSITIVE_INFINITY;
+    for (int i = 0; i < m; i++) {
+      min = Math.min(min, A[i][j]);
+    }
+    return min;
+  }
+
+  public double maxColumn(int j) {
+    double max = Double.NEGATIVE_INFINITY;
+    for (int i = 0; i < m; i++) {
+      max = Math.max(max, A[i][j]);
+    }
+    return max;
+  }
+
+  public double elementSum() {
+    double s = 0;
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        s += A[i][j];
+      }
+    }
+    return s;
+  }
+
+  public Matrix lineSum() {
+    Matrix S = new Matrix(m, 1);
+    double s[][] = S.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        s[i][0] += A[i][j];
+      }
+    }
+    return S;
+  }
+
+  public Matrix lineMean() {
+    Matrix S = new Matrix(m, 1);
+    double s[][] = S.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        s[i][0] += A[i][j];
+      }
+      s[i][0] /= n;
+    }
+    return S;
+  }
+
+  public Matrix columnSum() {
+    Matrix S = new Matrix(1, n);
+    double s[][] = S.getArray();
+    for (int j = 0; j < n; j++) {
+      for (int i = 0; i < m; i++) {
+        s[0][j] += A[i][j];
+      }
+    }
+    return S;
+  }
+
+  public Matrix columnMean() {
+    Matrix S = new Matrix(1, n);
+    double s[][] = S.getArray();
+    for (int j = 0; j < n; j++) {
+      for (int i = 0; i < m; i++) {
+        s[0][j] += A[i][j];
+      }
+      s[0][j] /= m;
+    }
+    return S;
+  }
+
+  public Matrix columnCovariance() {
+    double mean[] = new double[n];
+    for (int j = 0; j < n; j++) {
+      for (int i = 0; i < m; i++) {
+        mean[j] += A[i][j];
+      }
+      mean[j] /= m;
+    }
+    Matrix X = new Matrix(n, n);
+    double[][] B = X.getArray();
+    double[] Acolj = new double[m];
+    int coef = m > 2 ? m-1 : 1;
+    for (int j = 0; j < n; j++) {
+      for (int k = 0; k < m; k++) {
+        Acolj[k] = A[k][j] - mean[j];
+      }
+      for (int i = 0; i < n; i++) {
+        double[] Atrowi = new double[m];
+        for (int k = 0; k < m; k++) {
+          Atrowi[k] = A[k][i] - mean[i];
+        }
+        double s = 0;
+        for (int k = 0; k < m; k++) {
+          s += Atrowi[k] * Acolj[k];
+        }
+        B[i][j] = s / coef;
+      }
+    }
+    return X;
+  }
+
+public Matrix firstLineMinus(Matrix B) {
+     checkColumnDimension(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] - B.A[0][j];
+      }
+    }
+    return X;
+ 
+}
+  public Matrix nulColumnSuppression() {
+    ArrayList<Integer> cols = new ArrayList<Integer>();
+    for (int j = 0; j < n; j++) {
+      for (int i = 0; i < m; i++) {
+        if (A[i][j] != 0) {
+          cols.add(j);
+          break;
+        }
+      }
+    }
+    int[] c = new int[cols.size()];
+    for (int i = 0; i < c.length; i++) {
+      c[i] = cols.get(i);
+    }
+    return getMatrix(0, m - 1, c);
+  }
+
+  public Matrix arrayInverse() {
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = 1 / A[i][j];
+      }
+    }
+    return X;
+  }
+
+  public Matrix arraySqrt() {
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = Math.sqrt(A[i][j]);
+      }
+    }
+    return X;
+  }
+
+  public Matrix firstColumTimes(Matrix B) {
+    checkLineDimension(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+
+        C[i][j] = A[i][j] * B.A[i][0];
+      }
+    }
+    return X;
+  }
+
+  public Matrix firstColumnTimesEqual(Matrix B) {
+    checkLineDimension(B);
+    for (int i = 0; i < m; i++) {
+       for (int j = 0; j < n; j++) {
+
+        A[i][j] *= B.A[i][0];
+      }
+    }
+    return this;
+  }
+
+  public Matrix firstLineTimesEqual(Matrix B) {
+    checkColumnDimension(B);
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        A[i][j] *= B.A[0][j];
+      }
+    }
+    return this;
+  }
+
+  public Matrix firstLineTimes(Matrix B) {
+    checkColumnDimension(B);
+    Matrix X = new Matrix(m, n);
+    double[][] C = X.getArray();
+    for (int i = 0; i < m; i++) {
+      for (int j = 0; j < n; j++) {
+        C[i][j] = A[i][j] * B.A[0][j];
+      }
+    }
+    return X;
+  }
+
+  public void fixColumnSigns() {
+    for (int j = 0; j < n; j++) {
+      int i = 0;
+      while (i<m && A[i][j] == 0) i++;
+      if (i==m || A[i][j] > 0)  continue;
+      while (i < m) {
+        A[i][j] = -A[i][j];
+        i++;
+      }
+    }
+  }
+
+  /** Analyse factorielle de correspondances
+  @return     Analyse factorielle de correspondances
+  @see Analyse factorielle de correspondances
+   */
+  public AFC afc() {
+    return new AFC(this);
+  }
+}

Property changes on: tmp/org.txm.analec.rcp/src matt/JamaPlus/Matrix.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- tmp/org.txm.analec.rcp/.settings/org.eclipse.jdt.core.prefs	(revision 0)
+++ tmp/org.txm.analec.rcp/.settings/org.eclipse.jdt.core.prefs	(revision 481)
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7

Property changes on: tmp/org.txm.analec.rcp/.settings/org.eclipse.jdt.core.prefs
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/.classpath
===================================================================
--- tmp/org.txm.analec.rcp/.classpath	(revision 0)
+++ tmp/org.txm.analec.rcp/.classpath	(revision 481)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+		<accessrules>
+			<accessrule kind="accessible" pattern="**"/>
+		</accessrules>
+	</classpathentry>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="lib" path="libs/itext-pdfa-5.5.8.jar"/>
+	<classpathentry kind="lib" path="libs/itext-xtra-5.5.8.jar"/>
+	<classpathentry kind="lib" path="libs/jcommon-1.0.23.jar"/>
+	<classpathentry kind="lib" path="libs/jcommon-xml-1.0.23.jar"/>
+	<classpathentry kind="lib" path="libs/xmlworker-5.5.8.jar"/>
+	<classpathentry kind="lib" path="libs/itextpdf-5.5.4.jar"/>
+	<classpathentry kind="lib" path="libs/glazedlists_java15-1.9.0.jar"/>
+	<classpathentry exported="true" kind="con" path="GROOVY_DSL_SUPPORT"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Property changes on: tmp/org.txm.analec.rcp/.classpath
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/META-INF/MANIFEST.MF
===================================================================
--- tmp/org.txm.analec.rcp/META-INF/MANIFEST.MF	(revision 0)
+++ tmp/org.txm.analec.rcp/META-INF/MANIFEST.MF	(revision 481)
@@ -0,0 +1,37 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: AnalecRCP;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: analecrcp.Activator
+Require-Bundle: org.txm.concordance.core;bundle-version="1.0.0",
+ org.txm.concordance.rcp;bundle-version="1.0.0",
+ org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.jface,
+ org.eclipse.swt,
+ org.eclipse.core.expressions;bundle-version="3.4.600",
+ org.txm.libs.jfreechart;bundle-version="1.0.17",
+ org.txm.rcp;bundle-version="0.7.8",
+ org.txm.core;bundle-version="0.7.0",
+ org.txm.synopticeditor.rcp;bundle-version="1.0.0",
+ org.txm.searchengine.core;bundle-version="1.0.0",
+ org.txm.searchengine.cqp.core;bundle-version="1.1.0",
+ org.txm.statsengine.r.core;bundle-version="1.0.0",
+ org.txm.statsengine.r.rcp;bundle-version="1.0.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Export-Package: JamaPlus,
+ JamaPlus.util,
+ analecrcp,
+ org.txm.analec.commands,
+ visuAnalec,
+ visuAnalec.chaines,
+ visuAnalec.donnees,
+ visuAnalec.elements,
+ visuAnalec.fichiers,
+ visuAnalec.statistiques,
+ visuAnalec.texte,
+ visuAnalec.util,
+ visuAnalec.vue
+Bundle-Vendor: %Bundle-Vendor

Property changes on: tmp/org.txm.analec.rcp/META-INF/MANIFEST.MF
___________________________________________________________________
Added: svn:mime-type
   + text/plain

