Commit d540da37 authored by Roman Alifanov's avatar Roman Alifanov

CustomSetting: Can now create a notification (Toast) as well as callbacks:

NOTIFY:some message:seconds
parent 8e32b9d5
......@@ -131,21 +131,50 @@ class CustomSetting:
def _get_default_row_index(self):
return list(self.map.values()).index(self.default) if self.default in self.map.values() else None
def _execute_command(self, cmd, capture_output=True):
with subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
shell=True,
bufsize=1
) as p:
output = []
def process_line(line):
line = line.strip()
if not line:
return
if line.startswith('CALLBACK:'):
self._handle_callback(line)
elif line.startswith('NOTIFY:'):
self._handle_notify(line)
elif capture_output:
output.append(line)
while p.poll() is None:
line = p.stdout.readline()
process_line(line)
for line in p.stdout.read().splitlines():
process_line(line)
stderr = p.stderr.read().strip()
if p.returncode != 0:
raise subprocess.CalledProcessError(p.returncode, cmd, stderr=stderr)
return '\n'.join(output) if capture_output else ''
def _execute_get_command(self):
if not self.get_command:
return self.default
try:
cmd = self._format_command(self.get_command)
result = subprocess.run(
cmd,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
shell=True
)
return self._process_output(result.stdout)
output = self._execute_command(cmd)
return output
except subprocess.CalledProcessError as e:
self.logger.error(f"Get command failed: {e.stderr}")
return self.default
......@@ -156,16 +185,7 @@ class CustomSetting:
try:
cmd = self._format_command(self.set_command, value)
result = subprocess.run(
cmd,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
shell=True
)
self._process_output(result.stdout)
self._execute_command(cmd, capture_output=False)
return True
except subprocess.CalledProcessError as e:
self.logger.error(f"Set command failed: {e.stderr}")
......@@ -177,15 +197,8 @@ class CustomSetting:
try:
cmd = self._format_command(self.get_range_command)
result = subprocess.run(
cmd,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
shell=True
)
return ast.literal_eval(self._process_output(result.stdout))
output = self._execute_command(cmd)
return ast.literal_eval(output)
except subprocess.CalledProcessError as e:
self.logger.error(f"Get range command failed: {e.stderr}")
return None
......@@ -198,16 +211,6 @@ class CustomSetting:
}
return template.format(**variables)
def _process_output(self, output):
lines = []
for line in output.split('\n'):
line = line.strip()
if line.startswith('CALLBACK:'):
self._handle_callback(line)
else:
lines.append(line)
return '\n'.join(lines).strip()
def _handle_callback(self, line):
try:
_, action, target, value = line.split(':', 3)
......@@ -219,6 +222,23 @@ class CustomSetting:
except ValueError:
self.logger.error(f"Invalid callback format: {line}")
def _handle_notify(self, line):
self.logger.debug("handled notify")
try:
parts = line.split(':', 2)
parts += [None] * (3 - len(parts))
_, notification, seconds = parts
from ...main import get_main_window
get_main_window().setting_notify(
self.module.name,
self._(notification),
int(seconds) if seconds else None
)
except ValueError:
self.logger.error(f"Invalid notify format: {line}")
def _update_widget(self):
if self.widget:
self.widget.update_display()
......
......@@ -47,7 +47,7 @@ template $TuneitWindow: Adw.ApplicationWindow {
name: "settings";
title: _("Settings");
child: Adw.NavigationSplitView settings_split_view {
child: Adw.ToastOverlay settings_toast_overlay { child: Adw.NavigationSplitView settings_split_view {
hexpand: true;
content: Adw.NavigationPage {
......@@ -104,7 +104,7 @@ template $TuneitWindow: Adw.ApplicationWindow {
}
}
};
};
}; };
}
Adw.ViewStackPage {
......@@ -112,7 +112,7 @@ template $TuneitWindow: Adw.ApplicationWindow {
name: "shop";
title: _("Shop");
child: Box {};
child: Box {};
}
}
......
......@@ -28,6 +28,9 @@ from .settings.widgets.error_dialog import TuneItErrorDialog
class TuneitWindow(Adw.ApplicationWindow):
__gtype_name__ = 'TuneitWindow'
settings_toast_overlay = Gtk.Template.Child()
settings_pagestack = Gtk.Template.Child()
settings_listbox = Gtk.Template.Child()
settings_split_view = Gtk.Template.Child()
......@@ -58,12 +61,15 @@ class TuneitWindow(Adw.ApplicationWindow):
Можно вызвать вот так, благодаря сигналу:
self.settings_pagestack.get_root().emit("settings_page_update")
"""
self.setting_notify("Tune It", "Init settings...")
try:
init_settings_stack(
self.settings_pagestack,
self.settings_listbox,
self.settings_split_view,
)
self.setting_notify("Tune It", "Settings are initialized!")
except Exception as e:
self.error(traceback.format_exc())
......@@ -72,3 +78,14 @@ class TuneitWindow(Adw.ApplicationWindow):
self.error_dialog.textbuffer.set_text(str(error))
GLib.idle_add(self.error_dialog.present, self)
def setting_notify(self, module_name: str, notify: str, seconds: int = 5) -> None:
seconds = 5 if seconds is None else seconds
GLib.idle_add(self.settings_toast_overlay.dismiss_all)
toast = Adw.Toast(
title=f"{module_name}: {notify}",
timeout=seconds,
)
GLib.idle_add(self.settings_toast_overlay.add_toast, toast)
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment