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 22b69727cd Improve project/environment/git branch selection design 
#5879 (#5880)
22b69727cd is described below

commit 22b69727cd4937349656054785b709e9fd232676
Author: Nicolas Adment <[email protected]>
AuthorDate: Fri Nov 14 15:02:18 2025 +0100

    Improve project/environment/git branch selection design #5879 (#5880)
    
    - Add bottom toolbar to HopGui
    - Add a way to rename git branch
    - Add icon to the project and environment dialog
    - Avoid selecting an environment linked to another project
    - Allow duplication of environments #5085
    - Fix a small layout problem in HopDataOrchestrationPerspective
---
 .../main/java/org/apache/hop/git/GitGuiPlugin.java | 391 +++++++++------
 .../main/java/org/apache/hop/git/model/UIGit.java  |  11 +
 plugins/misc/git/src/main/resources/branch.svg     |  44 +-
 plugins/misc/git/src/main/resources/git-add.svg    |   2 -
 plugins/misc/git/src/main/resources/git-commit.svg |   5 +-
 .../git/src/main/resources/git_icon_inactive.svg   |  20 -
 plugins/misc/git/src/main/resources/merge.svg      |   4 +
 .../hop/git/messages/messages_en_US.properties     |  15 +-
 plugins/misc/git/src/main/resources/pull.svg       |   2 -
 plugins/misc/git/src/main/resources/push.svg       |   2 -
 plugins/misc/git/src/main/resources/repository.svg |  24 -
 plugins/misc/git/src/main/resources/tag.svg        |  44 --
 .../environment/LifecycleEnvironmentDialog.java    |  11 +-
 .../apache/hop/projects/gui/ProjectsGuiPlugin.java | 542 ++++++++++++---------
 .../apache/hop/projects/project/ProjectDialog.java |  38 +-
 .../org/apache/hop/projects/util/ProjectsUtil.java |  11 +-
 .../src/main/resources/environment-add.svg         |  39 --
 .../src/main/resources/environment-delete.svg      |  36 --
 .../src/main/resources/environment-edit.svg        |  56 ---
 .../projects/src/main/resources/environment.svg    |  51 +-
 .../environment/messages/messages_de_DE.properties |  16 +-
 .../environment/messages/messages_en_US.properties |  16 +-
 .../environment/messages/messages_fr_FR.properties |  14 +-
 .../environment/messages/messages_it_IT.properties |  14 +-
 .../environment/messages/messages_pt_BR.properties |  16 +-
 .../gui/messages/messages_de_DE.properties         |  23 +-
 .../gui/messages/messages_en_US.properties         |  19 +-
 .../gui/messages/messages_fr_FR.properties         |  19 +-
 .../gui/messages/messages_it_IT.properties         |  23 +-
 .../gui/messages/messages_pt_BR.properties         |  19 +-
 .../gui/messages/messages_zh_CN.properties         |  23 +-
 .../project/messages/messages_en_US.properties     |  22 +-
 .../projects/src/main/resources/project-add.svg    |  39 --
 .../projects/src/main/resources/project-delete.svg |  36 --
 .../projects/src/main/resources/project-edit.svg   |  56 ---
 .../misc/projects/src/main/resources/project.svg   |  34 +-
 .../main/java/org/apache/hop/ui/hopgui/HopGui.java |  25 +-
 .../dataorch/HopDataOrchestrationPerspective.java  |  24 +-
 38 files changed, 735 insertions(+), 1051 deletions(-)

diff --git 
a/plugins/misc/git/src/main/java/org/apache/hop/git/GitGuiPlugin.java 
b/plugins/misc/git/src/main/java/org/apache/hop/git/GitGuiPlugin.java
index 526486b361..1e0542fa8f 100644
--- a/plugins/misc/git/src/main/java/org/apache/hop/git/GitGuiPlugin.java
+++ b/plugins/misc/git/src/main/java/org/apache/hop/git/GitGuiPlugin.java
@@ -18,8 +18,6 @@
 
 package org.apache.hop.git;
 
-import static org.apache.hop.core.Const.NVL;
-
 import java.io.File;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -29,13 +27,17 @@ import java.util.Set;
 import lombok.Getter;
 import org.apache.commons.vfs2.FileObject;
 import org.apache.commons.vfs2.FileSystemException;
+import org.apache.hop.core.Const;
 import org.apache.hop.core.exception.HopFileException;
 import org.apache.hop.core.gui.plugin.GuiPlugin;
 import org.apache.hop.core.gui.plugin.callback.GuiCallback;
+import org.apache.hop.core.gui.plugin.key.GuiKeyboardShortcut;
+import org.apache.hop.core.gui.plugin.key.GuiOsxKeyboardShortcut;
 import org.apache.hop.core.gui.plugin.menu.GuiMenuElement;
 import org.apache.hop.core.gui.plugin.toolbar.GuiToolbarElement;
 import org.apache.hop.core.gui.plugin.toolbar.GuiToolbarElementType;
 import org.apache.hop.core.logging.LogChannel;
+import org.apache.hop.core.util.Utils;
 import org.apache.hop.core.vfs.HopVfs;
 import org.apache.hop.git.info.GitInfoExplorerFileType;
 import org.apache.hop.git.info.GitInfoExplorerFileTypeHandler;
@@ -60,13 +62,13 @@ import 
org.apache.hop.ui.hopgui.perspective.explorer.IExplorerRootChangedListene
 import 
org.apache.hop.ui.hopgui.perspective.explorer.IExplorerSelectionListener;
 import org.eclipse.jgit.merge.MergeStrategy;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CLabel;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.ToolItem;
 import org.eclipse.swt.widgets.Tree;
 import org.eclipse.swt.widgets.TreeItem;
 
@@ -79,6 +81,16 @@ public class GitGuiPlugin
 
   public static final Class<?> PKG = GitGuiPlugin.class;
 
+  public static final String ID_TOOLBAR_ITEM_GIT = "toolbar-item-30000-git";
+  public static final String ID_CONTEXT_MENU_GIT = "context-menu-git";
+
+  public static final String CONTEXT_MENU_GIT_CREATE_BRANCH = 
"context-menu-git-20010-CreateBranch";
+  public static final String CONTEXT_MENU_GIT_MERGE_BRANCH = 
"context-menu-git-20020-MergeBranch";
+  public static final String CONTEXT_MENU_GIT_RENAME_BRANCH = 
"context-menu-git-20020-RenameBranch";
+  public static final String CONTEXT_MENU_GIT_DELETE_BRANCH = 
"context-menu-git-20030-DeleteBranch";
+  public static final String CONTEXT_MENU_GIT_PUSH = 
"context-menu-git-30000-Push";
+  public static final String CONTEXT_MENU_GIT_PULL = 
"context-menu-git-30010-Pull";
+
   public static final String TOOLBAR_ITEM_GIT_INFO = 
"ExplorerPerspective-Toolbar-20100-GitInfo";
   public static final String TOOLBAR_ITEM_ADD = 
"ExplorerPerspective-Toolbar-20200-Add";
   public static final String TOOLBAR_ITEM_REVERT = 
"ExplorerPerspective-Toolbar-20300-Revert";
@@ -152,12 +164,6 @@ public class GitGuiPlugin
     enableButtons();
   }
 
-  @GuiMenuElement(
-      root = ExplorerPerspective.GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
-      parentId = ExplorerPerspective.GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
-      id = CONTEXT_MENU_GIT_COMMIT,
-      label = "i18n::GitGuiPlugin.Menu.Commit.Text",
-      image = "git-commit.svg")
   @GuiToolbarElement(
       root = ExplorerPerspective.GUI_PLUGIN_TOOLBAR_PARENT_ID,
       id = TOOLBAR_ITEM_COMMIT,
@@ -254,6 +260,13 @@ public class GitGuiPlugin
     return HopVfs.getFileObject(filename).exists();
   }
 
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_GIT,
+      parentId = ID_CONTEXT_MENU_GIT,
+      id = CONTEXT_MENU_GIT_PUSH,
+      label = "i18n::GitGuiPlugin.Menu.Branch.Push.Text",
+      image = "push.svg",
+      separator = true)
   @GuiToolbarElement(
       root = ExplorerPerspective.GUI_PLUGIN_TOOLBAR_PARENT_ID,
       id = TOOLBAR_ITEM_PUSH,
@@ -271,11 +284,19 @@ public class GitGuiPlugin
     }
   }
 
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_GIT,
+      parentId = ID_CONTEXT_MENU_GIT,
+      id = CONTEXT_MENU_GIT_PULL,
+      label = "i18n::GitGuiPlugin.Menu.Branch.Pull.Text",
+      image = "pull.svg")
   @GuiToolbarElement(
       root = ExplorerPerspective.GUI_PLUGIN_TOOLBAR_PARENT_ID,
       id = TOOLBAR_ITEM_PULL,
       toolTip = "i18n::GitGuiPlugin.Toolbar.Pull.Tooltip",
       image = "pull.svg")
+  @GuiKeyboardShortcut(control = true, key = 'T')
+  @GuiOsxKeyboardShortcut(control = true, key = 'T')
   public void gitPull() {
     try {
       if (git.pull()) {
@@ -298,162 +319,69 @@ public class GitGuiPlugin
   }
 
   @GuiToolbarElement(
-      root = ExplorerPerspective.GUI_PLUGIN_TOOLBAR_PARENT_ID,
-      id = TOOLBAR_ITEM_BRANCH,
-      type = GuiToolbarElementType.LABEL,
-      label = "xxxxxxxxxxxxxxxxxxxxx",
-      toolTip = "i18n::GitGuiPlugin.Toolbar.Branch.Tooltip")
-  public void gitBranches() {
+      root = HopGui.ID_STATUS_TOOLBAR,
+      id = ID_TOOLBAR_ITEM_GIT,
+      type = GuiToolbarElementType.BUTTON,
+      image = "branch.svg",
+      toolTip = "i18n::GitGuiPlugin.Toolbar.Branch.Tooltip",
+      separator = true)
+  public void showGitContextMenu() {
+    ToolItem item = getGitToolItem();
+    if (item != null) {
+      Rectangle rect = item.getBounds();
+      Point pt = item.getParent().toDisplay(new Point(rect.x, rect.y + 
rect.height));
+      Menu menu = createGitContextMenu();
+      menu.setLocation(pt);
+      menu.setVisible(true);
+    }
+  }
+
+  private Menu createGitContextMenu() {
+    Shell shell = HopGui.getInstance().getActiveShell();
+    Menu menu = new Menu(shell, SWT.POP_UP);
+
+    if (git == null) {
+      return menu;
+    }
+
     try {
-      List<String> branches = git.getBranches();
-      Menu menu = new Menu(HopGui.getInstance().getShell());
-      String currentBranch = git.getBranch();
+      // Create context menu...
+      //
+      GuiMenuWidgets menuWidgets = new GuiMenuWidgets();
+      menuWidgets.registerGuiPluginObject(this);
+      menuWidgets.createMenuWidgets(ID_CONTEXT_MENU_GIT, shell, menu);
 
-      MenuItem createBranch = new MenuItem(menu, SWT.PUSH);
-      createBranch.setText(BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.CreateBranch"));
-      MenuItem deleteBranch = new MenuItem(menu, SWT.PUSH);
-      deleteBranch.setText(BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.DeleteBranch"));
-      MenuItem mergeBranch = new MenuItem(menu, SWT.PUSH);
-      mergeBranch.setText(BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.MergeBranch"));
       new MenuItem(menu, SWT.SEPARATOR);
 
-      // Create Branch listener
-      createBranch.addSelectionListener(
-          new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-              EnterStringDialog enterStringDialog =
-                  new EnterStringDialog(
-                      HopGui.getInstance().getShell(),
-                      "",
-                      BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.CreateBranch.Header"),
-                      BaseMessages.getString(
-                          PKG, 
"GitGuiPlugin.Dialog.Branch.CreateBranch.Message"));
-              String message = enterStringDialog.open();
-              if (message != null) {
-                boolean branchCreated = git.createBranch(message);
-                if (branchCreated) {
-                  MessageBox pullSuccessful =
-                      new MessageBox(HopGui.getInstance().getShell(), 
SWT.ICON_INFORMATION);
-                  pullSuccessful.setText(
-                      BaseMessages.getString(
-                          PKG, 
"GitGuiPlugin.Dialog.Branch.CreateBranchSuccessFul.Header"));
-                  pullSuccessful.setMessage(
-                      BaseMessages.getString(
-                          PKG, 
"GitGuiPlugin.Dialog.Branch.CreateBranchSuccessFul.Message"));
-                  pullSuccessful.open();
-                }
-                // Refresh the tree, change colors...
-                //
-                ExplorerPerspective.getInstance().refresh();
-              }
-            }
-          });
-
-      // Delete Branch listener
-      deleteBranch.addSelectionListener(
-          new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-              EnterSelectionDialog selectionDialog =
-                  new EnterSelectionDialog(
-                      HopGui.getInstance().getShell(),
-                      branches.toArray(new String[0]),
-                      BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.DeleteBranch.Header"),
-                      BaseMessages.getString(
-                          PKG, 
"GitGuiPlugin.Dialog.Branch.DeleteBranch.Message"));
-              String branchToDelete = selectionDialog.open();
-              if (branchToDelete != null) {
-                boolean branchDeleted = git.deleteBranch(branchToDelete, true);
-                if (branchDeleted) {
-                  MessageBox pullSuccessful =
-                      new MessageBox(HopGui.getInstance().getShell(), 
SWT.ICON_INFORMATION);
-                  pullSuccessful.setText(
-                      BaseMessages.getString(
-                          PKG, 
"GitGuiPlugin.Dialog.Branch.DeleteBranchSuccessFul.Header"));
-                  pullSuccessful.setMessage(
-                      BaseMessages.getString(
-                          PKG, 
"GitGuiPlugin.Dialog.Branch.DeleteBranchSuccessFul.Message"));
-                  pullSuccessful.open();
-                }
-                // Refresh the tree, change colors...
-                //
-                ExplorerPerspective.getInstance().refresh();
-              }
-            }
-          });
-
-      // Merge Branch listener
-      mergeBranch.addSelectionListener(
-          new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-              EnterSelectionDialog selectionDialog =
-                  new EnterSelectionDialog(
-                      HopGui.getInstance().getShell(),
-                      branches.toArray(new String[0]),
-                      BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.MergeBranch.Header"),
-                      BaseMessages.getString(
-                          PKG, 
"GitGuiPlugin.Dialog.Branch.MergeBranch.Message"));
-              String branchToMerge = selectionDialog.open();
-              if (branchToMerge != null) {
-                try {
-                  boolean branchMerged = git.mergeBranch(branchToMerge, 
MergeStrategy.RECURSIVE);
-                  if (branchMerged) {
-                    MessageBox mergeSuccessful =
-                        new MessageBox(HopGui.getInstance().getShell(), 
SWT.ICON_INFORMATION);
-                    mergeSuccessful.setText(
-                        BaseMessages.getString(
-                            PKG, 
"GitGuiPlugin.Dialog.Branch.MergeBranchSuccessFul.Header"));
-                    mergeSuccessful.setMessage(
-                        BaseMessages.getString(
-                            PKG, 
"GitGuiPlugin.Dialog.Branch.MergeBranchSuccessFul.Message"));
-                    mergeSuccessful.open();
-                  }
-                } catch (Exception ex) {
-                  new ErrorDialog(
-                      HopGui.getInstance().getShell(),
-                      BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.MergeBranchError.Header"),
-                      BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.MergeBranchError.Message"),
-                      ex);
-                }
-                // Refresh the tree, change colors...
-                //
-                ExplorerPerspective.getInstance().refresh();
-              }
-            }
-          });
-
       // Add all known branches to the list
-      for (String branch : branches) {
+      // int count = 0;
+      String currentBranch = git.getBranch();
+      for (String name : git.getBranches()) {
         MenuItem item = new MenuItem(menu, SWT.CHECK);
-        item.setText(branch);
-        // If the item is the active branch mark it as checked
-        if (branch.equals(currentBranch)) {
-          item.setSelection(true);
-        }
+        item.setText(name);
+        // If the item is the active branch, mark it as checked
+        item.setSelection(currentBranch.equals(name));
         // Change Branch when selecting one of the branch options
-        item.addSelectionListener(
-            new SelectionAdapter() {
-              @Override
-              public void widgetSelected(SelectionEvent e) {
-                MenuItem item = (MenuItem) e.widget;
-                git.checkout(item.getText());
-                // Refresh the tree, change colors...
-                //
-                ExplorerPerspective.getInstance().refresh();
-              }
-            });
+        item.addListener(SWT.Selection, e -> gitCheckoutBranch(name));
+
+        // if (++count == 10) break;
       }
 
-      menu.setVisible(true);
+      // TODO: display only the last 10 used branches
+      // if (count == 10) {
+      // new MenuItem(menu, SWT.SEPARATOR);
+      // MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
+      // menuItem.setText("More...");
+      // }
     } catch (Exception e) {
       new ErrorDialog(
-          HopGui.getInstance().getShell(),
+          shell,
           BaseMessages.getString(PKG, "GitGuiPlugin.Dialog.Branch.Header"),
           BaseMessages.getString(PKG, "GitGuiPlugin.Dialog.Branch.Message"),
           e);
     }
+
+    return menu;
   }
 
   @GuiMenuElement(
@@ -565,8 +493,147 @@ public class GitGuiPlugin
     enableButtons();
   }
 
