Index: TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/views/corpora/CorporaView.java
===================================================================
--- TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/views/corpora/CorporaView.java	(revision 3946)
+++ TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/views/corpora/CorporaView.java	(revision 3947)
@@ -130,15 +130,8 @@
 	 */
 	// private static HashMap<Class, Class> managedDoubleClickClasses = new HashMap<Class, Class>();
 	
-	
 	public static HashMap<String, String> doubleClickInstalledCommands = new HashMap<>();
 	
-	
-	// public static HashMap<Class, Class> getManagedDoubleClickClasses() {
-	// return managedDoubleClickClasses;
-	// }
-	
-	
 	/**
 	 * Gets the single instance of CorporaView.
 	 *
@@ -157,6 +150,7 @@
 	}
 	
 	public TreeViewer getTreeViewer() {
+		
 		return treeViewer;
 	}
 	
@@ -492,6 +486,7 @@
 	 */
 	@Override
 	public void setFocus() {
+		
 		treeViewer.getControl().setFocus();
 	}
 	
@@ -501,6 +496,7 @@
 	 * @return
 	 */
 	public static Object getFirstSelectedObject() {
+		
 		CorporaView corporaView = getInstance();
 		if (corporaView != null) {
 			try {
@@ -521,6 +517,7 @@
 	 * @return
 	 */
 	public static List<?> getSelectedObjects() {
+		
 		CorporaView corporaView = getInstance();
 		if (corporaView != null) {
 			try {
@@ -585,6 +582,7 @@
 	 * Refresh the tree view.
 	 */
 	public static void refresh() {
+		
 		CorporaView corporaView = getInstance();
 		if (corporaView != null) {
 			corporaView.treeViewer.refresh();
@@ -602,28 +600,25 @@
 		corporaView.treeViewer.refresh();
 	}
 	
-	
-	
 	/**
 	 * Refreshes the specified result node in the tree view.
 	 * 
 	 * @param result
 	 */
 	public static void refreshObject(final TXMResult result) {
+		
 		Display.getDefault().syncExec(new Runnable() {
 			
 			@Override
 			public void run() {
 				
 				CorporaView corporaView = getInstance();
-				
 				corporaView.treeViewer.refresh();
 				
 				try {
 					CorporaView.expand(result.getParent());
 				}
-				catch (NullPointerException e) {
-				}
+				catch (NullPointerException e) { }
 			}
 		});
 	}
@@ -634,6 +629,7 @@
 	 * @param editor
 	 */
 	public static void refreshObject(TXMEditor editor) {
+		
 		refreshObject(editor.getResult());
 	}
 	
@@ -643,6 +639,7 @@
 	 * @param obj
 	 */
 	public static void expand(Object obj) {
+		
 		final CorporaView corporaView = getInstance();
 		if (obj != null) {
 			corporaView.treeViewer.expandToLevel(obj, 1);
@@ -654,6 +651,7 @@
 	 * @param obj
 	 */
 	public static void reveal(TXMResult obj) {
+		
 		final CorporaView corporaView = getInstance();
 		if (obj != null && corporaView != null) {
 			corporaView.treeViewer.reveal(obj);
@@ -666,6 +664,7 @@
 	 * @return
 	 */
 	public static boolean isActive() {
+		
 		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
 		if (window == null) {
 			return false;
Index: TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/commands/function/RefreshCorporaView.java
===================================================================
--- TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/commands/function/RefreshCorporaView.java	(revision 3946)
+++ TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/commands/function/RefreshCorporaView.java	(revision 3947)
@@ -5,6 +5,12 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.txm.rcp.views.corpora.CorporaView;
 
+/**
+ * Refresh the corpora view TreeViewer
+ * 
+ * @author mdecorde
+ *
+ */
 public class RefreshCorporaView extends AbstractHandler  {
 
 	@Override
Index: TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/editors/TXMEditor.java
===================================================================
--- TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/editors/TXMEditor.java	(revision 3946)
+++ TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/editors/TXMEditor.java	(revision 3947)
@@ -6,6 +6,7 @@
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -79,6 +80,7 @@
 import org.txm.rcp.messages.TXMUIMessages;
 import org.txm.rcp.preferences.RCPPreferences;
 import org.txm.rcp.swt.GLComposite;
+import org.txm.rcp.swt.HashMapWidget;
 import org.txm.rcp.swt.dialog.ComputeProgressMonitorDialog;
 import org.txm.rcp.swt.widget.AssistedChoiceQueryWidget;
 import org.txm.rcp.swt.widget.AssistedQueryWidget;
@@ -975,8 +977,6 @@
 								Log.finest("TXMEditor.compute(): " + TXMEditor.this.getClass().getSimpleName() + ": auto updating result from editor."); //$NON-NLS-1$ //$NON-NLS-2$
 								autoUpdateResultFromEditorParameters();
 								
-								
-								
 								// FIXME: SJ: useless at this time?
 								// Stores the last parameters before the computing to later auto-update the Widgets only if some parameters have changed
 								// setLastComputingParameters(TXMEditor.this.getResult().getLastParametersFromHistory());
@@ -1383,6 +1383,7 @@
 	 * NewNavigationWidget (Integer)
 	 * AssistedQueryWidget (String, from Query)
 	 * QueryWidget (String, from Query)
+	 * HashMapWidget (HashMap<String, String>)
 	 * 
 	 */
 	public void autoUpdateEditorFieldsFromResult(boolean update) {
@@ -1477,6 +1478,9 @@
 				else if (object instanceof NewNavigationWidget) {
 					((NewNavigationWidget) object).setCurrentPosition((Integer) value);
 				}
+				else if (object instanceof HashMapWidget) {
+					((HashMapWidget) object).setValues((LinkedHashMap) value);
+				}
 				else if (object instanceof AssistedChoiceQueryWidget) {
 					if (!((IQuery) value).getQueryString().isEmpty()) {
 						((AssistedChoiceQueryWidget) object).setText(((IQuery) value).getQueryString());
@@ -1575,6 +1579,9 @@
 				else if (object instanceof FloatSpinner) {
 					value = ((FloatSpinner) object).getSelectionAsFloat();
 				}
+				else if (object instanceof HashMapWidget) {
+					value = ((HashMapWidget) object).getValues();
+				}
 				else if (object instanceof Spinner) {
 					value = ((Spinner) object).getSelection();
 				}
Index: TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/HashMapDialog.java
===================================================================
--- TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/HashMapDialog.java	(revision 0)
+++ TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/HashMapDialog.java	(revision 3947)
@@ -0,0 +1,100 @@
+package org.txm.rcp.swt.dialog;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Dialog to set HashMap values given a HashMap pre-filled with values to edit
+ * 
+ * @author mdecorde
+ *
+ */
+public class HashMapDialog extends Dialog {
+
+	LinkedHashMap<String, String> values = new LinkedHashMap<String, String>();
+	LinkedHashMap<String, String> defaultValues = new LinkedHashMap<String, String>();
+	HashMap<String, Text> fields = new HashMap<String, Text>();
+	String title;
+	
+	/**
+	 * 
+	 * @param parentShell
+	 * @param title
+	 * @param values values to edit, value may be null
+	 */
+	public HashMapDialog(Shell parentShell, String title, LinkedHashMap<String, String> defaultValues, LinkedHashMap<String, String> values) {
+		
+		super(parentShell);
+		
+		this.title = title;
+		
+		if (defaultValues != null) {
+			this.values.putAll(defaultValues);
+		}
+
+		if (values != null) {
+			this.values.putAll(values);
+		}
+	}
+	
+	@Override
+	protected void configureShell(Shell newShell) {
+		
+		super.configureShell(newShell);
+		newShell.setText(title);
+	} 
+	
+	@Override
+	protected Control createDialogArea(Composite parent) {
+		
+		parent.setLayout(new GridLayout(2, false));
+		
+		for (String k : values.keySet()) {
+			Label l = new Label(parent, SWT.NONE);
+			l.setText(k);
+			l.setLayoutData(new GridData());
+			
+			Text field = new Text(parent, SWT.BORDER);
+			field.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
+			if (values.get(k) != null) {
+				field.setText(values.get(k));
+			}
+			
+			fields.put(k, field);
+		}
+		
+		return parent;
+	}
+	
+	@Override
+	protected void okPressed() {
+		
+		values.clear();
+		for (String k : fields.keySet()) {
+			if (fields.get(k).getText().length() > 0) {
+				values.put(k, fields.get(k).getText());
+			}
+		}
+		
+		super.okPressed();
+	}
+	
+	/**
+	 * 
+	 * @return the values set
+	 */
+	public LinkedHashMap<String, String> getValues() {
+		
+		return values;
+	}
+}

Property changes on: TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/HashMapDialog.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/ComboDialog.java
===================================================================
--- TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/ComboDialog.java	(revision 3946)
+++ TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/ComboDialog.java	(revision 3947)
@@ -37,7 +37,6 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Layout;
 import org.eclipse.swt.widgets.Shell;
 import org.txm.rcp.messages.TXMUIMessages;
 
@@ -85,8 +84,8 @@
 	 * @param defaultValue the default value (may be null)
 	 */
 	public ComboDialog(Shell parentShell, String title, List<String> values, String defaultValue) {
+		
 		this(parentShell, title, values, defaultValue, null);
-		
 	}
 	
 	/**
@@ -98,8 +97,8 @@
 	 * @param defaultValue the default value (may be null)
 	 * @param comboStyle if null combo is SINGLE and READONLY
 	 */
-	public ComboDialog(Shell parentShell, String title, List<String> values,
-			String defaultValue, Integer comboStyle) {
+	public ComboDialog(Shell parentShell, String title, List<String> values, String defaultValue, Integer comboStyle) {
+		
 		super(parentShell);
 		this.parentShell = parentShell;
 		this.setShellStyle(this.getShellStyle());
@@ -114,6 +113,7 @@
 	 */
 	@Override
 	protected void configureShell(Shell newShell) {
+		
 		super.configureShell(newShell);
 		newShell.setText(title);
 	}
@@ -139,8 +139,7 @@
 			style = comboStyle;
 		}
 		combo = new Combo(p, style);
-		combo.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true,
-				true, 5, 1));
+		combo.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 5, 1));
 		combo.setItems(values.toArray(new String[] {}));
 		// combo.setLayoutData(new GridData(GridData.FILL,GridData.FILL, true,
 		// true));
@@ -157,6 +156,7 @@
 	 */
 	@Override
 	protected void okPressed() {
+		
 		selectedIndex = combo.getSelectionIndex();
 		selectedValue = values.get(selectedIndex);
 		super.okPressed();
@@ -168,6 +168,7 @@
 	 * @return the values
 	 */
 	public List<String> getValues() {
+		
 		return values;
 	}
 
@@ -177,10 +178,12 @@
 	 * @param values the new values
 	 */
 	public void setValues(List<String> values) {
+		
 		this.values = values;
 		combo.setItems(values.toArray(new String[] {}));
-		if (values.size() > 0)
+		if (values.size() > 0) {
 			combo.select(0);
+		}
 	}
 
 	/**
@@ -189,6 +192,7 @@
 	 * @return the selected index
 	 */
 	public int getSelectedIndex() {
+		
 		return selectedIndex;
 	}
 
@@ -198,6 +202,7 @@
 	 * @return the selected value
 	 */
 	public String getSelectedValue() {
+		
 		return selectedValue;
 	}
 
@@ -207,6 +212,7 @@
 	 * @param string the string
 	 */
 	public void selectValue(String string) {
+		
 		for (int i = 0; i < values.size(); i++)
 			if (values.get(i).equals(string)) {
 				combo.select(i);
Index: TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/PropertySelector.java
===================================================================
--- TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/PropertySelector.java	(revision 3946)
+++ TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/PropertySelector.java	(revision 3947)
@@ -46,9 +46,8 @@
 import org.txm.searchengine.cqp.corpus.CQPCorpus;
 import org.txm.searchengine.cqp.corpus.Property;
 
-// TODO: Auto-generated Javadoc
 /**
- * The Class PropertySelector.
+ * Select and order a properties list
  */
 public class PropertySelector extends Dialog {
 
@@ -77,6 +76,7 @@
 	 * @param corpus the corpus
 	 */
 	public PropertySelector(Shell parentShell, CQPCorpus corpus) {
+		
 		super(parentShell);
 		try {
 			this.properties = new ArrayList<Property>(corpus.getOrderedProperties());
@@ -96,8 +96,8 @@
 	 * @param title the title
 	 * @param mess the mess
 	 */
-	public PropertySelector(Shell parentShell, CQPCorpus corpus, String title,
-			String mess) {
+	public PropertySelector(Shell parentShell, CQPCorpus corpus, String title, String mess) {
+		
 		super(parentShell);
 		this.corpus = corpus;
 		this.title = title;
@@ -115,10 +115,12 @@
 	 */
 	@Override
 	protected void configureShell(Shell newShell) {
+		
 		super.configureShell(newShell);
 		newShell.setText(TXMUIMessages.selectAProperty);
-		if (title != null)
+		if (title != null) {
 			newShell.setText(title);
+		}
 	}
 
 	/** The composite. */
@@ -129,6 +131,7 @@
 	 */
 	@Override
 	protected Control createDialogArea(Composite parent) {
+		
 		composite = new Composite(parent, SWT.NONE);
 		GridLayout layout = new GridLayout(2, false);
 		composite.setLayout(layout);
@@ -163,6 +166,7 @@
 	 */
 	@Override
 	protected void okPressed() {
+		
 		int propIndex = anaPropCombo.getSelectionIndex();
 		if (propIndex == -1) {
 			MessageDialog.openError(getShell(),
Index: TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/widget/PropertiesSelector.java
===================================================================
--- TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/widget/PropertiesSelector.java	(revision 3946)
+++ TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/widget/PropertiesSelector.java	(revision 3947)
@@ -33,6 +33,8 @@
 
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
+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;
@@ -43,6 +45,7 @@
 import org.eclipse.swt.widgets.Listener;
 import org.txm.objects.CorpusBuild;
 import org.txm.rcp.messages.TXMUIMessages;
+import org.txm.rcp.swt.dialog.HashMapDialog;
 import org.txm.rcp.swt.dialog.MultiplePropertySelectionDialog;
 import org.txm.rcp.swt.dialog.SinglePropertySelectionDialog;
 import org.txm.searchengine.core.Property;
@@ -87,6 +90,7 @@
 	
 	ArrayList<Listener> listeners = new ArrayList<>();
 	
+
 	/**
 	 * Instantiates a new properties selector.
 	 *
@@ -94,18 +98,48 @@
 	 * @param style the style
 	 */
 	public PropertiesSelector(Composite parent, int style) {
+		this(parent, style, null);
+	}
+	
+	/**
+	 * Instantiates a new properties selector.
+	 *
+	 * @param parent the parent
+	 * @param style the style
+	 * @param title widget title to display 
+	 */
+	public PropertiesSelector(Composite parent, int style, String title) {
 		super(parent, style);
 		
 		this.setLayout(new GridLayout(3, false));
 		
 		// "properties"
 		propLabel = new Label(this, SWT.NONE);
-		propLabel.setText(TXMUIMessages.propertiesColon);
+		if (title != null) {
+			propLabel.setText(title);
+		} else {
+			propLabel.setText(TXMUIMessages.propertiesColon);
+		}
 		propLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, true));
 		
 		// selected properties
 		propertiesLabel = new Label(this, SWT.NONE);
 		propertiesLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true));
+		propertiesLabel.addMouseListener(new MouseListener() {
+			
+			@Override
+			public void mouseUp(MouseEvent e) { }
+			
+			@Override
+			public void mouseDown(MouseEvent e) { }
+			
+			@Override
+			public void mouseDoubleClick(MouseEvent e) {
+				
+				showEditorDialog();
+				refresh();
+			}
+		});
 		
 		// "edit"
 		openEditDialog = new Button(this, SWT.PUSH);
@@ -131,9 +165,18 @@
 	 * @param parent
 	 */
 	public PropertiesSelector(Composite parent) {
-		this(parent, SWT.NONE);
+		this(parent, SWT.NONE, null);
 	}
 	
+	/**
+	 * Instantiates a new properties selector.
+	 * 
+	 * @param parent
+	 */
+	public PropertiesSelector(Composite parent, String title) {
+		this(parent, SWT.NONE, titles);
+	}
+	
 	public void setButtonText(String text) {
 		if (openEditDialog != null && !openEditDialog.isDisposed()) {
 			openEditDialog.setText(text);
Index: TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/HashMapWidget.java
===================================================================
--- TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/HashMapWidget.java	(revision 0)
+++ TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/HashMapWidget.java	(revision 3947)
@@ -0,0 +1,119 @@
+package org.txm.rcp.swt;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+
+import org.eclipse.swt.SWT;
+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.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.txm.rcp.messages.TXMUIMessages;
+import org.txm.rcp.swt.dialog.HashMapDialog;
+
+/**
+ * Widget : label + button to open the selector
+ * 
+ * @author mdecorde
+ *
+ */
+public class HashMapWidget extends GLComposite {
+	
+	Label valueLabel;
+	Button changeValues;
+	LinkedHashMap<String, String> values = new LinkedHashMap<String, String>();
+	LinkedHashMap<String, String> defaultValues = new LinkedHashMap<String, String>();
+
+	public HashMapWidget(Composite parent, int style, String name) {
+		
+		super(parent, style, name);
+		
+		new Label(parent, SWT.NONE).setText(name);
+		
+		valueLabel = new Label(parent, SWT.NONE);
+		valueLabel.addMouseListener(new MouseListener() {
+			
+			@Override
+			public void mouseUp(MouseEvent e) { }
+			
+			@Override
+			public void mouseDown(MouseEvent e) { }
+			
+			@Override
+			public void mouseDoubleClick(MouseEvent e) {
+				
+				HashMapDialog dialog = new HashMapDialog(e.display.getActiveShell(), "Negativ filters", defaultValues, values);
+				if (dialog.open() == HashMapDialog.OK) {
+					values = dialog.getValues();
+					updateLabel();
+				}
+				
+			}
+		});
+		
+		changeValues = new Button(parent, SWT.PUSH);
+		changeValues.setText(TXMUIMessages.edit);
+		changeValues.addSelectionListener(new SelectionListener() {
+			
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				
+				HashMapDialog dialog = new HashMapDialog(e.display.getActiveShell(), "Negativ filters", defaultValues, values);
+				if (dialog.open() == HashMapDialog.OK) {
+					values = dialog.getValues();
+					updateLabel();
+				}
+			}
+			
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) { }
+		});
+	}
+	
+	public void setDefaultValues(LinkedHashMap<String, String> values) {
+		
+		this.defaultValues.clear();
+		if (defaultValues == null) return;
+		
+		this.defaultValues.putAll(values);
+	}
+	
+	public void setValues(LinkedHashMap<String, String> values) {
+		
+		this.values.clear();
+		if (values == null) return;
+		
+		this.values.putAll(values);
+		updateLabel();
+	}
+
+	protected void updateLabel() {
+		
+		if (valueLabel.isDisposed()) return;
+		
+		String s = "";
+		for (String k : values.keySet()) {
+			if (values.get(k) != null && values.get(k).length() > 0) {
+				if (s.length() > 0) s += ", ";
+				s += k+ "=" + values.get(k);
+			}
+		}
+		valueLabel.setText(s);
+		valueLabel.getParent().layout(true);
+		valueLabel.getParent().getParent().layout(true);
+		
+	}
+
+	public LinkedHashMap<String, String> getValues() {
+		
+		return new LinkedHashMap<>(values);
+	}
+	
+	public LinkedHashMap<String, String> getDefaultValues() {
+		
+		return new LinkedHashMap<>(defaultValues);
+	}
+}

Property changes on: TXM/trunk/bundles/org.txm.rcp/src/main/java/org/txm/rcp/swt/HashMapWidget.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: TXM/trunk/bundles/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/StructuralUnitProperty.java
===================================================================
--- TXM/trunk/bundles/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/StructuralUnitProperty.java	(revision 3946)
+++ TXM/trunk/bundles/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/StructuralUnitProperty.java	(revision 3947)
@@ -39,7 +39,6 @@
 import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
 import org.txm.searchengine.cqp.clientExceptions.UnexpectedAnswerException;
 import org.txm.searchengine.cqp.corpus.query.CQLQuery;
-import org.txm.searchengine.cqp.corpus.query.MatchUtils;
 import org.txm.searchengine.cqp.serverException.CqiServerError;
 import org.txm.utils.logger.Log;
 
@@ -57,8 +56,6 @@
 	/** The structural unit. */
 	private StructuralUnit structuralUnit;
 	
-	
-	
 	/**
 	 * Instantiates a new structural unit property.
 	 * 
@@ -66,10 +63,10 @@
 	 *
 	 * @param structuralUnit the structural unit
 	 * @param name the name
-	 * @param corpus the corpus
-	 *            {@link StructuralUnit#getProperty(String)}
+	 * @param corpus the corpus {@link StructuralUnit#getProperty(String)}
 	 */
 	public StructuralUnitProperty(StructuralUnit structuralUnit, String name, CQPCorpus corpus) {
+		
 		super(name, corpus);
 		this.structuralUnit = structuralUnit;
 	}
@@ -80,6 +77,7 @@
 	 * @return the structural unit
 	 */
 	public StructuralUnit getStructuralUnit() {
+		
 		return structuralUnit;
 	}
 	
@@ -90,6 +88,7 @@
 	 */
 	@Override
 	public String getFullName() {
+		
 		return structuralUnit.getName() + "_" + this.getName(); //$NON-NLS-1$
 	}
 	
@@ -100,6 +99,7 @@
 	 * @return the full name
 	 */
 	public String asFullNameString() {
+		
 		return this.structuralUnit.getName() + this.asString();
 	}
 	
@@ -111,6 +111,7 @@
 	 * @return
 	 */
 	public static String asFullNameString(List<StructuralUnitProperty> properties) {
+		
 		String str = ""; ///$NON-NLS-1$
 		for (int i = 0; i < properties.size(); i++) {
 			if (i > 0) {
@@ -131,6 +132,7 @@
 	 * @throws CqiClientException the cqi client exception
 	 */
 	public List<String> getValues(CQPCorpus subcorpus) throws CqiClientException {
+		
 		try {
 			AbstractCqiClient cqiClient = CorpusManager.getCorpusManager().getCqiClient();
 			return cqiClient.getData(this, subcorpus);
@@ -163,6 +165,7 @@
 	 * @throws CqiClientException the cqi client exception
 	 */
 	public List<String> getValues(CQPCorpus subcorpus, int number) throws CqiClientException {
+		
 		try {
 			AbstractCqiClient cqiClient = CorpusManager.getCorpusManager().getCqiClient();
 			return cqiClient.getData(this, number);
@@ -191,6 +194,7 @@
 	 * @throws CqiClientException the cqi client exception
 	 */
 	public List<String> getValues() throws CqiClientException {
+		
 		return getValues(this.getCorpus());
 	}
 	
@@ -202,6 +206,7 @@
 	 * @throws CqiClientException the cqi client exception
 	 */
 	public List<String> getOrderedValues() throws CqiClientException {
+		
 		List<String> values = getValues(this.getCorpus());
 		Collections.sort(values);
 		return values;
@@ -216,6 +221,7 @@
 	 * @throws CqiClientException the cqi client exception
 	 */
 	public List<String> getOrderedValues(CQPCorpus corpus) throws CqiClientException {
+		
 		List<String> values = getValues(corpus);
 		Collections.sort(values);
 		return values;
@@ -228,6 +234,7 @@
 	 * @return the number of values in this corpus, -1 if an error occured
 	 */
 	public Integer getNumberOfValues(CQPCorpus corpus) {
+		
 		try {
 			QueryResult tmp = corpus.query(new CQLQuery("<" + this.getFullName() + ">[]"), UUID.randomUUID().toString(), false); //$NON-NLS-1$ //$NON-NLS-2$
 			int ret = tmp.getNMatch();
@@ -248,6 +255,7 @@
 	 * @return
 	 */
 	public static List<StructuralUnitProperty> stringToProperties(CQPCorpus corpus, String str) {
+		
 		ArrayList<StructuralUnitProperty> structs = new ArrayList<>();
 		if (str == null || str.length() == 0) {
 			return structs;
@@ -286,6 +294,7 @@
 	 * @throws CqiClientException
 	 */
 	public static StructuralUnitProperty stringToStructuralUnitProperty(CQPCorpus corpus, String str) throws CqiClientException {
+		
 		if (str == null) {
 			return null;
 		}
@@ -304,11 +313,13 @@
 	}
 	
 	public String cpos2Str(int position) throws UnexpectedAnswerException, IOException, CqiServerError {
+		
 		AbstractCqiClient cqiClient = CorpusManager.getCorpusManager().getCqiClient();
 		return cqiClient.getSingleData(this, new int[] { position }).get(0);
 	}
 	
 	public String[] cpos2Str(int[] positions) throws UnexpectedAnswerException, IOException, CqiServerError {
+		
 		AbstractCqiClient cqiClient = CorpusManager.getCorpusManager().getCqiClient();
 		return cqiClient.getSingleData(this, positions).toArray(new String[positions.length]);
 	}
@@ -322,6 +333,7 @@
 	 * @throws CqiClientException
 	 */
 	public int getNValues() throws IOException, CqiServerError, CqiClientException {
+		
 		return getValues().size();
 	}
 	
@@ -334,6 +346,7 @@
 	 * @throws CqiClientException
 	 */
 	public String[] getValuesAsStrings() throws IOException, CqiServerError, CqiClientException {
+		
 		List<String> values = getValues();
 		return values.toArray(new String[values.size()]);
 	}
Index: TXM/trunk/bundles/org.txm.texts.rcp/src/org/txm/texts/rcp/TextsViewEditor.java
===================================================================
--- TXM/trunk/bundles/org.txm.texts.rcp/src/org/txm/texts/rcp/TextsViewEditor.java	(revision 3946)
+++ TXM/trunk/bundles/org.txm.texts.rcp/src/org/txm/texts/rcp/TextsViewEditor.java	(revision 3947)
@@ -1,6 +1,8 @@
 package org.txm.texts.rcp;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
 
 import org.eclipse.e4.ui.workbench.modeling.EModelService;
@@ -18,7 +20,6 @@
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.TableColumn;
 import org.txm.Toolbox;
 import org.txm.core.results.Parameter;
@@ -31,6 +32,7 @@
 import org.txm.rcp.editors.TableKeyListener;
 import org.txm.rcp.editors.TableLinesViewerComparator;
 import org.txm.rcp.editors.listeners.ComputeSelectionListener;
+import org.txm.rcp.swt.HashMapWidget;
 import org.txm.rcp.swt.widget.PropertiesSelector;
 import org.txm.rcp.utils.SWTEditorsUtils;
 import org.txm.searchengine.cqp.corpus.StructuralUnitProperty;
@@ -42,7 +44,7 @@
 	PropertiesSelector<StructuralUnitProperty> propertiesSelector;
 	
 	@Parameter(key = "negativeFilters")
-	org.eclipse.swt.widgets.Text negativeFiltersText;
+	HashMapWidget negativeFiltersText;
 	
 	TableViewer viewer;
 //	HashMap<String, TableViewerColumn> columns = new HashMap<String, TableViewerColumn>();
@@ -56,25 +58,30 @@
 		
 		this.getMainParametersComposite().getLayout().numColumns = 10;
 		
-		propertiesSelector = new PropertiesSelector<>(this.getMainParametersComposite());
 		ArrayList<StructuralUnitProperty> properties = new ArrayList<>(getResult().getCorpus().getStructuralUnitProperties("text"));
 		for (int i = 0 ; i < properties.size() ; i++) {
-			if (properties.get(i).getName().equals("id")) {
+			if (properties.get(i).getName().equals("id") || properties.get(i).getName().equals("project")) {
 				properties.remove(i);
 				break;
 			}
 		}
+		Collections.sort(properties);
+		
+		ComputeSelectionListener computeSelectionListener = new ComputeSelectionListener(this);
+		
+		propertiesSelector = new PropertiesSelector<>(this.getMainParametersComposite(), "Metadata");
 		propertiesSelector.setProperties(properties);
-		ComputeSelectionListener computeSelectionListener = new ComputeSelectionListener(this);
 		propertiesSelector.addSelectionListener(computeSelectionListener);
-		
-		new Label(this.getMainParametersComposite(), SWT.NONE).setText("Negative filters (p1=v1;p2=v2)");
-		
-		negativeFiltersText = new org.eclipse.swt.widgets.Text(this.getMainParametersComposite(), SWT.BORDER);
-		negativeFiltersText.addSelectionListener(computeSelectionListener);
-		GridData gdata = new GridData(GridData.FILL, GridData.CENTER, true, false);
-		gdata.minimumWidth = 300;
+				
+		negativeFiltersText = new HashMapWidget(this.getMainParametersComposite(), SWT.NONE, "Negative filters: ");
+		//negativeFiltersText.addSelectionListener(computeSelectionListener);
+		GridData gdata = new GridData(GridData.FILL, GridData.FILL, false, false);
 		negativeFiltersText.setLayoutData(gdata);
+		LinkedHashMap<String, String> defaultValues = new LinkedHashMap<String, String>();
+		for (StructuralUnitProperty sup : properties) {
+			defaultValues.put(sup.getName(), "");
+		}
+		negativeFiltersText.setDefaultValues(defaultValues);
 		
 		viewer = new TableViewer(this.getResultArea(), SWT.MULTI|SWT.VIRTUAL);
 		viewer.getTable().setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
Index: TXM/trunk/bundles/org.txm.texts.core/src/org/txm/texts/core/TextsView.java
===================================================================
--- TXM/trunk/bundles/org.txm.texts.core/src/org/txm/texts/core/TextsView.java	(revision 3946)
+++ TXM/trunk/bundles/org.txm.texts.core/src/org/txm/texts/core/TextsView.java	(revision 3947)
@@ -1,10 +1,15 @@
 package org.txm.texts.core;
 
 import java.io.File;
+import java.io.ObjectOutputStream;
 import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Properties;
 
 import org.apache.commons.lang.StringUtils;
 import org.eclipse.osgi.util.NLS;
@@ -30,7 +35,7 @@
 	//	ArrayList<String> positiveFilters;
 
 	@Parameter(key = "negativeFilters")
-	String negativeFilters;
+	LinkedHashMap<String, String> negativeFilters;
 
 	private LinkedHashMap<String, ArrayList<String>> result;
 
@@ -53,9 +58,20 @@
 	@Override
 	public boolean saveParameters() throws Exception {
 
-		this.saveParameter("columns", StringUtils.join(pColumns, "\t"));
+		
+		String s = "";
+		for (StructuralUnitProperty sup : pColumns) {
+			if (s.length() > 0) s += "\t";
+			s += sup.getFullName();
+		}
+		this.saveParameter("columns", s);
 		//		this.saveParameter("positiveFilters", StringUtils.join(positiveFilters, "\t"));
-		this.saveParameter("negativeFilters", negativeFilters);
+		
+		Properties props = new Properties();
+		props.putAll(negativeFilters);
+		StringWriter sw = new StringWriter();
+		props.store(sw, "");
+		this.saveParameter("negativeFilters", sw.toString());
 		return true;
 	}
 
@@ -64,7 +80,7 @@
 
 		String v = this.getStringParameterValue("columns").toString();
 		if ("*".equals(v)) {
-			;
+			
 			this.pColumns = new ArrayList<>(getCorpus().getStructuralUnit("text").getUserDefinedOrderedProperties());
 			for (int i = 0 ; i < pColumns.size() ; i++) {
 				if (pColumns.get(i).getName().equals("id")) {
@@ -77,10 +93,12 @@
 		}
 
 		v = this.getStringParameterValue("negativeFilters").toString();
-		if (v.contains("=")) {
-			this.negativeFilters = v;
-		} else {
-			this.negativeFilters = "";
+		this.negativeFilters = new LinkedHashMap<String, String>();
+		if (v != null && v.length() > 0) {
+			Properties props = new Properties();
+			props.load(new StringReader(v));
+			
+			for (Object k : props.keySet()) negativeFilters.put(k.toString(), props.get(k.toString()).toString());
 		}
 
 		//		v = this.getStringParameterValue("positiveFilters").toString();
@@ -172,24 +190,18 @@
 				}
 			}
 		}
-		
-		
 
-		if (negativeFilters.length() > 0 && pColumns.size() > 0) {
+		if (negativeFilters.size() > 0 && pColumns.size() > 0) {
 
 			ArrayList<String> columnNames = new ArrayList<>(pColumns.size());
 			for (StructuralUnitProperty p : pColumns) columnNames.add(p.getName());
 
-			String[] filters = negativeFilters.split(";");
-
 			ArrayList<String> keys = new ArrayList<>(result.keySet());
 			for (String text : keys) {
 
-				for (String negativeFilter : filters) {
-					String[] split = negativeFilter.split("=", 2);
-					if (split.length == 2 
-							&& columnNames.contains(split[0]) 
-							&& result.get(text).get(columnNames.indexOf(split[0])).matches(split[1])) {
+				for (String negativeFilter : negativeFilters.keySet()) {
+					if (columnNames.contains(negativeFilter) 
+							&& result.get(text).get(columnNames.indexOf(negativeFilter)).matches(negativeFilters.get(negativeFilter))) {
 						// remove this line
 						result.remove(text);
 						break;
