Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.de.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
<p><strong>🔗 Webseite: <a href="https://timintech.github.io/blitztextweb/">timintech.github.io/blitztextweb</a></strong></p>
</div>

<div align="center">
<img src="docs/screenshots/linux/demo-de.gif" alt="Demo: Hotkey drücken, sprechen, und Blitztext fügt den transkribierten Text direkt in die aktive Anwendung ein" width="720">
<br>
<sub><kbd>Alt</kbd> gedrückt halten (Standard-Hotkey), sprechen, loslassen — das Transkript landet direkt in der aktiven Anwendung.</sub>
</div>

> [!IMPORTANT]
> **Eigenständiger Linux-Port:** Dieses Repository enthält ausschließlich den Linux-Port von Blitztext – eine eigenständige Python 3/PyQt6-Implementierung optimiert für **Kubuntu/Ubuntu unter KDE Plasma mit Wayland**. Für die originale macOS-Version besuche bitte das [offizielle Haupt-Repository](https://github.com/cmagnussen/blitztext-app).

Expand Down Expand Up @@ -47,7 +53,7 @@ Blitztext registriert globale Hotkeys via `evdev`. Mit diesen Kombinationen hast

| Workflow | Hotkey | LLM? | Beschreibung |
| :--- | :--- | :---: | :--- |
| **Blitztext** | <kbd>Meta</kbd> + <kbd>H</kbd> | ❌ | Standard: Nimmt auf, transkribiert und fügt den Text ein. |
| **Blitztext** | <kbd>Alt</kbd> (halten) | ❌ | Standard: Nimmt auf, solange die Taste gehalten wird, transkribiert und fügt den Text ein. Aufnahmetaste und Halten/Umschalten-Modus sind unter **Einstellungen → Spracherkennung** konfigurierbar. |
| **Blitztext Lokal** | <kbd>Meta</kbd> + <kbd>Shift</kbd> + <kbd>H</kbd> | ❌ | Erzwingt eine reine **Offline-Transkription**. |
| **Blitztext+** | <kbd>Meta</kbd> + <kbd>Shift</kbd> + <kbd>T</kbd> | ✅ | Formuliert deine Aufnahme professionell via LLM um. |
| **Blitztext $%&!** | <kbd>Meta</kbd> + <kbd>Shift</kbd> + <kbd>D</kbd> | ✅ | Emotionale Entladung: Wandelt Frust in eine sachliche Nachricht um. |
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
<p><strong>🔗 Website: <a href="https://timintech.github.io/blitztextweb/">timintech.github.io/blitztextweb</a></strong></p>
</div>

<div align="center">
<img src="docs/screenshots/linux/demo-en.gif" alt="Demo: press the hotkey, speak, and Blitztext pastes the transcribed text into the active application" width="720">
<br>
<sub>Hold <kbd>Alt</kbd> (default hotkey), speak, release — the transcript lands directly in the active application.</sub>
</div>

> [!IMPORTANT]
> **Standalone Linux port:** This repository contains exclusively the Linux port of Blitztext – a standalone Python 3/PyQt6 implementation optimized for **Kubuntu/Ubuntu running KDE Plasma with Wayland**. For the original macOS version, please visit the [official main repository](https://github.com/cmagnussen/blitztext-app).

Expand Down Expand Up @@ -47,7 +53,7 @@ Blitztext registers global hotkeys via `evdev`. With these combinations you have

| Workflow | Hotkey | LLM? | Description |
| :--- | :--- | :---: | :--- |
| **Blitztext** | <kbd>Meta</kbd> + <kbd>H</kbd> | ❌ | Default: records, transcribes, and pastes the text. |
| **Blitztext** | <kbd>Alt</kbd> (hold) | ❌ | Default: records while the key is held, transcribes, and pastes the text. Recording key and hold/toggle mode are configurable under **Settings → Speech Recognition**. |
| **Blitztext Local** | <kbd>Meta</kbd> + <kbd>Shift</kbd> + <kbd>H</kbd> | ❌ | Forces a pure **offline transcription**. |
| **Blitztext+** | <kbd>Meta</kbd> + <kbd>Shift</kbd> + <kbd>T</kbd> | ✅ | Rephrases your recording professionally via LLM. |
| **Blitztext $%&!** | <kbd>Meta</kbd> + <kbd>Shift</kbd> + <kbd>D</kbd> | ✅ | Emotional release: turns frustration into a matter-of-fact message. |
Expand Down
10 changes: 7 additions & 3 deletions app/blitztext_linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from app.config import Config, DEFAULTS, VALID_HOTKEY_KEYS
from app.llm_service import LLMService, WorkflowType, LLM_WORKFLOWS
from app.writing_presets import WRITING_PRESET_KEYS, get_preset, preset_index
from app.hotkey_service import HotkeyWorker
from app.hotkey_service import HotkeyWorker, hotkey_display_name
from app.audio_recorder import AudioRecorder, AudioRecorderError
from app.transcribe import transcribe, TranscribeError
from app.paste_service import PasteService, PasteServiceError
Expand Down Expand Up @@ -705,7 +705,9 @@ def setup_tray(self) -> None:
self.menu.addSeparator()

# Actions für die fünf Workflows
self.action_transcription = QAction(f"{t('workflow.transcription.name')}\tMeta+H", self)
self.action_transcription = QAction(
f"{t('workflow.transcription.name')}\t{hotkey_display_name(self.config.transcription_hotkey)}", self
)
self.action_transcription.triggered.connect(lambda: self._trigger_menu_workflow(WorkflowType.TRANSCRIPTION))
self.menu.addAction(self.action_transcription)

Expand Down Expand Up @@ -816,7 +818,9 @@ def _refresh_i18n_texts(self) -> None:
if hasattr(self, "action_compose"):
self.action_compose.setText(f"✍ {t('tray.compose')}")
if hasattr(self, "action_transcription"):
self.action_transcription.setText(f"{t('workflow.transcription.name')}\tMeta+H")
self.action_transcription.setText(
f"{t('workflow.transcription.name')}\t{hotkey_display_name(self.config.transcription_hotkey)}"
)
if hasattr(self, "action_local"):
self.action_local.setText(f"{t('workflow.local.name')}\tMeta+Shift+H")
if hasattr(self, "action_improver"):
Expand Down
23 changes: 23 additions & 0 deletions app/hotkey_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,29 @@
DEVICE_REFRESH_SECONDS = 5.0
logger = logging.getLogger("blitztext.hotkey")

# Anzeigenamen für die konfigurierbare Aufnahmetaste (config.transcription_hotkey).
# Deckt alle VALID_HOTKEY_KEYS aus app/config.py ab; unbekannte Namen fallen
# auf den evdev-Namen ohne "KEY_"-Präfix zurück.
_HOTKEY_DISPLAY_NAMES = {
"KEY_LEFTALT": "Alt",
"KEY_RIGHTALT": "AltGr",
"KEY_LEFTCTRL": "Ctrl",
"KEY_RIGHTCTRL": "Ctrl",
"KEY_F13": "F13",
"KEY_F14": "F14",
"KEY_F15": "F15",
"KEY_F16": "F16",
"KEY_SCROLLLOCK": "Scroll Lock",
"KEY_PAUSE": "Pause",
"KEY_INSERT": "Insert",
"KEY_CAPSLOCK": "Caps Lock",
}


def hotkey_display_name(key_name: str) -> str:
"""Menschenlesbarer Name der Aufnahmetaste für Menü- und UI-Labels."""
return _HOTKEY_DISPLAY_NAMES.get(key_name, key_name.removeprefix("KEY_").capitalize())

# Hotkey-Definitionen: WorkflowType -> (modifier_set, trigger_key_name)
_HOTKEY_MAP = [
# (workflow, trigger_key, required_modifiers)
Expand Down
5 changes: 4 additions & 1 deletion app/workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ class WorkflowType(str, Enum):
WORKFLOW_META: Dict[WorkflowType, Dict[str, Any]] = {
WorkflowType.TRANSCRIPTION: {
"display_name": "🎙 Blitztext",
"hotkey": "Meta+H",
# Standard-Aufnahmetaste (config.transcription_hotkey: KEY_LEFTALT);
# der tatsächliche Wert ist konfigurierbar, UI-Labels leiten ihn zur
# Laufzeit über hotkey_service.hotkey_display_name() ab.
"hotkey": "Alt",
"needs_llm": False,
"description": "Standard Sprache zu Text (Online oder Lokal)",
},
Expand Down
Binary file modified docs/screenshots/linux/Banner-de.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/Banner-en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/Banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/compose-de.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/compose-en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/linux/demo-de.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/linux/demo-en.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/history-de.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/history-en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/main-window-de.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/main-window-en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/main-window-recording-de.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/main-window-recording-en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/settings-ai-workflows-de.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/settings-ai-workflows-en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/settings-general-de.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/settings-general-en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/settings-speech-de.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/settings-speech-en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/tray-menu-de.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/tray-menu-en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/tts-de.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/linux/tts-en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading