From dcf0ac6cf62dacc1c52e7e100b5c92000b616774 Mon Sep 17 00:00:00 2001
From: Ludovic Apvrille <ludovic.apvrille@telecom-paristech.fr>
Date: Tue, 16 Dec 2008 13:46:10 +0000
Subject: [PATCH] TGAutoAdjust!

---
 src/ui/GTURTLEModeling.java               |   1 +
 src/ui/JToolBarMainTurtle.java            |   4 +-
 src/ui/MainGUI.java                       |  10 +-
 src/ui/TDiagramPanel.java                 |  28 +-
 src/ui/TGAutoAdjust.java                  |  53 ++
 src/ui/TGComponent.java                   |  20 +
 src/ui/req/Requirement.java               | 559 ++++++++++++++++------
 src/ui/req/RequirementDiagramPanel.java   |  62 +--
 src/ui/req/RequirementDiagramToolBar.java |  22 +-
 src/ui/req/RequirementObserver.java       | 455 ++++++++++++------
 src/ui/req/TGConnectorDerive.java         |   9 +
 src/ui/req/TGConnectorVerify.java         |  12 +-
 12 files changed, 874 insertions(+), 361 deletions(-)
 create mode 100755 src/ui/TGAutoAdjust.java

diff --git a/src/ui/GTURTLEModeling.java b/src/ui/GTURTLEModeling.java
index dbfeabacfa..64318fc0f0 100755
--- a/src/ui/GTURTLEModeling.java
+++ b/src/ui/GTURTLEModeling.java
@@ -3610,6 +3610,7 @@ public class GTURTLEModeling {
 			zoom = Double.parseDouble(elt.getAttribute("zoom"));
 			if (zoom != 0) {
 				tdp.setZoom(zoom);
+				mgui.updateZoomInfo();
 			}
 		} catch (Exception e) {
 			// Model was saved in an older version of TTool
diff --git a/src/ui/JToolBarMainTurtle.java b/src/ui/JToolBarMainTurtle.java
index 0dcefd7b92..b6e02bf828 100755
--- a/src/ui/JToolBarMainTurtle.java
+++ b/src/ui/JToolBarMainTurtle.java
@@ -112,14 +112,14 @@ public	class JToolBarMainTurtle extends JToolBar	{
         
         addSeparator();
         
-        button = add(mgui.actions[TGUIAction.ACT_FIRST_DIAG]);
+        /*button = add(mgui.actions[TGUIAction.ACT_FIRST_DIAG]);
         button.addMouseListener(mgui.mouseHandler);
         button = add(mgui.actions[TGUIAction.ACT_BACK_DIAG]);
         button.addMouseListener(mgui.mouseHandler);
         button = add(mgui.actions[TGUIAction.ACT_NEXT_DIAG]);
         button.addMouseListener(mgui.mouseHandler);
         button = add(mgui.actions[TGUIAction.ACT_LAST_DIAG]);
-        button.addMouseListener(mgui.mouseHandler);
+        button.addMouseListener(mgui.mouseHandler);*/
         
         addSeparator();
         addSeparator();
diff --git a/src/ui/MainGUI.java b/src/ui/MainGUI.java
index c6565f680b..d06bc21911 100755
--- a/src/ui/MainGUI.java
+++ b/src/ui/MainGUI.java
@@ -2094,7 +2094,13 @@ public	class MainGUI implements ActionListener, WindowListener, KeyListener {
 	}
 	
 	public void updateZoomInfo() {
-		String s = "" + (int)(getCurrentTDiagramPanel().getZoom()*100) + "%";
+		String s = "";
+		int zoom = (int)(getCurrentTDiagramPanel().getZoom()*100);
+		if (zoom < 100) {
+			s = "0" + zoom + "%";
+		} else {
+			s += zoom + "%";
+		}
 		actions[TGUIAction.ACT_SHOW_ZOOM].setName(TGUIAction.ACT_SHOW_ZOOM, s);
 	}
     
@@ -4768,7 +4774,7 @@ public	class MainGUI implements ActionListener, WindowListener, KeyListener {
 	 public void toggleAttr() {
         TDiagramPanel tdp = getCurrentTDiagramPanel();
         if (tdp != null){
-            //System.out.println("Toggle attributes");
+            System.out.println("Toggle attributes");
             tdp.setAttributes((tdp.getAttributeState() +1 )% 3);
             tdp.checkAllMySize();
             tdp.repaint();
diff --git a/src/ui/TDiagramPanel.java b/src/ui/TDiagramPanel.java
index 391abab675..478ef9155e 100755
--- a/src/ui/TDiagramPanel.java
+++ b/src/ui/TDiagramPanel.java
@@ -176,6 +176,8 @@ public abstract class TDiagramPanel extends JPanel implements GenericTree {
 	protected int internalCommentVisible = 0;
     protected boolean channelsVisible = true, eventsVisible = true, requestsVisible = true;
 	protected int attributesOn = 0;
+	
+	int adjustMode = 0;
     
     // Constructor
     public TDiagramPanel(MainGUI _mgui, TToolBar _ttb) {
@@ -212,6 +214,14 @@ public abstract class TDiagramPanel extends JPanel implements GenericTree {
     public double getZoom() {
         return zoom;
     }
+	
+	/*public int getFontSize() {
+		return (int)(Math.round(7.5*zoom+4.5));
+	}*/
+	
+	public int getFontSize() {
+		return (int)(Math.round(12*zoom));
+	}
     
     public void setZoom(double _zoom) {
 		if (_zoom < zoom) {
@@ -2961,9 +2971,21 @@ public abstract class TDiagramPanel extends JPanel implements GenericTree {
     public void enhance() {
         
     }
-    
-    
-    // Zoom -> graphics management
+	
+	public void autoAdjust() {
+		TGComponent tgc;
+        Iterator iterator = componentList.listIterator();
+        
+        while(iterator.hasNext()) {
+            tgc = (TGComponent)(iterator.next());
+			if (tgc instanceof TGAutoAdjust) {
+				((TGAutoAdjust)tgc).autoAdjust(adjustMode);
+			}
+        }
+		adjustMode = (adjustMode + 1)% 2;
+		
+		repaint();
+	}
     
     
 }
diff --git a/src/ui/TGAutoAdjust.java b/src/ui/TGAutoAdjust.java
new file mode 100755
index 0000000000..9ddc8a1055
--- /dev/null
+++ b/src/ui/TGAutoAdjust.java
@@ -0,0 +1,53 @@
+/**Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
+
+ludovic.apvrille AT enst.fr
+
+This software is a computer program whose purpose is to allow the 
+edition of TURTLE analysis, design and deployment diagrams, to 
+allow the generation of RT-LOTOS or Java code from this diagram, 
+and at last to allow the analysis of formal validation traces 
+obtained from external tools, e.g. RTL from LAAS-CNRS and CADP 
+from INRIA Rhone-Alpes.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+
+/**
+ * Class TGAutoAdjust
+ * Components that have the capability to auto adjust their size
+ * Creation: 11/12/2008
+ * @version 1.0 11/12/2008
+ * @author Ludovic APVRILLE
+ * @see
+ */
+
+
+package ui;
+
+public interface TGAutoAdjust  {
+	// Auto adjust mode: 2 modes: 0: regular, 1: small
+    public void autoAdjust(int mode);
+}
\ No newline at end of file
diff --git a/src/ui/TGComponent.java b/src/ui/TGComponent.java
index e1c0e4d2fd..5fc1d29027 100755
--- a/src/ui/TGComponent.java
+++ b/src/ui/TGComponent.java
@@ -1980,6 +1980,26 @@ public abstract class TGComponent implements CDElement, GenericTree {
 	}
     
     public void valueChanged() {}
+	
+	
+	// Pos contains either 0 : printed at x
+	//                     1 : printed in the middle of the area
+	public void drawLimitedString(Graphics g, String value, int x, int y, int maxW, int pos) {
+		int w  =  g.getFontMetrics().stringWidth(value);
+		if (x+w >= x+maxW) {
+			value = "...";
+			w  =  g.getFontMetrics().stringWidth(value);
+			if (x+w >= x + maxW) {
+				return;
+			}
+		}
+		if (pos == 0) {
+			g.drawString(value, x, y);
+		} else {
+			g.drawString(value, x+(maxW-w)/2, y);
+		}
+	}
+	
     
     // saving
     
diff --git a/src/ui/req/Requirement.java b/src/ui/req/Requirement.java
index 5ab2798a79..8f746e5709 100755
--- a/src/ui/req/Requirement.java
+++ b/src/ui/req/Requirement.java
@@ -36,13 +36,13 @@ The fact that you are presently reading this means that you have had
 knowledge of the CeCILL license and that you accept its terms.
 
 /**
- * Class Requirement
- * Turtle requirement: to be used in requirement diagram
- * Creation: 30/05/2006
- * @version 1.0 30/05/2006
- * @author Ludovic APVRILLE
- * @see
- */
+* Class Requirement
+* Turtle requirement: to be used in requirement diagram
+* Creation: 30/05/2006
+* @version 1.0 30/05/2006
+* @author Ludovic APVRILLE
+* @see
+*/
 
 package ui.req;
 
@@ -55,15 +55,24 @@ import org.w3c.dom.*;
 
 import myutil.*;
 import ui.*;
+import ui.window.*;
 
-public class Requirement extends TGCWithInternalComponent {
+public class Requirement extends TGCScalableWithInternalComponent implements WithAttributes, TGAutoAdjust {
     public String oldValue;
     protected int textX = 5;
     protected int textY = 22;
+	protected int lineHeight = 30;
+	private double dlineHeight = 0.0;
     protected boolean formal = false;
-    protected int startFontSize = 10;
+    //protected int startFontSize = 10;
     protected Graphics graphics;
-    protected int iconSize = 30;
+    //protected int iconSize = 30;
+	
+	private Font myFont, myFontB;
+	private int maxFontSize = 30;
+	private int minFontSize = 4;
+	private int currentFontSize = -1;
+	private boolean displayText = true;
     
     protected final static String REGULAR_REQ = "<<Requirement>>";
     protected final static String FORMAL_REQ = "<<Formal Requirement>>";
@@ -71,41 +80,75 @@ public class Requirement extends TGCWithInternalComponent {
     public final static int HIGH = 0;
     public final static int MEDIUM = 1;
     public final static int LOW = 2;
+	
+	protected String text;
+    protected String []texts;
+    protected String kind = "";
+    protected String criticality = "";
+    protected String violatedAction = "";
+	
+	
+	
+	// Icon
+	private int iconSize = 18;
+	private boolean iconIsDrawn = false;
     
     public Requirement(int _x, int _y, int _minX, int _maxX, int _minY, int _maxY, boolean _pos, TGComponent _father, TDiagramPanel _tdp)  {
         super(_x, _y, _minX, _maxX, _minY, _maxY, _pos, _father, _tdp);
         
-        width = 200; height = 30;
-        minWidth = 200;
-        minDesiredWidth = 200;
-        minDesiredHeight = 30;
+		initScaling(200, 120);
+		oldScaleFactor = tdp.getZoom();
+		dlineHeight = lineHeight * oldScaleFactor;
+		lineHeight = (int)dlineHeight;
+		dlineHeight = dlineHeight - lineHeight;
+		
+		minWidth = 1;
+        minHeight = lineHeight;
         
-        nbConnectingPoint = 10;
+        nbConnectingPoint = 24;
         connectingPoint = new TGConnectingPoint[nbConnectingPoint];
-        connectingPoint[0] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.0, .5);
-        connectingPoint[1] = new TGConnectingPointDerive(this, 0, 0, true, true, 1.0, 0.5);
-        connectingPoint[2] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.25, 0.0);
-        connectingPoint[3] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.5, 0.0);
-        connectingPoint[4] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.75, 0.0);
-        connectingPoint[5] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.0, .5);
-        connectingPoint[6] = new TGConnectingPointVerify(this, 0, 0, true, false, 1.0, 0.5);
-        connectingPoint[7] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.25, 0.0);
-        connectingPoint[8] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.5, 0.0);
-        connectingPoint[9] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.75, 0.0);
+        connectingPoint[0] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.0, 0.25);
+        connectingPoint[1] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.0, 0.5);
+        connectingPoint[2] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.0, 0.75);
+        connectingPoint[3] = new TGConnectingPointDerive(this, 0, 0, true, true, 1.0, 0.25);
+        connectingPoint[4] = new TGConnectingPointDerive(this, 0, 0, true, true, 1.0, 0.5);
+        connectingPoint[5] = new TGConnectingPointDerive(this, 0, 0, true, true, 1.0, 0.75);
+        connectingPoint[6] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.25, 0.0);
+        connectingPoint[7] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.5, 0.0);
+        connectingPoint[8] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.75, 0.0);
+        connectingPoint[9] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.25, 1.0);
+		connectingPoint[10] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.5, 1.0);
+		connectingPoint[11] = new TGConnectingPointDerive(this, 0, 0, true, true, 0.75, 1.0);
+        connectingPoint[12] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.0, 0.25);
+        connectingPoint[13] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.0, 0.5);
+        connectingPoint[14] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.0, 0.75);
+        connectingPoint[15] = new TGConnectingPointVerify(this, 0, 0, true, false, 1.0, 0.25);
+        connectingPoint[16] = new TGConnectingPointVerify(this, 0, 0, true, false, 1.0, 0.5);
+        connectingPoint[17] = new TGConnectingPointVerify(this, 0, 0, true, false, 1.0, 0.75);
+        connectingPoint[18] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.25, 0.0);
+        connectingPoint[19] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.5, 0.0);
+        connectingPoint[20] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.75, 0.0);
+        connectingPoint[21] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.25, 1.0);
+		connectingPoint[22] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.5, 1.0);
+		connectingPoint[23] = new TGConnectingPointVerify(this, 0, 0, true, false, 0.75, 1.0);
+		
         addTGConnectingPointsCommentTop();    
         
