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 56626c45a4 issue #7692: reopen files after environment/project refresh 
(#7695)
56626c45a4 is described below

commit 56626c45a4de5826a2d4a56b18c5ab8de2ce089f
Author: Matt Casters <[email protected]>
AuthorDate: Fri Jul 31 09:02:13 2026 +0200

    issue #7692: reopen files after environment/project refresh (#7695)
    
    Prevent bulk close handlers from wiping the saved open-files audit list,
    and restore tabs synchronously after enable so environment reload reopens
    the files that were closed.
---
 .../apache/hop/projects/gui/ProjectsGuiPlugin.java | 34 +++++++++++-----------
 .../ui/hopgui/delegates/HopGuiAuditDelegate.java   | 27 ++++++++++++++++-
 .../execution/ExecutionPerspective.java            |  8 ++++-
 .../perspective/explorer/ExplorerPerspective.java  |  7 ++++-
 .../perspective/metadata/MetadataPerspective.java  |  5 +++-
 5 files changed, 60 insertions(+), 21 deletions(-)

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 a2da9a7270..dfcb31c2b3 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
@@ -173,6 +173,11 @@ public class ProjectsGuiPlugin {
       //
       ExecutionPerspective.getInstance().saveState();
 
+      // Save explorer layout (split panes, panel visibility) while tabs are 
still open so the
+      // restored layout matches what the user had before the switch (issue 
#7692 / #6708).
+      //
+      ExplorerPerspective.getInstance().saveExplorerStateOnShutdown();
+
       // Close's all (including execution information tabs)
       //
       hopGui.fileDelegate.closeAllFiles();
@@ -183,10 +188,6 @@ public class ProjectsGuiPlugin {
         hopGui.getTerminalPanel().clearAllTerminals();
       }
 
-      // Save explorer perspective state for the current project before 
switching namespace
-      //
-      ExplorerPerspective.getInstance().saveExplorerStateOnShutdown();
-
       // This is called only in Hop GUI so we want to start with a new set of 
variables
       // It avoids variables from one project showing up in another
       //
@@ -224,19 +225,6 @@ public class ProjectsGuiPlugin {
         }
       }
 
-      // We need to change the currently set variables in the newly loaded 
files
-      //
-      hopGui.setVariables(variables);
-
-      // Re-open last open files for the namespace
-      hopGui.getDisplay().asyncExec(() -> 
hopGui.auditDelegate.openLastFiles());
-
-      // Restore terminal tabs for the new project (per-project terminals)
-      //
-      if (hopGui.getTerminalPanel() != null && 
hopGui.getProps().openLastFile()) {
-        hopGui.getDisplay().asyncExec(() -> 
hopGui.getTerminalPanel().restoreTerminals());
-      }
-
       // Clear last used, fill it with something useful.
       //
       IVariables hopGuiVariables = Variables.getADefaultVariableSpace();
@@ -248,6 +236,18 @@ public class ProjectsGuiPlugin {
         }
       }
 
+      // Re-open last open files for the namespace after HopGui variables are 
final.
+      // Run synchronously so tabs are restored before ProjectActivated 
listeners refresh the
+      // explorer layout (async restore raced with layout apply after #6708, 
issue #7692).
+      //
+      hopGui.auditDelegate.openLastFiles();
+
+      // Restore terminal tabs for the new project (per-project terminals)
+      //
+      if (hopGui.getTerminalPanel() != null && 
hopGui.getProps().openLastFile()) {
+        hopGui.getTerminalPanel().restoreTerminals();
+      }
+
       // Refresh the currently active file
       //
       hopGui.getActiveFileTypeHandler().updateGui();
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/delegates/HopGuiAuditDelegate.java 
b/ui/src/main/java/org/apache/hop/ui/hopgui/delegates/HopGuiAuditDelegate.java
index a075a66a3f..4fd81a83a0 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/delegates/HopGuiAuditDelegate.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/delegates/HopGuiAuditDelegate.java
@@ -82,8 +82,26 @@ public class HopGuiAuditDelegate {
       return;
     }
 
-    String namespace = HopNamespace.getNamespace();
+    // Prevent per-file writeLastOpenFiles() calls (from fileOpenWithType) 
from rewriting the
+    // audit list mid-restore. Same flag used at Hop GUI startup.
+    //
+    boolean previousReOpening = hopGui.isReOpeningFiles();
+    hopGui.setReOpeningFiles(true);
+    try {
+      openLastFilesInternal();
+    } finally {
+      hopGui.setReOpeningFiles(previousReOpening);
+    }
 
