Files
Wire-Py/ui/menu_bar.py

199 lines
7.1 KiB
Python

import os
import subprocess
import threading
import tkinter as tk
import webbrowser
from functools import partial
from pathlib import Path
from tkinter import ttk
from logger import app_logger
from shared_libs.common_tools import ConfigManager, Tooltip
from shared_libs.gitea import GiteaUpdate
from shared_libs.animated_icon import AnimatedIcon, PIL_AVAILABLE
from shared_libs.message import MessageDialog
from shared_libs.wp_app_config import AppConfig, Msg
class MenuBar(ttk.Frame):
def __init__(self, container, image_manager, tooltip_state, on_theme_toggle, toggle_log_window, **kwargs):
super().__init__(container, **kwargs)
self.image_manager = image_manager
self.tooltip_state = tooltip_state
self.on_theme_toggle = on_theme_toggle
self.options_btn = ttk.Menubutton(self, text=Msg.STR["options"])
self.options_btn.grid(column=0, row=0)
Tooltip(self.options_btn,
Msg.TTIP["settings"], state_var=self.tooltip_state)
self.set_update = tk.IntVar()
self.settings = tk.Menu(self, relief="flat")
self.options_btn.configure(menu=self.settings, style="Toolbutton")
self.settings.add_checkbutton(
label=Msg.STR["disable_updates"],
command=lambda: self.update_setting(self.set_update.get()),
variable=self.set_update,
)
self.update_label = tk.StringVar()
self.update_label_widget = ttk.Label(self, textvariable=self.update_label)
self.update_label_widget.grid(column=4, row=0, padx=10)
self.animated_icon_frame = ttk.Frame(self)
self.animated_icon_frame.grid(column=5, row=0, padx=10)
current_theme = ConfigManager.get("theme")
bg_color = "#ffffff" if current_theme == "light" else "#333333"
self.animated_icon = AnimatedIcon(
self.animated_icon_frame, animation_type="blink", use_pillow=PIL_AVAILABLE, bg=bg_color)
self.animated_icon.pack()
self.animated_icon_frame.bind("<Button-1>", lambda e: self.updater())
self.animated_icon.bind("<Button-1>", lambda e: self.updater())
# Tooltip Menu
self.tooltip_label = tk.StringVar()
self.tooltip_update_label()
self.settings.add_command(
label=self.tooltip_label.get(), command=self.tooltips_toggle
)
# Label show dark or light
self.theme_label = tk.StringVar()
self.update_theme_label()
self.settings.add_command(
label=self.theme_label.get(), command=self.on_theme_toggle
)
# About BTN Menu / Label
self.about_btn = ttk.Button(
self, text=Msg.STR["about"], style="Toolbutton", command=self.about
)
self.about_btn.grid(column=1, row=0)
# Add a column with weight to push button to the right
self.columnconfigure(10, weight=1)
self.log_btn = ttk.Button(
self,
image=self.image_manager.get_icon("log_small"),
style="Toolbutton",
command=toggle_log_window,
)
self.log_btn.grid(column=11, row=0, sticky='e')
Tooltip(self.log_btn, "Show Log", state_var=self.tooltip_state)
self.update_thread = threading.Thread(target=self.check_for_updates, daemon=True)
self.update_thread.start()
def check_for_updates(self):
"""
Checks for updates in a separate thread.
"""
res = GiteaUpdate.api_down(
AppConfig.UPDATE_URL, AppConfig.VERSION, ConfigManager.get("updates")
)
# Schedule the UI update in the main thread
self.after(0, self.update_ui_for_update, res)
def update_ui_for_update(self, res):
self.animated_icon_frame.grid_remove()
self.animated_icon.hide()
self.update_label.set("")
tooltip_msg = ""
if res == "False":
self.set_update.set(value=1)
self.update_label.set(Msg.STR["update_search_off"])
self.update_label_widget.configure(foreground="")
tooltip_msg = Msg.TTIP["updates_disabled"]
elif res == "No Internet Connection!":
self.update_label.set(Msg.STR["no_server_connection"])
self.update_label_widget.configure(foreground="red")
tooltip_msg = Msg.TTIP["no_server_conn_tt"]
elif res == "No Updates":
self.animated_icon_frame.grid()
self.animated_icon.stop()
tooltip_msg = Msg.TTIP["up_to_date"]
else:
self.set_update.set(value=0)
self.animated_icon_frame.grid()
self.animated_icon.start()
tooltip_msg = Msg.TTIP["install_new_version"]
if not PIL_AVAILABLE:
tooltip_msg += f"\n\n{Msg.TTIP['no_pillow']}"
Tooltip(self.animated_icon_frame, tooltip_msg,
state_var=self.tooltip_state)
def updater(self):
tmp_dir = Path("/tmp/lxtools")
Path.mkdir(tmp_dir, exist_ok=True)
os.chdir(tmp_dir)
result = subprocess.run(
["/usr/local/bin/lxtools_installer"], check=False)
if result.returncode != 0:
MessageDialog("error", result.stderr)
@staticmethod
def about() -> None:
MessageDialog(
"info",
Msg.STR["about_msg"],
buttons=["OK", Msg.STR["goto_git"]],
title=Msg.STR["info"],
commands=[
None,
partial(webbrowser.open, "https://git.ilunix.de/punix/Wire-Py"),
],
icon="/usr/share/icons/lx-icons/64/wg_vpn.png",
wraplength=420,
)
def update_setting(self, update_res) -> None:
if update_res == 1:
ConfigManager.set("updates", "off")
self.update_ui_for_update("False")
else:
ConfigManager.set("updates", "on")
try:
res = GiteaUpdate.api_down(
AppConfig.UPDATE_URL, AppConfig.VERSION, "on")
self.update_ui_for_update(res)
except Exception as e:
app_logger.log(f"Error checking for updates: {e}")
self.update_ui_for_update("No Internet Connection!")
def tooltip_update_label(self) -> None:
if self.tooltip_state.get():
self.tooltip_label.set(Msg.STR["disable_tooltips"])
else:
self.tooltip_label.set(Msg.STR["enable_tooltips"])
def tooltips_toggle(self):
new_bool_state = not self.tooltip_state.get()
ConfigManager.set("tooltips", str(new_bool_state))
self.tooltip_state.set(new_bool_state)
self.tooltip_update_label()
self.settings.entryconfigure(1, label=self.tooltip_label.get())
def update_theme_label(self) -> None:
current_theme = ConfigManager.get("theme")
if current_theme == "light":
self.theme_label.set(Msg.STR["dark"])
else:
self.theme_label.set(Msg.STR["light"])
def update_theme(self):
self.update_theme_label()
self.after(100, self._update_bg)
def _update_bg(self):
current_theme = ConfigManager.get("theme")
bg_color = "#ffffff" if current_theme == "light" else "#333333"
self.animated_icon.configure(bg=bg_color)