2023-03-21 03:19:20 +00:00
|
|
|
# Python imports
|
|
|
|
|
|
|
|
# Lib imports
|
2023-03-22 07:12:40 +00:00
|
|
|
import gi
|
|
|
|
gi.require_version('Gtk', '3.0')
|
|
|
|
gi.require_version('GtkSource', '4')
|
|
|
|
from gi.repository import Gtk
|
2023-03-26 06:07:35 +00:00
|
|
|
from gi.repository import Gio
|
2023-03-22 07:12:40 +00:00
|
|
|
from gi.repository import GtkSource
|
2023-03-21 03:19:20 +00:00
|
|
|
|
|
|
|
# Application imports
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SourceViewEventsMixin:
|
2023-03-23 04:03:16 +00:00
|
|
|
def get_current_file(self):
|
|
|
|
return self._current_file
|
|
|
|
|
2023-03-21 03:19:20 +00:00
|
|
|
def set_buffer_language(self, language = "python3"):
|
|
|
|
self._buffer.set_language( self._language_manager.get_language(language) )
|
|
|
|
|
|
|
|
def set_buffer_style(self, style = "tango"):
|
|
|
|
self._buffer.set_style_scheme( self._style_scheme_manager.get_scheme(style) )
|
|
|
|
|
|
|
|
def toggle_highlight_line(self, widget = None, eve = None):
|
|
|
|
self.set_highlight_current_line( not self.get_highlight_current_line() )
|
|
|
|
|
|
|
|
def scale_up_text(self, scale_step = 10):
|
|
|
|
current_scale = self._general_style_tag.get_property('scale')
|
|
|
|
start_itr = self._buffer.get_start_iter()
|
|
|
|
end_itr = self._buffer.get_end_iter()
|
|
|
|
|
|
|
|
self._general_style_tag.set_property('scale', current_scale + scale_step)
|
|
|
|
self._buffer.apply_tag(self._general_style_tag, start_itr, end_itr)
|
|
|
|
|
|
|
|
def scale_down_text(self, scale_step = 10):
|
|
|
|
tag_table = self._buffer.get_tag_table()
|
|
|
|
start_itr = self._buffer.get_start_iter()
|
|
|
|
end_itr = self._buffer.get_end_iter()
|
|
|
|
tag = tag_table.lookup('general_style')
|
|
|
|
|
|
|
|
tag.set_property('scale', tag.get_property('scale') - scale_step)
|
|
|
|
self._buffer.apply_tag(tag, start_itr, end_itr)
|
|
|
|
|
|
|
|
def update_cursor_position(self):
|
2023-03-23 04:03:16 +00:00
|
|
|
iter = self._buffer.get_iter_at_mark( self._buffer.get_insert() )
|
2023-03-21 03:19:20 +00:00
|
|
|
chars = iter.get_offset()
|
|
|
|
row = iter.get_line() + 1
|
|
|
|
col = self.get_visual_column(iter) + 1
|
|
|
|
|
|
|
|
event_system.emit("set_line_char_label", (f"{row}:{col}",))
|
|
|
|
|
2023-10-07 19:51:12 +00:00
|
|
|
def keyboard_insert_mark(self):
|
|
|
|
iter = self._buffer.get_iter_at_mark( self._buffer.get_insert() )
|
2023-10-09 06:23:08 +00:00
|
|
|
mark = Gtk.TextMark.new(name = f"multi_insert_{len(self._multi_insert_marks)}", left_gravity = False)
|
2023-10-07 19:51:12 +00:00
|
|
|
|
|
|
|
self._buffer.add_mark(mark, iter)
|
2023-10-09 06:23:08 +00:00
|
|
|
self._multi_insert_marks.append(mark)
|
2023-10-07 19:51:12 +00:00
|
|
|
mark.set_visible(True)
|
|
|
|
|
2023-10-09 06:23:08 +00:00
|
|
|
def keyboard_clear_marks(self):
|
|
|
|
self._buffer.begin_user_action()
|
|
|
|
|
|
|
|
for mark in self._multi_insert_marks:
|
|
|
|
mark.set_visible(False)
|
|
|
|
self._buffer.delete_mark(mark)
|
|
|
|
|
|
|
|
self._multi_insert_marks.clear()
|
|
|
|
self._buffer.end_user_action()
|
|
|
|
|
2023-09-13 03:14:31 +00:00
|
|
|
def got_to_line(self, line: int = 0):
|
|
|
|
index = line - 1
|
|
|
|
buffer = self.get_buffer()
|
|
|
|
line_itr = buffer.get_iter_at_line(index)
|
|
|
|
char_iter = buffer.get_iter_at_line_offset(index, line_itr.get_bytes_in_line())
|
|
|
|
|
|
|
|
buffer.place_cursor(char_iter)
|
|
|
|
if not buffer.get_mark("starting_cursor"):
|
|
|
|
buffer.create_mark("starting_cursor", char_iter, True)
|
|
|
|
self.scroll_to_mark( buffer.get_mark("starting_cursor"), 0.0, True, 0.0, 0.0 )
|
2023-03-21 03:19:20 +00:00
|
|
|
|
|
|
|
# https://github.com/ptomato/inform7-ide/blob/main/src/actions.c
|
|
|
|
def action_uncomment_selection(self):
|
|
|
|
...
|
|
|
|
|
|
|
|
def action_comment_out_selection(self):
|
2023-09-13 03:14:31 +00:00
|
|
|
...
|
2023-03-22 07:12:40 +00:00
|
|
|
|
2023-09-13 03:14:31 +00:00
|
|
|
def open_file(self, gfile, line: int = 0, *args):
|
2023-03-22 07:12:40 +00:00
|
|
|
self._current_file = gfile
|
|
|
|
|
|
|
|
self.load_file_info(gfile)
|
2023-09-13 03:14:31 +00:00
|
|
|
self.load_file_async(gfile, line)
|
2023-03-22 07:12:40 +00:00
|
|
|
self._create_file_watcher(gfile)
|
|
|
|
|
2023-03-26 06:07:35 +00:00
|
|
|
def save_file(self):
|
2023-09-11 00:54:35 +00:00
|
|
|
self.skip_file_load = True
|
2023-10-04 00:39:11 +00:00
|
|
|
gfile = event_system.emit_and_await("save_file_dialog", (self._current_filename, self._current_file)) if not self._current_file else self._current_file
|
2023-03-26 06:07:35 +00:00
|
|
|
|
2023-09-11 00:54:35 +00:00
|
|
|
if not gfile:
|
|
|
|
self.skip_file_load = False
|
2023-09-13 03:14:31 +00:00
|
|
|
return
|
2023-03-26 06:07:35 +00:00
|
|
|
|
2023-09-11 00:54:35 +00:00
|
|
|
self.open_file( self._write_file(gfile) )
|
|
|
|
self.skip_file_load = False
|
2023-03-26 06:07:35 +00:00
|
|
|
|
2023-09-11 00:54:35 +00:00
|
|
|
def save_file_as(self):
|
2023-10-04 00:39:11 +00:00
|
|
|
gfile = event_system.emit_and_await("save_file_dialog", (self._current_filename, self._current_file))
|
2023-09-13 03:14:31 +00:00
|
|
|
self._write_file(gfile, True)
|
2023-10-04 00:39:11 +00:00
|
|
|
if gfile: event_system.emit("create_view", (gfile,))
|
2023-03-26 06:07:35 +00:00
|
|
|
|
2023-03-22 07:12:40 +00:00
|
|
|
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()
|
|
|
|
self._current_filename = display_name
|
|
|
|
|
|
|
|
try:
|
|
|
|
lm = self._language_manager.guess_language(None, content_type)
|
2023-03-26 06:07:35 +00:00
|
|
|
self._current_filetype = lm.get_id()
|
|
|
|
self.set_buffer_language(self._current_filetype)
|
2023-03-22 07:12:40 +00:00
|
|
|
except Exception as e:
|
|
|
|
...
|
|
|
|
|
|
|
|
logger.debug(f"Detected Content Type: {content_type}")
|
2023-03-26 06:07:35 +00:00
|
|
|
if self._current_filetype == "buffer":
|
|
|
|
self._current_filetype = info.get_content_type()
|
2023-03-22 07:12:40 +00:00
|
|
|
|
2023-09-13 03:14:31 +00:00
|
|
|
def load_file_async(self, gfile, line: int = 0):
|
|
|
|
if self.skip_file_load:
|
|
|
|
self.update_labels(gfile)
|
|
|
|
return
|
2023-09-11 00:54:35 +00:00
|
|
|
|
2023-03-22 07:12:40 +00:00
|
|
|
file = GtkSource.File()
|
|
|
|
file.set_location(gfile)
|
|
|
|
self._file_loader = GtkSource.FileLoader.new(self._buffer, file)
|
|
|
|
|
|
|
|
def finish_load_callback(obj, res, user_data=None):
|
|
|
|
self._file_loader.load_finish(res)
|
|
|
|
self._is_changed = False
|
2023-03-24 06:01:57 +00:00
|
|
|
self._document_loaded()
|
2023-09-13 03:14:31 +00:00
|
|
|
self.got_to_line(line)
|
2023-09-11 00:54:35 +00:00
|
|
|
self.update_labels(gfile)
|
2023-03-26 06:07:35 +00:00
|
|
|
|
2023-03-22 07:12:40 +00:00
|
|
|
self._file_loader.load_async(io_priority = 98,
|
|
|
|
cancellable = None,
|
|
|
|
progress_callback = None,
|
|
|
|
progress_callback_data = None,
|
|
|
|
callback = finish_load_callback,
|
|
|
|
user_data = (None))
|
2023-09-11 00:54:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
def update_labels(self, gfile = None):
|
|
|
|
if not gfile: return
|
|
|
|
|
|
|
|
tab_widget = self.get_parent().get_tab_widget()
|
|
|
|
tab_widget.set_tab_label(self._current_filename)
|
|
|
|
self.set_bottom_labels(gfile)
|
|
|
|
|
|
|
|
def set_bottom_labels(self, gfile = None):
|
|
|
|
if not gfile: return
|
2023-09-13 03:14:31 +00:00
|
|
|
|
2023-09-11 00:54:35 +00:00
|
|
|
event_system.emit("set_bottom_labels", (gfile, None, self._current_filetype, None))
|
2023-09-13 03:14:31 +00:00
|
|
|
self.update_cursor_position()
|