-  private String calculateRelativePath(String directory, ExplorerFile 
explorerFile) {
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_GIT,
+      parentId = ID_CONTEXT_MENU_GIT,
+      id = CONTEXT_MENU_GIT_CREATE_BRANCH,
+      label = "i18n::GitGuiPlugin.Menu.Branch.Create.Text",
+      image = "ui/images/add.svg")
+  public void gitCreateBranch() {
+    EnterStringDialog enterStringDialog =
+        new EnterStringDialog(
+            HopGui.getInstance().getShell(),
+            "",
+            BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.CreateBranch.Header"),
+            BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.CreateBranch.Message"));
+    String message = enterStringDialog.open();
+    if (message != null) {
+      boolean branchCreated = git.createBranch(message);
+      if (branchCreated) {
+        MessageBox pullSuccessful =
+            new MessageBox(HopGui.getInstance().getShell(), 
SWT.ICON_INFORMATION);
+        pullSuccessful.setText(
+            BaseMessages.getString(
+                PKG, 
"GitGuiPlugin.Dialog.Branch.CreateBranchSuccessFul.Header"));
+        pullSuccessful.setMessage(
+            BaseMessages.getString(
+                PKG, 
"GitGuiPlugin.Dialog.Branch.CreateBranchSuccessFul.Message"));
+        pullSuccessful.open();
+      }
+      // Refresh the tree, change colors...
+      //
+      ExplorerPerspective.getInstance().refresh();
+    }
+  }
+
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_GIT,
+      parentId = ID_CONTEXT_MENU_GIT,
+      id = CONTEXT_MENU_GIT_RENAME_BRANCH,
+      label = "i18n::GitGuiPlugin.Menu.Branch.Rename.Text",
+      image = "ui/images/rename.svg")
+  public void gitRenameBranch() {
+    String oldName = getGitToolItem().getText();
+    EnterStringDialog enterStringDialog =
+        new EnterStringDialog(
+            HopGui.getInstance().getShell(),
+            oldName,
+            BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.RenameBranch.Header"),
+            BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.RenameBranch.Message"));
+    String newName = enterStringDialog.open();
+    if (!Utils.isEmpty(newName) && !newName.equals(oldName)) {
+      boolean renamed = git.renameBranch(oldName, newName);
+      if (renamed) {
+        this.setBranchLabel(newName);
+      }
+    }
+  }
+
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_GIT,
+      parentId = ID_CONTEXT_MENU_GIT,
+      id = CONTEXT_MENU_GIT_MERGE_BRANCH,
+      label = "i18n::GitGuiPlugin.Menu.Branch.Merge.Text",
+      image = "merge.svg")
+  public void gitMergeBranch() {
+    List<String> branches = git.getBranches();
+    EnterSelectionDialog selectionDialog =
+        new EnterSelectionDialog(
+            HopGui.getInstance().getShell(),
+            branches.toArray(new String[0]),
+            BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.MergeBranch.Header"),
+            BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.MergeBranch.Message"));
+    String branchToMerge = selectionDialog.open();
+    if (branchToMerge != null) {
+      try {
+        boolean branchMerged = git.mergeBranch(branchToMerge, 
MergeStrategy.RECURSIVE);
+        if (branchMerged) {
+          MessageBox mergeSuccessful =
+              new MessageBox(HopGui.getInstance().getShell(), 
SWT.ICON_INFORMATION);
+          mergeSuccessful.setText(
+              BaseMessages.getString(
+                  PKG, 
"GitGuiPlugin.Dialog.Branch.MergeBranchSuccessFul.Header"));
+          mergeSuccessful.setMessage(
+              BaseMessages.getString(
+                  PKG, 
"GitGuiPlugin.Dialog.Branch.MergeBranchSuccessFul.Message"));
+          mergeSuccessful.open();
+        }
+      } catch (Exception ex) {
+        new ErrorDialog(
+            HopGui.getInstance().getShell(),
+            BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.MergeBranchError.Header"),
+            BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.MergeBranchError.Message"),
+            ex);
+      }
+      // Refresh the tree, change colors...
+      //
+      ExplorerPerspective.getInstance().refresh();
+    }
+  }
+
+  private void gitCheckoutBranch(String name) {
+    git.checkout(name);
+
+    // Refresh the tree, change colors...
+    //
+    ExplorerPerspective.getInstance().refresh();
+  }
+
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_GIT,
+      parentId = ID_CONTEXT_MENU_GIT,
+      id = CONTEXT_MENU_GIT_DELETE_BRANCH,
+      label = "i18n::GitGuiPlugin.Menu.Branch.Delete.Text",
+      image = "ui/images/delete.svg")
+  public void gitDeleteBranch() {
+    List<String> branches = git.getBranches();
+    EnterSelectionDialog selectionDialog =
+        new EnterSelectionDialog(
+            HopGui.getInstance().getShell(),
+            branches.toArray(new String[0]),
+            BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.DeleteBranch.Header"),
+            BaseMessages.getString(PKG, 
"GitGuiPlugin.Dialog.Branch.DeleteBranch.Message"));
+    String branchToDelete = selectionDialog.open();
+    if (branchToDelete != null) {
+      boolean branchDeleted = git.deleteBranch(branchToDelete, true);
+      if (branchDeleted) {
+        MessageBox pullSuccessful =
+            new MessageBox(HopGui.getInstance().getShell(), 
SWT.ICON_INFORMATION);
+        pullSuccessful.setText(
+            BaseMessages.getString(
+                PKG, 
"GitGuiPlugin.Dialog.Branch.DeleteBranchSuccessFul.Header"));
+        pullSuccessful.setMessage(
+            BaseMessages.getString(
+                PKG, 
"GitGuiPlugin.Dialog.Branch.DeleteBranchSuccessFul.Message"));
+        pullSuccessful.open();
+      }
+      // Refresh the tree, change colors...
+      //
+      ExplorerPerspective.getInstance().refresh();
+    }
+  }
 
