Try to fix transient refleaks in test_distutils.
[python.git] / Tools / pynche / Main.py
blob1fa3f175c8a374856deeb2b10379300cd1e8b0d9
1 """Pynche -- The PYthon Natural Color and Hue Editor.
3 Contact: %(AUTHNAME)s
4 Email: %(AUTHEMAIL)s
5 Version: %(__version__)s
7 Pynche is based largely on a similar color editor I wrote years ago for the
8 SunView window system. That editor was called ICE: the Interactive Color
9 Editor. I'd always wanted to port the editor to X but didn't feel like
10 hacking X and C code to do it. Fast forward many years, to where Python +
11 Tkinter provides such a nice programming environment, with enough power, that
12 I finally buckled down and implemented it. I changed the name because these
13 days, too many other systems have the acronym `ICE'.
15 This program currently requires Python 2.2 with Tkinter.
17 Usage: %(PROGRAM)s [-d file] [-i file] [-X] [-v] [-h] [initialcolor]
19 Where:
20 --database file
21 -d file
22 Alternate location of a color database file
24 --initfile file
25 -i file
26 Alternate location of the initialization file. This file contains a
27 persistent database of the current Pynche options and color. This
28 means that Pynche restores its option settings and current color when
29 it restarts, using this file (unless the -X option is used). The
30 default is ~/.pynche
32 --ignore
34 Ignore the initialization file when starting up. Pynche will still
35 write the current option settings to this file when it quits.
37 --version
39 print the version number and exit
41 --help
43 print this message
45 initialcolor
46 initial color, as a color name or #RRGGBB format
47 """
49 __version__ = '1.4.1'
51 import sys
52 import os
53 import getopt
54 import ColorDB
56 from PyncheWidget import PyncheWidget
57 from Switchboard import Switchboard
58 from StripViewer import StripViewer
59 from ChipViewer import ChipViewer
60 from TypeinViewer import TypeinViewer
64 PROGRAM = sys.argv[0]
65 AUTHNAME = 'Barry Warsaw'
66 AUTHEMAIL = 'barry@python.org'
68 # Default locations of rgb.txt or other textual color database
69 RGB_TXT = [
70 # Solaris OpenWindows
71 '/usr/openwin/lib/rgb.txt',
72 # Linux
73 '/usr/lib/X11/rgb.txt',
74 # The X11R6.4 rgb.txt file
75 os.path.join(sys.path[0], 'X/rgb.txt'),
76 # add more here
81 # Do this because PyncheWidget.py wants to get at the interpolated docstring
82 # too, for its Help menu.
83 def docstring():
84 return __doc__ % globals()
87 def usage(code, msg=''):
88 print docstring()
89 if msg:
90 print msg
91 sys.exit(code)
95 def initial_color(s, colordb):
96 # function called on every color
97 def scan_color(s, colordb=colordb):
98 try:
99 r, g, b = colordb.find_byname(s)
100 except ColorDB.BadColor:
101 try:
102 r, g, b = ColorDB.rrggbb_to_triplet(s)
103 except ColorDB.BadColor:
104 return None, None, None
105 return r, g, b
107 # First try the passed in color
108 r, g, b = scan_color(s)
109 if r is None:
110 # try the same color with '#' prepended, since some shells require
111 # this to be escaped, which is a pain
112 r, g, b = scan_color('#' + s)
113 if r is None:
114 print 'Bad initial color, using gray50:', s
115 r, g, b = scan_color('gray50')
116 if r is None:
117 usage(1, 'Cannot find an initial color to use')
118 # does not return
119 return r, g, b
123 def build(master=None, initialcolor=None, initfile=None, ignore=None,
124 dbfile=None):
125 # create all output widgets
126 s = Switchboard(not ignore and initfile)
127 # defer to the command line chosen color database, falling back to the one
128 # in the .pynche file.
129 if dbfile is None:
130 dbfile = s.optiondb().get('DBFILE')
131 # find a parseable color database
132 colordb = None
133 files = RGB_TXT[:]
134 if dbfile is None:
135 dbfile = files.pop()
136 while colordb is None:
137 try:
138 colordb = ColorDB.get_colordb(dbfile)
139 except (KeyError, IOError):
140 pass
141 if colordb is None:
142 if not files:
143 break
144 dbfile = files.pop(0)
145 if not colordb:
146 usage(1, 'No color database file found, see the -d option.')
147 s.set_colordb(colordb)
149 # create the application window decorations
150 app = PyncheWidget(__version__, s, master=master)
151 w = app.window()
153 # these built-in viewers live inside the main Pynche window
154 s.add_view(StripViewer(s, w))
155 s.add_view(ChipViewer(s, w))
156 s.add_view(TypeinViewer(s, w))
158 # get the initial color as components and set the color on all views. if
159 # there was no initial color given on the command line, use the one that's
160 # stored in the option database
161 if initialcolor is None:
162 optiondb = s.optiondb()
163 red = optiondb.get('RED')
164 green = optiondb.get('GREEN')
165 blue = optiondb.get('BLUE')
166 # but if there wasn't any stored in the database, use grey50
167 if red is None or blue is None or green is None:
168 red, green, blue = initial_color('grey50', colordb)
169 else:
170 red, green, blue = initial_color(initialcolor, colordb)
171 s.update_views(red, green, blue)
172 return app, s
175 def run(app, s):
176 try:
177 app.start()
178 except KeyboardInterrupt:
179 pass
183 def main():
184 try:
185 opts, args = getopt.getopt(
186 sys.argv[1:],
187 'hd:i:Xv',
188 ['database=', 'initfile=', 'ignore', 'help', 'version'])
189 except getopt.error, msg:
190 usage(1, msg)
192 if len(args) == 0:
193 initialcolor = None
194 elif len(args) == 1:
195 initialcolor = args[0]
196 else:
197 usage(1)
199 ignore = False
200 dbfile = None
201 initfile = os.path.expanduser('~/.pynche')
202 for opt, arg in opts:
203 if opt in ('-h', '--help'):
204 usage(0)
205 elif opt in ('-v', '--version'):
206 print """\
207 Pynche -- The PYthon Natural Color and Hue Editor.
208 Contact: %(AUTHNAME)s
209 Email: %(AUTHEMAIL)s
210 Version: %(__version__)s""" % globals()
211 sys.exit(0)
212 elif opt in ('-d', '--database'):
213 dbfile = arg
214 elif opt in ('-X', '--ignore'):
215 ignore = True
216 elif opt in ('-i', '--initfile'):
217 initfile = arg
219 app, sb = build(initialcolor=initialcolor,
220 initfile=initfile,
221 ignore=ignore,
222 dbfile=dbfile)
223 run(app, sb)
224 sb.save_views()
228 if __name__ == '__main__':
229 main()