This is an automated email from the ASF dual-hosted git repository.
mattcasters 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 6e13af56a5 Fix pipeline marked dirty after opening a transform dialog
and clicking OK without changes (#7428)
6e13af56a5 is described below
commit 6e13af56a50ce4313bf4ebe848e53ed02e2a9d43
Author: Lance <[email protected]>
AuthorDate: Sun Jul 5 05:51:35 2026 +0800
Fix pipeline marked dirty after opening a transform dialog and clicking OK
without changes (#7428)
Signed-off-by: lance <[email protected]>
---
.../delegates/HopGuiPipelineTransformDelegate.java | 92 ++++++++++++++--------
1 file changed, 61 insertions(+), 31 deletions(-)
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineTransformDelegate.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineTransformDelegate.java
index c15dcf3d6d..a33e6e0164 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineTransformDelegate.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineTransformDelegate.java
@@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.hop.core.Const;
import org.apache.hop.core.exception.HopException;
import org.apache.hop.core.extension.ExtensionPointHandler;
import org.apache.hop.core.extension.HopExtensionPoint;
@@ -193,22 +194,21 @@ public class HopGuiPipelineTransformDelegate {
return null;
}
- // Before we do anything, let's store the situation the way it
- // was...
- //
- TransformMeta before = (TransformMeta) transformMeta.clone();
dialog = getTransformDialog(transformMeta.getTransform(), pipelineMeta,
name);
+ TransformMeta before = null;
if (dialog != null) {
dialogs.put(name, dialog);
dialog.setMetadataProvider(hopGui.getMetadataProvider());
transformMeta.getTransform().convertIOMetaToTransformNames();
+ // Snapshot after IO-meta normalization so OK-without-edits is not
treated as a change.
+ before = (TransformMeta) transformMeta.clone();
transformName = dialog.open();
dialogs.remove(name);
}
- if (!Utils.isEmpty(transformName)) {
+ if (!Utils.isEmpty(transformName) && before != null) {
// Force the recreation of the transform IO metadata object. (cached
by default)
//
transformMeta.getTransform().resetTransformIoMeta();
@@ -227,11 +227,6 @@ public class HopGuiPipelineTransformDelegate {
//
transformMeta.getTransform().searchInfoAndTargetTransforms(pipelineMeta.getTransforms());
- // Mark the TransformMeta wrapper as changed since the dialog was
closed with OK
- // This ensures that changes are properly tracked regardless of inner
metadata object
- // identity
- transformMeta.setChanged();
-
//
// See if the new name the user enter, doesn't collide with
// another transform.
@@ -261,17 +256,17 @@ public class HopGuiPipelineTransformDelegate {
pipelineMeta.notifyAllListeners(transformMeta, newTransformMeta);
transformMeta.setName(transformName);
- //
- // OK, so the transform has changed...
- // Backup the situation for undo/redo
- //
TransformMeta after = (TransformMeta) transformMeta.clone();
-
- hopGui.undoDelegate.addUndoChange(
- pipelineMeta,
- new TransformMeta[] {before},
- new TransformMeta[] {after},
- new int[] {pipelineMeta.indexOfTransform(transformMeta)});
+ if (hasTransformMetaChanged(before, after)) {
+ transformMeta.setChanged();
+ hopGui.undoDelegate.addUndoChange(
+ pipelineMeta,
+ new TransformMeta[] {before},
+ new TransformMeta[] {after},
+ new int[] {pipelineMeta.indexOfTransform(transformMeta)});
+ } else {
+ transformMeta.setChanged(before.hasChanged());
+ }
}
pipelineGraph.updateGui();
@@ -603,16 +598,23 @@ public class HopGuiPipelineTransformDelegate {
return dialog.open();
});
}
- transformMeta.setChanged();
- hopGui.undoDelegate.addUndoChange(
- partitionSettings.getPipelineMeta(),
- new TransformMeta[] {partitionSettings.getBefore()},
- new TransformMeta[] {partitionSettings.getAfter()},
- new int[] {
- partitionSettings
- .getPipelineMeta()
- .indexOfTransform(partitionSettings.getTransformMeta())
- });
+
+ TransformMeta partitionBefore = partitionSettings.getBefore();
+ TransformMeta partitionAfter = partitionSettings.getAfter();
+ if (hasTransformMetaChanged(partitionBefore, partitionAfter)) {
+ transformMeta.setChanged();
+ hopGui.undoDelegate.addUndoChange(
+ partitionSettings.getPipelineMeta(),
+ new TransformMeta[] {partitionBefore},
+ new TransformMeta[] {partitionAfter},
+ new int[] {
+ partitionSettings
+ .getPipelineMeta()
+ .indexOfTransform(partitionSettings.getTransformMeta())
+ });
+ } else {
+ transformMeta.setChanged(partitionBefore.hasChanged());
+ }
pipelineGraph.redraw();
}
} catch (Exception e) {
@@ -677,6 +679,7 @@ public class HopGuiPipelineTransformDelegate {
List<TransformMeta> targetTransforms =
pipelineMeta.findNextTransforms(transformMeta, true);
// now edit this transformErrorMeta object:
+ TransformMeta before = (TransformMeta) transformMeta.clone();
TransformErrorMetaDialog dialog =
new TransformErrorMetaDialog(
hopGui.getActiveShell(),
@@ -686,12 +689,39 @@ public class HopGuiPipelineTransformDelegate {
targetTransforms);
if (dialog.open()) {
transformMeta.setTransformErrorMeta(transformErrorMeta);
- transformMeta.setChanged();
+ TransformMeta after = (TransformMeta) transformMeta.clone();
+ if (hasTransformMetaChanged(before, after)) {
+ transformMeta.setChanged();
+ } else {
+ transformMeta.setChanged(before.hasChanged());
+ }
pipelineGraph.redraw();
}
}
}
+ /**
+ * Returns {@code true} if two transform snapshots differ in persisted
configuration (transform
+ * body, partitioning, GUI placement, and error handling).
+ */
+ private static boolean hasTransformMetaChanged(TransformMeta before,
TransformMeta after) {
+ try {
+ if (!before.getXml().equals(after.getXml())) {
+ return true;
+ }
+
+ return !getErrorMetaXml(before).equals(getErrorMetaXml(after));
+ } catch (HopException e) {
+ // If comparison fails, treat as changed to avoid losing edits.
+ return true;
+ }
+ }
+
+ private static String getErrorMetaXml(TransformMeta transformMeta) throws
HopException {
+ TransformErrorMeta errorMeta = transformMeta.getTransformErrorMeta();
+ return errorMeta == null ? Const.EMPTY_STRING : errorMeta.getXml();
+ }
+
public void delTransforms(PipelineMeta pipelineMeta, List<TransformMeta>
transforms) {
if (Utils.isEmpty(transforms)) {
return; // nothing to do