Пример #1
0
class AddAlertPopup(object):
    def __init__(self, master, coin):
        self.top = Toplevel(master)
        self.top.title("Add Alert")
        Label(self.top, text=("Alert when price goes")).grid(row=0,
                                                             column=0,
                                                             columnspan=2,
                                                             sticky="NEWS")
        b_m = ["above", "below"]
        self.a = Combobox(self.top, values=b_m, width=10)
        self.a.set(b_m[0])
        self.a.grid(row=1, column=0, sticky="NEWS")

        self.e = Entry(self.top)
        self.e.focus_set()
        self.e.grid(row=1, column=1, sticky="NEWS")

        mark = [coin.market, "USDT"]
        self.m = Combobox(self.top, values=mark, width=10)
        self.m.set(mark[0])
        self.m.grid(row=1, column=2, sticky="NEWS")

        Button(self.top, text='Ok', command=self.cleanup).grid(row=2,
                                                               column=0,
                                                               columnspan=3)
        ##center after packing
        center(self.top, master)

    def cleanup(self):
        self.value = [self.a.get(), self.e.get(), self.m.get()]
        self.top.destroy()
Пример #2
0
def main():

    root = Tk()
    root.geometry("250x85+1250+650")
    app = Example()

    frame1 = Frame(root)
    frame1.pack(fill=BOTH)

    lbl1 = Label(frame1, text="Enter today's work")
    lbl1.pack(fill=X, padx=5, pady=5)

    frame2 = Frame(root)
    frame2.pack(fill=BOTH)

    entry1 = Entry(frame2)
    entry1.pack(fill=X, padx=5, expand=True)
    entry1.focus_set()

    def callback():
        print(entry1.get())
        print_values(entry1.get())
        write_into_workbook(entry1.get())

    frame3 = Frame(root)
    frame3.pack(fill=BOTH, expand=True)

    subbtn = Button(frame3, text="Done", command=callback)
    subbtn.place(x=4,y=5)

    root.mainloop()
Пример #3
0
class AddCoinPopup(object):
    def __init__(self, master, overview):
        #228 107
        self.top = Toplevel(master, padx=50, pady=5)
        self.top.title("Add Coin")
        #Label(self.top, text="Add coin").grid(row=0,column=0,columnspan=2,sticky="NEWS")
        exch = ["Bittrex", "Binance"]

        mark = ["BTC", "ETH", "BNB", "USDT"]
        self.c = Combobox(self.top, values=exch, width=10)
        self.c.set(exch[0])
        self.c.grid(row=0, column=0, columnspan=2, sticky="NEWS")
        self.m = Combobox(self.top, values=mark, width=10)
        self.m.set(mark[0])
        self.m.grid(row=1, column=0, sticky="NEWS")
        self.e = Entry(self.top)
        self.e.focus_set()
        self.e.grid(row=1, column=1, columnspan=1, sticky="NEWS")
        Button(self.top, text='Ok', command=self.cleanup).grid(row=2,
                                                               column=0,
                                                               columnspan=2)
        ##center after packing
        center(self.top, master)

    def cleanup(self, ):
        self.value = [self.c.get(), self.m.get(), self.e.get()]
        self.top.destroy()
Пример #4
0
    def set_password(self):
        """Set the master password used to encrypt the mailbox config files."""
        def ok(event=None):
            pwd = getpwd.get()
            pwd2 = confpwd.get()
            if pwd == pwd2:
                # passwords match
                cryptedpwd = crypt.crypt(pwd,
                                         crypt.mksalt(crypt.METHOD_SHA512))
                with open(os.path.join(LOCAL_PATH, '.pwd'), "w") as fich:
                    fich.write(cryptedpwd)
                top.destroy()
                self.pwd = pwd
                logging.info('New password set')
            else:
                showerror(_('Error'), _('Passwords do not match!'))

        top = Toplevel(self, class_="CheckMails")
        top.iconphoto(True, self.im_icon)
        top.title(_("Set password"))
        top.resizable(False, False)
        Label(top, text=_("Enter master password")).pack(padx=10, pady=(4, 10))
        getpwd = Entry(top, show='*', justify='center')
        getpwd.pack(padx=10, pady=4)
        Label(top, text=_("Confirm master password")).pack(padx=10, pady=4)
        confpwd = Entry(top, show='*', justify='center')
        confpwd.pack(padx=10, pady=4)
        Button(top, text="Ok", command=ok).pack(padx=10, pady=(4, 10))
        confpwd.bind("<Key-Return>", ok)
        getpwd.focus_set()
        self.wait_window(top)
Пример #5
0
 class DateWidget(Frame):
     """Gets a date from the user."""
     def __init__(self, master):
         """Make boxes, register callbacks etc."""
         Frame.__init__(self, master)
         self.label = Label(self, text="När är du född?")
         self.label.pack()
         self.entry_text = StringVar()
         self.entry_text.trace("w", lambda *args: self.onEntryChanged())
         self.entry = Entry(self, width=date_entry_width,
              textvariable=self.entry_text)
         self.entry.insert(0, "ÅÅÅÅ-MM-DD")
         self.entry.pack(pady=small_pad)
         self.button = Button(self, text="Uppdatera",
              command=lambda: self.onDateChanged())
         self.button.pack()
         self.entry.focus_set()
         self.entry.select_range(0, END)
         self.entry.bind("<Return>", lambda x: self.onDateChanged())
     def setListener(self, pred_view):
         """Select whom to notify when a new date is entered."""
         self.pred_view = pred_view
     def onDateChanged(self):
         """Notifies the PredictionWidget that the date has been changed."""
         try:
             date = datetime.datetime.strptime(self.entry.get(),
                  "%Y-%m-%d").date()
             self.pred_view.update(date)
         except ValueError:
             self.entry.configure(foreground="red")
     def onEntryChanged(self):
         """Reset the text color."""
         self.entry.configure(foreground="")
Пример #6
0
class Add(Toplevel):
    def __init__(self, master):
        Toplevel.__init__(self, master, class_=APP_NAME, padx=6, pady=6)
        self.title(_("Add Feed"))
        self.grab_set()
        self.resizable(True, False)
        self.columnconfigure(1, weight=1)

        Label(self, text=_('URL')).grid(row=0,
                                        column=0,
                                        sticky='e',
                                        pady=4,
                                        padx=4)
        self.url = ""
        self.url_entry = Entry(self, width=30)
        self.url_entry.grid(row=0, column=1, sticky='ew', pady=4, padx=4)
        self.url_entry.bind('<Return>', self.validate)
        frame = Frame(self)
        frame.grid(row=1, column=0, columnspan=2)
        Button(frame, text=_('Ok'), command=self.validate).grid(row=0,
                                                                column=0,
                                                                sticky='e',
                                                                pady=4,
                                                                padx=4)

        Button(frame, text=_('Cancel'), command=self.destroy).grid(row=0,
                                                                   column=1,
                                                                   sticky='w',
                                                                   pady=4,
                                                                   padx=4)
        self.url_entry.focus_set()

    def validate(self, event=None):
        self.url = self.url_entry.get().strip()
        self.destroy()
Пример #7
0
    def ask_password(self):
        """Ask the master password in order to decrypt the mailbox config files."""
        def ok(event=None):
            with open(os.path.join(LOCAL_PATH, '.pwd')) as fich:
                cryptedpwd = fich.read()
            pwd = getpwd.get()
            if crypt.crypt(pwd, cryptedpwd) == cryptedpwd:
                # passwords match
                top.destroy()
                logging.info('Authentication successful')
                self.pwd = pwd
            else:
                showerror(_('Error'), _('Incorrect password!'))
                logging.warning('Authentication failed')
                getpwd.delete(0, "end")

        top = Toplevel(self, class_="CheckMails")
        top.title(_("Password"))
        top.resizable(False, False)
        Label(top, text=_("Enter password")).pack(padx=10, pady=(10, 4))
        getpwd = Entry(top, show='*', justify='center')
        getpwd.pack(padx=10, pady=4)
        Button(top, text="Ok", command=ok).pack(padx=10, pady=(4, 10))
        getpwd.bind("<Key-Return>", ok)
        getpwd.focus_set()
        self.wait_window(top)
Пример #8
0
def get_number_from(entry: Entry) -> float:
    try:
        return float(fix_separator(entry.get()))
    except ValueError:
        entry.focus_set()
        entry.select_range(0, END)
        stop_execution("Неверный формат строки")
Пример #9
0
    def add_task(self):
        def ajoute(event=None):
            task = nom.get()
            if task and not CONFIG.has_option("Tasks", task):
                index = len(CONFIG.options("Tasks"))
                self.menu_tasks.insert_radiobutton(index,
                                                   label=task,
                                                   value=task,
                                                   variable=self.task)
                CONFIG.set("Tasks", task, CMAP[index % len(CMAP)])
                top.destroy()
                with open(PATH_CONFIG, "w") as file:
                    CONFIG.write(file)
                self.menu_tasks.invoke(index)
            else:
                nom.delete(0, "end")

        top = Toplevel(self)
        top.title(_("New task"))
        top.transient(self)
        top.grab_set()
        nom = Entry(top, width=20)
        nom.grid(row=0, columnspan=2, sticky="ew")
        nom.focus_set()
        nom.bind('<Key-Return>', ajoute)
        Button(top, text=_("Cancel"), command=top.destroy).grid(row=1,
                                                                column=0)
        Button(top, text=_("Ok"), command=ajoute).grid(row=1, column=1)
        top.wait_window(top)
Пример #10
0
    def change_name(self, event):
        """Change category name."""
        def ok(event):
            cats = [l.cget('text').lower() for l in self.cat_labels.values()]
            cat = name.get().strip().lower()
            if cat and cat not in cats:
                label.configure(text=cat.capitalize())
                if old_cat == self.default_category.get():
                    self.default_category.set(cat.capitalize())
                self.update_def_cat_menu()

            name.destroy()

        label = event.widget
        old_cat = label.cget('text')
        name = Entry(self, justify='center')
        name.insert(0, label.cget('text'))
        name.place(in_=label,
                   relx=0,
                   rely=0,
                   anchor='nw',
                   relwidth=1,
                   relheight=1)
        name.bind('<FocusOut>', lambda e: name.destroy())
        name.bind('<Escape>', lambda e: name.destroy())
        name.bind('<Return>', ok)
        name.selection_range(0, 'end')
        name.focus_set()
Пример #11
0
    def add_link(self):
        def ok(eveny=None):
            lien = link.get()
            txt = text.get()
            if lien:
                if not txt:
                    txt = lien
                self.nb_links += 1
                if self.txt.tag_ranges("sel"):
                    index = self.txt.index("sel.first")
                    self.txt.delete('sel.first', 'sel.last')
                else:
                    index = "current"
                tags = self.txt.tag_names(index) + ("link",
                                                    "link#%i" % self.nb_links)
                self.txt.insert("current", txt, tags)
                if not lien[:4] == "http":
                    lien = "http://" + lien
                self.links[self.nb_links] = lien
                self.txt.tag_bind("link#%i" % self.nb_links, "<Button-1>",
                                  lambda e: open_url(lien))
            top.destroy()

        top = Toplevel(self)
        top.transient(self)
        top.update_idletasks()
        top.geometry("+%i+%i" % top.winfo_pointerxy())
        top.grab_set()
        top.resizable(True, False)
        top.title(_("Link"))
        top.columnconfigure(1, weight=1)
        text = Entry(top)
        link = Entry(top)
        if self.txt.tag_ranges('sel'):
            txt = self.txt.get('sel.first', 'sel.last')
        else:
            txt = ''
        text.insert(0, txt)
        text.icursor("end")
        Label(top, text=_("Text")).grid(row=0,
                                        column=0,
                                        sticky="e",
                                        padx=4,
                                        pady=4)
        Label(top, text=_("Link")).grid(row=1,
                                        column=0,
                                        sticky="e",
                                        padx=4,
                                        pady=4)
        text.grid(row=0, column=1, sticky="ew", padx=4, pady=4)
        link.grid(row=1, column=1, sticky="ew", padx=4, pady=4)
        Button(top, text="Ok", command=ok).grid(row=2,
                                                columnspan=2,
                                                padx=4,
                                                pady=4)

        text.focus_set()
        text.bind("<Return>", ok)
        link.bind("<Return>", ok)
Пример #12
0
    def customDate():
        def displayCustomDate(date):
            enterDateBox.destroy()
            print("Start listing songs from: " + date + ".")
            try:
                chart = billboard.ChartData("hot-100", date)
                label1 = str("1. " + str(chart[0]))
                label2 = str("2. " + str(chart[1]))
                label3 = str("3. " + str(chart[2]))
                label4 = str("4. " + str(chart[3]))
                label5 = str("5. " + str(chart[4]))
                topSong1.set(label1)
                topSong2.set(label2)
                topSong3.set(label3)
                topSong4.set(label4)
                topSong5.set(label5)
                chart_date.set("Chart data date: " + date)
                print("Done listing songs from: " + date + ".")
            except Exception as e:
                logDump(e)
                messagebox.showerror(
                    "Out of range date",
                    "Check your dates again. It could be due to:\n-Date too long in the past (before BillBoard charts existed)\-"
                )

        def cancelDialog():
            enterDateBox.destroy()
            date_object = datetime.now()
            formatted_date = "Chart data date: " + date_object.strftime(
                '%Y-%m-%d')
            chart_date.set(formatted_date)

        enterDateBox = Toplevel(billpy_window)
        enterDateBox.grab_set()
        enterDateBox.title("Custom date entry")
        enterDateBox.focus_set()
        enterDate_msg = Label(enterDateBox,
                              text="Enter the date below (YYYY-MM-DD):",
                              font=("Segoe UI", 10))
        enterDate_entry = Entry(enterDateBox)
        enterDate_entry.focus_set()
        enterDate_confirm = Button(
            enterDateBox,
            text="OK",
            command=lambda: displayCustomDate(enterDate_entry.get()))
        enterDate_confirm.bind(
            "<Return>", lambda: displayCustomDate(enterDate_entry.get()))
        enterDate_cancel = Button(enterDateBox,
                                  text="Cancel",
                                  command=cancelDialog)
        enterDate_msg.pack()
        enterDate_entry.pack()
        enterDate_confirm.pack()
        enterDate_cancel.pack()
        centerForms(enterDateBox)
        chart_date.set("Loading charts...")
        enterDateBox.mainloop()
Пример #13
0
 def __init__(self, parent, url=None, buttonSEC=False, buttonRSS=False):
     super(DialogURL, self).__init__(parent)
     self.parent = parent
     parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", parent.geometry())
     dialogX = int(parentGeometry.group(3))
     dialogY = int(parentGeometry.group(4))
     self.accepted = False
     self.url = None
     self.transient(self.parent)
     self.title("Enter URL")
     self.urlVar = StringVar()
     self.urlVar.set(url if url is not None else "http://")
     
     frame = Frame(self)
     urlLabel = Label(frame, text=_("URL:"), underline=0)
     urlEntry = Entry(frame, textvariable=self.urlVar, width=60)
     urlEntry.focus_set()
     okButton = Button(frame, text=_("OK"), command=self.ok)
     cancelButton = Button(frame, text=_("Cancel"), command=self.close)
     if buttonSEC:
         usSecButton = Button(frame, text=_("SEC search"), command=self.usSec)
         usSecButton.grid(row=1, column=1, sticky=W, pady=3)
         ToolTip(usSecButton, text=_("Opens US SEC Edgar Company Search (in web browser)\n\n"
                                  "(1) Find the company in web browser,\n"
                                  "(2) Click 'documents' button for desired filing,\n"
                                  "(3) Find 'data files' panel, instance document row, 'document' column,\n"
                                  "(4) On instance document file name, right-click browser menu: 'copy shortcut',\n"
                                  "(5) Come back to this dialog window,\n"
                                  "(6) Ctrl-v (paste) shortcut into above URL text box,\n"
                                  "(7) Click ok button to load instance document"),
                                  wraplength=480)
     if buttonRSS:
         rssButton = Button(frame, text=_("SEC RSS"), command=self.rssFeed)
         rssButton.grid(row=1, column=1, pady=3)
         ToolTip(rssButton, text=_("Opens current US SEC Edgar RSS feed"),
                                  wraplength=480)
     urlLabel.grid(row=0, column=0, sticky=W, pady=3, padx=3)
     urlEntry.grid(row=0, column=1, columnspan=3, sticky=EW, pady=3, padx=3)
     okButton.grid(row=1, column=2, sticky=E, pady=3)
     ToolTip(okButton, text=_("Opens above URL from web cache, downloading to cache if necessary"), wraplength=240)
     cancelButton.grid(row=1, column=3, sticky=EW, pady=3, padx=3)
     ToolTip(cancelButton, text=_("Cancel operation"))
                 
     frame.grid(row=0, column=0, sticky=(N,S,E,W))
     frame.columnconfigure(1, weight=1)
     window = self.winfo_toplevel()
     window.columnconfigure(0, weight=1)
     self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
     
     self.bind("<Alt-u>", lambda *ignore: urlEntry.focus_set())
     self.bind("<Return>", self.ok)
     self.bind("<Escape>", self.close)
     
     self.protocol("WM_DELETE_WINDOW", self.close)
     self.grab_set()
     self.wait_window(self)
