183 lines
6.5 KiB
Python
183 lines
6.5 KiB
Python
# Python imports
|
|
import sys, traceback, threading, subprocess, signal, inspect, os, time
|
|
|
|
# Gtk imports
|
|
import gi
|
|
gi.require_version('Gtk', '3.0')
|
|
from gi.repository import Gtk
|
|
from gi.repository import GLib
|
|
|
|
# Application imports
|
|
from .mixins import *
|
|
from . import ShowHideMixin, KeyboardSignalsMixin, Controller_Data
|
|
|
|
|
|
def threaded(fn):
|
|
def wrapper(*args, **kwargs):
|
|
threading.Thread(target=fn, args=args, kwargs=kwargs).start()
|
|
return wrapper
|
|
|
|
|
|
class Controller(Controller_Data, ShowHideMixin, KeyboardSignalsMixin, \
|
|
WidgetFileActionMixin, PaneMixin, WindowMixin):
|
|
def __init__(self, args, unknownargs, _settings):
|
|
sys.excepthook = self.my_except_hook
|
|
self.settings = _settings
|
|
self.setup_controller_data()
|
|
|
|
self.window.show()
|
|
self.generate_windows(self.state)
|
|
|
|
self.window.connect("delete-event", self.tear_down)
|
|
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self.tear_down)
|
|
self.gui_event_observer()
|
|
|
|
if unknownargs:
|
|
for arg in unknownargs:
|
|
if os.path.isdir(arg):
|
|
message = f"FILE|{arg}"
|
|
event_system.send_ipc_message(message)
|
|
|
|
if args.new_tab and os.path.isdir(args.new_tab):
|
|
message = f"FILE|{args.new_tab}"
|
|
event_system.send_ipc_message(message)
|
|
|
|
|
|
def tear_down(self, widget=None, eve=None):
|
|
event_system.monitor_events = False
|
|
event_system.send_ipc_message("close server")
|
|
self.window_controller.save_state()
|
|
time.sleep(event_sleep_time)
|
|
Gtk.main_quit()
|
|
|
|
|
|
@threaded
|
|
def gui_event_observer(self):
|
|
while event_system.monitor_events:
|
|
time.sleep(event_sleep_time)
|
|
event = event_system.consume_gui_event()
|
|
if event:
|
|
try:
|
|
type, target, data = event
|
|
method = getattr(self.__class__, type)
|
|
GLib.idle_add(method, (self, data,))
|
|
except Exception as e:
|
|
print(repr(e))
|
|
|
|
|
|
def my_except_hook(self, exctype, value, _traceback):
|
|
trace = ''.join(traceback.format_tb(_traceback))
|
|
data = f"Exectype: {exctype} <--> 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(self.error, data)
|
|
|
|
def display_message(self, type, text, seconds=None):
|
|
self.message_buffer.insert_at_cursor(text)
|
|
self.message_widget.popup()
|
|
if seconds:
|
|
self.hide_message_timeout(seconds)
|
|
|
|
@threaded
|
|
def hide_message_timeout(self, seconds=3):
|
|
time.sleep(seconds)
|
|
GLib.idle_add(self.message_widget.popdown)
|
|
|
|
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", self.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()
|
|
|
|
|
|
def do_edit_files(self, widget=None, eve=None):
|
|
self.to_rename_files = self.selected_files
|
|
self.rename_files()
|
|
|
|
def set_arc_buffer_text(self, widget=None, eve=None):
|
|
id = widget.get_active_id()
|
|
self.arc_command_buffer.set_text(self.arc_commands[int(id)])
|
|
|
|
|
|
def execute(self, _command, start_dir=os.getenv("HOME"), use_os_system=None):
|
|
if use_os_system:
|
|
os.system(_command)
|
|
else:
|
|
DEVNULL = open(os.devnull, 'w')
|
|
command = _command.split()
|
|
subprocess.Popen(command, cwd=start_dir, shell=False, start_new_session=True, stdout=DEVNULL, stderr=DEVNULL)
|
|
|
|
def do_action_from_menu_controls(self, widget, eventbutton):
|
|
action = widget.get_name()
|
|
self.ctrlDown = True
|
|
self.hide_context_menu()
|
|
self.hide_new_file_menu()
|
|
self.hide_edit_file_menu()
|
|
|
|
if action == "execute":
|
|
self.execute_files()
|
|
if action == "execute_in_terminal":
|
|
self.execute_files(in_terminal=True)
|
|
if action == "create":
|
|
self.create_file()
|
|
self.hide_new_file_menu()
|
|
if action == "open":
|
|
self.open_files()
|
|
if action == "rename":
|
|
self.to_rename_files = self.selected_files
|
|
self.rename_files()
|
|
if action == "cut":
|
|
self.to_copy_files.clear()
|
|
self.cut_files()
|
|
if action == "copy":
|
|
self.to_cut_files.clear()
|
|
self.copy_files()
|
|
if action == "paste":
|
|
self.paste_files()
|
|
if action == "archive":
|
|
self.show_archiver_dialogue()
|
|
if action == "delete":
|
|
self.delete_files()
|
|
if action == "trash":
|
|
self.trash_files()
|
|
if action == "go_to_trash":
|
|
self.builder.get_object("path_entry").set_text(self.trash_files_path)
|
|
|
|
self.ctrlDown = False
|
|
|
|
|
|
def generate_windows(self, data = None):
|
|
if data:
|
|
for j, value in enumerate(data):
|
|
i = j + 1
|
|
isHidden = True if value[0]["window"]["isHidden"] == "True" else False
|
|
object = self.builder.get_object(f"tggl_notebook_{i}")
|
|
views = value[0]["window"]["views"]
|
|
self.window_controller.create_window()
|
|
object.set_active(True)
|
|
|
|
for view in views:
|
|
self.create_new_view_notebook(None, i, view)
|
|
|
|
if isHidden:
|
|
self.toggle_notebook_pane(object)
|
|
else:
|
|
for j in range(0, 4):
|
|
i = j + 1
|
|
self.window_controller.create_window()
|
|
self.create_new_view_notebook(None, i, None)
|