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 f7f1642057 Highlight error and warn lines in logging pannel, fixes 
#6245 (#6280)
f7f1642057 is described below

commit f7f1642057d91560ca224f3e9234ffc68ae96cd9
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Thu Jan 1 11:38:09 2026 +0100

    Highlight error and warn lines in logging pannel, fixes #6245 (#6280)
    
    * Highlight error and warn lines in logging pannel, fixes #6245
    
    * spotless fix
---
 .../hop/ui/core/widget/LogStyledTextComp.java      | 43 +++++++++++
 .../hop/ui/core/widget/highlight/LogHighlight.java | 88 ++++++++++++++++++++++
 .../ui/hopgui/file/pipeline/HopGuiLogBrowser.java  | 35 +++++----
 .../delegates/HopGuiPipelineLogDelegate.java       | 42 +++++++----
 .../ui/hopgui/file/shared/LogStyledTextWidget.java | 32 ++++++++
 .../apache/hop/ui/hopgui/file/shared/TextZoom.java | 45 ++++++++++-
 .../delegates/HopGuiWorkflowLogDelegate.java       | 48 +++++++-----
 .../hop/ui/core/widget/text/TextFormatterTest.java | 16 ++--
 8 files changed, 293 insertions(+), 56 deletions(-)

diff --git 
a/ui/src/main/java/org/apache/hop/ui/core/widget/LogStyledTextComp.java 
b/ui/src/main/java/org/apache/hop/ui/core/widget/LogStyledTextComp.java
new file mode 100644
index 0000000000..e6675f5d54
--- /dev/null
+++ b/ui/src/main/java/org/apache/hop/ui/core/widget/LogStyledTextComp.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.ui.core.widget;
+
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.ui.core.widget.highlight.LogHighlight;
+import org.apache.hop.ui.util.EnvironmentUtils;
+import org.eclipse.swt.widgets.Composite;
+
+public class LogStyledTextComp extends StyledTextVar {
+  public LogStyledTextComp(IVariables variables, Composite parent, int style) {
+    super(variables, parent, style, false, false);
+  }
+
+  @Override
+  public void addLineStyleListener() {
+    // Only add highlighting in SWT mode (RWT doesn't have StyledText)
+    if (!EnvironmentUtils.getInstance().isWeb()) {
+      addLineStyleListener(new LogHighlight());
+    }
+  }
+
+  @Override
+  public void addLineStyleListener(java.util.List<String> keywords) {
+    // Log highlighting doesn't use keywords, just use default
+    addLineStyleListener();
+  }
+}
diff --git 
a/ui/src/main/java/org/apache/hop/ui/core/widget/highlight/LogHighlight.java 
b/ui/src/main/java/org/apache/hop/ui/core/widget/highlight/LogHighlight.java
new file mode 100644
index 0000000000..b53b802742
--- /dev/null
+++ b/ui/src/main/java/org/apache/hop/ui/core/widget/highlight/LogHighlight.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.ui.core.widget.highlight;
+
+import org.apache.hop.ui.core.gui.GuiResource;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.LineStyleEvent;
+import org.eclipse.swt.custom.LineStyleListener;
+import org.eclipse.swt.custom.StyleRange;
+
+public class LogHighlight implements LineStyleListener {
+  private static final String[] ERROR_KEYWORDS = {"ERROR", "EXCEPTION", 
"FATAL", "SEVERE"};
+  private static final String[] WARNING_KEYWORDS = {"WARN", "WARNING", 
"CAUTION"};
+
+  private StyleAttribute errorStyle;
+  private StyleAttribute warningStyle;
+
+  public LogHighlight() {
+    initializeStyles();
+  }
+
+  void initializeStyles() {
+    GuiResource resource = GuiResource.getInstance();
+    // Red color for errors
+    errorStyle = new StyleAttribute(GuiResource.getInstance().getColorRed(), 
SWT.NORMAL);
+    // Orange/Yellow color for warnings
+    warningStyle = new 
StyleAttribute(GuiResource.getInstance().getColorOrange(), SWT.NORMAL);
+  }
+
+  @Override
+  public void lineGetStyle(LineStyleEvent event) {
+    String lineText = event.lineText;
+    if (lineText == null || lineText.isEmpty()) {
+      event.styles = new StyleRange[0];
+      return;
+    }
+
+    String upperLine = lineText.toUpperCase();
+
+    // Check for error keywords
+    for (String keyword : ERROR_KEYWORDS) {
+      if (upperLine.contains(keyword)) {
+        StyleRange styleRange =
+            new StyleRange(
+                event.lineOffset,
+                lineText.length(),
+                errorStyle.getForeground(),
+                null,
+                errorStyle.getStyle());
+        event.styles = new StyleRange[] {styleRange};
+        return;
+      }
+    }
+
+    // Check for warning keywords
+    for (String keyword : WARNING_KEYWORDS) {
+      if (upperLine.contains(keyword)) {
+        StyleRange styleRange =
+            new StyleRange(
+                event.lineOffset,
+                lineText.length(),
+                warningStyle.getForeground(),
+                null,
+                warningStyle.getStyle());
+        event.styles = new StyleRange[] {styleRange};
+        return;
+      }
+    }
+
+    // No highlighting needed
+    event.styles = new StyleRange[0];
+  }
+}
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiLogBrowser.java 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiLogBrowser.java
index 432e0ad340..a5976a99b4 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiLogBrowser.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/HopGuiLogBrowser.java
@@ -42,10 +42,8 @@ import org.apache.hop.core.variables.DescribedVariable;
 import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.ConstUi;
 import org.apache.hop.ui.core.gui.GuiResource;