Пример #14
0
 def __init__(self, parent, url=None, buttonSEC=False, buttonRSS=False):
     super(DialogURL, self).__init__(parent)
     self.parent = parent
     parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", parent.geometry())
     dialogX = int(parentGeometry.group(3))
     dialogY = int(parentGeometry.group(4))
     self.accepted = False
     self.url = None
     self.transient(self.parent)
     self.title("Enter URL")
     self.urlVar = StringVar()
     self.urlVar.set(url if url is not None else "http://")
     
     frame = Frame(self)
     urlLabel = Label(frame, text=_("URL:"), underline=0)
     urlEntry = Entry(frame, textvariable=self.urlVar, width=60)
     urlEntry.focus_set()
     okButton = Button(frame, text=_("OK"), command=self.ok)
     cancelButton = Button(frame, text=_("Cancel"), command=self.close)
     if buttonSEC:
         usSecButton = Button(frame, text=_("SEC search"), command=self.usSec)
         usSecButton.grid(row=1, column=1, sticky=W, pady=3)
         ToolTip(usSecButton, text=_("Opens US SEC Edgar Company Search (in web browser)\n\n"
                                  "(1) Find the company in web browser,\n"
                                  "(2) Click 'documents' button for desired filing,\n"
                                  "(3) Find 'data files' panel, instance document row, 'document' column,\n"
                                  "(4) On instance document file name, right-click browser menu: 'copy shortcut',\n"
                                  "(5) Come back to this dialog window,\n"
                                  "(6) Ctrl-v (paste) shortcut into above URL text box,\n"
                                  "(7) Click ok button to load instance document"),
                                  wraplength=480)
     if buttonRSS:
         rssButton = Button(frame, text=_("SEC RSS"), command=self.rssFeed)
         rssButton.grid(row=1, column=1, pady=3)
         ToolTip(rssButton, text=_("Opens current US SEC Edgar RSS feed"),
                                  wraplength=480)
     urlLabel.grid(row=0, column=0, sticky=W, pady=3, padx=3)
     urlEntry.grid(row=0, column=1, columnspan=3, sticky=EW, pady=3, padx=3)
     okButton.grid(row=1, column=2, sticky=E, pady=3)
     ToolTip(okButton, text=_("Opens above URL from web cache, downloading to cache if necessary"), wraplength=240)
     cancelButton.grid(row=1, column=3, sticky=EW, pady=3, padx=3)
     ToolTip(cancelButton, text=_("Cancel operation"))
                 
     frame.grid(row=0, column=0, sticky=(N,S,E,W))
     frame.columnconfigure(1, weight=1)
     window = self.winfo_toplevel()
     window.columnconfigure(0, weight=1)
     self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
     
     self.bind("<Alt-u>", lambda *ignore: urlEntry.focus_set())
     self.bind("<Return>", self.ok)
     self.bind("<Escape>", self.close)
     
     self.protocol("WM_DELETE_WINDOW", self.close)
     self.grab_set()
     self.wait_window(self)
Пример #15
0
    def add_cat(self):
        """Add a category."""
        top = Toplevel(self, class_='MyNotes')
        top.transient(self)
        top.grab_set()
        top.resizable(False, False)
        top.title(_("New Category"))

        def valide(event=None):
            cats = [l.cget('text').lower() for l in self.cat_labels.values()]
            cat = name.get().strip().lower()
            if cat and cat not in cats:
                c, i = self.frame_cat.grid_size()
                self.cat_labels[cat] = Label(self.frame_cat,
                                             text="%s" % cat.capitalize())
                self.cat_labels[cat].grid(row=i, column=0, sticky="e")
                self.cat_colors[cat] = StringVar(self, _("Yellow"))
                self.cat_menus[cat] = OptionMenu(
                    self.frame_cat,
                    self.cat_colors[cat],
                    _("Yellow"),
                    *self.colors,
                    command=lambda color, c=cat: self.change_menubutton_color(
                        color, c),
                    style="%s.TMenubutton" % cat)
                self.style.configure("%s.TMenubutton" % cat,
                                     background=COLORS[_("Yellow")])
                optionmenu_patch(self.cat_menus[cat], self.cat_colors[cat])
                self.cat_menus[cat].grid(row=i, column=1, padx=4, pady=4)
                self.cat_buttons[cat] = Button(
                    self.frame_cat,
                    image=self.im_delete,
                    padding=0,
                    command=lambda c=cat: self.del_cat(c))
                self.cat_buttons[cat].grid(row=i,
                                           column=2,
                                           padx=4,
                                           pady=4,
                                           sticky='ns')
                self.cat_buttons[self.categories[0]].configure(state="normal")
                self.categories.append(cat)
                self.categories.sort()
                self.update_def_cat_menu()
                top.destroy()

        name = Entry(top, justify="center")
        name.grid(row=0, column=0, columnspan=2, sticky="ew")
        name.bind("<Return>", valide)
        name.bind("<Escape>", lambda e: top.destroy())
        name.focus_set()
        Button(top, text="Ok", command=valide).grid(row=1,
                                                    column=0,
                                                    sticky="nswe")
        Button(top, text=_("Cancel"), command=top.destroy).grid(row=1,
                                                                column=1,
                                                                sticky="nswe")
Пример #16
0
    def change_password(self):
        """
        Change the master password: decrypt all the mailbox config files
        using the old password and encrypt them with the new.
        """
        def ok(event=None):
            with open(os.path.join(LOCAL_PATH, '.pwd')) as fich:
                cryptedpwd = fich.read()
            old = oldpwd.get()
            pwd = newpwd.get()
            pwd2 = confpwd.get()
            if crypt.crypt(old, cryptedpwd) == cryptedpwd:
                # passwords match
                if pwd == pwd2:
                    # new passwords match
                    cryptedpwd = crypt.crypt(pwd,
                                             crypt.mksalt(crypt.METHOD_SHA512))
                    with open(os.path.join(LOCAL_PATH, '.pwd'), "w") as fich:
                        fich.write(cryptedpwd)
                    mailboxes = CONFIG.get(
                        "Mailboxes", "active").split(", ") + CONFIG.get(
                            "Mailboxes", "inactive").split(", ")
                    while "" in mailboxes:
                        mailboxes.remove("")
                    for mailbox in mailboxes:
                        server, login, password, folder = decrypt(mailbox, old)
                        if server is not None:
                            encrypt(mailbox, pwd, server, login, password,
                                    folder)
                    self.pwd = pwd
                    top.destroy()
                    logging.info('Password changed')
                    return pwd
                else:
                    showerror(_('Error'), _('Passwords do not match!'))
            else:
                showerror(_('Error'), _('Incorrect password!'))

        top = Toplevel(self, class_="CheckMails")
        top.iconphoto(True, self.im_icon)
        top.resizable(False, False)
        Label(top, text=_("Old password")).pack(padx=10, pady=(10, 4))
        oldpwd = Entry(top, show='*', justify='center')
        oldpwd.pack(padx=10, pady=4)
        Label(top, text=_("New password")).pack(padx=10, pady=4)
        newpwd = Entry(top, show='*', justify='center')
        newpwd.pack(padx=10, pady=4)
        Label(top, text=_("Confirm password")).pack(padx=10, pady=4)
        confpwd = Entry(top, show='*', justify='center')
        confpwd.pack(padx=10, pady=4)
        Button(top, text="Ok", command=ok).pack(padx=10, pady=(4, 10))
        confpwd.bind("<Key-Return>", ok)
        oldpwd.focus_set()
        self.wait_window(top)
Пример #17
0
class WinLogin(Tk):
    def __init__(self, *args, **kwargs):
        '''
        Se establecen las configuraciones de la ventana de logueo
        '''
        global connection
        self.cursor = connection.cursor()

        self.accepted = False

        self.root = Tk()
        self.root.title("Inicio de sesión")
        self.root.resizable(0, 0)
        # Cuando se genera el evento de eliminar la pantalla (cerrarla)
        # se destuye la ventana principal de la aplicación que estaba minimizada
        self.root.protocol("WM_DELETE_WINDOW", self.root.destroy)

        lbl_user = Label(self.root, text="Usuario: ")
        lbl_user.grid(row=0, column=0, padx=(20, 10), pady=(10, 0))

        self.e_user = Entry(self.root, width=25)
        self.e_user.grid(row=0, column=1, padx=(10, 20), pady=(20, 10))
        self.e_user.focus_set()

        lbl_password = Label(self.root, text="Contraseña: ")
        lbl_password.grid(row=2, column=0, padx=(20, 10))

        self.e_password = Entry(self.root, width=25, show="*")
        self.e_password.grid(row=2, column=1, padx=(10, 20), pady=10)

        btn_login = Button(self.root, text="Ingresar", command=self.login)
        btn_login.grid(row=3, column=0, columnspan=3, padx=10, pady=(5, 20))

        self.root.mainloop()

    def login(self):
        '''
        Realiza el proceso de logueo de un administrador
        '''
        # Busca el administrador que posea el usuario y la contraseña proporcionados.
        sql = '''SELECT * 
                 FROM `Administrador` 
                 WHERE usuario = (?) and contrasena = (?)'''
        self.cursor.execute(sql, (self.e_user.get(), self.e_password.get()))

        # Si lo encontró, completa el logueo. Caso contrario, informa el error.
        if self.cursor.fetchone():
            self.accepted = True
            self.root.destroy()
        else:
            mb.showerror("Datos inválidos",
                         "El usuario y/o la contraseña son incorrectos.")
Пример #18
0
class StudentIDDlg(Toplevel):
 def __init__(self, initialText, title, labeltext = '' ):
     Toplevel.__init__(self)
     self.initUI(initialText,title,labeltext)

 def initUI(self,initialText,title,labeltext=''):
     self.STID = initialText
     self.geometry("200x120")
     if len(title) > 0: 
         self.title(title)
         self.style = Style()
         self.style.theme_use("default") # default

     style = Style()
     style.configure("Exit.TButton", foreground="red", background="white")
     style.configure("MainButton.TButton", foreground="yellow", background="red")

     if len(labeltext) == 0: 
         labeltext = 'Please enter your ID..'
         self.bind("<Return>", self.ok)

     xpos = 40
     ypos = 30
     xpos2 = xpos+100
     l1 = Label(self, text=initialText, foreground = "#ff0000", background = "light blue", font = "Arial 9") # Arial 12 bold italic
     l1.place(x=xpos, y=ypos)

     self.txtID = Entry(self)
     self.txtID.place(x=xpos2, y = ypos, width=70)
     self.txtID.bind("<Return>", self.ok)
     self.txtID.bind("<Escape>", self.cancel)
     self.txtID.focus_set()

     ypos += 30

     okButton = Button(self, text="OK", background = "light blue", command=self.ok)
     #okButton.configure(style="ExitButton.TButton") # does not work
     okButton.place(x=xpos2, y=ypos)

 def getID(self):
    return self.STID

 def ok(self, event=None):
    self.STID = self.txtID.get()
    self.destroy()

 def cancel(self, event=None):
    self.destroy()
Пример #19
0
 def add(self):
     def ok(event=None):
         txt = e.get()
         txt = txt.strip().replace(" ", "\ ")
         if txt and txt not in self.exclude_list:
             self.exclude_list.append(txt)
             self.listvar.set(" ".join(self.exclude_list))
         top.destroy()
     top = Toplevel(self)
     top.transient(self)
     top.grab_set()
     e = Entry(top)
     e.pack(expand=True, fill="x", padx=10, pady=(10, 4))
     e.focus_set()
     e.bind("<Key-Return>", ok)
     Button(top, text="Ok", command=ok).pack(padx=10, pady=(4, 10))
Пример #20
0
class SelectKernel(Toplevel):
    """About Toplevel."""
    def __init__(self, master):
        """Create the Toplevel to select an existing Jupyter kernel."""
        Toplevel.__init__(self, master, class_=master.winfo_class(), padx=10, pady=10)
        self.resizable(True, False)
        self.title("Select existing kernel")
        self.columnconfigure(0, minsize=22)
        self.columnconfigure(1, weight=1)
        self.columnconfigure(2, weight=1)

        self.selected_kernel = ''

        Label(self,
              text="Select the .json connection file or enter the existing kernel's id:").grid(columnspan=4,
                                                                                               sticky='w',
                                                                                               pady=4)
        self.entry = Entry(self, width=10)
        self.entry.grid(row=1, columnspan=3, sticky='ew', pady=4)
        self.entry.bind('<Return>', lambda e: self.validate())
        Button(self, text='...', width=2, padding=0,
               command=self.select_file).grid(row=1, column=3, sticky='sn', pady=4)

        Button(self, text='Ok', command=self.validate).grid(row=2, column=1,
                                                            padx=4, pady=4,
                                                            sticky='e')
        Button(self, text='Cancel', command=self.destroy).grid(row=2, column=2,
                                                               padx=4, pady=4,
                                                               sticky='w')
        self.transient(master)
        self.entry.focus_set()
        self.update_idletasks()
        self.grab_set()

    def validate(self):
        self.selected_kernel = self.entry.get()
        self.destroy()

    def select_file(self):
        filename = askopenfilename(self, "Select connection file",
                                   initialdir=jupyter_runtime_dir(),
                                   defaultextension='.json',
                                   filetypes=[('JSON', '*.json'), ('All files', '*')])
        if filename:
            self.entry.delete(0, 'end')
            self.entry.insert(0, filename)
Пример #21
0
    def add_task(self):
        def ajoute(event=None):
            task = nom.get().lower().strip()
            if task in self.tasks:
                showerror(
                    _("Error"),
                    _("The task {task} already exists.").format(task=task),
                    parent=self)

            elif task:
                coul = CMAP[(len(self.tasks) + 1) % len(CMAP)]
                i = self.task_frame.grid_size()[1] + 1
                self.tasks[task] = ColorFrame(self.task_frame, coul,
                                              task.capitalize())
                self.tasks[task].grid(row=i,
                                      column=0,
                                      sticky='e',
                                      padx=4,
                                      pady=4)
                b = Button(self.task_frame,
                           image=self.im_moins,
                           padding=2,
                           command=lambda t=task: self.del_task(t))
                b.grid(row=i, column=1, sticky='w', padx=4, pady=4)
                self._tasks_btns[task] = b
                self._tasks_btns[CONFIG.options("PomodoroTasks")[0]].state(
                    ['!disabled'])
            top.destroy()

        top = Toplevel(self)
        top.title(_("New task"))
        top.transient(self)
        top.grab_set()
        nom = Entry(top, width=20, justify='center')
        nom.grid(row=0, columnspan=2, sticky="ew")
        nom.focus_set()
        nom.bind('<Key-Return>', ajoute)
        Button(top, text=_("Cancel"), command=top.destroy).grid(row=1,
                                                                column=0)
        Button(top, text=_("Ok"), command=ajoute).grid(row=1, column=1)
        top.wait_window(top)
Пример #22
0
    def text_query(self, query_lable, original_text=None, accept_func=None):
        if self._query is not None:
            return
        frame = Frame(self.menubar)
        label = Label(frame, text=query_lable)
        label.grid(column=0, row=0, sticky=(N, S))
        self._accept_func = accept_func

        entry = Entry(frame)
        if original_text is not None:
            entry.insert(0, original_text)
        entry.original_value = original_text
        entry.grid(column=1, row=0, sticky=(N,S,W,E))
        kb.make_bindings(kb.text_query, 
                {'accept': self.accept_query,
                 'cancel': lambda e: self.close_query()}, entry.bind)

        frame.grid(column=self._menucolumn, row=0)
        self._menucolumn += 1
        entry.focus_set()
        self._query = frame
Пример #23
0
    def text_query(self, query_lable, original_text=None, accept_func=None):
        if self._query is not None:
            return
        frame = Frame(self.menubar)
        label = Label(frame, text=query_lable)
        label.grid(column=0, row=0, sticky=(N, S))
        self._accept_func = accept_func

        entry = Entry(frame)
        if original_text is not None:
            entry.insert(0, original_text)
        entry.original_value = original_text
        entry.grid(column=1, row=0, sticky=(N, S, W, E))
        kb.make_bindings(kb.text_query, {
            'accept': self.accept_query,
            'cancel': lambda e: self.close_query()
        }, entry.bind)

        frame.grid(column=self._menucolumn, row=0)
        self._menucolumn += 1
        entry.focus_set()
        self._query = frame
