SolarFM/src/versions/solarfm-0.0.1/solarfm/core/widgets/popups/message_popup_widget.py

113 lines
3.9 KiB
Python

# Python imports
import inspect
import traceback
import time
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GLib
# Application imports
class MessagePopupWidget(Gtk.Popover):
""" MessagePopupWidget custom exception hook viewer to reroute to log Gtk text area too. """
def __init__(self):
super(MessagePopupWidget, self).__init__()
self.builder = settings.get_builder()
self.builder.expose_object(f"message_popup_widget", self)
self._message_buffer = None
self._setup_styling()
self._setup_signals()
self._load_widgets()
def _setup_styling(self):
self.set_relative_to( self.builder.get_object(f"main_menu_bar") )
self.set_modal(True)
self.set_position(Gtk.PositionType.BOTTOM)
self.set_size_request(620, 580)
def _setup_signals(self):
event_system.subscribe("show_messages_popup", self.show_messages_popup)
event_system.subscribe("hide_messages_popup", self.hide_messages_popup)
def _load_widgets(self):
self._message_buffer = Gtk.TextBuffer()
vbox = Gtk.Box()
scroll_window = Gtk.ScrolledWindow()
message_text_view = Gtk.TextView.new_with_buffer(self._message_buffer)
button = Gtk.Button(label="Save As")
button.set_image( Gtk.Image(stock=Gtk.STOCK_SAVE_AS) )
button.connect("released", self.save_debug_alerts)
button.set_always_show_image(True)
vbox.set_vexpand(True)
vbox.set_hexpand(True)
scroll_window.set_vexpand(True)
scroll_window.set_hexpand(True)
vbox.set_orientation(Gtk.Orientation.VERTICAL)
self.builder.expose_object(f"message_popup_widget", self)
self.builder.expose_object(f"message_text_view", message_text_view)
vbox.add(button)
scroll_window.add(message_text_view)
vbox.add(scroll_window)
self.add(vbox)
def show_messages_popup(self):
self.popup()
def hide_messages_popup(self):
self.popup()
def custom_except_hook(self, exec_type, value, _traceback):
trace = ''.join(traceback.format_tb(_traceback))
data = f"Exec Type: {exec_type} <--> Value: {value}\n\n{trace}\n\n\n\n"
start_itr = self._message_buffer.get_start_iter()
self._message_buffer.place_cursor(start_itr)
self.display_message(settings.get_error_color(), data)
def display_message(self, type, text, seconds=None):
self._message_buffer.insert_at_cursor(text)
self.popup()
if seconds:
self.hide_message_timeout(seconds)
@threaded
def hide_message_timeout(self, seconds=3):
time.sleep(seconds)
GLib.idle_add(event_system.emit, ("hide_messages_popup"))
def save_debug_alerts(self, widget=None, eve=None):
start_itr, end_itr = self._message_buffer.get_bounds()
save_location_prompt = Gtk.FileChooserDialog("Choose Save Folder", settings.get_main_window(), \
action = Gtk.FileChooserAction.SAVE, \
buttons = (Gtk.STOCK_CANCEL, \
Gtk.ResponseType.CANCEL, \
Gtk.STOCK_SAVE, \
Gtk.ResponseType.OK))
text = self._message_buffer.get_text(start_itr, end_itr, False)
resp = save_location_prompt.run()
if (resp == Gtk.ResponseType.CANCEL) or (resp == Gtk.ResponseType.DELETE_EVENT):
pass
elif resp == Gtk.ResponseType.OK:
target = save_location_prompt.get_filename();
with open(target, "w") as f:
f.write(text)
save_location_prompt.destroy()