Skip to content

Commit e70c272

Browse files
committed
Bug fixes & missing translations
1 parent 18eabf8 commit e70c272

File tree

10 files changed

+2786
-2758
lines changed

10 files changed

+2786
-2758
lines changed

src/switchcraft/assets/lang/de.json

Lines changed: 1253 additions & 1257 deletions
Large diffs are not rendered by default.

src/switchcraft/assets/lang/en.json

Lines changed: 1259 additions & 1262 deletions
Large diffs are not rendered by default.

src/switchcraft/assets/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"display": "standalone",
77
"background_color": "#111315",
88
"theme_color": "#0066cc",
9-
"description": "SwitchCraft Modern Software Management (v2026.1.5b3.dev0+f487e59)",
9+
"description": "SwitchCraft Modern Software Management (v2026.1.5b3.dev0+1bfe6fb)",
1010
"icons": [
1111
{
1212
"src": "icon-192.png",

src/switchcraft/assets/splash.png

2.14 KB
Loading

src/switchcraft/gui_modern/utils/view_utils.py

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -124,22 +124,34 @@ def _safe_update(self, control=None, *args):
124124
logger.debug(f"Safe update failed (non-critical): {e}")
125125

126126
def _show_snack(self, msg, color="GREEN"):
127-
"""Show a snackbar message on the page using modern API."""
127+
"""Show a snackbar message on the page with robust compatibility."""
128128
try:
129129
page = getattr(self, "app_page", None)
130130
if not page:
131131
try:
132132
page = self.page
133133
except (RuntimeError, AttributeError):
134-
logger.warning("Failed to show snackbar: page not available (RuntimeError/AttributeError)")
134+
logger.warning("Failed to show snackbar: page not available")
135135
return
136136
if not page:
137-
logger.warning("Failed to show snackbar: page is None")
138137
return
139138

140-
page.snack_bar = ft.SnackBar(ft.Text(msg), bgcolor=color)
141-
# Use newer API for showing snackbar
142-
page.open(page.snack_bar)
139+
# Create snackbar
140+
sb = ft.SnackBar(ft.Text(msg), bgcolor=color)
141+
page.snack_bar = sb
142+
143+
# Try modern API
144+
if hasattr(page, 'open'):
145+
try:
146+
page.open(sb)
147+
page.update()
148+
return
149+
except Exception as e_modern:
150+
logger.debug(f"Modern snackbar open failed: {e_modern}")
151+
152+
# Fallback for older or specific builds
153+
sb.open = True
154+
page.update()
143155
except Exception as e:
144156
logger.warning(f"Failed to show snackbar: {e}", exc_info=True)
145157

@@ -404,7 +416,7 @@ async def async_wrapper():
404416
def _open_dialog_safe(self, dlg):
405417
"""
406418
Open a dialog safely across Flet versions and environments.
407-
Prioritizes modern 'page.open(dlg)' API, falls back to legacy 'page.dialog = dlg'.
419+
Handles both modern 'page.open(dlg)' and legacy 'page.dialog = dlg'.
408420
"""
409421
page = getattr(self, "app_page", None)
410422
if not page:
@@ -418,28 +430,24 @@ def _open_dialog_safe(self, dlg):
418430
return False
419431

420432
try:
421-
# Method 1: Modern API (Preferred)
433+
# 1. Try modern API (Preferred)
422434
if hasattr(page, 'open'):
423435
try:
424-
logger.debug("Attempting to open dialog using page.open()...")
425436
page.open(dlg)
426437
page.update()
427-
logger.info("Dialog opened successfully using page.open()")
428438
return True
429-
except Exception as e:
430-
logger.warning(f"page.open(dlg) failed: {e}. Falling back to legacy mode.")
439+
except Exception as e_modern:
440+
logger.debug(f"Modern dialog open failed: {e_modern}")
431441

432-
# Method 2: Legacy API (Fallback)
433-
logger.debug("Attempting to open dialog using legacy page.dialog...")
442+
# 2. Legacy Fallback
434443
page.dialog = dlg
435444
if hasattr(dlg, 'open'):
436445
dlg.open = True
437446
page.update()
438-
logger.info("Dialog opened using legacy page.dialog mode")
439447
return True
440448

441449
except Exception as e:
442-
logger.error(f"Failed to open dialog in any mode: {e}", exc_info=True)
450+
logger.error(f"Failed to open dialog in any mode: {e}")
443451
return False
444452

445453
def _close_dialog(self, dialog=None):
@@ -633,4 +641,51 @@ def handle_task_exception(task):
633641
logger.exception(f"Error in direct execution: {ex}")
634642
if error_msg:
635643
self._show_snack(error_msg, "RED")
636-
return False
644+
return False
645+
646+
def _copy_to_clipboard(self, text: str):
647+
"""Centralized robust clipboard copy with multiple fallbacks."""
648+
if not text:
649+
from switchcraft.utils.i18n import i18n
650+
self._show_snack(i18n.get("nothing_to_copy") or "Nothing to copy", "ORANGE")
651+
return
652+
653+
from switchcraft.utils.i18n import i18n
654+
page = getattr(self, "app_page", None) or getattr(self, "page", None)
655+
656+
# 1. Try Flet Page (Best for Web/Standard Desktop)
657+
if page:
658+
try:
659+
# set_clipboard is usually sync, but some async environments might need set_clipboard_async
660+
if hasattr(page, 'set_clipboard_async'):
661+
async def _clip(): await page.set_clipboard_async(text)
662+
self._run_task_safe(_clip)
663+
else:
664+
page.set_clipboard(text)
665+
666+
self._show_snack(i18n.get("copied_to_clipboard") or "Copied to clipboard!", "GREEN_700")
667+
return
668+
except Exception as e:
669+
logger.debug(f"Flet clipboard failed: {e}")
670+
671+
# 2. Try Pyperclip (Desktop standard)
672+
try:
673+
import pyperclip
674+
pyperclip.copy(text)
675+
self._show_snack(i18n.get("copied_to_clipboard") or "Copied to clipboard!", "GREEN_700")
676+
return
677+
except Exception as e:
678+
logger.debug(f"Pyperclip failed: {e}")
679+
680+
# 3. Fallback to Shell (Windows 'clip' or 'xdg-copy' etc via ShellUtils)
681+
try:
682+
from switchcraft.utils.shell_utils import ShellUtils
683+
import sys
684+
if sys.platform == "win32":
685+
ShellUtils.run_command(['clip'], input=text.encode('utf-8'), check=False, silent=True)
686+
self._show_snack(i18n.get("copied_to_clipboard") or "Copied to clipboard!", "GREEN_700")
687+
return
688+
except Exception as e:
689+
logger.debug(f"Shell clipboard fallback failed: {e}")
690+
691+
self._show_snack("Failed to copy to clipboard", "RED")

0 commit comments

Comments
 (0)