+  private String calculateRelativePath(String directory, ExplorerFile 
explorerFile) {
     try {
       FileObject file = HopVfs.getFileObject(explorerFile.getFilename());
       FileObject root = HopVfs.getFileObject(directory);
@@ -695,6 +762,8 @@ public class GitGuiPlugin
     menuWidgets.enableMenuItem(CONTEXT_MENU_GIT_ADD, isSelected);
     menuWidgets.enableMenuItem(CONTEXT_MENU_GIT_COMMIT, isSelected);
     menuWidgets.enableMenuItem(CONTEXT_MENU_GIT_REVERT, isSelected);
+
+    getGitToolItem().setEnabled(isGit);
   }
 
   /**
@@ -778,13 +847,15 @@ public class GitGuiPlugin
     return git;
   }
 
+  private static ToolItem getGitToolItem() {
+    return 
HopGui.getInstance().getStatusToolbarWidgets().findToolItem(ID_TOOLBAR_ITEM_GIT);
+  }
+
   private void setBranchLabel(String branch) {
     // Set the branch name
-    GuiToolbarWidgets widgets = ExplorerPerspective.getToolBarWidgets();
-    Map<String, Control> widgetsMap = widgets.getWidgetsMap();
-    CLabel branchLabel = (CLabel) widgetsMap.get(TOOLBAR_ITEM_BRANCH);
-    branchLabel.setText(
-        BaseMessages.getString(PKG, "GitGuiPlugin.Dialog.Branch.BranchName", 
NVL(branch, "")));
-    branchLabel.setEnabled(branch != null);
+    ToolItem item = getGitToolItem();
+    if (item != null && !item.isDisposed()) {
+      item.setText(Const.NVL(branch, ""));
+    }
   }
 }
diff --git a/plugins/misc/git/src/main/java/org/apache/hop/git/model/UIGit.java 
b/plugins/misc/git/src/main/java/org/apache/hop/git/model/UIGit.java
index 97ab9f7a47..7e85c7cddc 100644
--- a/plugins/misc/git/src/main/java/org/apache/hop/git/model/UIGit.java
+++ b/plugins/misc/git/src/main/java/org/apache/hop/git/model/UIGit.java
@@ -837,6 +837,17 @@ public class UIGit extends VCS {
     }
   }
 
+  public boolean renameBranch(String oldName, String newName) {
+    try {
+      git.branchRename().setOldName(oldName).setNewName(newName).call();
+      checkoutBranch(getExpandedName(newName, VCS.TYPE_BRANCH));
+      return true;
+    } catch (Exception e) {
+      showMessageBox(BaseMessages.getString(PKG, CONST_DIALOG_ERROR), 
e.getMessage());
+      return false;
+    }
+  }
+
   public boolean deleteBranch(String name, boolean force) {
     try {
       git.branchDelete()
diff --git a/plugins/misc/git/src/main/resources/branch.svg 
b/plugins/misc/git/src/main/resources/branch.svg
index c7c7cd23fc..633af9c673 100644
--- a/plugins/misc/git/src/main/resources/branch.svg
+++ b/plugins/misc/git/src/main/resources/branch.svg
@@ -1,42 +1,4 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        version="1.1"
-        x="0px"
-        y="0px"
-        viewBox="0 0 16 16"
-        enable-background="new 0 0 16 16"
-        width="16px"
-        height="16px">
-
-    <circle
-            r="2.5"
-            cy="3.5"
-            cx="3.5"
-            
style="fill:none;fill-opacity:1;stroke:#3d6380;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <circle
-            
style="fill:none;fill-opacity:1;stroke:#3d6380;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-            cx="3.5"
-            cy="12.5"
-            r="2.5"/>
-    <circle
-            r="2.5"
-            cy="8.5158167"
-            cx="12.5"
-            
style="fill:none;fill-opacity:1;stroke:#3d6380;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <path
-            d="m 3.5,4.9701937 c 0,6.0000003 0,6.0000003 0,6.0000003 l 0,0"
-            
style="fill:none;fill-rule:evenodd;stroke:#3d6380;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <path
-            d="m 5,12 c 4,0 6,-2 6,-2"
-            
style="fill:none;fill-rule:evenodd;stroke:#3d6380;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"/>
-    <path
-            d="M 2.8750101,4.83184 C 2.561256,4.6828448 2.3093469,4.4273512 
2.1546186,4.101198 2.0458581,3.8719408 2.0305774,3.7971312 2.0312724,3.4973333 
2.0323037,3.0524728 2.1620215,2.7477698 2.4773258,2.4495681 2.800113,2.1442895 
3.0757084,2.0316863 3.4990037,2.0321294 3.786166,2.0324301 3.8807138,2.0503858 
4.0869495,2.1437873 4.3980364,2.2846745 4.7072783,2.5946747 4.8548766,2.9135974 
4.9491934,3.1173922 4.9667322,3.2086239 4.9670964,3.4973333 4.9674749,3.7978468 
4.9521139,3.8721714 [...]
-            
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <path
-            d="M 3.0498967,13.910515 C 2.289671,13.627081 1.877696,12.890469 
2.0667278,12.152605 c 0.1178304,-0.459936 0.4149544,-0.814213 
0.8517469,-1.015583 0.2848515,-0.131322 0.8762064,-0.131322 1.161058,0 
0.9627554,0.443849 1.2018597,1.658466 0.4696873,2.385949 -0.317573,0.315539 
-0.5396331,0.41172 -0.9898298,0.428727 -0.2385252,0.009 -0.4126041,-0.0051 
-0.5094935,-0.04118 z"
-            
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <path
-            d="M 11.98445,9.9026308 C 10.74926,9.4074902 10.701086,7.731986 
11.905801,7.167237 c 0.197172,-0.09243 0.280858,-0.1070958 0.610916,-0.107058 
0.342678,3.92e-5 0.406584,0.012263 0.614559,0.1175494 0.27655,0.1400021 
0.603903,0.4727024 0.725993,0.7378512 0.07188,0.1560997 0.08811,0.2652528 
0.08833,0.593831 2.34e-4,0.3524866 -0.01311,0.4311102 -0.107231,0.6319041 
-0.13726,0.2928279 -0.417609,0.5730006 -0.709876,0.7094308 C 12.822191,9.993727 
12.27375,10.0186 11.98445,9.9026308 Z"
-            
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="24" height="24">
+    <path fill="#0e3a5a" d="M13,14C9.64,14 8.54,15.35 8.18,16.24C9.25,16.7 
10,17.76 10,19A3,3 0 0,1 7,22A3,3 0 0,1 4,19C4,17.69 4.83,16.58 
6,16.17V7.83C4.83,7.42 4,6.31 4,5A3,3 0 0,1 7,2A3,3 0 0,1 10,5C10,6.31 
9.17,7.42 8,7.83V13.12C8.88,12.47 10.16,12 12,12C14.67,12 15.56,10.66 
15.85,9.77C14.77,9.32 14,8.25 14,7A3,3 0 0,1 17,4A3,3 0 0,1 20,7C20,8.34 
19.12,9.5 17.91,9.86C17.65,11.29 16.68,14 13,14M7,18A1,1 0 0,0 6,19A1,1 0 0,0 
7,20A1,1 0 0,0 8,19A1,1 0 0,0 7,18M7,4A1,1 0 0,0 6,5A1,1 0 0, [...]
 </svg>
\ No newline at end of file
diff --git a/plugins/misc/git/src/main/resources/git-add.svg 
b/plugins/misc/git/src/main/resources/git-add.svg
index 846fced426..f75f35e728 100644
--- a/plugins/misc/git/src/main/resources/git-add.svg
+++ b/plugins/misc/git/src/main/resources/git-add.svg
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 
6.00 Build 43363)  -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
 <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; x="0px" y="0px"
         width="97px" height="97px" viewBox="0 0 97 97" enable-background="new 
0 0 97 97" xml:space="preserve">
 <g transform="matrix(0.84298576,0,0,0.84298576,0.40113214,0.40160318)">
diff --git a/plugins/misc/git/src/main/resources/git-commit.svg 
b/plugins/misc/git/src/main/resources/git-commit.svg
index 99cd2e2761..a71fd123f1 100644
--- a/plugins/misc/git/src/main/resources/git-commit.svg
+++ b/plugins/misc/git/src/main/resources/git-commit.svg
@@ -1,8 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; x="0px" y="0px"
-        width="24px" height="24px" viewBox="0 0 800 800" 
enable-background="new 0 0 800 800" xml:space="preserve">
-<title>ionicons-v5-d</title>
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg"; width="24px" 
height="24px" viewBox="0 0 800 800" enable-background="new 0 0 800 800" 
xml:space="preserve">
 <path fill="#0E3A5A" 
d="M700,350H593.75c-27.566-106.962-136.622-171.326-243.584-143.76
        
C279.648,224.414,224.58,279.481,206.406,350H100c-27.614,0-50,22.386-50,50s22.386,50,50,50h106.328
        
c27.481,106.983,136.487,171.433,243.471,143.951C520.441,575.805,575.604,520.642,593.75,450H700c27.613,0,50-22.386,50-50
diff --git a/plugins/misc/git/src/main/resources/git_icon_inactive.svg 
b/plugins/misc/git/src/main/resources/git_icon_inactive.svg
deleted file mode 100644
index ccf98f9d30..0000000000
--- a/plugins/misc/git/src/main/resources/git_icon_inactive.svg
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        enable-background="new 0 0 97 97"
-        viewBox="0 0 97 97"
-        height="97px"
-        width="97px"
-        y="0px"
-        x="0px"
-        version="1.1"
->
-    <g
-            style="opacity:0.3"
-    >
-        <path
-                style=""
-                
d="M92.71,44.408L52.591,4.291c-2.31-2.311-6.057-2.311-8.369,0l-8.33,8.332L46.459,23.19
   
c2.456-0.83,5.272-0.273,7.229,1.685c1.969,1.97,2.521,4.81,1.67,7.275l10.186,10.185c2.465-0.85,5.307-0.3,7.275,1.671
   
c2.75,2.75,2.75,7.206,0,9.958c-2.752,2.751-7.208,2.751-9.961,0c-2.068-2.07-2.58-5.11-1.531-7.658l-9.5-9.499v24.997
   
c0.67,0.332,1.303,0.774,1.861,1.332c2.75,2.75,2.75,7.206,0,9.959c-2.75,2.749-7.209,2.749-9.957,0c-2.75-2.754-2.75-7.21,0-9.959
   c0.68-0.679,1.467-1.193 [...]
-                fill="#F05133"/>
-    </g>
-</svg>
\ No newline at end of file
diff --git a/plugins/misc/git/src/main/resources/merge.svg 
b/plugins/misc/git/src/main/resources/merge.svg
new file mode 100644
index 0000000000..b9d0cd9ef1
--- /dev/null
+++ b/plugins/misc/git/src/main/resources/merge.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="24" height="24">
+    <path fill="#0e3a5a" d="M7,3A3,3 0 0,1 10,6C10,7.29 9.19,8.39 
8.04,8.81C8.58,13.81 13.08,14.77 15.19,14.96C15.61,13.81 16.71,13 18,13A3,3 0 
0,1 21,16A3,3 0 0,1 18,19C16.69,19 15.57,18.16 15.16,17C10.91,16.8 9.44,15.19 
8,13.39V15.17C9.17,15.58 10,16.69 10,18A3,3 0 0,1 7,21A3,3 0 0,1 4,18C4,16.69 
4.83,15.58 6,15.17V8.83C4.83,8.42 4,7.31 4,6A3,3 0 0,1 7,3M7,5A1,1 0 0,0 
6,6A1,1 0 0,0 7,7A1,1 0 0,0 8,6A1,1 0 0,0 7,5M7,17A1,1 0 0,0 6,18A1,1 0 0,0 
7,19A1,1 0 0,0 8,18A1,1 0 0,0 7,17M18,15A1, [...]
+</svg>
\ No newline at end of file
diff --git 
a/plugins/misc/git/src/main/resources/org/apache/hop/git/messages/messages_en_US.properties
 
b/plugins/misc/git/src/main/resources/org/apache/hop/git/messages/messages_en_US.properties
index 8a38e968b7..32b820dbdc 100644
--- 
a/plugins/misc/git/src/main/resources/org/apache/hop/git/messages/messages_en_US.properties
+++ 
b/plugins/misc/git/src/main/resources/org/apache/hop/git/messages/messages_en_US.properties
@@ -23,19 +23,18 @@ GitGuiPlugin.Dialog.AddError.Message=There was an error 
doing a git add
 GitGuiPlugin.Dialog.Branch.BranchName=Branch: {0}
 GitGuiPlugin.Dialog.Branch.CreateBranch.Header=Create a Branch
 GitGuiPlugin.Dialog.Branch.CreateBranch.Message=Branch name
-GitGuiPlugin.Dialog.Branch.CreateBranch=Create Branch
 GitGuiPlugin.Dialog.Branch.CreateBranchSuccessFul.Header=Branch Created
 GitGuiPlugin.Dialog.Branch.CreateBranchSuccessFul.Message=Branch created 
Successfully
-GitGuiPlugin.Dialog.Branch.DeleteBranch.Header=Create a Branch
-GitGuiPlugin.Dialog.Branch.DeleteBranch.Message=Branch name
-GitGuiPlugin.Dialog.Branch.DeleteBranch=Delete Branch
+GitGuiPlugin.Dialog.Branch.DeleteBranch.Header=Delete a Branch
+GitGuiPlugin.Dialog.Branch.DeleteBranch.Message=Select the branch you want to 
delete
 GitGuiPlugin.Dialog.Branch.DeleteBranchSuccessFul.Header=Branch Deleted
 GitGuiPlugin.Dialog.Branch.DeleteBranchSuccessFul.Message=Branch deleted 
Successfully
 GitGuiPlugin.Dialog.Branch.MergeBranch.Header=Merge Branch
 GitGuiPlugin.Dialog.Branch.MergeBranch.Message=Select the branch you want to 
merge
-GitGuiPlugin.Dialog.Branch.MergeBranch=Merge Branch
 GitGuiPlugin.Dialog.Branch.MergeBranchSuccessFul.Header=Merge successful
 GitGuiPlugin.Dialog.Branch.MergeBranchSuccessFul.Message=Successful merge
+GitGuiPlugin.Dialog.Branch.RenameBranch.Header=Rename a Branch
+GitGuiPlugin.Dialog.Branch.RenameBranch.Message=New branch name
 GitGuiPlugin.Dialog.CommitError.Header=Commit Error
 GitGuiPlugin.Dialog.CommitError.Message=There was an error doing a git commit
 GitGuiPlugin.Dialog.FilesReverted.Header=Files Reverted
@@ -64,6 +63,12 @@ GitGuiPlugin.Dialog.StageFiles.Header=Select files to commit
 GitGuiPlugin.Dialog.StageFiles.Message=Please select the files to commit. 
They'll be staged (add) for the commit to git
 GitGuiPlugin.Info.Label=Git Info: {0}
 GitGuiPlugin.Menu.Add.Text=Git Add
+GitGuiPlugin.Menu.Branch.Create.Text=Create Branch...
+GitGuiPlugin.Menu.Branch.Delete.Text=Delete Branch...
+GitGuiPlugin.Menu.Branch.Merge.Text=Merge Branch...
+GitGuiPlugin.Menu.Branch.Pull.Text=Pull...
+GitGuiPlugin.Menu.Branch.Push.Text=Push...
+GitGuiPlugin.Menu.Branch.Rename.Text=Rename Branch...
 GitGuiPlugin.Menu.Commit.Text=Git Commit
 GitGuiPlugin.Menu.Info.Text=Git Info
 GitGuiPlugin.Menu.Revert.Text=Git Revert
diff --git a/plugins/misc/git/src/main/resources/pull.svg 
b/plugins/misc/git/src/main/resources/pull.svg
index 5d4994cae8..1116d6555c 100644
--- a/plugins/misc/git/src/main/resources/pull.svg
+++ b/plugins/misc/git/src/main/resources/pull.svg
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 
6.00 Build 43363)  -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
 <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; x="0px" y="0px"
         width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 
0 0 16 16" xml:space="preserve">
 <g>
diff --git a/plugins/misc/git/src/main/resources/push.svg 
b/plugins/misc/git/src/main/resources/push.svg
index 450cea8ca4..8baf1b58eb 100644
--- a/plugins/misc/git/src/main/resources/push.svg
+++ b/plugins/misc/git/src/main/resources/push.svg
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 
6.00 Build 43363)  -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
 <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; x="0px" y="0px"
         width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 
0 0 16 16" xml:space="preserve">
 <rect x="7.002" y="4.073" fill="#0E3A5A" width="2" height="9"/>
diff --git a/plugins/misc/git/src/main/resources/repository.svg 
b/plugins/misc/git/src/main/resources/repository.svg
deleted file mode 100644
index f8a57c03ef..0000000000
--- a/plugins/misc/git/src/main/resources/repository.svg
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        version="1.1"
-        x="0px"
-        y="0px"
-        viewBox="0 0 16 16"
-        enable-background="new 0 0 16 16"
-        width="16px"
-        height="16px">
-
-    <path
-            d="M 14 3.5273438 A 10.506676 7.0558767 0 0 1 13.919922 3.5644531 
A 10.506676 7.0558767 0 0 1 13.025391 3.9355469 A 10.506676 7.0558767 0 0 1 
12.082031 4.2441406 A 10.506676 7.0558767 0 0 1 11.095703 4.4863281 A 10.506676 
7.0558767 0 0 1 10.078125 4.6621094 A 10.506676 7.0558767 0 0 1 9.0410156 
4.7695312 A 10.506676 7.0558767 0 0 1 7.9921875 4.8066406 A 10.506676 7.0558767 
0 0 1 7.9179688 4.8066406 A 10.506676 7.0558767 0 0 1 6.8691406 4.765625 A 
10.506676 7.0558767 0 0 1 5.8 [...]
-            
style="fill:none;fill-opacity:1;stroke:#3d6380;stroke-width:1.94511342;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <path
-            d="M 2 2.21875 L 2 3.5449219 A 10.506676 7.0558767 0 0 0 2.890625 
3.9179688 A 10.506676 7.0558767 0 0 0 3.8339844 4.2304688 A 10.506676 7.0558767 
0 0 0 4.8164062 4.4765625 A 10.506676 7.0558767 0 0 0 5.8320312 4.65625 A 
10.506676 7.0558767 0 0 0 6.8691406 4.765625 A 10.506676 7.0558767 0 0 0 
7.9179688 4.8066406 A 10.506676 7.0558767 0 0 0 7.9921875 4.8066406 A 10.506676 
7.0558767 0 0 0 9.0410156 4.7695312 A 10.506676 7.0558767 0 0 0 10.078125 
4.6621094 A 10.506676 7.0558767 0 [...]
-            
style="fill:none;fill-opacity:1;stroke:#3d6380;stroke-width:1.94511342;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <path
-            d="m 6.7681443,14.026377 c -1.315269,-0.120466 
-2.7035844,-0.438525 -3.7398501,-0.856791 -0.051659,-0.02085 
-0.054653,-0.245299 -0.054653,-4.0964002 0,-3.8658107 0.0028,-4.0734936 
0.054653,-4.0577867 0.030059,0.0091 0.1670831,0.05126 0.3044972,0.093678 
0.9121799,0.2815786 2.0397071,0.5040021 3.1074329,0.612993 0.5429859,0.055427 
2.0193972,0.074113 2.6077451,0.033005 1.2703276,-0.088758 2.5897646,-0.328431 
3.6103506,-0.655813 0.164956,-0.052914 0.309006,-0.096208 0.320113,-0.0 [...]
-            
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <path
-            d="M 7.1741406,3.7958594 C 6.1582749,3.7150555 5.6559389,3.6454066 
4.9285857,3.4845129 4.3799103,3.3631436 3.6714529,3.1563589 3.2391,2.9913857 L 
2.9580257,2.8841359 3.0829476,2.830419 C 3.6214302,2.5988695 4.778053,2.2808062 
5.5657708,2.1476596 6.4952892,1.9905447 6.8878198,1.96002 7.9861331,1.9594427 c 
1.0099725,-5.308e-4 1.2728251,0.015601 2.0612119,0.126504 0.9141,0.1285869 
2.088018,0.429309 2.781084,0.7124292 l 0.185812,0.075905 -0.142308,0.061313 C 
12.651336,3.0306391 1 [...]
-            
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-</svg>
\ No newline at end of file
diff --git a/plugins/misc/git/src/main/resources/tag.svg 
b/plugins/misc/git/src/main/resources/tag.svg
deleted file mode 100644
index b7233172d0..0000000000
--- a/plugins/misc/git/src/main/resources/tag.svg
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        version="1.1"
-        x="0px"
-        y="0px"
-        viewBox="0 0 16 16"
-        enable-background="new 0 0 16 16"
-        width="16px"
-        height="16px">
-
-    <g
-            style="fill:none;stroke:none;stroke-opacity:1"
-    >
-        <g
-                style="fill:none;stroke:none;stroke-opacity:1"
-        >
-            <rect
-                    fill="none"
-                    style="fill:none;stroke:none;stroke-opacity:1"
-                    width="16"
-                    height="16"
-            />
-        </g>
-    </g>
-    <path
-            d="M 2.8750101,4.83184 C 2.561256,4.6828448 2.3093469,4.4273512 
2.1546186,4.101198 2.0458581,3.8719408 2.0305774,3.7971312 2.0312724,3.4973333 
2.0323037,3.0524728 2.1620215,2.7477698 2.4773258,2.4495681 2.800113,2.1442895 
3.0757084,2.0316863 3.4990037,2.0321294 3.786166,2.0324301 3.8807138,2.0503858 
4.0869495,2.1437873 4.3980364,2.2846745 4.7072783,2.5946747 4.8548766,2.9135974 
4.9491934,3.1173922 4.9667322,3.2086239 4.9670964,3.4973333 4.9674749,3.7978468 
4.9521139,3.8721714 [...]
-            
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <path
-            d="M 1.0332031 1.0019531 L 1.0332031 6.9453125 L 1.1230469 
6.9453125 L 1.046875 7.0214844 L 9.0878906 15.0625 L 15.078125 9.0722656 L 
7.0371094 1.03125 L 7.0078125 1.0605469 L 7.0078125 1.0019531 L 1.0332031 
1.0019531 z "
-            
style="fill:none;fill-opacity:1;stroke:#3d6380;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <ellipse
-            ry="1.4987406"
-            rx="1.5143459"
-            cy="4.4687896"
-            cx="4.5156054"
-            
style="fill:#3d6380;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <path
-            d="m 5.5653692,10.115562 -3.5108847,-3.5111941 0,-2.2901108 
0,-2.2901109 2.2782519,0 2.2782521,0 3.5230615,3.5231238 3.523062,3.5231237 
-2.278277,2.2781813 c -1.253052,1.253 -2.2837455,2.278182 -2.2904291,2.278182 
-0.00668,0 -1.59205,-1.580038 -3.5230367,-3.511195 z M 4.8947068,5.9262001 C 
5.1108251,5.8744916 5.3713109,5.7334121 5.5456863,5.5736287 6.177585,4.9946084 
6.2014238,4.0159485 5.5982713,3.4148659 5.3008995,3.1185147 4.9370433,2.9675729 
4.5200392,2.9675729 c -0.43259 [...]
-            
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-    <path
-            d="m 5.5654516,10.115728 -3.5109671,-3.5110299 0,-2.2902759 
0,-2.290276 2.2782519,0 2.2782521,0 3.5230615,3.5231238 3.523062,3.5231237 
-2.278277,2.2781813 c -1.253052,1.253 -2.2837085,2.278182 -2.2903467,2.278182 
-0.00664,0 -1.5920048,-1.579963 -3.5230367,-3.511029 z M 5.0363769,5.8834832 C 
5.742329,5.6103355 6.1492995,4.9014805 6.0088947,4.1895666 5.8684702,3.477554 
5.24109,2.9658801 4.5101296,2.9672156 c -0.9853051,0.0018 -1.7073747,0.923697 
-1.4651824,1.8706601 0.069903,0. [...]
-            
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
-</svg>
\ No newline at end of file
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java
index 25033ebf10..dbd7893974 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java
@@ -28,6 +28,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.projects.config.ProjectsConfig;
 import org.apache.hop.projects.config.ProjectsConfigSingleton;
 import org.apache.hop.projects.project.ProjectConfig;
+import org.apache.hop.ui.core.ConstUi;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
@@ -94,7 +95,13 @@ public class LifecycleEnvironmentDialog extends Dialog {
     Shell parent = getParent();
 
     shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | 
SWT.RESIZE);
-    shell.setImage(GuiResource.getInstance().getImageHopUi());
+    shell.setImage(
+        GuiResource.getInstance()
+            .getImage(
+                "environment.svg",
+                PKG.getClassLoader(),
+                ConstUi.SMALL_ICON_SIZE,
+                ConstUi.SMALL_ICON_SIZE));
     PropsUi.setLook(shell);
 
     int margin = PropsUi.getMargin() + 2;
@@ -241,6 +248,8 @@ public class LifecycleEnvironmentDialog extends Dialog {
 
     getData();
 
+    wName.setFocus();
+
     BaseDialog.defaultShellHandling(shell, c -> ok(), c -> cancel());
 
     return returnValue;
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/ProjectsGuiPlugin.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/ProjectsGuiPlugin.java
index ece133c9c9..6e2a2a8ed1 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/ProjectsGuiPlugin.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/ProjectsGuiPlugin.java
@@ -25,7 +25,6 @@ import java.io.OutputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.Collections;
 import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
@@ -73,11 +72,12 @@ import org.apache.hop.ui.core.FormDataBuilder;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.bus.HopGuiEvents;
 import org.apache.hop.ui.core.dialog.BaseDialog;
+import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.dialog.ProgressMonitorDialog;
+import org.apache.hop.ui.core.gui.GuiMenuWidgets;
 import org.apache.hop.ui.core.gui.GuiResource;
-import org.apache.hop.ui.core.gui.GuiToolbarWidgets;
 import org.apache.hop.ui.core.gui.HopNamespace;
 import org.apache.hop.ui.core.vfs.HopVfsFileDialog;
 import org.apache.hop.ui.core.widget.FileTree;
@@ -87,29 +87,37 @@ import 
org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.apache.hop.workflow.config.WorkflowRunConfiguration;
 import org.apache.hop.workflow.engines.local.LocalWorkflowRunConfiguration;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.ToolItem;
 
 @GuiPlugin
 public class ProjectsGuiPlugin {
 
   public static final Class<?> PKG = ProjectsGuiPlugin.class; // i18n
 
-  public static final String ID_TOOLBAR_PROJECT_LABEL = 
"toolbar-40000-project-label";
-  public static final String ID_TOOLBAR_PROJECT_COMBO = 
"toolbar-40010-project-list";
-  public static final String ID_TOOLBAR_PROJECT_EDIT = 
"toolbar-40020-project-edit";
-  public static final String ID_TOOLBAR_PROJECT_ADD = 
"toolbar-40030-project-add";
-  public static final String ID_TOOLBAR_PROJECT_DELETE = 
"toolbar-40040-project-delete";
+  public static final String ID_TOOLBAR_ITEM_PROJECT = 
"toolbar-item-10000-project";
+  public static final String ID_CONTEXT_MENU_PROJECT = "context-menu-project";
+  public static final String ID_CONTEXT_MENU_PROJECT_ADD = 
"context-menu-project-40010-add";
+  public static final String ID_CONTEXT_MENU_PROJECT_EDIT = 
"context-menu-project-40020-edit";
+  public static final String ID_CONTEXT_MENU_PROJECT_DELETE = 
"context-menu-project-40030-delete";
 
-  public static final String ID_TOOLBAR_ENVIRONMENT_LABEL = 
"toolbar-50000-environment-label";
-  public static final String ID_TOOLBAR_ENVIRONMENT_COMBO = 
"toolbar-50010-environment-list";
-  public static final String ID_TOOLBAR_ENVIRONMENT_EDIT = 
"toolbar-50020-environment-edit";
-  public static final String ID_TOOLBAR_ENVIRONMENT_ADD = 
"toolbar-50030-environment-add";
-  public static final String ID_TOOLBAR_ENVIRONMENT_DELETE = 
"toolbar-50040-environment-delete";
+  public static final String ID_TOOLBAR_ITEM_ENVIRONMENT = 
"toolbar-item-20000-environment";
+  public static final String ID_CONTEXT_MENU_ENVIRONMENT = 
"context-menu-environment";
+  public static final String ID_CONTEXT_MENU_ENVIRONMENT_ADD = 
"context-menu-environment-50010-add";
+  public static final String ID_CONTEXT_MENU_ENVIRONMENT_EDIT =
+      "context-menu-environment-50020-edit";
+  public static final String ID_CONTEXT_MENU_ENVIRONMENT_DUPLICATE =
+      "context-menu-environment-50030-duplicate";
+
+  public static final String ID_CONTEXT_MENU_ENVIRONMENT_DELETE =
+      "context-menu-environment-50040-delete";
 
   public static final String ID_MAIN_MENU_PROJECT_EXPORT = 
"10055-menu-file-export-to-svg";
 
@@ -119,7 +127,7 @@ public class ProjectsGuiPlugin {
 
   FileTree tree;
 
-  /** Automatically instantiated when the toolbar widgets etc need it */
+  /** Automatically instantiated when the toolbar widgets need it */
   public ProjectsGuiPlugin() {
     // Do nothing
   }
@@ -204,10 +212,10 @@ public class ProjectsGuiPlugin {
       //
       hopGui.getActivePerspective().getActiveFileTypeHandler().updateGui();
 
-      // Update the toolbar combos
+      // Update the toolbar items
       //
-      ProjectsGuiPlugin.selectProjectInList(projectName);
-      ProjectsGuiPlugin.selectEnvironmentInList(environment == null ? null : 
environment.getName());
+      updateProjectToolItem(projectName);
+      updateEnvironmentToolItem(environmentName);
 
       // Also add this as an event so we know what the project usage history is
       //
@@ -220,11 +228,6 @@ public class ProjectsGuiPlugin {
               new Date());
       AuditManager.getActive().storeEvent(prjUsedEvent);
 
-      // Now use that event to refresh the list...
-      //
-      refreshProjectsList();
-      ProjectsGuiPlugin.selectProjectInList(projectName);
-
       if (environment != null) {
         // Also add this as an event so we know what the project usage history 
is
         //
@@ -232,7 +235,7 @@ public class ProjectsGuiPlugin {
             new AuditEvent(
                 ProjectsUtil.STRING_PROJECTS_AUDIT_GROUP,
                 ProjectsUtil.STRING_ENVIRONMENT_AUDIT_TYPE,
-                environment.getName(),
+                environmentName,
                 "open",
                 new Date());
         AuditManager.getActive().storeEvent(envUsedEvent);
@@ -254,56 +257,33 @@ public class ProjectsGuiPlugin {
 
       // Reset VFS filesystem to load additional configurations
       HopVfs.reset();
-
     } catch (Exception e) {
       throw new HopException("Error enabling project '" + projectName + "' in 
HopGui", e);
     }
   }
 
-  private static Combo getProjectsCombo() {
-    Control control =
-        HopGui.getInstance()
-            .getMainToolbarWidgets()
-            .getWidgetsMap()
-            .get(ProjectsGuiPlugin.ID_TOOLBAR_PROJECT_COMBO);
-    if (control instanceof Combo combo) {
-      return combo;
-    }
-    return null;
-  }
-
-  private static Combo getEnvironmentsCombo() {
-    Control control =
-        HopGui.getInstance()
-            .getMainToolbarWidgets()
-            .getWidgetsMap()
-            .get(ProjectsGuiPlugin.ID_TOOLBAR_ENVIRONMENT_COMBO);
-    if (control instanceof Combo combo) {
-      return combo;
-    }
-    return null;
+  private static ToolItem getProjectToolItem() {
+    return 
HopGui.getInstance().getStatusToolbarWidgets().findToolItem(ID_TOOLBAR_ITEM_PROJECT);
   }
 
-  public static void refreshProjectsList() {
-    
HopGui.getInstance().getMainToolbarWidgets().refreshComboItemList(ID_TOOLBAR_PROJECT_COMBO);
+  private static ToolItem getEnvironmentToolItem() {
+    return 
HopGui.getInstance().getStatusToolbarWidgets().findToolItem(ID_TOOLBAR_ITEM_ENVIRONMENT);
   }
 
-  public static void selectProjectInList(String name) {
-    GuiToolbarWidgets toolbarWidgets = 
HopGui.getInstance().getMainToolbarWidgets();
-    ProjectsConfig config = ProjectsConfigSingleton.getConfig();
-
-    toolbarWidgets.selectComboItem(ID_TOOLBAR_PROJECT_COMBO, name);
-    Combo combo = getProjectsCombo();
-    if (combo != null) {
-      ProjectConfig projectConfig = config.findProjectConfig(name);
+  private static void updateProjectToolItem(String projectName) {
+    ToolItem item = getProjectToolItem();
+    if (item != null && !item.isDisposed()) {
+      ProjectsConfig config = ProjectsConfigSingleton.getConfig();
+      ProjectConfig projectConfig = config.findProjectConfig(projectName);
       if (projectConfig != null) {
         String projectHome = projectConfig.getProjectHome();
         if (StringUtils.isNotEmpty(projectHome)) {
-          combo.setToolTipText(
+          item.setText(projectName);
+          item.setToolTipText(
               BaseMessages.getString(
                   PKG,
-                  "ProjectGuiPlugin.SelectProject.Tooltip",
-                  name,
+                  "HopGui.Toolbar.Project.Tooltip",
+                  projectName,
                   projectHome,
                   projectConfig.getConfigFilename()));
         }
@@ -311,24 +291,25 @@ public class ProjectsGuiPlugin {
     }
   }
 
-  public static void refreshEnvironmentsList() {
-    
HopGui.getInstance().getMainToolbarWidgets().refreshComboItemList(ID_TOOLBAR_ENVIRONMENT_COMBO);
-  }
-
-  public static void selectEnvironmentInList(String name) {
-    GuiToolbarWidgets toolbarWidgets = 
HopGui.getInstance().getMainToolbarWidgets();
+  private static void updateEnvironmentToolItem(String environmentName) {
+    ToolItem item = getEnvironmentToolItem();
+    if (item != null && !item.isDisposed()) {
+      if (Utils.isEmpty(environmentName)) {
+        item.setText("");
+        item.setToolTipText(
+            BaseMessages.getString(PKG, 
"HopGui.Toolbar.Environment.Select.Tooltip"));
+        return;
+      }
 
-    toolbarWidgets.selectComboItem(ID_TOOLBAR_ENVIRONMENT_COMBO, name);
-    Combo combo = getEnvironmentsCombo();
-    if (combo != null) {
       ProjectsConfig config = ProjectsConfigSingleton.getConfig();
-      LifecycleEnvironment environment = config.findEnvironment(name);
+      LifecycleEnvironment environment = 
config.findEnvironment(environmentName);
       if (environment != null) {
-        combo.setToolTipText(
+        item.setText(environmentName);
+        item.setToolTipText(
             BaseMessages.getString(
                 PKG,
-                "ProjectGuiPlugin.FindEnvironment.Tooltip",
-                name,
+                "HopGui.Toolbar.Environment.Tooltip",
+                environmentName,
                 environment.getProjectName(),
                 environment.getPurpose()));
       }
@@ -361,23 +342,18 @@ public class ProjectsGuiPlugin {
     enableHopGuiProject(projectName, project, null);
   }
 
-  @GuiToolbarElement(
-      root = HopGui.ID_MAIN_TOOLBAR,
-      id = ID_TOOLBAR_PROJECT_LABEL,
-      type = GuiToolbarElementType.LABEL,
-      label = "i18n::HopGui.Toolbar.Project.Label",
-      toolTip = "i18n::HopGui.Toolbar.Project.Tooltip",
-      separator = true)
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_PROJECT,
+      parentId = ID_CONTEXT_MENU_PROJECT,
+      id = ID_CONTEXT_MENU_PROJECT_EDIT,
+      label = "i18n::HopGui.Toolbar.Project.Edit.Label",
+      toolTip = "i18n::HopGui.Toolbar.Project.Edit.Tooltip",
+      image = "ui/images/edit.svg")
   public void editProject() {
     HopGui hopGui = HopGui.getInstance();
-    Combo combo = getProjectsCombo();
-    if (combo == null) {
-      return;
-    }
-    ProjectsConfig config = ProjectsConfigSingleton.getConfig();
-
-    String projectName = combo.getText();
+    String projectName = getProjectToolItem().getText();
 
+    ProjectsConfig config = ProjectsConfigSingleton.getConfig();
     ProjectConfig projectConfig = config.findProjectConfig(projectName);
     if (projectConfig == null) {
       return;
@@ -407,17 +383,16 @@ public class ProjectsGuiPlugin {
         }
 
         project.saveToFile();
-        refreshProjectsList();
-        selectProjectInList(projectName);
+        updateProjectToolItem(projectName);
 
         if (projectDialog.isNeedingProjectRefresh()) {
           if (askAboutProjectRefresh(hopGui)) {
             // Try to stick to the same environment if we have one selected...
             //
             LifecycleEnvironment environment = null;
-            Combo environmentsCombo = getEnvironmentsCombo();
-            if (environmentsCombo != null) {
-              environment = 
config.findEnvironment(environmentsCombo.getText());
+            ToolItem environmentItem = getEnvironmentToolItem();
+            if (environmentItem != null) {
+              environment = config.findEnvironment(environmentItem.getText());
             }
             enableHopGuiProject(projectConfig.getProjectName(), project, 
environment);
           }
@@ -446,46 +421,160 @@ public class ProjectsGuiPlugin {
   }
 
   @GuiToolbarElement(
-      root = HopGui.ID_MAIN_TOOLBAR,
-      id = ID_TOOLBAR_PROJECT_COMBO,
-      type = GuiToolbarElementType.COMBO,
-      comboValuesMethod = "getProjectsList",
-      extraWidth = 200,
-      toolTip = "i18n::HopGui.Toolbar.ProjectsList.Tooltip",
-      readOnly = true)
-  public void selectProject() {
-    HopGui hopGui = HopGui.getInstance();
+      root = HopGui.ID_STATUS_TOOLBAR,
+      id = ID_TOOLBAR_ITEM_PROJECT,
+      type = GuiToolbarElementType.BUTTON,
+      image = "project.svg",
+      toolTip = "i18n::HopGui.Toolbar.Project.Tooltip")
+  public void showProjectContextMenu() {
+    ToolItem item = getProjectToolItem();
+    if (item != null) {
+      Rectangle rect = item.getBounds();
+      Point location = item.getParent().toDisplay(new Point(rect.x, rect.y + 
rect.height));
+      Menu menu = createProjectContextMenu();
+      menu.setLocation(location);
+      menu.setVisible(true);
+    }
+  }
+
+  private Menu createProjectContextMenu() {
+    Shell shell = HopGui.getInstance().getActiveShell();
+    Menu menu = new Menu(shell, SWT.POP_UP);
+
+    // Create context menu...
+    //
+    GuiMenuWidgets menuWidgets = new GuiMenuWidgets();
+    menuWidgets.registerGuiPluginObject(this);
+    menuWidgets.createMenuWidgets(ID_CONTEXT_MENU_PROJECT, shell, menu);
+
+    // Enable menus if a project is active.
+    //
+    boolean enabled = !"".equals(getProjectToolItem().getText());
+    menuWidgets.enableMenuItem(ID_CONTEXT_MENU_PROJECT_EDIT, enabled);
+    menuWidgets.enableMenuItem(ID_CONTEXT_MENU_PROJECT_DELETE, enabled);
+
+    new MenuItem(menu, SWT.SEPARATOR);
+
+    String currentProjectName = HopNamespace.getNamespace();
+    List<String> names = 
ProjectsConfigSingleton.getConfig().listProjectConfigNames();
+    int count = 0;
+    for (String name : names) {
+      MenuItem item = new MenuItem(menu, SWT.CHECK);
+      item.setText(name);
+      item.setSelection(currentProjectName.equals(name));
+      item.addListener(SWT.Selection, e -> selectProject(name));
+      //    if (++count == 10) break;
+    }
+    // TODO: display only the last 10 used projects
+    //    if (count == 5) {
+    //      new MenuItem(menu, SWT.SEPARATOR);
+    //      MenuItem item = new MenuItem(menu, SWT.PUSH);
+    //      item.setText("More...");
+    //      item.addListener(SWT.Selection, e -> selectProject());
+    //    }
+
+    return menu;
+  }
+
+  private Menu createEnvironmentContextMenu() {
+    Shell shell = HopGui.getInstance().getActiveShell();
+    Menu menu = new Menu(shell, SWT.POP_UP);
+
+    // Create context menu...
+    //
+    GuiMenuWidgets menuWidgets = new GuiMenuWidgets();
+    menuWidgets.registerGuiPluginObject(this);
+    menuWidgets.createMenuWidgets(ID_CONTEXT_MENU_ENVIRONMENT, shell, menu);
+
+    // Enable menus if an environment is active.
+    //
+    boolean enabled = !"".equals(getEnvironmentToolItem().getText());
+    menuWidgets.enableMenuItem(ID_CONTEXT_MENU_ENVIRONMENT_EDIT, enabled);
+    menuWidgets.enableMenuItem(ID_CONTEXT_MENU_ENVIRONMENT_DUPLICATE, enabled);
+    menuWidgets.enableMenuItem(ID_CONTEXT_MENU_ENVIRONMENT_DELETE, enabled);
+
+    new MenuItem(menu, SWT.SEPARATOR);
+
+    String currentProjectName = getProjectToolItem().getText();
+    String currentEnvironmentName = getEnvironmentToolItem().getText();
+
+    // List of first 10 projects
+    //
     ProjectsConfig config = ProjectsConfigSingleton.getConfig();
+    List<String> names = config.listEnvironmentNames();
+    int count = 0;
+    for (String name : names) {
+
+      // Exclude environment linked to another project
+      LifecycleEnvironment environment = config.findEnvironment(name);
+      if (Utils.isEmpty(environment.getProjectName())
+          || currentProjectName.equals(environment.getProjectName())) {
+        MenuItem item = new MenuItem(menu, SWT.CHECK);
+        item.setText(name);
+        item.setSelection(currentEnvironmentName.equals(name));
+        item.addListener(SWT.Selection, e -> selectEnvironment(name));
+        // if (++count == 10) break;
+      }
+    }
 
-    Combo projectsCombo = getProjectsCombo();
-    Combo environmentsCombo = getEnvironmentsCombo();
+    // TODO: display only the last 10 used environments
+    // If more projects, open a dialog to select it
+    //    if (count == 10) {
+    //      new MenuItem(menu, SWT.SEPARATOR);
+    //      MenuItem item = new MenuItem(menu, SWT.PUSH);
+    //      item.setText("More...");
+    //      item.addListener(SWT.Selection, e -> selectEnvironment());
+    //    }
 
-    if (projectsCombo == null) {
-      return;
+    return menu;
+  }
+
+  @GuiToolbarElement(
+      root = HopGui.ID_STATUS_TOOLBAR,
+      id = ID_TOOLBAR_ITEM_ENVIRONMENT,
+      type = GuiToolbarElementType.BUTTON,
+      image = "environment.svg",
+      toolTip = "i18n::HopGui.Toolbar.Environment.Tooltip")
+  public void showEnvironmentContextMenu() {
+    ToolItem item = getEnvironmentToolItem();
+    if (item != null) {
+      Rectangle rect = item.getBounds();
+      Point location = item.getParent().toDisplay(new Point(rect.x, rect.y + 
rect.height));
+      Menu menu = createEnvironmentContextMenu();
+      menu.setLocation(location);
+      menu.setVisible(true);
+    }
+  }
+
+  public void selectProject() {
+    List<String> projectNames = 
ProjectsConfigSingleton.getConfig().listProjectConfigNames();
+    EnterSelectionDialog dialog =
+        new EnterSelectionDialog(
+            HopGui.getInstance().getActiveShell(),
+            projectNames.toArray(new String[0]),
+            BaseMessages.getString(PKG, 
"ProjectGuiPlugin.Dialog.AvailableProjects.Title"),
+            BaseMessages.getString(PKG, 
"ProjectGuiPlugin.Dialog.AvailableProjects.Message"));
+    dialog.setCurrentValue(HopNamespace.getNamespace());
+
+    String name = dialog.open();
+    if (name != null) {
+      selectProject(name);
     }
-    String projectName = projectsCombo.getText();
+  }
 
+  public void selectProject(String projectName) {
+    HopGui hopGui = HopGui.getInstance();
+
+    ProjectsConfig config = ProjectsConfigSingleton.getConfig();
     if (config.isEnvironmentsForActiveProject() && 
StringUtils.isEmpty(projectName)) {
       // list all environments and select the first one if we don't have a 
project selected
       List<String> allEnvironments = config.listEnvironmentNames();
-      environmentsCombo.setItems(allEnvironments.toArray(new String[0]));
-      selectEnvironmentInList(allEnvironments.get(0));
+      updateEnvironmentToolItem(allEnvironments.get(0));
       return;
     }
 
     ProjectConfig projectConfig = config.findProjectConfig(projectName);
 
-    if (config.isEnvironmentsForActiveProject()) {
-      // get the environments for the selected project.
-      if (environmentsCombo != null) {
-        List<String> projectEnvironments = 
config.listEnvironmentNamesForProject(projectName);
-        environmentsCombo.setItems(projectEnvironments.toArray(new String[0]));
-      }
-    } else {
-      List<String> projectEnvironments = config.listEnvironmentNames();
-      environmentsCombo.setItems(projectEnvironments.toArray(new String[0]));
-    }
-
     // What is the last used environment?
     //
     LifecycleEnvironment environment = null;
@@ -525,7 +614,7 @@ public class ProjectsGuiPlugin {
       LogChannel.UI.logError("Error reading the last used environment from the 
audit logs", e);
     }
 
-    // If there is no recent usage select the first environment.
+    // If there is no recent usage, select the first environment.
     //
     if (environment == null) {
       List<LifecycleEnvironment> environments = 
config.findEnvironmentsOfProject(projectName);
@@ -551,20 +640,13 @@ public class ProjectsGuiPlugin {
     }
   }
 
-  @GuiToolbarElement(
-      root = HopGui.ID_MAIN_TOOLBAR,
-      id = ID_TOOLBAR_PROJECT_EDIT,
-      toolTip = "i18n::HopGui.Toolbar.Project.Edit.Tooltip",
-      image = "project-edit.svg")
-  public void editSelectedProject() {
-    editProject();
-  }
-
-  @GuiToolbarElement(
-      root = HopGui.ID_MAIN_TOOLBAR,
-      id = ID_TOOLBAR_PROJECT_ADD,
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_PROJECT,
+      parentId = ID_CONTEXT_MENU_PROJECT,
+      id = ID_CONTEXT_MENU_PROJECT_ADD,
+      label = "i18n::HopGui.Toolbar.Project.Add.Label",
       toolTip = "i18n::HopGui.Toolbar.Project.Add.Tooltip",
-      image = "project-add.svg")
+      image = "ui/images/add.svg")
   public void addNewProject() {
     HopGui hopGui = HopGui.getInstance();
     IVariables variables = hopGui.getVariables();
@@ -604,8 +686,7 @@ public class ProjectsGuiPlugin {
           project.readFromFile();
         }
 
-        refreshProjectsList();
-        selectProjectInList(projectName);
+        updateProjectToolItem(projectName);
 
         enableHopGuiProject(projectName, project, null);
 
@@ -692,17 +773,15 @@ public class ProjectsGuiPlugin {
     }
   }
 
-  @GuiToolbarElement(
-      root = HopGui.ID_MAIN_TOOLBAR,
-      id = ID_TOOLBAR_PROJECT_DELETE,
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_PROJECT,
+      parentId = ID_CONTEXT_MENU_PROJECT,
+      id = ID_CONTEXT_MENU_PROJECT_DELETE,
+      label = "i18n::HopGui.Toolbar.Project.Delete.Label",
       toolTip = "i18n::HopGui.Toolbar.Project.Delete.Tooltip",
-      image = "project-delete.svg")
-  public void deleteSelectedProject() {
-    Combo combo = getProjectsCombo();
-    if (combo == null) {
-      return;
-    }
-    String projectName = combo.getText();
+      image = "ui/images/delete.svg")
+  public void deleteProject() {
+    String projectName = getProjectToolItem().getText();
     if (StringUtils.isEmpty(projectName)) {
       return;
     }
@@ -768,11 +847,10 @@ public class ProjectsGuiPlugin {
         config.removeProjectConfig(projectName);
         ProjectsConfigSingleton.saveConfig();
 
-        refreshProjectsList();
         if (StringUtils.isEmpty(config.getDefaultProject())) {
-          selectProjectInList(null);
+          updateProjectToolItem(null);
         } else {
-          selectProjectInList(config.getDefaultProject());
+          updateProjectToolItem(config.getDefaultProject());
         }
       } catch (Exception e) {
         new ErrorDialog(
@@ -785,30 +863,24 @@ public class ProjectsGuiPlugin {
     }
   }
 
-  @GuiToolbarElement(
-      root = HopGui.ID_MAIN_TOOLBAR,
-      id = ID_TOOLBAR_ENVIRONMENT_LABEL,
-      type = GuiToolbarElementType.LABEL,
-      label = "i18n::HopGui.Toolbar.Environment.Label",
-      toolTip = "i18n::HopGui.Toolbar.Environment.Tooltip",
-      separator = true)
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_ENVIRONMENT,
+      parentId = ID_CONTEXT_MENU_ENVIRONMENT,
+      id = ID_CONTEXT_MENU_ENVIRONMENT_EDIT,
+      label = "i18n::HopGui.Toolbar.Environment.Edit.Label",
+      toolTip = "i18n::HopGui.Toolbar.Environment.Edit.Tooltip",
+      image = "ui/images/edit.svg")
   public void editEnvironment() {
-    HopGui hopGui = HopGui.getInstance();
-    Combo combo = getEnvironmentsCombo();
-    if (combo == null) {
-      return;
-    }
     ProjectsConfig config = ProjectsConfigSingleton.getConfig();
-
-    String environmentName = combo.getText();
-    if (StringUtils.isEmpty(environmentName)) {
-      return;
-    }
-    LifecycleEnvironment environment = config.findEnvironment(environmentName);
-    if (environment == null) {
-      return;
+    LifecycleEnvironment environment = 
config.findEnvironment(getEnvironmentToolItem().getText());
+    if (environment != null) {
+      this.editEnvironment(environment);
     }
+  }
 
+  public void editEnvironment(LifecycleEnvironment environment) {
+    HopGui hopGui = HopGui.getInstance();
+    ProjectsConfig config = ProjectsConfigSingleton.getConfig();
     try {
       LifecycleEnvironmentDialog dialog =
           new LifecycleEnvironmentDialog(
@@ -817,9 +889,7 @@ public class ProjectsGuiPlugin {
         config.addEnvironment(environment);
         ProjectsConfigSingleton.saveConfig();
 
-        refreshEnvironmentsList();
-
-        selectEnvironmentInList(environmentName);
+        updateEnvironmentToolItem(environment.getName());
       }
 
       // A refresh of the project and environment is likely needed
@@ -828,34 +898,19 @@ public class ProjectsGuiPlugin {
       if (dialog.isNeedingEnvironmentRefresh() && 
askAboutProjectRefresh(hopGui)) {
         // Refresh the loaded environment
         //
-        selectEnvironment();
+        selectEnvironment(environment.getName());
       }
     } catch (Exception e) {
       new ErrorDialog(
           hopGui.getActiveShell(),
           BaseMessages.getString(PKG, 
"ProjectGuiPlugin.EditEnvironment.Error.Dialog.Header"),
           BaseMessages.getString(
-              PKG, "ProjectGuiPlugin.EditEnvironment.Error.Dialog.Message", 
environmentName),
+              PKG, "ProjectGuiPlugin.EditEnvironment.Error.Dialog.Message", 
environment.getName()),
           e);
     }
   }
 
-  @GuiToolbarElement(
-      root = HopGui.ID_MAIN_TOOLBAR,
-      id = ID_TOOLBAR_ENVIRONMENT_COMBO,
-      type = GuiToolbarElementType.COMBO,
-      comboValuesMethod = "getEnvironmentsList",
-      extraWidth = 200,
-      toolTip = "i18n::HopGui.Toolbar.EnvironmentsList.Tooltip",
-      readOnly = true)
-  public void selectEnvironment() {
-    HopGui hopGui = HopGui.getInstance();
-    Combo envCombo = getEnvironmentsCombo();
-    if (envCombo == null) {
-      return;
-    }
-
-    String environmentName = envCombo.getText();
+  public void selectEnvironment(String environmentName) {
     if (StringUtils.isEmpty(environmentName)) {
       return;
     }
@@ -864,22 +919,23 @@ public class ProjectsGuiPlugin {
     if (environment == null) {
       return;
     }
-    if (StringUtils.isEmpty(environment.getProjectName())) {
-      return;
+    String projectName = environment.getProjectName();
+    if (StringUtils.isEmpty(projectName)) {
+      projectName = getProjectToolItem().getText();
     }
-    ProjectConfig projectConfig = 
config.findProjectConfig(environment.getProjectName());
+    ProjectConfig projectConfig = config.findProjectConfig(projectName);
     if (projectConfig == null) {
       return;
     }
 
     try {
-      Project project = projectConfig.loadProject(hopGui.getVariables());
+      Project project = 
projectConfig.loadProject(HopGui.getInstance().getVariables());
       if (project != null) {
         enableHopGuiProject(projectConfig.getProjectName(), project, 
environment);
       }
     } catch (Exception e) {
       new ErrorDialog(
-          hopGui.getActiveShell(),
+          HopGui.getInstance().getActiveShell(),
           BaseMessages.getString(PKG, 
"ProjectGuiPlugin.ChangeEnvironment.Error.Dialog.Header"),
           BaseMessages.getString(
               PKG, "ProjectGuiPlugin.ChangeEnvironment.Error.Dialog.Message", 
environmentName),
@@ -887,25 +943,18 @@ public class ProjectsGuiPlugin {
     }
   }
 
-  @GuiToolbarElement(
-      root = HopGui.ID_MAIN_TOOLBAR,
-      id = ID_TOOLBAR_ENVIRONMENT_EDIT,
-      toolTip = "i18n::HopGui.Toolbar.Environment.Edit.Tooltip",
-      image = "environment-edit.svg")
-  public void editSelectedEnvironment() {
-    editEnvironment();
-  }
-
-  @GuiToolbarElement(
-      root = HopGui.ID_MAIN_TOOLBAR,
-      id = ID_TOOLBAR_ENVIRONMENT_ADD,
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_ENVIRONMENT,
+      parentId = ID_CONTEXT_MENU_ENVIRONMENT,
+      id = ID_CONTEXT_MENU_ENVIRONMENT_ADD,
+      label = "i18n::HopGui.Toolbar.Environment.Add.Label",
       toolTip = "i18n::HopGui.Toolbar.Environment.Add.Tooltip",
-      image = "environment-add.svg")
+      image = "ui/images/add.svg")
   public void addNewEnvironment() {
     HopGui hopGui = HopGui.getInstance();
     try {
       ProjectsConfig config = ProjectsConfigSingleton.getConfig();
-      String projectName = getProjectsCombo().getText(); // The default is the 
active project
+      String projectName = getProjectToolItem().getText(); // The default is 
the active project
 
       LifecycleEnvironment environment =
           new LifecycleEnvironment(null, "", projectName, new ArrayList<>());
@@ -917,8 +966,7 @@ public class ProjectsGuiPlugin {
         config.addEnvironment(environment);
         ProjectsConfigSingleton.saveConfig();
 
-        refreshEnvironmentsList();
-        selectEnvironmentInList(environmentName);
+        updateEnvironmentToolItem(environmentName);
 
         ProjectConfig projectConfig = config.findProjectConfig(projectName);
         if (projectConfig != null) {
@@ -935,18 +983,35 @@ public class ProjectsGuiPlugin {
     }
   }
 
-  @GuiToolbarElement(
-      root = HopGui.ID_MAIN_TOOLBAR,
-      id = ID_TOOLBAR_ENVIRONMENT_DELETE,
-      toolTip = "i18n::HopGui.Toolbar.Environment.Delete.Tooltip",
-      image = "environment-delete.svg")
-  public void deleteSelectedEnvironment() {
-    HopGui hopGui = HopGui.getInstance();
-    Combo combo = getEnvironmentsCombo();
-    if (combo == null) {
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_ENVIRONMENT,
+      parentId = ID_CONTEXT_MENU_ENVIRONMENT,
+      id = ID_CONTEXT_MENU_ENVIRONMENT_DUPLICATE,
+      label = "i18n::HopGui.Toolbar.Environment.Duplicate.Label",
+      toolTip = "i18n::HopGui.Toolbar.Environment.Duplicate.Tooltip",
+      image = "ui/images/duplicate.svg")
+  public void duplicateEnvironment() {
+    ProjectsConfig config = ProjectsConfigSingleton.getConfig();
+    LifecycleEnvironment environment = 
config.findEnvironment(getEnvironmentToolItem().getText());
+    if (environment == null) {
       return;
     }
-    String environmentName = combo.getText();
+
+    LifecycleEnvironment newEnvironment = new 
LifecycleEnvironment(environment);
+    newEnvironment.setName(null);
+    this.editEnvironment(newEnvironment);
+  }
+
+  @GuiMenuElement(
+      root = ID_CONTEXT_MENU_ENVIRONMENT,
+      parentId = ID_CONTEXT_MENU_ENVIRONMENT,
+      id = ID_CONTEXT_MENU_ENVIRONMENT_DELETE,
+      label = "i18n::HopGui.Toolbar.Environment.Delete.Label",
+      toolTip = "i18n::HopGui.Toolbar.Environment.Delete.Tooltip",
+      image = "ui/images/delete.svg")
+  public void deleteEnvironment() {
+    HopGui hopGui = HopGui.getInstance();
+    String environmentName = getEnvironmentToolItem().getText();
     if (StringUtils.isEmpty(environmentName)) {
       return;
     }
@@ -958,8 +1023,7 @@ public class ProjectsGuiPlugin {
       return;
     }
 
-    MessageBox box =
-        new MessageBox(HopGui.getInstance().getShell(), SWT.YES | SWT.NO | 
SWT.ICON_QUESTION);
+    MessageBox box = new MessageBox(hopGui.getShell(), SWT.YES | SWT.NO | 
SWT.ICON_QUESTION);
     box.setText(BaseMessages.getString(PKG, 
"ProjectGuiPlugin.DeleteEnvironment.Dialog.Header"));
     box.setMessage(
         BaseMessages.getString(
@@ -972,20 +1036,20 @@ public class ProjectsGuiPlugin {
     int answer = box.open();
     if ((answer & SWT.YES) != 0) {
       try {
-        String projectName = getProjectsCombo().getText(); // The default is 
the active project
+        String projectName = getProjectToolItem().getText(); // The default is 
the active project
         ProjectConfig projectConfig = config.findProjectConfig(projectName);
         Project project = projectConfig.loadProject(hopGui.getVariables());
 
         config.removeEnvironment(environmentName);
         ProjectsConfigSingleton.saveConfig();
 
-        refreshEnvironmentsList();
-        selectEnvironmentInList(null);
-        enableHopGuiProject(
-            projectName, project, null); // Reload the project to clear 
current variables
+        updateEnvironmentToolItem(null);
+
+        // Reload the project to clear current variables
+        enableHopGuiProject(projectName, project, null);
       } catch (Exception e) {
         new ErrorDialog(
-            HopGui.getInstance().getShell(),
+            hopGui.getShell(),
             BaseMessages.getString(PKG, 
"ProjectGuiPlugin.DeleteEnvironment.Error.Dialog.Header"),
             BaseMessages.getString(
                 PKG, 
"ProjectGuiPlugin.DeleteEnvironment.Error.Dialog.Message", environmentName),
@@ -995,7 +1059,7 @@ public class ProjectsGuiPlugin {
   }
 
   /**
-   * Called by the Combo in the toolbar
+   * Called by the menu in the toolbar
    *
    * @param log the current logchannel
    * @param metadataProvider
@@ -1006,10 +1070,8 @@ public class ProjectsGuiPlugin {
       throws Exception {
     List<String> names = 
ProjectsConfigSingleton.getConfig().listProjectConfigNames();
     Map<String, Date> lastUsedMap = new HashMap<>();
-    names.stream()
-        .forEach(
-            name ->
-                lastUsedMap.put(name, new GregorianCalendar(1900, 
Calendar.JANUARY, 1).getTime()));
+    names.forEach(
+        name -> lastUsedMap.put(name, new GregorianCalendar(1900, 
Calendar.JANUARY, 1).getTime()));
 
     // Get the list of events from the Audit Manager...
     //
@@ -1027,8 +1089,7 @@ public class ProjectsGuiPlugin {
 
     // Reverse sort by last used date of a project...
     //
-    Collections.sort(
-        names,
+    names.sort(
         (name1, name2) -> {
           int cmp = -lastUsedMap.get(name1).compareTo(lastUsedMap.get(name2));
           if (cmp == 0) {
@@ -1041,7 +1102,7 @@ public class ProjectsGuiPlugin {
   }
 
   /**
-   * Called by the environments Combo in the toolbar
+   * Called by the environment menu in the toolbar
    *
    * @param log
    * @param metadataProvider
@@ -1050,7 +1111,7 @@ public class ProjectsGuiPlugin {
     return ProjectsConfigSingleton.getConfig().listEnvironmentNames();
   }
 
-  // Add an e button to the file dialog browser toolbar
+  // Add a "Navigate to project home" button to the file dialog browser toolbar
   //
   @GuiToolbarElement(
       root = NAVIGATE_TOOLBAR_PARENT_ID,
@@ -1099,12 +1160,11 @@ public class ProjectsGuiPlugin {
     if (zipFilename == null) {
       return;
     }
-
-    Combo combo = getProjectsCombo();
-    if (combo == null) {
+    ToolItem projectItem = getProjectToolItem();
+    if (projectItem == null) {
       return;
     }
-    String projectName = combo.getText();
+    String projectName = projectItem.getText();
     if (StringUtils.isEmpty(projectName)) {
       return;
     }
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/project/ProjectDialog.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/project/ProjectDialog.java
index fe1ac837be..959062f3ac 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/project/ProjectDialog.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/project/ProjectDialog.java
@@ -20,6 +20,8 @@ package org.apache.hop.projects.project;
 import java.io.File;
 import java.util.Collections;
 import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.vfs2.FileObject;
 import org.apache.hop.core.Const;
@@ -34,6 +36,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.projects.config.ProjectsConfig;
 import org.apache.hop.projects.config.ProjectsConfigSingleton;
 import org.apache.hop.projects.util.ProjectsUtil;
+import org.apache.hop.ui.core.ConstUi;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
@@ -89,16 +92,17 @@ public class ProjectDialog extends Dialog {
   private TableView wVariables;
 
   private final IVariables variables;
-  private boolean needingProjectRefresh;
 
-  private final Boolean editMode;
+  @Getter @Setter private boolean needingProjectRefresh;
+
+  private final boolean editMode;
 
   public ProjectDialog(
       Shell parent,
       Project project,
       ProjectConfig projectConfig,
       IVariables variables,
-      Boolean editMode) {
+      boolean editMode) {
     super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE);
 
     this.project = project;
@@ -125,7 +129,14 @@ public class ProjectDialog extends Dialog {
     Shell parent = getParent();
 
     shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | 
SWT.RESIZE);
-    shell.setImage(GuiResource.getInstance().getImageHopUi());
+    shell.setImage(
+        GuiResource.getInstance()
+            .getImage(
+                "project.svg",
+                PKG.getClassLoader(),
+                ConstUi.SMALL_ICON_SIZE,
+                ConstUi.SMALL_ICON_SIZE));
+
     PropsUi.setLook(shell);
 
     int margin = PropsUi.getMargin() + 2;
@@ -135,7 +146,7 @@ public class ProjectDialog extends Dialog {
     formLayout.marginWidth = PropsUi.getFormMargin();
     formLayout.marginHeight = PropsUi.getFormMargin();
 
-    shell.setLayout(new FormLayout());
+    shell.setLayout(formLayout);
     shell.setText(BaseMessages.getString(PKG, "ProjectDialog.Shell.Name"));
 
     // Buttons go at the bottom of the dialog
@@ -438,6 +449,7 @@ public class ProjectDialog extends Dialog {
     scroll.setMinSize(comp.computeSize(SWT.DEFAULT, SWT.DEFAULT));
     shell.setMinimumSize(comp.getBounds().width, 200);
     shell.setDefaultButton(wOk);
+    wName.setFocus();
     BaseDialog.defaultShellHandling(shell, c -> ok(), c -> cancel());
 
     return returnValue;
@@ -755,20 +767,4 @@ public class ProjectDialog extends Dialog {
     //
     project.verifyProjectsChain(projectConfig.getProjectName(), variables);
   }
-
-  /**
-   * Gets variablesChanged
-   *
-   * @return value of variablesChanged
-   */
-  public boolean isNeedingProjectRefresh() {
-    return needingProjectRefresh;
-  }
-
-  /**
-   * @param needingProjectRefresh The variablesChanged to set
-   */
-  public void setNeedingProjectRefresh(boolean needingProjectRefresh) {
-    this.needingProjectRefresh = needingProjectRefresh;
-  }
 }
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/util/ProjectsUtil.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/util/ProjectsUtil.java
index ebff7cef83..c1bd913919 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/util/ProjectsUtil.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/util/ProjectsUtil.java
@@ -18,7 +18,6 @@
 package org.apache.hop.projects.util;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import org.apache.commons.lang.StringUtils;
@@ -157,10 +156,8 @@ public class ProjectsUtil {
     }
 
     FileObject parent = file.getParent();
-    if (parent != null && isInSubDirectory(parent, directory)) {
-      return true;
-    }
-    return false;
+
+    return parent != null && isInSubDirectory(parent, directory);
   }
 
   public static void validateFileInProject(
@@ -228,7 +225,7 @@ public class ProjectsUtil {
     ProjectConfig currentProjectConfig = config.findProjectConfig(projectName);
 
     if (currentProjectConfig == null) {
-      parentProjectReferences = Collections.EMPTY_LIST;
+      parentProjectReferences = List.of();
     } else {
       for (String prj : prjs) {
         if (!prj.equals(projectName)) {
@@ -259,7 +256,7 @@ public class ProjectsUtil {
     ProjectConfig currentProjectConfig = config.findProjectConfig(currentName);
 
     if (currentProjectConfig == null) {
-      parentProjectReferences = Collections.EMPTY_LIST;
+      parentProjectReferences = List.of();
     } else {
       for (String prj : prjs) {
         if (!prj.equals(currentName)) {
diff --git a/plugins/misc/projects/src/main/resources/environment-add.svg 
b/plugins/misc/projects/src/main/resources/environment-add.svg
deleted file mode 100644
index 3892b0231a..0000000000
--- a/plugins/misc/projects/src/main/resources/environment-add.svg
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        enable-background="new 0 0 42 42"
-        viewBox="0 0 42 42"
-        height="42px"
-        width="42px"
-        y="0px"
-        x="0px"
-        version="1.1">
-    <text
-            
style="font-style:normal;font-weight:normal;font-size:192px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-            x="56.459057"
-            y="19.834593"
-    >
-        <tspan
-                x="56.459057"
-                y="194.53062"/>
-    </text>
-    <g
-            transform="matrix(0.48941052,0,0,0.48941052,24.528835,24.811866)">
-        <polygon
-                style="fill:#3d6380"
-                points="18.2,0 13.8,0 13.8,13.8 0,13.8 0,18.2 13.8,18.2 
13.8,32 18.2,32 18.2,18.2 32,18.2 32,13.8 18.2,13.8 "
-        />
-    </g>
-    <text
-            y="29.700094"
-            x="-1.4979153"
-            
style="font-style:normal;font-weight:normal;font-size:52.08139801px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.27125728"
-    >
-        <tspan
-                style="stroke-width:0.27125728"
-                y="29.700094"
-                x="-1.4979153"
-        >e
-        </tspan>
-    </text>
-</svg>
\ No newline at end of file
diff --git a/plugins/misc/projects/src/main/resources/environment-delete.svg 
b/plugins/misc/projects/src/main/resources/environment-delete.svg
deleted file mode 100644
index 29c1e6f0be..0000000000
--- a/plugins/misc/projects/src/main/resources/environment-delete.svg
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        enable-background="new 0 0 42 42"
-        viewBox="0 0 42 42"
-        height="42px"
-        width="42px"
-        y="0px"
-        x="0px"
-        version="1.1">
-    <text
-            
style="font-style:normal;font-weight:normal;font-size:192px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-            x="56.459057"
-            y="19.834593"
-    >
-        <tspan
-                x="56.459057"
-                y="194.53062"/>
-    </text>
-    <polygon
-            transform="matrix(1.6377839,0,0,1.6377839,-23.702184,-25.258686)"
-            style="fill:#ea102a"
-            points="37.6,31.4 34.7,34.3 31.8,31.4 30.4,32.7 33.3,35.6 
30.4,38.5 31.8,39.9 34.7,37 37.6,39.9 38.9,38.5 36,35.6 38.9,32.7 "/>
-    <text
-            y="29.151655"
-            x="-1.8970144"
-            
style="font-style:normal;font-weight:normal;font-size:52.08139801px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.27125728"
-    >
-        <tspan
-                style="stroke-width:0.27125728"
-                y="29.151655"
-                x="-1.8970144"
-        >e
-        </tspan>
-    </text>
-</svg>
\ No newline at end of file
diff --git a/plugins/misc/projects/src/main/resources/environment-edit.svg 
b/plugins/misc/projects/src/main/resources/environment-edit.svg
deleted file mode 100644
index e183b09cef..0000000000
--- a/plugins/misc/projects/src/main/resources/environment-edit.svg
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        enable-background="new 0 0 42 42"
-        viewBox="0 0 42 42"
-        height="42px"
-        width="42px"
-        y="0px"
-        x="0px"
-        version="1.1">
-    <text
-            
style="font-style:normal;font-weight:normal;font-size:192px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-            x="56.459057"
-            y="19.834593"
-    >
-        <tspan
-                x="56.459057"
-                y="194.53062"/>
-    </text>
-    <ellipse
-            
style="opacity:1;fill:#000000;fill-opacity:1;stroke-width:0.72368419;paint-order:markers
 fill stroke"
-            cx="25.54306"
-            cy="34.986797"
-            rx="2.0330944"
-            ry="2.0063434"/>
-    <ellipse
-            style="opacity:0.3;fill:#ffd700;fill-opacity:1;paint-order:markers 
fill stroke"
-            cx="29.202629"
-            cy="35.715889"
-            rx="1.3307527"
-            ry="0.22179212"/>
-    <ellipse
-            
style="opacity:1;fill:#000000;fill-opacity:1;stroke-width:0.72368419;paint-order:markers
 fill stroke"
-            cx="30.903036"
-            cy="34.976582"
-            rx="2.0330944"
-            ry="2.0063434"/>
-    <ellipse
-            
style="opacity:1;fill:#000000;fill-opacity:1;stroke-width:0.72368419;paint-order:markers
 fill stroke"
-            cx="36.004257"
-            cy="34.976585"
-            rx="2.0330944"
-            ry="2.0063434"/>
-    <text
-            y="29.321312"
-            x="-1.9212515"
-            
style="font-style:normal;font-weight:normal;font-size:52.08139801px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.27125728"
-    >
-        <tspan
-                style="stroke-width:0.27125728"
-                y="29.321312"
-                x="-1.9212515"
-        >e
-        </tspan>
-    </text>
-</svg>
\ No newline at end of file
diff --git a/plugins/misc/projects/src/main/resources/environment.svg 
b/plugins/misc/projects/src/main/resources/environment.svg
index 85aebdbcde..01769f4e1a 100644
--- a/plugins/misc/projects/src/main/resources/environment.svg
+++ b/plugins/misc/projects/src/main/resources/environment.svg
@@ -1,41 +1,10 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        enable-background="new 0 0 42 42"
-        viewBox="0 0 42 42"
-        height="42px"
-        width="42px"
-        y="0px"
-        x="0px"
-        version="1.1">
-    <text
-            
style="font-style:normal;font-weight:normal;font-size:192px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-            x="56.459057"
-            y="19.834593"
-    >
-        <tspan
-                x="56.459057"
-                y="194.53062"/>
-    </text>
-    <text
-            
style="font-style:normal;font-weight:normal;font-size:192px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-            x="1.9880279"
-            y="9.3003683"
-    >
-        <tspan
-                x="1.9880279"
-                y="183.9964"/>
-    </text>
-    <text
-            y="35.017017"
-            x="6.2466292"
-            
style="font-style:normal;font-weight:normal;font-size:52.08139801px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.27125728"
-    >
-        <tspan
-                style="stroke-width:0.27125728"
-                y="35.017017"
-                x="6.2466292"
-        >e
-        </tspan>
-    </text>
-</svg>
\ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg";  width="1024px" height="1024px" 
viewBox="0 0 1024 1024">
+    <path fill="#0E3A5A" 
d="M870.4,373.459l-284.16,154.24C560,541.779,544,569.938,544,601.299v298.24c0,32,31.359,53.12,57.6,38.399
+       
l284.16-154.239c25.6-14.08,42.24-42.24,42.24-73.601v-297.6C928,379.859,896.64,359.379,870.4,373.459z
 M437.76,527.059
+       
l-284.16-153.6c-26.24-14.08-57.6,6.4-57.6,38.4v299.52c0,31.36,16,59.52,42.24,73.6L422.4,938.579
+       
c26.24,14.08,57.601-7.04,57.601-39.04v-298.88C480,569.299,464,541.139,437.76,527.059z
 M844.159,303.699
+       
c13.44-7.04,19.841-19.2,18.561-30.72c1.28-12.16-5.12-23.68-18.561-30.72L554.88,91.219c-12.801-7.04-28.16-10.24-43.521-10.24
+       
c-15.359,0-30.72,3.2-43.52,10.24l-289.28,150.4c-13.439,7.04-19.2,19.2-18.56,30.72c-0.641,12.16,5.12,24.32,18.56,31.36
+       
l289.28,150.4c12.8,7.04,28.16,10.24,43.52,10.24c15.36,0,30.72-3.2,43.521-10.24L844.159,303.699z"/>
+</svg>
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_de_DE.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_de_DE.properties
index 03d2808d98..5a6edda210 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_de_DE.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_de_DE.properties
@@ -17,18 +17,18 @@
 #
 #
 
-LifecycleEnvironmentDialog.Button.Edit=Bearbeiten... 
-LifecycleEnvironmentDialog.Button.New=Neu... 
-LifecycleEnvironmentDialog.Button.Select=Ausw\u00E4hlen... 
+LifecycleEnvironmentDialog.Button.Edit=Bearbeiten...
+LifecycleEnvironmentDialog.Button.New=Neu...
+LifecycleEnvironmentDialog.Button.Select=Ausw\u00E4hlen...
 LifecycleEnvironmentDialog.DetailTable.Label.Filename=Dateiname
-LifecycleEnvironmentDialog.Group.Label.ConfigurationFiles=Konfigurationsdateien:
 
-LifecycleEnvironmentDialog.Label.EnvironmentName=Name 
-LifecycleEnvironmentDialog.Label.EnvironmentPurpose=Zweck 
-LifecycleEnvironmentDialog.Label.ReferencedProject=Projekt 
+LifecycleEnvironmentDialog.Group.Label.ConfigurationFiles=Konfigurationsdateien:
+LifecycleEnvironmentDialog.Label.EnvironmentName=Name
+LifecycleEnvironmentDialog.Label.EnvironmentPurpose=Zweck
+LifecycleEnvironmentDialog.Label.ReferencedProject=Projekt
 LifecycleEnvironmentDialog.Purpose.Text.Acceptance=Abnahme
 LifecycleEnvironmentDialog.Purpose.Text.CB=Allgemeiner Build
 LifecycleEnvironmentDialog.Purpose.Text.CI=Continuous Integration
 LifecycleEnvironmentDialog.Purpose.Text.Development=Entwicklung
 LifecycleEnvironmentDialog.Purpose.Text.Production=Produktion
 LifecycleEnvironmentDialog.Purpose.Text.Testing=Testen
-LifecycleEnvironmentDialog.Shell.Name=Umgebungseigenschaften 
+LifecycleEnvironmentDialog.Shell.Name=Umgebungseigenschaften
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_en_US.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_en_US.properties
index 541b69c420..4bd8428114 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_en_US.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_en_US.properties
@@ -16,18 +16,18 @@
 #
 #
 
-LifecycleEnvironmentDialog.Button.Edit=Edit... 
-LifecycleEnvironmentDialog.Button.New=New... 
-LifecycleEnvironmentDialog.Button.Select=Select... 
+LifecycleEnvironmentDialog.Button.Edit=Edit...
+LifecycleEnvironmentDialog.Button.New=New...
+LifecycleEnvironmentDialog.Button.Select=Select...
 LifecycleEnvironmentDialog.DetailTable.Label.Filename=Filename
-LifecycleEnvironmentDialog.Group.Label.ConfigurationFiles=Configuration files: 
-LifecycleEnvironmentDialog.Label.EnvironmentName=Name 
-LifecycleEnvironmentDialog.Label.EnvironmentPurpose=Purpose 
-LifecycleEnvironmentDialog.Label.ReferencedProject=Project 
+LifecycleEnvironmentDialog.Group.Label.ConfigurationFiles=Configuration files:
+LifecycleEnvironmentDialog.Label.EnvironmentName=Name
+LifecycleEnvironmentDialog.Label.EnvironmentPurpose=Purpose
+LifecycleEnvironmentDialog.Label.ReferencedProject=Project
 LifecycleEnvironmentDialog.Purpose.Text.Acceptance=Acceptance
 LifecycleEnvironmentDialog.Purpose.Text.CB=Common Build
 LifecycleEnvironmentDialog.Purpose.Text.CI=Continuous Integration
 LifecycleEnvironmentDialog.Purpose.Text.Development=Development
 LifecycleEnvironmentDialog.Purpose.Text.Production=Production
 LifecycleEnvironmentDialog.Purpose.Text.Testing=Testing
-LifecycleEnvironmentDialog.Shell.Name=Environment Properties 
+LifecycleEnvironmentDialog.Shell.Name=Environment Properties
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_fr_FR.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_fr_FR.properties
index cf4ad276ea..d2b84249ed 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_fr_FR.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_fr_FR.properties
@@ -17,15 +17,15 @@
 #
 #
 
-LifecycleEnvironmentDialog.Button.Edit=Editer... 
-LifecycleEnvironmentDialog.Button.New=Nouveau... 
-LifecycleEnvironmentDialog.Button.Select=S\u00E9lectionner... 
+LifecycleEnvironmentDialog.Button.Edit=Editer...
+LifecycleEnvironmentDialog.Button.New=Nouveau...
+LifecycleEnvironmentDialog.Button.Select=S\u00E9lectionner...
 LifecycleEnvironmentDialog.DetailTable.Label.Filename=Nom du fichier
-LifecycleEnvironmentDialog.Group.Label.ConfigurationFiles=Fichiers de 
configuration : 
-LifecycleEnvironmentDialog.Label.EnvironmentName=Nom 
-LifecycleEnvironmentDialog.Label.ReferencedProject=Projet 
+LifecycleEnvironmentDialog.Group.Label.ConfigurationFiles=Fichiers de 
configuration :
+LifecycleEnvironmentDialog.Label.EnvironmentName=Nom
+LifecycleEnvironmentDialog.Label.ReferencedProject=Projet
 LifecycleEnvironmentDialog.Purpose.Text.Acceptance=Acceptation
 LifecycleEnvironmentDialog.Purpose.Text.Development=D\u00E9veloppement
 LifecycleEnvironmentDialog.Purpose.Text.Production=Production
 LifecycleEnvironmentDialog.Purpose.Text.Testing=Test
-LifecycleEnvironmentDialog.Shell.Name=Propri\u00E9t\u00E9s de l''environnement 
+LifecycleEnvironmentDialog.Shell.Name=Propri\u00E9t\u00E9s de l''environnement
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_it_IT.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_it_IT.properties
index e3b3c274df..839e76e373 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_it_IT.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_it_IT.properties
@@ -16,14 +16,14 @@
 #
 #
 
-LifecycleEnvironmentDialog.Button.Edit=Modifica... 
-LifecycleEnvironmentDialog.Button.New=Nuovo... 
-LifecycleEnvironmentDialog.Button.Select=Seleziona... 
+LifecycleEnvironmentDialog.Button.Edit=Modifica...
+LifecycleEnvironmentDialog.Button.New=Nuovo...
+LifecycleEnvironmentDialog.Button.Select=Seleziona...
 LifecycleEnvironmentDialog.DetailTable.Label.Filename=Nome file
-LifecycleEnvironmentDialog.Group.Label.ConfigurationFiles=Files di 
configurazione: 
-LifecycleEnvironmentDialog.Label.EnvironmentName=Nome 
-LifecycleEnvironmentDialog.Label.EnvironmentPurpose=Scopo 
-LifecycleEnvironmentDialog.Label.ReferencedProject=Progetto 
+LifecycleEnvironmentDialog.Group.Label.ConfigurationFiles=Files di 
configurazione:
+LifecycleEnvironmentDialog.Label.EnvironmentName=Nome
+LifecycleEnvironmentDialog.Label.EnvironmentPurpose=Scopo
+LifecycleEnvironmentDialog.Label.ReferencedProject=Progetto
 LifecycleEnvironmentDialog.Purpose.Text.Acceptance=Accettazione
 LifecycleEnvironmentDialog.Purpose.Text.CB=Common Build
 LifecycleEnvironmentDialog.Purpose.Text.CI=Continuous Integration
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_pt_BR.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_pt_BR.properties
index f822209682..bbea92eb92 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_pt_BR.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_pt_BR.properties
@@ -17,18 +17,18 @@
 #
 #
 
-LifecycleEnvironmentDialog.Button.Edit=Editar... 
-LifecycleEnvironmentDialog.Button.New=Novo... 
-LifecycleEnvironmentDialog.Button.Select=selecionar... 
+LifecycleEnvironmentDialog.Button.Edit=Editar...
+LifecycleEnvironmentDialog.Button.New=Novo...
+LifecycleEnvironmentDialog.Button.Select=selecionar...
 LifecycleEnvironmentDialog.DetailTable.Label.Filename=Nome do arquivo
-LifecycleEnvironmentDialog.Group.Label.ConfigurationFiles=Arquivos de 
configura\u00E7\u00E3o: 
-LifecycleEnvironmentDialog.Label.EnvironmentName=Nome 
-LifecycleEnvironmentDialog.Label.EnvironmentPurpose=prop\u00F3sito 
-LifecycleEnvironmentDialog.Label.ReferencedProject=Projeto 
+LifecycleEnvironmentDialog.Group.Label.ConfigurationFiles=Arquivos de 
configura\u00E7\u00E3o:
+LifecycleEnvironmentDialog.Label.EnvironmentName=Nome
+LifecycleEnvironmentDialog.Label.EnvironmentPurpose=prop\u00F3sito
+LifecycleEnvironmentDialog.Label.ReferencedProject=Projeto
 LifecycleEnvironmentDialog.Purpose.Text.Acceptance=aceita\u00E7\u00E3o
 LifecycleEnvironmentDialog.Purpose.Text.CB=Compila\u00E7\u00E3o Comum
 LifecycleEnvironmentDialog.Purpose.Text.CI=Integra\u00E7\u00E3o cont\u00EDnua
 LifecycleEnvironmentDialog.Purpose.Text.Development=Desenvolvimento
 LifecycleEnvironmentDialog.Purpose.Text.Production=Produ\u00E7\u00E3o
 LifecycleEnvironmentDialog.Purpose.Text.Testing=Testando
-LifecycleEnvironmentDialog.Shell.Name=Propriedades do ambiente 
+LifecycleEnvironmentDialog.Shell.Name=Propriedades do ambiente
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_de_DE.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_de_DE.properties
index 9bc6db443a..5f57870716 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_de_DE.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_de_DE.properties
@@ -19,18 +19,15 @@
 
 FileDialog.Browse.Project.Home=Zum Projekt Home Verzeichnis wechseln
 HopGui.FileMenu.Project.Export.Label=Aktuelles Projekt in ZIP Datei exportieren
-HopGui.Toolbar.Environment.Add.Tooltip=Neue Umgebung hinzuf\u00FCgen
-HopGui.Toolbar.Environment.Delete.Tooltip=Ausgew\u00E4hlte Umgebung 
l\u00F6schen
-HopGui.Toolbar.Environment.Edit.Tooltip=Ausgew\u00E4hlte Umgebung bearbeiten
-HopGui.Toolbar.Environment.Label=Umgebung:
-HopGui.Toolbar.Environment.Tooltip=Hier klicken, um aktive Umgebung zu 
bearbeiten
-HopGui.Toolbar.EnvironmentsList.Tooltip=Aktive Umgebung ausw\u00E4hlen
-HopGui.Toolbar.Project.Add.Tooltip=Neues Projekt hinzuf\u00FCgen
-HopGui.Toolbar.Project.Delete.Tooltip=Ausgew\u00E4hltes Projekt l\u00F6schen
-HopGui.Toolbar.Project.Edit.Tooltip=Ausgew\u00E4hltes Projekt bearbeiten
-HopGui.Toolbar.Project.Label=Projekt:
-HopGui.Toolbar.Project.Tooltip=Hier klicken, um aktives Projekt zu bearbeiten
-HopGui.Toolbar.ProjectsList.Tooltip=Aktives Projekt ausw\u00E4hlen
+HopGui.Toolbar.Environment.Select.Tooltip=Aktive Umgebung ausw\u00E4hlen
+HopGui.Toolbar.Environment.Tooltip=Umgebung {0} f\u00FCr Projekt "{1}" hat 
Grund: {2}
+HopGui.Toolbar.Environment.Add.Label=Neue Umgebung hinzuf\u00FCgen
+HopGui.Toolbar.Environment.Delete.Label=Ausgew\u00E4hlte Umgebung l\u00F6schen
+HopGui.Toolbar.Environment.Edit.Label=Ausgew\u00E4hlte Umgebung bearbeiten
+HopGui.Toolbar.Project.Tooltip=Projekt {0} in "{1}" konfiguriert in "{2}"
+HopGui.Toolbar.Project.Add.Label=Neues Projekt hinzuf\u00FCgen
+HopGui.Toolbar.Project.Delete.Label=Ausgew\u00E4hltes Projekt l\u00F6schen
+HopGui.Toolbar.Project.Edit.Label=Ausgew\u00E4hltes Projekt bearbeiten
 ProjectGuiPlugin.AddEnvironment.Error.Dialog.Header=Fehler
 ProjectGuiPlugin.AddEnvironment.Error.Dialog.Message=Fehler beim 
Hinzuf\u00FCgen einer Lifecycle Umgebung
 ProjectGuiPlugin.AddProject.Error.Dialog.Header=Fehler
@@ -56,7 +53,6 @@ ProjectGuiPlugin.EditEnvironment.Error.Dialog.Header=Fehler
 ProjectGuiPlugin.EditEnvironment.Error.Dialog.Message=Bearbeitungsfehler in 
Umgebung "{0}"
 ProjectGuiPlugin.EditProject.Error.Dialog.Header=Fehler
 ProjectGuiPlugin.EditProject.Error.Dialog.Message=Fehler bei 
Projektbearbeitung "{0}"
-ProjectGuiPlugin.FindEnvironment.Tooltip=Umgebung {0} f\u00FCr Projekt "{1}" 
hat Grund: {2}
 ProjectGuiPlugin.Lifecycle.Dialog.Header=Lifecycle Umgebung f\u00FCr Projekt 
anlegen?
 ProjectGuiPlugin.Lifecycle.Dialog.Message1=Soll eine Lifecycle Umgebung 
hinzugef\u00FCgt werden, wenn dieses Projekt Teil eines Lifecycles is ?
 ProjectGuiPlugin.Lifecycle.Dialog.Message2=Damit k\u00F6nnen spezifische 
Einstellungen wie Hostnamen und Pfade f\u00FCr die Umgebung gesetzt werden
@@ -70,7 +66,6 @@ ProjectGuiPlugin.ReloadProject.Dialog.Message=Um alle 
\u00C4nderungen zu ber\u00
 ProjectGuiPlugin.RenameProject.ProjectReferencedAsParent.Header=Projekt konnte 
nicht umbenannt werden!
 ProjectGuiPlugin.RenameProject.ProjectReferencedAsParent.Message1=Aktuelles 
Projekt kann nicht umbenannt werden, da es von diesen anderen Projekten 
referenziert wird :
 ProjectGuiPlugin.RenameProject.ProjectReferencedAsParent.Message2=Um 
umzubenennen muss zun\u00E4chst die Referenz auf das Hauptverzeichnis im 
Projekt entfernt werden.
-ProjectGuiPlugin.SelectProject.Tooltip=Projekt {0} in "{1}" konfiguriert in 
"{2}"
 ProjectGuiPlugin.ZipDirectory.Dialog.Header=Zip Datei aus Projektverzeichnis 
erstellt
 ProjectGuiPlugin.ZipDirectory.Dialog.Message1=Eine Zipdatei wurde erfolgreich 
erstellt: {0}
 ProjectGuiPlugin.ZipDirectory.Dialog.Message2=Der Dateiname wurde in die 
Zwischenablage kopiert.
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_en_US.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_en_US.properties
index a420a26b7c..87c39f9806 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_en_US.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_en_US.properties
@@ -19,18 +19,23 @@
 
 FileDialog.Browse.Project.Home=Navigate to the project home directory
 HopGui.FileMenu.Project.Export.Label=Export current project to zip
+HopGui.Toolbar.Environment.Select.Tooltip=Select the active environment
+HopGui.Toolbar.Environment.Tooltip=Environment {0} for project ''{1}'' has 
purpose: {2}
+HopGui.Toolbar.Environment.Add.Label=Add environment...
 HopGui.Toolbar.Environment.Add.Tooltip=Add a new environment
+HopGui.Toolbar.Environment.Duplicate.Label=Duplicate environment...
+HopGui.Toolbar.Environment.Duplicate.Tooltip=Duplicate the selected environment
+HopGui.Toolbar.Environment.Delete.Label=Delete environment...
 HopGui.Toolbar.Environment.Delete.Tooltip=Delete the selected environment
+HopGui.Toolbar.Environment.Edit.Label=Edit environment...
 HopGui.Toolbar.Environment.Edit.Tooltip=Edit the selected environment
-HopGui.Toolbar.Environment.Label=Environment:
-HopGui.Toolbar.Environment.Tooltip=Click here to edit the active environment
-HopGui.Toolbar.EnvironmentsList.Tooltip=Select the active environment
+HopGui.Toolbar.Project.Tooltip=Project {0} in ''{1}'' configured in ''{2}''
+HopGui.Toolbar.Project.Add.Label=Add project...
 HopGui.Toolbar.Project.Add.Tooltip=Add a new project
+HopGui.Toolbar.Project.Delete.Label=Delete project...
 HopGui.Toolbar.Project.Delete.Tooltip=Delete the selected project
+HopGui.Toolbar.Project.Edit.Label=Edit project...
 HopGui.Toolbar.Project.Edit.Tooltip=Edit the selected project
-HopGui.Toolbar.Project.Label=Project:
-HopGui.Toolbar.Project.Tooltip=Click here to edit the active project
-HopGui.Toolbar.ProjectsList.Tooltip=Select the active project
 ProjectGuiPlugin.AddEnvironment.Error.Dialog.Header=Error
 ProjectGuiPlugin.AddEnvironment.Error.Dialog.Message=Error adding lifecycle 
environment
 ProjectGuiPlugin.AddProject.Error.Dialog.Header=Error
@@ -56,7 +61,6 @@ ProjectGuiPlugin.EditEnvironment.Error.Dialog.Header=Error
 ProjectGuiPlugin.EditEnvironment.Error.Dialog.Message=Error editing 
environment ''{0}''
 ProjectGuiPlugin.EditProject.Error.Dialog.Header=Error
 ProjectGuiPlugin.EditProject.Error.Dialog.Message=Error editing project ''{0}''
-ProjectGuiPlugin.FindEnvironment.Tooltip=Environment {0} for project ''{1}'' 
has purpose: {2}
 ProjectGuiPlugin.Lifecycle.Dialog.Header=Create project lifecycle environment?
 ProjectGuiPlugin.Lifecycle.Dialog.Message1=If this project is part of a 
lifecyle then perhaps you want to add it to a lifecycle environment?
 ProjectGuiPlugin.Lifecycle.Dialog.Message2=With it you can manage the specific 
settings like hostnames and paths for the environment
@@ -70,7 +74,6 @@ ProjectGuiPlugin.ReloadProject.Dialog.Message=To apply all 
changes you made a re
 ProjectGuiPlugin.RenameProject.ProjectReferencedAsParent.Header=Can''t rename 
the project!
 ProjectGuiPlugin.RenameProject.ProjectReferencedAsParent.Message1=Current 
project cannot be renamed because is referenced as parent project in following 
projects:
 ProjectGuiPlugin.RenameProject.ProjectReferencedAsParent.Message2=To perform 
the rename, you MUST firstly remove the parent project reference in the listed 
projects and then retry.
-ProjectGuiPlugin.SelectProject.Tooltip=Project {0} in ''{1}'' configured in 
''{2}''
 ProjectGuiPlugin.ZipDirectory.Dialog.Header=Project zip file created
 ProjectGuiPlugin.ZipDirectory.Dialog.Message1=A zip file was successfully 
created: {0}
 ProjectGuiPlugin.ZipDirectory.Dialog.Message2=The filename was copied to the 
clipboard.
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_fr_FR.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_fr_FR.properties
index 0f1a24a734..0fe23b4c66 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_fr_FR.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_fr_FR.properties
@@ -19,18 +19,21 @@
 
 FileDialog.Browse.Project.Home=Naviguer vers le r\u00E9pertoire du projet
 HopGui.FileMenu.Project.Export.Label=Exporter le projet en zip
-HopGui.Toolbar.Environment.Add.Tooltip=Cr\u00E9er un environnement
+HopGui.Toolbar.Environment.Select.Tooltip=S\u00E9lectionner l''environnement 
actif
+HopGui.Toolbar.Environment.Tooltip=L''environnement {0} du projet ''{1}'' a 
pour objectif: {2}
+HopGui.Toolbar.Environment.Add.Label=Cr\u00E9er un environnement...
+HopGui.Toolbar.Environment.Add.Tooltip=Cr\u00E9er un nouvel environnement
+HopGui.Toolbar.Environment.Delete.Label=Supprimer l''environnement...
 HopGui.Toolbar.Environment.Delete.Tooltip=Supprimer l''environnement 
s\u00E9lectionn\u00E9
+HopGui.Toolbar.Environment.Edit.Label=Editer l''environnement...
 HopGui.Toolbar.Environment.Edit.Tooltip=Editer l''environnement 
s\u00E9lectionn\u00E9
-HopGui.Toolbar.Environment.Label=Environnement\u202F:
-HopGui.Toolbar.Environment.Tooltip=Cliquer ici pour editer l''environnement
-HopGui.Toolbar.EnvironmentsList.Tooltip=S\u00E9lectionner l''environnement 
actif
-HopGui.Toolbar.Project.Add.Tooltip=Cr\u00E9er un projet
+HopGui.Toolbar.Project.Tooltip=Projet ''{0}'' dans le r\u00E9pertoire ''{1}'' 
configur\u00E9 dans ''{2}''
+HopGui.Toolbar.Project.Add.Label=Cr\u00E9er un projet...
+HopGui.Toolbar.Project.Add.Tooltip=Cr\u00E9er un nouveau projet
+HopGui.Toolbar.Project.Delete.Label=Supprimer le projet...
 HopGui.Toolbar.Project.Delete.Tooltip=Supprimer le projet s\u00E9lectionn\u00E9
+HopGui.Toolbar.Project.Edit.Label=Editer le projet...
 HopGui.Toolbar.Project.Edit.Tooltip=Editer le projet s\u00E9lectionn\u00E9
-HopGui.Toolbar.Project.Label=Projet\u202F:
-HopGui.Toolbar.Project.Tooltip=Cliquer ici pour \u00E9diter le projet
-HopGui.Toolbar.ProjectsList.Tooltip=S\u00E9lectionner le projet actif
 ProjectGuiPlugin.AddEnvironment.Error.Dialog.Header=Erreur
 ProjectGuiPlugin.AddEnvironment.Error.Dialog.Message=Erreur lors de l''ajout 
d''un environnement de cycle de vie
 ProjectGuiPlugin.AddProject.Error.Dialog.Header=Erreur
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_it_IT.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_it_IT.properties
index 828c94faf6..d2c2e32721 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_it_IT.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_it_IT.properties
@@ -17,18 +17,15 @@
 
 FileDialog.Browse.Project.Home=Vai alla home directory del progetto
 HopGui.FileMenu.Project.Export.Label=Esporta il progetto corrente in un file 
zip
-HopGui.Toolbar.Environment.Add.Tooltip=Aggiungi un nuovo ambiente
-HopGui.Toolbar.Environment.Delete.Tooltip=Cancella l''ambiente selezionato
-HopGui.Toolbar.Environment.Edit.Tooltip=Modifica l''ambiente selezionato
-HopGui.Toolbar.Environment.Label=Ambiente\:
-HopGui.Toolbar.Environment.Tooltip=Fai click qui per modificare l''ambiente 
attivo
-HopGui.Toolbar.EnvironmentsList.Tooltip=Seleziona l''ambiente attivo
-HopGui.Toolbar.Project.Add.Tooltip=Aggiungi un nuovo progetto
-HopGui.Toolbar.Project.Delete.Tooltip=Cancella il progetto selezionato
-HopGui.Toolbar.Project.Edit.Tooltip=Modifica il progetto selezionato
-HopGui.Toolbar.Project.Label=Progetto\:
-HopGui.Toolbar.Project.Tooltip=Fai click qui per modificare il progetto attivo
-HopGui.Toolbar.ProjectsList.Tooltip=Seleziona il progetto attivo
+HopGui.Toolbar.Environment.Select.Tooltip=Seleziona l''ambiente attivo
+HopGui.Toolbar.Environment.Tooltip=L''ambiente {0} per il progetto ''{1}'' ha 
la finalit\u00E0 di: {2}
+HopGui.Toolbar.Environment.Add.Label=Aggiungi un nuovo ambiente
+HopGui.Toolbar.Environment.Delete.Label=Cancella l''ambiente selezionato
+HopGui.Toolbar.Environment.Edit.Label=Modifica l''ambiente selezionato
+HopGui.Toolbar.Project.Tooltip=Il progetto {0} in ''{1}'' \u00E8 configurato 
in ''{2}''
+HopGui.Toolbar.Project.Add.Label=Aggiungi un nuovo progetto
+HopGui.Toolbar.Project.Delete.Label=Cancella il progetto selezionato
+HopGui.Toolbar.Project.Edit.Label=Modifica il progetto selezionato
 ProjectGuiPlugin.AddEnvironment.Error.Dialog.Header=Errore
 ProjectGuiPlugin.AddEnvironment.Error.Dialog.Message=Si \u00E8 verificato un 
errore aggiungendo l''ambiente
 ProjectGuiPlugin.AddProject.Error.Dialog.Header=Errore
@@ -54,7 +51,6 @@ ProjectGuiPlugin.EditEnvironment.Error.Dialog.Header=Errore
 ProjectGuiPlugin.EditEnvironment.Error.Dialog.Message=Si \u00E8 verificato un 
errore cancellando l''ambiente ''{0}''
 ProjectGuiPlugin.EditProject.Error.Dialog.Header=Errore
 ProjectGuiPlugin.EditProject.Error.Dialog.Message=Si \u00E8 verificato un 
errore modificando il progetto ''{0}''
-ProjectGuiPlugin.FindEnvironment.Tooltip=L''ambiente {0} per il progetto 
''{1}'' ha la finalit\u00E0 di: {2}
 ProjectGuiPlugin.Lifecycle.Dialog.Header=Create un ambiente per il progetto?
 ProjectGuiPlugin.Lifecycle.Dialog.Message1=Questo progetto potrebbe essere 
parte di una gestione che comprende ambienti di esecuzione, vuoi forse 
aggiungere il progetto ad un ambiente?
 ProjectGuiPlugin.Lifecycle.Dialog.Message2=In questo modo puoi gestire 
impostazioni specifiche come hostnames percorsi per lo specifico ambiente
@@ -68,7 +64,6 @@ ProjectGuiPlugin.ReloadProject.Dialog.Message=Per applicare 
tutte le modifiche f
 ProjectGuiPlugin.RenameProject.ProjectReferencedAsParent.Header=Non posso 
rinominare il progetto!
 ProjectGuiPlugin.RenameProject.ProjectReferencedAsParent.Message1=Non \u00E8 
possibile rinominare il progetto corrente in quanto referenziato come progetto 
padre nei seguenti progetti:
 ProjectGuiPlugin.RenameProject.ProjectReferencedAsParent.Message2=Per 
rinominarlo, devi prima rimuovere la referenza di progetto padre nei progetti 
elencati e poi riprovare.
-ProjectGuiPlugin.SelectProject.Tooltip=Il progetto {0} in ''{1}'' \u00E8 
configurato in ''{2}''
 ProjectGuiPlugin.ZipDirectory.Dialog.Header=File ZIP del progetto creato
 ProjectGuiPlugin.ZipDirectory.Dialog.Message1=Un file zip contenente il 
progetto \u00E8 stato creato con successo: {0}
 ProjectGuiPlugin.ZipDirectory.Dialog.Message2=Il file \u00E8 stato copiato con 
successo nella clipboard.
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_pt_BR.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_pt_BR.properties
index 0c3678ce03..555e646550 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_pt_BR.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_pt_BR.properties
@@ -18,18 +18,13 @@
 #
 
 HopGui.FileMenu.Project.Export.Label=Exportar projeto atual para zip
-HopGui.Toolbar.Environment.Add.Tooltip=Adicionar ambiente novo
-HopGui.Toolbar.Environment.Delete.Tooltip=Apagar ambiente selecionado
-HopGui.Toolbar.Environment.Edit.Tooltip=Editar ambiente selecionado
-HopGui.Toolbar.Environment.Label=Ambiente:
-HopGui.Toolbar.Environment.Tooltip=Clica aqui para editar o ambiente ativo
-HopGui.Toolbar.EnvironmentsList.Tooltip=Selecionar ambiente ativo
-HopGui.Toolbar.Project.Add.Tooltip=Adicionar projeto novo
-HopGui.Toolbar.Project.Delete.Tooltip=Apagar projeto selecionado
-HopGui.Toolbar.Project.Edit.Tooltip=Editar projeto selecionado
-HopGui.Toolbar.Project.Label=Projeto:
-HopGui.Toolbar.Project.Tooltip=Clica aqui para editar o projeto ativo
-HopGui.Toolbar.ProjectsList.Tooltip=Selecionar o projeto ativo
+HopGui.Toolbar.Environment.Select.Tooltip=Selecionar ambiente ativo
+HopGui.Toolbar.Environment.Add.Label=Adicionar ambiente novo
+HopGui.Toolbar.Environment.Delete.Label=Apagar ambiente selecionado
+HopGui.Toolbar.Environment.Edit.Label=Editar ambiente selecionado
+HopGui.Toolbar.Project.Add.Label=Adicionar projeto novo
+HopGui.Toolbar.Project.Delete.Label=Apagar projeto selecionado
+HopGui.Toolbar.Project.Edit.Label=Editar projeto selecionado
 ProjectGuiPlugin.AddEnvironment.Error.Dialog.Header=Erro
 ProjectGuiPlugin.AddProject.Error.Dialog.Header=Erro
 ProjectGuiPlugin.AddProject.Error.Dialog.Message=Erro na adi\u00E7\u00E3o de 
projeto
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_zh_CN.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_zh_CN.properties
index 2e568e36aa..cbbad490f8 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_zh_CN.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/gui/messages/messages_zh_CN.properties
@@ -19,18 +19,15 @@
 
 FileDialog.Browse.Project.Home=\u5BFC\u822A\u5230\u9879\u76EE\u4E3B\u76EE\u5F55
 
HopGui.FileMenu.Project.Export.Label=\u5F53\u524D\u9879\u76EE\u5BFC\u51FA\u5230(zip)...
-HopGui.Toolbar.Environment.Add.Tooltip=\u6DFB\u52A0\u65B0\u73AF\u5883
-HopGui.Toolbar.Environment.Delete.Tooltip=\u5220\u9664\u9009\u5B9A\u7684\u73AF\u5883
-HopGui.Toolbar.Environment.Edit.Tooltip=\u7F16\u8F91\u9009\u5B9A\u7684\u73AF\u5883
-HopGui.Toolbar.Environment.Label=\u73AF\u5883\:
-HopGui.Toolbar.Environment.Tooltip=\u5355\u51FB\u6B64\u5904\u7F16\u8F91\u5F53\u524D\u73AF\u5883
-HopGui.Toolbar.EnvironmentsList.Tooltip=\u9009\u62E9\u5F53\u524D\u73AF\u5883
-HopGui.Toolbar.Project.Add.Tooltip=\u6DFB\u52A0\u65B0\u9879\u76EE
-HopGui.Toolbar.Project.Delete.Tooltip=\u5220\u9664\u9009\u4E2D\u7684\u9879\u76EE
-HopGui.Toolbar.Project.Edit.Tooltip=\u7F16\u8F91\u9009\u5B9A\u7684\u9879\u76EE
-HopGui.Toolbar.Project.Label=\u9879\u76EE\:
-HopGui.Toolbar.Project.Tooltip=\u5355\u51FB\u6B64\u5904\u7F16\u8F91\u5F53\u524D\u9879\u76EE
-HopGui.Toolbar.ProjectsList.Tooltip=\u9009\u62E9\u5F53\u524D\u9879\u76EE
+HopGui.Toolbar.Environment.Select.Tooltip=\u9009\u62E9\u5F53\u524D\u73AF\u5883
+HopGui.Toolbar.Environment.Tooltip=\u73AF\u5883 {0} \u5728\u9879\u76EE 
\u201C{1}\u201D \u4E2D\u88AB\u7528\u4E8E {2}
+HopGui.Toolbar.Environment.Add.Label=\u6DFB\u52A0\u65B0\u73AF\u5883
+HopGui.Toolbar.Environment.Delete.Label=\u5220\u9664\u9009\u5B9A\u7684\u73AF\u5883
+HopGui.Toolbar.Environment.Edit.Label=\u7F16\u8F91\u9009\u5B9A\u7684\u73AF\u5883
+HopGui.Toolbar.Project.Tooltip="{1}" \u76EE\u5F55\u4E0A\u7684\u9879\u76EE {0} 
\u914D\u7F6E\u5728 "{2}" \u6587\u4EF6\u4E2D
+HopGui.Toolbar.Project.Add.Label=\u6DFB\u52A0\u65B0\u9879\u76EE
+HopGui.Toolbar.Project.Delete.Label=\u5220\u9664\u9009\u4E2D\u7684\u9879\u76EE
+HopGui.Toolbar.Project.Edit.Label=\u7F16\u8F91\u9009\u5B9A\u7684\u9879\u76EE
 ProjectGuiPlugin.AddEnvironment.Error.Dialog.Header=\u9519\u8BEF
 
ProjectGuiPlugin.AddEnvironment.Error.Dialog.Message=\u6DFB\u52A0\u8FD0\u884C\u73AF\u5883\u65F6\u51FA\u9519
 ProjectGuiPlugin.AddProject.Error.Dialog.Header=\u9519\u8BEF
@@ -56,7 +53,6 @@ 
ProjectGuiPlugin.EditEnvironment.Error.Dialog.Header=\u9519\u8BEF
 
ProjectGuiPlugin.EditEnvironment.Error.Dialog.Message=\u7F16\u8F91\u73AF\u5883\u53D8\u91CF
 "{0}" \u65F6\u51FA\u9519
 ProjectGuiPlugin.EditProject.Error.Dialog.Header=\u9519\u8BEF
 ProjectGuiPlugin.EditProject.Error.Dialog.Message=\u7F16\u8F91\u9879\u76EE 
"{0}" \u65F6\u51FA\u9519
-ProjectGuiPlugin.FindEnvironment.Tooltip=\u73AF\u5883 {0} \u5728\u9879\u76EE 
\u201C{1}\u201D \u4E2D\u88AB\u7528\u4E8E {2}
 
ProjectGuiPlugin.Lifecycle.Dialog.Header=\u4E3A\u9879\u76EE\u521B\u5EFA\u5168\u751F\u547D\u5468\u671F\u73AF\u5883
 
ProjectGuiPlugin.Lifecycle.Dialog.Message1=\u5982\u679C\u8FD9\u4E2A\u9879\u76EE\u662F\u751F\u547D\u5468\u671F\u7684\u4E00\u90E8\u5206,
 
\u5EFA\u8BAE\u60A8\u5C06\u5B83\u6DFB\u52A0\u5230\u751F\u547D\u5468\u671F\u73AF\u5883\u4E2D?
 
ProjectGuiPlugin.Lifecycle.Dialog.Message2=\u60A8\u53EF\u4EE5\u4F7F\u7528\u5B83\u7BA1\u7406\u7279\u5B9A\u8BBE\u7F6E,
 
\u4F8B\u5982\u73AF\u5883\u7684\u4E3B\u673A\u540D\u548C\u8DEF\u5F84\u7B49\u4FE1\u606F
@@ -67,7 +63,6 @@ 
ProjectGuiPlugin.ProjectExists.Dialog.Header=\u914D\u7F6E\u6587\u4EF6\u5DF2\u7EC
 
ProjectGuiPlugin.ProjectExists.Dialog.Message=\u5728\u6307\u5B9A\u6587\u4EF6\u5939\u4E2D\u627E\u5230\u73B0\u6709\u9879\u76EE\u914D\u7F6E\u6587\u4EF6,
 \u5B83\u5C06\u88AB\u7528\u4E8E\u8FD9\u4E2A\u9879\u76EE
 
ProjectGuiPlugin.ReloadProject.Dialog.Header=\u91CD\u65B0\u52A0\u8F7D\u9879\u76EE?
 
ProjectGuiPlugin.ReloadProject.Dialog.Message=\u9700\u8981\u91CD\u65B0\u52A0\u8F7D\u6B64\u9879\u76EE,
 \u6240\u505A\u7684\u66F4\u6539\u624D\u4F1A\u751F\u6548, 
\u4F60\u73B0\u5728\u60F3\u8FD9\u6837\u505A\u5417?
-ProjectGuiPlugin.SelectProject.Tooltip="{1}" 
\u76EE\u5F55\u4E0A\u7684\u9879\u76EE {0} \u914D\u7F6E\u5728 "{2}" 
\u6587\u4EF6\u4E2D
 ProjectGuiPlugin.ZipDirectory.Dialog.Header=\u9879\u76EE zip 
\u6587\u4EF6\u5DF2\u521B\u5EFA
 ProjectGuiPlugin.ZipDirectory.Dialog.Message1=zip \u6587\u4EF6 {0} 
\u521B\u5EFA\u6210\u529F
 
ProjectGuiPlugin.ZipDirectory.Dialog.Message2=\u6587\u4EF6\u540D\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F
diff --git 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/project/messages/messages_en_US.properties
 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/project/messages/messages_en_US.properties
index 8577abca6c..f64633b92b 100644
--- 
a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/project/messages/messages_en_US.properties
+++ 
b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/project/messages/messages_en_US.properties
@@ -31,18 +31,18 @@ ProjectDialog.DetailTable.Label.VariableName=Name
 ProjectDialog.DetailTable.Label.VariableValue=Value
 ProjectDialog.FileList.AllFiles.Text=All Files (*.*)
 ProjectDialog.FileList.PrjFiles.Text=Project Config File (*.json)
-ProjectDialog.Group.Label.ProjectVariablesToSet=Project variables to set : 
+ProjectDialog.Group.Label.ProjectVariablesToSet=Project variables to set :
 ProjectDialog.Label.Company=Company 
-ProjectDialog.Label.ConfigurationFile=Configuration file (relative path) 
-ProjectDialog.Label.DatasetCSVFolder=Data Sets CSV Folder 
(HOP_DATASETS_FOLDER) 
-ProjectDialog.Label.Department=Department 
-ProjectDialog.Label.Description=Description 
-ProjectDialog.Label.EnforceExecutionInHome=Enforce executions in project home? 
-ProjectDialog.Label.HomeFolder=Home folder 
-ProjectDialog.Label.MetadataBaseFolder=Metadata base folder 
(HOP_METADATA_FOLDER) 
-ProjectDialog.Label.ParentProject=Parent project to inherit from 
-ProjectDialog.Label.ProjectName=Name 
-ProjectDialog.Label.UnitTestBaseFolder=Unit tests base path 
(HOP_UNIT_TESTS_FOLDER) 
+ProjectDialog.Label.ConfigurationFile=Configuration file (relative path)
+ProjectDialog.Label.DatasetCSVFolder=Data Sets CSV Folder (HOP_DATASETS_FOLDER)
+ProjectDialog.Label.Department=Department
+ProjectDialog.Label.Description=Description
+ProjectDialog.Label.EnforceExecutionInHome=Enforce executions in project home
+ProjectDialog.Label.HomeFolder=Home folder
+ProjectDialog.Label.MetadataBaseFolder=Metadata base folder 
(HOP_METADATA_FOLDER)
+ProjectDialog.Label.ParentProject=Parent project to inherit from
+ProjectDialog.Label.ProjectName=Name
+ProjectDialog.Label.UnitTestBaseFolder=Unit tests base path 
(HOP_UNIT_TESTS_FOLDER)
 ProjectDialog.ProjectConfigError.Error.Dialog.Header=Error
 ProjectDialog.ProjectConfigError.Error.Dialog.Message=There is a configuration 
error in the project
 ProjectDialog.ProjectDefinitionError.Error.Dialog.Header=Error
diff --git a/plugins/misc/projects/src/main/resources/project-add.svg 
b/plugins/misc/projects/src/main/resources/project-add.svg
deleted file mode 100644
index 83b10b2e89..0000000000
--- a/plugins/misc/projects/src/main/resources/project-add.svg
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        enable-background="new 0 0 42 42"
-        viewBox="0 0 42 42"
-        height="42px"
-        width="42px"
-        y="0px"
-        x="0px"
-        version="1.1">
-    <text
-            
style="font-style:normal;font-weight:normal;font-size:192px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-            x="56.459057"
-            y="19.834593"
-    >
-        <tspan
-                x="56.459057"
-                y="194.53062"/>
-    </text>
-    <g
-            transform="matrix(0.48941052,0,0,0.48941052,24.528835,24.811866)">
-        <polygon
-                style="fill:#3d6380"
-                points="18.2,0 13.8,0 13.8,13.8 0,13.8 0,18.2 13.8,18.2 
13.8,32 18.2,32 18.2,18.2 32,18.2 32,13.8 18.2,13.8 "
-        />
-    </g>
-    <text
-            y="28.042698"
-            x="2.8721724"
-            
style="font-style:normal;font-weight:normal;font-size:48.81200027px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25422916"
-    >
-        <tspan
-                style="stroke-width:0.25422916"
-                y="28.042698"
-                x="2.8721724"
-        >p
-        </tspan>
-    </text>
-</svg>
\ No newline at end of file
diff --git a/plugins/misc/projects/src/main/resources/project-delete.svg 
b/plugins/misc/projects/src/main/resources/project-delete.svg
deleted file mode 100644
index 9e8fd4f044..0000000000
--- a/plugins/misc/projects/src/main/resources/project-delete.svg
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        enable-background="new 0 0 42 42"
-        viewBox="0 0 42 42"
-        height="42px"
-        width="42px"
-        y="0px"
-        x="0px"
-        version="1.1">
-    <text
-            
style="font-style:normal;font-weight:normal;font-size:192px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-            x="56.459057"
-            y="19.834593"
-    >
-        <tspan
-                x="56.459057"
-                y="194.53062"/>
-    </text>
-    <polygon
-            transform="matrix(1.6377839,0,0,1.6377839,-23.702184,-25.258686)"
-            style="fill:#ea102a"
-            points="37.6,31.4 34.7,34.3 31.8,31.4 30.4,32.7 33.3,35.6 
30.4,38.5 31.8,39.9 34.7,37 37.6,39.9 38.9,38.5 36,35.6 38.9,32.7 "/>
-    <text
-            y="28.091171"
-            x="2.7267504"
-            
style="font-style:normal;font-weight:normal;font-size:48.81200027px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25422916"
-    >
-        <tspan
-                style="stroke-width:0.25422916"
-                y="28.091171"
-                x="2.7267504"
-        >p
-        </tspan>
-    </text>
-</svg>
\ No newline at end of file
diff --git a/plugins/misc/projects/src/main/resources/project-edit.svg 
b/plugins/misc/projects/src/main/resources/project-edit.svg
deleted file mode 100644
index 8e3cd21ae4..0000000000
--- a/plugins/misc/projects/src/main/resources/project-edit.svg
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        enable-background="new 0 0 42 42"
-        viewBox="0 0 42 42"
-        height="42px"
-        width="42px"
-        y="0px"
-        x="0px"
-        version="1.1">
-    <text
-            
style="font-style:normal;font-weight:normal;font-size:192px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-            x="56.459057"
-            y="19.834593"
-    >
-        <tspan
-                x="56.459057"
-                y="194.53062"/>
-    </text>
-    <ellipse
-            
style="opacity:1;fill:#000000;fill-opacity:1;stroke-width:0.72368419;paint-order:markers
 fill stroke"
-            cx="25.54306"
-            cy="34.986797"
-            rx="2.0330944"
-            ry="2.0063434"/>
-    <ellipse
-            style="opacity:0.3;fill:#ffd700;fill-opacity:1;paint-order:markers 
fill stroke"
-            cx="29.202629"
-            cy="35.715889"
-            rx="1.3307527"
-            ry="0.22179212"/>
-    <ellipse
-            
style="opacity:1;fill:#000000;fill-opacity:1;stroke-width:0.72368419;paint-order:markers
 fill stroke"
-            cx="30.903036"
-            cy="34.976582"
-            rx="2.0330944"
-            ry="2.0063434"/>
-    <ellipse
-            
style="opacity:1;fill:#000000;fill-opacity:1;stroke-width:0.72368419;paint-order:markers
 fill stroke"
-            cx="36.004257"
-            cy="34.976585"
-            rx="2.0330944"
-            ry="2.0063434"/>
-    <text
-            y="28.188118"
-            x="2.7025132"
-            
style="font-style:normal;font-weight:normal;font-size:48.81200027px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25422916"
-    >
-        <tspan
-                style="stroke-width:0.25422916"
-                y="28.188118"
-                x="2.7025132"
-        >p
-        </tspan>
-    </text>
-</svg>
\ No newline at end of file
diff --git a/plugins/misc/projects/src/main/resources/project.svg 
b/plugins/misc/projects/src/main/resources/project.svg
index 5718f91a44..fe7092a1ec 100644
--- a/plugins/misc/projects/src/main/resources/project.svg
+++ b/plugins/misc/projects/src/main/resources/project.svg
@@ -1,32 +1,4 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-        xmlns="http://www.w3.org/2000/svg";
-        enable-background="new 0 0 42 42"
-        viewBox="0 0 42 42"
-        height="42px"
-        width="42px"
-        y="0px"
-        x="0px"
-        version="1.1">
-    <text
-            
style="font-style:normal;font-weight:normal;font-size:192px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-            x="56.459057"
-            y="19.834593"
-    >
-        <tspan
-                x="56.459057"
-                y="194.53062"/>
-    </text>
-    <text
-            y="28.045294"
-            x="2.8174167"
-            
style="font-style:normal;font-weight:normal;font-size:48.81200027px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.25422916"
-    >
-        <tspan
-                style="stroke-width:0.25422916"
-                y="28.045294"
-                x="2.8174167"
-        >p
-        </tspan>
-    </text>
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="24" height="24">
+    <path fill="#0e3a5a" d="M10,2H14A2,2 0 0,1 16,4V6H20A2,2 0 0,1 22,8V19A2,2 
0 0,1 20,21H4C2.89,21 2,20.1 2,19V8C2,6.89 2.89,6 4,6H8V4C8,2.89 8.89,2 
10,2M14,6V4H10V6H14Z" />4
 </svg>
\ No newline at end of file
diff --git a/ui/src/main/java/org/apache/hop/ui/hopgui/HopGui.java 
b/ui/src/main/java/org/apache/hop/ui/hopgui/HopGui.java
index fe677b717a..55de257de9 100644
--- a/ui/src/main/java/org/apache/hop/ui/hopgui/HopGui.java
+++ b/ui/src/main/java/org/apache/hop/ui/hopgui/HopGui.java
@@ -220,6 +220,8 @@ public class HopGui
   public static final String ID_MAIN_TOOLBAR_SAVE = "toolbar-10040-save";
   public static final String ID_MAIN_TOOLBAR_SAVE_AS = "toolbar-10050-save-as";
 
+  public static final String ID_STATUS_TOOLBAR = "HopGui-Status-Toolbar";
+
   public static final String GUI_PLUGIN_PERSPECTIVES_PARENT_ID = 
"HopGui-Perspectives";
 
   public static final String DEFAULT_HOP_GUI_NAMESPACE = "hop-gui";
@@ -255,6 +257,9 @@ public class HopGui
   private ToolBar mainToolbar;
   private GuiToolbarWidgets mainToolbarWidgets;
 
+  private ToolBar statusToolbar;
+  private GuiToolbarWidgets statusToolbarWidgets;
+
   private ToolBar perspectivesToolbar;
   private Composite mainPerspectivesComposite;
   private HopPerspectiveManager perspectiveManager;
@@ -417,6 +422,7 @@ public class HopGui
     shell.setText(BaseMessages.getString(PKG, "HopGui.Application.Name"));
     addMainMenu();
     addMainToolbar();
+    addStatusToolbar();
     addPerspectivesToolbar();
     addMainPerspectivesComposite();
 
@@ -1241,7 +1247,7 @@ public class HopGui
   }
 
   protected void addMainToolbar() {
-    mainToolbar = new ToolBar(shell, SWT.WRAP | SWT.LEFT | SWT.HORIZONTAL);
+    mainToolbar = new ToolBar(shell, SWT.WRAP | SWT.RIGHT | SWT.HORIZONTAL);
     FormData fdToolBar = new FormData();
     fdToolBar.left = new FormAttachment(0, 0);
     fdToolBar.top = new FormAttachment(0, 0);
@@ -1255,6 +1261,21 @@ public class HopGui
     mainToolbar.pack();
   }
 
+  protected void addStatusToolbar() {
+    statusToolbar = new ToolBar(shell, SWT.WRAP | SWT.RIGHT | SWT.HORIZONTAL);
+    FormData fdToolBar = new FormData();
+    fdToolBar.left = new FormAttachment(0, 0);
+    fdToolBar.right = new FormAttachment(100, 0);
+    fdToolBar.bottom = new FormAttachment(100, 0);
+    statusToolbar.setLayoutData(fdToolBar);
+    PropsUi.setLook(statusToolbar, Props.WIDGET_STYLE_TOOLBAR);
+
+    statusToolbarWidgets = new GuiToolbarWidgets();
+    statusToolbarWidgets.registerGuiPluginObject(this);
+    statusToolbarWidgets.createToolbarWidgets(statusToolbar, 
ID_STATUS_TOOLBAR);
+    statusToolbar.pack();
+  }
+
   protected void addPerspectivesToolbar() {
     // We can't mix horizontal and vertical toolbars so we need to add a 
composite.
     //
@@ -1265,7 +1286,7 @@ public class HopGui
     formData.left = new FormAttachment(0, 0);
     formData.right = new FormAttachment(100, 0);
     formData.top = new FormAttachment(mainToolbar, 0);
-    formData.bottom = new FormAttachment(100, 0);
+    formData.bottom = new FormAttachment(statusToolbar, 0);
     mainHopGuiComposite.setLayoutData(formData);
 
     perspectivesToolbar = new ToolBar(mainHopGuiComposite, SWT.WRAP | 
SWT.RIGHT | SWT.VERTICAL);
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/dataorch/HopDataOrchestrationPerspective.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/dataorch/HopDataOrchestrationPerspective.java
index 3f0df32ec2..7d28e8d9b6 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/dataorch/HopDataOrchestrationPerspective.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/dataorch/HopDataOrchestrationPerspective.java
@@ -63,7 +63,6 @@ import org.eclipse.swt.custom.CTabFolderEvent;
 import org.eclipse.swt.custom.CTabItem;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Event;
@@ -85,9 +84,6 @@ public class HopDataOrchestrationPerspective implements 
IHopPerspective, TabClos
   private final HopWorkflowFileType<WorkflowMeta> workflowFileType;
 
   private HopGui hopGui;
-  private Composite parent;
-
-  private Composite composite;
 
   private CTabFolder tabFolder;
 
@@ -128,26 +124,10 @@ public class HopDataOrchestrationPerspective implements 
IHopPerspective, TabClos
   @Override
   public void initialize(HopGui hopGui, Composite parent) {
     this.hopGui = hopGui;
-    this.parent = parent;
-
-    PropsUi props = PropsUi.getInstance();
-
-    composite = new Composite(parent, SWT.NONE);
-    FormLayout layout = new FormLayout();
-    layout.marginRight = PropsUi.getMargin();
-    layout.marginBottom = PropsUi.getMargin();
-    composite.setLayout(layout);
-
-    FormData formData = new FormData();
-    formData.left = new FormAttachment(0, 0);
-    formData.top = new FormAttachment(0, 0);
-    formData.right = new FormAttachment(100, 0);
-    formData.bottom = new FormAttachment(100, 0);
-    composite.setLayoutData(formData);
 
     // A tab folder covers the complete area...
     //
-    tabFolder = new CTabFolder(composite, SWT.MULTI | SWT.BORDER);
+    tabFolder = new CTabFolder(parent, SWT.MULTI | SWT.BORDER);
     PropsUi.setLook(tabFolder, Props.WIDGET_STYLE_TAB);
     FormData fdLabel = new FormData();
     fdLabel.left = new FormAttachment(0, 0);
@@ -637,7 +617,7 @@ public class HopDataOrchestrationPerspective implements 
IHopPerspective, TabClos
 
   @Override
   public Control getControl() {
-    return composite;
+    return tabFolder;
   }
 
   /**


Reply via email to