From c71032ff5182b50dd70bd3389d173b84941f7b39 Mon Sep 17 00:00:00 2001 From: Trigam <142107083+TrigamDev@users.noreply.github.com> Date: Thu, 7 Aug 2025 15:29:09 -0400 Subject: [PATCH] feat(ui): clickable links in text fields (#924) * feat: links in text fields are clickable * style: fix linting errors * style: remove unnecessary comment * feat: better url pattern * chore: disable Ruff error * style: add trailing line * style: maybe format it? that'd be smart * ui: chance text_label from RichText to Markdown --------- Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com> --- src/tagstudio/qt/widgets/text.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/tagstudio/qt/widgets/text.py b/src/tagstudio/qt/widgets/text.py index 90b3008e..aa6fcff3 100644 --- a/src/tagstudio/qt/widgets/text.py +++ b/src/tagstudio/qt/widgets/text.py @@ -3,6 +3,8 @@ # Created for TagStudio: https://github.com/CyanVoxel/TagStudio +import re + from PySide6.QtCore import Qt from PySide6.QtWidgets import QHBoxLayout, QLabel @@ -19,9 +21,25 @@ class TextWidget(FieldWidget): self.text_label = QLabel() self.text_label.setStyleSheet("font-size: 12px") self.text_label.setWordWrap(True) - self.text_label.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse) + self.text_label.setTextFormat(Qt.TextFormat.MarkdownText) + self.text_label.setOpenExternalLinks(True) + self.text_label.setTextInteractionFlags(Qt.TextInteractionFlag.TextBrowserInteraction) self.base_layout.addWidget(self.text_label) self.set_text(text) def set_text(self, text: str): + text = linkify(text) self.text_label.setText(text) + + +# Regex from https://stackoverflow.com/a/6041965 +def linkify(text: str): + url_pattern = ( + r"(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-*]*[\w@?^=%&\/~+#-*])" + ) + return re.sub( + url_pattern, + lambda url: f'{url.group(0)}', + text, + flags=re.IGNORECASE, + )