/Tools/pynche/Main.py

http://unladen-swallow.googlecode.com/ · Python · 229 lines · 185 code · 22 blank · 22 comment · 35 complexity · cbdf48883c6dd1fbc816785be1d7dbfe MD5 · raw file

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