This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new 1c27968a36 Add support for resizing notes #6056 (#6134)
1c27968a36 is described below

commit 1c27968a36a3081c900b4bda5730f87b13b9d0c5
Author: Nicolas Adment <[email protected]>
AuthorDate: Sun Dec 7 14:18:24 2025 +0100

    Add support for resizing notes #6056 (#6134)
    
    - Improve click handling by layering interactions (area owners, hops, 
notes, background).
    - Clearer cursor changes during operations.
    - The viewport is now on the top layer.
    - Fix `previousTransformLocations` with `previousActionLocations` for 
better naming consistency.
    - Add gui action to bring a note to front or send to back
    - Add i18n to pipeline contextual action categories
---
 .../main/java/org/apache/hop/core/NotePadMeta.java |  41 +-
 .../java/org/apache/hop/core/gui/BasePainter.java  | 128 +++---
 .../java/org/apache/hop/workflow/WorkflowMeta.java |   8 +-
 .../main/java/org/apache/hop/ui/core/PropsUi.java  |  34 +-
 .../apache/hop/ui/hopgui/dialog/NotePadDialog.java |   1 +
 .../hopgui/file/pipeline/HopGuiPipelineGraph.java  | 354 +++++++++------
 .../ui/hopgui/file/shared/HopGuiAbstractGraph.java | 194 ++++++++-
 .../hopgui/file/workflow/HopGuiWorkflowGraph.java  | 474 +++++++++++++--------
 .../perspective/execution/DragViewZoomBase.java    |  28 +-
 .../pipeline/messages/messages_en_US.properties    |   9 +
 .../workflow/messages/messages_en_US.properties    |   5 +
 ui/src/main/resources/ui/images/bring-to-front.svg |  12 +
 ui/src/main/resources/ui/images/send-to-back.svg   |  14 +
 13 files changed, 876 insertions(+), 426 deletions(-)

diff --git a/engine/src/main/java/org/apache/hop/core/NotePadMeta.java 
b/engine/src/main/java/org/apache/hop/core/NotePadMeta.java
index 24679dc72c..e6d11bb2ac 100644
--- a/engine/src/main/java/org/apache/hop/core/NotePadMeta.java
+++ b/engine/src/main/java/org/apache/hop/core/NotePadMeta.java
@@ -17,6 +17,8 @@
 
 package org.apache.hop.core;
 
+import lombok.Getter;
+import lombok.Setter;
 import org.apache.hop.core.exception.HopXmlException;
 import org.apache.hop.core.gui.IGuiPosition;
 import org.apache.hop.core.gui.IGuiSize;
