diff --git a/README.md b/README.md new file mode 100644 index 0000000..455a14a --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Text Editor diff --git a/main.py b/main.py new file mode 100644 index 0000000..f93e912 --- /dev/null +++ b/main.py @@ -0,0 +1,3 @@ +from src.editor import Editor + +text_editor = Editor() diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..59d586b --- /dev/null +++ b/src/README.md @@ -0,0 +1,21 @@ +# text_editor + +# Базовый функционал: + +1)Возможность редактирования файла + +2)Перемещение по тексту при помощи “стрелок” - по словам (option+<>), в начало/конец строки (command+<>) + +3)Удаление строк(control+d) и слов (control+w) + +4)Текстовый поиск и замена(control+f) + +5)Хоткеи для сохранения(control+s) и выхода(command+q) + +# Дополнительный функционал: + +1)Графический интерфейс + +2)Возможность сохранять файл как .cpp, .py, .c + +3)Возможность выставлять шрифты и размер diff --git a/src/actions.py b/src/actions.py new file mode 100644 index 0000000..d448d7c --- /dev/null +++ b/src/actions.py @@ -0,0 +1,65 @@ +from tkinter import filedialog, simpledialog, messagebox, END, INSERT +from src import size, font + + +class Actions(): + + def __init__(self, text): + self.text = text + + def SaveFile(self, event=None): + file_path = filedialog.asksaveasfilename(filetypes=(('Text Documents (*.txt)', '*.txt'), ('All Files', '*.*'))) + if file_path: + with open(file_path, 'w', encoding='utf-8') as file: + file.write(self.text.get('1.0', END)) + + def DeleteLine(self, event=None): + current_line = self.text.index(INSERT).split('.')[0] + start = f"{current_line}.0" + end = f"{current_line}.end" + self.text.delete(start, end) + + def DeleteWord(self, event=None): + cursor_index = self.text.index(INSERT) + end_index = self.text.search(r"\s", cursor_index, regexp=True) + start_index = self.text.search(r"\s", cursor_index, backwards=True, regexp=True) + if start_index == end_index: + self.text.delete("1.0", end_index) + if start_index == "" or end_index == "": + return + self.text.delete(start_index, end_index) + + def OpenFile(self, event=None): + file_path = filedialog.askopenfilename(title='Выбор файла', filetypes=( + ('C++ files (*.cpp)', '*.cpp'), ('Python files (*.py)', '*.py'), ('Все файлы (*.*)', '*.*'))) + if file_path: + self.text.delete('1.0', END) + self.text.insert('1.0', open(file_path, encoding='utf-8').read()) + + def FindText(self, event=None): + search_query = simpledialog.askstring("Find", "Enter text to search:") + if search_query: + replace_query = simpledialog.askstring("Replace", "Enter text to replace:") + start_pos = "1.0" + while True: + start_pos = self.text.search(search_query, start_pos, END) + if not start_pos: + break + end_pos = f"{start_pos}+{len(search_query)}c" + self.text.tag_add("search", start_pos, end_pos) + if replace_query: + self.text.delete(start_pos, end_pos) + self.text.insert(start_pos, replace_query) + elif self.text.tag_ranges("search"): + self.text.mark_set("insert", self.text.tag_ranges("search")[0]) + self.text.see(self.text.tag_ranges("search")[0]) + self.text.tag_config("search", background="grey") + else: + messagebox.showinfo("Find", "Text not found.") + start_pos = end_pos + + def ChangeFonts(self, font_to_change): + self.text['font'] = font.fonts[font_to_change]['font'] + + def ChangeSize(self, size_to_change): + self.text['font'] = size.sizes[size_to_change]['size'] diff --git a/src/editor.py b/src/editor.py new file mode 100644 index 0000000..be112b2 --- /dev/null +++ b/src/editor.py @@ -0,0 +1,77 @@ +from tkinter import WORD, LEFT, Tk, Scrollbar, RIGHT, Y, Frame, Text, BOTH, Menu +from src.actions import Actions + +class Editor: + + def WindowEditor(self): + self.editor_window.title('TextEditor') + self.editor_window.geometry('700x800') + + def FileMenuEditor(self): + self.file_menu = Menu(self.main_menu) + self.file_menu.add_command(label='Open', command=self.actions.OpenFile) + self.file_menu.add_command(label='Find', command=self.actions.FindText) + self.file_menu.add_command(label='Save', command=self.actions.SaveFile) + self.file_menu.add_separator() + self.file_menu.add_command(label='Delete') + self.editor_window.config(menu=self.file_menu) + + def ViewMenuEditor(self): + self.view_menu = Menu(self.main_menu) + self.font_menu = Menu(self.view_menu) + self.font_menu.add_command(label='Times New Roman', command=lambda: self.actions.ChangeFonts('TNR')) + self.font_menu.add_command(label='Arial', command=lambda: self.actions.ChangeFonts('Arial')) + self.font_menu.add_command(label='Courier New', command=lambda: self.actions.ChangeFonts('CN')) + self.view_menu.add_cascade(label='Font', menu=self.font_menu) + self.size_menu = Menu(self.view_menu) + self.size_menu.add_command(label='10', command=lambda: self.actions.ChangeSize('10')) + self.size_menu.add_command(label='20', command=lambda: self.actions.ChangeSize('20')) + self.size_menu.add_command(label='30', command=lambda: self.actions.ChangeSize('30')) + self.view_menu.add_cascade(label='Size', menu=self.size_menu) + self.editor_window.config(menu=self.view_menu) + + def MenuEditor(self): + self.main_menu = Menu(self.editor_window) + + self.FileMenuEditor() + self.ViewMenuEditor() + + self.editor_window.config(menu=self.main_menu) + self.main_menu.add_cascade(label='File', menu=self.file_menu) + self.main_menu.add_cascade(label='View', menu=self.view_menu) + + def ScrollEditor(self): + self.scroll = Scrollbar(self.text, command=self.text.yview) + self.scroll.pack(side=RIGHT, fill=Y) + self.text.config(yscrollcommand=self.scroll.set) + + def TextEditor(self): + self.widget = Frame(self.editor_window) + self.widget.pack(fill=BOTH, expand=1) + self.text = Text(self.widget, + fg='white', + bg='black', + padx=10, + pady=10, + wrap=WORD, + insertbackground='white', + spacing3=10) + self.text.pack(fill=BOTH, side=LEFT, expand=1) + + def __init__(self): + self.editor_window = Tk() + self.TextEditor() + + self.actions = Actions(self.text) + + self.WindowEditor() + self.MenuEditor() + self.ScrollEditor() + + self.editor_window.bind('', self.actions.SaveFile) + self.editor_window.bind('', self.actions.OpenFile) + self.editor_window.bind('', self.actions.FindText) + self.editor_window.bind('', self.actions.DeleteLine) + self.editor_window.bind('', self.actions.DeleteWord) + + self.editor_window.mainloop() diff --git a/src/font.py b/src/font.py new file mode 100644 index 0000000..b15cb04 --- /dev/null +++ b/src/font.py @@ -0,0 +1,11 @@ +fonts = { + 'Arial': { + 'font': 'Arial 14 bold' + }, + 'CN': { + 'font': ('Courier New', 14, 'bold') + }, + 'TNR': { + 'font': ('Times New Roman', 14, 'bold') + } +} diff --git a/src/size.py b/src/size.py new file mode 100644 index 0000000..80b3837 --- /dev/null +++ b/src/size.py @@ -0,0 +1,11 @@ +sizes = { + '10': { + 'size': ('Arial', 10, 'bold') + }, + '20': { + 'size': ('Arial', 20, 'bold') + }, + '30': { + 'size': ('Arial', 30, 'bold') + } +}