import sys import random import base64 from PyQt6.QtWidgets import ( QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QTextEdit, QComboBox, QPushButton, QFrame, QListView ) from PyQt6.QtGui import QFont, QIcon, QPixmap, QPainter, QLinearGradient, QColor, QBrush, QPainterPath from PyQt6.QtCore import ( Qt, QSize, QPoint, QPointF, QRectF, QTimer, QPropertyAnimation, QEasingCurve, QSequentialAnimationGroup ) def create_char_map(start_normal, end_normal, start_special): """Helper function to create a character mapping.""" return {chr(ord(start_normal) + i): chr(start_special + i) for i in range(ord(end_normal) - ord(start_normal) + 1)} # --- Gradient Container Widget ---import sys import random import base64 import re # <-- Import regular expressions module from PyQt6.QtWidgets import ( QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QTextEdit, QComboBox, QPushButton, QFrame, QListView, QCheckBox # <-- Import QCheckBox ) from PyQt6.QtGui import QFont, QIcon, QPixmap, QPainter, QLinearGradient, QColor, QBrush, QPainterPath from PyQt6.QtCore import ( Qt, QSize, QPoint, QPointF, QRectF, QTimer, QPropertyAnimation, QEasingCurve, QSequentialAnimationGroup ) def create_char_map(start_normal, end_normal, start_special): """Helper function to create a character mapping.""" return {chr(ord(start_normal) + i): chr(start_special + i) for i in range(ord(end_normal) - ord(start_normal) + 1)} # --- Gradient Container Widget --- class GradientContainer(QWidget): """A custom widget that paints a gradient within rounded corners.""" def __init__(self, parent=None): super().__init__(parent) self.setObjectName("Container") def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(QPainter.RenderHint.Antialiasing) gradient = QLinearGradient(QPointF(0, 0), QPointF(self.width(), self.height())) gradient.setColorAt(0.0, QColor("#3730A3")) # Indigo gradient.setColorAt(1.0, QColor("#DB2777")) # Fuchsia path = QPainterPath() # The radius should match the stylesheet's border-radius path.addRoundedRect(QRectF(self.rect()), 12, 12) painter.fillPath(path, QBrush(gradient)) # --- Character Maps and Special Functions --- text_maps = { "Bold": {**create_char_map('A', 'Z', 0x1D400), **create_char_map('a', 'z', 0x1D41A), **create_char_map('0', '9', 0x1D7CE)},"Italic": {**create_char_map('A', 'Z', 0x1D434), **create_char_map('a', 'z', 0x1D44E)},"Bold Italic": {**create_char_map('A', 'Z', 0x1D468), **create_char_map('a', 'z', 0x1D482)},"Script": {'A': '๐’œ', 'B': 'โ„ฌ', 'C': '๐’ž', 'D': '๐’Ÿ', 'E': 'โ„ฐ', 'F': 'โ„ฑ', 'G': '๐’ข', 'H': 'โ„‹', 'I': 'โ„', 'J': '๐’ฅ', 'K': '๐’ฆ', 'L': 'โ„’', 'M': 'โ„ณ', 'N': '๐’ฉ', 'O': '๐’ช', 'P': '๐’ซ', 'Q': '๐’ฌ', 'R': 'โ„›', 'S': '๐’ฎ', 'T': '๐’ฏ', 'U': '๐’ฐ', 'V': '๐’ฑ', 'W': '๐’ฒ', 'X': '๐’ณ', 'Y': '๐’ด', 'Z': '๐’ต', 'a': '๐’ถ', 'b': '๐’ท', 'c': '๐’ธ', 'd': '๐’น', 'e': 'โ„ฏ', 'f': '๐’ป', 'g': 'โ„Š', 'h': '๐’ฝ', 'i': '๐’พ', 'j': '๐’ฟ', 'k': '๐“€', 'l': '๐“', 'm': '๐“‚', 'n': '๐“ƒ', 'o': 'โ„ด', 'p': '๐“…', 'q': '๐“†', 'r': '๐“‡', 's': '๐“ˆ', 't': '๐“‰', 'u': '๐“Š', 'v': '๐“‹', 'w': '๐“Œ', 'x': '๐“', 'y': '๐“Ž', 'z': '๐“'},"Bold Script": {**create_char_map('A', 'Z', 0x1D4D0), **create_char_map('a', 'z', 0x1D4EA)},"Fraktur": {'A': '๐”„', 'B': '๐”…', 'C': 'โ„ญ', 'D': '๐”‡', 'E': 'โ„ˆ', 'F': '๐”‰', 'G': '๐”Š', 'H': 'โ„Œ', 'I': 'โ„‘', 'J': '๐”', 'K': '๐”Ž', 'L': '๐”', 'M': '๐”', 'N': '๐”‘', 'O': '๐’ช', 'P': '๐”“', 'Q': '๐””', 'R': 'โ„œ', 'S': '๐”–', 'T': '๐”—', 'U': '๐”˜', 'V': '๐”™', 'W': '๐”š', 'X': '๐”›', 'Y': '๐”œ', 'Z': 'โ„จ', 'a': '๐”ž', 'b': '๐”Ÿ', 'c': '๐” ', 'd': '๐”ก', 'e': '๐”ข', 'f': '๐”ฃ', 'g': '๐”ค', 'h': '๐”ฅ', 'i': '๐”ฆ', 'j': '๐”ง', 'k': '๐”จ', 'l': '๐”ฉ', 'm': '๐”ช', 'n': '๐”ซ', 'o': '๐”ฌ', 'p': '๐”ญ', 'q': '๐”ฎ', 'r': '๐”ฏ', 's': '๐”ฐ', 't': '๐”ฑ', 'u': '๐“Š', 'v': '๐“‹', 'w': '๐”ด', 'x': '๐”ต', 'y': '๐”ถ', 'z': '๐”ท'},"Bold Fraktur": {**create_char_map('A', 'Z', 0x1D56C), **create_char_map('a', 'z', 0x1D586)},"Double-Struck": {**create_char_map('A', 'Z', 0x1D538), **create_char_map('a', 'z', 0x1D552), **create_char_map('0', '9', 0x1D7D8)},"Monospace": {**create_char_map('A', 'Z', 0x1D670), **create_char_map('a', 'z', 0x1D68A), **create_char_map('0', '9', 0x1D7F6)},"Full-Width": {**{chr(i): chr(i + 0xFEE0) for i in range(0x21, 0x7F)}, **{chr(0x20): chr(0x3000)}},"Circled": {**create_char_map('A', 'Z', 0x24B6), **create_char_map('a', 'z', 0x24D0), '0': 'โ“ช', **create_char_map('1', '9', 0x2460)},"Leetspeak": {'a': '4', 'A': '4', 'b': '8', 'B': '8', 'e': '3', 'E': '3', 'g': '6', 'G': '6', 'i': '1', 'I': '1', 'l': '1', 'L': '1', 'o': '0', 'O': '0', 's': '5', 'S': '5', 't': '7', 'T': '7', 'z': '2', 'Z': '2'},"Superscript": {'0': 'โฐ', '1': 'ยน', '2': 'ยฒ', '3': 'ยณ', '4': 'โด', '5': 'โต', '6': 'โถ', '7': 'โท', '8': 'โธ', '9': 'โน', 'a': 'แตƒ', 'b': 'แต‡', 'c': 'แถœ', 'd': 'แตˆ', 'e': 'แต‰', 'f': 'แถ ', 'g': 'แต', 'h': 'สฐ', 'i': 'โฑ', 'j': 'สฒ', 'k': 'แต', 'l': 'หก', 'm': 'แต', 'n': 'โฟ', 'o': 'แต’', 'p': 'แต–', 'r': 'สณ', 's': 'หข', 't': 'แต—', 'u': 'แต˜', 'v': 'แต›', 'w': 'สท', 'x': 'หฃ', 'y': 'สธ', 'z': 'แถป', '+': 'โบ', '-': 'โป', '=': 'โผ', '(': 'โฝ', ')': 'โพ'},"Subscript": {'0': 'โ‚€', '1': 'โ‚', '2': 'โ‚‚', '3': 'โ‚ƒ', '4': 'โ‚„', '5': 'โ‚…', '6': 'โ‚†', '7': 'โ‚‡', '8': 'โ‚ˆ', '9': 'โ‚‰', 'a': 'โ‚', 'e': 'โ‚‘', 'h': 'โ‚•', 'i': 'แตข', 'j': 'โฑผ', 'k': 'โ‚–', 'l': 'โ‚—', 'm': 'โ‚˜', 'n': 'โ‚™', 'o': 'โ‚’', 'p': 'โ‚š', 'r': 'แตฃ', 's': 'โ‚›', 't': 'โ‚œ', 'u': 'แตค', 'v': 'แตฅ', 'x': 'โ‚“', '+': 'โ‚Š', '-': 'โ‚‹', '=': 'โ‚Œ', '(': 'โ‚', ')': 'โ‚Ž'},"Morse Code": {'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----', ' ': '/', '.': '.-.-.-', ',': '--..--', '?': '..--..', "'": '.----.', '!': '-.-.--', '/': '-..-.', '(': '-.--.', ')': '-.--.-', '&': '.-...', ':': '---...', ';': '-.-.-.', '=': '-...-', '+': '.-.-.', '-': '-....-', '_': '..--.-', '"': '.-..-.', '$': '...-..-', '@': '.--.-.'},"Mirrored": {'a': 'ษ’', 'b': 'd', 'c': 'ษ”', 'd': 'b', 'e': 'ษ˜', 'f': 'แŽธ', 'g': 'วซ', 'h': 'ฮผ', 'i': 'i', 'j': '๊ž', 'k': 'สž', 'l': 'l', 'm': 'm', 'n': 'n', 'o': 'o', 'p': 'q', 'q': 'p', 'r': 'ษฟ', 's': 'ฦจ', 't': 'ฦš', 'u': 'u', 'v': 'v', 'w': 'w', 'x': 'x', 'y': 'ฮณ', 'z': 'z'} } def apply_zalgo(text): zalgo_chars = [chr(i) for i in range(0x0300, 0x036F)] return "".join(char + (''.join(random.choice(zalgo_chars) for _ in range(random.randint(1, 8))) if char.strip() else '') for char in text) def apply_combiner(text, combiner): return "".join(char + combiner for char in text) def reverse_text(text): return text[::-1] def spongebob_case(text): return "".join(char.lower() if random.random() < 0.5 else char.upper() for char in text) def vaporwave(text): return '\u3000'.join(text_maps["Full-Width"].get(char, char) for char in text) def clap_back(text): return " ๐Ÿ‘ ".join(text.split()) def regional_indicators(text): return "".join(chr(0x1F1E6 + (ord(char.upper()) - ord('A'))) if 'A' <= char.upper() <= 'Z' else char for char in text) def to_binary(text): return ' '.join(format(ord(char), '08b') for char in text) ICON_COPY_SVG = b'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNlNWU3ZmIiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cmVjdCB4PSI4IiB5PSI4IiB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHJ4PSIyIiByeT0iMiIgLz48cGF0aCBkPSJNNCAxNlY0YTIgMiAwIDAgMSAyLTJoOGEyIDIgMCAwIDEgMiAydjQiIC8+PC9zdmc+' ICON_CHECK_SVG = b'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZGhyPSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBvbHlsaW5lIHBvaW50cz0iMjAgNiA5IDE3IDQgMTIiPjwvcG9seWxpbmU+PC9zdmc+' class UltimateTextConverter(QMainWindow): def __init__(self): super().__init__() self.setWindowFlags(Qt.WindowType.FramelessWindowHint) self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) self.setWindowTitle("Ultimate Text Converter") self.setGeometry(100, 100, 750, 480) self.setMinimumSize(700, 450) self.old_pos = self.pos() self.init_ui() self.apply_stylesheet() def init_ui(self): # --- Main Container --- container = GradientContainer() self.setCentralWidget(container) main_layout = QVBoxLayout(container) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.setSpacing(0) # --- Custom Title Bar --- title_bar = QWidget() title_bar.setObjectName("TitleBar") title_bar_layout = QHBoxLayout(title_bar) title_label = QLabel("Ultimate Text Converter") title_label.setObjectName("TitleLabel") btn_close = QPushButton("โœ•") btn_minimize = QPushButton("โ€”") btn_maximize = QPushButton("๏ฟฝ") btn_close.setObjectName("WindowButton") btn_minimize.setObjectName("WindowButton") btn_maximize.setObjectName("WindowButton") btn_close.clicked.connect(self.close) btn_minimize.clicked.connect(self.showMinimized) btn_maximize.clicked.connect(self.toggle_maximize_restore) title_bar_layout.addWidget(title_label) title_bar_layout.addStretch() title_bar_layout.addWidget(btn_minimize) title_bar_layout.addWidget(btn_maximize) title_bar_layout.addWidget(btn_close) main_layout.addWidget(title_bar) # --- Content Area (Side-by-Side) --- content_layout = QHBoxLayout() content_layout.setContentsMargins(15, 15, 15, 15) content_layout.setSpacing(15) main_layout.addLayout(content_layout, 1) # --- Left and Right Panels --- left_panel = QFrame(); left_panel.setObjectName("Panel") right_panel = QFrame(); right_panel.setObjectName("Panel") left_layout = QVBoxLayout(left_panel); right_layout = QVBoxLayout(right_panel) for layout in [left_layout, right_layout]: layout.setContentsMargins(15, 15, 15, 15); layout.setSpacing(10) # --- Left Panel Widgets --- input_label = QLabel("Input"); input_label.setObjectName("HeaderLabel") self.input_textbox = QTextEdit(); self.input_textbox.setPlaceholderText("Start typing here...") self.input_textbox.textChanged.connect(self.convert_text) style_label = QLabel("Style"); style_label.setObjectName("HeaderLabel") self.style_list = sorted(list(text_maps.keys()) + ["Zalgo", "Reversed", "Strikethrough", "Underline", "Overline", "Spongebob Case", "Vaporwave", "Clap Back", "Regional Indicators", "Binary Code"]) self.style_dropdown = QComboBox(); self.style_dropdown.addItems(self.style_list) self.style_dropdown.setView(QListView()); self.style_dropdown.setCurrentText("Bold") self.style_dropdown.currentTextChanged.connect(self.convert_text) # --- NEW: Ignore Brackets Checkbox --- self.ignore_brackets_checkbox = QCheckBox("Ignore text within brackets: {{..}}, [..], (..)") self.ignore_brackets_checkbox.stateChanged.connect(self.convert_text) left_layout.addWidget(input_label); left_layout.addWidget(self.input_textbox) left_layout.addWidget(style_label); left_layout.addWidget(self.style_dropdown) left_layout.addWidget(self.ignore_brackets_checkbox) # Add checkbox to layout left_layout.addStretch() # --- Right Panel Widgets --- output_header_layout = QHBoxLayout() output_label = QLabel("Output"); output_label.setObjectName("HeaderLabel") self.copy_button = QPushButton("Copy") self.copy_button.setObjectName("CopyButton") self.copy_icon = self.create_icon_from_svg(ICON_COPY_SVG) self.check_icon = self.create_icon_from_svg(ICON_CHECK_SVG) self.copy_button.setIcon(self.copy_icon) self.copy_button.clicked.connect(self.copy_to_clipboard) output_header_layout.addWidget(output_label); output_header_layout.addStretch(); output_header_layout.addWidget(self.copy_button) self.output_textbox = QTextEdit(); self.output_textbox.setReadOnly(True) right_layout.addLayout(output_header_layout); right_layout.addWidget(self.output_textbox) content_layout.addWidget(left_panel); content_layout.addWidget(right_panel) # --- Custom Status Bar --- self.status_label = QLabel("Ready") self.status_label.setObjectName("StatusLabel") main_layout.addWidget(self.status_label) # --- Window Drag and Control Methods --- def mousePressEvent(self, event): self.old_pos = event.globalPosition().toPoint() def mouseMoveEvent(self, event): delta = QPoint(event.globalPosition().toPoint() - self.old_pos) self.move(self.x() + delta.x(), self.y() + delta.y()) self.old_pos = event.globalPosition().toPoint() def toggle_maximize_restore(self): if self.isMaximized(): self.showNormal() else: self.showMaximized() def create_icon_from_svg(self, svg_data): pixmap = QPixmap(); pixmap.loadFromData(base64.b64decode(svg_data), "svg") return QIcon(pixmap) def apply_stylesheet(self): self.setStyleSheet(""" #Container { border-radius: 12px; } #TitleBar { background-color: transparent; } #TitleLabel { font-size: 14px; font-weight: 600; padding: 8px 15px; color: #FFFFFF; } #WindowButton { background-color: transparent; color: #E5E7EB; border: none; font-size: 14px; font-weight: bold; padding: 4px 12px; } #WindowButton:hover { color: #FFFFFF; } #Panel { background-color: rgba(0, 0, 0, 0.25); border: 2px solid rgba(255, 255, 255, 0.3); border-radius: 12px; } #HeaderLabel { font-size: 12px; font-weight: 500; color: #D1D5DB; padding-left: 2px; background-color: transparent; } QTextEdit, QComboBox { background-color: rgba(0, 0, 0, 0.2); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 6px; padding: 8px; font-size: 14px; color: #F9FAFB; } QTextEdit:focus, QComboBox:focus { border: 1px solid #A78BFA; } QComboBox:hover { border: 1px solid rgba(255, 255, 255, 0.3); } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 20px; border: none; } QComboBox::down-arrow { image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iI0QxRDVEMkIiIHZpZXdCb3g9IjAgMCAyNTYiPjxwYXRoIGQ9Ik0yMTMuNjYgMTAxLjY2bC04MCA4MGE4IDggMCAwIDEtMTEuMzIgMGwtODAtODBhOC4wMSA4LjAxIDAgMCAxIDExLjMyLTExLjMyTDEyOCAxODQuYzkbDczLjY2LTczLjY3YTguMDEgOC4wMSAwIDAgMSAxMS4zMiAxMS4zMloiLz48L3N2Zz4=); } QComboBox QAbstractItemView { background-color: #1F2937; border: 1px solid rgba(255, 255, 255, 0.2); color: #F9FAFB; selection-background-color: #4F46E5; selection-color: #FFFFFF; outline: 0px; } QCheckBox { color: #D1D5DB; background-color: transparent; spacing: 5px; padding-top: 5px; font-size: 13px; } QCheckBox::indicator { width: 16px; height: 16px; border: 1px solid rgba(255, 255, 255, 0.3); border-radius: 4px; background-color: rgba(0, 0, 0, 0.2); } QCheckBox::indicator:hover { border: 1px solid rgba(255, 255, 255, 0.5); } QCheckBox::indicator:checked { background-color: #8B5CF6; border: 1px solid #8B5CF6; image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0id2hpdGUiIHZpZXdCb3g9IjAgMCAyNTYgMjU2Ij48cGF0aCBkPSJNMjI5LjY2IDEwMS42NmwtMTI4IDEyOGE4IDggMCAwIDEtMTEuMzIgMGwtNTYtNTZhOCA4IDAgMCAxIDExLjMyLTExLjMyTDEwMCAyMDYuNjlsMTIzLjY2LTEyMy42N2E4IDggMCAwIDEgMTEuMzIgMTEuMzJaIi8+PC9zdmc+); } #CopyButton { background-color: transparent; color: #E5E7EB; border: 2px solid rgba(255, 255, 255, 0.3); padding: 8px 16px; border-radius: 6px; font-size: 13px; font-weight: 600; } #CopyButton:hover { background-color: rgba(255, 255, 255, 0.1); } #CopyButton:pressed { background-color: rgba(255, 255, 255, 0.2); } #CopyButton[copied="true"] { background-color: #10B981; color: #FFFFFF; border: 2px solid #10B981; } #StatusLabel { color: #D1D5DB; background-color: transparent; font-size: 12px; padding: 4px 15px; } """) def convert_text(self): input_text = self.input_textbox.toPlainText() style = self.style_dropdown.currentText() output_text = "" def apply_style(text_chunk): """Helper function to apply the selected style to a string.""" if not text_chunk: return "" conversion_logic = {"Zalgo": apply_zalgo, "Reversed": reverse_text, "Spongebob Case": spongebob_case, "Vaporwave": vaporwave, "Clap Back": clap_back, "Regional Indicators": regional_indicators, "Binary Code": to_binary, "Strikethrough": lambda t: apply_combiner(t, '\u0336'), "Underline": lambda t: apply_combiner(t, '\u0332'), "Overline": lambda t: apply_combiner(t, '\u0305')} if style in conversion_logic: return conversion_logic[style](text_chunk) elif style in text_maps: conversion_map = text_maps[style] if style == "Morse Code": return " ".join(conversion_map.get(char.upper(), char) for char in text_chunk) elif style == "Mirrored": return "".join(conversion_map.get(char.lower(), char) for char in reversed(text_chunk)) else: return "".join(conversion_map.get(char, char) for char in text_chunk) return "Style not implemented." if not self.ignore_brackets_checkbox.isChecked(): output_text = apply_style(input_text) else: # Logic to ignore content within brackets # Pattern matches {{...}}, [[...]], (...), {...}, and [...] pattern = r'(\{\{.*?\}\}|\[\[.*?\]\]|\(.*?\)|\{.*?\}|\[.*?\])' if style == "Clap Back": # Special case for "Clap Back" which relies on word separation brackets = [] def store_bracket(match): brackets.append(match.group(0)) # Use a placeholder with spaces so split() treats it as a word return f' \uE000{len(brackets)-1}\uE001 ' temp_text = re.sub(pattern, store_bracket, input_text) converted_temp = clap_back(temp_text) output_text = converted_temp for i, bracket_content in enumerate(brackets): output_text = output_text.replace(f' \uE000{i}\uE001 ', bracket_content) else: # General case for character-based styles parts = re.split(pattern, input_text) output_parts = [apply_style(part) if i % 2 == 0 else part for i, part in enumerate(parts)] output_text = "".join(output_parts) self.output_textbox.setText(output_text) def copy_to_clipboard(self): text_to_copy = self.output_textbox.toPlainText() if text_to_copy: QApplication.clipboard().setText(text_to_copy) self.status_label.setText("Copied to clipboard!") self.anim_group = QSequentialAnimationGroup() anim_grow = QPropertyAnimation(self.copy_button, b"geometry") original_geo = self.copy_button.geometry() anim_grow.setDuration(100); anim_grow.setStartValue(original_geo) anim_grow.setEndValue(original_geo.adjusted(-2, -2, 2, 2)); anim_grow.setEasingCurve(QEasingCurve.Type.OutQuad) anim_shrink = QPropertyAnimation(self.copy_button, b"geometry") anim_shrink.setDuration(100); anim_shrink.setStartValue(original_geo.adjusted(-2, -2, 2, 2)) anim_shrink.setEndValue(original_geo); anim_shrink.setEasingCurve(QEasingCurve.Type.InQuad) self.anim_group.addAnimation(anim_grow); self.anim_group.addAnimation(anim_shrink) self.anim_group.start() self.copy_button.setText("Copied!"); self.copy_button.setIcon(self.check_icon) self.copy_button.setProperty("copied", True); self.copy_button.style().unpolish(self.copy_button) self.copy_button.style().polish(self.copy_button) QTimer.singleShot(1500, self.restore_copy_button_state) else: self.status_label.setText("Nothing to copy.") def restore_copy_button_state(self): self.copy_button.setText("Copy"); self.copy_button.setIcon(self.copy_icon) self.copy_button.setProperty("copied", False); self.copy_button.style().unpolish(self.copy_button) self.copy_button.style().polish(self.copy_button) if __name__ == "__main__": app = QApplication(sys.argv) app.setFont(QFont("Inter", 13)) main_win = UltimateTextConverter() fade_in = QPropertyAnimation(main_win, b"windowOpacity") fade_in.setDuration(400); fade_in.setStartValue(0) fade_in.setEndValue(1); fade_in.setEasingCurve(QEasingCurve.Type.InOutQuad) main_win.show() fade_in.start() sys.exit(app.exec()) class GradientContainer(QWidget): """A custom widget that paints a gradient within rounded corners.""" def __init__(self, parent=None): super().__init__(parent) self.setObjectName("Container") def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(QPainter.RenderHint.Antialiasing) gradient = QLinearGradient(QPointF(0, 0), QPointF(self.width(), self.height())) gradient.setColorAt(0.0, QColor("#3730A3")) # Indigo gradient.setColorAt(1.0, QColor("#DB2777")) # Fuchsia path = QPainterPath() # The radius should match the stylesheet's border-radius path.addRoundedRect(QRectF(self.rect()), 12, 12) painter.fillPath(path, QBrush(gradient)) # --- Character Maps and Special Functions --- text_maps = { "Bold": {**create_char_map('A', 'Z', 0x1D400), **create_char_map('a', 'z', 0x1D41A), **create_char_map('0', '9', 0x1D7CE)},"Italic": {**create_char_map('A', 'Z', 0x1D434), **create_char_map('a', 'z', 0x1D44E)},"Bold Italic": {**create_char_map('A', 'Z', 0x1D468), **create_char_map('a', 'z', 0x1D482)},"Script": {'A': '๐’œ', 'B': 'โ„ฌ', 'C': '๐’ž', 'D': '๐’Ÿ', 'E': 'โ„ฐ', 'F': 'โ„ฑ', 'G': '๐’ข', 'H': 'โ„‹', 'I': 'โ„', 'J': '๐’ฅ', 'K': '๐’ฆ', 'L': 'โ„’', 'M': 'โ„ณ', 'N': '๐’ฉ', 'O': '๐’ช', 'P': '๐’ซ', 'Q': '๐’ฌ', 'R': 'โ„›', 'S': '๐’ฎ', 'T': '๐’ฏ', 'U': '๐’ฐ', 'V': '๐’ฑ', 'W': '๐’ฒ', 'X': '๐’ณ', 'Y': '๐’ด', 'Z': '๐’ต', 'a': '๐’ถ', 'b': '๐’ท', 'c': '๐’ธ', 'd': '๐’น', 'e': 'โ„ฏ', 'f': '๐’ป', 'g': 'โ„Š', 'h': '๐’ฝ', 'i': '๐’พ', 'j': '๐’ฟ', 'k': '๐“€', 'l': '๐“', 'm': '๐“‚', 'n': '๐“ƒ', 'o': 'โ„ด', 'p': '๐“…', 'q': '๐“†', 'r': '๐“‡', 's': '๐“ˆ', 't': '๐“‰', 'u': '๐“Š', 'v': '๐“‹', 'w': '๐“Œ', 'x': '๐“', 'y': '๐“Ž', 'z': '๐“'},"Bold Script": {**create_char_map('A', 'Z', 0x1D4D0), **create_char_map('a', 'z', 0x1D4EA)},"Fraktur": {'A': '๐”„', 'B': '๐”…', 'C': 'โ„ญ', 'D': '๐”‡', 'E': '๐”ˆ', 'F': '๐”‰', 'G': '๐”Š', 'H': 'โ„Œ', 'I': 'โ„‘', 'J': '๐”', 'K': '๐”Ž', 'L': '๐”', 'M': '๐”', 'N': '๐”‘', 'O': '๐’ช', 'P': '๐”“', 'Q': '๐””', 'R': 'โ„œ', 'S': '๐”–', 'T': '๐”—', 'U': '๐”˜', 'V': '๐”™', 'W': '๐”š', 'X': '๐”›', 'Y': '๐”œ', 'Z': 'โ„จ', 'a': '๐”ž', 'b': '๐”Ÿ', 'c': '๐” ', 'd': '๐”ก', 'e': '๐”ข', 'f': '๐”ฃ', 'g': '๐”ค', 'h': '๐”ฅ', 'i': '๐”ฆ', 'j': '๐”ง', 'k': '๐”จ', 'l': '๐”ฉ', 'm': '๐”ช', 'n': '๐”ซ', 'o': '๐”ฌ', 'p': '๐”ญ', 'q': '๐”ฎ', 'r': '๐”ฏ', 's': '๐”ฐ', 't': '๐”ฑ', 'u': '๐“Š', 'v': '๐“‹', 'w': '๐”ด', 'x': '๐”ต', 'y': '๐”ถ', 'z': '๐”ท'},"Bold Fraktur": {**create_char_map('A', 'Z', 0x1D56C), **create_char_map('a', 'z', 0x1D586)},"Double-Struck": {**create_char_map('A', 'Z', 0x1D538), **create_char_map('a', 'z', 0x1D552), **create_char_map('0', '9', 0x1D7D8)},"Monospace": {**create_char_map('A', 'Z', 0x1D670), **create_char_map('a', 'z', 0x1D68A), **create_char_map('0', '9', 0x1D7F6)},"Full-Width": {**{chr(i): chr(i + 0xFEE0) for i in range(0x21, 0x7F)}, **{chr(0x20): chr(0x3000)}},"Circled": {**create_char_map('A', 'Z', 0x24B6), **create_char_map('a', 'z', 0x24D0), '0': 'โ“ช', **create_char_map('1', '9', 0x2460)},"Leetspeak": {'a': '4', 'A': '4', 'b': '8', 'B': '8', 'e': '3', 'E': '3', 'g': '6', 'G': '6', 'i': '1', 'I': '1', 'l': '1', 'L': '1', 'o': '0', 'O': '0', 's': '5', 'S': '5', 't': '7', 'T': '7', 'z': '2', 'Z': '2'},"Superscript": {'0': 'โฐ', '1': 'ยน', '2': 'ยฒ', '3': 'ยณ', '4': 'โด', '5': 'โต', '6': 'โถ', '7': 'โท', '8': 'โธ', '9': 'โน', 'a': 'แตƒ', 'b': 'แต‡', 'c': 'แถœ', 'd': 'แตˆ', 'e': 'แต‰', 'f': 'แถ ', 'g': 'แต', 'h': 'สฐ', 'i': 'โฑ', 'j': 'สฒ', 'k': 'แต', 'l': 'หก', 'm': 'แต', 'n': 'โฟ', 'o': 'แต’', 'p': 'แต–', 'r': 'สณ', 's': 'หข', 't': 'แต—', 'u': 'แต˜', 'v': 'แต›', 'w': 'สท', 'x': 'หฃ', 'y': 'สธ', 'z': 'แถป', '+': 'โบ', '-': 'โป', '=': 'โผ', '(': 'โฝ', ')': 'โพ'},"Subscript": {'0': 'โ‚€', '1': 'โ‚', '2': 'โ‚‚', '3': 'โ‚ƒ', '4': 'โ‚„', '5': 'โ‚…', '6': 'โ‚†', '7': 'โ‚‡', '8': 'โ‚ˆ', '9': 'โ‚‰', 'a': 'โ‚', 'e': 'โ‚‘', 'h': 'โ‚•', 'i': 'แตข', 'j': 'โฑผ', 'k': 'โ‚–', 'l': 'โ‚—', 'm': 'โ‚˜', 'n': 'โ‚™', 'o': 'โ‚’', 'p': 'โ‚š', 'r': 'แตฃ', 's': 'โ‚›', 't': 'โ‚œ', 'u': 'แตค', 'v': 'แตฅ', 'x': 'โ‚“', '+': 'โ‚Š', '-': 'โ‚‹', '=': 'โ‚Œ', '(': 'โ‚', ')': 'โ‚Ž'},"Morse Code": {'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----', ' ': '/', '.': '.-.-.-', ',': '--..--', '?': '..--..', "'": '.----.', '!': '-.-.--', '/': '-..-.', '(': '-.--.', ')': '-.--.-', '&': '.-...', ':': '---...', ';': '-.-.-.', '=': '-...-', '+': '.-.-.', '-': '-....-', '_': '..--.-', '"': '.-..-.', '$': '...-..-', '@': '.--.-.'},"Mirrored": {'a': 'ษ’', 'b': 'd', 'c': 'ษ”', 'd': 'b', 'e': 'ษ˜', 'f': 'แŽธ', 'g': 'วซ', 'h': 'ฮผ', 'i': 'i', 'j': '๊ž', 'k': 'สž', 'l': 'l', 'm': 'm', 'n': 'n', 'o': 'o', 'p': 'q', 'q': 'p', 'r': 'ษฟ', 's': 'ฦจ', 't': 'ฦš', 'u': 'u', 'v': 'v', 'w': 'w', 'x': 'x', 'y': 'ฮณ', 'z': 'z'} } def apply_zalgo(text): zalgo_chars = [chr(i) for i in range(0x0300, 0x036F)] return "".join(char + (''.join(random.choice(zalgo_chars) for _ in range(random.randint(1, 8))) if char.strip() else '') for char in text) def apply_combiner(text, combiner): return "".join(char + combiner for char in text) def reverse_text(text): return text[::-1] def spongebob_case(text): return "".join(char.lower() if random.random() < 0.5 else char.upper() for char in text) def vaporwave(text): return '\u3000'.join(text_maps["Full-Width"].get(char, char) for char in text) def clap_back(text): return " ๐Ÿ‘ ".join(text.split()) def regional_indicators(text): return "".join(chr(0x1F1E6 + (ord(char.upper()) - ord('A'))) if 'A' <= char.upper() <= 'Z' else char for char in text) def to_binary(text): return ' '.join(format(ord(char), '08b') for char in text) ICON_COPY_SVG = b'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNlNWU3ZmIiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cmVjdCB4PSI4IiB5PSI4IiB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHJ4PSIyIiByeT0iMiIgLz48cGF0aCBkPSJNNCAxNlY0YTIgMiAwIDAgMSAyLTJoOGEyIDIgMCAwIDEgMiAydjQiIC8+PC9zdmc+' ICON_CHECK_SVG = b'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZHRoPSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBvbHlsaW5lIHBvaW50cz0iMjAgNiA5IDE3IDQgMTIiPjwvcG9seWxpbmU+PC9zdmc+' class UltimateTextConverter(QMainWindow): def __init__(self): super().__init__() self.setWindowFlags(Qt.WindowType.FramelessWindowHint) self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) self.setWindowTitle("Ultimate Text Converter") self.setGeometry(100, 100, 750, 480) self.setMinimumSize(700, 450) self.old_pos = self.pos() self.init_ui() self.apply_stylesheet() def init_ui(self): # --- Main Container --- container = GradientContainer() self.setCentralWidget(container) main_layout = QVBoxLayout(container) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.setSpacing(0) # --- Custom Title Bar --- title_bar = QWidget() title_bar.setObjectName("TitleBar") title_bar_layout = QHBoxLayout(title_bar) title_label = QLabel("Ultimate Text Converter") title_label.setObjectName("TitleLabel") btn_close = QPushButton("โœ•") btn_minimize = QPushButton("โ€”") btn_maximize = QPushButton("๏ฟฝ") btn_close.setObjectName("WindowButton") btn_minimize.setObjectName("WindowButton") btn_maximize.setObjectName("WindowButton") btn_close.clicked.connect(self.close) btn_minimize.clicked.connect(self.showMinimized) btn_maximize.clicked.connect(self.toggle_maximize_restore) title_bar_layout.addWidget(title_label) title_bar_layout.addStretch() title_bar_layout.addWidget(btn_minimize) title_bar_layout.addWidget(btn_maximize) title_bar_layout.addWidget(btn_close) main_layout.addWidget(title_bar) # --- Content Area (Side-by-Side) --- content_layout = QHBoxLayout() content_layout.setContentsMargins(15, 15, 15, 15) content_layout.setSpacing(15) main_layout.addLayout(content_layout, 1) # --- Left and Right Panels --- left_panel = QFrame(); left_panel.setObjectName("Panel") right_panel = QFrame(); right_panel.setObjectName("Panel") left_layout = QVBoxLayout(left_panel); right_layout = QVBoxLayout(right_panel) for layout in [left_layout, right_layout]: layout.setContentsMargins(15, 15, 15, 15); layout.setSpacing(10) # --- Left Panel Widgets --- input_label = QLabel("Input"); input_label.setObjectName("HeaderLabel") self.input_textbox = QTextEdit(); self.input_textbox.setPlaceholderText("Start typing here...") self.input_textbox.textChanged.connect(self.convert_text) style_label = QLabel("Style"); style_label.setObjectName("HeaderLabel") self.style_list = sorted(list(text_maps.keys()) + ["Zalgo", "Reversed", "Strikethrough", "Underline", "Overline", "Spongebob Case", "Vaporwave", "Clap Back", "Regional Indicators", "Binary Code"]) self.style_dropdown = QComboBox(); self.style_dropdown.addItems(self.style_list) self.style_dropdown.setView(QListView()); self.style_dropdown.setCurrentText("Bold") self.style_dropdown.currentTextChanged.connect(self.convert_text) left_layout.addWidget(input_label); left_layout.addWidget(self.input_textbox) left_layout.addWidget(style_label); left_layout.addWidget(self.style_dropdown) left_layout.addStretch() # --- Right Panel Widgets --- output_header_layout = QHBoxLayout() output_label = QLabel("Output"); output_label.setObjectName("HeaderLabel") self.copy_button = QPushButton("Copy") self.copy_button.setObjectName("CopyButton") self.copy_icon = self.create_icon_from_svg(ICON_COPY_SVG) self.check_icon = self.create_icon_from_svg(ICON_CHECK_SVG) self.copy_button.setIcon(self.copy_icon) self.copy_button.clicked.connect(self.copy_to_clipboard) output_header_layout.addWidget(output_label); output_header_layout.addStretch(); output_header_layout.addWidget(self.copy_button) self.output_textbox = QTextEdit(); self.output_textbox.setReadOnly(True) right_layout.addLayout(output_header_layout); right_layout.addWidget(self.output_textbox) content_layout.addWidget(left_panel); content_layout.addWidget(right_panel) # --- Custom Status Bar --- self.status_label = QLabel("Ready") self.status_label.setObjectName("StatusLabel") main_layout.addWidget(self.status_label) # --- Window Drag and Control Methods --- def mousePressEvent(self, event): self.old_pos = event.globalPosition().toPoint() def mouseMoveEvent(self, event): delta = QPoint(event.globalPosition().toPoint() - self.old_pos) self.move(self.x() + delta.x(), self.y() + delta.y()) self.old_pos = event.globalPosition().toPoint() def toggle_maximize_restore(self): if self.isMaximized(): self.showNormal() else: self.showMaximized() def create_icon_from_svg(self, svg_data): pixmap = QPixmap(); pixmap.loadFromData(base64.b64decode(svg_data), "svg") return QIcon(pixmap) def apply_stylesheet(self): self.setStyleSheet(""" #Container { border-radius: 12px; } #TitleBar { background-color: transparent; } #TitleLabel { font-size: 14px; font-weight: 600; padding: 8px 15px; color: #FFFFFF; } #WindowButton { background-color: transparent; color: #E5E7EB; border: none; font-size: 14px; font-weight: bold; padding: 4px 12px; } #WindowButton:hover { color: #FFFFFF; } #Panel { background-color: rgba(0, 0, 0, 0.25); border: 2px solid rgba(255, 255, 255, 0.3); border-radius: 12px; } #HeaderLabel { font-size: 12px; font-weight: 500; color: #D1D5DB; padding-left: 2px; background-color: transparent; } QTextEdit, QComboBox { background-color: rgba(0, 0, 0, 0.2); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 6px; padding: 8px; font-size: 14px; color: #F9FAFB; } QTextEdit:focus, QComboBox:focus { border: 1px solid #A78BFA; } QComboBox:hover { border: 1px solid rgba(255, 255, 255, 0.3); } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 20px; border: none; } QComboBox::down-arrow { image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iI0QxRDVEMkIiIHZpZXdCb3g9IjAgMCAyNTYiPjxwYXRoIGQ9Ik0yMTMuNjYgMTAxLjY2bC04MCA4MGE4IDggMCAwIDEtMTEuMzIgMGwtODAtODBhOC4wMSA4LjAxIDAgMCAxIDExLjMyLTExLjMyTDEyOCAxODQuYzkbDczLjY2LTczLjY3YTguMDEgOC4wMSAwIDAgMSAxMS4zMiAxMS4zMloiLz48L3N2Zz4=); } QComboBox QAbstractItemView { background-color: #1F2937; border: 1px solid rgba(255, 255, 255, 0.2); color: #F9FAFB; selection-background-color: #4F46E5; selection-color: #FFFFFF; outline: 0px; } #CopyButton { background-color: transparent; color: #E5E7EB; border: 2px solid rgba(255, 255, 255, 0.3); padding: 8px 16px; border-radius: 6px; font-size: 13px; font-weight: 600; } #CopyButton:hover { background-color: rgba(255, 255, 255, 0.1); } #CopyButton:pressed { background-color: rgba(255, 255, 255, 0.2); } #CopyButton[copied="true"] { background-color: #10B981; color: #FFFFFF; border: 2px solid #10B981; } #StatusLabel { color: #D1D5DB; background-color: transparent; font-size: 12px; padding: 4px 15px; } """) def convert_text(self): input_text = self.input_textbox.toPlainText() style = self.style_dropdown.currentText() output_text = "" conversion_logic = {"Zalgo": apply_zalgo, "Reversed": reverse_text, "Spongebob Case": spongebob_case, "Vaporwave": vaporwave, "Clap Back": clap_back, "Regional Indicators": regional_indicators, "Binary Code": to_binary, "Strikethrough": lambda t: apply_combiner(t, '\u0336'), "Underline": lambda t: apply_combiner(t, '\u0332'), "Overline": lambda t: apply_combiner(t, '\u0305')} if style in conversion_logic: output_text = conversion_logic[style](input_text) elif style in text_maps: conversion_map = text_maps[style] if style == "Morse Code": output_text = " ".join(conversion_map.get(char.upper(), char) for char in input_text) elif style == "Mirrored": output_text = "".join(conversion_map.get(char.lower(), char) for char in reversed(input_text)) else: output_text = "".join(conversion_map.get(char, char) for char in input_text) else: output_text = "Style not implemented." self.output_textbox.setText(output_text) def copy_to_clipboard(self): text_to_copy = self.output_textbox.toPlainText() if text_to_copy: QApplication.clipboard().setText(text_to_copy) self.status_label.setText("Copied to clipboard!") # --- Button Pop Animation --- self.anim_group = QSequentialAnimationGroup() # Animation to grow anim_grow = QPropertyAnimation(self.copy_button, b"geometry") original_geo = self.copy_button.geometry() anim_grow.setDuration(100) anim_grow.setStartValue(original_geo) anim_grow.setEndValue(original_geo.adjusted(-2, -2, 2, 2)) anim_grow.setEasingCurve(QEasingCurve.Type.OutQuad) # Animation to shrink back anim_shrink = QPropertyAnimation(self.copy_button, b"geometry") anim_shrink.setDuration(100) anim_shrink.setStartValue(original_geo.adjusted(-2, -2, 2, 2)) anim_shrink.setEndValue(original_geo) anim_shrink.setEasingCurve(QEasingCurve.Type.InQuad) self.anim_group.addAnimation(anim_grow) self.anim_group.addAnimation(anim_shrink) self.anim_group.start() # Temporarily change button appearance self.copy_button.setText("Copied!") self.copy_button.setIcon(self.check_icon) self.copy_button.setProperty("copied", True) self.copy_button.style().unpolish(self.copy_button) self.copy_button.style().polish(self.copy_button) # Revert after 1.5 seconds QTimer.singleShot(1500, self.restore_copy_button_state) else: self.status_label.setText("Nothing to copy.") def restore_copy_button_state(self): self.copy_button.setText("Copy") self.copy_button.setIcon(self.copy_icon) self.copy_button.setProperty("copied", False) self.copy_button.style().unpolish(self.copy_button) self.copy_button.style().polish(self.copy_button) if __name__ == "__main__": app = QApplication(sys.argv) app.setFont(QFont("Inter", 13)) main_win = UltimateTextConverter() # --- Window Fade-in Animation --- fade_in = QPropertyAnimation(main_win, b"windowOpacity") fade_in.setDuration(400) fade_in.setStartValue(0) fade_in.setEndValue(1) fade_in.setEasingCurve(QEasingCurve.Type.InOutQuad) main_win.show() fade_in.start() sys.exit(app.exec())