Пример #24
0
class FunnelEditor(tk.Frame, Subscriber, Observable):
    """Editor for one funnel
    Args:
        parent (tk.Frame): parent widget
        funnel (model.shipdata.Funnel): self explanatory
        index (int): just a number to indicate the funnel's number. Display only
        command_stack (framework.Command_stack): undo/redo stack
    """

    def __init__(self, parent, funnel, index, command_stack):
        tk.Frame.__init__(self, parent, borderwidth=4, relief="raised")
        Subscriber.__init__(self, funnel)
        Observable.__init__(self)
        self._funnel = funnel
        self._command_stack = command_stack

        self._active_var = tk.IntVar()
        self._active_var.trace_add("write", self._switch_active)

        self._y_var = tk.StringVar()
        self._y_var.set(0)
        self._y_var.trace_add("write", self._set_position)

        self._x_var = tk.StringVar()
        self._x_var.set(0)
        self._x_var.trace_add("write", self._set_position)

        self._oval_var = tk.IntVar()
        self._oval_var.trace_add("write", self._switch_oval)

        self._update()
        self.bind("<Button-1>", self._on_click)

        is_active = Checkbutton(
            self, text=f"Funnel n°{index}:  ", variable=self._active_var)
        is_active.grid(columnspan=3)
        is_active.bind("<FocusIn>", self._on_get_focus)
        is_active.bind("<FocusOut>", self._on_lost_focus)

        x_label = Label(self, text="\u21d5", anchor=tk.CENTER)
        x_label.grid(sticky=tk.E + tk.W)
        x_label.bind("<Button-1>", self._on_click)

        self.x_entry = Entry(self, textvariable=self._x_var, width=6)
        self.x_entry.grid(row=2, column=0, sticky=tk.W + tk.E)
        self.x_entry.bind("<FocusIn>", self._on_get_focus)
        self.x_entry.bind("<FocusOut>", self._on_lost_focus)

        y_label = Label(self, text="\u21d4", anchor=tk.CENTER)
        y_label.grid(row=1, column=1, sticky=tk.E+tk.W)
        y_label.bind("<Button-1>", self._on_click)

        self.y_entry = Entry(self, textvariable=self._y_var, width=6)
        self.y_entry.grid(row=2, column=1, sticky=tk.W + tk.E)
        self.y_entry.bind("<FocusIn>", self._on_get_focus)
        self.y_entry.bind("<FocusOut>", self._on_lost_focus)

        is_oval = Checkbutton(self, text="Is Oval", variable=self._oval_var)
        is_oval.grid(row=1, column=2)
        is_oval.bind("<FocusIn>", self._on_get_focus)
        is_oval.bind("<FocusOut>", self._on_lost_focus)

        force_centerline = Button(
            self, text="force on centerline", command=self._force_centerline)
        force_centerline.grid(row=2, column=2)

        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
        self.columnconfigure(2, weight=1)

    def _on_click(self, _event):
        self.x_entry.focus_set()

    def _on_notification(self, observable, event_type, event_info):
        self._update()

    def _on_lost_focus(self, event):
        self.configure(relief="raised")

    def _on_get_focus(self, *_args):
        self.configure(relief="sunken")
        self._notify("Focus", {})

    def _update(self, *_args):
        """Set all the displayed info to what is in the funnel data
        """
        # flags to avoid circular update of the values
        self._updating = True
        self._active_var.set(int(self._funnel.y != 0))
        self._y_var.set(round(self._funnel.y, 1))
        self._x_var.set(round(self._funnel.x, 1))
        self._oval_var.set(self._funnel.oval)
        self._notify(
            "Update", {"Position": [self.x, self.y], "Oval": self.oval})
        self._updating = False

    def _set_position(self, _var_name, _list_index, _operation):
        """Called when the position of a funnel is modified
        """
        if not self._updating and is_float(self._x_var.get()) and is_float(self._y_var.get()):
            self._command_stack.do(model.funnel.MoveFunnel(self._funnel, float(self._x_var.get()),
                                                           float(self._y_var.get())))

    def _switch_active(self, _var_name, _list_index, _operation):
        """Called when switching the funnel on and off
        """
        if not self._updating:
            if not bool(self._active_var.get()):
                self._command_stack.do(
                    model.funnel.MoveFunnel(self._funnel, 0))
            else:
                self._command_stack.do(
                    model.funnel.MoveFunnel(self._funnel, 1))

    def _switch_oval(self, _var_name, _list_index, _operation):
        """Called when switching the funnel from oval to circular and vice-versa
        """
        if not self._updating:
            self._command_stack.do(model.funnel.OvalFunnel(self._funnel,
                                                           bool(self._oval_var.get())))

    def update_to_coord(self, point):
        """Move the funnel to the Y position of the given point

        Intended to be called from click on the top view
        point in funnel coordinates
        """
        self._command_stack.do(model.funnel.MoveFunnel(self._funnel, point[0],
                                                       point[1]))

    def _force_centerline(self):
        self._x_var.set(0)

    @property
    def oval(self):
        """Pipe throught the funnel's data state"""
        return self._funnel.oval

    @property
    def y(self):
        """Pipe throught the funnel's data state"""
        return self._funnel.y

    @property
    def x(self):
        """Pipe throught the funnel's data state"""
        return self._funnel.x
Пример #25
0
class Query(Toplevel):
    """Base class for getting verified answer from a user.

    For this base class, accept any non-blank string.
    """
    def __init__(self,
                 parent,
                 title,
                 message,
                 *,
                 text0='',
                 used_names={},
                 _htest=False,
                 _utest=False):
        """Create modal popup, return when destroyed.

        Additional subclass init must be done before this unless
        _utest=True is passed to suppress wait_window().

        title - string, title of popup dialog
        message - string, informational message to display
        text0 - initial value for entry
        used_names - names already in use
        _htest - bool, change box location when running htest
        _utest - bool, leave window hidden and not modal
        """
        self.parent = parent  # Needed for Font call.
        self.message = message
        self.text0 = text0
        self.used_names = used_names

        Toplevel.__init__(self, parent)
        self.withdraw()  # Hide while configuring, especially geometry.
        self.title(title)
        self.transient(parent)
        if not _utest:  # Otherwise fail when directly run unittest.
            self.grab_set()

        _setup_dialog(self)
        if self._windowingsystem == 'aqua':
            self.bind("<Command-.>", self.cancel)
        self.bind('<Key-Escape>', self.cancel)
        self.protocol("WM_DELETE_WINDOW", self.cancel)
        self.bind('<Key-Return>', self.ok)
        self.bind("<KP_Enter>", self.ok)

        self.create_widgets()
        self.update_idletasks()  # Need here for winfo_reqwidth below.
        self.geometry(  # Center dialog over parent (or below htest box).
            "+%d+%d" % (parent.winfo_rootx() +
                        (parent.winfo_width() / 2 - self.winfo_reqwidth() / 2),
                        parent.winfo_rooty() +
                        ((parent.winfo_height() / 2 -
                          self.winfo_reqheight() / 2) if not _htest else 150)))
        self.resizable(height=False, width=False)

        if not _utest:
            self.deiconify()  # Unhide now that geometry set.
            self.wait_window()

    def create_widgets(self, ok_text='OK'):  # Do not replace.
        """Create entry (rows, extras, buttons.

        Entry stuff on rows 0-2, spanning cols 0-2.
        Buttons on row 99, cols 1, 2.
        """
        # Bind to self the widgets needed for entry_ok or unittest.
        self.frame = frame = Frame(self, padding=10)
        frame.grid(column=0, row=0, sticky='news')
        frame.grid_columnconfigure(0, weight=1)

        entrylabel = Label(frame,
                           anchor='w',
                           justify='left',
                           text=self.message)
        self.entryvar = StringVar(self, self.text0)
        self.entry = Entry(frame, width=30, textvariable=self.entryvar)
        self.entry.focus_set()
        self.error_font = Font(name='TkCaptionFont',
                               exists=True,
                               root=self.parent)
        self.entry_error = Label(frame,
                                 text=' ',
                                 foreground='red',
                                 font=self.error_font)
        # Display or blank error by setting ['text'] =.
        entrylabel.grid(column=0, row=0, columnspan=3, padx=5, sticky=W)
        self.entry.grid(column=0,
                        row=1,
                        columnspan=3,
                        padx=5,
                        sticky=W + E,
                        pady=[10, 0])
        self.entry_error.grid(column=0,
                              row=2,
                              columnspan=3,
                              padx=5,
                              sticky=W + E)

        self.create_extra()

        self.button_ok = Button(frame,
                                text=ok_text,
                                default='active',
                                command=self.ok)
        self.button_cancel = Button(frame, text='Cancel', command=self.cancel)

        self.button_ok.grid(column=1, row=99, padx=5)
        self.button_cancel.grid(column=2, row=99, padx=5)

    def create_extra(self):
        pass  # Override to add widgets.

    def showerror(self, message, widget=None):
        #self.bell(displayof=self)
        (widget or self.entry_error)['text'] = 'ERROR: ' + message

    def entry_ok(self):  # Example: usually replace.
        "Return non-blank entry or None."
        entry = self.entry.get().strip()
        if not entry:
            self.showerror('blank line.')
            return None
        return entry

    def ok(self, event=None):  # Do not replace.
        '''If entry is valid, bind it to 'result' and destroy tk widget.

        Otherwise leave dialog open for user to correct entry or cancel.
        '''
        self.entry_error['text'] = ''
        entry = self.entry_ok()
        if entry is not None:
            self.result = entry
            self.destroy()
        else:
            # [Ok] moves focus.  (<Return> does not.)  Move it back.
            self.entry.focus_set()

    def cancel(self, event=None):  # Do not replace.
        "Set dialog result to None and destroy tk widget."
        self.result = None
        self.destroy()

    def destroy(self):
        self.grab_release()
        super().destroy()
Пример #26
0
class MainApp():
    def __init__(self):
        self.File_name = None
        self.Programe_Name = "CHE-Editor"
        self.WDG = Tk()
        self.WDG.title(self.Programe_Name)
        self.WDG.iconbitmap("icons/icon_editor.ico")
        self.WDG.geometry("860x620")
        self.WDG.maxsize(width=1340, height=700)
        self.WDG.minsize(width=860, height=620)
        self.Main_UI()

    def Main_UI(self):
        self.MenuBar = Menu(self.WDG)

        #1      #MenuBar
        #File_menu
        self.File_menu = Menu(self.MenuBar, tearoff=0, title="File")
        self.MenuBar.add_cascade(label="File", menu=self.File_menu)
        #Edit_menu
        self.Edit_menu = Menu(self.MenuBar, tearoff=0, title="Edit")
        self.MenuBar.add_cascade(label="Edit", menu=self.Edit_menu)
        #View_menu
        self.View_menu = Menu(self.MenuBar, tearoff=0, title="View")
        self.MenuBar.add_cascade(label="View", menu=self.View_menu)
        #Theme_menu in View
        self.Theme_menu = Menu(self.View_menu, tearoff=0, title="Theme")
        self.View_menu.add_cascade(label="Theme", menu=self.Theme_menu)
        #Option_menu
        self.Options_menu = Menu(self.MenuBar, tearoff=0, title="Options")
        self.MenuBar.add_cascade(label="Options", menu=self.Options_menu)
        #Help_menu
        self.Help_menu = Menu(self.MenuBar, tearoff=0, title="Help")
        self.MenuBar.add_cascade(label="Help", menu=self.Help_menu)

        #2      #Icons Variables
        #Edit_Menu Icons
        Undo = PhotoImage(file="icons/Undo.gif")
        Redo = PhotoImage(file="icons/redo.gif")
        Paste = PhotoImage(file="icons/paste.gif")
        Copy = PhotoImage(file="icons/copy.gif")
        Cut = PhotoImage(file="icons/cut.gif")
        #Help_Menu_Icons
        Help = PhotoImage(file="icons/help.gif")
        About = PhotoImage(file="icons/about.gif")
        #File_Menu_Icons
        New = PhotoImage(file="icons/new.gif")
        Open = PhotoImage(file="icons/open.gif")
        Save = PhotoImage(file="icons/save.gif")
        Save_As = PhotoImage(file="icons/save_as.gif")
        Exit = PhotoImage(file="icons/exit.gif")

        #Appear menubar in app
        self.WDG.config(menu=self.MenuBar)
        #self.WDG.config(menu=self.IconBar)

        #3      #Set commands in menus
        #File_Menu
        self.File_menu.add_command(label="New",
                                   accelerator="Ctrl+N",
                                   compound="left",
                                   underline=0,
                                   command=self.New)
        self.File_menu.add_command(label="Open",
                                   accelerator="Ctrl+O",
                                   compound="left",
                                   underline=0,
                                   command=self.Open)
        self.File_menu.add_command(label="Save",
                                   accelerator="Ctrl+S",
                                   compound="left",
                                   underline=0,
                                   command=self.Save)
        self.File_menu.add_command(label="Save as",
                                   accelerator="Shift+Ctrl+S",
                                   compound="left",
                                   underline=0,
                                   command=self.Save_As)
        self.File_menu.add_separator()
        self.File_menu.add_command(label="Exit",
                                   accelerator="F4",
                                   compound="left",
                                   underline=0,
                                   command=self.Exit)
        #Edit_Menu
        self.Edit_menu.add_command(label="Undo",
                                   accelerator="Ctrl+Z",
                                   compound="left",
                                   underline=0,
                                   command=self.Undo)
        self.Edit_menu.add_command(label="Redo",
                                   accelerator='Ctrl+Y',
                                   compound='left',
                                   underline=0,
                                   command=self.Redo)
        self.Edit_menu.add_command(label="Select all",
                                   accelerator='Ctrl+A',
                                   compound='left',
                                   underline=0,
                                   command=self.Select)
        self.Edit_menu.add_command(label="Cut",
                                   accelerator='Ctrl+X',
                                   compound='left',
                                   underline=7,
                                   command=self.Cut)
        self.Edit_menu.add_command(label="Copy",
                                   accelerator='Ctrl+C',
                                   compound='left',
                                   underline=0,
                                   command=self.Copy)
        self.Edit_menu.add_command(label="Paste",
                                   accelerator='Ctrl+V',
                                   compound='left',
                                   underline=0,
                                   command=self.Paste)
        self.Edit_menu.add_command(label="Search",
                                   accelerator='Ctrl+F',
                                   compound='left',
                                   underline=0,
                                   command=self.Search)
        #Help_Menu
        self.Help_menu.add_command(label="Help",
                                   accelerator="F1",
                                   compound="left",
                                   underline=0,
                                   command=self.Help)
        self.Help_menu.add_command(label="About",
                                   compound="left",
                                   underline=0,
                                   command=self.About)
        #View_Menu
        self.Show_line_number = IntVar()
        self.Show_line_number.set(1)
        self.theme_name = StringVar()
        self.View_menu.add_checkbutton(label="Show Line Number",
                                       variable=self.Show_line_number)
        self.Highlightline = BooleanVar()
        self.View_menu.add_checkbutton(label='Highlight Current Line',
                                       onvalue=1,
                                       offvalue=0,
                                       variable=self.Highlightline,
                                       command=self.Toggle_highlight)
        self.cursorcoord = BooleanVar()
        self.View_menu.add_checkbutton(label='Show Cursor Location',
                                       variable=self.cursorcoord,
                                       command=self.Show_cursor_coord)
        self.Theme_menu.add_radiobutton(label="Default",
                                        variable=self.theme_name)

        #4      #add Shortcut_Bar & Row_Number_Bar
        #Shortcut_Bar
        self.Shortcut_Bar = Frame(self.WDG, height=25)
        self.Shortcut_Bar.pack(expand='no', fill='x')
        Icons = ['New', 'Open', 'Save', 'Copy', 'Cut', 'Paste', 'Undo', 'Redo']
        for i, icon in enumerate(Icons):
            Tool_icon = PhotoImage(file='icons/{}.gif'.format(icon))
            #c_var = 'self.{}'.format(icon)
            cmd = eval('self.{}'.format(icon))
            self.Tool_bar_btn = Button(self.Shortcut_Bar,
                                       image=Tool_icon,
                                       command=cmd)
            self.Tool_bar_btn.image = Tool_icon
            self.Tool_bar_btn.pack(side='left')
        #Row_Number_Bar
        self.Row_Number_Bar = Text(self.WDG,
                                   width=3,
                                   padx=3,
                                   takefocus=0,
                                   border=0,
                                   background='khaki',
                                   state='disabled',
                                   wrap='none')
        self.Row_Number_Bar.pack(side='left', fill='y')

        #5      #add Content_Text
        self.Content_Text = Text(self.WDG, wrap='word', undo=1)
        self.Content_Text.pack(expand='yes', fill='both')
        self.Content_Text.tag_configure('active_line', background='ivory2')
        self.Scroll_Bar = Scrollbar(self.Content_Text)
        self.Content_Text.configure(yscrollcommand=self.Scroll_Bar.set)
        self.Scroll_Bar.config(command=self.Content_Text.yview)
        self.Scroll_Bar.pack(side='right', fill='y')

        #6      #add_Cursor_Coord_Bar
        self.Cursor_Coord_Bar = Label(self.Content_Text,
                                      text='Row: 1 | Column: 1')
        self.Cursor_Coord_Bar.pack(fill=None,
                                   expand='no',
                                   side='right',
                                   anchor='se')

        #7      #Binding
        self.Content_Text.bind("<Control-o>", self.Open)
        self.Content_Text.bind("<Control-O>", self.Open)
        self.Content_Text.bind("<Control-s>", self.Save)
        self.Content_Text.bind("<Control-S>", self.Save)
        self.Content_Text.bind("<Shift-Control-KeyPress-s>", self.Save_As)
        self.Content_Text.bind("<Shift-Control-KeyPress-S>", self.Save_As)
        self.Content_Text.bind("<Control-n>", self.New)
        self.Content_Text.bind("<Control-N>", self.New)
        self.Content_Text.bind("<Control-z>", self.Undo)
        self.Content_Text.bind("<Control-Z>", self.Undo)
        self.Content_Text.bind("<Control-y>", self.Redo)
        self.Content_Text.bind("<Control-Y>", self.Redo)
        self.Content_Text.bind("<Control-x>", self.Cut)
        self.Content_Text.bind("<Control-X>", self.Cut)
        self.Content_Text.bind("<Control-a>", self.Select)
        self.Content_Text.bind("<Control-A>", self.Select)
        self.Content_Text.bind("<Control-c>", self.Copy)
        self.Content_Text.bind("<Control-C>", self.Copy)
        self.Content_Text.bind("<Control-v>", self.Paste)
        self.Content_Text.bind("<Control-V>", self.Paste)
        self.Content_Text.bind("<Control-f>", self.Search)
        self.Content_Text.bind("<Control-F>", self.Search)
        self.Content_Text.bind("<Any-KeyPress>", self.Content_changed)
        self.WDG.bind_all("<KeyPress-F1>", self.Help)
        self.WDG.bind_all("<KeyPress-F4>", self.Exit)