+    // Persist the actual open set once restore is finished (failed opens are 
omitted).
+    // Only when we were not already inside a broader re-open block.
+    //
+    if (!previousReOpening) {
+      writeLastOpenFiles();
+    }
+  }
+
+  private void openLastFilesInternal() {
     // Collect files that fail to open
     List<String> failedFiles = new ArrayList<>();
 
@@ -303,6 +321,13 @@ public class HopGuiAuditDelegate {
     if (hopGui.isReOpeningFiles()) {
       return;
     }
+    // Bulk close (project/environment switch, File → Close All) empties tabs 
first, then may call
+    // writeLastOpenFiles from closeTab handlers. Writing then would overwrite 
the list we just
+    // saved for reopen (issue #7692).
+    //
+    if (hopGui.fileDelegate != null && hopGui.fileDelegate.isClosing()) {
+      return;
+    }
     if (!hopGui.getProps().openLastFile()) {
       return;
     }
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/execution/ExecutionPerspective.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/execution/ExecutionPerspective.java
index d18587f127..cf4531b4bd 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/execution/ExecutionPerspective.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/execution/ExecutionPerspective.java
@@ -1474,7 +1474,13 @@ public class ExecutionPerspective implements 
IHopPerspective, TabClosable {
     tabItem.dispose();
 
     if (isRemoved) {
-      hopGui.auditDelegate.writeLastOpenFiles();
+      // Skip during bulk close (project/environment switch or closeAllTabs): 
the open-files list
+      // was saved before closeAllFiles; writing here would overwrite it with 
empty tabs after
+      // pipelines/workflows were already closed (issue #7692).
+      //
+      if (!closingAllTabs && !hopGui.fileDelegate.isClosing()) {
+        hopGui.auditDelegate.writeLastOpenFiles();
+      }
       // Keep the per-project open-tabs audit in sync when the user closes a 
single tab.
       // Skip during closeAllTabs so a prior saveState() for project switch is 
not wiped.
       //
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/ExplorerPerspective.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/ExplorerPerspective.java
index 2248fdfb55..f294f82414 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/ExplorerPerspective.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/explorer/ExplorerPerspective.java
@@ -398,6 +398,8 @@ public class ExplorerPerspective implements 
IHopPerspective, TabClosable, IFileD
     }
 
     // Refresh the file explorer when a project is activated or updated.
+    // applyRestoredState() only rebuilds the editor split layout when the 
editor is empty, so it
+    // is safe after enableHopGuiProject has already reopened tabs (issue 
#7692).
     //
     hopGui
         .getEventsHandler()
@@ -2142,7 +2144,10 @@ public class ExplorerPerspective implements 
IHopPerspective, TabClosable, IFileD
       removeHandlerAndDisposeTab(tabItem);
       isRemoved = true;
     }
-    if (isRemoved) {
+    // Skip during bulk close (project/environment switch): writeLastOpenFiles 
was already called
+    // before closeAllFiles; writing here would persist an empty open-files 
list (issue #7692).
+    //
+    if (isRemoved && !hopGui.fileDelegate.isClosing()) {
       hopGui.auditDelegate.writeLastOpenFiles();
     }
     if (!isRemoved && event != null) {
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/metadata/MetadataPerspective.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/metadata/MetadataPerspective.java
index f0876ea64f..a07e57e31d 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/metadata/MetadataPerspective.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/metadata/MetadataPerspective.java
@@ -3322,7 +3322,10 @@ public class MetadataPerspective implements 
IHopPerspective, TabClosable, IMetad
     MetadataEditor<?> editor = (MetadataEditor<?>) tabItem.getData();
 
     boolean isRemoved = remove(editor);
-    if (isRemoved) {
+    // Skip during bulk close (project/environment switch): the open-files 
list was saved before
+    // closeAllFiles; writing here would overwrite it with whatever is left 
(issue #7692).
+    //
+    if (isRemoved && !hopGui.fileDelegate.isClosing()) {
       hopGui.auditDelegate.writeLastOpenFiles();
     }
     if (!isRemoved && event != null) {

Reply via email to