@@ -89,6 +91,9 @@ public class NotePadMeta implements Cloneable, IGuiPosition, 
IGuiSize {
   @HopMetadataProperty public int width;
   @HopMetadataProperty public int height;
 
+  @Getter @Setter private int minimumWidth;
+  @Getter @Setter private int minimumHeight;
+
   private boolean selected;
   private boolean changed;
 
@@ -115,11 +120,11 @@ public class NotePadMeta implements Cloneable, 
IGuiPosition, IGuiSize {
   }
 
   public NotePadMeta(
-      String n,
-      int xl,
-      int yl,
-      int w,
-      int h,
+      String note,
+      int x,
+      int y,
+      int width,
+      int height,
       String fontName,
       int fontSize,
       boolean fontBold,
@@ -127,16 +132,16 @@ public class NotePadMeta implements Cloneable, 
IGuiPosition, IGuiSize {
       int fontColorRed,
       int fontColorGreen,
       int fontColorBlue,
-      int backGrounColorRed,
-      int backGrounColorGreen,
-      int backGrounColorBlue,
+      int backGroundColorRed,
+      int backGroundColorGreen,
+      int backGroundColorBlue,
       int borderColorRed,
       int borderColorGreen,
       int borderColorBlue) {
-    this.note = n;
-    this.location = new Point(xl, yl);
-    this.width = w;
-    this.height = h;
+    this.note = note;
+    this.location = new Point(x, y);
+    this.width = width;
+    this.height = height;
     this.selected = false;
     this.fontName = fontName;
     this.fontSize = fontSize;
@@ -147,9 +152,9 @@ public class NotePadMeta implements Cloneable, 
IGuiPosition, IGuiSize {
     this.fontColorGreen = fontColorGreen;
     this.fontColorBlue = fontColorBlue;
     // background color
-    this.backGroundColorRed = backGrounColorRed;
-    this.backGroundColorGreen = backGrounColorGreen;
-    this.backGroundColorBlue = backGrounColorBlue;
+    this.backGroundColorRed = backGroundColorRed;
+    this.backGroundColorGreen = backGroundColorGreen;
+    this.backGroundColorBlue = backGroundColorBlue;
     // border color
     this.borderColorRed = borderColorRed;
     this.borderColorGreen = borderColorGreen;
@@ -354,6 +359,9 @@ public class NotePadMeta implements Cloneable, 
IGuiPosition, IGuiSize {
    */
   @Override
   public void setHeight(int height) {
+    if (this.height != height) {
+      setChanged();
+    }
     this.height = height;
   }
 
@@ -370,6 +378,9 @@ public class NotePadMeta implements Cloneable, 
IGuiPosition, IGuiSize {
    */
   @Override
   public void setWidth(int width) {
+    if (this.width != width) {
+      setChanged();
+    }
     this.width = width;
   }
 
diff --git a/engine/src/main/java/org/apache/hop/core/gui/BasePainter.java 
b/engine/src/main/java/org/apache/hop/core/gui/BasePainter.java
index 62dd45e487..ef312afca3 100644
--- a/engine/src/main/java/org/apache/hop/core/gui/BasePainter.java
+++ b/engine/src/main/java/org/apache/hop/core/gui/BasePainter.java
@@ -127,102 +127,90 @@ public abstract class BasePainter<Hop extends 
BaseHopMeta<?>, Part extends IBase
   }
 
   public static EImage getStreamIconImage(StreamIcon streamIcon, boolean 
enabled) {
-    switch (streamIcon) {
-      case TRUE:
-        return (enabled) ? EImage.TRUE : EImage.TRUE_DISABLED;
-      case FALSE:
-        return (enabled) ? EImage.FALSE : EImage.FALSE_DISABLED;
-      case ERROR:
-        return (enabled) ? EImage.ERROR : EImage.ERROR_DISABLED;
-      case INFO:
-        return (enabled) ? EImage.INFO : EImage.INFO_DISABLED;
-      case TARGET:
-        return (enabled) ? EImage.TARGET : EImage.TARGET_DISABLED;
-      case INPUT:
-        return EImage.INPUT;
-      case OUTPUT:
-        return EImage.OUTPUT;
-      default:
-        return EImage.ARROW_DEFAULT;
+    return switch (streamIcon) {
+      case TRUE -> (enabled) ? EImage.TRUE : EImage.TRUE_DISABLED;
+      case FALSE -> (enabled) ? EImage.FALSE : EImage.FALSE_DISABLED;
+      case ERROR -> (enabled) ? EImage.ERROR : EImage.ERROR_DISABLED;
+      case INFO -> (enabled) ? EImage.INFO : EImage.INFO_DISABLED;
+      case TARGET -> (enabled) ? EImage.TARGET : EImage.TARGET_DISABLED;
+      case INPUT -> EImage.INPUT;
+      case OUTPUT -> EImage.OUTPUT;
+      default -> EImage.ARROW_DEFAULT;
+    };
+  }
+
+  protected Point calculateMinimumSize(NotePadMeta note) {
+    if (Utils.isEmpty(note.getNote())) {
+      return new Point(20, 20); // Empty note
     }
+
+    int fontHeight;
+    if (note.getFontSize() > 0) {
+      fontHeight = note.getFontSize();
+    } else {
+      fontHeight = noteFontHeight;
+    }
+    gc.setFont(
+        Const.NVL(note.getFontName(), noteFontName),
+        (int) ((double) fontHeight / zoomFactor),
+        note.isFontBold(),
+        note.isFontItalic());
+
+    Point size = gc.textExtent(note.getNote());
+    size.x += 2 * Const.NOTE_MARGIN;
+    size.y += 2 * Const.NOTE_MARGIN;
+
+    return size;
   }
 
-  protected void drawNote(NotePadMeta notePadMeta) {
-    if (notePadMeta.isSelected()) {
+  protected void drawNote(NotePadMeta noteMeta) {
+    if (noteMeta.isSelected()) {
       gc.setLineWidth(2);
     } else {
       gc.setLineWidth(1);
     }
 
-    Point ext;
-    if (Utils.isEmpty(notePadMeta.getNote())) {
-      ext = new Point(10, 10); // Empty note
-    } else {
+    Point minimumSize = this.calculateMinimumSize(noteMeta);
 
-      int fontHeight;
-      if (notePadMeta.getFontSize() > 0) {
-        fontHeight = notePadMeta.getFontSize();
-      } else {
-        fontHeight = noteFontHeight;
-      }
-      gc.setFont(
-          Const.NVL(notePadMeta.getFontName(), noteFontName),
-          (int) ((double) fontHeight / zoomFactor),
-          notePadMeta.isFontBold(),
-          notePadMeta.isFontItalic());
+    // Cache the minimum size for resize operation
+    noteMeta.setMinimumWidth(minimumSize.x);
+    noteMeta.setMinimumHeight(minimumSize.y);
 
-      ext = gc.textExtent(notePadMeta.getNote());
-    }
-    Point p = new Point(ext.x, ext.y);
-    Point loc = notePadMeta.getLocation();
+    Point loc = noteMeta.getLocation();
     Point note = real2screen(loc.x, loc.y);
-    int margin = Const.NOTE_MARGIN;
-    p.x += 2 * margin;
-    p.y += 2 * margin;
-    int width = notePadMeta.width;
-    int height = notePadMeta.height;
-    if (p.x > width) {
-      width = p.x;
+
+    int width = noteMeta.width;
+    int height = noteMeta.height;
+    if (minimumSize.x > width) {
+      width = minimumSize.x;
     }
-    if (p.y > height) {
-      height = p.y;
+    if (minimumSize.y > height) {
+      height = minimumSize.y;
     }
-
     Rectangle noteShape = new Rectangle(note.x, note.y, width, height);
 
     gc.setBackground(
-        notePadMeta.getBackGroundColorRed(),
-        notePadMeta.getBackGroundColorGreen(),
-        notePadMeta.getBackGroundColorBlue());
+        noteMeta.getBackGroundColorRed(),
+        noteMeta.getBackGroundColorGreen(),
+        noteMeta.getBackGroundColorBlue());
     gc.setForeground(
-        notePadMeta.getBorderColorRed(),
-        notePadMeta.getBorderColorGreen(),
-        notePadMeta.getBorderColorBlue());
+        noteMeta.getBorderColorRed(),
+        noteMeta.getBorderColorGreen(),
+        noteMeta.getBorderColorBlue());
 
     // Radius is half the font height
     //
-    int radius = (int) Math.round(zoomFactor * notePadMeta.getFontSize() / 2);
+    int radius = (int) Math.round(zoomFactor * 8);
 
     gc.fillRoundRectangle(
         noteShape.x, noteShape.y, noteShape.width, noteShape.height, radius, 
radius);
     gc.drawRoundRectangle(
         noteShape.x, noteShape.y, noteShape.width, noteShape.height, radius, 
radius);
 
-    if (!Utils.isEmpty(notePadMeta.getNote())) {
+    if (!Utils.isEmpty(noteMeta.getNote())) {
       gc.setForeground(
-          notePadMeta.getFontColorRed(),
-          notePadMeta.getFontColorGreen(),
-          notePadMeta.getFontColorBlue());
-      gc.drawText(notePadMeta.getNote(), note.x + margin, note.y + margin, 
true);
-    }
-
-    notePadMeta.width = width; // Save for the "mouse" later on...
-    notePadMeta.height = height;
-
-    if (notePadMeta.isSelected()) {
-      gc.setLineWidth(1);
-    } else {
-      gc.setLineWidth(2);
+          noteMeta.getFontColorRed(), noteMeta.getFontColorGreen(), 
noteMeta.getFontColorBlue());
+      gc.drawText(noteMeta.getNote(), note.x + Const.NOTE_MARGIN, note.y + 
Const.NOTE_MARGIN, true);
     }
 
     // Add to the list of areas...
@@ -236,7 +224,7 @@ public abstract class BasePainter<Hop extends 
BaseHopMeta<?>, Part extends IBase
             noteShape.height,
             offset,
             subject,
-            notePadMeta));
+            noteMeta));
   }
 
   protected Point real2screen(int x, int y) {
diff --git a/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java 
b/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java
index fd69ee1021..54ea897961 100644
--- a/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java
+++ b/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java
@@ -1278,9 +1278,9 @@ public class WorkflowMeta extends AbstractMeta
   }
 
   /**
-   * Gets the selected locations.
+   * Gets the selected actions locations.
    *
-   * @return the selected locations
+   * @return the selected actions locations
    */
   public Point[] getSelectedLocations() {
     List<ActionMeta> actions = getSelectedActions();
@@ -1294,9 +1294,9 @@ public class WorkflowMeta extends AbstractMeta
   }
 
   /**
-   * Get all the selected note locations
+   * Get all the selected notes locations
    *
-   * @return The selected transform and notes locations.
+   * @return The selected notes locations.
    */
   public Point[] getSelectedNoteLocations() {
     List<Point> points = new ArrayList<>();
diff --git a/ui/src/main/java/org/apache/hop/ui/core/PropsUi.java 
b/ui/src/main/java/org/apache/hop/ui/core/PropsUi.java
index 9dc962af80..3b19e7dfac 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/PropsUi.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/PropsUi.java
@@ -23,6 +23,7 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.hop.core.Const;
 import org.apache.hop.core.Props;
 import org.apache.hop.core.gui.IGuiPosition;
+import org.apache.hop.core.gui.IGuiSize;
 import org.apache.hop.core.gui.Point;
 import org.apache.hop.core.logging.LogChannel;
 import org.apache.hop.core.util.Utils;
@@ -907,8 +908,8 @@ public class PropsUi extends Props {
       // Snap to grid...
       //
       return new Point(
-          gridSize * Math.round((float) p.x / gridSize),
-          gridSize * Math.round((float) p.y / gridSize));
+          gridSize * (int) Math.round((float) (p.x / gridSize)),
+          gridSize * (int) Math.round((float) (p.y / gridSize)));
     } else {
       // Normal draw
       //
@@ -916,6 +917,35 @@ public class PropsUi extends Props {
     }
   }
 
+  /**
+   * Sets the size of a given GUI element, ensuring that the width and height 
do not fall below a
+   * predefined minimum size. The size is adjusted to align with a grid 
through calculation.
+   *
+   * @param element the GUI element whose size is to be set
+   * @param width the desired width of the element
+   * @param height the desired height of the element
+   */
+  public static void setSize(IGuiSize element, int width, int height) {
+
+    if (width < ConstUi.NOTE_MIN_SIZE) {
+      width = ConstUi.NOTE_MIN_SIZE;
+    }
+    if (height < ConstUi.NOTE_MIN_SIZE) {
+      height = ConstUi.NOTE_MIN_SIZE;
+    }
+    int gridSize = PropsUi.getInstance().getCanvasGridSize();
+    if (gridSize > 1) {
+      int w = width / gridSize;
+      if (width % gridSize > 0) w += 1;
+      int h = height / gridSize;
+      if (height % gridSize > 0) h += 1;
+      width = gridSize * w;
+      height = gridSize * h;
+    }
+    element.setWidth(width);
+    element.setHeight(height);
+  }
+
   public boolean isIndicateSlowPipelineTransformsEnabled() {
     String indicate = getProperty(STRING_INDICATE_SLOW_PIPELINE_TRANSFORMS, 
"Y");
     return YES.equalsIgnoreCase(indicate);
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/dialog/NotePadDialog.java 
b/ui/src/main/java/org/apache/hop/ui/hopgui/dialog/NotePadDialog.java
index d742bd13c7..ca8a5c9c8d 100644
--- a/ui/src/main/java/org/apache/hop/ui/hopgui/dialog/NotePadDialog.java
+++ b/ui/src/main/java/org/apache/hop/ui/hopgui/dialog/NotePadDialog.java
@@ -252,6 +252,7 @@ public class NotePadDialog extends Dialog {
             refreshTextNote();
           }
         });
+    PropsUi.setLook(wFontSize);
 
     // Font bold?
     Label wlFontBold = new Label(wNoteFontComp, SWT.RIGHT);
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
index e38f3269a0..877fc21084 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiPipelineGraph.java
@@ -569,7 +569,7 @@ public class HopGuiPipelineGraph extends HopGuiAbstractGraph
   }
 
   @Override
-  public void mouseDoubleClick(MouseEvent e) {
+  public void mouseDoubleClick(MouseEvent event) {
 
     if (!PropsUi.getInstance().useDoubleClick()) {
       return;
@@ -578,7 +578,7 @@ public class HopGuiPipelineGraph extends HopGuiAbstractGraph
     doubleClick = true;
     clearSettings();
 
-    Point real = screen2real(e.x, e.y);
+    Point real = screen2real(event.x, event.y);
 
     // Hide the tooltip!
     hideToolTips();
@@ -586,7 +586,8 @@ public class HopGuiPipelineGraph extends HopGuiAbstractGraph
     AreaOwner areaOwner = getVisibleAreaOwner(real.x, real.y);
 
     try {
-      HopGuiPipelineGraphExtension ext = new 
HopGuiPipelineGraphExtension(this, e, real, areaOwner);
+      HopGuiPipelineGraphExtension ext =
+          new HopGuiPipelineGraphExtension(this, event, real, areaOwner);
       ExtensionPointHandler.callExtensionPoint(
           LogChannel.GENERAL, variables, 
HopExtensionPoint.PipelineGraphMouseDoubleClick.id, ext);
       if (ext.isPreventingDefault()) {
@@ -599,7 +600,7 @@ public class HopGuiPipelineGraph extends HopGuiAbstractGraph
 
     TransformMeta transformMeta = pipelineMeta.getTransform(real.x, real.y, 
iconSize);
     if (transformMeta != null) {
-      if (e.button == 1) {
+      if (event.button == 1) {
         editTransform(transformMeta);
       } else {
         editDescription(transformMeta);
@@ -633,21 +634,22 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
   }
 
   @Override
-  public void mouseDown(MouseEvent e) {
+  public void mouseDown(MouseEvent event) {
     if (EnvironmentUtils.getInstance().isWeb()) {
       // RAP does not support certain mouse events.
-      mouseHover(e);
+      mouseHover(event);
     }
     doubleClick = false;
     mouseMovedSinceClick = false;
+    resize = null;
 
-    boolean alt = (e.stateMask & SWT.ALT) != 0;
-    boolean control = (e.stateMask & SWT.MOD1) != 0;
-    boolean shift = (e.stateMask & SWT.SHIFT) != 0;
+    boolean alt = (event.stateMask & SWT.ALT) != 0;
+    boolean control = (event.stateMask & SWT.MOD1) != 0;
+    boolean shift = (event.stateMask & SWT.SHIFT) != 0;
 
-    lastButton = e.button;
-    Point real = screen2real(e.x, e.y);
+    Point real = screen2real(event.x, event.y);
     lastClick = new Point(real.x, real.y);
+    lastButton = event.button;
 
     // Hide the tooltip!
     hideToolTips();
@@ -655,7 +657,8 @@ public class HopGuiPipelineGraph extends HopGuiAbstractGraph
     AreaOwner areaOwner = getVisibleAreaOwner(real.x, real.y);
 
     try {
-      HopGuiPipelineGraphExtension ext = new 
HopGuiPipelineGraphExtension(this, e, real, areaOwner);
+      HopGuiPipelineGraphExtension ext =
+          new HopGuiPipelineGraphExtension(this, event, real, areaOwner);
       ExtensionPointHandler.callExtensionPoint(
           LogChannel.GENERAL, variables, 
HopExtensionPoint.PipelineGraphMouseDown.id, ext);
       if (ext.isPreventingDefault()) {
@@ -665,14 +668,26 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       LogChannel.GENERAL.logError("Error calling PipelineGraphMouseDown 
extension point", ex);
     }
 
+    // Layer 0: See if we're dragging around the view-port over the pipeline 
graph.
+    //
+    Point clickScreen = new Point(event.x, event.y);
+    if (setupDragViewPort(clickScreen)) {
+      return;
+    }
+
     // A single left or middle click on one of the area owners...
     //
+    boolean done = false;
+
+    // Layer 1: Click on an area owner except note (else if a note is present 
in the background,
+    // you cannot click the hop link).
     if (areaOwner != null && areaOwner.getAreaType() != null) {
       switch (areaOwner.getAreaType()) {
         case TRANSFORM_INFO_ICON:
           // Click on the transform info icon means: Edit transformation 
description
           //
           this.editDescription((TransformMeta) areaOwner.getOwner());
+          done = true;
           break;
 
         case HOP_INFO_ICON:
@@ -680,6 +695,7 @@ public class HopGuiPipelineGraph extends HopGuiAbstractGraph
           //
           pipelineTransformDelegate.editTransform(
               pipelineMeta, (TransformMeta) areaOwner.getOwner());
+          done = true;
           break;
 
         case TRANSFORM_TARGET_HOP_ICON:
@@ -687,9 +703,11 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
           //
           pipelineTransformDelegate.editTransform(
               pipelineMeta, (TransformMeta) areaOwner.getParent());
+          done = true;
           break;
 
         case HOP_COPY_ICON:
+          done = true;
           break;
 
         case HOP_ERROR_ICON:
@@ -697,6 +715,11 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
           //
           pipelineTransformDelegate.editTransformErrorHandling(
               pipelineMeta, (TransformMeta) areaOwner.getParent());
+          done = true;
+          break;
+
+        case TRANSFORM_NAME:
+          done = true;
           break;
 
         case TRANSFORM_ICON:
@@ -707,7 +730,7 @@ public class HopGuiPipelineGraph extends HopGuiAbstractGraph
 
           if (candidate != null && !OsHelper.isMac()) {
             // Avoid duplicate pop-up for hop handling as candidate is never 
null? */
-            addCandidateAsHop(e.x, e.y);
+            addCandidateAsHop(event.x, event.y);
           }
 
           TransformMeta transformMeta = (TransformMeta) areaOwner.getOwner();
@@ -719,12 +742,12 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
 
           // ALT-Click: edit error handling
           //
-          if (e.button == 1 && alt && transformMeta.supportsErrorHandling()) {
+          if (event.button == 1 && alt && 
transformMeta.supportsErrorHandling()) {
             pipelineTransformDelegate.editTransformErrorHandling(pipelineMeta, 
transformMeta);
             return;
-          } else if (e.button == 1 && startHopTransform != null && 
endHopTransform == null) {
+          } else if (event.button == 1 && startHopTransform != null && 
endHopTransform == null) {
             candidate = new PipelineHopMeta(startHopTransform, 
currentTransform);
-          } else if (e.button == 2 || (e.button == 1 && shift)) {
+          } else if (event.button == 2 || (event.button == 1 && shift)) {
             // SHIFT CLICK is start of drag to create a new hop
             //
             canvas.setData("mode", "hop");
@@ -744,37 +767,31 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
             iconOffset = new Point(real.x - p.x, real.y - p.y);
           }
           redraw();
-          break;
-
-        case NOTE:
-          currentNotePad = (NotePadMeta) areaOwner.getOwner();
-          selectedNotes = pipelineMeta.getSelectedNotes();
-          selectedNote = currentNotePad;
-          Point loc = currentNotePad.getLocation();
-
-          previousNoteLocations = pipelineMeta.getSelectedNoteLocations();
-
-          noteOffset = new Point(real.x - loc.x, real.y - loc.y);
-
-          redraw();
+          done = true;
           break;
 
         case TRANSFORM_COPIES_TEXT:
           copies((TransformMeta) areaOwner.getOwner());
+          done = true;
           break;
 
         case TRANSFORM_DATA_SERVICE:
           editProperties(pipelineMeta, hopGui, PipelineDialog.Tabs.EXTRA_TAB);
+          done = true;
           break;
+
         default:
           break;
       }
-    } else {
+    }
+
+    // Layer 2: click on hop links between transforms
+    if (!done) {
       // hop links between transforms are found searching by (x,y) coordinates.
       PipelineHopMeta hop = findPipelineHop(real.x, real.y);
       if (hop != null) {
         // Delete hop with on click
-        if (e.button == 1 && shift && control) {
+        if (event.button == 1 && shift && control) {
           // Delete the hop
           pipelineHopDelegate.delHop(pipelineMeta, hop);
           updateGui();
@@ -782,7 +799,7 @@ public class HopGuiPipelineGraph extends HopGuiAbstractGraph
         // User held control and clicked a hop between steps - We want to flip 
the active state of
         // the hop.
         //
-        else if (e.button == 2 || (e.button == 1 && control)) {
+        else if (event.button == 2 || (event.button == 1 && control)) {
           hop.setEnabled(!hop.isEnabled());
           updateGui();
         } else {
@@ -790,38 +807,68 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
           //
           clickedPipelineHop = hop;
         }
-      } else {
-        // If we're dragging a candidate hop around and click on the 
background it simply needs to
-        // go away.
-        //
-        if (startHopTransform != null) {
-          startHopTransform = null;
-          candidate = null;
-          lastClick = null;
-          avoidContextDialog = true;
-          redraw();
-          return;
-        }
+        done = true;
+      }
+    }
 
-        // Dragging on the background?
-        // See if we're dragging around the view-port over the pipeline graph.
-        //
-        if (setupDragView(e.button, control, new Point(e.x, e.y))) {
-          return;
-        }
+    // Layer 3: click on a note
+    if (!done && areaOwner != null && areaOwner.getAreaType() == 
AreaOwner.AreaType.NOTE) {
+      currentNotePad = (NotePadMeta) areaOwner.getOwner();
+      selectedNotes = pipelineMeta.getSelectedNotes();
+      selectedNote = currentNotePad;
+      Point loc = currentNotePad.getLocation();
 
-        // No area-owner & no hop means : background click:
-        //
-        canvas.setData("mode", "select");
-        if (!control && e.button == 1) {
-          selectionRegion = new org.apache.hop.core.gui.Rectangle(real.x, 
real.y, 0, 0);
-        }
-        updateGui();
+      previousNoteLocations = pipelineMeta.getSelectedNoteLocations();
+
+      noteOffset = new Point(real.x - loc.x, real.y - loc.y);
+
+      resize = this.getResize(areaOwner.getArea(), real);
+      // Keep the original area of the resizing note
+      resizeArea =
+          new Rectangle(
+              currentNotePad.getLocation().x,
+              currentNotePad.getLocation().y,
+              currentNotePad.getWidth(),
+              currentNotePad.getHeight());
+
+      updateGui();
+      done = true;
+    }
+
+    // Layer 4: Click on the background of the graph
+    if (!done) {
+      // If we're dragging a candidate hop around and click on the background 
it simply needs to
+      // go away.
+      //
+      if (startHopTransform != null) {
+        startHopTransform = null;
+        candidate = null;
+        lastClick = null;
+        avoidContextDialog = true;
+        redraw();
+        return;
       }
+
+      // Click to drag the background
+      //
+      if (setupDragView(event.button, control, clickScreen)) {
+        return;
+      }
+
+      // Click to create a lasso
+      //
+      canvas.setData("mode", "select");
+      if (!control && event.button == 1) {
+        selectionRegion = new org.apache.hop.core.gui.Rectangle(real.x, 
real.y, 0, 0);
+        // Change cursor when selecting a region
+        setCursor(getDisplay().getSystemCursor(SWT.CURSOR_CROSS));
+      }
+      updateGui();
     }
+
     if (EnvironmentUtils.getInstance().isWeb()) {
       // RAP does not support certain mouse events.
-      mouseMove(e);
+      mouseMove(event);
     }
   }
 
@@ -835,6 +882,8 @@ public class HopGuiPipelineGraph extends HopGuiAbstractGraph
 
   @Override
   public void mouseUp(MouseEvent e) {
+    resize = null;
+
     // canvas.setData("mode", null); does not work.
     canvas.setData("mode", "null");
 
@@ -850,7 +899,6 @@ public class HopGuiPipelineGraph extends HopGuiAbstractGraph
       viewDrag = false;
       viewPortNavigation = false;
       viewPortStart = null;
-      setCursor(null);
       return;
     }
 
@@ -1034,6 +1082,13 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
               singleClick = true;
               singleClickType = SingleClickType.Note;
               singleClickNote = selectedNote;
+
+              // If the clicked note is not part of the current selection, 
cancel the current
+              // selection
+              if (!selectedNote.isSelected()) {
+                pipelineMeta.unselectAll();
+                selectedNote.setSelected(true);
+              }
             }
           } else {
             // Find out which Transforms & Notes are selected
@@ -1350,7 +1405,6 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
     noInputTransform = null;
     mouseMovedSinceClick = true;
     boolean doRedraw = false;
-    PipelineHopMeta hop = null;
 
     // disable the tooltip
     //
@@ -1372,6 +1426,13 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
     //
     lastMove = real;
 
+    // Resizing the current note
+    if (resize != null) {
+      resizeNote(selectedNote, real);
+      redraw();
+      return;
+    }
+
     if (iconOffset == null) {
       iconOffset = new Point(0, 0);
     }
@@ -1385,12 +1446,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
     // Moved over an area?
     //
     AreaOwner areaOwner = getVisibleAreaOwner(real.x, real.y);
-
-    // Moved over an hop?
-    //
-    if (areaOwner == null) {
-      hop = this.findPipelineHop(real.x, real.y);
-    }
+    Resize resizeOver = resize;
 
     try {
       HopGuiPipelineGraphExtension ext =
@@ -1404,19 +1460,27 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       LogChannel.GENERAL.logError("Error calling PipelineGraphMouseMoved 
extension point", ex);
     }
 
-    // Mouse over the name of the transform
-    //
-    if (!PropsUi.getInstance().useDoubleClick()) {
-      if (areaOwner != null && areaOwner.getAreaType() == 
AreaType.TRANSFORM_NAME) {
-        if (mouseOverName == null) {
-          doRedraw = true;
-        }
-        mouseOverName = (String) areaOwner.getOwner();
-      } else {
-        if (mouseOverName != null) {
-          doRedraw = true;
+    if (areaOwner != null) {
+      // Mouse over the name of the transform
+      //
+      if (!PropsUi.getInstance().useDoubleClick()) {
+        if (areaOwner.getAreaType() == AreaType.TRANSFORM_NAME) {
+          if (mouseOverName == null) {
+            doRedraw = true;
+          }
+          mouseOverName = (String) areaOwner.getOwner();
+        } else {
+          if (mouseOverName != null) {
+            doRedraw = true;
+          }
+          mouseOverName = null;
         }
-        mouseOverName = null;
+      }
+
+      // Mouse over a note
+      if (areaOwner.getAreaType() == AreaOwner.AreaType.NOTE) {
+        // Check if the mouse hovers over the border to resize
+        resizeOver = this.getResize(areaOwner.getArea(), real);
       }
     }
 
@@ -1538,9 +1602,9 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       }
     }
 
-    // Move around notes & transforms
+    // Move around notes and transforms
     //
-    if (selectedNote != null && lastButton == 1 && !shift) {
+    if (selectedNote != null && lastButton == 1 && !shift && resize == null) {
       /*
        * One or more notes are selected and moved around...
        *
@@ -1555,19 +1619,15 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
     }
 
     Cursor cursor = null;
-    // Change cursor when dragging view or view port
-    if (viewDrag || viewPortNavigation) {
-      cursor = getDisplay().getSystemCursor(SWT.CURSOR_SIZEALL);
-    }
-    // Change cursor when selecting a region
-    else if (selectionRegion != null) {
-      cursor = getDisplay().getSystemCursor(SWT.CURSOR_CROSS);
+    // Change the cursor when the mouse is on the resize edge of a note
+    if (resizeOver != null) {
+      cursor = getDisplay().getSystemCursor(resizeOver.getCursor());
     }
-    // Change cursor when hover an hop or an area that support hover
-    else if (hop != null
-        || (areaOwner != null
+    // Change cursor when the mouse is on a hop or an area that support 
hovering
+    else if ((areaOwner != null
             && areaOwner.getAreaType() != null
-            && areaOwner.getAreaType().isSupportHover())) {
+            && areaOwner.getAreaType().isSupportHover())
+        || this.findPipelineHop(real.x, real.y) != null) {
       cursor = getDisplay().getSystemCursor(SWT.CURSOR_HAND);
     }
     setCursor(cursor);
@@ -2111,7 +2171,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::System.Button.Help",
       tooltip = "i18n::System.Tooltip.Help",
       image = "ui/images/help.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void openTransformHelp(HopGuiPipelineTransformContext context) {
     IPlugin plugin =
@@ -2128,7 +2188,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.TransformAction.DetachTransform.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.TransformAction.DetachTransform.Tooltip",
       image = "ui/images/hop-delete.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void detachTransform(HopGuiPipelineTransformContext context) {
     TransformMeta transformMeta = context.getTransformMeta();
@@ -2194,7 +2254,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.TransformAction.EditTransform.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.TransformAction.EditTransform.Tooltip",
       image = "ui/images/edit.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void editTransform(HopGuiPipelineTransformContext context) {
     editTransform(context.getTransformMeta());
@@ -2212,7 +2272,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.TransformAction.EditDescription.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.TransformAction.EditDescription.Tooltip",
       image = "ui/images/edit-description.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void editDescription(HopGuiPipelineTransformContext context) {
     editDescription(context.getTransformMeta());
@@ -2225,7 +2285,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.TransformAction.DistributeRows.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.TransformAction.DistributeRows.Tooltip",
       image = "ui/images/distribute.svg",
-      category = "Data routing",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Routing.Text",
       categoryOrder = "2")
   public void setDistributes(HopGuiPipelineTransformContext context) {
     context.getTransformMeta().setDistributes(true);
@@ -2240,7 +2300,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.TransformAction.CopyRows.Name",
       tooltip = "i18n::HopGuiPipelineGraph.TransformAction.CopyRows.Tooltip",
       image = "ui/images/copy-rows.svg",
-      category = "Data routing",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Routing.Text",
       categoryOrder = "2")
   public void setCopies(HopGuiPipelineTransformContext context) {
     context.getTransformMeta().setDistributes(false);
@@ -2295,7 +2355,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.TransformAction.SpecifyCopies.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.TransformAction.SpecifyCopies.Tooltip",
       image = "ui/images/exponent.svg",
-      category = "Data routing",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Routing.Text",
       categoryOrder = "2")
   public void copies(HopGuiPipelineTransformContext context) {
     TransformMeta transformMeta = context.getTransformMeta();
@@ -2339,7 +2399,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.TransformAction.DeleteTransform.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.TransformAction.DeleteTransform.Tooltip",
       image = "ui/images/delete.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void delTransform(HopGuiPipelineTransformContext context) {
     delSelected(context.getTransformMeta());
@@ -2352,7 +2412,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = 
"i18n::HopGuiPipelineGraph.TransformAction.Transform.ShowInputFields.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.TransformAction.Transform.ShowInputFields.Tooltip",
       image = "ui/images/input.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void fieldsBefore(HopGuiPipelineTransformContext context) {
     selectedTransforms = null;
@@ -2366,7 +2426,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = 
"i18n::HopGuiPipelineGraph.TransformAction.Transform.ShowOutputFields.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.TransformAction.Transform.ShowOutputFields.Tooltip",
       image = "ui/images/output.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void fieldsAfter(HopGuiPipelineTransformContext context) {
     selectedTransforms = null;
@@ -2389,7 +2449,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.HopAction.EnableHop.Name",
       tooltip = "i18n::HopGuiPipelineGraph.HopAction.EnableHop.Tooltip",
       image = "ui/images/hop.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void enableHop(HopGuiPipelineHopContext context) {
     PipelineHopMeta hop = context.getHopMeta();
@@ -2486,7 +2546,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.HopAction.DisableHop.Name",
       tooltip = "i18n::HopGuiPipelineGraph.HopAction.DisableHop.Tooltip",
       image = "ui/images/hop-disable.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void disableHop(HopGuiPipelineHopContext context) {
     PipelineHopMeta hopMeta = context.getHopMeta();
@@ -2512,7 +2572,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.HopAction.DeleteHop.Name",
       tooltip = "i18n::HopGuiPipelineGraph.HopAction.DeleteHop.Tooltip",
       image = "ui/images/hop-delete.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void deleteHop(HopGuiPipelineHopContext context) {
     pipelineHopDelegate.delHop(pipelineMeta, context.getHopMeta());
@@ -2534,7 +2594,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = 
"i18n::HopGuiPipelineGraph.HopAction.EnableBetweenSelectedTransforms.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.HopAction.EnableBetweenSelectedTransforms.Tooltip",
       image = "ui/images/hop-enable-between-selected.svg",
-      category = "Bulk",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Bulk.Text",
       categoryOrder = "2")
   public void enableHopsBetweenSelectedTransforms(final 
HopGuiPipelineHopContext context) {
     enableHopsBetweenSelectedTransforms(true);
@@ -2547,7 +2607,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = 
"i18n::HopGuiPipelineGraph.HopAction.DisableBetweenSelectedTransforms.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.HopAction.DisableBetweenSelectedTransforms.Tooltip",
       image = "ui/images/hop-disable-between-selected.svg",
-      category = "Bulk",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Bulk.Text",
       categoryOrder = "2")
   public void disableHopsBetweenSelectedTransforms(final 
HopGuiPipelineHopContext context) {
     enableHopsBetweenSelectedTransforms(false);
@@ -2596,7 +2656,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.HopAction.EnableDownstreamHop.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.HopAction.EnableDownstreamHop.Tooltip",
       image = "ui/images/hop-enable-downstream.svg",
-      category = "Bulk",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Bulk.Text",
       categoryOrder = "2")
   public void enableHopsDownstream(final HopGuiPipelineHopContext context) {
     enableDisableHopsDownstream(context.getHopMeta(), true);
@@ -2609,7 +2669,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.HopAction.DisableDownstreamHop.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.HopAction.DisableDownstreamHop.Tooltip",
       image = "ui/images/hop-disable-downstream.svg",
-      category = "Bulk",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Bulk.Text",
       categoryOrder = "2")
   public void disableHopsDownstream(final HopGuiPipelineHopContext context) {
     enableDisableHopsDownstream(context.getHopMeta(), false);
@@ -2669,7 +2729,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.HopAction.InsetTransform.Text",
       tooltip = "i18n::HopGuiPipelineGraph.HopAction.InsetTransform.Tooltip",
       image = "ui/images/add-item.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "13")
   public void insertTransform(HopGuiPipelineHopContext context) {
     // Build actions list
@@ -2728,7 +2788,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.NoteAction.EditNote.Name",
       tooltip = "i18n::HopGuiPipelineGraph.NoteAction.EditNote.Tooltip",
       image = "ui/images/edit.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void editNote(HopGuiPipelineNoteContext context) {
     selectionRegion = null;
@@ -2742,7 +2802,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.NoteAction.DeleteNote.Name",
       tooltip = "i18n::HopGuiPipelineGraph.NoteAction.DeleteNote.Tooltip",
       image = "ui/images/delete.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void deleteNote(HopGuiPipelineNoteContext context) {
     selectionRegion = null;
@@ -2762,7 +2822,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.NoteAction.CreateNote.Name",
       tooltip = "i18n::HopGuiPipelineGraph.NoteAction.CreateNote.Tooltip",
       image = "ui/images/note-add.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void newNote(HopGuiPipelineContext context) {
     selectionRegion = null;
@@ -2804,13 +2864,53 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.PipelineAction.CopyToClipboard.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.PipelineAction.CopyToClipboard.Tooltip",
       image = "ui/images/copy.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void copyNotePadToClipboard(HopGuiPipelineNoteContext context) {
     pipelineClipboardDelegate.copySelected(
         pipelineMeta, Collections.emptyList(), 
Arrays.asList(context.getNotePadMeta()));
   }
 
+  @GuiContextAction(
+      id = "pipeline-graph-30-bring-note-to-front",
+      parentId = HopGuiPipelineNoteContext.CONTEXT_ID,
+      type = GuiActionType.Modify,
+      name = "i18n::HopGuiPipelineGraph.NoteAction.BringToFront.Text",
+      tooltip = "i18n::HopGuiPipelineGraph.NoteAction.BringToFront.Tooltip",
+      image = "ui/images/bring-to-front.svg",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Arrange.Text",
+      categoryOrder = "2")
+  public void bringNoteToFront(HopGuiPipelineNoteContext context) {
+    selectionRegion = null;
+    NotePadMeta note = context.getNotePadMeta();
+    int idx = pipelineMeta.indexOfNote(note);
+    if (idx >= 0) {
+      pipelineMeta.raiseNote(idx);
+      hopGui.undoDelegate.addUndoDelete(pipelineMeta, new NotePadMeta[] 
{note}, new int[] {idx});
+    }
+    redraw();
+  }
+
+  @GuiContextAction(
+      id = "pipeline-graph-40-send-note-to-back",
+      parentId = HopGuiPipelineNoteContext.CONTEXT_ID,
+      type = GuiActionType.Modify,
+      name = "i18n::HopGuiPipelineGraph.NoteAction.SendToBack.Text",
+      tooltip = "i18n::HopGuiPipelineGraph.NoteAction.SendToBack.Tooltip",
+      image = "ui/images/send-to-back.svg",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Arrange.Text",
+      categoryOrder = "2")
+  public void sendNoteToBack(HopGuiPipelineNoteContext context) {
+    selectionRegion = null;
+    NotePadMeta note = context.getNotePadMeta();
+    int idx = pipelineMeta.indexOfNote(note);
+    if (idx >= 0) {
+      pipelineMeta.lowerNote(idx);
+      hopGui.undoDelegate.addUndoDelete(pipelineMeta, new NotePadMeta[] 
{note}, new int[] {idx});
+    }
+    redraw();
+  }
+
   @GuiContextAction(
       id = "pipeline-graph-edit-pipeline",
       parentId = HopGuiPipelineContext.CONTEXT_ID,
@@ -2818,7 +2918,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.PipelineAction.EditPipeline.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.PipelineAction.EditPipeline.Tooltip",
       image = "ui/images/pipeline.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void editPipelineProperties(HopGuiPipelineContext context) {
     editProperties(pipelineMeta, hopGui, true);
@@ -3117,6 +3217,14 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
     showToolTip(new org.eclipse.swt.graphics.Point(screenX, screenY));
   }
 
+  /**
+   * Find the last area owner, the one drawn last, for the given coordinate. 
In other words, this
+   * searches the provided list back-to-front.
+   *
+   * @param x The x coordinate
+   * @param y The y coordinate
+   * @return The area owner or null if nothing could be found
+   */
   public synchronized AreaOwner getVisibleAreaOwner(int x, int y) {
     for (int i = areaOwners.size() - 1; i >= 0; i--) {
       AreaOwner areaOwner = areaOwners.get(i);
@@ -3384,8 +3492,6 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       ni.setBorderColorRed(n.getBorderColorRed());
       ni.setBorderColorGreen(n.getBorderColorGreen());
       ni.setBorderColorBlue(n.getBorderColorBlue());
-      ni.width = ConstUi.NOTE_MIN_SIZE;
-      ni.height = ConstUi.NOTE_MIN_SIZE;
 
       NotePadMeta after = (NotePadMeta) ni.clone();
       hopGui.undoDelegate.addUndoChange(
@@ -3421,7 +3527,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.HopAction.CreateHop.Name",
       tooltip = "i18n::HopGuiPipelineGraph.HopAction.CreateHop.Tooltip",
       image = "ui/images/hop.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void newHopCandidate(HopGuiPipelineTransformContext context) {
     startHopTransform = context.getTransformMeta();
@@ -3501,7 +3607,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.PipelineAction.Preview.Name",
       tooltip = "i18n::HopGuiPipelineGraph.PipelineAction.Preview.Tooltip",
       image = "ui/images/preview.svg",
-      category = "Preview",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Preview.Text",
       categoryOrder = "3")
   /** Preview a single transform */
   public void preview(HopGuiPipelineTransformContext context) {
@@ -3546,7 +3652,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.PipelineAction.DebugOutput.Name",
       tooltip = "i18n::HopGuiPipelineGraph.PipelineAction.DebugOutput.Tooltip",
       image = "ui/images/debug.svg",
-      category = "Preview",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Preview.Text",
       categoryOrder = "3")
   /** Debug a single transform */
   public void debug(HopGuiPipelineTransformContext context) {
@@ -4704,7 +4810,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.PipelineAction.SniffOutput.Name",
       tooltip = "i18n::HopGuiPipelineGraph.PipelineAction.SniffOutput.Tooltip",
       image = "ui/images/preview.svg",
-      category = "Preview",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Preview.Text",
       categoryOrder = "3")
   public void sniff(HopGuiPipelineTransformContext context) {
     TransformMeta transformMeta = context.getTransformMeta();
@@ -5102,7 +5208,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = 
"i18n::HopGuiPipelineGraph.PipelineAction.PasteFromClipboard.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.PipelineAction.PasteFromClipboard.Tooltip",
       image = "ui/images/paste.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void pasteFromClipboard(HopGuiPipelineContext context) {
     pasteFromClipboard(context.getClick());
@@ -5115,7 +5221,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = "i18n::HopGuiPipelineGraph.PipelineAction.CopyToClipboard.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.PipelineAction.CopyToClipboard.Tooltip",
       image = "ui/images/copy.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void copyTransformToClipboard(HopGuiPipelineTransformContext context) 
{
     pipelineClipboardDelegate.copySelected(
@@ -5198,7 +5304,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = 
"i18n::HopGuiPipelineGraph.ContextualAction.NavigateToExecutionInfo.Text",
       tooltip = 
"i18n::HopGuiPipelineGraph.ContextualAction.NavigateToExecutionInfo.Tooltip",
       image = "ui/images/execution.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void navigateToExecutionInfo(HopGuiPipelineContext context) {
     navigateToExecutionInfo();
@@ -5305,7 +5411,7 @@ public class HopGuiPipelineGraph extends 
HopGuiAbstractGraph
       name = 
"i18n::HopGuiPipelineGraph.TransformAction.ViewExecutionInfo.Name",
       tooltip = 
"i18n::HopGuiPipelineGraph.TransformAction.ViewExecutionInfo.Tooltip",
       image = "ui/images/execution.svg",
-      category = "Basic",
+      category = 
"i18n::HopGuiPipelineGraph.ContextualAction.Category.Basic.Text",
       categoryOrder = "1")
   public void viewTransformExecutionInfo(HopGuiPipelineTransformContext 
context) {
     try {
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/shared/HopGuiAbstractGraph.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/shared/HopGuiAbstractGraph.java
index a64941ec9b..d633a5ad9f 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/shared/HopGuiAbstractGraph.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/shared/HopGuiAbstractGraph.java
@@ -20,6 +20,8 @@ package org.apache.hop.ui.hopgui.file.shared;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
+import lombok.Getter;
+import org.apache.hop.core.NotePadMeta;
 import org.apache.hop.core.gui.DPoint;
 import org.apache.hop.core.gui.Point;
 import org.apache.hop.core.gui.Rectangle;
@@ -29,14 +31,13 @@ import 
org.apache.hop.core.gui.plugin.key.GuiOsxKeyboardShortcut;
 import org.apache.hop.core.variables.IVariables;
 import org.apache.hop.core.variables.Variables;
 import org.apache.hop.ui.core.ConstUi;
+import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.gui.GuiMenuWidgets;
-import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.apache.hop.ui.hopgui.file.IGraphSnapAlignDistribute;
 import org.apache.hop.ui.hopgui.file.IHopFileType;
 import org.apache.hop.ui.hopgui.perspective.execution.DragViewZoomBase;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Font;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
@@ -52,25 +53,20 @@ public abstract class HopGuiAbstractGraph extends 
DragViewZoomBase
   public static final String STATE_MAGNIFICATION = "magnification";
   public static final String STATE_SCROLL_X_SELECTION = "offset-x";
   public static final String STATE_SCROLL_Y_SELECTION = "offset-y";
+  protected final String id;
 
   protected HopGui hopGui;
-
   protected IVariables variables;
-
   protected Composite parentComposite;
-
   protected Point iconOffset;
   protected Point noteOffset;
-
-  private boolean changedState;
-  private final Font defaultFont;
-
-  protected final String id;
-
+  protected Rectangle resizeArea;
+  protected Resize resize;
   protected ToolTip toolTip;
-
   protected String mouseOverName;
 
+  private boolean changedState;
+
   /**
    * This is a state map which can be used by plugins to render extra states 
on top of pipelines and
    * workflows or their components.
@@ -83,7 +79,6 @@ public abstract class HopGuiAbstractGraph extends 
DragViewZoomBase
     this.hopGui = hopGui;
     this.variables = new Variables();
     this.variables.copyFrom(hopGui.getVariables());
-    this.defaultFont = GuiResource.getInstance().getFontDefault();
     this.changedState = false;
     this.id = UUID.randomUUID().toString();
     this.stateMap = new HashMap<>();
@@ -203,6 +198,162 @@ public abstract class HopGuiAbstractGraph extends 
DragViewZoomBase
     setChanged();
   }
 
+  /**
+   * Evaluates whether the point is near any of the edges or corners of the 
rectangle and returns
+   * the corresponding resize direction.
+   *
+   * @param rectangle the rectangle to check against
+   * @param point the point whose position is evaluated
+   * @return the resize direction as {@link Resize} enum; returns null if the 
point does not
+   *     correspond with any resize region
+   */
+  public Resize getResize(Rectangle rectangle, Point point) {
+    // West border
+    if (point.x <= rectangle.x + 4) {
+      if (point.y <= rectangle.y + 4) return Resize.NORTH_WEST;
+      if (point.y >= rectangle.y + rectangle.height - 4) return 
Resize.SOUTH_WEST;
+      return Resize.WEST;
+    }
+
+    // East border
+    if (point.x >= rectangle.x + rectangle.width - 4) {
+      if (point.y <= rectangle.y + 4) return Resize.NORTH_EAST;
+      if (point.y >= rectangle.y + rectangle.height - 4) return 
Resize.SOUTH_EAST;
+      return Resize.EAST;
+    }
+
+    // North
+    if (point.y <= rectangle.y + 4) {
+      return Resize.NORTH;
+    }
+    if (point.y >= rectangle.y + rectangle.height - 4) {
+      return Resize.SOUTH;
+    }
+    return null;
+  }
+
+  /**
+   * Resizes the given {@link NotePadMeta} based on the original area, the 
specified resize
+   * direction and real mouse position.
+   *
+   * @param noteMeta the metadata of the note to be resized
+   * @param real the current position of the mouse used for calculating the 
resize dimensions
+   */
+  protected void resizeNote(NotePadMeta noteMeta, Point real) {
+    switch (resize) {
+      case EAST -> {
+        int width = real.x - resizeArea.x;
+        if (width < noteMeta.getMinimumWidth()) {
+          width = noteMeta.getMinimumWidth();
+        }
+        PropsUi.setSize(noteMeta, width, resizeArea.height);
+      }
+      case NORTH -> {
+        int y = real.y;
+        if (y < 0) {
+          y = 0;
+        }
+        if (y > resizeArea.y + resizeArea.height - 
noteMeta.getMinimumHeight()) {
+          y = resizeArea.y + resizeArea.height - noteMeta.getMinimumHeight();
+        }
+        PropsUi.setLocation(noteMeta, resizeArea.x, y);
+        PropsUi.setSize(
+            noteMeta,
+            resizeArea.width,
+            resizeArea.y + resizeArea.height - noteMeta.getLocation().y);
+      }
+      case NORTH_EAST -> {
+        int x = real.x;
+        if (x < 0) {
+          x = 0;
+        }
+        int width = real.x - resizeArea.x;
+        if (width < noteMeta.getMinimumWidth()) {
+          width = noteMeta.getMinimumWidth();
+        }
+        int y = real.y;
+        if (y < 0) {
+          y = 0;
+        }
+        if (y > resizeArea.y + resizeArea.height - 
noteMeta.getMinimumHeight()) {
+          y = resizeArea.y + resizeArea.height - noteMeta.getMinimumHeight();
+        }
+        PropsUi.setLocation(noteMeta, resizeArea.x, y);
+        PropsUi.setSize(
+            noteMeta, width, resizeArea.y + resizeArea.height - 
noteMeta.getLocation().y);
+      }
+      case NORTH_WEST -> {
+        int x = real.x;
+        if (x < 0) {
+          x = 0;
+        }
+        if (x > resizeArea.x + resizeArea.width - noteMeta.getMinimumWidth()) {
+          x = resizeArea.x + resizeArea.width - noteMeta.getMinimumWidth();
+        }
+        int y = real.y;
+        if (y < 0) {
+          y = 0;
+        }
+        if (y > resizeArea.y + resizeArea.height - 
noteMeta.getMinimumHeight()) {
+          y = resizeArea.y + resizeArea.height - noteMeta.getMinimumHeight();
+        }
+        PropsUi.setLocation(noteMeta, x, y);
+        PropsUi.setSize(
+            noteMeta,
+            resizeArea.x + resizeArea.width - noteMeta.getLocation().x,
+            resizeArea.height + resizeArea.y - noteMeta.getLocation().y);
+      }
+      case SOUTH -> {
+        int height = real.y - resizeArea.y;
+        if (height < noteMeta.getMinimumHeight()) {
+          height = noteMeta.getMinimumHeight();
+        }
+        PropsUi.setSize(noteMeta, resizeArea.width, height);
+      }
+      case SOUTH_EAST -> {
+        int width = real.x - resizeArea.x;
+        if (width < noteMeta.getMinimumWidth()) {
+          width = noteMeta.getMinimumWidth();
+        }
+        int height = real.y - resizeArea.y;
+        if (height < noteMeta.getMinimumHeight()) {
+          height = noteMeta.getMinimumHeight();
+        }
+        PropsUi.setSize(noteMeta, width, height);
+      }
+      case SOUTH_WEST -> {
+        int x = real.x;
+        if (x < 0) {
+          x = 0;
+        }
+        if (x > resizeArea.x + resizeArea.width - noteMeta.getMinimumWidth()) {
+          x = resizeArea.x + resizeArea.width - noteMeta.getMinimumWidth();
+        }
+        int height = real.y - resizeArea.y;
+        if (height < noteMeta.getMinimumHeight()) {
+          height = noteMeta.getMinimumHeight();
+        }
+        PropsUi.setLocation(noteMeta, x, resizeArea.y);
+        PropsUi.setSize(
+            noteMeta, resizeArea.x + resizeArea.width - 
noteMeta.getLocation().x, height);
+      }
+      case WEST -> {
+        int x = real.x;
+        if (x < 0) {
+          x = 0;
+        }
+        if (x > resizeArea.x + resizeArea.width - noteMeta.getMinimumWidth()) {
+          x = resizeArea.x + resizeArea.width - noteMeta.getMinimumWidth();
+        }
+        PropsUi.setLocation(noteMeta, x, resizeArea.y);
+        PropsUi.setSize(
+            noteMeta,
+            resizeArea.x + resizeArea.width - noteMeta.getLocation().x,
+            resizeArea.height);
+      }
+    }
+  }
+
   /**
    * Gets variables
    *
@@ -346,4 +497,21 @@ public abstract class HopGuiAbstractGraph extends 
DragViewZoomBase
   public void setMouseOverName(String mouseOverName) {
     this.mouseOverName = mouseOverName;
   }
+
+  public enum Resize {
+    EAST(SWT.CURSOR_SIZEW),
+    NORTH(SWT.CURSOR_SIZENS),
+    NORTH_EAST(SWT.CURSOR_SIZENESW),
+    NORTH_WEST(SWT.CURSOR_SIZENW),
+    SOUTH(SWT.CURSOR_SIZENS),
+    SOUTH_EAST(SWT.CURSOR_SIZENW),
+    SOUTH_WEST(SWT.CURSOR_SIZENESW),
+    WEST(SWT.CURSOR_SIZEW);
+
+    @Getter private final int cursor;
+
+    Resize(int cursor) {
+      this.cursor = cursor;
+    }
+  }
 }
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
index e7b9714011..c121fbe9da 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/HopGuiWorkflowGraph.java
@@ -342,7 +342,7 @@ public class HopGuiWorkflowGraph extends HopGuiAbstractGraph
 
   private ActionMeta endHopAction;
   private ActionMeta noInputAction;
-  private Point[] previousTransformLocations;
+  private Point[] previousActionLocations;
   private Point[] previousNoteLocations;
   private ActionMeta currentAction;
   private boolean ignoreNextClick;
@@ -544,6 +544,7 @@ public class HopGuiWorkflowGraph extends HopGuiAbstractGraph
       mouseHover(event);
     }
     doubleClick = false;
+    resize = null;
 
     if (ignoreNextClick) {
       ignoreNextClick = false;
@@ -553,9 +554,9 @@ public class HopGuiWorkflowGraph extends HopGuiAbstractGraph
     boolean control = (event.stateMask & SWT.MOD1) != 0;
     boolean shift = (event.stateMask & SWT.SHIFT) != 0;
 
-    lastButton = event.button;
     Point real = screen2real(event.x, event.y);
     lastClick = new Point(real.x, real.y);
+    lastButton = event.button;
 
     // Hide the tooltip!
     hideToolTips();
@@ -574,142 +575,180 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
       LogChannel.GENERAL.logError("Error calling WorkflowGraphMouseDown 
extension point", ex);
     }
 
-    // A single left or middle click on one of the area owners...
+    // Layer 0: See if we're dragging around the view-port over the workflow 
graph.
     //
-    if (event.button == 1 || event.button == 2) {
-      if (areaOwner != null && areaOwner.getAreaType() != null) {
-        switch (areaOwner.getAreaType()) {
-          case ACTION_ICON:
-            if (shift && control) {
-              openReferencedObject();
-              return;
-            }
-
-            ActionMeta actionCopy = (ActionMeta) areaOwner.getOwner();
-            currentAction = actionCopy;
+    Point clickScreen = new Point(event.x, event.y);
+    if (setupDragViewPort(clickScreen)) {
+      return;
+    }
 
-            if (hopCandidate != null) {
-              addCandidateAsHop();
+    // A single left or middle click on one of the area owners...
+    //
+    boolean done = false;
 
-            } else if (event.button == 2 || (event.button == 1 && shift)) {
-              // SHIFT CLICK is start of drag to create a new hop
-              //
-              canvas.setData("mode", "hop");
-              startHopAction = actionCopy;
+    // Layer 1: Click on an area owner except note (else if a note is present 
in the background,
+    // you cannot click the hop link).
+    if (areaOwner != null && areaOwner.getAreaType() != null) {
+      switch (areaOwner.getAreaType()) {
+        case ACTION_ICON:
+          if (shift && control) {
+            openReferencedObject();
+            return;
+          }
 
-            } else {
-              canvas.setData("mode", "drag");
-              selectedActions = workflowMeta.getSelectedActions();
-              selectedAction = actionCopy;
-              //
-              // When an icon is moved that is not selected, it gets
-              // selected too late.
-              // It is not captured here, but in the mouseMoveListener...
-              //
-              previousTransformLocations = workflowMeta.getSelectedLocations();
+          ActionMeta actionCopy = (ActionMeta) areaOwner.getOwner();
+          currentAction = actionCopy;
 
-              Point p = actionCopy.getLocation();
-              iconOffset = new Point(real.x - p.x, real.y - p.y);
-            }
-            updateGui();
-            break;
+          if (hopCandidate != null) {
+            addCandidateAsHop();
 
-          case ACTION_INFO_ICON:
-            // Click on the info icon means: Edit action description
+          } else if (event.button == 2 || (event.button == 1 && shift)) {
+            // SHIFT CLICK is start of drag to create a new hop
             //
-            editActionDescription((ActionMeta) areaOwner.getOwner());
-            break;
-
-          case NOTE:
-            currentNotePad = (NotePadMeta) areaOwner.getOwner();
-            selectedNotes = workflowMeta.getSelectedNotes();
-            selectedNote = currentNotePad;
-            Point loc = currentNotePad.getLocation();
+            canvas.setData("mode", "hop");
+            startHopAction = actionCopy;
+          } else {
+            canvas.setData("mode", "drag");
+            selectedActions = workflowMeta.getSelectedActions();
+            selectedAction = actionCopy;
+            //
+            // When an icon is moved that is not selected, it gets
+            // selected too late.
+            // It is not captured here, but in the mouseMoveListener...
+            //
+            previousActionLocations = workflowMeta.getSelectedLocations();
 
-            previousNoteLocations = workflowMeta.getSelectedNoteLocations();
+            Point p = actionCopy.getLocation();
+            iconOffset = new Point(real.x - p.x, real.y - p.y);
+          }
+          updateGui();
+          done = true;
+          break;
 
-            noteOffset = new Point(real.x - loc.x, real.y - loc.y);
+        case ACTION_NAME:
+          done = true;
+          break;
 
-            updateGui();
-            break;
+        case ACTION_INFO_ICON:
+          // Click on the info icon means: Edit action description
+          //
+          editActionDescription((ActionMeta) areaOwner.getOwner());
+          done = true;
+          break;
 
-            // If you click on an evaluating icon, change the evaluation...
-            //
-          case WORKFLOW_HOP_ICON:
-            WorkflowHopMeta hop = (WorkflowHopMeta) areaOwner.getOwner();
-            WorkflowHopMeta originalHop = hop.clone();
-            if (hop.getFromAction().isEvaluation()) {
-              if (hop.isUnconditional()) {
-                hop.setUnconditional(false);
-                hop.setEvaluation(true);
+          // If you click on an evaluating icon, change the evaluation...
+          //
+        case WORKFLOW_HOP_ICON:
+          WorkflowHopMeta hop = (WorkflowHopMeta) areaOwner.getOwner();
+          WorkflowHopMeta originalHop = hop.clone();
+          if (hop.getFromAction().isEvaluation()) {
+            if (hop.isUnconditional()) {
+              hop.setUnconditional(false);
+              hop.setEvaluation(true);
+            } else {
+              if (hop.isEvaluation()) {
+                hop.setEvaluation(false);
               } else {
-                if (hop.isEvaluation()) {
-                  hop.setEvaluation(false);
-                } else {
-                  hop.setUnconditional(true);
-                }
+                hop.setUnconditional(true);
               }
-              hopGui.undoDelegate.addUndoChange(
-                  workflowMeta,
-                  new WorkflowHopMeta[] {originalHop},
-                  new WorkflowHopMeta[] {hop},
-                  new int[] {workflowMeta.indexOfWorkflowHop(hop)});
-              updateGui();
             }
-            break;
-          default:
-            break;
-        }
-      } else {
-        WorkflowHopMeta hop = findWorkflowHop(real.x, real.y);
-        if (hop != null) {
-          // Delete hop with on click
-          if (event.button == 1 && shift && control) {
-            // Delete the hop
-            workflowHopDelegate.delHop(workflowMeta, hop);
-            updateGui();
-          }
-          // User held control and clicked a hop between actions - We want to 
flip the active state
-          // of
-          // the hop.
-          //
-          else if (event.button == 2 || (event.button == 1 && control)) {
-            hop.setEnabled(!hop.isEnabled());
+            hopGui.undoDelegate.addUndoChange(
+                workflowMeta,
+                new WorkflowHopMeta[] {originalHop},
+                new WorkflowHopMeta[] {hop},
+                new int[] {workflowMeta.indexOfWorkflowHop(hop)});
             updateGui();
-          } else {
-            // A hop: show the hop context menu in the mouseUp() listener
-            //
-            clickedWorkflowHop = hop;
           }
+          done = true;
+          break;
+        case NOTE:
+        default:
+          break;
+      }
+    }
+
+    // Layer 2: click on hop links between actions
+    if (!done) {
+      // Hop links between actions are found searching by (x,y) coordinates.
+      WorkflowHopMeta hop = findWorkflowHop(real.x, real.y);
+      if (hop != null) {
+        // Delete hop with on click
+        if (event.button == 1 && shift && control) {
+          // Delete the hop
+          workflowHopDelegate.delHop(workflowMeta, hop);
+          updateGui();
+        }
+        // User held control and clicked a hop between actions - We want to 
flip the active state
+        // of
+        // the hop.
+        //
+        else if (event.button == 2 || (event.button == 1 && control)) {
+          hop.setEnabled(!hop.isEnabled());
+          updateGui();
         } else {
-          // If we're dragging a candidate hop around and click on the 
background it simply needs to
-          // go away.
+          // A hop: show the hop context menu in the mouseUp() listener
           //
-          if (startHopAction != null) {
-            startHopAction = null;
-            hopCandidate = null;
-            lastClick = null;
-            redraw();
-            return;
-          }
+          clickedWorkflowHop = hop;
+        }
+        done = true;
+      }
+    }
 
-          // Dragging on the background?
-          // See if we're dragging around the view-port over the workflow 
graph.
-          //
-          if (setupDragView(event.button, control, new Point(event.x, 
event.y))) {
-            return;
-          }
+    // Layer 3: click on a note
+    if (!done && areaOwner != null && areaOwner.getAreaType() == 
AreaOwner.AreaType.NOTE) {
+      currentNotePad = (NotePadMeta) areaOwner.getOwner();
+      selectedNotes = workflowMeta.getSelectedNotes();
+      selectedNote = currentNotePad;
+      Point loc = currentNotePad.getLocation();
 
-          // No area-owner means: background:
-          //
-          canvas.setData("mode", "select");
-          if (!control && event.button == 1) {
-            selectionRegion = new org.apache.hop.core.gui.Rectangle(real.x, 
real.y, 0, 0);
-          }
-          updateGui();
-        }
+      previousNoteLocations = workflowMeta.getSelectedNoteLocations();
+
+      noteOffset = new Point(real.x - loc.x, real.y - loc.y);
+
+      canvas.setData("mode", "resize");
+      resize = this.getResize(areaOwner.getArea(), real);
+      // Keep the original area of the resizing note
+      resizeArea =
+          new Rectangle(
+              currentNotePad.getLocation().x,
+              currentNotePad.getLocation().y,
+              currentNotePad.getWidth(),
+              currentNotePad.getHeight());
+
+      updateGui();
+      done = true;
+    }
+
+    // Layer 4: Click on the background of the graph
+    if (!done) {
+
+      // If we're dragging a candidate hop around and click on the background 
it simply needs to
+      // go away.
+      //
+      if (startHopAction != null) {
+        startHopAction = null;
+        hopCandidate = null;
+        lastClick = null;
+        redraw();
+        return;
+      }
+
+      // Click to drag the background
+      if (setupDragView(event.button, control, clickScreen)) {
+        return;
+      }
+
+      // Click to create a lasso
+      //
+      canvas.setData("mode", "select");
+      if (!control && event.button == 1) {
+        selectionRegion = new org.apache.hop.core.gui.Rectangle(real.x, 
real.y, 0, 0);
+        // Change cursor when selecting a region
+        setCursor(getDisplay().getSystemCursor(SWT.CURSOR_CROSS));
       }
+      updateGui();
     }
+
     if (EnvironmentUtils.getInstance().isWeb()) {
       // RAP does not support certain mouse events.
       mouseMove(event);
@@ -726,6 +765,8 @@ public class HopGuiWorkflowGraph extends HopGuiAbstractGraph
 
   @Override
   public void mouseUp(MouseEvent event) {
+    resize = null;
+
     // canvas.setData("mode", null); does not work.
     canvas.setData("mode", "null");
     if (EnvironmentUtils.getInstance().isWeb()) {
@@ -866,12 +907,12 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
           }
           if (selectedActions != null
               && !selectedActions.isEmpty()
-              && previousTransformLocations != null) {
+              && previousActionLocations != null) {
             int[] indexes = workflowMeta.getActionIndexes(selectedActions);
             addUndoPosition(
                 selectedActions.toArray(new 
ActionMeta[selectedActions.size()]),
                 indexes,
-                previousTransformLocations,
+                previousActionLocations,
                 workflowMeta.getSelectedLocations(),
                 also);
           }
@@ -934,6 +975,13 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
               singleClick = true;
               singleClickType = SingleClickType.Note;
               singleClickNote = selectedNote;
+
+              // If the clicked note is not part of the current selection, 
cancel the
+              // current selection
+              if (!selectedNote.isSelected()) {
+                workflowMeta.unselectAll();
+                selectedNote.setSelected(true);
+              }
             }
           } else {
             // Find out which Transforms & Notes are selected
@@ -956,12 +1004,12 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
             }
             if (selectedActions != null
                 && !selectedActions.isEmpty()
-                && previousTransformLocations != null) {
+                && previousActionLocations != null) {
               int[] indexes = workflowMeta.getActionIndexes(selectedActions);
               addUndoPosition(
                   selectedActions.toArray(new 
ActionMeta[selectedActions.size()]),
                   indexes,
-                  previousTransformLocations,
+                  previousActionLocations,
                   workflowMeta.getSelectedLocations(),
                   also);
             }
@@ -1115,7 +1163,6 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
     boolean shift = (event.stateMask & SWT.SHIFT) != 0;
     noInputAction = null;
     boolean doRedraw = false;
-    WorkflowHopMeta hop = null;
 
     // disable the tooltip
     //
@@ -1129,6 +1176,7 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
     }
 
     Point real = screen2real(event.x, event.y);
+
     // Remember the last position of the mouse for paste with keyboard
     //
     lastMove = real;
@@ -1143,29 +1191,53 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
     }
     Point note = new Point(real.x - noteOffset.x, real.y - noteOffset.y);
 
+    // First, check for operations that have been started, such as move 
selection, dragging the
+    // view, creating a hop or
+    // resizing a note.
+
+    // Drag the view around with middle button on the background?
+    //
+    if (viewDrag && lastClick != null) {
+      dragView(viewDragStart, new Point(event.x, event.y));
+      return;
+    }
+
+    // Resizing the current note
+    if (resize != null) {
+      resizeNote(selectedNote, real);
+      redraw();
+      return;
+    }
+
     // Moved over an area?
     //
     AreaOwner areaOwner = getVisibleAreaOwner(real.x, real.y);
+    Resize resizeOver = null;
 
     // Moved over an hop?
     //
-    if (areaOwner == null) {
-      hop = findWorkflowHop(real.x, real.y);
-    }
+    if (areaOwner != null) {
 
-    // Mouse over the name of the action
-    //
-    if (!PropsUi.getInstance().useDoubleClick()) {
-      if (areaOwner != null && areaOwner.getAreaType() == 
AreaOwner.AreaType.ACTION_NAME) {
-        if (mouseOverName == null) {
-          doRedraw = true;
-        }
-        mouseOverName = (String) areaOwner.getOwner();
-      } else {
-        if (mouseOverName != null) {
-          doRedraw = true;
+      // Mouse over the name of the action
+      //
+      if (!PropsUi.getInstance().useDoubleClick()) {
+        if (areaOwner != null && areaOwner.getAreaType() == 
AreaOwner.AreaType.ACTION_NAME) {
+          if (mouseOverName == null) {
+            doRedraw = true;
+          }
+          mouseOverName = (String) areaOwner.getOwner();
+        } else {
+          if (mouseOverName != null) {
+            doRedraw = true;
+          }
+          mouseOverName = null;
         }
-        mouseOverName = null;
+      }
+
+      // Mouse over note
+      if (areaOwner.getAreaType() == AreaOwner.AreaType.NOTE) {
+        // Check if the mouse is over the border to activate a resize cursor
+        resizeOver = this.getResize(areaOwner.getArea(), real);
       }
     }
 
@@ -1179,7 +1251,7 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
       selectedAction.setSelected(true);
       selectedActions = new ArrayList<>();
       selectedActions.add(selectedAction);
-      previousTransformLocations = new Point[] {selectedAction.getLocation()};
+      previousActionLocations = new Point[] {selectedAction.getLocation()};
       doRedraw = true;
     } else if (selectedNote != null && !selectedNote.isSelected()) {
       workflowMeta.unselectAll();
@@ -1269,12 +1341,6 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
       }
 
       doRedraw = true;
-    } else {
-      // Drag the view around with middle button on the background?
-      //
-      if (viewDrag && lastClick != null) {
-        dragView(viewDragStart, new Point(event.x, event.y));
-      }
     }
 
     // Move around notes & actions
@@ -1295,18 +1361,22 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
 
     Cursor cursor = null;
     // Change cursor when dragging view or view port
-    if (viewDrag || viewPortNavigation) {
-      cursor = getDisplay().getSystemCursor(SWT.CURSOR_SIZEALL);
-    }
+    // if (viewDrag || viewPortNavigation) {
+    //    cursor = getDisplay().getSystemCursor(SWT.CURSOR_SIZEALL);
+    // }
     // Change cursor when selecting a region
-    else if (selectionRegion != null) {
-      cursor = getDisplay().getSystemCursor(SWT.CURSOR_CROSS);
-    }
-    // Change cursor when hover an hop or an area that support hover
-    else if (hop != null
-        || (areaOwner != null
+    //  else if (selectionRegion != null) {
+    //  cursor = getDisplay().getSystemCursor(SWT.CURSOR_CROSS);
+    /// } else
+    // Change the cursor when the mouse is on the resize edge of a note
+    if (resizeOver != null) {
+      cursor = getDisplay().getSystemCursor(resizeOver.getCursor());
+    }
+    // Change cursor when the mouse is on a hop or an area that support 
hovering
+    else if ((areaOwner != null
             && areaOwner.getAreaType() != null
-            && areaOwner.getAreaType().isSupportHover())) {
+            && areaOwner.getAreaType().isSupportHover())
+        || findWorkflowHop(real.x, real.y) != null) {
       cursor = getDisplay().getSystemCursor(SWT.CURSOR_HAND);
     }
     setCursor(cursor);
@@ -1402,7 +1472,15 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
     return ok;
   }
 
-  public AreaOwner getVisibleAreaOwner(int x, int y) {
+  /**
+   * Find the last area owner, the one drawn last, for the given coordinate. 
In other words, this
+   * searches the provided list back-to-front.
+   *
+   * @param x The x coordinate
+   * @param y The y coordinate
+   * @return The area owner or null if nothing could be found
+   */
+  public synchronized AreaOwner getVisibleAreaOwner(int x, int y) {
     for (int i = areaOwners.size() - 1; i >= 0; i--) {
       AreaOwner areaOwner = areaOwners.get(i);
       if (areaOwner.contains(x, y)) {
@@ -1729,24 +1807,24 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
   }
 
   /**
-   * See if location (x,y) is on a line between two transforms: the hop!
+   * See if the location (x,y) is on a line between two actions: the hop!
    *
    * @param x
    * @param y
-   * @return the pipeline hop on the specified location, otherwise: null
+   * @return the workflow hop on the specified location, otherwise: null
    */
   private WorkflowHopMeta findWorkflowHop(int x, int y) {
     return findHop(x, y, null);
   }
 
   /**
-   * See if location (x,y) is on a line between two transforms: the hop!
+   * See if the location (x,y) is on a line between two actions: the hop!
    *
    * @param x
    * @param y
-   * @param exclude the transform to exclude from the hops (from or to 
location). Specify null if no
-   *     transform is to be excluded.
-   * @return the pipeline hop on the specified location, otherwise: null
+   * @param exclude the action to exclude from the hops (from or to location). 
Specify null if no
+   *     action is to be excluded.
+   * @return the workflow hop on the specified location, otherwise: null
    */
   private WorkflowHopMeta findHop(int x, int y, ActionMeta exclude) {
     int i;
@@ -2070,32 +2148,32 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
       categoryOrder = "1")
   public void newNote(HopGuiWorkflowContext context) {
     String title = BaseMessages.getString(PKG, 
"WorkflowGraph.Dialog.EditNote.Title");
-    NotePadDialog dd = new NotePadDialog(variables, hopShell(), title);
-    NotePadMeta n = dd.open();
-    if (n != null) {
-      NotePadMeta npi =
+    NotePadDialog dialog = new NotePadDialog(variables, hopShell(), title);
+    NotePadMeta note = dialog.open();
+    if (note != null) {
+      NotePadMeta newNote =
           new NotePadMeta(
-              n.getNote(),
+              note.getNote(),
               context.getClick().x,
               context.getClick().y,
               ConstUi.NOTE_MIN_SIZE,
               ConstUi.NOTE_MIN_SIZE,
-              n.getFontName(),
-              n.getFontSize(),
-              n.isFontBold(),
-              n.isFontItalic(),
-              n.getFontColorRed(),
-              n.getFontColorGreen(),
-              n.getFontColorBlue(),
-              n.getBackGroundColorRed(),
-              n.getBackGroundColorGreen(),
-              n.getBackGroundColorBlue(),
-              n.getBorderColorRed(),
-              n.getBorderColorGreen(),
-              n.getBorderColorBlue());
-      workflowMeta.addNote(npi);
+              note.getFontName(),
+              note.getFontSize(),
+              note.isFontBold(),
+              note.isFontItalic(),
+              note.getFontColorRed(),
+              note.getFontColorGreen(),
+              note.getFontColorBlue(),
+              note.getBackGroundColorRed(),
+              note.getBackGroundColorGreen(),
+              note.getBackGroundColorBlue(),
+              note.getBorderColorRed(),
+              note.getBorderColorGreen(),
+              note.getBorderColorBlue());
+      workflowMeta.addNote(newNote);
       hopGui.undoDelegate.addUndoNew(
-          workflowMeta, new NotePadMeta[] {npi}, new int[] 
{workflowMeta.indexOfNote(npi)});
+          workflowMeta, new NotePadMeta[] {newNote}, new int[] 
{workflowMeta.indexOfNote(newNote)});
       redraw();
     }
   }
@@ -2142,20 +2220,42 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
     redraw();
   }
 
-  public void raiseNote() {
+  @GuiContextAction(
+      id = "workflow-graph-30-bring-note-to-front",
+      parentId = HopGuiWorkflowNoteContext.CONTEXT_ID,
+      type = GuiActionType.Modify,
+      name = 
"i18n::HopGuiWorkflowGraph.ContextualAction.BringNoteToFront.Text",
+      tooltip = 
"i18n::HopGuiWorkflowGraph.ContextualAction.BringNoteToFront.Tooltip",
+      image = "ui/images/bring-to-front.svg",
+      category = 
"i18n::HopGuiWorkflowGraph.ContextualAction.Category.Arrange.Text",
+      categoryOrder = "2")
+  public void bringNoteToFront(HopGuiWorkflowNoteContext context) {
     selectionRegion = null;
-    int idx = workflowMeta.indexOfNote(getCurrentNote());
+    NotePadMeta note = context.getNotePadMeta();
+    int idx = workflowMeta.indexOfNote(note);
     if (idx >= 0) {
       workflowMeta.raiseNote(idx);
+      hopGui.undoDelegate.addUndoDelete(workflowMeta, new NotePadMeta[] 
{note}, new int[] {idx});
     }
     redraw();
   }
 
-  public void lowerNote() {
+  @GuiContextAction(
+      id = "workflow-graph-40-send-note-to-back",
+      parentId = HopGuiWorkflowNoteContext.CONTEXT_ID,
+      type = GuiActionType.Modify,
+      name = "i18n::HopGuiWorkflowGraph.ContextualAction.SendNoteToBack.Text",
+      tooltip = 
"i18n::HopGuiWorkflowGraph.ContextualAction.SendNoteToBack.Tooltip",
+      image = "ui/images/send-to-back.svg",
+      category = 
"i18n::HopGuiWorkflowGraph.ContextualAction.Category.Arrange.Text",
+      categoryOrder = "2")
+  public void sendNoteToBack(HopGuiWorkflowNoteContext context) {
     selectionRegion = null;
-    int idx = workflowMeta.indexOfNote(getCurrentNote());
+    NotePadMeta note = context.getNotePadMeta();
+    int idx = workflowMeta.indexOfNote(note);
     if (idx >= 0) {
       workflowMeta.lowerNote(idx);
+      hopGui.undoDelegate.addUndoDelete(workflowMeta, new NotePadMeta[] 
{note}, new int[] {idx});
     }
     redraw();
   }
@@ -3045,8 +3145,8 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
           new NotePadMeta[] {before},
           new NotePadMeta[] {notePadMeta},
           new int[] {workflowMeta.indexOfNote(notePadMeta)});
-      notePadMeta.width = ConstUi.NOTE_MIN_SIZE;
-      notePadMeta.height = ConstUi.NOTE_MIN_SIZE;
+      // notePadMeta.width = ConstUi.NOTE_MIN_SIZE;
+      // notePadMeta.height = ConstUi.NOTE_MIN_SIZE;
 
       updateGui();
     }
@@ -4207,7 +4307,7 @@ public class HopGuiWorkflowGraph extends 
HopGuiAbstractGraph
       new ErrorDialog(
           getShell(),
           CONST_ERROR,
-          "Error navigating to the latest execution information for this 
pipeline",
+          "Error navigating to the latest execution information for this 
workflow",
           e);
     }
   }
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/execution/DragViewZoomBase.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/execution/DragViewZoomBase.java
index bc34371cc6..61b7f5463f 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/execution/DragViewZoomBase.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/execution/DragViewZoomBase.java
@@ -257,17 +257,6 @@ public abstract class DragViewZoomBase extends Composite {
    * @return
    */
   protected boolean setupDragView(int button, boolean control, Point 
screenClick) {
-    // See if this is a click on the navigation view inner rectangle with the 
goal of dragging it
-    // around a bit.
-    //
-    if (viewPort != null && viewPort.contains(screenClick)) {
-      viewPortNavigation = true;
-      viewPortStart = new Point(screenClick);
-      viewDragBaseOffset = new DPoint(offset);
-      setCursor(getDisplay().getSystemCursor(SWT.CURSOR_SIZEALL));
-      return true;
-    }
-
     // Middle button
     // CTRL + left button
     //
@@ -275,6 +264,23 @@ public abstract class DragViewZoomBase extends Composite {
     if (viewDrag) {
       viewDragStart = screenClick;
       viewDragBaseOffset = new DPoint(offset);
+      // Change cursor when dragging view
+      setCursor(getDisplay().getSystemCursor(SWT.CURSOR_SIZEALL));
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * See if this is a click on the navigation view inner rectangle with the 
goal of dragging it
+   * around a bit.
+   */
+  protected boolean setupDragViewPort(Point screenClick) {
+    if (viewPort != null && viewPort.contains(screenClick)) {
+      viewPortNavigation = true;
+      viewPortStart = new Point(screenClick);
+      viewDragBaseOffset = new DPoint(offset);
+      // Change cursor when dragging view port
       setCursor(getDisplay().getSystemCursor(SWT.CURSOR_SIZEALL));
       return true;
     }
diff --git 
a/ui/src/main/resources/org/apache/hop/ui/hopgui/file/pipeline/messages/messages_en_US.properties
 
b/ui/src/main/resources/org/apache/hop/ui/hopgui/file/pipeline/messages/messages_en_US.properties
index 2d68245bf6..1078da9da0 100644
--- 
a/ui/src/main/resources/org/apache/hop/ui/hopgui/file/pipeline/messages/messages_en_US.properties
+++ 
b/ui/src/main/resources/org/apache/hop/ui/hopgui/file/pipeline/messages/messages_en_US.properties
@@ -15,6 +15,11 @@
 # limitations under the License.
 #
 
+HopGuiPipelineGraph.ContextualAction.Category.Arrange.Text=Arrange
+HopGuiPipelineGraph.ContextualAction.Category.Basic.Text=Basic
+HopGuiPipelineGraph.ContextualAction.Category.Bulk.Text=Bulk
+HopGuiPipelineGraph.ContextualAction.Category.Preview.Text=Preview
+HopGuiPipelineGraph.ContextualAction.Category.Routing.Text=Data routing
 HopGuiPipelineGraph.ContextualAction.NavigateToExecutionInfo.Text=To execution 
info
 HopGuiPipelineGraph.ContextualAction.NavigateToExecutionInfo.Tooltip=Navigate 
to the execution information for this pipeline
 HopGuiPipelineGraph.DistributionMethodDialog.Header=Select distribution method
@@ -42,12 +47,16 @@ HopGuiPipelineGraph.HopAction.EnableHop.Name=Enable hop
 HopGuiPipelineGraph.HopAction.EnableHop.Tooltip=Enable the hop
 HopGuiPipelineGraph.HopAction.InsetTransform.Text=Insert transform
 HopGuiPipelineGraph.HopAction.InsetTransform.Tooltip=Split the hop and insert 
a new transform
+HopGuiPipelineGraph.NoteAction.BringToFront.Text=Bring to front
+HopGuiPipelineGraph.NoteAction.BringToFront.Tooltip=Bring note to front
 HopGuiPipelineGraph.NoteAction.CreateNote.Name=Create a note
 HopGuiPipelineGraph.NoteAction.CreateNote.Tooltip=Create a new note
 HopGuiPipelineGraph.NoteAction.DeleteNote.Name=Delete
 HopGuiPipelineGraph.NoteAction.DeleteNote.Tooltip=Delete the note
 HopGuiPipelineGraph.NoteAction.EditNote.Name=Edit
 HopGuiPipelineGraph.NoteAction.EditNote.Tooltip=Edit the note
+HopGuiPipelineGraph.NoteAction.SendToBack.Text=Send to back
+HopGuiPipelineGraph.NoteAction.SendToBack.Tooltip=Send note to back
 HopGuiPipelineGraph.PipelineAction.CopyToClipboard.Name=Copy to clipboard
 HopGuiPipelineGraph.PipelineAction.CopyToClipboard.Tooltip=Copy the XML 
representation of this object to the clipboard
 HopGuiPipelineGraph.PipelineAction.DebugOutput.Name=Debug output
diff --git 
a/ui/src/main/resources/org/apache/hop/ui/hopgui/file/workflow/messages/messages_en_US.properties
 
b/ui/src/main/resources/org/apache/hop/ui/hopgui/file/workflow/messages/messages_en_US.properties
index 4b12332932..220e466963 100644
--- 
a/ui/src/main/resources/org/apache/hop/ui/hopgui/file/workflow/messages/messages_en_US.properties
+++ 
b/ui/src/main/resources/org/apache/hop/ui/hopgui/file/workflow/messages/messages_en_US.properties
@@ -18,10 +18,13 @@
 HopGuiWorkflowGraph.ActionAction.ViewExecutionInfo.Name=View execution info
 HopGuiWorkflowGraph.ActionAction.ViewExecutionInfo.Tooltip=Look up the 
execution information of the \
     pipeline or workflow that has this action as its parent.
+HopGuiWorkflowGraph.ContextualAction.BringNoteToFront.Text=Bring to front
+HopGuiWorkflowGraph.ContextualAction.BringNoteToFront.Tooltip=Bring note to 
front
 HopGuiWorkflowGraph.ContextualAction.Category.Advanced.Text=Advanced
 HopGuiWorkflowGraph.ContextualAction.Category.Basic.Text=Basic
 HopGuiWorkflowGraph.ContextualAction.Category.Bulk.Text=Bulk
 HopGuiWorkflowGraph.ContextualAction.Category.Routing.Text=Routing
+HopGuiWorkflowGraph.ContextualAction.Category.Arrange.Text=Arrange
 HopGuiWorkflowGraph.ContextualAction.CopyAction.Text=Copy Action to clipboard
 HopGuiWorkflowGraph.ContextualAction.CopyAction.Tooltip=Copy the XML 
representation of this Action to the clipboard
 HopGuiWorkflowGraph.ContextualAction.CopyNote.Text=Copy Note to clipboard
@@ -70,6 +73,8 @@ 
HopGuiWorkflowGraph.ContextualAction.ParallelExecution.Text=Parallel execution
 HopGuiWorkflowGraph.ContextualAction.ParallelExecution.Tooltip=Enable or 
disable parallel execution of next actions
 HopGuiWorkflowGraph.ContextualAction.PasteFromClipboard.Text=Paste from the 
clipboard
 HopGuiWorkflowGraph.ContextualAction.PasteFromClipboard.Tooltip=Paste actions, 
notes or a whole workflow from the clipboard
+HopGuiWorkflowGraph.ContextualAction.SendNoteToBack.Text=Send to back
+HopGuiWorkflowGraph.ContextualAction.SendNoteToBack.Tooltip=Send note to back
 HopGuiWorkflowGraph.ContextualAction.StartWorkflowHere.Text=Start the workflow 
here
 HopGuiWorkflowGraph.ContextualAction.StartWorkflowHere.Tooltip=Start the 
execution of the workflow from this action.
 HopGuiWorkflowGraph.ContextualAction.SuccessHop.Text=Success hop
diff --git a/ui/src/main/resources/ui/images/bring-to-front.svg 
b/ui/src/main/resources/ui/images/bring-to-front.svg
new file mode 100644
index 0000000000..98e73a2c29
--- /dev/null
+++ b/ui/src/main/resources/ui/images/bring-to-front.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="800" height="800">
+<path fill="#0E3A5A" 
d="M600,240v320c0,22.092-17.909,40-40,40H240c-22.092,0-40-17.908-40-40V240
+       c0-22.091,17.908-40,40-40h320C582.091,200,600,217.909,600,240z"/>
+<path fill="none" stroke="#0E3A5A" stroke-width="42" stroke-linecap="round" 
stroke-linejoin="round" d="M600,440h120
+       
c22.091,0,40,17.908,40,40v240c0,22.092-17.909,40-40,40H480c-22.092,0-40-17.908-40-40V600"/>
+<path fill="none" stroke="#0E3A5A" stroke-width="42" stroke-linecap="round" 
stroke-linejoin="round" d="M200,360
+       
H80c-22.092,0-40-17.909-40-40V80c0-22.091,17.908-40,40-40h240c22.091,0,40,17.909,40,40v120"/>
+<path fill="none" stroke="#0E3A5A" stroke-width="42" stroke-linecap="round" 
stroke-linejoin="round" d="M600,240
+       
v320c0,22.092-17.909,40-40,40H240c-22.092,0-40-17.908-40-40V240c0-22.091,17.908-40,40-40h320C582.091,200,600,217.909,600,240z"
+       />
+</svg>
diff --git a/ui/src/main/resources/ui/images/send-to-back.svg 
b/ui/src/main/resources/ui/images/send-to-back.svg
new file mode 100644
index 0000000000..3cba731b5a
--- /dev/null
+++ b/ui/src/main/resources/ui/images/send-to-back.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="800" height="800">
+<path fill="none" 
d="M600,240v320c0,22.092-17.909,40-40,40H240c-22.092,0-40-17.908-40-40V240
+       c0-22.091,17.908-40,40-40h320C582.091,200,600,217.909,600,240z"/>
+<path fill="none" stroke="#0E3A5A" stroke-width="42" stroke-linecap="round" 
stroke-linejoin="round" d="M600,240
+       
v320c0,22.092-17.909,40-40,40H240c-22.092,0-40-17.908-40-40V240c0-22.091,17.908-40,40-40h320C582.091,200,600,217.909,600,240z"
+       />
+<path fill="#0E3A5A" stroke="#0E3A5A" stroke-width="42" 
d="M772.487,477.161v253.293
+       
c0,17.486-14.191,31.662-31.697,31.662H487.211c-17.506,0-31.697-14.176-31.697-31.662V477.161
+       
c0-17.486,14.191-31.661,31.697-31.661h253.578C758.295,445.5,772.487,459.675,772.487,477.161z"/>
+<path fill="#0E3A5A" stroke="#0E3A5A" stroke-width="42" 
d="M358.487,71.661v253.293
+       
c0,17.486-14.191,31.662-31.697,31.662H73.211c-17.506,0-31.697-14.176-31.697-31.662V71.661C41.514,54.175,55.705,40,73.211,40
+       h253.578C344.295,40,358.487,54.175,358.487,71.661z"/>
+</svg>


Reply via email to