#8  #Built In Finctions
#File_Menu_Functions

    def New(self, event=None):
        self.Content_Text.delete(1., 'end')
        self.WDG.title('{} - {}'.format('Untitled', self.Programe_Name))

    ##
    def Open(self, event=None):
        self.Open_file_name = filedialog.askopenfilename(
            defaultextension=".txt",
            filetypes=[("All Files", "*.*"), ("Text Documents", "*.txt")])
        if self.Open_file_name:
            self.File_name = self.Open_file_name
            self.WDG.title("{} - {}".format(os.path.basename(self.File_name),
                                            self.Programe_Name))
            self.Content_Text.delete(1.0, 'end')
            with open(self.File_name) as _File:
                self.Content_Text.insert(1.0, _File.read())

    ##
    def Save(self, event=None):
        if not self.File_name:
            self.Save_As()
        else:
            self.Write_to_file(self.File_name)
        return "break"

    ##
    def Save_As(self, event=None):
        self.Save_file_name = filedialog.asksaveasfilename(
            defaultextension='.txt',
            filetypes=[('All Files', '*.*'), ('Text Documents', '*.txt')])
        if self.Save_file_name:
            self.File_name = self.Save_file_name
            self.Write_to_file(self.File_name)
            self.WDG.title('{} - {}'.format(os.path.basename(self.File_name),
                                            self.Programe_Name))
        return "break"

    ##
    def Write_to_file(self, filename):
        try:
            self.content = self.Content_Text.get(1.0, 'end')
            with open(self.File_name, 'w') as the_file:
                the_file.write(self.content)
        except IOError as er:
            print(er)

    ##
    def Exit(self, event=None):
        self.msg_exit = messagebox.askyesno('Exit Editor',
                                            'Do you want to exit?')
        if self.msg_exit:
            self.WDG.destroy()

    #Edit_Menu_Functions
    ##
    def Select(self, event=None):
        self.Content_Text.tag_add("sel", 1.0, "end")
        print("Done1")
        return "breake"

    ##
    def Cut(self, event=None):
        self.Content_Text.event_generate("<<Cut>>")
        return "breake"

    ##
    def Copy(self, event=None):
        self.Content_Text.event_generate("<<Copy>>")
        return "breake"

    ##
    def Paste(self, event=None):
        self.Content_Text.event_generate("<<Paste>>")
        return "breake"

    ##
    def Undo(self, event=None):
        self.Content_Text.event_generate("<<Undo>>")
        return "breake"

    ##
    def Redo(self, event=None):
        self.Content_Text.event_generate("<<Redo>>")
        return "breake"

    ##
    def Search(self, event=None):
        self.Search_Window = Toplevel(self.WDG)
        self.Search_Window.title("Search About...")
        self.Search_Window.transient(self.WDG)
        self.Search_Window.resizable(False, False)
        self.S_lbl_1 = Label(self.Search_Window, text='Search About :')
        self.S_lbl_1.grid(row=0, column=0, sticky='e')
        self.S_ent_1 = Entry(self.Search_Window, width=28)
        self.S_ent_1.grid(row=0, column=1, padx=2, pady=2, sticky='we')
        self.S_ent_1.focus_set()
        Ignore_case_value = IntVar()
        self.S_chk_1 = Checkbutton(self.Search_Window,
                                   text='Ignor Case',
                                   variable=Ignore_case_value)
        self.S_chk_1.grid(row=1, column=1, padx=2, pady=2, sticky='e')
        self.S_btn_1 = Button(
            self.Search_Window,
            text='Find',
            underline=0,
            command=lambda: self.Search_results(self.S_ent_1.get(
            ), Ignore_case_value.get(), self.Content_Text, self.Search_Window,
                                                self.S_ent_1))
        self.S_btn_1.grid(row=0, column=2, padx=2, pady=2, sticky='e' + 'w')
        self.S_btn_2 = Button(self.Search_Window,
                              text='Cancel',
                              underline=0,
                              command=self.Close_Search_Window)
        self.S_btn_2.grid(row=1, column=2, padx=2, pady=2, sticky='e' + 'w')

    ##
    def Search_results(self, Keyword, IfIgnoreCase, Content, Output, Input):
        Content.tag_remove('match', '1.0', 'end')
        matches_found = 0
        if Keyword:
            start_pos = '1.0'
            while True:
                start_pos = Content.search(Keyword,
                                           start_pos,
                                           nocase=IfIgnoreCase,
                                           stopindex='end')
                if not start_pos:
                    break
                end_pos = "{} + {}c".format(start_pos, len(Keyword))
                Content.tag_add('match', start_pos, end_pos)
                matches_found += 1
                start_pos = end_pos
            Content.tag_config('match', foreground='red', background='yellow')
            Input.focus_set()
            Output.title("{} matches found".format(matches_found))

    ##
    def Close_Search_Window(self):
        self.Content_Text.tag_remove('match', '1.0', 'end')
        self.Search_Window.destroy()
        #self.Search_Window.protocol('WM_DELETE_WINDOW',self.Close_Search_Window)
        return "break"

    #View_Menu_Functions
    ##
    def Content_changed(self, event=None):
        self.Update_line_numbers()
        self.Update_cursor_coord()

    ##
    def Get_line_numbers(self, event=None):
        self.Number = ""
        if self.Show_line_number.get():
            self.Row, self.Column = self.Content_Text.index('end').split('.')
            for i in range(1, int(self.Row)):
                self.Number += str(i) + "\n"
        return self.Number

    ##
    def Update_line_numbers(self):
        self.Line_Number = self.Get_line_numbers()
        self.Row_Number_Bar.config(state='normal')
        self.Row_Number_Bar.delete(1.0, 'end')
        self.Row_Number_Bar.insert(1.0, self.Line_Number)
        self.Row_Number_Bar.config(state='disabled')

    ##
    def Toggle_highlight(self, event=None):
        if self.Highlightline.get():
            self.Highlight_line()
        else:
            self.Undo_highlight()

    ##
    def Highlight_line(self, interval=100):
        self.Content_Text.tag_remove('active_line', 1.0, 'end')
        self.Content_Text.tag_add('active_line', "insert linestart",
                                  "insert lineend+1c")
        self.Content_Text.after(interval, self.Toggle_highlight)

    ##
    def Undo_highlight(self):
        self.Content_Text.tag_remove('active_line', 1.0, 'end')

    ##
    def Show_cursor_coord(self):
        self.cursor_coord_checked = self.cursorcoord.get()
        if self.cursor_coord_checked:
            self.Cursor_Coord_Bar.pack(expand='no',
                                       fill=None,
                                       side='right',
                                       anchor='se')
        else:
            self.Cursor_Coord_Bar.pack_forget()

    ##
    def Update_cursor_coord(self):
        self.Row_2, self.Column_2 = self.Content_Text.index('insert').split(
            '.')
        self.row_num, self.col_num = str(int(
            self.Row_2)), str(int(self.Column_2) + 1)
        self.Coord = "Row: {} | Column: {}".format(self.row_num, self.col_num)
        self.Cursor_Coord_Bar.config(text=self.Coord)

    #Help_Menu_Functions
    ##
    def About(self, event=None):
        messagebox.showinfo(
            'About', '{} {}'.format(self.Programe_Name,
                                    '\nDeveloped by \n TaReK'))

    ##
    def Help(self, event=None):
        messagebox.showinfo('Help',
                            'Text Editor building in python',
                            icon='question')
Пример #27
0
class GetKeysDialog(Toplevel):

    # Dialog title for invalid key sequence
    keyerror_title = 'Key Sequence Error'

    def __init__(self, parent, title, action, current_key_sequences,
                 *, _htest=False, _utest=False):
        """
        parent - parent of this dialog
        title - string which is the title of the popup dialog
        action - string, the name of the virtual event these keys will be
                 mapped to
        current_key_sequences - list, a list of all key sequence lists
                 currently mapped to virtual events, for overlap checking
        _htest - bool, change box location when running htest
        _utest - bool, do not wait when running unittest
        """
        Toplevel.__init__(self, parent)
        self.withdraw()  # Hide while setting geometry.
        self.configure(borderwidth=5)
        self.resizable(height=False, width=False)
        self.title(title)
        self.transient(parent)
        self.grab_set()
        self.protocol("WM_DELETE_WINDOW", self.cancel)
        self.parent = parent
        self.action = action
        self.current_key_sequences = current_key_sequences
        self.result = ''
        self.key_string = StringVar(self)
        self.key_string.set('')
        # Set self.modifiers, self.modifier_label.
        self.set_modifiers_for_platform()
        self.modifier_vars = []
        for modifier in self.modifiers:
            variable = StringVar(self)
            variable.set('')
            self.modifier_vars.append(variable)
        self.advanced = False
        self.create_widgets()
        self.update_idletasks()
        self.geometry(
                "+%d+%d" % (
                    parent.winfo_rootx() +
                    (parent.winfo_width()/2 - self.winfo_reqwidth()/2),
                    parent.winfo_rooty() +
                    ((parent.winfo_height()/2 - self.winfo_reqheight()/2)
                    if not _htest else 150)
                ) )  # Center dialog over parent (or below htest box).
        if not _utest:
            self.deiconify()  # Geometry set, unhide.
            self.wait_window()

    def showerror(self, *args, **kwargs):
        # Make testing easier.  Replace in #30751.
        messagebox.showerror(*args, **kwargs)

    def create_widgets(self):
        self.frame = frame = Frame(self, borderwidth=2, relief='sunken')
        frame.pack(side='top', expand=True, fill='both')

        frame_buttons = Frame(self)
        frame_buttons.pack(side='bottom', fill='x')

        self.button_ok = Button(frame_buttons, text='OK',
                                width=8, command=self.ok)
        self.button_ok.grid(row=0, column=0, padx=5, pady=5)
        self.button_cancel = Button(frame_buttons, text='Cancel',
                                   width=8, command=self.cancel)
        self.button_cancel.grid(row=0, column=1, padx=5, pady=5)

        # Basic entry key sequence.
        self.frame_keyseq_basic = Frame(frame, name='keyseq_basic')
        self.frame_keyseq_basic.grid(row=0, column=0, sticky='nsew',
                                      padx=5, pady=5)
        basic_title = Label(self.frame_keyseq_basic,
                            text=f"New keys for '{self.action}' :")
        basic_title.pack(anchor='w')

        basic_keys = Label(self.frame_keyseq_basic, justify='left',
                           textvariable=self.key_string, relief='groove',
                           borderwidth=2)
        basic_keys.pack(ipadx=5, ipady=5, fill='x')

        # Basic entry controls.
        self.frame_controls_basic = Frame(frame)
        self.frame_controls_basic.grid(row=1, column=0, sticky='nsew', padx=5)

        # Basic entry modifiers.
        self.modifier_checkbuttons = {}
        column = 0
        for modifier, variable in zip(self.modifiers, self.modifier_vars):
            label = self.modifier_label.get(modifier, modifier)
            check = Checkbutton(self.frame_controls_basic,
                                command=self.build_key_string, text=label,
                                variable=variable, onvalue=modifier, offvalue='')
            check.grid(row=0, column=column, padx=2, sticky='w')
            self.modifier_checkbuttons[modifier] = check
            column += 1

        # Basic entry help text.
        help_basic = Label(self.frame_controls_basic, justify='left',
                           text="Select the desired modifier keys\n"+
                                "above, and the final key from the\n"+
                                "list on the right.\n\n" +
                                "Use upper case Symbols when using\n" +
                                "the Shift modifier.  (Letters will be\n" +
                                "converted automatically.)")
        help_basic.grid(row=1, column=0, columnspan=4, padx=2, sticky='w')

        # Basic entry key list.
        self.list_keys_final = Listbox(self.frame_controls_basic, width=15,
                                       height=10, selectmode='single')
        self.list_keys_final.insert('end', *AVAILABLE_KEYS)
        self.list_keys_final.bind('<ButtonRelease-1>', self.final_key_selected)
        self.list_keys_final.grid(row=0, column=4, rowspan=4, sticky='ns')
        scroll_keys_final = Scrollbar(self.frame_controls_basic,
                                      orient='vertical',
                                      command=self.list_keys_final.yview)
        self.list_keys_final.config(yscrollcommand=scroll_keys_final.set)
        scroll_keys_final.grid(row=0, column=5, rowspan=4, sticky='ns')
        self.button_clear = Button(self.frame_controls_basic,
                                   text='Clear Keys',
                                   command=self.clear_key_seq)
        self.button_clear.grid(row=2, column=0, columnspan=4)

        # Advanced entry key sequence.
        self.frame_keyseq_advanced = Frame(frame, name='keyseq_advanced')
        self.frame_keyseq_advanced.grid(row=0, column=0, sticky='nsew',
                                         padx=5, pady=5)
        advanced_title = Label(self.frame_keyseq_advanced, justify='left',
                               text=f"Enter new binding(s) for '{self.action}' :\n" +
                                     "(These bindings will not be checked for validity!)")
        advanced_title.pack(anchor='w')
        self.advanced_keys = Entry(self.frame_keyseq_advanced,
                                   textvariable=self.key_string)
        self.advanced_keys.pack(fill='x')

        # Advanced entry help text.
        self.frame_help_advanced = Frame(frame)
        self.frame_help_advanced.grid(row=1, column=0, sticky='nsew', padx=5)
        help_advanced = Label(self.frame_help_advanced, justify='left',
            text="Key bindings are specified using Tkinter keysyms as\n"+
                 "in these samples: <Control-f>, <Shift-F2>, <F12>,\n"
                 "<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n"
                 "Upper case is used when the Shift modifier is present!\n\n" +
                 "'Emacs style' multi-keystroke bindings are specified as\n" +
                 "follows: <Control-x><Control-y>, where the first key\n" +
                 "is the 'do-nothing' keybinding.\n\n" +
                 "Multiple separate bindings for one action should be\n"+
                 "separated by a space, eg., <Alt-v> <Meta-v>." )
        help_advanced.grid(row=0, column=0, sticky='nsew')

        # Switch between basic and advanced.
        self.button_level = Button(frame, command=self.toggle_level,
                                  text='<< Basic Key Binding Entry')
        self.button_level.grid(row=2, column=0, stick='ew', padx=5, pady=5)
        self.toggle_level()

    def set_modifiers_for_platform(self):
        """Determine list of names of key modifiers for this platform.

        The names are used to build Tk bindings -- it doesn't matter if the
        keyboard has these keys; it matters if Tk understands them.  The
        order is also important: key binding equality depends on it, so
        config-keys.def must use the same ordering.
        """
        if sys.platform == "darwin":
            self.modifiers = ['Shift', 'Control', 'Option', 'Command']
        else:
            self.modifiers = ['Control', 'Alt', 'Shift']
        self.modifier_label = {'Control': 'Ctrl'}  # Short name.

    def toggle_level(self):
        "Toggle between basic and advanced keys."
        if  self.button_level.cget('text').startswith('Advanced'):
            self.clear_key_seq()
            self.button_level.config(text='<< Basic Key Binding Entry')
            self.frame_keyseq_advanced.lift()
            self.frame_help_advanced.lift()
            self.advanced_keys.focus_set()
            self.advanced = True
        else:
            self.clear_key_seq()
            self.button_level.config(text='Advanced Key Binding Entry >>')
            self.frame_keyseq_basic.lift()
            self.frame_controls_basic.lift()
            self.advanced = False

    def final_key_selected(self, event=None):
        "Handler for clicking on key in basic settings list."
        self.build_key_string()

    def build_key_string(self):
        "Create formatted string of modifiers plus the key."
        keylist = modifiers = self.get_modifiers()
        final_key = self.list_keys_final.get('anchor')
        if final_key:
            final_key = translate_key(final_key, modifiers)
            keylist.append(final_key)
        self.key_string.set(f"<{'-'.join(keylist)}>")

    def get_modifiers(self):
        "Return ordered list of modifiers that have been selected."
        mod_list = [variable.get() for variable in self.modifier_vars]
        return [mod for mod in mod_list if mod]

    def clear_key_seq(self):
        "Clear modifiers and keys selection."
        self.list_keys_final.select_clear(0, 'end')
        self.list_keys_final.yview('moveto', '0.0')
        for variable in self.modifier_vars:
            variable.set('')
        self.key_string.set('')

    def ok(self, event=None):
        keys = self.key_string.get().strip()
        if not keys:
            self.showerror(title=self.keyerror_title, parent=self,
                           message="No key specified.")
            return
        if (self.advanced or self.keys_ok(keys)) and self.bind_ok(keys):
            self.result = keys
        self.grab_release()
        self.destroy()

    def cancel(self, event=None):
        self.result = ''
        self.grab_release()
        self.destroy()

    def keys_ok(self, keys):
        """Validity check on user's 'basic' keybinding selection.

        Doesn't check the string produced by the advanced dialog because
        'modifiers' isn't set.
        """
        final_key = self.list_keys_final.get('anchor')
        modifiers = self.get_modifiers()
        title = self.keyerror_title
        key_sequences = [key for keylist in self.current_key_sequences
                             for key in keylist]
        if not keys.endswith('>'):
            self.showerror(title, parent=self,
                           message='Missing the final Key')
        elif (not modifiers
              and final_key not in FUNCTION_KEYS + MOVE_KEYS):
            self.showerror(title=title, parent=self,
                           message='No modifier key(s) specified.')
        elif (modifiers == ['Shift']) \
                 and (final_key not in
                      FUNCTION_KEYS + MOVE_KEYS + ('Tab', 'Space')):
            msg = 'The shift modifier by itself may not be used with'\
                  ' this key symbol.'
            self.showerror(title=title, parent=self, message=msg)
        elif keys in key_sequences:
            msg = 'This key combination is already in use.'
            self.showerror(title=title, parent=self, message=msg)
        else:
            return True
        return False

    def bind_ok(self, keys):
        "Return True if Tcl accepts the new keys else show message."
        try:
            binding = self.bind(keys, lambda: None)
        except TclError as err:
            self.showerror(
                    title=self.keyerror_title, parent=self,
                    message=(f'The entered key sequence is not accepted.\n\n'
                             f'Error: {err}'))
            return False
        else:
            self.unbind(keys, binding)
            return True