-        nbInternalTGComponent = 1;
-        tgcomponent = new TGComponent[nbInternalTGComponent];
+        nbInternalTGComponent = 0;
+        //tgcomponent = new TGComponent[nbInternalTGComponent];
         
         int h = 1;
-        TAttributeRequirement tgc0;
-        tgc0 = new TAttributeRequirement(x, y+height+h, 0, 0, height + h, height+h, true, this, _tdp);
-        tgcomponent[0] = tgc0;
+        //TAttributeRequirement tgc0;
+        //tgc0 = new TAttributeRequirement(x, y+height+h, 0, 0, height + h, height+h, true, this, _tdp);
+        //tgcomponent[0] = tgc0;
         
         moveable = true;
         editable = true;
         removable = true;
-        
+        userResizable = true;
+		multieditable = true;
+		
+		
         formal = false;
         
         // Name of the requirement
@@ -114,133 +157,200 @@ public class Requirement extends TGCWithInternalComponent {
         oldValue = value;
         
         myImageIcon = IconManager.imgic104;
+		
+		text = "Requirement description:\nDouble-click to edit";
         
         actionOnAdd();
     }
-    
-    public void recalculateSize() {
-        //System.out.println("Recalculate size of " + this);
-        int i, j;
-     
-        for(i=0; i<nbInternalTGComponent; i++) {
-            tgcomponent[i].calculateMyDesiredSize();
-        }
-        
-        int minW = getMyDesiredWidth();
-        for(i=0; i<nbInternalTGComponent; i++) {
-            minW = Math.max(minW, tgcomponent[i].getMinDesiredWidth());
-        }
-        
-        for(i=0; i<nbInternalTGComponent; i++) {
-            tgcomponent[i].forceSize(minW, tgcomponent[i].getMinDesiredHeight());
-        }
-        
-        forceSize(minW, getHeight());
-        
-        // Reposition all internal components
-        int h = getHeight();
-        for(i=0; i<nbInternalTGComponent; i++) {
-            tgcomponent[i].setCdRectangle(0, 0, h, h);
-            tgcomponent[i].setCd(tgcomponent[i].getX(), h);
-            h += tgcomponent[i].getHeight();
-        }
-    }
-    
-    public int getMyDesiredWidth() {
-        if (graphics == null) {
-            graphics = tdp.getGraphics();
-        }
-        if (graphics == null) {
-            return minWidth;
-        }
-        int size = graphics.getFontMetrics().stringWidth(value) + iconSize + 5;
-        minDesiredWidth = Math.max(size, minWidth);
-        return minDesiredWidth;
-    }
-    
-    
-    private int calculateDesiredWidth() {
-        return Math.max(minDesiredWidth, tgcomponent[0].getMinDesiredWidth());
+	
+	public void makeValue() {
+        texts = Conversion.wrapText(text);
     }
     
-    
     public void internalDrawing(Graphics g) {
+		Font f = g.getFont();
+		Font fold = f;
+		int w, c;
+		int size;
+		
+		if (texts == null) {
+			makeValue();
+		}
+		
         if (!tdp.isScaled()) {
             graphics = g;
         }
+		
+		if (((rescaled) && (!tdp.isScaled())) || myFont == null) {
+			currentFontSize = tdp.getFontSize();
+			//System.out.println("Rescaled, font size = " + currentFontSize + " height=" + height);
+			myFont = f.deriveFont((float)currentFontSize);
+			myFontB = myFont.deriveFont(Font.BOLD);
+			
+			if (rescaled) {
+				rescaled = false;
+			}
+		}
+		
+		if(currentFontSize <minFontSize) {
+			displayText = false;
+		} else {
+			displayText = true;
+		}
+		
+		int h  = g.getFontMetrics().getHeight();
         
-        Font f = g.getFont();
-        int size = f.getSize();
-        g.drawRect(x, y, width, height);
-        g.setColor(Color.yellow);
-        g.fillRect(x+1, y+1, width-1, height-1);
-        g.drawImage(IconManager.img8, x + width - 20, y + 6, Color.yellow, null);
-        ColorManager.setColor(g, getState(), 0);
-        g.setFont(f.deriveFont(Font.BOLD));
-        int w = g.getFontMetrics().stringWidth(value);
-        g.drawString(value, x + (width - w)/2, y + textY);
-        g.setFont(f);
-        g.setFont(f.deriveFont((float)startFontSize));
-        if (formal) {
-            w  =  g.getFontMetrics().stringWidth(FORMAL_REQ);
-            g.drawString(FORMAL_REQ, x + (width - w)/2, y + startFontSize);
-        } else {
-            w  =  g.getFontMetrics().stringWidth(REGULAR_REQ);
-            g.drawString(REGULAR_REQ, x + (width-w)/2, y + startFontSize);
+		g.drawRect(x, y, width, height);
+        
+		g.drawLine(x, y+lineHeight, x+width, y+lineHeight);
+		g.setColor(Color.yellow);
+        g.fillRect(x+1, y+1, width-1, lineHeight-1);
+		g.setColor(ColorManager.REQ_ATTRIBUTE_BOX);
+		g.fillRect(x+1, y+1+lineHeight, width-1, height-1-lineHeight);
+		ColorManager.setColor(g, getState(), 0);
+		if ((lineHeight > 23) && (width > 23)){
+			g.drawImage(IconManager.img8, x + width - iconSize + 1, y + 3, Color.yellow, null);
+		}
+		
+		if (displayText) {
+			size = currentFontSize - 2;
+			g.setFont(myFont.deriveFont((float)(myFont.getSize() - 2)));
+			if (formal) {
+				drawLimitedString(g, FORMAL_REQ, x, y + size, width, 1);
+			} else {
+				drawLimitedString(g, REGULAR_REQ, x, y + size, width, 1);
+			}			
+			size += currentFontSize;
+			g.setFont(myFontB);
+			w = g.getFontMetrics().stringWidth(value);
+			drawLimitedString(g, value, x, y + size, width, 1);
+			
+		}
+		
+		g.setFont(myFont);
+		String texti;
+		if (formal) {
+			texti = "TRDD";
+		} else {
+			texti = "Text";
+		}
+		
+		String s ;
+		int i;
+		size = lineHeight + currentFontSize;
+        for(i=0; i<texts.length; i++) {
+			if (size < (height - 2)) {
+				s = texts[i];
+				if (i == 0) {
+					s = texti + "=\"" + s;
+				}
+				if (i == (texts.length - 1)) {
+					s = s + "\"";
+				}
+				drawLimitedString(g, s, x + textX, y + size, width, 0);
+			}
+			size += currentFontSize;
+            
         }
+        // Type and risk
+		if (size < (height - 2)) {
+			drawLimitedString(g, "Type=\"" + kind + "\"", x + textX, y + size, width, 0);
+			size += currentFontSize;
+			if (size < (height - 2)) {
+				drawLimitedString(g, "Risk=\"" + criticality + "\"", x + textX, y + size, width, 0);
+			}
+		}
+		
+        
         g.setFont(f);
     }
     
-    public boolean editOndoubleClick(JFrame frame) {
+	public boolean editOndoubleClick(JFrame frame, int _x, int _y) {
+		// On the name ?
         oldValue = value;
+		
+        if ((displayText) && (_y <= (y + lineHeight))) {
+			String text = getName() + ": ";
+			if (hasFather()) {
+				text = getTopLevelName() + " / " + text;
+			}
+			String s = (String)JOptionPane.showInputDialog(frame, text,
+				"setting value", JOptionPane.PLAIN_MESSAGE, IconManager.imgic101,
+				null,
+				getValue());
+			
+			if ((s != null) && (s.length() > 0) && (!s.equals(oldValue))) {
+				//boolean b;
+				if (!TAttribute.isAValidId(s, false, false)) {
+					JOptionPane.showMessageDialog(frame,
+						"Could not change the name of the Requirement: the new name is not a valid name",
+						"Error",
+						JOptionPane.INFORMATION_MESSAGE);
+					return false;
+				}
+				
+				if (!tdp.isRequirementNameUnique(s)) {
+					JOptionPane.showMessageDialog(frame,
+						"Could not change the name of the Requirement: the new name is already in use",
+						"Error",
+						JOptionPane.INFORMATION_MESSAGE);
+					return false;
+				}
+				
+				
+				int size = graphics.getFontMetrics().stringWidth(s) + iconSize + 5;
+				minDesiredWidth = Math.max(size, minWidth);
+				if (minDesiredWidth != width) {
+					newSizeForSon(null);
+				}
+				setValue(s);
+				
+				if (tdp.actionOnDoubleClick(this)) {
+					return true;
+				} else {
+					JOptionPane.showMessageDialog(frame,
+						"Could not change the name of the Requirement: this name is already in use",
+						"Error",
+						JOptionPane.INFORMATION_MESSAGE);
+					setValue(oldValue);
+				}
+			}
+			return false;
+		}
+		
+		return editAttributes();
+		
+    }
+	
+	public boolean editAttributes() {
+		//String oldValue = value;
+        JDialogRequirement jdr = new JDialogRequirement(tdp.getGUI().getFrame(), "Setting attributes of Requirement " + getRequirementName(), text, kind, criticality, violatedAction, isFormal());
+        jdr.setSize(750, 400);
+        GraphicLib.centerOnParent(jdr);
+        jdr.show();
         
-        String text = getName() + ": ";
-        if (hasFather()) {
-            text = getTopLevelName() + " / " + text;
+        if (!jdr.isRegularClose()) {
+            return false;
         }
-        String s = (String)JOptionPane.showInputDialog(frame, text,
-        "setting value", JOptionPane.PLAIN_MESSAGE, IconManager.imgic101,
-        null,
-        getValue());
         
-        if ((s != null) && (s.length() > 0) && (!s.equals(oldValue))) {
-            //boolean b;
-            if (!TAttribute.isAValidId(s, false, false)) {
-                JOptionPane.showMessageDialog(frame,
-                "Could not change the name of the Requirement: the new name is not a valid name",
-                "Error",
-                JOptionPane.INFORMATION_MESSAGE);
-                return false;
-            }
-            
-            if (!tdp.isRequirementNameUnique(s)) {
-                JOptionPane.showMessageDialog(frame,
-                "Could not change the name of the Requirement: the new name is already in use",
-                "Error",
-                JOptionPane.INFORMATION_MESSAGE);
-                return false;
-            }
-            
-           
-            int size = graphics.getFontMetrics().stringWidth(s) + iconSize + 5;
-            minDesiredWidth = Math.max(size, minWidth);
-            if (minDesiredWidth != width) {
-                newSizeForSon(null);
-            }
-            setValue(s);
-  
-            if (tdp.actionOnDoubleClick(this)) {
-                return true;
-            } else {
-                JOptionPane.showMessageDialog(frame,
-                "Could not change the name of the Requirement: this name is already in use",
-                "Error",
-                JOptionPane.INFORMATION_MESSAGE);
-                setValue(oldValue);
-            }
-        }
-        return false;
-    }
+        text = jdr.getText();
+        kind = jdr.getKind();
+        criticality = jdr.getCriticality();
+        violatedAction = jdr.getViolatedAction();
+        
+        makeValue();
+        return true;
+	}
+	
+	public void rescale(double scaleFactor){
+		dlineHeight = (lineHeight + dlineHeight) / oldScaleFactor * scaleFactor;
+		lineHeight = (int)(dlineHeight);
+		dlineHeight = dlineHeight - lineHeight; 
+		
+		minHeight = lineHeight;
+		
+		super.rescale(scaleFactor);
+	}
     
     
     public TGComponent isOnOnlyMe(int x1, int y1) {
@@ -278,9 +388,13 @@ public class Requirement extends TGCWithInternalComponent {
         } else {
             isFormal = new JMenuItem("Set as formal requirement");
         }
+		isFormal.addActionListener(menuAL);
+		
+		JMenuItem editAttributes = new JMenuItem("Edit attributes");
+		editAttributes.addActionListener(menuAL);
         
-        isFormal.addActionListener(menuAL);
         componentMenu.add(isFormal);
+		componentMenu.add(editAttributes);
     }
     
     public boolean eventOnPopup(ActionEvent e) {
@@ -289,8 +403,12 @@ public class Requirement extends TGCWithInternalComponent {
             //System.out.println("Set to regular");
             formal = false;
         } else {
-            //System.out.println("Set to formal");
-            formal = true;
+			if (s.indexOf("formal") > 1) {
+				//System.out.println("Set to formal");
+				formal = true;
+			} else {
+				return editAttributes();
+			}
         }
         return true;
     }
@@ -302,7 +420,14 @@ public class Requirement extends TGCWithInternalComponent {
         }  else {
             ret = ret + " " + REGULAR_REQ;
         }
- 
+		
+		ret += " " + text;
+		ret += " criticality=" + criticality;
+		
+		if (formal) {
+			ret += " violatedAction=" + violatedAction;
+		}
+		
         return ret;
     }
     
@@ -310,22 +435,40 @@ public class Requirement extends TGCWithInternalComponent {
         StringBuffer sb = new StringBuffer("<extraparam>\n");
         sb.append("<Formal isFormal=\"");
         if (isFormal()) {
-            sb.append("true");
+            sb.append("true\" />\n");
         } else {
-            sb.append("false");
+            sb.append("false\" />\n");
         }
+		if (texts != null) {
+            for(int i=0; i<texts.length; i++) {
+                //value = value + texts[i] + "\n";
+                sb.append("<textline data=\"");
+                sb.append(texts[i]);
+                sb.append("\" />\n");
+            }
+        }
+        sb.append("<kind data=\"");
+        sb.append(kind);
+        sb.append("\" />\n");
+        sb.append("<criticality data=\"");
+        sb.append(criticality);
+        sb.append("\" />\n");
+        sb.append("<violated data=\"");
+        sb.append(violatedAction);
         sb.append("\" />\n");
         sb.append("</extraparam>\n");
         return new String(sb);
     }
- 
+	
     
     public void loadExtraParam(NodeList nl, int decX, int decY, int decId) throws MalformedModelingException{
         try {
             NodeList nli;
             Node n1, n2;
             Element elt;
-            String startS;
+			String oldtext = text;
+            text = "";
+			String s;
             
             //System.out.println("Loading tclass " + getValue());
             //System.out.println(nl.toString());
@@ -339,33 +482,141 @@ public class Requirement extends TGCWithInternalComponent {
                         if (n2.getNodeType() == Node.ELEMENT_NODE) {
                             elt = (Element) n2;
                             if (elt.getTagName().equals("Formal")) {
-                                startS = elt.getAttribute("isFormal");
-                                if (startS.equals("true")) {
+                                s = elt.getAttribute("isFormal");
+                                if (s.equals("true")) {
                                     formal = true;
                                 } else {
                                     formal = false;
                                 }
+                            } else if (elt.getTagName().equals("textline")) {
+                                //System.out.println("Analyzing line0");
+                                s = elt.getAttribute("data");
+                                if (s.equals("null")) {
+                                    s = "";
+                                }
+                                text += GTURTLEModeling.decodeString(s) + "\n";
+                            } else if (elt.getTagName().equals("kind")) {
+                                //System.out.println("Analyzing line1");
+                                kind = elt.getAttribute("data");
+                                if (kind.equals("null")) {
+                                    kind = "";
+                                }
+                            } else if (elt.getTagName().equals("criticality")) {
+                                //System.out.println("Analyzing line2");
+                                criticality = elt.getAttribute("data");
+                                if (criticality.equals("null")) {
+                                    criticality = "";
+                                }
+                            } else if (elt.getTagName().equals("violated")) {
+                                //System.out.println("Analyzing line3");
+                                violatedAction = elt.getAttribute("data");
+                                if (violatedAction.equals("null")) {
+                                    violatedAction = "";
+                                }
+								//System.out.println("Analyzing line4");
                             }
                         }
                     }
                 }
             }
-            
+			if (text.length() == 0) {
+                text = oldtext;
+            }
         } catch (Exception e) {
+			System.out.println("Failed when loading requirement extra parameters");
             throw new MalformedModelingException();
         }
+		
+		makeValue();
     }
     
     public String getViolatedAction() {
-        return ((TAttributeRequirement)(tgcomponent[0])).getViolatedAction();
+        return violatedAction;
     }
     
     public String getText() {
-        return ((TAttributeRequirement)(tgcomponent[0])).getText();
+        return text;
     }
     
     public int getCriticality() {
-         return ((TAttributeRequirement)(tgcomponent[0])).getCriticality();
+        //System.out.println("Criticality=" + criticality);
+        if (criticality.compareTo("High") == 0) {
+            return Requirement.HIGH;
+        } else if (criticality.compareTo("Medium") == 0) {
+            return Requirement.MEDIUM;
+        } else {
+            return Requirement.LOW;
+        }
     }
+	
+	public String getAttributes() {
+		String attr = "";
+		if (formal) {
+			attr += "TRDD= " + text + "\n";
+		} else {
+			attr += "Text= " + text + "\n";
+		}
+		attr += "Type= " + kind + "\n";
+		attr += "Risk= " + criticality + "\n";
+		return attr;
+	}
+	
+	public void autoAdjust(int mode) {
+		//System.out.println("Auto adjust in mode = " + mode);
+		
+		if (graphics == null) {
+			return;
+		}
+		
+		// Must find for both modes which width is desirable
+		String s0, s1;
+		if (formal) {
+			s0 = FORMAL_REQ;
+			s1 = "TRDD=";
+		} else {
+			s0 = REGULAR_REQ;
+			s1 = "Text=";
+		}
+		
+		int w0 = graphics.getFontMetrics().stringWidth(s0);
+		int w1 = graphics.getFontMetrics().stringWidth(value);
+		int w2 = Math.max(w0, w1) + (2 * iconSize);
+		int w3, w4 = w2;
+		
+		
+		int i;
+		
+		if(texts.length == 1) {
+			w3 = graphics.getFontMetrics().stringWidth(s1 + "=\"" + texts[0] + "\"");
+			w4 = Math.max(w4, w3);
+		} else {
+			for(i=0; i<texts.length; i++) {
+				if (i == 0) {
+					w3 = graphics.getFontMetrics().stringWidth(s1 + "=\"" + texts[i]);
+				} else if (i == (texts.length - 1)) {
+					w3 = graphics.getFontMetrics().stringWidth(texts[i] + "\"");
+				} else {
+					w3 = graphics.getFontMetrics().stringWidth(texts[i]);
+				}
+				
+				w4 = Math.max(w4, w3+2);
+			}
+		}
+		w3 = graphics.getFontMetrics().stringWidth("Type=\"" + kind + "\"") + 2;
+		w4 = Math.max(w4, w3);
+		w3 = graphics.getFontMetrics().stringWidth("Risk=\"" + criticality + "\"") + 2;
+		w4 = Math.max(w4, w3);
+		
+		
+		if (mode == 1) {
+			resize(w4, lineHeight);
+			return;
+		}
+		
+		int h = ((texts.length + 3) * currentFontSize) + lineHeight;
+		
+		resize(w4, h);
+		
+	}
     
 }
