summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/aboutDialog.py
blob: 8960b0054e1a3807dbc01171c525d78bcf4290f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
"""About Dialog for IDLE

"""

from Tkinter import *
import string, os
import textView
import idlever

class AboutDialog(Toplevel):
    """Modal about dialog for idle

    """
    def __init__(self,parent,title):
        Toplevel.__init__(self, parent)
        self.configure(borderwidth=5)
        self.geometry("+%d+%d" % (parent.winfo_rootx()+30,
                                  parent.winfo_rooty()+30))
        self.bg = "#707070"
        self.fg = "#ffffff"
        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.parent = parent
        self.buttonOk.focus_set()
        self.bind('<Return>',self.Ok) #dismiss dialog
        self.bind('<Escape>',self.Ok) #dismiss dialog
        self.wait_window()

    def CreateWidgets(self):
        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)
        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'
        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)
        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,
                        sticky=W, padx=10, pady=0)
        labelWWW = Label(frameBg, text='www:  http://www.python.org/idle/',
                         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:  ' + \
                               sys.version.split()[0], fg=self.fg, bg=self.bg)
        labelPythonVer.grid(row=9, column=0, sticky=W, padx=10, pady=0)
        # handle weird tk version num in windoze python >= 1.6 (?!?)
        tkVer = `TkVersion`.split('.')
        tkVer[len(tkVer)-1] = str('%.3g' % (float('.'+tkVer[len(tkVer)-1])))[2:]
        if tkVer[len(tkVer)-1] == '':
            tkVer[len(tkVer)-1] = '0'
        tkVer = string.join(tkVer,'.')
        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:   ' + idlever.IDLE_VERSION,
                       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)

    def ShowLicense(self):
        self.display_printer_text(license, 'About - License')

    def ShowCopyright(self):
        self.display_printer_text(copyright, 'About - Copyright')

    def ShowPythonCredits(self):
        self.display_printer_text(credits, 'About - Python Credits')

    def ShowIDLECredits(self):
        self.ViewFile('About - Credits','CREDITS.txt', 'iso-8859-1')

    def ShowIDLEAbout(self):
        self.ViewFile('About - Readme', 'README.txt')

    def ShowIDLENEWS(self):
        self.ViewFile('About - NEWS', 'NEWS.txt')

    def display_printer_text(self, printer, title):
        printer._Printer__setup()
        data = '\n'.join(printer._Printer__lines)
        textView.TextViewer(self, title, None, data)

    def ViewFile(self, viewTitle, viewFile, encoding=None):
        fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), viewFile)
        if encoding:
            import codecs
            try:
                textFile = codecs.open(fn, 'r')
            except IOError:
                tkMessageBox.showerror(title='File Load Error',
                                       message='Unable to load file '+
                                       `fileName`+' .')
                return
            else:
                data = textFile.read()
        else:
            data = None
        textView.TextViewer(self, viewTitle, fn, data=data)

    def Ok(self, event=None):
        self.destroy()

if __name__ == '__main__':
    # test the dialog
    root = Tk()
    def run():
        import aboutDialog
        aboutDialog.AboutDialog(root, 'About')
    Button(root, text='Dialog', command=run).pack()
    root.mainloop()