Пример #28
0
class Query(Toplevel):
    """Base class for getting verified answer from a user.

    For this base class, accept any non-blank string.
    """
    def __init__(self, parent, title, message, *, text0='', used_names={},
                 _htest=False, _utest=False):
        """Create popup, do not return until tk widget destroyed.

        Additional subclass init must be done before calling this
        unless  _utest=True is passed to suppress wait_window().

        title - string, title of popup dialog
        message - string, informational message to display
        text0 - initial value for entry
        used_names - names already in use
        _htest - bool, change box location when running htest
        _utest - bool, leave window hidden and not modal
        """
        Toplevel.__init__(self, parent)
        self.withdraw()  # Hide while configuring, especially geometry.
        self.parent = parent
        self.title(title)
        self.message = message
        self.text0 = text0
        self.used_names = used_names
        self.transient(parent)
        self.grab_set()
        windowingsystem = self.tk.call('tk', 'windowingsystem')
        if windowingsystem == 'aqua':
            try:
                self.tk.call('::tk::unsupported::MacWindowStyle', 'style',
                             self._w, 'moveableModal', '')
            except:
                pass
            self.bind("<Command-.>", self.cancel)
        self.bind('<Key-Escape>', self.cancel)
        self.protocol("WM_DELETE_WINDOW", self.cancel)
        self.bind('<Key-Return>', self.ok)
        self.bind("<KP_Enter>", self.ok)
        self.resizable(height=False, width=False)
        self.create_widgets()
        self.update_idletasks()  # Needed here for winfo_reqwidth below.
        self.geometry(  # Center dialog over parent (or below htest box).
                "+%d+%d" % (
                    parent.winfo_rootx() +
                    (parent.winfo_width()/2 - self.winfo_reqwidth()/2),
                    parent.winfo_rooty() +
                    ((parent.winfo_height()/2 - self.winfo_reqheight()/2)
                    if not _htest else 150)
                ) )
        if not _utest:
            self.deiconify()  # Unhide now that geometry set.
            self.wait_window()

    def create_widgets(self):  # Call from override, if any.
        # Bind to self widgets needed for entry_ok or unittest.
        self.frame = frame = Frame(self, padding=10)
        frame.grid(column=0, row=0, sticky='news')
        frame.grid_columnconfigure(0, weight=1)

        entrylabel = Label(frame, anchor='w', justify='left',
                           text=self.message)
        self.entryvar = StringVar(self, self.text0)
        self.entry = Entry(frame, width=30, textvariable=self.entryvar)
        self.entry.focus_set()
        self.error_font = Font(name='TkCaptionFont',
                               exists=True, root=self.parent)
        self.entry_error = Label(frame, text=' ', foreground='red',
                                 font=self.error_font)
        self.button_ok = Button(
                frame, text='OK', default='active', command=self.ok)
        self.button_cancel = Button(
                frame, text='Cancel', command=self.cancel)

        entrylabel.grid(column=0, row=0, columnspan=3, padx=5, sticky=W)
        self.entry.grid(column=0, row=1, columnspan=3, padx=5, sticky=W+E,
                        pady=[10,0])
        self.entry_error.grid(column=0, row=2, columnspan=3, padx=5,
                              sticky=W+E)
        self.button_ok.grid(column=1, row=99, padx=5)
        self.button_cancel.grid(column=2, row=99, padx=5)

    def showerror(self, message, widget=None):
        #self.bell(displayof=self)
        (widget or self.entry_error)['text'] = 'ERROR: ' + message

    def entry_ok(self):  # Example: usually replace.
        "Return non-blank entry or None."
        self.entry_error['text'] = ''
        entry = self.entry.get().strip()
        if not entry:
            self.showerror('blank line.')
            return None
        return entry

    def ok(self, event=None):  # Do not replace.
        '''If entry is valid, bind it to 'result' and destroy tk widget.

        Otherwise leave dialog open for user to correct entry or cancel.
        '''
        entry = self.entry_ok()
        if entry is not None:
            self.result = entry
            self.destroy()
        else:
            # [Ok] moves focus.  (<Return> does not.)  Move it back.
            self.entry.focus_set()

    def cancel(self, event=None):  # Do not replace.
        "Set dialog result to None and destroy tk widget."
        self.result = None
        self.destroy()
Пример #29
0
class GraphicalUserInterface(Frame):
    """
    Graphical User Interface class
    """
    # constant tag names
    STRONG = "STRONG"
    ITALIC = "ITALIC"
    HIGHLIGHT = "HIGHLIGHT"

    window_title = "DiAnnotator"  # window title

    padding = config.get_int("padding", 25)  # padding for text area")
    wrap_length = config.get_int(
        "wrap_length", 960)  # max length of labels before automatic newline")

    # text parameters
    text_font_family = config.get_string("text_font_family", "mono")
    text_font_size = config.get_int("text_font_size", 12)
    text_font_weight = config.get_string("text_font_weight", "normal")
    text_foreground = config.get_string("text_foreground", "#ffffff")
    text_background = config.get_string("text_background", "#171717")

    # label parameters
    label_font_family = config.get_string("label_font_family", "mono")
    label_font_size = config.get_int("label_font_size", 12)
    label_font_weight = config.get_string("label_font_weight", "normal")

    # entry parameters
    entry_font_family = config.get_string("entry_font_family", "TkDefaultFont")
    entry_font_size = config.get_int("entry_font_size", 14)
    entry_font_weight = config.get_string("entry_font_weight", "normal")

    # menu parameters
    menu_font_family = config.get_string("menu_font_family", "modern")

    # button parameters
    button_font_family = config.get_string("button_font_family", "modern")

    # special button parameters
    special_button_font_family = config.get_string(
        "special_button_font_family", "mono")
    special_button_font_size = config.get_int("special_button_font_size", 11)
    special_button_font_weight = config.get_string(
        "special_button_font_weight", "bold")
    special_button_active = config.get_string("special_button_active",
                                              "#353131")

    # prompt parameters
    prompt_font_family = config.get_string("prompt_font_family", "modern")
    prompt_font_size = config.get_int("prompt_font_size", 12)
    prompt_font_weight = config.get_string("prompt_font_weight", "bold")

    # selection parameters
    select_background = config.get_string("select_background", "#332f2f")

    # highlight parameters
    highlight_background = config.get_string("highlight_background", "#332f2f")

    special_button_style = "Special.TButton"

    def __init__(self):
        """
        Initializes the graphical user interface
        """
        # main interface object
        self.parent = Tk()
        self.parent.state = False

        # strings manager
        strings = Strings()
        self._ = strings.get

        # theme
        style = ThemedStyle(self.parent)
        style.set_theme("arc")

        # button style
        style.configure("TButton", font=self.button_font_family)

        # special button style
        style.configure(self.special_button_style,
                        font=(self.special_button_font_family,
                              self.special_button_font_size,
                              self.special_button_font_weight))

        # make buttons change foreground when hovered
        style.map("TButton",
                  foreground=[("active", self.special_button_active)])

        # root window initialization
        Frame.__init__(self, self.parent)

        w = config.get_int("minimum_window_width",
                           1280)  # minimum width for the Tk parent
        h = config.get_int("minimum_window_height",
                           800)  # minimum height for the Tk parent

        # get screen width and height
        ws = self.parent.winfo_screenwidth()  # width of the screen
        hs = self.parent.winfo_screenheight()  # height of the screen

        self.parent.geometry("%dx%d+0+0" %
                             (ws, hs))  # set the dimensions of the window
        self.parent.minsize(w, h)  # minimum size of the window

        # window title
        self.parent.title(self.window_title)

        # menu bar
        self.menu_bar = Menu(self.parent, font=self.menu_font_family)

        self.file_menu = Menu(self.menu_bar,
                              tearoff=0,
                              font=self.menu_font_family)
        self.menu_bar.add_cascade(label=self._("menu.cascade.file"),
                                  menu=self.file_menu)

        self.edit_menu = Menu(self.menu_bar,
                              tearoff=0,
                              font=self.menu_font_family)
        self.menu_bar.add_cascade(label=self._("menu.cascade.edit"),
                                  menu=self.edit_menu)

        self.view_menu = Menu(self.menu_bar,
                              tearoff=0,
                              font=self.menu_font_family)
        self.menu_bar.add_cascade(label=self._("menu.cascade.view"),
                                  menu=self.view_menu)
        self.view_menu.add_command(label=self._("menu.zoom_in"),
                                   accelerator="Ctrl++",
                                   command=self.zoom_in)
        self.view_menu.add_command(label=self._("menu.zoom_out"),
                                   accelerator="Ctrl+-",
                                   command=self.zoom_out)

        self.filter_menu = Menu(self.menu_bar,
                                tearoff=0,
                                font=self.menu_font_family)
        self.menu_bar.add_cascade(label=self._("menu.cascade.filter"),
                                  menu=self.filter_menu)

        self.taxonomy_menu = Menu(self.menu_bar,
                                  tearoff=0,
                                  font=self.menu_font_family)
        self.menu_bar.add_cascade(label=self._("menu.cascade.taxonomy"),
                                  menu=self.taxonomy_menu)

        self.parent.config(menu=self.menu_bar)

        # make the frame take the whole window
        self.pack(fill=BOTH, expand=1)

        # input frame
        self.input_frame = None

        # output frame
        self.output_frame = Frame(self)
        self.output_frame.pack(fill=BOTH, anchor=N, expand=1)
        self.output_frame.grid_propagate(False)  # ensure a consistent GUI size
        self.output_frame.grid_rowconfigure(
            0, weight=30)  # implement stretchability
        self.output_frame.grid_rowconfigure(
            1, weight=1)  # implement stretchability
        self.output_frame.grid_columnconfigure(0, weight=1)
        self.text = Text(self.output_frame,
                         borderwidth=3,
                         relief=SUNKEN,
                         cursor="arrow",
                         selectbackground=self.select_background,
                         inactiveselectbackground=self.select_background)

        # Text widget
        self.text.grid(row=0,
                       column=0,
                       sticky="nsew",
                       padx=self.padding,
                       pady=(self.padding, 0))
        self.text.config(font=(self.text_font_family, self.text_font_size),
                         undo=True,
                         wrap=WORD,
                         bg=self.text_background,
                         fg=self.text_foreground,
                         state=DISABLED)

        # create a Scrollbar and associate it with text
        self.scrollbar = Scrollbar(self.output_frame, command=self.text.yview)
        self.scrollbar.grid(row=0, rowspan=3, column=1, sticky=NSEW)
        self.text["yscrollcommand"] = self.scrollbar.set

        # status bar
        self.status = Label(self.output_frame,
                            font=(self.label_font_family, self.label_font_size,
                                  "bold"))
        self.status.grid(row=1, column=0, pady=0)

        # binds any typing to the command input field to the update_commands method
        sv = StringVar()
        sv.trace("w", lambda name, index, mode, sv=sv: self.update_commands())

        # input frame
        self.input_frame = Frame(self)
        self.input_frame.pack(fill=X, side=BOTTOM)

        # makes the command input field
        self.entry = Entry(self.input_frame,
                           font=(self.entry_font_family, self.entry_font_size),
                           textvariable=sv,
                           state=DISABLED)
        self.entry.bind(
            "<Return>", self.return_pressed
        )  # binds the Return key to the return_pressed() method
        self.entry.bind(
            "<KP_Enter>", self.return_pressed
        )  # binds the Return key to the return_pressed() method
        self.entry.bind(
            "<Tab>",
            self.tab_pressed)  # binds the Tab key to the tab_pressed() method
        self.entry.pack(fill=X, side=BOTTOM, padx=2,
                        pady=2)  # places the input field
        self.entry.focus_set()  # sets the focus on the input field

        # creates the frame containing buttons
        self.commands = Frame(self.input_frame)
        self.commands.pack(fill=X, side=BOTTOM)

        self.prompt = StringVar()
        self.prompt_label = Label(self.commands,
                                  font=(self.prompt_font_family,
                                        self.prompt_font_size,
                                        self.prompt_font_weight),
                                  textvariable=self.prompt)
        self.prompt_label.pack(side=LEFT, padx=(10, 15), pady=10)

        # creates the frame containing special buttons
        self.special_commands = Frame(self.input_frame)
        self.special_commands.pack(fill=X, side=BOTTOM)

        # default bindings
        self.parent.bind(config.get_string("toggle_fullscreen", "<F11>"),
                         lambda event: self.toggle_fullscreen())
        self.parent.bind(config.get_string("exit_prompt", "<Escape>"),
                         lambda event: self.exit_prompt())
        self.parent.bind(config.get_string("zoom_in", "<Control-KP_Add>"),
                         lambda event: self.zoom_in())
        self.parent.bind(
            config.get_string("zoom_out", "<Control-KP_Subtract>"),
            lambda event: self.zoom_out())

        # binding mouse clicks and movement
        self.text.bind("<Button-1>", self.record_click)
        self.text.bind("<Button-2>", self.record_click)
        self.clickable_text_tag = "clickable_text_tag"
        self.text.bind("<ButtonRelease-1>", self.mouse_left_click)
        self.text.bind("<ButtonRelease-3>", self.mouse_right_click)
        self.text.bind("<Motion>", self.mouse_motion)

        self.last_click_index = "1.0"
        self.last_release_index = "1.0"

        self.command_list = []  # list of potential commands

        self.action = None  # default command action
        self.default_action = None  # default command action

        self.free_input = False  # sets whether it's possible to input anything in the entry

        # basic text tags

        self.add_tag(GraphicalUserInterface.STRONG, font_weight="bold")
        self.add_tag(GraphicalUserInterface.ITALIC, font_weight="italic")
        self.add_tag(GraphicalUserInterface.HIGHLIGHT,
                     background=self.highlight_background)

        self.text.tag_raise(SEL)  # makes sure the selection is fisible

    ############################
    # MOUSE MANAGEMENT METHODS #
    ############################

    def record_click(self, event):
        """
        Records last click index
        """
        index = self.text.index("@%s,%s" % (event.x, event.y))
        self.last_click_index = index

    def record_release(self, event):
        """
        Records last click release index
        """
        index = self.text.index("@%s,%s" % (event.x, event.y))
        self.last_release_index = index

    def mouse_motion(self, event):
        """
        Returns data when the cursor is on a clickable element
        """
        start, end, text = self.examine_mouse_position(event)
        self.manage_motion(start, end, text)

    def mouse_left_click(self, event):
        """
        Returns data when the user left clicks on a clickable element
        """
        self.record_release(event)

        start, end, text = self.examine_mouse_position(event)
        self.manage_left_click(start, end, event.x_root, event.y_root, text)

    def mouse_right_click(self, event):
        """
        Returns data when the user right clicks on a clickable element
        """
        self.record_release(event)

        start, end, text = self.examine_mouse_position(event)
        self.manage_right_click(start, end, event.x_root, event.y_root, text)

    def examine_mouse_position(self, event):
        """
        Examines the mouse position and returns data if a clickable element is hovered
        """
        # get the index of the mouse click
        index = self.text.index("@%s,%s" % (event.x, event.y))

        # get the indices of all clickable text tags
        tag_indices = list(self.text.tag_ranges(self.clickable_text_tag))

        # iterate them pairwise (start and end index)
        for start, end in zip(tag_indices[0::2], tag_indices[1::2]):
            # check if the tag matches the mouse click index
            if self.text.compare(start, '<=', index) and self.text.compare(
                    index, '<', end):
                # deals with string between tag start and end
                return start, end, self.text.get(start, end)

        return None, None, None

    def manage_motion(self, start, end, text):
        """
        Mouse motion management
        """
        pass  # pass on purpose

    def manage_left_click(self, start, end, x, y, text):
        """
        Mouse left click management
        """
        pass  # pass on purpose

    def manage_right_click(self, start, end, x, y, text):
        """
        Mouse right click management
        """
        pass  # pass on purpose

    ###############################
    # KEYBOARD MANAGEMENT METHODS #
    ##############################

    def return_pressed(self, e):
        """
        Handles presses of the Return key
        """
        focus = self.parent.focus_get()

        if focus == self.entry:
            # if the input is free, the entry content is captured; else the only corresponding command is captured
            if self.free_input:
                text = self.entry.get()
                self.entry.delete(0, END)  # clears the entry field
                self.process_input(text)
            elif len(self.entry.get()) == 0:
                self.default_action()  # default action
            else:
                # list of buttons in the button list
                commands = self.commands.winfo_children()

                # if there is only one button (plus label), invokes it's function
                if len(commands) == 2:
                    self.commands.winfo_children()[1].invoke()
        else:
            for button in self.commands.winfo_children():
                if focus == button:
                    self.button_pressed(button.cget("text"))

    def tab_pressed(self, e):
        """
        Handles presses of the Tab key
        """
        self.entry.focus_set()  # sets the focus on the input field

    ############################
    # INPUT MANAGEMENT METHODS #
    ############################

    def button_pressed(self, b):
        """
        Activates command buttons
        """
        self.entry.delete(0, END)  # clears the entry field
        self.process_input(
            b
        )  # processes input corresponding to the button to the output canvas

    def process_input(self, t):
        """
        Processes user input
        """
        self.free_input = False
        self.action(t)

    ##############################
    # DISPLAY MANAGEMENT METHODS #
    ##############################

    def update_status_message(self, text):
        """
        Status message
        """
        self.status.config(text=text)

    def update_commands(self):
        """
        Updates the command button list
        """
        for element in self.commands.winfo_children():
            if isinstance(element, Button):
                element.destroy()

        input_text = self.entry.get()

        match = None

        for cmd in self.command_list:
            if cmd.lower() == input_text.lower():
                match = cmd

        # if only one match
        if match:
            self.make_button(match)
        else:
            chunks = input_text.split(" ")

            for s in self.command_list:
                # only if the input text can correspond to the command
                if len([c for c in chunks
                        if c.lower() in s.lower()]) == len(chunks):
                    self.make_button(s)

    def make_button(self, text, disabled=False):
        b = Button(self.commands,
                   text=text,
                   command=lambda n=text: self.button_pressed(n))
        b.bind("<Return>", self.return_pressed
               )  # binds the Return key to the return_pressed method
        b.pack(side=LEFT)

        if disabled:
            b.config(state=DISABLED)

    def toggle_fullscreen(self):
        """
        Toggles between windowed and fullscreen
        """
        self.parent.state = not self.parent.state  # Just toggling the boolean
        self.parent.attributes("-fullscreen", self.parent.state)

        return "break"

    def exit_prompt(self):
        """
        Show an exit prompt
        """
        if messagebox.askyesno(self._("box.title.quit"),
                               self._("box.text.quit")):
            self.parent.destroy()

    ###########################
    # TEXT MANAGEMENT METHODS #
    ###########################

    def select(self, start, end):
        """
        Selects text
        """
        self.text.tag_add(SEL, start, end)
        self.text.mark_set(INSERT, "1.0")

    def zoom_in(self):
        """
        Increases Text widget font
        """
        if self.text_font_size < 20:
            self.text_font_size += 1
            self.update_font_size()

    def zoom_out(self):
        """
        Decreases Text widget font
        """
        if self.text_font_size > 8:
            self.text_font_size -= 1
            self.update_font_size()

    def update_font_size(self):
        """
        Updates Text widget font size
        """
        self.text.config(font=(self.text_font_family, self.text_font_size))
        self.text.tag_config(GraphicalUserInterface.STRONG,
                             font=(self.text_font_family, self.text_font_size,
                                   "bold"))
        self.text.tag_config(GraphicalUserInterface.ITALIC,
                             font=(self.text_font_family, self.text_font_size,
                                   "italic"))

    def clear_screen(self):
        """
        Clears the text widget
        """
        self.text.config(state=NORMAL)  # makes the text editable
        self.text.delete("1.0", self.text.index(END))
        self.text.config(state=DISABLED)  # makes the text editable

    def clear_last_line(self):
        """
        Clears the last line
        """
        self.text.config(state=NORMAL)  # makes the text editable
        self.text.delete("end-{}c linestart".format(self.previous_line_length),
                         self.text.index(END))
        self.text.config(state=DISABLED)  # makes the text editable

        self.add_blank_lines(1)

    def highlight_last_line(self):
        """
        Highlights the last line
        """
        start = "{}.{}".format(int(self.text.index(END).split(".")[0]) - 2,
                               0)  # start position of the line to output
        end = "{}.{}".format(int(self.text.index(END).split(".")[0]) - 1, 0)
        # adds style to the text
        self.text.tag_add(GraphicalUserInterface.HIGHLIGHT, start, end)

    def add_text(self, text, style=None, offset=0):
        """
        Adds text to the text widget
        """
        line_number = int(self.text.index(END).split(
            ".")[0]) - 1  # line number relative to the rest of the text

        self.text.config(state=NORMAL)  # makes the text editable
        self.text.insert(END, text + "\n")  # inserts text

        start = "{}.{}".format(line_number, 0 +
                               offset)  # start position of the line to output
        end = "{}.{}".format(
            line_number,
            len(text) + offset)  # end position of the line that was outputted

        # adds style to the text
        if text and style:
            if isinstance(style, list):
                for s in style:
                    self.text.tag_add(s, start, end)
            else:
                self.text.tag_add(style, start, end)

        self.text.config(state=DISABLED)  # disabe the text field

        self.previous_tag_name = style
        self.previous_line_length = len(text)

    def add_to_last_line(self, text, style=None, offset=0):
        """
        Adds text to the end of the previous line
        """
        self.text.config(state=NORMAL)  # makes the text editable
        self.text.delete("end-2c lineend", self.text.index(END))
        self.text.config(state=DISABLED)  # makes the text uneditable

        self.add_text(text, style=style, offset=offset)

    def add_blank_lines(self, n):
        """
        Adds blank lines to the text widget
        """
        if n > 0:
            self.add_text("" + "\n" * (n - 1))

    def add_tag(self,
                name,
                foreground=None,
                background=None,
                justify=None,
                font_weight=None):
        """
        Creates a new tag
        """
        if foreground:
            self.text.tag_config(name, foreground=foreground)

        if background:
            self.text.tag_config(name, background=background)

        if justify:
            self.text.tag_config(name, justify=justify)

        if font_weight:
            self.text.tag_config(name,
                                 font=(self.text_font_family,
                                       self.text_font_size, font_weight))

    #########################
    # IO MANAGEMENT METHODS #
    #########################

    def input(self,
              prompt,
              commands,
              action,
              free=False,
              sort=True,
              placeholder=""):
        """
        Manages user input
        """
        self.prompt.set(self._(prompt).title() + ":" if prompt else "")
        self.free_input = free
        self.action = action

        commands = sorted(list(commands)) if sort else list(
            commands)  # sort commands alphabetically if necessary

        command_list = [str(c) for c in commands]

        if command_list != self.command_list:
            self.command_list = [str(c) for c in commands]
            self.update_commands()

        self.entry.delete(0, END)  # clears the entry field
        self.entry.insert(0, placeholder)  # inserts the placeholder
        self.entry.config(state=NORMAL)
        self.entry.focus_set()  # sets the focus on the input field

    def output(self, message, style=None, blank_before=0, blank_after=0):
        """
        Adds formatted text to the output buffer
        """
        # convert numbers in the message to words
        self.add_blank_lines(blank_before)  # blank lines before the output

        for line in message.split("\n"):
            self.add_text(line, style=style)

        self.add_blank_lines(blank_after)  # blank lines after the output
