diff -r b076b62731b7 Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py Mon Sep 07 19:59:38 2015 +0300 +++ b/Lib/idlelib/EditorWindow.py Tue Sep 08 09:39:20 2015 -0700 @@ -531,7 +531,7 @@ return 'normal' def about_dialog(self, event=None): - aboutDialog.AboutDialog(self.top,'About IDLE') + aboutDialog.show(self.top) def config_dialog(self, event=None): configDialog.ConfigDialog(self.top,'Settings') diff -r b076b62731b7 Lib/idlelib/aboutDialog.py --- a/Lib/idlelib/aboutDialog.py Mon Sep 07 19:59:38 2015 +0300 +++ b/Lib/idlelib/aboutDialog.py Tue Sep 08 09:39:20 2015 -0700 @@ -5,140 +5,141 @@ import os from sys import version from tkinter import * -from idlelib import textView + + +dlg = None + +def show(parent): + "Main routine; show dialog window, creating or raising as necessary." + global dlg + if dlg is None: + dlg = AboutDialog(parent, destroy_callback=_destroyed) + dlg.lift() + dlg.focus_set() + +def _destroyed(): + global dlg + dlg = None + class AboutDialog(Toplevel): - """Modal about dialog for idle - - """ - def __init__(self, parent, title, _htest=False): + """About dialog for IDLE """ + def __init__(self, parent, title='About IDLE', _htest=False, + destroy_callback=None): """ _htest - bool, change box location when running htest """ Toplevel.__init__(self, parent) + self.destroy_callback = destroy_callback self.configure(borderwidth=5) # place dialog below parent if running htest self.geometry("+%d+%d" % ( parent.winfo_rootx()+30, parent.winfo_rooty()+(30 if not _htest else 100))) - self.bg = "#707070" - self.fg = "#ffffff" + self.bg = "#bbbbbb" + self.fg = "#000000" + self.link_cursor = 'hand2' # TODO use ui.clickable_cursor self.CreateWidgets() self.resizable(height=FALSE, width=FALSE) self.title(title) - self.transient(parent) - self.grab_set() - self.protocol("WM_DELETE_WINDOW", self.Ok) + self.protocol("WM_DELETE_WINDOW", self.close) self.parent = parent - self.buttonOk.focus_set() - self.bind('',self.Ok) #dismiss dialog - self.bind('',self.Ok) #dismiss dialog - self.wait_window() + self.bind('', self.close) # dismiss dialog def CreateWidgets(self): + self['borderwidth'] = 0 release = version[:version.index(' ')] - frameMain = Frame(self, borderwidth=2, relief=SUNKEN) - frameButtons = Frame(self) - frameButtons.pack(side=BOTTOM, fill=X) - frameMain.pack(side=TOP, expand=TRUE, fill=BOTH) - self.buttonOk = Button(frameButtons, text='Close', - command=self.Ok) - self.buttonOk.pack(padx=5, pady=5) - #self.picture = Image('photo', data=self.pictureData) - frameBg = Frame(frameMain, bg=self.bg) - frameBg.pack(expand=TRUE, fill=BOTH) + logofn = os.path.join(os.path.abspath(os.path.dirname(__file__)), + "Icons", "idle_48.gif") + self.picture = PhotoImage(master=self._root(), file=logofn) + self.frameBg = frameBg = Frame(self, bg=self.bg, borderwidth=0) + frameBg.grid(sticky='nsew') labelTitle = Label(frameBg, text='IDLE', fg=self.fg, bg=self.bg, font=('courier', 24, 'bold')) - labelTitle.grid(row=0, column=0, sticky=W, padx=10, pady=10) - #labelPicture = Label(frameBg, text='[picture]') - #image=self.picture, bg=self.bg) - #labelPicture.grid(row=1, column=1, sticky=W, rowspan=2, - # padx=0, pady=3) - byline = "Python's Integrated DeveLopment Environment" + 5*'\n' + labelTitle.grid(row=0, column=1, sticky=W, padx=10, pady=[10,0]) + labelPicture = Label(frameBg, image=self.picture, bg=self.bg) + labelPicture.grid(row=0, column=0, sticky=NE, rowspan=2, + padx=10, pady=10) + byline = "Python's Integrated DeveLopment Environment" labelDesc = Label(frameBg, text=byline, justify=LEFT, fg=self.fg, bg=self.bg) - labelDesc.grid(row=2, column=0, sticky=W, columnspan=3, padx=10, pady=5) + labelDesc.grid(row=1, column=1, sticky=W, columnspan=3, padx=10, + pady=[0,20]) labelEmail = Label(frameBg, text='email: idle-dev@python.org', justify=LEFT, fg=self.fg, bg=self.bg) - labelEmail.grid(row=6, column=0, columnspan=2, + labelEmail.grid(row=6, column=1, columnspan=2, sticky=W, padx=10, pady=0) labelWWW = Label(frameBg, text='https://docs.python.org/' + version[:3] + '/library/idle.html', justify=LEFT, fg=self.fg, bg=self.bg) - labelWWW.grid(row=7, column=0, columnspan=2, sticky=W, padx=10, pady=0) - Frame(frameBg, borderwidth=1, relief=SUNKEN, - height=2, bg=self.bg).grid(row=8, column=0, sticky=EW, - columnspan=3, padx=5, pady=5) - labelPythonVer = Label(frameBg, text='Python version: ' + - release, fg=self.fg, bg=self.bg) - labelPythonVer.grid(row=9, column=0, sticky=W, padx=10, pady=0) + labelWWW.grid(row=7, column=1, columnspan=2, sticky=W, padx=10, pady=0) tkVer = self.tk.call('info', 'patchlevel') - labelTkVer = Label(frameBg, text='Tk version: '+ - tkVer, fg=self.fg, bg=self.bg) - labelTkVer.grid(row=9, column=1, sticky=W, padx=2, pady=0) - py_button_f = Frame(frameBg, bg=self.bg) - py_button_f.grid(row=10, column=0, columnspan=2, sticky=NSEW) - buttonLicense = Button(py_button_f, text='License', width=8, - highlightbackground=self.bg, - command=self.ShowLicense) - buttonLicense.pack(side=LEFT, padx=10, pady=10) - buttonCopyright = Button(py_button_f, text='Copyright', width=8, - highlightbackground=self.bg, - command=self.ShowCopyright) - buttonCopyright.pack(side=LEFT, padx=10, pady=10) - buttonCredits = Button(py_button_f, text='Credits', width=8, - highlightbackground=self.bg, - command=self.ShowPythonCredits) - buttonCredits.pack(side=LEFT, padx=10, pady=10) - Frame(frameBg, borderwidth=1, relief=SUNKEN, - height=2, bg=self.bg).grid(row=11, column=0, sticky=EW, - columnspan=3, padx=5, pady=5) - idle_v = Label(frameBg, text='IDLE version: ' + release, - fg=self.fg, bg=self.bg) - idle_v.grid(row=12, column=0, sticky=W, padx=10, pady=0) - idle_button_f = Frame(frameBg, bg=self.bg) - idle_button_f.grid(row=13, column=0, columnspan=3, sticky=NSEW) - idle_about_b = Button(idle_button_f, text='README', width=8, - highlightbackground=self.bg, - command=self.ShowIDLEAbout) - idle_about_b.pack(side=LEFT, padx=10, pady=10) - idle_news_b = Button(idle_button_f, text='NEWS', width=8, - highlightbackground=self.bg, - command=self.ShowIDLENEWS) - idle_news_b.pack(side=LEFT, padx=10, pady=10) - idle_credits_b = Button(idle_button_f, text='Credits', width=8, - highlightbackground=self.bg, - command=self.ShowIDLECredits) - idle_credits_b.pack(side=LEFT, padx=10, pady=10) + labelVersion = Label(frameBg, text='Python ' + + release + ' (with Tk '+tkVer+')', + fg=self.fg, bg=self.bg) + labelVersion.grid(row=4, column=1, sticky=W, padx=10, pady=[0,5]) + self.morelink = Label(frameBg, text='More...', fg='blue', bg=self.bg, + cursor=self.link_cursor) + self.morelink.grid(column=0, columnspan=3, pady=10, padx=10, sticky=E) + self.morelink.bind('<1>', self.showMore) - def ShowLicense(self): - self.display_printer_text('About - License', license) + def showMore(self, ev=None): + self.morelink.grid_forget() + fmore = Frame(self.frameBg, borderwidth=2, relief='ridge', bg='white') + fmore.grid_columnconfigure(0, weight=1) + self.t = Text(fmore, height=15, width=80, borderwidth=0, + highlightthickness=0, state='disabled', bg='white') + s = Scrollbar(fmore, command=self.t.yview) + self.t['yscrollcommand'] = s.set + self.load_moreinfo() + self.which = StringVar(self) + self.which.set(self.info[0][0]) + self.which.trace_variable('w', self.changeInfo) + fmore.grid(column=0, row=20, sticky='nwes', padx=5, pady=[15,5], + columnspan=4) + l = [] + for k, t in self.info: + l.append(k) + wh = OptionMenu(fmore, self.which, *l) + wh.grid(column=0, row=0, pady=[2,10]) + self.t.grid(column=0, row=1) + s.grid(column=1, row=0, sticky='ns', rowspan=2) + self.changeInfo() - def ShowCopyright(self): - self.display_printer_text('About - Copyright', copyright) + def changeInfo(self, *params): + for key, txt in self.info: + if key == self.which.get(): + self.t['state'] = 'normal' + self.t.delete('1.0', 'end') + self.t.insert('1.0', txt) + self.t['state'] = 'disabled' - def ShowPythonCredits(self): - self.display_printer_text('About - Python Credits', credits) + def load_moreinfo(self): + self.info = [] + self.load_from_file('IDLE Readme', 'README.txt') + self.load_from_file('IDLE News', 'NEWS.txt') + self.load_from_file('IDLE Credits', 'CREDITS.txt', 'iso-8859-1') + self.load_from_printer('Python License', license) + self.load_from_printer('Python Copyright', copyright) + self.load_from_printer('Python Credits', credits) - def ShowIDLECredits(self): - self.display_file_text('About - Credits', 'CREDITS.txt', 'iso-8859-1') + def load_from_file(self, key, filename, encoding=None): + fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), filename) + try: + with open(fn, 'r', encoding=encoding) as file: + contents = file.read() + except IOError: + pass + else: + self.info.append((key, contents)) - def ShowIDLEAbout(self): - self.display_file_text('About - Readme', 'README.txt') + def load_from_printer(self, key, printercmd): + printercmd._Printer__setup() + self.info.append((key, '\n'.join(printercmd._Printer__lines))) - def ShowIDLENEWS(self): - self.display_file_text('About - NEWS', 'NEWS.txt') - - def display_printer_text(self, title, printer): - printer._Printer__setup() - text = '\n'.join(printer._Printer__lines) - textView.view_text(self, title, text) - - def display_file_text(self, title, filename, encoding=None): - fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), filename) - textView.view_file(self, title, fn, encoding) - - def Ok(self, event=None): + def close(self, event=None): + if self.destroy_callback: + self.destroy_callback() self.destroy() if __name__ == '__main__': diff -r b076b62731b7 Lib/idlelib/macosxSupport.py --- a/Lib/idlelib/macosxSupport.py Mon Sep 07 19:59:38 2015 +0300 +++ b/Lib/idlelib/macosxSupport.py Tue Sep 08 09:39:20 2015 -0700 @@ -160,7 +160,7 @@ def about_dialog(event=None): from idlelib import aboutDialog - aboutDialog.AboutDialog(root, 'About IDLE') + aboutDialog.show(root) def config_dialog(event=None): from idlelib import configDialog