diff --git a/src/ui/req/RequirementDiagramPanel.java b/src/ui/req/RequirementDiagramPanel.java
index 6a5810c466..7cbb84e327 100755
--- a/src/ui/req/RequirementDiagramPanel.java
+++ b/src/ui/req/RequirementDiagramPanel.java
@@ -51,7 +51,7 @@ import java.util.*;
 
 import ui.*;
 
-public class RequirementDiagramPanel extends TDiagramPanel {
+public class RequirementDiagramPanel extends TDiagramPanel implements TDPWithAttributes {
     public Vector validated, ignored;
     
     public  RequirementDiagramPanel(MainGUI mgui, TToolBar _ttb) {
@@ -92,7 +92,7 @@ public class RequirementDiagramPanel extends TDiagramPanel {
     }
     
     public String getXMLHead() {
-        return "<TRequirementDiagramPanel name=\"" + name + "\"" + sizeParam() + " >";
+        return "<TRequirementDiagramPanel name=\"" + name + "\"" + sizeParam() + zoomParam() + " >";
     }
     
     public String getXMLTail() {
@@ -148,60 +148,6 @@ public class RequirementDiagramPanel extends TDiagramPanel {
        return b;
    }*/
     
-    public void enhance() {
-        //System.out.println("enhance");
-        /*Vector v = new Vector();
-        Object o;
-        Iterator iterator = componentList.listIterator();
-         
-        while(iterator.hasNext()) {
-            o = iterator.next();
-            if (o instanceof IODStartState){
-                enhance(v, (IODStartState)o);
-            }
-        }
-         
-        mgui.changeMade(this, MOVE_CONNECTOR);
-        repaint();*/
-    }
-    
-    public void enhance(Vector v, TGComponent tgc) {
-        /*TGComponent tgc1;
-        TGConnector tgcon;
-        int i;
-         
-        //System.out.println("Enhancing: " + tgc);
-         
-        if (tgc == null) {
-            return;
-        }
-         
-        if (v.contains(tgc)) {
-            return;
-        }
-         
-        v.add(tgc);
-         
-        //System.out.println("Nb of nexts: " + tgc.getNbNext());
-        if (!(tgc instanceof IODStartState)) {
-            for(i=0; i<tgc.getNbNext(); i++) {
-                tgc1 = getNextTGComponent(tgc, i);
-                tgcon = getNextTGConnector(tgc, i);
-                if (tgcon.getAutomaticDrawing()) {
-                    if ((tgc1 != null) && (tgcon != null)) {
-                        tgcon.alignOrMakeSquareTGComponents();
-                    }
-                }
-            }
-        }
-         
-        // Explore next elements
-        for(i=0; i<tgc.getNbNext(); i++) {
-            tgc1 = getNextTGComponent(tgc, i);
-            enhance(v, tgc1);
-        }*/
-    }
-    
     public int nbOfVerifyStartingAt(TGComponent tgc) {
         ListIterator iterator = getComponentList().listIterator();
         TGComponent tgc1, tgc2;
@@ -240,6 +186,10 @@ public class RequirementDiagramPanel extends TDiagramPanel {
         
         return false;
     }
+	
+	public void enhance() {
+		autoAdjust();
+    }
     
 }
 
diff --git a/src/ui/req/RequirementDiagramToolBar.java b/src/ui/req/RequirementDiagramToolBar.java
index a279c72553..03037d798f 100755
--- a/src/ui/req/RequirementDiagramToolBar.java
+++ b/src/ui/req/RequirementDiagramToolBar.java
@@ -60,6 +60,12 @@ public class RequirementDiagramToolBar extends TToolBar {
     }
     
     protected void setActive(boolean b) {
+		mgui.actions[TGUIAction.ACT_ZOOM_MORE].setEnabled(b);
+		mgui.actions[TGUIAction.ACT_ZOOM_LESS].setEnabled(b);
+		
+		mgui.actions[TGUIAction.ACT_SHOW_ZOOM].setEnabled(b);
+		mgui.updateZoomInfo();
+		
         mgui.actions[TGUIAction.IOD_EDIT].setEnabled(b);
         mgui.actions[TGUIAction.UML_NOTE].setEnabled(b);
         mgui.actions[TGUIAction.CONNECTOR_COMMENT].setEnabled(b);
@@ -67,8 +73,10 @@ public class RequirementDiagramToolBar extends TToolBar {
         mgui.actions[TGUIAction.TREQ_OBSERVER].setEnabled(b);
         mgui.actions[TGUIAction.TREQ_VERIFY].setEnabled(b);
         mgui.actions[TGUIAction.TREQ_DERIVE].setEnabled(b);
-        
-
+		
+		mgui.actions[TGUIAction.ACT_TOGGLE_ATTR].setEnabled(b);
+		
+		mgui.actions[TGUIAction.ACT_ENHANCE].setEnabled(b);
         
     }
     
@@ -100,6 +108,16 @@ public class RequirementDiagramToolBar extends TToolBar {
         button.addMouseListener(mgui.mouseHandler);
         
         button = this.add(mgui.actions[TGUIAction.TREQ_VERIFY]);
+        button.addMouseListener(mgui.mouseHandler);
+		
+		this.addSeparator();
+		
+		button = this.add(mgui.actions[TGUIAction.ACT_TOGGLE_ATTR]);
+        button.addMouseListener(mgui.mouseHandler);
+		
+		this.addSeparator();
+         
+        button = this.add(mgui.actions[TGUIAction.ACT_ENHANCE]);
         button.addMouseListener(mgui.mouseHandler);
         
     }
diff --git a/src/ui/req/RequirementObserver.java b/src/ui/req/RequirementObserver.java
index fb9cdb9556..82d6548888 100755
--- a/src/ui/req/RequirementObserver.java
+++ b/src/ui/req/RequirementObserver.java
@@ -51,176 +51,240 @@ import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 
+import org.w3c.dom.*;
+
 import myutil.*;
 import ui.*;
+import ui.window.*;
 
-public class RequirementObserver extends TGCWithInternalComponent {
+public class RequirementObserver extends TGCScalableWithInternalComponent implements WithAttributes, TGAutoAdjust {
     public String oldValue;
     protected int textX = 5;
     protected int textY = 22;
-    protected int startFontSize = 10;
+	protected int lineHeight = 30;
+	private double dlineHeight = 0.0;
+    //protected int startFontSize = 10;
     protected Graphics graphics;
-    protected int iconSize = 30;
-    
+    //protected int iconSize = 30;
+	
+	private Font myFont, myFontB;
+	private int maxFontSize = 30;
+	private int minFontSize = 4;
+	private int currentFontSize = -1;
+	private boolean displayText = true;
+	
     protected final static String TOBSERVER = "<<TObserver>";
+	
+	protected String diagramText;
+	protected String violatedAction = "noAction";
+	
+	private int iconSize = 18;
+	private boolean iconIsDrawn = false;
     
     public RequirementObserver(int _x, int _y, int _minX, int _maxX, int _minY, int _maxY, boolean _pos, TGComponent _father, TDiagramPanel _tdp)  {
         super(_x, _y, _minX, _maxX, _minY, _maxY, _pos, _father, _tdp);
         
-        width = 200; height = 30;
-        minWidth = 200;
-        minDesiredWidth = 200;
-        minDesiredHeight = 30;
+        initScaling(200, 120);
+		oldScaleFactor = tdp.getZoom();
+		dlineHeight = lineHeight * oldScaleFactor;
+		lineHeight = (int)dlineHeight;
+		dlineHeight = dlineHeight - lineHeight;
+
+		minWidth = 1;
+        minHeight = lineHeight;
         
-        nbConnectingPoint = 5;
+        nbConnectingPoint = 12;
         connectingPoint = new TGConnectingPoint[nbConnectingPoint];
-        connectingPoint[0] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.0, .5);
-        connectingPoint[1] = new TGConnectingPointVerify(this, 0, 0, false, true, 1.0, 0.5);
-        connectingPoint[2] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.25, 0.0);
-        connectingPoint[3] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.5, 0.0);
-        connectingPoint[4] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.75, 0.0);
-        addTGConnectingPointsCommentTop();
+        connectingPoint[0] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.0, 0.25);
+        connectingPoint[1] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.0, 0.5);
+        connectingPoint[2] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.0, 0.75);
+        connectingPoint[3] = new TGConnectingPointVerify(this, 0, 0, false, true, 1.0, 0.25);
+        connectingPoint[4] = new TGConnectingPointVerify(this, 0, 0, false, true, 1.0, 0.5);
+        connectingPoint[5] = new TGConnectingPointVerify(this, 0, 0, false, true, 1.0, 0.75);
+        connectingPoint[6] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.25, 0.0);
+        connectingPoint[7] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.5, 0.0);
+        connectingPoint[8] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.75, 0.0);
+        connectingPoint[9] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.25, 1.0);
+		connectingPoint[10] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.5, 1.0);
+		connectingPoint[11] = new TGConnectingPointVerify(this, 0, 0, false, true, 0.75, 1.0);
+
+        addTGConnectingPointsCommentTop();    
         
