Merged release21-maint changes.
[python/dscho.git] / Tools / pynche / Main.py
blob8cea31cbc17950307bd7097cda9f363c0c3647b0
1 """Pynche -- The PYthon Natural Color and Hue Editor.
3 Contact: Barry Warsaw
4 Email: bwarsaw@python.org
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 1.5 with Tkinter. It has only been
16 tested on Solaris 2.6. Feedback is greatly appreciated. Send email to
17 bwarsaw@python.org
19 Usage: %(PROGRAM)s [-d file] [-i file] [-X] [-v] [-h] [initialcolor]
21 Where:
22 --database file
23 -d file
24 Alternate location of a color database file
26 --initfile file
27 -i file
28 Alternate location of the initialization file. This file contains a
29 persistent database of the current Pynche options and color. This
30 means that Pynche restores its option settings and current color when
31 it restarts, using this file (unless the -X option is used). The
32 default is ~/.pynche
34 --ignore
36 Ignore the initialization file when starting up. Pynche will still
37 write the current option settings to this file when it quits.
39 --version
41 print the version number
43 --help
45 print this message
47 initialcolor
48 initial color, as a color name or #RRGGBB format
49 """
51 __version__ = '1.2'
53 import sys
54 import os
55 import getopt
56 import ColorDB
58 from PyncheWidget import PyncheWidget
59 from Switchboard import Switchboard
60 from StripViewer import StripViewer
61 from ChipViewer import ChipViewer
62 from TypeinViewer import TypeinViewer
66 PROGRAM = sys.argv[0]
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 # create all output widgets
125 s = Switchboard(not ignore and initfile)
127 # load the color database
128 colordb = None
129 try:
130 dbfile = s.optiondb()['DBFILE']
131 colordb = ColorDB.get_colordb(dbfile)
132 except (KeyError, IOError):
133 # scoot through the files listed above to try to find a usable color
134 # database file
135 for f in RGB_TXT:
136 try:
137 colordb = ColorDB.get_colordb(f)
138 if colordb:
139 break
140 except IOError:
141 pass
142 if not colordb:
143 usage(1, 'No color database file found, see the -d option.')
144 s.set_colordb(colordb)
146 # create the application window decorations
147 app = PyncheWidget(__version__, s, master=master)
148 w = app.window()
150 # these built-in viewers live inside the main Pynche window
151 s.add_view(StripViewer(s, w))
152 s.add_view(ChipViewer(s, w))
153 s.add_view(TypeinViewer(s, w))
155 # get the initial color as components and set the color on all views. if
156 # there was no initial color given on the command line, use the one that's
157 # stored in the option database
158 if initialcolor is None:
159 optiondb = s.optiondb()
160 red = optiondb.get('RED')
161 green = optiondb.get('GREEN')
162 blue = optiondb.get('BLUE')
163 # but if there wasn't any stored in the database, use grey50
164 if red is None or blue is None or green is None:
165 red, green, blue = initial_color('grey50', colordb)
166 else:
167 red, green, blue = initial_color(initialcolor, colordb)
168 s.update_views(red, green, blue)
169 return app, s
172 def run(app, s):
173 try:
174 app.start()
175 except KeyboardInterrupt:
176 pass
180 def main():
181 try:
182 opts, args = getopt.getopt(
183 sys.argv[1:],
184 'hd:i:Xv',
185 ['database=', 'initfile=', 'ignore', 'help', 'version'])
186 except getopt.error, msg:
187 usage(1, msg)
189 if len(args) == 0:
190 initialcolor = None
191 elif len(args) == 1:
192 initialcolor = args[0]
193 else:
194 usage(1)
196 ignore = 0
197 initfile = os.path.expanduser('~/.pynche')
198 for opt, arg in opts:
199 if opt in ('-h', '--help'):
200 usage(0)
201 elif opt in ('-v', '--version'):
202 print '''\
203 Pynche -- The PYthon Natural Color and Hue Editor.
204 Contact: Barry Warsaw
205 Email: bwarsaw@python.org
206 Version: %s''' % __version__
207 sys.exit(0)
208 elif opt in ('-d', '--database'):
209 RGB_TXT.insert(0, arg)
210 elif opt in ('-X', '--ignore'):
211 ignore = 1
212 elif opt in ('-i', '--initfile'):
213 initfile = arg
215 app, sb = build(initialcolor=initialcolor,
216 initfile=initfile,
217 ignore=ignore)
218 run(app, sb)
219 sb.save_views()
223 if __name__ == '__main__':
224 main()