-import org.apache.hop.ui.core.widget.text.Format;
-import org.apache.hop.ui.core.widget.text.TextFormatter;
+import org.apache.hop.ui.core.widget.TextComposite;
 import org.apache.hop.ui.hopgui.HopGui;
-import org.apache.hop.ui.util.EnvironmentUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.MouseAdapter;
 import org.eclipse.swt.events.MouseEvent;
@@ -53,18 +51,17 @@ import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
-import org.eclipse.swt.widgets.Text;
 
 public class HopGuiLogBrowser {
   private static final Class<?> PKG = HopGui.class;
 
-  @Getter private Text text;
+  @Getter private TextComposite text;
   @Getter private ILogParentProvided logProvider;
   private List<String> childIds = new ArrayList<>();
   private Date lastLogRegistryChange;
   private AtomicBoolean paused;
 
-  public HopGuiLogBrowser(final Text text, final ILogParentProvided 
logProvider) {
+  public HopGuiLogBrowser(final TextComposite text, final ILogParentProvided 
logProvider) {
     this.text = text;
     this.logProvider = logProvider;
     this.paused = new AtomicBoolean(false);
@@ -146,30 +143,36 @@ public class HopGuiLogBrowser {
                                 int length = line.length();
 
                                 if (length > 0) {
-                                  Format format = 
TextFormatter.getInstance().execute(line);
-                                  text.append(format.getText());
-                                  text.append(Const.CR);
+                                  // Append by inserting at end
+                                  String currentText = text.getText();
+                                  text.setText(currentText + line + Const.CR);
                                 }
                               }
                             }
 
                             // Erase it all in one go
                             // This makes it a bit more efficient
-                            // getLineCount is not supported in RAP
+                            String textContent = text.getText();
+                            // Calculate line count
                             int size;
-                            if (!EnvironmentUtils.getInstance().isWeb()) {
-                              size = text.getLineCount();
+                            if (textContent == null || textContent.isEmpty()) {
+                              size = 0;
                             } else {
-                              size = text.getText().length();
+                              size = 1;
+                              for (int i = 0; i < textContent.length(); i++) {
+                                if (textContent.charAt(i) == '\n') {
+                                  size++;
+                                }
+                              }
                             }
 
                             if (maxSize > 0 && size > maxSize) {
                               int dropIndex =
-                                  
StringUtils.lastOrdinalIndexOf(text.getText(), "\n", maxSize + 1);
-                              text.setText(text.getText().substring(dropIndex 
+ 1));
+                                  StringUtils.lastOrdinalIndexOf(textContent, 
"\n", maxSize + 1);
+                              text.setText(textContent.substring(dropIndex + 
1));
                             }
 
-                            text.setSelection(text.getText().length());
+                            text.setSelection(text.getCharCount());
                             lastLogId.set(lastNr);
                           }
                         }
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineLogDelegate.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineLogDelegate.java
index 90b13c6d8c..7ab4fee70b 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineLogDelegate.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineLogDelegate.java
@@ -33,19 +33,22 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.gui.GuiToolbarWidgets;
+import org.apache.hop.ui.core.widget.LogStyledTextComp;
 import org.apache.hop.ui.core.widget.OsHelper;
+import org.apache.hop.ui.core.widget.StyledTextComp;
+import org.apache.hop.ui.core.widget.TextComposite;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.apache.hop.ui.hopgui.file.IHopFileTypeHandler;
 import org.apache.hop.ui.hopgui.file.pipeline.HopGuiLogBrowser;
 import org.apache.hop.ui.hopgui.file.pipeline.HopGuiPipelineGraph;
 import org.apache.hop.ui.hopgui.file.shared.TextZoom;
+import org.apache.hop.ui.util.EnvironmentUtils;
 import org.eclipse.swt.SWT;
 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.Text;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
 
@@ -69,7 +72,7 @@ public class HopGuiPipelineLogDelegate {
 
   @Getter private CTabItem pipelineLogTab;
 
-  private Text pipelineLogText;
+  private TextComposite pipelineLogText;
   private TextZoom textZoom;
 
   private ToolBar toolbar;
@@ -113,10 +116,23 @@ public class HopGuiPipelineLogDelegate {
     fd.right = new FormAttachment(100, 0);
     toolbar.setLayoutData(fd);
 
-    pipelineLogText =
-        new Text(
-            pipelineLogComposite,
-            SWT.READ_ONLY | SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | 
SWT.H_SCROLL);
+    // Use StyledTextComp for web (uses Text widget), LogStyledTextComp for 
desktop (with
+    // highlighting)
+    if (EnvironmentUtils.getInstance().isWeb()) {
+      pipelineLogText =
+          new StyledTextComp(
+              pipelineGraph.getVariables(),
+              pipelineLogComposite,
+              SWT.READ_ONLY | SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | 
SWT.H_SCROLL);
+    } else {
+      pipelineLogText =
+          new LogStyledTextComp(
+              pipelineGraph.getVariables(),
+              pipelineLogComposite,
+              SWT.READ_ONLY | SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | 
SWT.H_SCROLL);
+      // Add log highlighting (only works in SWT, not RWT)
+      pipelineLogText.addLineStyleListener();
+    }
     PropsUi.setLook(pipelineLogText);
     FormData fdText = new FormData();
     fdText.left = new FormAttachment(0, 0);
@@ -196,11 +212,8 @@ public class HopGuiPipelineLogDelegate {
   public void clearLog() {
     if (pipelineLogText != null && !pipelineLogText.isDisposed()) {
       // add a CR to avoid fontStyle from getting lost on macos HOP-2583
-      if (OsHelper.isMac()) {
-        pipelineLogText.setText(Const.CR);
-      } else {
-        pipelineLogText.setText("");
-      }
+      String textToSet = OsHelper.isMac() ? Const.CR : "";
+      pipelineLogText.setText(textToSet);
     }
     Map<String, String> transformLogMap = pipelineGraph.getTransformLogMap();
     if (transformLogMap != null) {
@@ -345,9 +358,10 @@ public class HopGuiPipelineLogDelegate {
   }
 
   public boolean hasSelectedText() {
-    return pipelineLogText != null
-        && !pipelineLogText.isDisposed()
-        && StringUtils.isNotEmpty(pipelineLogText.getSelectionText());
+    if (pipelineLogText == null || pipelineLogText.isDisposed()) {
+      return false;
+    }
+    return StringUtils.isNotEmpty(pipelineLogText.getSelectionText());
   }
 
   public void copySelected() {
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/shared/LogStyledTextWidget.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/shared/LogStyledTextWidget.java
new file mode 100644
index 0000000000..65ff1ccdaa
--- /dev/null
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/shared/LogStyledTextWidget.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.ui.hopgui.file.shared;
+
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * Factory class to create StyledText widgets. This class should only be 
loaded in desktop mode, not
+ * in web/RAP mode.
+ */
+public class LogStyledTextWidget {
+  public static Control createStyledText(Composite parent, int style) {
+    return new StyledText(parent, style);
+  }
+}
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/shared/TextZoom.java 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/shared/TextZoom.java
index a9df64417d..c603f380f8 100644
--- a/ui/src/main/java/org/apache/hop/ui/hopgui/file/shared/TextZoom.java
+++ b/ui/src/main/java/org/apache/hop/ui/hopgui/file/shared/TextZoom.java
@@ -17,28 +17,67 @@
 
 package org.apache.hop.ui.hopgui.file.shared;
 
+import org.apache.hop.ui.core.widget.TextComposite;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Text;
 
+/**
+ * Utility class to handle font zooming for text widgets. Supports both Text 
and StyledText widgets
+ * for RAP/RWT compatibility.
+ */
 public class TextZoom {
   public static final int STEP_DEFAULT = 1;
   public static final int MIN_HEIGHT = 4;
 
-  private Text widget;
+  private Control widget;
   private Font font;
   private int step;
   private int minHeight;
 
   public TextZoom(Text widget, Font font) {
-    this(widget, font, TextZoom.STEP_DEFAULT);
+    this.widget = (Control) widget;
+    this.font = font;
+    this.step = TextZoom.STEP_DEFAULT;
+    this.minHeight = MIN_HEIGHT;
   }
 
   public TextZoom(Text widget, Font font, int step) {
-    this(widget, font, step, MIN_HEIGHT);
+    this.widget = (Control) widget;
+    this.font = font;
+    this.step = step;
+    this.minHeight = MIN_HEIGHT;
   }
 
   public TextZoom(Text widget, Font font, int step, int minHeight) {
+    this.widget = (Control) widget;
+    this.font = font;
+    this.step = step;
+    this.minHeight = minHeight;
+  }
+
+  /**
+   * Constructor that accepts TextComposite (works for both Text and 
StyledText without direct
+   * StyledText dependency).
+   */
+  public TextZoom(TextComposite widget, Font font) {
+    this.widget = widget;
+    this.font = font;
+    this.step = TextZoom.STEP_DEFAULT;
+    this.minHeight = MIN_HEIGHT;
+  }
+
+  /** Constructor that accepts TextComposite with custom step. */
+  public TextZoom(TextComposite widget, Font font, int step) {
+    this.widget = widget;
+    this.font = font;
+    this.step = step;
+    this.minHeight = MIN_HEIGHT;
+  }
+
+  /** Constructor that accepts TextComposite with custom step and minHeight. */
+  public TextZoom(TextComposite widget, Font font, int step, int minHeight) {
     this.widget = widget;
     this.font = font;
     this.step = step;
diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/delegates/HopGuiWorkflowLogDelegate.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/delegates/HopGuiWorkflowLogDelegate.java
index 6b8b34149b..a71f88f659 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/delegates/HopGuiWorkflowLogDelegate.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/file/workflow/delegates/HopGuiWorkflowLogDelegate.java
@@ -29,12 +29,16 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.gui.GuiToolbarWidgets;
+import org.apache.hop.ui.core.widget.LogStyledTextComp;
 import org.apache.hop.ui.core.widget.OsHelper;
+import org.apache.hop.ui.core.widget.StyledTextComp;
+import org.apache.hop.ui.core.widget.TextComposite;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.apache.hop.ui.hopgui.file.IHopFileTypeHandler;
 import org.apache.hop.ui.hopgui.file.pipeline.HopGuiLogBrowser;
 import org.apache.hop.ui.hopgui.file.shared.TextZoom;
 import org.apache.hop.ui.hopgui.file.workflow.HopGuiWorkflowGraph;
+import org.apache.hop.ui.util.EnvironmentUtils;
 import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.action.ActionMeta;
 import org.eclipse.swt.SWT;
@@ -43,8 +47,6 @@ 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.Text;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
 
@@ -67,7 +69,7 @@ public class HopGuiWorkflowLogDelegate {
 
   private CTabItem workflowLogTab;
 
-  private Text workflowLogText;
+  private TextComposite workflowLogText;
   private TextZoom textZoom;
 
   /** The number of lines in the log tab */
@@ -115,15 +117,28 @@ public class HopGuiWorkflowLogDelegate {
     fd.right = new FormAttachment(100, 0);
     toolbar.setLayoutData(fd);
 
-    workflowLogText =
-        new Text(
-            workflowLogComposite,
-            SWT.READ_ONLY | SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | 
SWT.H_SCROLL);
+    // Use StyledTextComp for web (uses Text widget), LogStyledTextComp for 
desktop (with
+    // highlighting)
+    if (EnvironmentUtils.getInstance().isWeb()) {
+      workflowLogText =
+          new StyledTextComp(
+              workflowGraph.getVariables(),
+              workflowLogComposite,
+              SWT.READ_ONLY | SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | 
SWT.H_SCROLL);
+    } else {
+      workflowLogText =
+          new LogStyledTextComp(
+              workflowGraph.getVariables(),
+              workflowLogComposite,
+              SWT.READ_ONLY | SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | 
SWT.H_SCROLL);
+      // Add log highlighting (only works in SWT, not RWT)
+      workflowLogText.addLineStyleListener();
+    }
     PropsUi.setLook(workflowLogText);
     FormData fdText = new FormData();
     fdText.left = new FormAttachment(0, 0);
     fdText.right = new FormAttachment(100, 0);
-    fdText.top = new FormAttachment((Control) toolbar, 0);
+    fdText.top = new FormAttachment(toolbar, 0);
     fdText.bottom = new FormAttachment(100, 0);
     workflowLogText.setLayoutData(fdText);
 
@@ -188,11 +203,8 @@ public class HopGuiWorkflowLogDelegate {
   public void clearLog() {
     if (workflowLogText != null && !workflowLogText.isDisposed()) {
       // add a CR to avoid fontStyle from getting lost on macos HOP-2583
-      if (OsHelper.isMac()) {
-        workflowLogText.setText(Const.CR);
-      } else {
-        workflowLogText.setText("");
-      }
+      String textToSet = OsHelper.isMac() ? Const.CR : "";
+      workflowLogText.setText(textToSet);
     }
   }
 
@@ -202,7 +214,8 @@ public class HopGuiWorkflowLogDelegate {
       toolTip = 
"i18n:org.apache.hop.ui.hopgui:WorkflowLog.Button.LogCopyToClipboard",
       image = "ui/images/copy.svg")
   public void copyToClipboard() {
-    GuiResource.getInstance().toClipboard(workflowLogText.getText());
+    String text = workflowLogText.getText();
+    GuiResource.getInstance().toClipboard(text);
   }
 
   @GuiToolbarElement(
@@ -324,9 +337,10 @@ public class HopGuiWorkflowLogDelegate {
   }
 
   public boolean hasSelectedText() {
-    return workflowLogText != null
-        && !workflowLogText.isDisposed()
-        && StringUtils.isNotEmpty(workflowLogText.getSelectionText());
+    if (workflowLogText == null || workflowLogText.isDisposed()) {
+      return false;
+    }
+    return StringUtils.isNotEmpty(workflowLogText.getSelectionText());
   }
 
   public void copySelected() {
diff --git 
a/ui/src/test/java/org/apache/hop/ui/core/widget/text/TextFormatterTest.java 
b/ui/src/test/java/org/apache/hop/ui/core/widget/text/TextFormatterTest.java
index 312849e36c..eec082ffba 100644
--- a/ui/src/test/java/org/apache/hop/ui/core/widget/text/TextFormatterTest.java
+++ b/ui/src/test/java/org/apache/hop/ui/core/widget/text/TextFormatterTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.hop.ui.core.widget.text;
 
+import org.eclipse.swt.custom.StyleRange;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -33,11 +34,14 @@ public class TextFormatterTest {
     Assert.assertEquals(
         "This has one this is the first value this is the second value", 
format.getText());
     Assert.assertEquals(2, format.getStyleRanges().size());
-    Assert.assertEquals(
-        "http://www.example.com/page/index.html?query=test1";, 
format.getStyleRanges().get(0).data);
-    Assert.assertEquals(
-        "http://www.example.com/page/index.html?query=test2";, 
format.getStyleRanges().get(1).data);
-    Assert.assertEquals(13, format.getStyleRanges().get(0).start);
-    Assert.assertEquals(37, format.getStyleRanges().get(1).start);
+
+    // Cast Object to StyleRange to access properties
+    StyleRange styleRange0 = (StyleRange) format.getStyleRanges().get(0);
+    StyleRange styleRange1 = (StyleRange) format.getStyleRanges().get(1);
+
+    Assert.assertEquals("http://www.example.com/page/index.html?query=test1";, 
styleRange0.data);
+    Assert.assertEquals("http://www.example.com/page/index.html?query=test2";, 
styleRange1.data);
+    Assert.assertEquals(13, styleRange0.start);
+    Assert.assertEquals(37, styleRange1.start);
   }
 }

Reply via email to