Пример #30
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/6/10 18:58
# @File    : entry控件.py
# @Software: PyCharm

import tkinter as tk
from tkinter.ttk import Entry, Label

root = tk.Tk()
root.title("entry控件")
root.geometry("300x160")

Label(root, text='Name:').grid(row=0)
Label(root, text='Pwd:').grid(row=1)

var1 = tk.StringVar()
var2 = tk.StringVar()

entry1 = Entry(root, textvariable=var1, show="$")
entry2 = Entry(root, textvariable=var2, show="$")

entry1.grid(row=0, column=1)
entry2.grid(row=1, column=1)
entry1.focus_set()

root.mainloop()
Пример #31
0
    def __init__(self, parent, title, host=None, realm=None, useOsProxy=None, urlAddr=None, urlPort=None, user=None, password=None, database=None, timeout=None, dbType=None, showUrl=False, showUser=False, showHost=True, showRealm=True, showDatabase=False):
        super(DialogUserPassword, self).__init__(parent)
        self.parent = parent
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))
        self.accepted = False
        self.transient(self.parent)
        self.title(title)
        self.urlAddrVar = StringVar()
        self.urlAddrVar.set(urlAddr if urlAddr else "")
        self.urlPortVar = StringVar()
        self.urlPortVar.set(urlPort if urlPort else "")
        self.userVar = StringVar()
        self.userVar.set(user if user else "")
        self.passwordVar = StringVar()
        self.passwordVar.set(password if password else "")
        self.databaseVar = StringVar()
        self.databaseVar.set(database if database else "")
        self.timeoutVar = StringVar()
        self.timeoutVar.set(timeout if timeout else "")
        
        frame = Frame(self)
        y = 0
        if showHost:
            hostLabel = Label(frame, text=_("Host:"), underline=0)
            hostDisplay = Label(frame, text=host, width=30)
            if host and len(host) > 30:
                ToolTip(hostDisplay, text=host, wraplength=240)
            hostLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            hostDisplay.grid(row=y, column=1, columnspan=4, sticky=EW, pady=3, padx=3)
            y += 1
        if showRealm:
            realmLabel = Label(frame, text=_("Realm:"), underline=0)
            realmDisplay = Label(frame, text=realm, width=25)
            if realm and len(realm) > 30:
                ToolTip(realmDisplay, text=realm, wraplength=240)
            realmLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            realmDisplay.grid(row=y, column=1, columnspan=4, sticky=EW, pady=3, padx=3)
            y += 1
        self.enabledWidgets = []
        if useOsProxy is not None:
            if sys.platform.startswith("win"):
                hostProxy = _('Microsoft Windows Internet Settings')
            elif sys.platform in ("darwin", "macos"):
                hostProxy = _('Mac OS X System Configuration')
            else: # linux/unix
                hostProxy = _('environment variables')
            useOsProxyCb = checkbox(frame, 0, y, text=_("Use proxy server of {0}").format(hostProxy))
            useOsProxyCb.grid(columnspan=5)
            useOsProxyCb.valueVar.set(useOsProxy)
            ToolTip(useOsProxyCb, text=_("Check to use {0} \n"
                                         "Uncheck to specify: \n"
                                         "   No proxy if URL address is left blank, \n"
                                         "   Proxy via URL address if it is not blank, \n"
                                         "       with user and password (if provided)"
                                         ).format(hostProxy), wraplength=360)
            self.useOsProxyCb = useOsProxyCb
            useOsProxyCb.valueVar.trace("w", self.setEnabledState)

            y += 1
        if showUrl:
            urlAddrLabel = Label(frame, text=_("Address:"), underline=0)
            urlAddrEntry = Entry(frame, textvariable=self.urlAddrVar, width=16)
            urlPortLabel = Label(frame, text=_("Port:"), underline=0)
            urlPortEntry = Entry(frame, textvariable=self.urlPortVar, width=5)
            urlAddrEntry.focus_set()
            urlAddrLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            urlAddrEntry.grid(row=y, column=1, columnspan=2, sticky=EW, pady=3, padx=3)
            urlPortLabel.grid(row=y, column=3, sticky=W, pady=3, padx=3)
            urlPortEntry.grid(row=y, column=4, sticky=EW, pady=3, padx=3)
            ToolTip(urlAddrEntry, text=_("Enter URL address and port number \n"
                                         "  e.g., address: 168.1.2.3 port: 8080 \n"
                                         "  or address: proxy.myCompany.com port: 8080 \n"
                                         "  or leave blank to specify no proxy server"), wraplength=360)
            self.enabledWidgets.append(urlAddrEntry)
            self.enabledWidgets.append(urlPortEntry)
            y += 1
        userLabel = Label(frame, text=_("User:"******"Password:"******"*")
        passwordLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
        passwordEntry.grid(row=y, column=1, columnspan=4, sticky=EW, pady=3, padx=3)
        self.enabledWidgets.append(passwordEntry)
        y += 1
        if showDatabase:
            urlDatabaseLabel = Label(frame, text=_("Database:"), underline=0)
            urlDatabaseEntry = Entry(frame, textvariable=self.databaseVar, width=25)
            urlDatabaseLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            urlDatabaseEntry.grid(row=y, column=1, columnspan=4, sticky=EW, pady=3, padx=3)
            ToolTip(urlAddrEntry, text=_("Enter database name (optional) or leave blank"), wraplength=360)
            self.enabledWidgets.append(urlDatabaseEntry)
            y += 1
            urlTimeoutLabel = Label(frame, text=_("Timeout:"), underline=0)
            urlTimeoutEntry = Entry(frame, textvariable=self.timeoutVar, width=25)
            urlTimeoutLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            urlTimeoutEntry.grid(row=y, column=1, columnspan=4, sticky=EW, pady=3, padx=3)
            ToolTip(urlAddrEntry, text=_("Enter timeout seconds (optional) or leave blank for default (60 secs.)"), wraplength=360)
            self.enabledWidgets.append(urlTimeoutEntry)
            y += 1
            dbTypeLabel = Label(frame, text=_("DB type:"), underline=0)
            dbTypeLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            self.cbDbType = gridCombobox(frame, 1, y, values=DBDescriptions, 
                                         selectindex=DBTypes.index(dbType) if dbType in DBTypes else None)
            self.cbDbType.grid(columnspan=4, pady=3, padx=3)
            y += 1
        okButton = Button(frame, text=_("OK"), command=self.ok)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        okButton.grid(row=y, column=2, sticky=E, pady=3)
        cancelButton.grid(row=y, column=3, columnspan=2, sticky=EW, pady=3, padx=3)
        y += 1
                
        if useOsProxy is not None:
            self.setEnabledState()

        frame.grid(row=0, column=0, sticky=(N,S,E,W))
        frame.columnconfigure(1, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
        
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)
        
        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()
        self.wait_window(self)
Пример #32
0
class GetKeysDialog(Toplevel):

    # Dialog title for invalid key sequence
    keyerror_title = 'Key Sequence Error'

    def __init__(self,
                 parent,
                 title,
                 action,
                 current_key_sequences,
                 *,
                 _htest=False,
                 _utest=False):
        """
        parent - parent of this dialog
        title - string which is the title of the popup dialog
        action - string, the name of the virtual event these keys will be
                 mapped to
        current_key_sequences - list, a list of all key sequence lists
                 currently mapped to virtual events, for overlap checking
        _htest - bool, change box location when running htest
        _utest - bool, do not wait when running unittest
        """
        Toplevel.__init__(self, parent)
        self.withdraw()  # Hide while setting geometry.
        self.configure(borderwidth=5)
        self.resizable(height=False, width=False)
        self.title(title)
        self.transient(parent)
        self.grab_set()
        self.protocol("WM_DELETE_WINDOW", self.cancel)
        self.parent = parent
        self.action = action
        self.current_key_sequences = current_key_sequences
        self.result = ''
        self.key_string = StringVar(self)
        self.key_string.set('')
        # Set self.modifiers, self.modifier_label.
        self.set_modifiers_for_platform()
        self.modifier_vars = []
        for modifier in self.modifiers:
            variable = StringVar(self)
            variable.set('')
            self.modifier_vars.append(variable)
        self.advanced = False
        self.create_widgets()
        self.update_idletasks()
        self.geometry("+%d+%d" %
                      (parent.winfo_rootx() +
                       (parent.winfo_width() / 2 - self.winfo_reqwidth() / 2),
                       parent.winfo_rooty() +
                       ((parent.winfo_height() / 2 -
                         self.winfo_reqheight() / 2) if not _htest else 150))
                      )  # Center dialog over parent (or below htest box).
        if not _utest:
            self.deiconify()  # Geometry set, unhide.
            self.wait_window()

    def showerror(self, *args, **kwargs):
        # Make testing easier.  Replace in #30751.
        messagebox.showerror(*args, **kwargs)

    def create_widgets(self):
        self.frame = frame = Frame(self, borderwidth=2, relief='sunken')
        frame.pack(side='top', expand=True, fill='both')

        frame_buttons = Frame(self)
        frame_buttons.pack(side='bottom', fill='x')

        self.button_ok = Button(frame_buttons,
                                text='OK',
                                width=8,
                                command=self.ok)
        self.button_ok.grid(row=0, column=0, padx=5, pady=5)
        self.button_cancel = Button(frame_buttons,
                                    text='Cancel',
                                    width=8,
                                    command=self.cancel)
        self.button_cancel.grid(row=0, column=1, padx=5, pady=5)

        # Basic entry key sequence.
        self.frame_keyseq_basic = Frame(frame, name='keyseq_basic')
        self.frame_keyseq_basic.grid(row=0,
                                     column=0,
                                     sticky='nsew',
                                     padx=5,
                                     pady=5)
        basic_title = Label(self.frame_keyseq_basic,
                            text=f"New keys for '{self.action}' :")
        basic_title.pack(anchor='w')

        basic_keys = Label(self.frame_keyseq_basic,
                           justify='left',
                           textvariable=self.key_string,
                           relief='groove',
                           borderwidth=2)
        basic_keys.pack(ipadx=5, ipady=5, fill='x')

        # Basic entry controls.
        self.frame_controls_basic = Frame(frame)
        self.frame_controls_basic.grid(row=1, column=0, sticky='nsew', padx=5)

        # Basic entry modifiers.
        self.modifier_checkbuttons = {}
        column = 0
        for modifier, variable in zip(self.modifiers, self.modifier_vars):
            label = self.modifier_label.get(modifier, modifier)
            check = Checkbutton(self.frame_controls_basic,
                                command=self.build_key_string,
                                text=label,
                                variable=variable,
                                onvalue=modifier,
                                offvalue='')
            check.grid(row=0, column=column, padx=2, sticky='w')
            self.modifier_checkbuttons[modifier] = check
            column += 1

        # Basic entry help text.
        help_basic = Label(self.frame_controls_basic,
                           justify='left',
                           text="Select the desired modifier keys\n" +
                           "above, and the final key from the\n" +
                           "list on the right.\n\n" +
                           "Use upper case Symbols when using\n" +
                           "the Shift modifier.  (Letters will be\n" +
                           "converted automatically.)")
        help_basic.grid(row=1, column=0, columnspan=4, padx=2, sticky='w')

        # Basic entry key list.
        self.list_keys_final = Listbox(self.frame_controls_basic,
                                       width=15,
                                       height=10,
                                       selectmode='single')
        self.list_keys_final.insert('end', *AVAILABLE_KEYS)
        self.list_keys_final.bind('<ButtonRelease-1>', self.final_key_selected)
        self.list_keys_final.grid(row=0, column=4, rowspan=4, sticky='ns')
        scroll_keys_final = Scrollbar(self.frame_controls_basic,
                                      orient='vertical',
                                      command=self.list_keys_final.yview)
        self.list_keys_final.config(yscrollcommand=scroll_keys_final.set)
        scroll_keys_final.grid(row=0, column=5, rowspan=4, sticky='ns')
        self.button_clear = Button(self.frame_controls_basic,
                                   text='Clear Keys',
                                   command=self.clear_key_seq)
        self.button_clear.grid(row=2, column=0, columnspan=4)

        # Advanced entry key sequence.
        self.frame_keyseq_advanced = Frame(frame, name='keyseq_advanced')
        self.frame_keyseq_advanced.grid(row=0,
                                        column=0,
                                        sticky='nsew',
                                        padx=5,
                                        pady=5)
        advanced_title = Label(
            self.frame_keyseq_advanced,
            justify='left',
            text=f"Enter new binding(s) for '{self.action}' :\n" +
            "(These bindings will not be checked for validity!)")
        advanced_title.pack(anchor='w')
        self.advanced_keys = Entry(self.frame_keyseq_advanced,
                                   textvariable=self.key_string)
        self.advanced_keys.pack(fill='x')

        # Advanced entry help text.
        self.frame_help_advanced = Frame(frame)
        self.frame_help_advanced.grid(row=1, column=0, sticky='nsew', padx=5)
        help_advanced = Label(
            self.frame_help_advanced,
            justify='left',
            text="Key bindings are specified using Tkinter keysyms as\n" +
            "in these samples: <Control-f>, <Shift-F2>, <F12>,\n"
            "<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n"
            "Upper case is used when the Shift modifier is present!\n\n" +
            "'Emacs style' multi-keystroke bindings are specified as\n" +
            "follows: <Control-x><Control-y>, where the first key\n" +
            "is the 'do-nothing' keybinding.\n\n" +
            "Multiple separate bindings for one action should be\n" +
            "separated by a space, eg., <Alt-v> <Meta-v>.")
        help_advanced.grid(row=0, column=0, sticky='nsew')

        # Switch between basic and advanced.
        self.button_level = Button(frame,
                                   command=self.toggle_level,
                                   text='<< Basic Key Binding Entry')
        self.button_level.grid(row=2, column=0, stick='ew', padx=5, pady=5)
        self.toggle_level()

    def set_modifiers_for_platform(self):
        """Determine list of names of key modifiers for this platform.

        The names are used to build Tk bindings -- it doesn't matter if the
        keyboard has these keys; it matters if Tk understands them.  The
        order is also important: key binding equality depends on it, so
        config-keys.def must use the same ordering.
        """
        if sys.platform == "darwin":
            self.modifiers = ['Shift', 'Control', 'Option', 'Command']
        else:
            self.modifiers = ['Control', 'Alt', 'Shift']
        self.modifier_label = {'Control': 'Ctrl'}  # Short name.

    def toggle_level(self):
        "Toggle between basic and advanced keys."
        if self.button_level.cget('text').startswith('Advanced'):
            self.clear_key_seq()
            self.button_level.config(text='<< Basic Key Binding Entry')
            self.frame_keyseq_advanced.lift()
            self.frame_help_advanced.lift()
            self.advanced_keys.focus_set()
            self.advanced = True
        else:
            self.clear_key_seq()
            self.button_level.config(text='Advanced Key Binding Entry >>')
            self.frame_keyseq_basic.lift()
            self.frame_controls_basic.lift()
            self.advanced = False

    def final_key_selected(self, event=None):
        "Handler for clicking on key in basic settings list."
        self.build_key_string()

    def build_key_string(self):
        "Create formatted string of modifiers plus the key."
        keylist = modifiers = self.get_modifiers()
        final_key = self.list_keys_final.get('anchor')
        if final_key:
            final_key = translate_key(final_key, modifiers)
            keylist.append(final_key)
        self.key_string.set(f"<{'-'.join(keylist)}>")

    def get_modifiers(self):
        "Return ordered list of modifiers that have been selected."
        mod_list = [variable.get() for variable in self.modifier_vars]
        return [mod for mod in mod_list if mod]

    def clear_key_seq(self):
        "Clear modifiers and keys selection."
        self.list_keys_final.select_clear(0, 'end')
        self.list_keys_final.yview('moveto', '0.0')
        for variable in self.modifier_vars:
            variable.set('')
        self.key_string.set('')

    def ok(self, event=None):
        keys = self.key_string.get().strip()
        if not keys:
            self.showerror(title=self.keyerror_title,
                           parent=self,
                           message="No key specified.")
            return
        if (self.advanced or self.keys_ok(keys)) and self.bind_ok(keys):
            self.result = keys
        self.grab_release()
        self.destroy()

    def cancel(self, event=None):
        self.result = ''
        self.grab_release()
        self.destroy()

    def keys_ok(self, keys):
        """Validity check on user's 'basic' keybinding selection.

        Doesn't check the string produced by the advanced dialog because
        'modifiers' isn't set.
        """
        final_key = self.list_keys_final.get('anchor')
        modifiers = self.get_modifiers()
        title = self.keyerror_title
        key_sequences = [
            key for keylist in self.current_key_sequences for key in keylist
        ]
        if not keys.endswith('>'):
            self.showerror(title, parent=self, message='Missing the final Key')
        elif (not modifiers and final_key not in FUNCTION_KEYS + MOVE_KEYS):
            self.showerror(title=title,
                           parent=self,
                           message='No modifier key(s) specified.')
        elif (modifiers == ['Shift']) \
                 and (final_key not in
                      FUNCTION_KEYS + MOVE_KEYS + ('Tab', 'Space')):
            msg = 'The shift modifier by itself may not be used with'\
                  ' this key symbol.'
            self.showerror(title=title, parent=self, message=msg)
        elif keys in key_sequences:
            msg = 'This key combination is already in use.'
            self.showerror(title=title, parent=self, message=msg)
        else:
            return True
        return False

    def bind_ok(self, keys):
        "Return True if Tcl accepts the new keys else show message."
        try:
            binding = self.bind(keys, lambda: None)
        except TclError as err:
            self.showerror(
                title=self.keyerror_title,
                parent=self,
                message=(f'The entered key sequence is not accepted.\n\n'
                         f'Error: {err}'))
            return False
        else:
            self.unbind(keys, binding)
            return True
Пример #33
0
class Query(Toplevel):
    """Base class for getting verified answer from a user.

    For this base class, accept any non-blank string.
    """

    def __init__(self, parent, title, message, *, _htest=False, _utest=False):  # Call from override.
        """Create popup, do not return until tk widget destroyed.

        Additional subclass init must be done before calling this.

        title - string, title of popup dialog
        message - string, informational message to display
        _htest - bool, change box location when running htest
        _utest - bool, leave window hidden and not modal
        """
        Toplevel.__init__(self, parent)
        self.configure(borderwidth=5)
        self.resizable(height=FALSE, width=FALSE)
        self.title(title)
        self.transient(parent)
        self.grab_set()
        self.bind("<Key-Return>", self.ok)
        self.protocol("WM_DELETE_WINDOW", self.cancel)
        self.parent = parent
        self.message = message
        self.create_widgets()
        self.update_idletasks()
        # needs to be done here so that the winfo_reqwidth is valid
        self.withdraw()  # Hide while configuring, especially geometry.
        self.geometry(
            "+%d+%d"
            % (
                parent.winfo_rootx() + (parent.winfo_width() / 2 - self.winfo_reqwidth() / 2),
                parent.winfo_rooty()
                + ((parent.winfo_height() / 2 - self.winfo_reqheight() / 2) if not _htest else 150),
            )
        )  # centre dialog over parent (or below htest box)
        if not _utest:
            self.deiconify()  # geometry set, unhide
            self.wait_window()

    def create_widgets(self):  # Call from override, if any.
        frame = Frame(self, borderwidth=2, relief="sunken")
        label = Label(frame, anchor="w", justify="left", text=self.message)
        self.entry = Entry(frame, width=30)  # Bind name for entry_ok.
        self.entry.focus_set()

        buttons = Frame(self)  # Bind buttons for invoke in unittest.
        self.button_ok = Button(buttons, text="Ok", width=8, command=self.ok)
        self.button_cancel = Button(buttons, text="Cancel", width=8, command=self.cancel)

        frame.pack(side="top", expand=TRUE, fill="both")
        label.pack(padx=5, pady=5)
        self.entry.pack(padx=5, pady=5)
        buttons.pack(side="bottom")
        self.button_ok.pack(side="left", padx=5)
        self.button_cancel.pack(side="right", padx=5)

    def entry_ok(self):  # Usually replace.
        "Check that entry not blank."
        entry = self.entry.get().strip()
        if not entry:
            showerror(title="Entry Error", message="Blank line.", parent=self)
        return entry

    def ok(self, event=None):  # Do not replace.
        """If entry is valid, bind it to 'result' and destroy tk widget.

        Otherwise leave dialog open for user to correct entry or cancel.
        """
        entry = self.entry_ok()
        if entry:
            self.result = entry
            self.destroy()
        else:
            # [Ok] (but not <Return>) moves focus.  Move it back.
            self.entry.focus_set()

    def cancel(self, event=None):  # Do not replace.
        "Set dialog result to None and destroy tk widget."
        self.result = None
        self.destroy()
Пример #34
0
class Query(Toplevel):
    """Base class for getting verified answer from a user.

    For this base class, accept any non-blank string.
    """
    def __init__(self, parent, title, message, *, text0='', used_names={},
                 _htest=False, _utest=False):
        """Create popup, do not return until tk widget destroyed.

        Additional subclass init must be done before calling this
        unless  _utest=True is passed to suppress wait_window().

        title - string, title of popup dialog
        message - string, informational message to display
        text0 - initial value for entry
        used_names - names already in use
        _htest - bool, change box location when running htest
        _utest - bool, leave window hidden and not modal
        """
        Toplevel.__init__(self, parent)
        self.withdraw()  # Hide while configuring, especially geometry.
        self.configure(borderwidth=5)
        self.resizable(height=False, width=False)
        self.title(title)
        self.transient(parent)
        self.grab_set()
        self.bind('<Key-Return>', self.ok)
        self.bind('<Key-Escape>', self.cancel)
        self.protocol("WM_DELETE_WINDOW", self.cancel)
        self.parent = parent
        self.message = message
        self.text0 = text0
        self.used_names = used_names
        self.create_widgets()
        self.update_idletasks()  # Needed here for winfo_reqwidth below.
        self.geometry(  # Center dialog over parent (or below htest box).
                "+%d+%d" % (
                    parent.winfo_rootx() +
                    (parent.winfo_width()/2 - self.winfo_reqwidth()/2),
                    parent.winfo_rooty() +
                    ((parent.winfo_height()/2 - self.winfo_reqheight()/2)
                    if not _htest else 150)
                ) )
        if not _utest:
            self.deiconify()  # Unhide now that geometry set.
            self.wait_window()

    def create_widgets(self):  # Call from override, if any.
        # Bind to self widgets needed for entry_ok or unittest.
        self.frame = frame = Frame(self, borderwidth=2, relief='sunken', )
        entrylabel = Label(frame, anchor='w', justify='left',
                           text=self.message)
        self.entryvar = StringVar(self, self.text0)
        self.entry = Entry(frame, width=30, textvariable=self.entryvar)
        self.entry.focus_set()

        buttons = Frame(self)
        self.button_ok = Button(buttons, text='Ok',
                width=8, command=self.ok)
        self.button_cancel = Button(buttons, text='Cancel',
                width=8, command=self.cancel)

        frame.pack(side='top', expand=True, fill='both')
        entrylabel.pack(padx=5, pady=5)
        self.entry.pack(padx=5, pady=5)
        buttons.pack(side='bottom')
        self.button_ok.pack(side='left', padx=5)
        self.button_cancel.pack(side='right', padx=5)

    def entry_ok(self):  # Example: usually replace.
        "Return non-blank entry or None."
        entry = self.entry.get().strip()
        if not entry:
            showerror(title='Entry Error',
                    message='Blank line.', parent=self)
            return None
        return entry

    def ok(self, event=None):  # Do not replace.
        '''If entry is valid, bind it to 'result' and destroy tk widget.

        Otherwise leave dialog open for user to correct entry or cancel.
        '''
        entry = self.entry_ok()
        if entry is not None:
            self.result = entry
            self.destroy()
        else:
            # [Ok] moves focus.  (<Return> does not.)  Move it back.
            self.entry.focus_set()

    def cancel(self, event=None):  # Do not replace.
        "Set dialog result to None and destroy tk widget."
        self.result = None
        self.destroy()
Пример #35
0
class Query(Toplevel):
    """Base class for getting verified answer from a user.

    For this base class, accept any non-blank string.
    """
    def __init__(self,
                 parent,
                 title,
                 message,
                 *,
                 text0='',
                 used_names={},
                 _htest=False,
                 _utest=False):
        """Create popup, do not return until tk widget destroyed.

        Additional subclass init must be done before calling this
        unless  _utest=True is passed to suppress wait_window().

        title - string, title of popup dialog
        message - string, informational message to display
        text0 - initial value for entry
        used_names - names already in use
        _htest - bool, change box location when running htest
        _utest - bool, leave window hidden and not modal
        """
        Toplevel.__init__(self, parent)
        self.withdraw()
        self.parent = parent
        self.title(title)
        self.message = message
        self.text0 = text0
        self.used_names = used_names
        self.transient(parent)
        self.grab_set()
        windowingsystem = self.tk.call('tk', 'windowingsystem')
        if windowingsystem == 'aqua':
            try:
                self.tk.call('::tk::unsupported::MacWindowStyle', 'style',
                             self._w, 'moveableModal', '')
            except:
                pass
            self.bind('<Command-.>', self.cancel)
        self.bind('<Key-Escape>', self.cancel)
        self.protocol('WM_DELETE_WINDOW', self.cancel)
        self.bind('<Key-Return>', self.ok)
        self.bind('<KP_Enter>', self.ok)
        self.resizable(height=False, width=False)
        self.create_widgets()
        self.update_idletasks()
        self.geometry('+%d+%d' %
                      (parent.winfo_rootx() +
                       (parent.winfo_width() / 2 - self.winfo_reqwidth() / 2),
                       parent.winfo_rooty() +
                       (parent.winfo_height() / 2 -
                        self.winfo_reqheight() / 2 if not _htest else 150)))
        if not _utest:
            self.deiconify()
            self.wait_window()

    def create_widgets(self):
        self.frame = frame = Frame(self, padding=10)
        frame.grid(column=0, row=0, sticky='news')
        frame.grid_columnconfigure(0, weight=1)
        entrylabel = Label(frame,
                           anchor='w',
                           justify='left',
                           text=self.message)
        self.entryvar = StringVar(self, self.text0)
        self.entry = Entry(frame, width=30, textvariable=self.entryvar)
        self.entry.focus_set()
        self.error_font = Font(name='TkCaptionFont',
                               exists=True,
                               root=self.parent)
        self.entry_error = Label(frame,
                                 text=' ',
                                 foreground='red',
                                 font=self.error_font)
        self.button_ok = Button(frame,
                                text='OK',
                                default='active',
                                command=self.ok)
        self.button_cancel = Button(frame, text='Cancel', command=self.cancel)
        entrylabel.grid(column=0, row=0, columnspan=3, padx=5, sticky=W)
        self.entry.grid(column=0,
                        row=1,
                        columnspan=3,
                        padx=5,
                        sticky=W + E,
                        pady=[10, 0])
        self.entry_error.grid(column=0,
                              row=2,
                              columnspan=3,
                              padx=5,
                              sticky=W + E)
        self.button_ok.grid(column=1, row=99, padx=5)
        self.button_cancel.grid(column=2, row=99, padx=5)

    def showerror(self, message, widget=None):
        (widget or self.entry_error)['text'] = 'ERROR: ' + message

    def entry_ok(self):
        """Return non-blank entry or None."""
        self.entry_error['text'] = ''
        entry = self.entry.get().strip()
        if not entry:
            self.showerror('blank line.')
            return None
        return entry

    def ok(self, event=None):
        """If entry is valid, bind it to 'result' and destroy tk widget.

        Otherwise leave dialog open for user to correct entry or cancel.
        """
        entry = self.entry_ok()
        if entry is not None:
            self.result = entry
            self.destroy()
        else:
            self.entry.focus_set()

    def cancel(self, event=None):
        """Set dialog result to None and destroy tk widget."""
        self.result = None
        self.destroy()
Пример #36
0
    def add_latex(self, img_name=None):
        def ok(event):
            latex = r'%s' % text.get()
            if latex:
                if img_name is None:
                    l = [
                        int(os.path.splitext(f)[0])
                        for f in os.listdir(PATH_LATEX)
                    ]
                    l.sort()
                    if l:
                        i = l[-1] + 1
                    else:
                        i = 0
                    img = "%i.png" % i
                    self.txt.tag_bind(img, '<Double-Button-1>',
                                      lambda e: self.add_latex(img))
                    self.latex[img] = latex

                else:
                    img = img_name
                im = os.path.join(PATH_LATEX, img)
                try:
                    math_to_image(latex,
                                  im,
                                  fontsize=CONFIG.getint("Font", "text_size") -
                                  2)
                    self.images.append(PhotoImage(file=im, master=self))
                    if self.txt.tag_ranges("sel"):
                        index = self.txt.index("sel.first")
                        self.txt.delete('sel.first', 'sel.last')
                    else:
                        index = self.txt.index("current")
                    self.txt.image_create(index,
                                          image=self.images[-1],
                                          name=im)
                    self.txt.tag_add(img, index)
                    top.destroy()

                except Exception as e:
                    showerror(_("Error"), str(e))

        top = Toplevel(self)
        top.transient(self)
        top.update_idletasks()
        top.geometry("+%i+%i" % top.winfo_pointerxy())
        top.grab_set()
        top.resizable(True, False)
        top.title("LaTex")
        text = Entry(top, justify='center')
        if img_name is not None:
            text.insert(0, self.latex[img_name])
        else:
            if self.txt.tag_ranges('sel'):
                text.insert(0, self.txt.get('sel.first', 'sel.last'))
            else:
                text.insert(0, '$$')
                text.icursor(1)

        text.pack(fill='x', expand=True)
        text.bind('<Return>', ok)
        text.focus_set()
Пример #37
0
class EmpDatTableCanvas(TableCanvas):
    """
    Override for TableCanvas
    """
    def __init__(self,
                 *args,
                 col_modifiers: dict = None,
                 on_change=None,
                 on_unsaved=None,
                 on_selected=None,
                 **kwargs):
        """
        TableCanvas constructor
        :param args: blanket passthrough
        :param col_modifiers: dictionary modifying column entry
            Example:
                {
                    0: {
                        'read_only': True
                    },
                    1: {
                        'options': ['A', 'B', 'C"]  # Options A, B, and C
                    },
                    2: {
                        'render_as': lambda X: Y    # Render X as Y
                    }
                }
        :param on_change: callback called on every change
        :param on_unsaved: callback called on every change, passes 1 parameter
                            on whether there are pending changes
        :param on_selected: callback called on when a row is selected
        :param kwargs: blanket passthrough
        """
        super().__init__(*args, **kwargs)

        self.col_modifiers = col_modifiers
        self.unsaved = set()
        self.on_change = on_change
        self.on_unsaved = on_unsaved
        self.on_selected = on_selected

    def drawText(self, row, col, celltxt, fgcolor=None, align=None):
        """Draw the text inside a cell area"""

        col_name = self.model.getColumnName(col)

        if col_name in self.col_modifiers and 'render_as' in self.col_modifiers[
                col_name]:
            celltxt = self.col_modifiers[col_name]['render_as'](celltxt)
        if len(celltxt) == 0 or celltxt == 'None':
            celltxt = ''

        self.delete('celltext' + str(col) + '_' + str(row))
        h = self.rowheight
        x1, y1, x2, y2 = self.getCellCoords(row, col)
        w = x2 - x1
        wrap = False
        pad = 5
        # If celltxt is a number then we make it a string
        if type(celltxt) is float or type(celltxt) is int:
            celltxt = str(celltxt)
        length = len(celltxt)
        if length == 0:
            return
        # if cell width is less than x, print nothing
        if w <= 10:
            return

        if fgcolor == None or fgcolor == "None":
            fgcolor = 'black'
        if align == None:
            align = 'w'
        if align == 'w':
            x1 = x1 - w / 2 + pad
        elif align == 'e':
            x1 = x1 + w / 2 - pad

        if w < 18:
            celltxt = '.'
        else:
            fontsize = self.fontsize
            colname = self.model.getColumnName(col)
            # scaling between canvas and text normalised to about font 14
            scale = 8.5 * float(fontsize) / 12
            size = length * scale
            if size > w:
                newlength = w / scale
                # print w, size, length, newlength
                celltxt = celltxt[0:int(math.floor(newlength))]

        # if celltxt is dict then we are drawing a hyperlink
        if self.isLink(celltxt) == True:
            haslink = 0
            linktext = celltxt['text']
            if len(linktext) > w / scale or w < 28:
                linktext = linktext[0:int(w / fontsize * 1.2) - 2] + '..'
            if celltxt['link'] != None and celltxt['link'] != '':
                f, s = self.thefont
                linkfont = (f, s, 'underline')
                linkcolor = 'blue'
                haslink = 1
            else:
                linkfont = self.thefont
                linkcolor = fgcolor

            rect = self.create_text(x1 + w / 2,
                                    y1 + h / 2,
                                    text=linktext,
                                    fill=linkcolor,
                                    font=linkfont,
                                    tag=('text', 'hlink', 'celltext' +
                                         str(col) + '_' + str(row)))
            if haslink == 1:
                self.tag_bind(rect, '<Double-Button-1>', self.check_hyperlink)

        # just normal text
        else:
            rect = self.create_text(x1 + w / 2,
                                    y1 + h / 2,
                                    text=celltxt,
                                    fill=fgcolor,
                                    font=self.thefont,
                                    anchor=align,
                                    tag=('text', 'celltext' + str(col) + '_' +
                                         str(row)))
        return

    def drawCellEntry(self, row, col, text=None):
        """When the user single/double clicks on a text/number cell, bring up entry window"""

        col_name = self.model.getColumnName(col)

        if self.read_only or (col_name in self.col_modifiers
                              and 'read_only' in self.col_modifiers[col_name]
                              and self.col_modifiers[col_name]['read_only']):
            return
        # absrow = self.get_AbsoluteRow(row)
        height = self.rowheight
        model = self.getModel()
        cellvalue = self.model.getCellRecord(row, col)
        if Formula.isFormula(cellvalue):
            return
        else:
            text = self.model.getValueAt(row, col)
        if text == 'None':
            text = ''
        x1, y1, x2, y2 = self.getCellCoords(row, col)
        w = x2 - x1
        # Draw an entry window
        txtvar = StringVar()
        txtvar.set(text)

        def callback(e):
            value = txtvar.get()
            if value == '=':
                # do a dialog that gets the formula into a text area
                # then they can click on the cells they want
                # when done the user presses ok and its entered into the cell
                self.cellentry.destroy()
                # its all done here..
                self.formula_Dialog(row, col)
                return

            coltype = self.model.getColumnType(col)
            if coltype == 'number':
                sta = self.checkDataEntry(e)
                if sta == 1:
                    self.unsaved.add(self.model.getRecName(row))
                    model.setValueAt(value, row, col)
            elif coltype == 'text':
                self.unsaved.add(self.model.getRecName(row))
                model.setValueAt(value, row, col)

            color = self.model.getColorAt(row, col, 'fg')
            self.drawText(row, col, value, color, align=self.align)
            if not isinstance(e, str) and e.keysym == 'Return':
                self.delete('entry')
                # self.drawRect(row, col)
                # self.gotonextCell(e)
            if self.on_change:
                self.on_change()
            if len(self.unsaved) > 0:
                self.on_unsaved(False, row, col)
            else:
                self.on_unsaved(True, row, col)

            is_required = True if col_name in self.col_modifiers and \
                                  'required' in self.col_modifiers[col_name] else False
            if col_name in self.col_modifiers and 'validator' in self.col_modifiers[
                    col_name]:
                if not is_required and value == '':
                    self.model.setColorAt(row, col, 'white')
                    self.redrawCell(row, col)
                    return

                if callable(self.col_modifiers[col_name]['validator']):
                    if not self.col_modifiers[col_name]['validator'](value):
                        self.model.setColorAt(row, col, 'coral')
                        self.redrawCell(row, col)
                else:
                    if not is_valid_against(
                            self.col_modifiers[col_name]['validator'], value):
                        self.model.setColorAt(row, col, 'coral')
                        self.redrawCell(row, col)
            return

        if col_name in self.col_modifiers and 'options' in self.col_modifiers[
                col_name]:
            options = list(self.col_modifiers[col_name]['options'])

            if cellvalue in options:
                first = cellvalue
                options.remove(first)
                options.insert(0, first)

            self.cellentry = OptionMenu(self.parentframe,
                                        txtvar,
                                        *options,
                                        command=callback)
        elif col_name in self.col_modifiers and 'date' in self.col_modifiers[
                col_name]:
            self.cellentry = DateEntry(self.parentframe,
                                       width=20,
                                       textvariable=txtvar,
                                       takefocus=1,
                                       font=self.thefont)
            self.cellentry.bind('<<DateEntrySelected>>', callback)
        else:
            self.cellentry = Entry(self.parentframe,
                                   width=20,
                                   textvariable=txtvar,
                                   takefocus=1,
                                   font=self.thefont)
            self.cellentry.selection_range(0, END)

        try:
            self.cellentry.icursor(END)
        except AttributeError:
            pass
        self.cellentry.bind('<Return>', callback)
        self.cellentry.bind('<KeyRelease>', callback)
        self.cellentry.focus_set()
        self.entrywin = self.create_window(x1 + self.inset,
                                           y1 + self.inset,
                                           width=w - self.inset * 2,
                                           height=height - self.inset * 2,
                                           window=self.cellentry,
                                           anchor='nw',
                                           tag='entry')

        return

    def handle_left_click(self, event):
        """Respond to a single press"""

        self.on_selected()
        super().handle_left_click(event)

    def popupMenu(self, event, rows=None, cols=None, outside=None):
        """Add left and right click behaviour for canvas, should not have to override
            this function, it will take its values from defined dicts in constructor"""

        defaultactions = {
            "Set Fill Color": lambda: self.setcellColor(rows, cols, key='bg'),
            "Set Text Color": lambda: self.setcellColor(rows, cols, key='fg'),
            "Copy": lambda: self.copyCell(rows, cols),
            "Paste": lambda: self.pasteCell(rows, cols),
            "Fill Down": lambda: self.fillDown(rows, cols),
            "Fill Right": lambda: self.fillAcross(cols, rows),
            "Add Row(s)": lambda: self.addRows(),
            "Delete Row(s)": lambda: self.deleteRow(),
            "View Record": lambda: self.getRecordInfo(row),
            "Clear Data": lambda: self.deleteCells(rows, cols),
            "Select All": self.select_All,
            "Auto Fit Columns": self.autoResizeColumns,
            "Filter Records": self.showFilteringBar,
            "New": self.new,
            "Load": self.load,
            "Save": self.save,
            "Import text": self.importTable,
            "Export csv": self.exportTable,
            "Plot Selected": self.plotSelected,
            "Plot Options": self.plotSetup,
            "Export Table": self.exportTable,
            "Preferences": self.showtablePrefs,
            "Formulae->Value": lambda: self.convertFormulae(rows, cols)
        }

        main = [
            "Set Fill Color", "Set Text Color", "Copy", "Paste", "Fill Down",
            "Fill Right", "Clear Data"
        ]
        general = [
            "Select All", "Auto Fit Columns", "Filter Records", "Preferences"
        ]

        def createSubMenu(parent, label, commands):
            menu = Menu(parent, tearoff=0)
            popupmenu.add_cascade(label=label, menu=menu)
            for action in commands:
                menu.add_command(label=action, command=defaultactions[action])
            return menu

        def add_commands(fieldtype):
            """Add commands to popup menu for column type and specific cell"""
            functions = self.columnactions[fieldtype]
            for f in functions.keys():
                func = getattr(self, functions[f])
                popupmenu.add_command(label=f, command=lambda: func(row, col))
            return

        popupmenu = Menu(self, tearoff=0)

        def popupFocusOut(event):
            popupmenu.unpost()

        if outside == None:
            # if outside table, just show general items
            row = self.get_row_clicked(event)
            col = self.get_col_clicked(event)
            coltype = self.model.getColumnType(col)

            def add_defaultcommands():
                """now add general actions for all cells"""
                for action in main:
                    if action == 'Fill Down' and (rows == None
                                                  or len(rows) <= 1):
                        continue
                    if action == 'Fill Right' and (cols == None
                                                   or len(cols) <= 1):
                        continue
                    else:
                        popupmenu.add_command(label=action,
                                              command=defaultactions[action])
                return

            if coltype in self.columnactions:
                add_commands(coltype)
            add_defaultcommands()

        for action in general:
            popupmenu.add_command(label=action, command=defaultactions[action])

        popupmenu.add_separator()
        # createSubMenu(popupmenu, 'File', filecommands)
        # createSubMenu(popupmenu, 'Plot', plotcommands)
        popupmenu.bind("<FocusOut>", popupFocusOut)
        popupmenu.focus_set()
        popupmenu.post(event.x_root, event.y_root)
        return popupmenu