ss="hl kwa">None][i] for i in _state_subsets[s]] handler = self.__create_handler(lists, type, _state_codes[s]) seq = '<'+_state_names[s]+self.typename+'>' self.handlerids.append((seq, self.widget.bind(self.widgetinst, seq, handler))) def bind(self, triplet, func): if triplet[2] not in self.bindedfuncs: self.bindedfuncs[triplet[2]] = [[] for s in _states] for s in _states: lists = [ self.bindedfuncs[detail][i] for detail in (triplet[2], None) for i in _state_subsets[s] ] handler = self.__create_handler(lists, self.type, _state_codes[s]) seq = "<%s%s-%s>"% (_state_names[s], self.typename, triplet[2]) self.handlerids.append((seq, self.widget.bind(self.widgetinst, seq, handler))) doit = lambda: self.bindedfuncs[triplet[2]][triplet[0]].append(func) if not self.ishandlerrunning: doit() else: self.doafterhandler.append(doit) def unbind(self, triplet, func): doit = lambda: self.bindedfuncs[triplet[2]][triplet[0]].remove(func) if not self.ishandlerrunning: doit() else: self.doafterhandler.append(doit) def __del__(self): for seq, id in self.handlerids: self.widget.unbind(self.widgetinst, seq, id) # define the list of event types to be handled by MultiEvent. the order is # compatible with the definition of event type constants. _types = ( ("KeyPress", "Key"), ("KeyRelease",), ("ButtonPress", "Button"), ("ButtonRelease",), ("Activate",), ("Circulate",), ("Colormap",), ("Configure",), ("Deactivate",), ("Destroy",), ("Enter",), ("Expose",), ("FocusIn",), ("FocusOut",), ("Gravity",), ("Leave",), ("Map",), ("Motion",), ("MouseWheel",), ("Property",), ("Reparent",), ("Unmap",), ("Visibility",), ) # which binder should be used for every event type? _binder_classes = (_ComplexBinder,) * 4 + (_SimpleBinder,) * (len(_types)-4) # A dictionary to map a type name into its number _type_names = dict([(name, number) for number in range(len(_types)) for name in _types[number]]) _keysym_re = re.compile(r"^\w+$") _button_re = re.compile(r"^[1-5]$") def _parse_sequence(sequence): """Get a string which should describe an event sequence. If it is successfully parsed as one, return a tuple containing the state (as an int), the event type (as an index of _types), and the detail - None if none, or a string if there is one. If the parsing is unsuccessful, return None. """ if not sequence or sequence[0] != '<' or sequence[-1] != '>': return None words = sequence[1:-1].split('-') modifiers = 0 while words and words[0] in _modifier_names: modifiers |= 1 << _modifier_names[words[0]] del words[0] if words and words[0] in _type_names: type = _type_names[words[0]] del words[0] else: return None if _binder_classes[type] is _SimpleBinder: if modifiers or words: return None else: detail = None else: # _ComplexBinder if type in [_type_names[s] for s in ("KeyPress", "KeyRelease")]: type_re = _keysym_re else: type_re = _button_re if not words: detail = None elif len(words) == 1 and type_re.match(words[0]): detail = words[0] else: return None return modifiers, type, detail def _triplet_to_sequence(triplet): if triplet[2]: return '<'+_state_names[triplet[0]]+_types[triplet[1]][0]+'-'+ \ triplet[2]+'>' else: return '<'+_state_names[triplet[0]]+_types[triplet[1]][0]+'>' _multicall_dict = {} def MultiCallCreator(widget): """Return a MultiCall class which inherits its methods from the given widget class (for example, Tkinter.Text). This is used instead of a templating mechanism. """ if widget in _multicall_dict: return _multicall_dict[widget] class MultiCall (widget): assert issubclass(widget, tkinter.Misc) def __init__(self, *args, **kwargs): widget.__init__(self, *args, **kwargs) # a dictionary which maps a virtual event to a tuple with: # 0. the function binded # 1. a list of triplets - the sequences it is binded to self.__eventinfo = {} self.__binders = [_binder_classes[i](i, widget, self) for i in range(len(_types))] def bind(self, sequence=None, func=None, add=None): #print("bind(%s, %s, %s)" % (sequence, func, add), # file=sys.__stderr__) if type(sequence) is str and len(sequence) > 2 and \ sequence[:2] == "<<" and sequence[-2:] == ">>": if sequence in self.__eventinfo: ei = self.__eventinfo[sequence] if ei[0] is not None: for triplet in ei[1]: self.__binders[triplet[1]].unbind(triplet, ei[0]) ei[0] = func if ei[0] is not None: for triplet in ei[1]: self.__binders[triplet[1]].bind(triplet, func) else: self.__eventinfo[sequence] = [func, []] return widget.bind(self, sequence, func, add) def unbind(self, sequence, funcid=None): if type(sequence) is str and len(sequence) > 2 and \ sequence[:2] == "<<" and sequence[-2:] == ">>" and \ sequence in self.__eventinfo: func, triplets = self.__eventinfo[sequence] if func is not None: for triplet in triplets: self.__binders[triplet[1]].unbind(triplet, func) self.__eventinfo[sequence][0] = None return widget.unbind(self, sequence, funcid) def event_add(self, virtual, *sequences): #print("event_add(%s, %s)" % (repr(virtual), repr(sequences)), # file=sys.__stderr__) if virtual not in self.__eventinfo: self.__eventinfo[virtual] = [None, []] func, triplets = self.__eventinfo[virtual] for seq in sequences: triplet = _parse_sequence(seq) if triplet is None: #print("Tkinter event_add(%s)" % seq, file=sys.__stderr__) widget.event_add(self, virtual, seq) else: if func is not None: self.__binders[triplet[1]].bind(triplet, func) triplets.append(triplet) def event_delete(self, virtual, *sequences): if virtual not in self.__eventinfo: return func, triplets = self.__eventinfo[virtual] for seq in sequences: triplet = _parse_sequence(seq) if triplet is None: #print("Tkinter event_delete: %s" % seq, file=sys.__stderr__) widget.event_delete(self, virtual, seq) else: if func is not None: self.__binders[triplet[1]].unbind(triplet, func) triplets.remove(triplet) def event_info(self, virtual=None): if virtual is None or virtual not in self.__eventinfo: return widget.event_info(self, virtual) else: return tuple(map(_triplet_to_sequence, self.__eventinfo[virtual][1])) + \ widget.event_info(self, virtual) def __del__(self): for virtual in self.__eventinfo: func, triplets = self.__eventinfo[virtual] if func: for triplet in triplets: self.__binders[triplet[1]].unbind(triplet, func) _multicall_dict[widget] = MultiCall return MultiCall if __name__ == "__main__": # Test root = tkinter.Tk() text = MultiCallCreator(tkinter.Text)(root) text.pack() def bindseq(seq, n=[0]): def handler(event): print(seq) text.bind("<<handler%d>>"%n[0], handler) text.event_add("<<handler%d>>"%n[0], seq) n[0] += 1 bindseq("<Key>") bindseq("<Control-Key>") bindseq("<Alt-Key-a>") bindseq("<Control-Key-a>") bindseq("<Alt-Control-Key-a>") bindseq("<Key-b>") bindseq("<Control-Button-1>") bindseq("<Alt-Button-1>") bindseq("<FocusOut>") bindseq("<Enter>") bindseq("<Leave>") root.mainloop()