-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from kuczynskimaciej1/navbar_move_do_menu
Navbar move do menu
- Loading branch information
Showing
12 changed files
with
800 additions
and
689 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
from collections.abc import Callable, Iterable | ||
from enum import Enum | ||
from sqlalchemy.exc import IntegrityError | ||
from types import TracebackType | ||
from traceback import print_tb | ||
from typing import Literal, Any, NoReturn | ||
from tkinter import Event, Menu, simpledialog, ttk, Listbox, Tk, Text, Button, Frame, Label, Entry, Scrollbar, Toplevel, Misc, messagebox, Menubutton, Canvas,Checkbutton,BooleanVar, VERTICAL, RAISED | ||
from tkinter.ttk import Combobox | ||
from tkinter.constants import NORMAL, DISABLED, BOTH, RIDGE, END, LEFT, RIGHT, TOP, X, Y, INSERT, SEL, WORD | ||
from group_controller import GroupController | ||
from models import Contact, IModel, Template, Group | ||
from tkhtmlview import HTMLLabel, HTMLText | ||
from DataSources.dataSources import GapFillSource | ||
|
||
|
||
class AddContactWindow(Toplevel): | ||
def __init__(self, parent: Toplevel | ContactList) -> None: | ||
super().__init__(parent) | ||
self.parent = parent | ||
|
||
def prepareInterface(self): | ||
self.title("Dodaj Kontakt") | ||
|
||
email_label = Label(self, text="Adres email:", bg="lightblue") | ||
self.email_entry = Entry(self, bg="white", fg="black") | ||
name_label = Label(self, text="Imię:", bg="lightblue") | ||
self.name_entry = Entry(self, bg="white", fg="black") | ||
surname_label = Label(self, text="Nazwisko:", bg="lightblue") | ||
self.surname_entry = Entry(self, bg="white", fg="black") | ||
btn_add_contact = Button(self, text="Dodaj kontakt", bg="lightblue", fg="black", command=self.add_manual_contact) | ||
|
||
email_label.grid(row=0, column=0, padx=5, pady=5) | ||
self.email_entry.grid(row=0, column=1, padx=5, pady=5) | ||
name_label.grid(row=1, column=0, padx=5, pady=5) | ||
self.name_entry.grid(row=1, column=1, padx=5, pady=5) | ||
surname_label.grid(row=2, column=0, padx=5, pady=5) | ||
self.surname_entry.grid(row=2, column=1, padx=5, pady=5) | ||
btn_add_contact.grid(row=3, column=0, columnspan=2, padx=5, pady=5, sticky="ew") | ||
|
||
def add_manual_contact(self): | ||
email = self.email_entry.get() | ||
name = self.name_entry.get() | ||
surname = self.surname_entry.get() | ||
if email: | ||
newContact = Contact(_email=email, _first_name=name, _last_name=surname) | ||
self.parent.update() | ||
self.destroy() | ||
# TODO: Jakiś sygnał do parenta żeby się zaktualizował? | ||
else: | ||
messagebox.showerror("Błąd", "Podaj adres e-mail") | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
from collections.abc import Callable, Iterable | ||
from types import TracebackType | ||
from traceback import print_tb | ||
from typing import NoReturn | ||
from tkinter import Menu, simpledialog, Listbox, Tk, Frame, Label, Entry, Scrollbar | ||
from tkinter.constants import BOTH, RIDGE, END, LEFT, RIGHT, TOP, X, Y, INSERT | ||
from models import IModel, Template, Group | ||
from tkhtmlview import HTMLLabel | ||
from .GroupEditor import GroupEditor | ||
from .Settings import Settings | ||
from .TemplateEditor import TemplateEditor | ||
|
||
|
||
def errorHandler(xd, exctype: type, excvalue: Exception, tb: TracebackType): | ||
msg = f"{exctype}: {excvalue}, {print_tb(tb)}" | ||
print(msg) | ||
simpledialog.messagebox.showerror("Error", msg) | ||
|
||
Tk.report_callback_exception = errorHandler | ||
|
||
class AppUI(): | ||
def __init__(self) -> None: | ||
self.root = Tk() | ||
self.grupy: list[Group] = [] | ||
self.szablony: list[Template] = [] | ||
self.template_window: TemplateEditor = None | ||
|
||
def prepareInterface(self) -> None: | ||
self.root.title("MailBuddy") | ||
self.root.configure(bg="black") | ||
self.root.minsize(width=800, height=470) | ||
self.root.protocol("WM_DELETE_WINDOW", self.__exit_clicked) | ||
|
||
self.__create_menu() | ||
self.__create_mailing_group_pane() | ||
self.__create_template_pane() | ||
self.__create_mail_input_pane() | ||
|
||
def add_periodic_task(self, period: int, func: Callable): | ||
# TODO można poprawić żeby się odpalało tylko przy dodaniu obiektu, | ||
# przemyśleć | ||
def wrapper(): | ||
func() | ||
self.root.after(period, wrapper) | ||
wrapper() | ||
|
||
def run(self): | ||
self.root.mainloop() | ||
|
||
def __exit_clicked(self) -> NoReturn | None: | ||
# Wait for saving objects to DB | ||
print("Exiting") | ||
exit() | ||
|
||
def add_template(self, content: Template | Iterable[Template]): | ||
if isinstance(content, Template): | ||
if content not in self.szablony: | ||
self.szablony.append(content) | ||
else: | ||
[self.szablony.append(i) | ||
for i in content if i not in self.szablony] | ||
self.__update_listbox(self.template_listbox, self.szablony) | ||
|
||
def add_group(self, g: Group | Iterable[Group]): | ||
if isinstance(g, Group): | ||
if g not in self.grupy: | ||
self.grupy.append(g) | ||
else: | ||
[self.grupy.append(i) for i in g if i not in self.grupy] | ||
self.__update_listbox(self.grupy_listbox, self.grupy) | ||
|
||
def __add_group_clicked(self): | ||
self.show_group_window() | ||
|
||
def show_group_window(self, g: Group | None = None): | ||
group_editor = GroupEditor(self, g) | ||
group_editor.prepareInterface() | ||
|
||
def __send_clicked(event) -> None: | ||
print("send mail") | ||
pass | ||
|
||
def __importuj_clicked(self): | ||
pass | ||
|
||
def __eksportuj_clicked(self): | ||
pass | ||
|
||
def __template_selection_changed(self, _event): | ||
selected = self.template_listbox.curselection() | ||
if len(selected) > 0: | ||
self.showTemplate(self.szablony[selected[0]]) | ||
|
||
def __group_doubleclicked(self, _event): | ||
selected = self.grupy_listbox.curselection() | ||
if len(selected) > 0: | ||
elem = int(self.grupy_listbox.get(selected[0]).split(':')[0]) | ||
self.show_group_window(self.grupy[elem]) | ||
|
||
def __group_selection_changed(self, _event): | ||
selected: int = self.grupy_listbox.curselection() | ||
if len(selected) > 0: | ||
g: Group = self.grupy[selected[0]] | ||
mails = [", ".join(x.email) for x in g.contacts] | ||
self.entry_adres.delete(0, END) | ||
self.entry_adres.insert(INSERT, mails) | ||
|
||
def __template_doubleclicked(self, _event): | ||
ui_selection = self.template_listbox.curselection() | ||
if len(ui_selection) > 0: | ||
selected = self.szablony[ui_selection[0]] | ||
self.show_template_window(selected) | ||
|
||
def showTemplate(self, selected: Template): | ||
self.entry_text.delete('1.0', END) | ||
self.entry_text.insert(END, selected.content) | ||
|
||
@staticmethod | ||
def __update_listbox(lb: Listbox, content: Iterable[IModel] | dict[IModel]): | ||
if isinstance(content, Iterable): | ||
lb.delete(0, END) | ||
[lb.insert(END, i) for i in content] | ||
elif isinstance(content, dict): | ||
lb.delete(0, END) | ||
[lb.insert(END, k) for k in content.keys()] | ||
else: | ||
raise AttributeError( | ||
f"Wrong type of 'content', expected dict or Iterable, got { | ||
type(content)}") | ||
|
||
def __add_template_clicked(self): | ||
self.show_template_window() | ||
|
||
def __create_menu(self): | ||
menubar = Menu(self.root) | ||
|
||
file_menu = Menu(menubar, tearoff=0) | ||
file_menu.add_command(label="Import", command=self.__importuj_clicked) | ||
file_menu.add_command(label="Export", command=self.__eksportuj_clicked) | ||
menubar.add_cascade(label="File", menu=file_menu) | ||
|
||
edit_menu = Menu(menubar, tearoff=0) | ||
add_menu = Menu(edit_menu, tearoff=0) | ||
add_menu.add_command( | ||
label="Template", | ||
command=self.__add_template_clicked) | ||
add_menu.add_command(label="Group", command=self.__add_group_clicked) | ||
edit_menu.add_cascade(label="Add...", menu=add_menu) | ||
menubar.add_cascade(label="Edit", menu=edit_menu) | ||
menubar.add_command(label="Open Settings", command=self.logout) | ||
menubar.add_command(label="Send", command=lambda: self.__send_clicked()) | ||
|
||
|
||
self.root.config(menu=menubar) | ||
|
||
|
||
|
||
def __create_mailing_group_pane(self): | ||
groups_frame = Frame( | ||
self.root, bg="lightblue", width=200, height=100, relief=RIDGE, borderwidth=2) | ||
grupy_label = Label( | ||
groups_frame, text="Grupy mailowe", bg="lightblue") | ||
self.grupy_listbox = Listbox(groups_frame, bg="lightblue", fg="black") | ||
self.grupy_listbox.bind( | ||
'<<ListboxSelect>>', | ||
self.__group_selection_changed) | ||
self.grupy_listbox.bind('<Double-1>', self.__group_doubleclicked) | ||
|
||
groups_frame.pack(side=LEFT, padx=10, pady=10, | ||
fill=BOTH, expand=True, ipadx=5, ipady=5) | ||
grupy_label.pack() | ||
self.grupy_listbox.pack(fill=BOTH, expand=True) | ||
|
||
def __create_template_pane(self): | ||
templates_frame = Frame( | ||
self.root, bg="lightblue", width=200, height=100, relief=RIDGE, borderwidth=2) | ||
szablony_label = Label( | ||
templates_frame, text="Szablony wiadomości", bg="lightblue") | ||
self.template_listbox = Listbox( | ||
templates_frame, bg="lightblue", fg="black") | ||
self.template_listbox.bind( | ||
'<<ListboxSelect>>', | ||
self.__template_selection_changed) | ||
self.template_listbox.bind('<Double-1>', self.__template_doubleclicked) | ||
|
||
templates_frame.pack(side=LEFT, padx=10, pady=10, | ||
fill=BOTH, expand=True, ipadx=5, ipady=5) | ||
szablony_label.pack() | ||
self.template_listbox.pack(fill=BOTH, expand=True) | ||
|
||
def __create_mail_input_pane(self): | ||
entry_frame = Frame(self.root, bg="lightblue", | ||
relief=RIDGE, borderwidth=2) | ||
entry_scrollbar = Scrollbar(entry_frame) | ||
self.entry_html_label = HTMLLabel( | ||
entry_frame, html="", bg="lightblue") | ||
entry_adres_label = Label( | ||
entry_frame, text="Wyślij do:", bg="lightblue", anchor="s") | ||
self.entry_adres = Entry(entry_frame, bg="white", fg="black") | ||
|
||
entry_frame.pack(side=TOP, padx=10, pady=10, | ||
fill=BOTH, expand=True, ipadx=5, ipady=5) | ||
entry_scrollbar.pack(side=RIGHT, fill=Y) | ||
self.entry_html_label.pack(fill=BOTH, expand=True) | ||
entry_adres_label.pack(side=TOP, padx=5, pady=5) | ||
self.entry_adres.pack(side=TOP, padx=5, pady=5, fill=X) | ||
|
||
def showTemplate(self, selected: Template): | ||
self.entry_html_label.set_html(selected.content) | ||
|
||
def show_template_window(self, obj: Template | None = None): | ||
self.template_window = TemplateEditor(self, self.root, obj) | ||
self.template_window.prepareInterface() | ||
|
||
def logout(self): | ||
|
||
root = Tk() # Otwórz ponownie okno logowania | ||
settings = Settings(root) | ||
settings.prepareInterface() | ||
root.mainloop() | ||
|
||
|
||
|
||
|
Oops, something went wrong.