From e84de621c277b83530acb97864c5570b459a7596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliberk=20Sand=C4=B1k=C3=A7=C4=B1?= Date: Fri, 21 Jun 2024 18:53:38 +0300 Subject: [PATCH] Ders 3 --- shell.nix | 7 +- src/FileOperations.py | 39 ++++++++++ src/MainWindow.py | 170 ++++++++++++++++++++++++++++++++++++------ src/main.py | 3 +- 4 files changed, 195 insertions(+), 24 deletions(-) create mode 100644 src/FileOperations.py diff --git a/shell.nix b/shell.nix index 3732830..a90299e 100644 --- a/shell.nix +++ b/shell.nix @@ -10,7 +10,12 @@ in pkgs.mkShell { pkgs.gobject-introspection pkgs.pkg-config pkgs.libnotify - # pkgs.libadwaita + pkgs.libadwaita + # pkgs.xdg-desktop-portal-shana + # pkgs.xdg-desktop-portal + # pkgs.xdg-desktop-portal-gtk + # pkgs.xdg-desktop-portal-gnome + # pkgs.gtk3 (pkgs.python3.withPackages (python-pkgs: [ # select Python packages here # python-pkgs.gi diff --git a/src/FileOperations.py b/src/FileOperations.py new file mode 100644 index 0000000..e6e6c20 --- /dev/null +++ b/src/FileOperations.py @@ -0,0 +1,39 @@ +import gi, sys +gi.require_version('Gtk', '4.0') +from gi.repository import GLib, Gio + +def get_name(file): + info = file.query_info("standard::display-name", Gio.FileQueryInfoFlags.NONE) + if info: + return info.get_attribute_string("standard::display-name") + else: + return file.get_basename() + +def read_file(file, on_finish_callback): + file.load_contents_async(None, _read_file_finish, on_finish_callback) + +def _read_file_finish(file, result, on_finish_callback): + contents = file.load_contents_finish(result) + + if not contents[0]: + path = file.peek_path() + on_finish_callback(file, "", f"Unable to open {path}: {contents[1]}") + return; + + try: + on_finish_callback(file, contents[1].decode('utf-8'), "") + + except UnicodeError as err: + path = file.peek_path() + on_finish_callback(file, "", f"Unable to load the contents of {path}: the file is not encoded with UTF-8") + + +def save_file(file, text, on_finish_callback): + file.replace_contents_async(str.encode(text), None, False, Gio.FileCreateFlags.NONE, None, _save_file_finish, on_finish_callback) + +def _save_file_finish(file, result, on_finish_callback): + (success, new_etag) = file.replace_contents_finish(result) + + on_finish_callback(file, success, new_etag) + + diff --git a/src/MainWindow.py b/src/MainWindow.py index dfae02b..1846672 100644 --- a/src/MainWindow.py +++ b/src/MainWindow.py @@ -2,48 +2,92 @@ import gi, sys gi.require_version('Gtk', '4.0') from gi.repository import Gtk, Gio +import FileOperations + class MainWindow(Gtk.ApplicationWindow): def __init__(self, app): super().__init__(application=app) - - self.setup_actions() - + + self.setup_variables() + + self.setup_actions() + self.setup_window() - + self.setup_headerbar() - + self.setup_ui() - + # == SETUPS == + def setup_variables(self): + self._current_working_file = None + + def setup_actions(self): - pass - + new_action = Gio.SimpleAction(name="new") + new_action.connect("activate", self.on_action_win_new_activated) + self.add_action(new_action) + + open_action = Gio.SimpleAction(name="open") + open_action.connect("activate", self.on_action_win_open_activated) + self.add_action(open_action) + + save_action = Gio.SimpleAction(name="save") + save_action.connect("activate" , self.on_action_win_save_activated) + self.add_action(save_action) + + save_as_action = Gio.SimpleAction(name="save-as") + save_as_action.connect("activate", self.on_action_win_save_as_activated) + self.add_action(save_as_action) + + + def setup_window(self): self.set_default_size(600, 400) self.set_title("Metin Editörü") - + def setup_headerbar(self): - btn_new = Gtk.Button(label="New", icon_name="document-new-symbolic", tooltip_text="Yeni Doküman") - btn_open = Gtk.Button(label="Open", icon_name="document-open-symbolic", tooltip_text="Dosya Aç") - btn_save = Gtk.Button(label="Save", icon_name="document-save-symbolic", tooltip_text="Kaydet") - btn_save_as = Gtk.Button(label="Save As", icon_name="document-save-as-symbolic", tooltip_text="Farklı Kaydet") - + btn_new = Gtk.Button( + label="New", + action_name="win.new", + icon_name="document-new-symbolic", + tooltip_text="Yeni Doküman" + ) + btn_open = Gtk.Button( + label="Open", + action_name="win.open", + icon_name="document-open-symbolic", + tooltip_text="Dosya Aç" + ) + btn_save = Gtk.Button( + label="Save", + action_name="win.save", + icon_name="document-save-symbolic", + tooltip_text="Kaydet" + ) + btn_save_as = Gtk.Button( + label="Save As", + action_name="win.save-as", + icon_name="document-save-as-symbolic", + tooltip_text="Farklı Kaydet" + ) + box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) box.append(btn_new) box.append(btn_open) box.append(btn_save) box.append(btn_save_as) - + headerbar = Gtk.HeaderBar() headerbar.pack_start(box) - - btn_preferences = Gtk.Button(label="Preferences", icon_name="preferences-system-symbolic", tooltip_text="Seçenekler") + + btn_preferences = Gtk.Button(label="Preferences", icon_name="open-menu-symbolic", tooltip_text="Seçenekler") box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) box.append(btn_preferences) headerbar.pack_end(box) - + self.set_titlebar(headerbar) - + def setup_ui(self): self.text_view = Gtk.TextView ( monospace=True, @@ -54,8 +98,90 @@ class MainWindow(Gtk.ApplicationWindow): scrolled_window = Gtk.ScrolledWindow(child=self.text_view) self.set_child(scrolled_window) - + # == FUNCTIONS == + def get_textview_text(self): + buffer = self.text_view.get_buffer() + + start = buffer.get_start_iter() + + end = buffer.get_end_iter() + return buffer.get_text(start, end, False) + + def set_textview_text(self, text): + buffer = self.text_view.get_buffer() + + buffer.set_text(text) + + start = buffer.get_start_iter() + buffer.place_cursor(start) + + # == CALLBACKS == - def on_btn_button_clicked(self, btn): - print("Merhaba, evet bu bir buton") \ No newline at end of file + def on_action_win_new_activated(self, action, params): + self.set_textview_text("") + self.set_title("New File") + self._current_working_file = None + + def on_action_win_open_activated(self, action, params): + self._open_file_chooser = Gtk.FileChooserNative ( + title="Open File", + transient_for=self, + action=Gtk.FileChooserAction.OPEN, + accept_label="_Open", + cancel_label="_Cancel" + ) + + self._open_file_chooser.connect("response", self.on_open_dialog_response) + self._open_file_chooser.show() + + def on_open_dialog_response(self, dialog, response): + if response == Gtk.ResponseType.ACCEPT: + FileOperations.read_file(dialog.get_file(), self.on_file_read) + + self._open_file_chooser = None + + def on_file_read(self, file, content, err): + if err: + print(f"Error: {err}") + return + self.set_textview_text(content) + + filename = FileOperations.get_name(file) + self.set_title(filename) + self._current_working_file = file + + def on_action_win_save_activated(self, action, params): + if self._current_working_file: + text = self.get_textview_text() + FileOperations.save_file(self._current_working_file, text, self.on_file_saved) + else: + self.activate_action("win.save-as") + + def on_action_win_save_as_activated(self, action, params): + self._save_file_chooser = Gtk.FileChooserNative ( + title="Save File", + transient_for=self, + action=Gtk.FileChooserAction.SAVE, + accept_label="_Save", + cancel_label="_Cancel" + ) + + self._save_file_chooser.connect("response", self.on_save_dialog_response) + self._save_file_chooser.show() + + def on_save_dialog_response(self, dialog, response): + if response == Gtk.ResponseType.ACCEPT: + text = self.get_textview_text() + + FileOperations.save_file(dialog.get_file(), text, self.on_file_saved) + + self._save_file_chooser = None + + def on_file_saved(self, file, success, new_etag): + if success: + filename = FileOperations.get_name(file) + self.set_title(filename) + self._current_working_file = file + + diff --git a/src/main.py b/src/main.py index 44cd21b..b7d829d 100755 --- a/src/main.py +++ b/src/main.py @@ -17,8 +17,9 @@ def on_activate(app): app = Gtk.Application(application_id='com.asandikci.gtk4py') app.connect('activate', on_activate) +app.set_accels_for_action('win.new', ['t']) app.set_accels_for_action('win.open', ['o']) app.set_accels_for_action('win.save', ['s']) app.set_accels_for_action('win.save-as', ['s']) -app.run(sys.argv) \ No newline at end of file +app.run(sys.argv)