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 5ff6cea743 tab name update #6354 (#6367)
5ff6cea743 is described below
commit 5ff6cea7435e834bc85e4101364d5ba3810a9add
Author: Bart Maertens <[email protected]>
AuthorDate: Wed Jan 14 07:00:24 2026 +0000
tab name update #6354 (#6367)
* add support for HTML and PDF files in Hop Gui. #6354
* i18n updates. #6354
* improved tab names for html files. #6354
* tab name updates. #6354
---
.../transforms/types/HtmlExplorerFileType.java | 3 +-
.../types/HtmlExplorerFileTypeHandler.java | 69 ++++++++++++
.../perspective/explorer/ExplorerPerspective.java | 123 ++++++++++++++++++++-
3 files changed, 192 insertions(+), 3 deletions(-)
diff --git
a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/HtmlExplorerFileType.java
b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/HtmlExplorerFileType.java
index 3addf9545b..fd75d07a8a 100644
---
a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/HtmlExplorerFileType.java
+++
b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/HtmlExplorerFileType.java
@@ -70,9 +70,10 @@ public class HtmlExplorerFileType extends
BaseExplorerFileType<HtmlExplorerFileT
if (resolvedFilename.toLowerCase().startsWith("http://")
|| resolvedFilename.toLowerCase().startsWith("https://")) {
// Create handler without VFS checks for URLs
+ // The tab title will be extracted by
ExplorerPerspective.getTabDisplayName()
//
ExplorerFile explorerFile = new ExplorerFile();
- explorerFile.setName(resolvedFilename);
+ explorerFile.setName(resolvedFilename); // Will be shortened by tab
display logic
explorerFile.setFilename(resolvedFilename);
explorerFile.setFileType(this);
diff --git
a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/HtmlExplorerFileTypeHandler.java
b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/HtmlExplorerFileTypeHandler.java
index b408cea05e..7b766736c0 100644
---
a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/HtmlExplorerFileTypeHandler.java
+++
b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/types/HtmlExplorerFileTypeHandler.java
@@ -32,6 +32,8 @@ import
org.apache.hop.ui.hopgui.perspective.explorer.ExplorerPerspective;
import
org.apache.hop.ui.hopgui.perspective.explorer.file.types.base.BaseExplorerFileTypeHandler;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.ProgressEvent;
+import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Composite;
@@ -60,6 +62,21 @@ public class HtmlExplorerFileTypeHandler extends
BaseExplorerFileTypeHandler {
fdBrowser.bottom = new FormAttachment(100, 0);
wBrowser.setLayoutData(fdBrowser);
+ // Add a progress listener to update tab title when page finishes loading
+ wBrowser.addProgressListener(
+ new ProgressListener() {
+ @Override
+ public void changed(ProgressEvent event) {
+ // Progress changed
+ }
+
+ @Override
+ public void completed(ProgressEvent event) {
+ // Page finished loading, try to update tab title from HTML page
title
+ updateTitleFromPageTitle();
+ }
+ });
+
reload();
}
@@ -138,6 +155,11 @@ public class HtmlExplorerFileTypeHandler extends
BaseExplorerFileTypeHandler {
if (filename.toLowerCase().startsWith("http://")
|| filename.toLowerCase().startsWith("https://")) {
wBrowser.setUrl(filename);
+
+ // Try to update the tab title after the page loads
+ // This is done asynchronously since the page needs to load first
+ updateTitleFromPageTitle();
+
clearChanged();
return;
}
@@ -183,4 +205,51 @@ public class HtmlExplorerFileTypeHandler extends
BaseExplorerFileTypeHandler {
// null);");
// For now, do nothing
}
+
+ /**
+ * Attempt to update the tab title from the HTML page title after the page
loads. This runs
+ * asynchronously since the page needs time to load.
+ */
+ private void updateTitleFromPageTitle() {
+ if (wBrowser == null || wBrowser.isDisposed()) {
+ return;
+ }
+
+ // Use a timer to wait a bit for the page to fully render, then extract
the title
+ hopGui
+ .getDisplay()
+ .timerExec(
+ 500,
+ () -> {
+ if (wBrowser == null || wBrowser.isDisposed()) {
+ return;
+ }
+ try {
+ // Try to get the page title via JavaScript
+ Object result = wBrowser.evaluate("return document.title;");
+
+ if (result != null) {
+ String pageTitle = result.toString();
+
+ if (pageTitle != null && !pageTitle.isEmpty() &&
!pageTitle.equals("null")) {
+ // Limit title length to 30 characters for tab display
+ String shortTitle = pageTitle;
+ if (shortTitle.length() > 30) {
+ shortTitle = shortTitle.substring(0, 27) + "...";
+ }
+
+ // Update the name - ExplorerPerspective will handle the
tab display
+ if (!shortTitle.equals(explorerFile.getName())) {
+ explorerFile.setName(shortTitle);
+ // Update the tab to reflect the new name
+ perspective.updateTabItem(this);
+ }
+ }
+ }
+ } catch (Exception e) {
+ // Silently fail - the initial title from URL extraction is
fine
+ LogChannel.UI.logDebug("Could not extract page title for tab:
" + e.getMessage());
+ }
+ });
+ }
}
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 cb4ba4a9e0..f29f7f33e8 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
@@ -1112,7 +1112,8 @@ public class ExplorerPerspective implements
IHopPerspective, TabClosable {
//
CTabItem tabItem = new CTabItem(tabFolder, SWT.CLOSE);
tabItem.setFont(GuiResource.getInstance().getFontDefault());
- tabItem.setText(Const.NVL(fileTypeHandler.getName(), ""));
+ String displayName = getTabDisplayName(fileTypeHandler);
+ tabItem.setText(Const.NVL(displayName, ""));
tabItem.setToolTipText(Const.NVL(fileTypeHandler.getFilename(), ""));
tabItem.setImage(getFileTypeImage(fileTypeHandler.getFileType()));
tabItem.setData(fileTypeHandler);
@@ -2025,7 +2026,8 @@ public class ExplorerPerspective implements
IHopPerspective, TabClosable {
if (tabItemHandler != null) {
CTabItem tabItem = tabItemHandler.getTabItem();
if (!tabItem.isDisposed()) {
- tabItem.setText(Const.NVL(fileTypeHandler.getName(), "<>"));
+ String displayName = getTabDisplayName(fileTypeHandler);
+ tabItem.setText(Const.NVL(displayName, "<>"));
tabItem.setToolTipText(Const.NVL(fileTypeHandler.getFilename(), ""));
Font font =
fileTypeHandler.hasChanged()
@@ -2036,6 +2038,123 @@ public class ExplorerPerspective implements
IHopPerspective, TabClosable {
}
}
+ /**
+ * Get a display name for a tab, extracting a short title from URLs if
needed.
+ *
+ * @param fileTypeHandler The file type handler
+ * @return A short display name (max 30 characters for URLs)
+ */
+ private String getTabDisplayName(IHopFileTypeHandler fileTypeHandler) {
+ String name = fileTypeHandler.getName();
+ String filename = fileTypeHandler.getFilename();
+
+ // If the filename is a URL and the name is the full URL or very long,
extract a better title
+ if (filename != null
+ && (filename.toLowerCase().startsWith("http://")
+ || filename.toLowerCase().startsWith("https://"))) {
+ // If name is the URL or longer than 30 chars, extract a better title
+ if (name == null || name.equals(filename) || name.length() > 30) {
+ return extractTitleFromUrl(filename);
+ }
+ }
+
+ return name;
+ }
+
+ /**
+ * Extract a meaningful title from a URL for use as a tab name.
+ *
+ * @param url The URL to extract a title from
+ * @return A short, meaningful title (max 30 characters)
+ */
+ private String extractTitleFromUrl(String url) {
+ try {
+ // Remove protocol and query parameters
+ String path = url;
+ if (path.contains("?")) {
+ path = path.substring(0, path.indexOf("?"));
+ }
+ if (path.contains("#")) {
+ path = path.substring(0, path.indexOf("#"));
+ }
+
+ // Extract the last meaningful part of the path
+ // e.g.,
"https://hop.apache.org/manual/latest/pipelines/transforms/data-grid.html"
+ // becomes "Data Grid"
+ String[] parts = path.split("/");
+ String lastPart = "";
+ for (int i = parts.length - 1; i >= 0; i--) {
+ if (!parts[i].isEmpty() && !parts[i].equals("manual") &&
!parts[i].equals("latest")) {
+ lastPart = parts[i];
+ break;
+ }
+ }
+
+ // Remove file extension and decode
+ if (lastPart.endsWith(".html") || lastPart.endsWith(".htm")) {
+ lastPart = lastPart.substring(0, lastPart.lastIndexOf("."));
+ }
+
+ // Convert kebab-case, snake_case, or camelCase to Title Case
+ // e.g., "data-grid" -> "Data Grid", "data_grid" -> "Data Grid"
+ String title = lastPart.replaceAll("[-_]", " ");
+ title = title.replaceAll("([a-z])([A-Z])", "$1 $2"); // camelCase
+
+ // Capitalize words
+ String[] words = title.split("\\s+");
+ StringBuilder result = new StringBuilder();
+ for (String word : words) {
+ if (word.length() > 0) {
+ if (result.length() > 0) {
+ result.append(" ");
+ }
+ result.append(word.substring(0, 1).toUpperCase());
+ if (word.length() > 1) {
+ result.append(word.substring(1).toLowerCase());
+ }
+ }
+ }
+ title = result.toString();
+
+ // If we got a meaningful title, use it (limit to 30 chars)
+ if (!title.isEmpty() && title.length() <= 30) {
+ return title;
+ }
+
+ // Fallback: show domain + last part (truncated to 30 chars)
+ if (title.length() > 30) {
+ title = title.substring(0, 27) + "...";
+ }
+
+ // If still no good title, use smart truncation of the full URL
+ if (title.isEmpty() || title.length() < 5) {
+ // Show domain and last path segment
+ int domainEnd = path.indexOf("/", 8); // After "https://"
+ if (domainEnd > 0 && domainEnd < path.length() - 1) {
+ String domain = path.substring(0, domainEnd);
+ String pathPart = path.substring(domainEnd);
+ if (pathPart.length() > 20) {
+ pathPart = "..." + pathPart.substring(pathPart.length() - 17);
+ }
+ title = domain + pathPart;
+ } else {
+ title = path;
+ }
+ if (title.length() > 30) {
+ title = title.substring(0, 27) + "...";
+ }
+ }
+
+ return title;
+ } catch (Exception e) {
+ // Fallback to simple truncation if anything goes wrong
+ if (url.length() > 30) {
+ return url.substring(0, 27) + "...";
+ }
+ return url;
+ }
+ }
+
/** Update tree item */
public void updateTreeItem(IHopFileTypeHandler fileTypeHandler) {
// If no filename, no need to update the tree item