diff --git a/src/__main__.py b/src/__main__.py index abdc793..97a80ca 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -32,7 +32,9 @@ if __name__ == "__main__": # Add long and short arguments parser.add_argument("--debug", "-d", default="false", help="Do extra console messaging.") parser.add_argument("--trace-debug", "-td", default="false", help="Disable saves, ignore IPC lock, do extra console messaging.") - parser.add_argument("--file", "-f", default="default", help="JUST SOME FILE ARG.") + parser.add_argument("--no-plugins", "-np", default="false", help="Do not load plugins.") + parser.add_argument("--new-tab", "-t", default="", help="Open a file into new tab.") + parser.add_argument("--new-window", "-w", default="", help="Open a file into a new window.") # Read arguments (If any...) args, unknownargs = parser.parse_known_args() diff --git a/src/app.py b/src/app.py index 1ea9b36..dc32ca4 100644 --- a/src/app.py +++ b/src/app.py @@ -26,7 +26,7 @@ class Application(IPCServer): if not self.is_ipc_alive: for arg in unknownargs + [args.new_tab,]: - if os.path.isdir(arg): + if os.path.isfile(arg): message = f"FILE|{arg}" self.send_ipc_message(message) diff --git a/src/core/controller.py b/src/core/controller.py index 9024c7f..841f46d 100644 --- a/src/core/controller.py +++ b/src/core/controller.py @@ -1,4 +1,5 @@ # Python imports +import os # Lib imports import gi @@ -23,6 +24,14 @@ class Controller(SignalsMixins, ControllerData): self._setup_signals() self._subscribe_to_events() + if args.no_plugins == "false": + self.plugins.launch_plugins() + + for arg in unknownargs + [args.new_tab,]: + if os.path.isfile(arg): + message = f"FILE|{arg}" + event_system.emit("post_file_to_ipc", message) + def _setup_styling(self): ... diff --git a/src/core/core_widget.py b/src/core/core_widget.py index 81966df..a5a9d3b 100644 --- a/src/core/core_widget.py +++ b/src/core/core_widget.py @@ -7,8 +7,8 @@ from gi.repository import Gtk # Application imports from .widgets.base.banner_controls import BannerControls -from .widgets.base.notebook.editor_notebook import EditorNotebook -from .widgets.base.bottom_status_info_widget import BottomStatusInfoWidget +from .editors_container import EditorsContainer +from .widgets.base.general_info_widget import GeneralInfoWidget @@ -34,6 +34,5 @@ class CoreWidget(Gtk.Box): def _load_widgets(self): self.add(BannerControls()) - self.add(EditorNotebook()) - - BottomStatusInfoWidget() + GeneralInfoWidget() + self.add(EditorsContainer()) diff --git a/src/core/editors_container.py b/src/core/editors_container.py new file mode 100644 index 0000000..caec6fe --- /dev/null +++ b/src/core/editors_container.py @@ -0,0 +1,37 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from .widgets.base.notebook.editor_notebook import EditorNotebook + + + +class EditorsContainer(Gtk.Paned): + def __init__(self): + super(EditorsContainer, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show() + + + def _setup_styling(self): + self.set_wide_handle(True) + self.set_vexpand(True) + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + self.add1(EditorNotebook()) + self.add2(EditorNotebook()) diff --git a/src/core/mixins/signals/ipc_signals_mixin.py b/src/core/mixins/signals/ipc_signals_mixin.py index 34c6555..acd4717 100644 --- a/src/core/mixins/signals/ipc_signals_mixin.py +++ b/src/core/mixins/signals/ipc_signals_mixin.py @@ -6,12 +6,12 @@ - class IPCSignalsMixin: """ IPCSignalsMixin handle messages from another starting solarfm process. """ def print_to_console(self, message=None): print(message) - def handle_file_from_ipc(self, path: str) -> None: - print(f"Path From IPC: {path}") + def handle_file_from_ipc(self, path: any) -> None: + logger.debug(f"Path From IPC: {path}") + event_system.emit("create_view", (path,)) diff --git a/src/core/widgets/base/bottom_status_info_widget.py b/src/core/widgets/base/general_info_widget.py similarity index 61% rename from src/core/widgets/base/bottom_status_info_widget.py rename to src/core/widgets/base/general_info_widget.py index 2c9bbf3..de4ea9f 100644 --- a/src/core/widgets/base/bottom_status_info_widget.py +++ b/src/core/widgets/base/general_info_widget.py @@ -12,13 +12,13 @@ from gi.repository import Gio # NOTE: https://github.com/rwaldron/gtksourceview/blob/master/tests/test-widget.py -class BottomStatusInfoWidget: - """docstring for BottomStatusInfoWidget.""" +class GeneralInfoWidget: + """ docstring for StatusInfoWidget. """ def __init__(self): - super(BottomStatusInfoWidget, self).__init__() + super(GeneralInfoWidget, self).__init__() - _GLADE_FILE = f"{settings.get_ui_widgets_path()}/bottom_status_info_ui.glade" + _GLADE_FILE = f"{settings.get_ui_widgets_path()}/general_info_ui.glade" self._builder = Gtk.Builder() self._builder.add_from_file(_GLADE_FILE) @@ -45,11 +45,11 @@ class BottomStatusInfoWidget: def _load_widgets(self): builder = settings.get_builder() - self.bottom_status_info = self._builder.get_object("bottom_status_info") - self.bottom_path_label = self._builder.get_object("bottom_path_label") - self.bottom_encoding_label = self._builder.get_object("bottom_encoding_label") - self.bottom_line_char_label = self._builder.get_object("bottom_line_char_label") - self.bottom_file_type_label = self._builder.get_object("bottom_file_type_label") + self.bottom_status_info = self._builder.get_object("general_info") + self.bottom_path_label = self._builder.get_object("path_label") + self.bottom_encoding_label = self._builder.get_object("encoding_label") + self.bottom_line_char_label = self._builder.get_object("line_char_label") + self.bottom_file_type_label = self._builder.get_object("file_type_label") builder.expose_object(f"bottom_status_info", self.bottom_status_info) builder.expose_object(f"bottom_path_label", self.bottom_path_label) @@ -63,22 +63,25 @@ class BottomStatusInfoWidget: builder.get_object("core_widget").add(self.bottom_status_info) - def set_bottom_labels(self, gfile, info): - self.bottom_path_label.set_text( gfile.get_path() ) - self.bottom_path_label.set_tooltip_text( gfile.get_path() ) + def set_bottom_labels(self, path = None, line_char = None, file_type = None, encoding_type = None): + self._set_path_label(path) + self._set_line_char_label() + self._set_file_type_label(file_type) + self._set_encoding_label() - self.bottom_encoding_label.set_text("utf-8") - self.bottom_line_char_label.set_text("1:1") - self.bottom_file_type_label.set_text( info.get_content_type() ) + def _set_path_label(self, gfile = ""): + if isinstance(gfile, str): + self.bottom_path_label.set_text( gfile ) + self.bottom_path_label.set_tooltip_text( gfile ) + else: + self.bottom_path_label.set_text( gfile.get_path() ) + self.bottom_path_label.set_tooltip_text( gfile.get_path() ) - def _set_path_label(self): - ... + def _set_line_char_label(self, line_char = "1:1"): + self.bottom_line_char_label.set_text(line_char) - def _set_encoding_label(self): - ... + def _set_file_type_label(self, file_type = "buffer"): + self.bottom_file_type_label.set_text(file_type) - def _set_line_char_label(self, label = "0:0"): - self.bottom_line_char_label.set_text(label) - - def _set_file_type_label(self): - ... + def _set_encoding_label(self, encoding_type = "utf-8"): + self.bottom_encoding_label.set_text(encoding_type) diff --git a/src/core/widgets/base/notebook/editor_controller.py b/src/core/widgets/base/notebook/editor_controller.py index 354908d..5d9a640 100644 --- a/src/core/widgets/base/notebook/editor_controller.py +++ b/src/core/widgets/base/notebook/editor_controller.py @@ -7,11 +7,18 @@ class EditorControllerMixin: - def action_controller(self, action = "", query = ""): + def get_active_view(self): page_num = self.get_current_page() container = self.get_nth_page( page_num ) source_view = container.get_source_view() + return page_num, container, source_view + def action_controller(self, action = "", query = ""): + # NOTE: Not efficent here as multiple same calls + if not self.is_editor_focused: # TODO: Find way to converge this + return + + page_num, container, source_view = self.get_active_view() if action == "do_text_search": self.do_text_search(source_view, query) if action == "set_buffer_language": @@ -30,6 +37,14 @@ class EditorControllerMixin: self.keyboard_prev_tab(page_num) if action == "keyboard_next_tab": self.keyboard_next_tab(page_num) + if action == "keyboard_move_tab_left": + self.keyboard_move_tab_left(page_num) + if action == "keyboard_move_tab_right": + self.keyboard_move_tab_right(page_num) + if action == "keyboard_move_tab_to_1": + self.keyboard_move_tab_to_1(page_num) + if action == "keyboard_move_tab_to_2": + self.keyboard_move_tab_to_2(page_num) if action == "save_file": source_view.save_file() if action == "save_file_as": diff --git a/src/core/widgets/base/notebook/editor_events.py b/src/core/widgets/base/notebook/editor_events.py index 162c078..acd76d8 100644 --- a/src/core/widgets/base/notebook/editor_events.py +++ b/src/core/widgets/base/notebook/editor_events.py @@ -3,42 +3,49 @@ # Lib imports # Application imports +from ..sourceview_container import SourceViewContainer class EditorEventsMixin: - def _toggle_highlight_line(self): - self.action_controller("toggle_highlight_line") + def create_view(self, widget = None, eve = None, gfile = None): + container = SourceViewContainer(self.close_tab) - def _keyboard_close_tab(self): - self.action_controller("close_tab") + page_num = self.append_page(container, container.get_tab_widget()) + self.set_tab_detachable(container, True) - def _keyboard_open_file(self, gfile): - self.open_file(gfile) + ctx = self.get_style_context() + ctx.add_class("notebook-unselected-focus") + self.set_tab_reorderable(container, True) - def _keyboard_create_tab(self, _gfile=None): - self.create_view(gfile=_gfile) + if gfile: + source_view = container.get_source_view() + source_view.open_file(gfile) - def _keyboard_next_tab(self): - self.action_controller("keyboard_next_tab") + self.show_all() + self.set_current_page(page_num) - def _keyboard_prev_tab(self): - self.action_controller("keyboard_prev_tab") + def open_file(self, gfile): + page_num = self.get_current_page() + container = self.get_nth_page( page_num ) + source_view = container.get_source_view() - def _keyboard_scale_up_text(self): - self.action_controller("scale_up_text") + if source_view._current_filename == "": + source_view.open_file(gfile) + else: + self.create_view(None, None, gfile) - def _keyboard_scale_down_text(self): - self.action_controller("scale_down_text") + def close_tab(self, button, container, source_view, eve = None): + if self.NAME == "notebook_1" and self.get_n_pages() == 1: + return - def _keyboard_save_file(self): - self.action_controller("save_file") + page_num = self.page_num(container) + source_view._cancel_current_file_watchers() + self.remove_page(page_num) - def _keyboard_save_file_as(self): - self.action_controller("save_file_as") + if self.NAME == "notebook_2" and self.get_n_pages() == 0: + self.hide() - def _text_search(self, widget = None, eve = None): - self.action_controller("do_text_search", widget.get_text()) def do_text_search(self, query = ""): source_view.scale_down_text() @@ -57,6 +64,48 @@ class EditorEventsMixin: page_num = 0 if self.get_n_pages() - 1 == page_num else page_num + 1 self.set_current_page(page_num) + def keyboard_move_tab_to_1(self, page_num): + notebook = self.builder.get_object("notebook_1") + if self.NAME == "notebook_1": + if self.get_n_pages() == 1: + return + + notebook = self.builder.get_object("notebook_2") + + page = self.get_nth_page(page_num) + tab = page.get_tab_widget() + self.detach_tab(page) + + notebook.insert_page(page, tab, -1) + notebook.show() + + def keyboard_move_tab_to_2(self, page_num): + if self.NAME == "notebook_1" and self.get_n_pages() == 1: + return + + notebook = self.builder.get_object("notebook_2") + if self.NAME == "notebook_2": + notebook = self.builder.get_object("notebook_1") + + page = self.get_nth_page(page_num) + tab = page.get_tab_widget() + self.detach_tab(page) + + notebook.insert_page(page, tab, -1) + notebook.show() + if self.NAME == "notebook_2" and self.get_n_pages() == 0: + self.hide() + + def keyboard_move_tab_left(self, page_num): + page = self.get_nth_page(page_num) + page_num = self.get_n_pages() - 1 if page_num == 0 else page_num - 1 + self.reorder_child(page, page_num) + + def keyboard_move_tab_right(self, page_num): + page = self.get_nth_page(page_num) + page_num = 0 if self.get_n_pages() - 1 == page_num else page_num + 1 + self.reorder_child(page, page_num) + def scale_up_text(self, source_view): source_view.scale_up_text() diff --git a/src/core/widgets/base/notebook/editor_notebook.py b/src/core/widgets/base/notebook/editor_notebook.py index e058822..5bc2923 100644 --- a/src/core/widgets/base/notebook/editor_notebook.py +++ b/src/core/widgets/base/notebook/editor_notebook.py @@ -9,7 +9,6 @@ from gi.repository import Gdk from gi.repository import Gio # Application imports -from ..sourceview_container import SourceViewContainer from .editor_controller import EditorControllerMixin from .editor_events import EditorEventsMixin @@ -18,10 +17,23 @@ from .editor_events import EditorEventsMixin # NOTE: https://github.com/Axel-Erfurt/TextEdit/tree/b65f09be945196eb05bef83d81a6abcd129b4eb0 class EditorNotebook(EditorEventsMixin, EditorControllerMixin, Gtk.Notebook): + ccount = 0 + + def __new__(cls, *args, **kwargs): + obj = super(EditorNotebook, cls).__new__(cls) + cls.ccount += 1 + + return obj + def __init__(self): super(EditorNotebook, self).__init__() + self.NAME = f"notebook_{self.ccount}" + self.is_editor_focused = False self.set_group_name("editor_widget") + self.builder = settings.get_builder() + + self.builder.expose_object(self.NAME, self) self._add_action_widgets() self._setup_styling() @@ -31,6 +43,10 @@ class EditorNotebook(EditorEventsMixin, EditorControllerMixin, Gtk.Notebook): self.show_all() + print(self.NAME) + if self.NAME == "notebook_2": + self.hide() + def _setup_styling(self): self.set_scrollable(True) @@ -42,7 +58,7 @@ class EditorNotebook(EditorEventsMixin, EditorControllerMixin, Gtk.Notebook): def _subscribe_to_events(self): # event_system.subscribe("set_buffer_language", self.action_controller, *("set_buffer_language",)) - event_system.subscribe("create_view", self.create_view) + event_system.subscribe("create_view", self._create_view) event_system.subscribe("set_buffer_style", self.action_controller) event_system.subscribe("set_buffer_language", self.action_controller) event_system.subscribe("set_buffer_style", self.action_controller) @@ -52,10 +68,19 @@ class EditorNotebook(EditorEventsMixin, EditorControllerMixin, Gtk.Notebook): event_system.subscribe("keyboard_close_tab", self._keyboard_close_tab) event_system.subscribe("keyboard_prev_tab", self._keyboard_prev_tab) event_system.subscribe("keyboard_next_tab", self._keyboard_next_tab) + event_system.subscribe("keyboard_move_tab_left", self._keyboard_move_tab_left) + event_system.subscribe("keyboard_move_tab_right", self._keyboard_move_tab_right) + event_system.subscribe("keyboard_move_tab_to_1", self._keyboard_move_tab_to_1) + event_system.subscribe("keyboard_move_tab_to_2", self._keyboard_move_tab_to_2) event_system.subscribe("keyboard_scale_up_text", self._keyboard_scale_up_text) event_system.subscribe("keyboard_scale_down_text", self._keyboard_scale_down_text) event_system.subscribe("keyboard_save_file", self._keyboard_save_file) event_system.subscribe("keyboard_save_file_as", self._keyboard_save_file_as) + event_system.subscribe("focused_target_changed", self._focused_target_changed) + + + def _focused_target_changed(self, target): + self.is_editor_focused = True if target == self.NAME else False def _add_action_widgets(self): start_box = Gtk.Box() @@ -81,7 +106,8 @@ class EditorNotebook(EditorEventsMixin, EditorControllerMixin, Gtk.Notebook): self.set_action_widget(end_box, 1) def _load_widgets(self): - self.create_view() + if self.NAME == "notebook_1": + self.create_view() def _dbl_click_create_view(self, notebook, eve): if eve.type == Gdk.EventType.DOUBLE_BUTTON_PRESS and eve.button == 1: # l-click @@ -93,38 +119,67 @@ class EditorNotebook(EditorEventsMixin, EditorControllerMixin, Gtk.Notebook): if gfile: source_view.load_file_info( gfile ) source_view.update_cursor_position() - - def create_view(self, widget = None, eve = None, gfile = None): - container = SourceViewContainer(self.close_tab) - - index = self.append_page(container, container.get_tab_widget()) - self.set_tab_detachable(container, True) - - ctx = self.get_style_context() - ctx.add_class("notebook-unselected-focus") - self.set_tab_reorderable(container, True) - - if gfile: - source_view = container.get_source_view() - source_view.open_file(gfile) - - self.show_all() - self.set_current_page(index) - - def open_file(self, gfile): - page_num = self.get_current_page() - container = self.get_nth_page( page_num ) - source_view = container.get_source_view() - - if source_view._current_filename == "": - source_view.open_file(gfile) else: - self.create_view(None, None, gfile) + event_system.emit("set_path_label", ("",)) + event_system.emit("set_file_type_label", (source_view._current_filetype,)) - def close_tab(self, button, container, source_view, eve = None): - if self.get_n_pages() == 1: + def _create_view(self, gfile = None): + if not self.is_editor_focused: # TODO: Find way to converge this return - page_num = self.page_num(container) - source_view._cancel_current_file_watchers() - self.remove_page(page_num) + if isinstance(gfile, str): + gfile = Gio.File.new_for_path(gfile) + + self.create_view(None, None, gfile,) + + def _keyboard_open_file(self, gfile): + if not self.is_editor_focused: # TODO: Find way to converge this + return + + self.open_file(gfile) + + def _keyboard_create_tab(self, _gfile=None): + if not self.is_editor_focused: # TODO: Find way to converge this + return + + self.create_view(gfile=_gfile) + + + def _keyboard_close_tab(self): + self.action_controller("close_tab") + + def _toggle_highlight_line(self): + self.action_controller("toggle_highlight_line") + + def _keyboard_next_tab(self): + self.action_controller("keyboard_next_tab") + + def _keyboard_move_tab_left(self): + self.action_controller("keyboard_move_tab_left") + + def _keyboard_move_tab_right(self): + self.action_controller("keyboard_move_tab_right") + + def _keyboard_move_tab_to_1(self): + self.action_controller("keyboard_move_tab_to_1") + + def _keyboard_move_tab_to_2(self): + self.action_controller("keyboard_move_tab_to_2") + + def _keyboard_prev_tab(self): + self.action_controller("keyboard_prev_tab") + + def _keyboard_scale_up_text(self): + self.action_controller("scale_up_text") + + def _keyboard_scale_down_text(self): + self.action_controller("scale_down_text") + + def _keyboard_save_file(self): + self.action_controller("save_file") + + def _keyboard_save_file_as(self): + self.action_controller("save_file_as") + + def _text_search(self, widget = None, eve = None): + self.action_controller("do_text_search", widget.get_text()) diff --git a/src/core/widgets/base/sourceview/source_view.py b/src/core/widgets/base/sourceview/source_view.py index f1d3f18..7582fe6 100644 --- a/src/core/widgets/base/sourceview/source_view.py +++ b/src/core/widgets/base/sourceview/source_view.py @@ -21,19 +21,22 @@ class SourceView(SourceViewEventsMixin, GtkSource.View): def __init__(self): super(SourceView, self).__init__() - self._language_manager = GtkSource.LanguageManager() - self._style_scheme_manager = GtkSource.StyleSchemeManager() + self._language_manager = GtkSource.LanguageManager() + self._style_scheme_manager = GtkSource.StyleSchemeManager() - self._general_style_tag = None - self._file_change_watcher = None - self._file_cdr_watcher = None + self._general_style_tag = None + self._file_loader = None + self._file_change_watcher = None + self._file_cdr_watcher = None + self._last_eve_in_queue = None + self._current_file: Gio.File = None + + self._current_filename: str = "" + self._current_filepath: str = None + self._current_filetype: str = "buffer" self._is_changed = False self._ignore_internal_change = False - self._last_eve_in_queue = None - self._current_file: Gio.File = None - self._current_filename: str = "" - self._file_loader = None self._buffer = self.get_buffer() self._completion = self.get_completion() @@ -48,7 +51,6 @@ class SourceView(SourceViewEventsMixin, GtkSource.View): self._file_filter_all.set_name("All Files") self._file_filter_all.add_pattern("*.*") - self._setup_styling() self._setup_signals() self._set_up_dnd() @@ -108,13 +110,38 @@ class SourceView(SourceViewEventsMixin, GtkSource.View): self._general_style_tag.set_property('size', 100) self._general_style_tag.set_property('scale', 100) + def _is_modified(self, *args): + self._is_changed = True + self.update_cursor_position() + + def _on_cursor_move(self, buf, cursor_iter, mark, user_data = None): + if mark != buf.get_insert(): return + + target = self.get_parent().get_parent().NAME + path = self._current_file if self._current_file else "" + + event_system.emit('focused_target_changed', (target,)) + event_system.emit("set_path_label", (path,)) + event_system.emit("set_encoding_label") + event_system.emit("set_file_type_label", (self._current_filetype,)) + self.update_cursor_position() + def _set_up_dnd(self): - URI_TARGET_TYPE = 80 - uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE) - targets = [ uri_target ] + WIDGET_TARGET_TYPE = 70 + URI_TARGET_TYPE = 80 + widget_target = Gtk.TargetEntry.new('dummy', Gtk.TargetFlags(0), WIDGET_TARGET_TYPE) + uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE) + targets = [ widget_target, uri_target ] self.drag_dest_set_target_list(targets) def _on_drag_data_received(self, widget, drag_context, x, y, data, info, time): + if info == 70: + print(drag_context) + print(data) + print(info) + # detach_tab(child) + return + if info == 80: uris = data.get_uris() @@ -141,14 +168,6 @@ class SourceView(SourceViewEventsMixin, GtkSource.View): event_system.emit('create_view', (None, None, gfile,)) - def _is_modified(self, *args): - self._is_changed = True - self.update_cursor_position() - - def _on_cursor_move(self, buf, cursor_iter, mark, user_data = None): - if mark != buf.get_insert(): return - - self.update_cursor_position() def _create_file_watcher(self, gfile = None): if not gfile: return @@ -186,37 +205,6 @@ class SourceView(SourceViewEventsMixin, GtkSource.View): self._file_cdr_watcher.cancel() self._file_cdr_watcher = None - def save_file(self): - if not self._current_file: - self.save_file_as() - return - - self._write_file(self._current_file) - - - def save_file_as(self): - # TODO: Move Chooser logic to own widget - dlg = Gtk.FileChooserDialog(title="Please choose a file...", parent = None, action = 1) - - dlg.add_buttons("Cancel", Gtk.ResponseType.CANCEL, "Save", Gtk.ResponseType.OK) - dlg.set_do_overwrite_confirmation(True) - dlg.add_filter(self._file_filter_text) - dlg.add_filter(self._file_filter_all) - - if self._current_filename == "": - dlg.set_current_name("new.txt") - else: - dlg.set_current_folder(self._current_file.get_parent().get_path()) - dlg.set_current_name(self._current_filename) - - response = dlg.run() - file = dlg.get_filename() if response == Gtk.ResponseType.OK else "" - dlg.destroy() - - if not file == "": - gfile = Gio.File.new_for_path(file) - self._write_file(gfile, True) - def _write_file(self, gfile, save_as = False): with open(gfile.get_path(), 'w') as f: if not save_as: diff --git a/src/core/widgets/base/sourceview/source_view_events.py b/src/core/widgets/base/sourceview/source_view_events.py index 4c7540a..6d22a50 100644 --- a/src/core/widgets/base/sourceview/source_view_events.py +++ b/src/core/widgets/base/sourceview/source_view_events.py @@ -5,6 +5,7 @@ import gi gi.require_version('Gtk', '3.0') gi.require_version('GtkSource', '4') from gi.repository import Gtk +from gi.repository import Gio from gi.repository import GtkSource # Application imports @@ -77,22 +78,52 @@ class SourceViewEventsMixin: self._create_file_watcher(gfile) self.grab_focus() + def save_file(self): + if not self._current_file: + self.save_file_as() + return + + self._write_file(self._current_file) + + def save_file_as(self): + # TODO: Move Chooser logic to own widget + dlg = Gtk.FileChooserDialog(title="Please choose a file...", parent = None, action = 1) + + dlg.add_buttons("Cancel", Gtk.ResponseType.CANCEL, "Save", Gtk.ResponseType.OK) + dlg.set_do_overwrite_confirmation(True) + dlg.add_filter(self._file_filter_text) + dlg.add_filter(self._file_filter_all) + + if self._current_filename == "": + dlg.set_current_name("new.txt") + else: + dlg.set_current_folder(self._current_file.get_parent().get_path()) + dlg.set_current_name(self._current_filename) + + response = dlg.run() + file = dlg.get_filename() if response == Gtk.ResponseType.OK else "" + dlg.destroy() + + if not file == "": + gfile = Gio.File.new_for_path(file) + self._write_file(gfile, True) + def load_file_info(self, gfile): info = gfile.query_info("standard::*", 0, cancellable=None) content_type = info.get_content_type() display_name = info.get_display_name() - tab_widget = self.get_parent().get_tab_widget() self._current_filename = display_name try: lm = self._language_manager.guess_language(None, content_type) - self.set_buffer_language( lm.get_id() ) + self._current_filetype = lm.get_id() + self.set_buffer_language(self._current_filetype) except Exception as e: ... logger.debug(f"Detected Content Type: {content_type}") - tab_widget.set_tab_label(display_name) - event_system.emit("set_bottom_labels", (gfile, info)) + if self._current_filetype == "buffer": + self._current_filetype = info.get_content_type() def load_file_async(self, gfile): file = GtkSource.File() @@ -104,6 +135,10 @@ class SourceViewEventsMixin: self._is_changed = False self._document_loaded() + tab_widget = self.get_parent().get_tab_widget() + tab_widget.set_tab_label(self._current_filename) + event_system.emit("set_bottom_labels", (gfile, None, self._current_filetype, None)) + self._file_loader.load_async(io_priority = 98, cancellable = None, progress_callback = None, diff --git a/src/utils/ipc_server.py b/src/utils/ipc_server.py index 8226247..2ad105f 100644 --- a/src/utils/ipc_server.py +++ b/src/utils/ipc_server.py @@ -6,6 +6,7 @@ from multiprocessing.connection import Client from multiprocessing.connection import Listener # Lib imports +from gi.repository import GLib # Application imports @@ -56,17 +57,19 @@ class IPCServer: @daemon_threaded def _run_ipc_loop(self, listener) -> None: while True: - conn = listener.accept() - start_time = time.perf_counter() - self._handle_ipc_message(conn, start_time) + try: + conn = listener.accept() + start_time = time.perf_counter() + GLib.idle_add(self._handle_ipc_message, *(conn, start_time,)) + except Exception as e: + ... listener.close() def _handle_ipc_message(self, conn, start_time) -> None: while True: msg = conn.recv() - if settings.is_debug(): - print(msg) + logger.debug(msg) if "FILE|" in msg: file = msg.split("FILE|")[1].strip() diff --git a/user_config/bin/newton b/user_config/bin/newton index 9626164..2852326 100755 --- a/user_config/bin/newton +++ b/user_config/bin/newton @@ -18,8 +18,8 @@ function main() { fi # NOTE: Remove if you want to pass file(s) besides directories... - if [ ! -d "${path}" ]; then - echo "Newton: Path given not a directory..." + if [ ! -f "${path}" ]; then + echo "Newton: Path given not a file..." exit 1 fi diff --git a/user_config/usr/share/newton/key-bindings.json b/user_config/usr/share/newton/key-bindings.json index 2dea9c7..0040e24 100644 --- a/user_config/usr/share/newton/key-bindings.json +++ b/user_config/usr/share/newton/key-bindings.json @@ -14,8 +14,12 @@ "keyboard_down" : "Down", "keyboard_left" : "Left", "keyboard_riht" : "Right", - "keyboard_prev_tab" : "Page_Up", - "keyboard_next_tab" : "Page_Down", + "keyboard_move_tab_to_1" : "Down", + "keyboard_move_tab_to_2" : "Up", + "keyboard_move_tab_right" : "Right", + "keyboard_move_tab_left" : "Left", + "keyboard_next_tab" : "Up", + "keyboard_prev_tab" : "Down", "keyboard_scale_up_text" : "equal", "keyboard_scale_down_text" : "minus" } diff --git a/user_config/usr/share/newton/ui_widgets/bottom_status_info_ui.glade b/user_config/usr/share/newton/ui_widgets/general_info_ui.glade similarity index 88% rename from user_config/usr/share/newton/ui_widgets/bottom_status_info_ui.glade rename to user_config/usr/share/newton/ui_widgets/general_info_ui.glade index f3ee0e4..7594499 100644 --- a/user_config/usr/share/newton/ui_widgets/bottom_status_info_ui.glade +++ b/user_config/usr/share/newton/ui_widgets/general_info_ui.glade @@ -2,7 +2,7 @@ - + True False 10 @@ -14,7 +14,7 @@ 15 top - + True False True @@ -27,7 +27,7 @@ - + True False start @@ -41,7 +41,7 @@ - + True False @@ -53,7 +53,7 @@ - + True False