-        nbInternalTGComponent = 1;
-        tgcomponent = new TGComponent[nbInternalTGComponent];
+        nbInternalTGComponent = 0;
+        //tgcomponent = new TGComponent[nbInternalTGComponent];
         
         int h = 1;
-        TAttributeObserver tgc0;
-        tgc0 = new TAttributeObserver(x, y+height+h, 0, 0, height + h, height+h, true, this, _tdp);
-        tgcomponent[0] = tgc0;
+        //TAttributeRequirement tgc0;
+        //tgc0 = new TAttributeRequirement(x, y+height+h, 0, 0, height + h, height+h, true, this, _tdp);
+        //tgcomponent[0] = tgc0;
         
         moveable = true;
         editable = true;
         removable = true;
- 
-        // Name of the requirement
+        userResizable = true;
+		multieditable = true;
+		
+        
+        // Name of the observer
         name = "RequirementObserver";
         value = "RequirementObserver";
+		//value = tdp.findRequirementName("Requirement_");
         oldValue = value;
         
         myImageIcon = IconManager.imgic104;
+		
+		diagramText = "no diagram";
         
         actionOnAdd();
     }
+	
     
-    public void recalculateSize() {
-        //System.out.println("Recalculate size of " + this);
-        int i, j;
-        
-        for(i=0; i<nbInternalTGComponent; i++) {
-            tgcomponent[i].calculateMyDesiredSize();
-        }
-        
-        int minW = getMyDesiredWidth();
-        for(i=0; i<nbInternalTGComponent; i++) {
-            minW = Math.max(minW, tgcomponent[i].getMinDesiredWidth());
-        }
-        
-        for(i=0; i<nbInternalTGComponent; i++) {
-            tgcomponent[i].forceSize(minW, tgcomponent[i].getMinDesiredHeight());
-        }
-        
-        forceSize(minW, getHeight());
-        
-        // Reposition all internal components
-        int h = getHeight();
-        for(i=0; i<nbInternalTGComponent; i++) {
-            tgcomponent[i].setCdRectangle(0, 0, h, h);
-            tgcomponent[i].setCd(tgcomponent[i].getX(), h);
-            h += tgcomponent[i].getHeight();
-        }
-    }
-    
-    public int getMyDesiredWidth() {
-        if (graphics == null) {
-            graphics = tdp.getGraphics();
-        }
-        if (graphics == null) {
-            return minWidth;
-        }
-        int size = graphics.getFontMetrics().stringWidth(value) + iconSize + 5;
-        minDesiredWidth = Math.max(size, minWidth);
-        return minDesiredWidth;
-    }
-    
-    
-    private int calculateDesiredWidth() {
-        return Math.max(minDesiredWidth, tgcomponent[0].getMinDesiredWidth());
-    }
-    
-    
-    public void internalDrawing(Graphics g) {
+   public void internalDrawing(Graphics g) {
+		Font f = g.getFont();
+		Font fold = f;
+		int w, c;
+		int size;
+		
         if (!tdp.isScaled()) {
             graphics = g;
         }
+		
+		if (((rescaled) && (!tdp.isScaled())) || myFont == null) {
+			currentFontSize = tdp.getFontSize();
+			//System.out.println("Rescaled, font size = " + currentFontSize + " height=" + height);
+			myFont = f.deriveFont((float)currentFontSize);
+			myFontB = myFont.deriveFont(Font.BOLD);
+			
+			if (rescaled) {
+				rescaled = false;
+			}
+		}
+		
+		if(currentFontSize <minFontSize) {
+			displayText = false;
+		} else {
+			displayText = true;
+		}
+		
+		int h  = g.getFontMetrics().getHeight();
         
-        Font f = g.getFont();
-        int size = f.getSize();
-        g.drawRect(x, y, width, height);
-        g.setColor(Color.yellow);
-        g.fillRect(x+1, y+1, width-1, height-1);
-        g.drawImage(IconManager.img8, x + width - 20, y + 6, Color.yellow, null);
-        ColorManager.setColor(g, getState(), 0);
-        g.setFont(f.deriveFont(Font.BOLD));
-        int w = g.getFontMetrics().stringWidth(value);
-        g.drawString(value, x + (width - w)/2, y + textY);
-        g.setFont(f.deriveFont((float)startFontSize));
-        w  =  g.getFontMetrics().stringWidth(TOBSERVER);
-        g.drawString(TOBSERVER, x + (width - w)/2, y + startFontSize);
-        g.setFont(f);
+		g.drawRect(x, y, width, height);
         
+		g.drawLine(x, y+lineHeight, x+width, y+lineHeight);
+		g.setColor(Color.yellow);
+        g.fillRect(x+1, y+1, width-1, lineHeight-1);
+		g.setColor(ColorManager.OBS_ATTRIBUTE_BOX);
+		g.fillRect(x+1, y+1+lineHeight, width-1, height-1-lineHeight);
+		ColorManager.setColor(g, getState(), 0);
+		if ((lineHeight > 23) && (width > 23)){
+			g.drawImage(IconManager.img8, x + width - iconSize + 1, y + 3, Color.yellow, null);
+		}
+		
+		if (displayText) {
+			size = currentFontSize - 2;
+			g.setFont(myFont.deriveFont((float)(myFont.getSize() - 2)));
+			drawLimitedString(g, TOBSERVER, x, y + size, width, 1);
+			size += currentFontSize;
+			g.setFont(myFontB);
+			w = g.getFontMetrics().stringWidth(value);
+			drawLimitedString(g, value, x, y + size, width, 1);
+			
+		}
+		
+		g.setFont(myFont);
+		
+		size = lineHeight + currentFontSize;
+		if (size < (height - 2)) {
+			drawLimitedString(g, "Diagram=\"" + diagramText + "\"", x + textX, y + size, width, 0);
+			size += currentFontSize;
+			// Violated action
+			if (size < (height - 2)) {
+				drawLimitedString(g, "Violated_Action=\"" + violatedAction + "\"", x + textX, y + size, width, 0);
+			}
+		}
+        g.setFont(f);
     }
     
-    public boolean editOndoubleClick(JFrame frame) {
+    public boolean editOndoubleClick(JFrame frame, int _x, int _y) {
         oldValue = value;
         
-        String text = getName() + ": ";
-        if (hasFather()) {
-            text = getTopLevelName() + " / " + text;
-        }
-        String s = (String)JOptionPane.showInputDialog(frame, text,
-        "setting value", JOptionPane.PLAIN_MESSAGE, IconManager.imgic101,
-        null,
-        getValue());
+		if ((displayText) && (_y <= (y + lineHeight))) {
+			String texti = getName() + ": ";
+			if (hasFather()) {
+				texti = getTopLevelName() + " / " + diagramText;
+			}
+			String s = (String)JOptionPane.showInputDialog(frame, texti,
+				"setting value", JOptionPane.PLAIN_MESSAGE, IconManager.imgic101,
+				null,
+				getValue());
+			
+			if ((s != null) && (s.length() > 0) && (!s.equals(oldValue))) {
+				//boolean b;
+				if (!TAttribute.isAValidId(s, false, false)) {
+					JOptionPane.showMessageDialog(frame,
+						"Could not change the name of the Requirement: the new name is not a valid name",
+						"Error",
+						JOptionPane.INFORMATION_MESSAGE);
+					return false;
+				}
+				
+				if (!tdp.isRequirementNameUnique(s)) {
+					JOptionPane.showMessageDialog(frame,
+						"Could not change the name of the Requirement: the new name is already in use",
+						"Error",
+						JOptionPane.INFORMATION_MESSAGE);
+					return false;
+				}
+				
+				
+				int size = graphics.getFontMetrics().stringWidth(s) + iconSize + 5;
+				minDesiredWidth = Math.max(size, minWidth);
+				if (minDesiredWidth != width) {
+					newSizeForSon(null);
+				}
+				setValue(s);
+				
+				if (tdp.actionOnDoubleClick(this)) {
+					return true;
+				} else {
+					JOptionPane.showMessageDialog(frame,
+						"Could not change the name of the Requirement: this name is already in use",
+						"Error",
+						JOptionPane.INFORMATION_MESSAGE);
+					setValue(oldValue);
+				}
+			}
+			return false;
+		} else {
+			return editAttributes();
+		}
         
-        if ((s != null) && (s.length() > 0) && (!s.equals(oldValue))) {
-            //boolean b;
-            if (!TAttribute.isAValidId(s, false, false)) {
-                JOptionPane.showMessageDialog(frame,
-                "Could not change the name of the Requirement: the new name is not a valid name",
-                "Error",
-                JOptionPane.INFORMATION_MESSAGE);
-                return false;
-            }
-            
-            if (!tdp.isRequirementNameUnique(s)) {
-                JOptionPane.showMessageDialog(frame,
-                "Could not change the name of the Requirement: the new name is already in use",
-                "Error",
-                JOptionPane.INFORMATION_MESSAGE);
-                return false;
-            }
-            
-            
-            int size = graphics.getFontMetrics().stringWidth(s) + iconSize + 5;
-            minDesiredWidth = Math.max(size, minWidth);
-            if (minDesiredWidth != width) {
-                newSizeForSon(null);
-            }
-            setValue(s);
-            
-            if (tdp.actionOnDoubleClick(this)) {
-                return true;
-            } else {
-                JOptionPane.showMessageDialog(frame,
-                "Could not change the name of the Requirement: this name is already in use",
-                "Error",
-                JOptionPane.INFORMATION_MESSAGE);
-                setValue(oldValue);
-            }
-        }
-        return false;
     }
+	
+	public boolean editAttributes() {
+		JDialogObserver jdo = new JDialogObserver(tdp.getGUI().getFrame(), "Setting diagrams of Observer " + getRequirementObserverName(), diagramText, violatedAction);
+		jdo.setSize(750, 400);
+		GraphicLib.centerOnParent(jdo);
+		jdo.show();
+		
+		if (!jdo.isRegularClose()) {
+			return false;
+		}
+		
+		diagramText = jdo.getText();
+		violatedAction = jdo.getViolatedAction();
+		
+		return true;
+	}
+	
+	public void rescale(double scaleFactor){
+		dlineHeight = (lineHeight + dlineHeight) / oldScaleFactor * scaleFactor;
+		lineHeight = (int)(dlineHeight);
+		dlineHeight = dlineHeight - lineHeight; 
+		minHeight = lineHeight;
+		
+		super.rescale(scaleFactor);
+	}
     
     
     public TGComponent isOnOnlyMe(int x1, int y1) {
@@ -239,10 +303,6 @@ public class RequirementObserver extends TGCWithInternalComponent {
         return TGComponentManager.TREQ_OBSERVER;
     }
     
-    public void checkSizeOfSons() {
-        ((TAttributeObserver)(tgcomponent[0])).checkMySize();
-    }
-    
     public void addActionToPopupMenu(JPopupMenu componentMenu, ActionListener menuAL, int x, int y) {
         componentMenu.addSeparator();
         JMenuItem generate = null;
@@ -251,13 +311,19 @@ public class RequirementObserver extends TGCWithInternalComponent {
         
         generate.addActionListener(menuAL);
         componentMenu.add(generate);
+		
+		JMenuItem editAttributes = new JMenuItem("Edit attributes");
+		editAttributes.addActionListener(menuAL);
+		componentMenu.add(editAttributes);
     }
     
     public boolean eventOnPopup(ActionEvent e) {
         String s = e.getActionCommand();
         if (s.indexOf("diagrams") > -1) {
            // To be implemented!
-        }
+        } else {
+			return editAttributes();
+		}
         return true;
     }
     
@@ -265,15 +331,126 @@ public class RequirementObserver extends TGCWithInternalComponent {
         String ret =  getValue() + TOBSERVER;
         return ret;
     }
+	
+	public String getViolatedAction() {
+        return violatedAction;
+    }
     
     public String getDiagramName() {
-        return ((TAttributeObserver)(tgcomponent[0])).getValue().trim();
+        return diagramText;
+    }
+	
+	 public String[] getDiagramNames() {
+		 String texts[] = new String[1];
+		 texts[0] = diagramText;
+		 return texts;
     }
     
-    public String[] getDiagramNames() {
-        TAttributeObserver tao = (TAttributeObserver)(tgcomponent[0]);
-        String []ret = tao.getValue().trim().split("((\\s)+(\\r)*(\\n)*)+");
-        return ret;
+	protected String translateExtraParam() {
+        StringBuffer sb = new StringBuffer("<extraparam>\n");
+        sb.append("<diagramText data=\"");
+        sb.append(diagramText);
+		sb.append("\" />\n");
+		sb.append("<violated data=\"");
+        sb.append(violatedAction);
+        sb.append("\" />\n");
+        sb.append("</extraparam>\n");
+        return new String(sb);
+    }
+    
+    public void loadExtraParam(NodeList nl, int decX, int decY, int decId) throws MalformedModelingException{
+        try {
+            NodeList nli;
+            Node n1, n2;
+            Element elt;
+            //int access, type;
+            //String typeOther;
+            //String id, valueAtt;
+            String s;
+            
+            //System.out.println("Loading attributes");
+            //System.out.println(nl.toString());
+            
+            for(int i=0; i<nl.getLength(); i++) {
+                n1 = nl.item(i);
+                //System.out.println(n1);
+                if (n1.getNodeType() == Node.ELEMENT_NODE) {
+                    nli = n1.getChildNodes();
+                    for(int j=0; j<nli.getLength(); j++) {
+                        n2 = nli.item(j);
+                        //System.out.println(n2);
+                        if (n2.getNodeType() == Node.ELEMENT_NODE) {
+                            elt = (Element) n2;
+                            if (elt.getTagName().equals("diagramText")) {
+                                //System.out.println("Analyzing line");
+                                s = elt.getAttribute("data");
+                                if (s.equals("null")) {
+                                    s = "";
+                                }
+                               diagramText = s;
+                            } else if (elt.getTagName().equals("violated")) {
+                                //System.out.println("Analyzing line");
+                                violatedAction = elt.getAttribute("data");
+                                if (violatedAction.equals("null")) {
+                                    violatedAction = "";
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new MalformedModelingException();
+        }  
+        
     }
+	
+	public String getAttributes() {
+		String attr = "";
+		attr += "Diagram= " + diagramText + "\n";
+		attr += "Violated action = " + violatedAction + "\n";
+		return attr;
+	}
+	
+	public void autoAdjust(int mode) {
+		//System.out.println("Auto adjust in mode = " + mode);
+		
+		if (graphics == null) {
+			return;
+		}
+		
+		Font f = graphics.getFont();
+		Font f0 = f.deriveFont((float)currentFontSize);
+		Font f1 = f0.deriveFont(Font.BOLD);
+		Font f2 = f.deriveFont((float)(currentFontSize - 2));
+		
+		// Must find for both modes which width is desirable
+		String s0, s1;
+		
+		s0 = TOBSERVER;
+		
+		graphics.setFont(f2);
+		int w0 = graphics.getFontMetrics().stringWidth(s0);
+		graphics.setFont(f1);
+		int w1 = graphics.getFontMetrics().stringWidth(value);
+		int w2 = Math.max(w0, w1) + (2 * iconSize);
+		graphics.setFont(f0);
+		int w3 = graphics.getFontMetrics().stringWidth("Diagram=\"" + diagramText + "\"") + textX;
+		int w4 = graphics.getFontMetrics().stringWidth("Violated_Action=\"" + violatedAction + "\"") + textX;
+		graphics.setFont(f);
+		
+		w2 = Math.max(w2, w3);
+		w2 = Math.max(w2, w4);
+		
+		if (mode == 1) {
+			resize(w2, lineHeight);
+			return;
+		}
+		
+		int h = (3 * currentFontSize) + lineHeight;
+		
+		resize(w2, h);
+		
+	}
     
 }
\ No newline at end of file
diff --git a/src/ui/req/TGConnectorDerive.java b/src/ui/req/TGConnectorDerive.java
index bd59ad5ca7..ee0f3f99b0 100755
--- a/src/ui/req/TGConnectorDerive.java
+++ b/src/ui/req/TGConnectorDerive.java
@@ -68,9 +68,18 @@ public  class TGConnectorDerive extends TGConnector {
         GraphicLib.dashedArrowWithLine(g, 1, 1, 0, x1, y1, x2, y2, false);
         
         // Indicate semantics
+		
+		Font f = g.getFont();
+		Font old = f;
+		if (f.getSize() != tdp.getFontSize()) {
+			f = f.deriveFont((float)tdp.getFontSize());
+			g.setFont(f);
+		}
+		
         w  = g.getFontMetrics().stringWidth(value);
         h = g.getFontMetrics().getHeight();
         g.drawString(value, (p1.getX() + p2.getX() - w) / 2, (p1.getY() + p2.getY())/2);
+		g.setFont(old);
     }
     
     public TGComponent extraIsOnOnlyMe(int x1, int y1) {
diff --git a/src/ui/req/TGConnectorVerify.java b/src/ui/req/TGConnectorVerify.java
index 55671fb5ac..ce9bc49474 100755
--- a/src/ui/req/TGConnectorVerify.java
+++ b/src/ui/req/TGConnectorVerify.java
@@ -63,13 +63,19 @@ public  class TGConnectorVerify extends TGConnector {
     }
     
     protected void drawLastSegment(Graphics g, int x1, int y1, int x2, int y2){
-        //g.drawLine(x1, y1, x2, y2);
-        GraphicLib.dashedArrowWithLine(g, 1, 1, 0, x1, y1, x2, y2, false);
+		GraphicLib.dashedArrowWithLine(g, 1, 1, 0, x1, y1, x2, y2, false);
         
-        // Indicate semantics 
+        Font f = g.getFont();
+		Font old = f;
+		if (f.getSize() != tdp.getFontSize()) {
+			f = f.deriveFont((float)tdp.getFontSize());
+			g.setFont(f);
+		}
+		
         w  = g.getFontMetrics().stringWidth(value);
         h = g.getFontMetrics().getHeight();
         g.drawString(value, (p1.getX() + p2.getX() - w) / 2, (p1.getY() + p2.getY())/2);
+		g.setFont(old);
     }
     
     public TGComponent extraIsOnOnlyMe(int x1, int y1) {
-- 
GitLab