blob: ee83d4766334a027ec3e8059107318e16b37d629 [file] [log] [blame]
Barry Warsaw4638c5b1998-10-02 16:20:14 +00001"""Switchboard class.
2
3This class is used to coordinate updates among all Viewers. Every Viewer must
4conform to the following interface:
5
6 - it must include a method called update_yourself() which takes three
7 arguments; the red, green, and blue values of the selected color.
8
9 - When a Viewer selects a color and wishes to update all other Views, it
Barry Warsaw531e3932002-10-21 14:20:37 +000010 should call update_views() on the Switchboard object. Note that the
11 Viewer typically does *not* update itself before calling update_views(),
Barry Warsaw4638c5b1998-10-02 16:20:14 +000012 since this would cause it to get updated twice.
Barry Warsaw2095b2f1999-04-27 18:53:29 +000013
14Optionally, Viewers can also implement:
15
16 - save_options() which takes an optiondb (a dictionary). Store into this
17 dictionary any values the Viewer wants to save in the persistent
18 ~/.pynche file. This dictionary is saved using marshal. The namespace
19 for the keys is ad-hoc; make sure you don't clobber some other Viewer's
20 keys!
21
22 - withdraw() which takes no arguments. This is called when Pynche is
23 unmapped. All Viewers should implement this.
24
25 - colordb_changed() which takes a single argument, an instance of
Barry Warsaw531e3932002-10-21 14:20:37 +000026 ColorDB. This is called whenever the color name database is changed and
Barry Warsaw2095b2f1999-04-27 18:53:29 +000027 gives a chance for the Viewers to do something on those events. See
28 ListViewer for details.
29
Barry Warsaw531e3932002-10-21 14:20:37 +000030External Viewers are found dynamically. Viewer modules should have names such
Barry Warsaw2095b2f1999-04-27 18:53:29 +000031as FooViewer.py. If such a named module has a module global variable called
32ADDTOVIEW and this variable is true, the Viewer will be added dynamically to
33the `View' menu. ADDTOVIEW contains a string which is used as the menu item
34to display the Viewer (one kludge: if the string contains a `%', this is used
35to indicate that the next character will get an underline in the menu,
36otherwise the first character is underlined).
37
38FooViewer.py should contain a class called FooViewer, and its constructor
39should take two arguments, an instance of Switchboard, and optionally a Tk
40master window.
41
Barry Warsaw4638c5b1998-10-02 16:20:14 +000042"""
43
Barry Warsaw4ab5ae21998-10-22 18:48:01 +000044import sys
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000045from types import DictType
46import marshal
47
Barry Warsawffa926d2001-07-10 21:48:51 +000048
49
Barry Warsaw987fb921998-09-28 15:59:21 +000050class Switchboard:
Barry Warsaw0604d721999-04-26 23:17:16 +000051 def __init__(self, initfile):
Barry Warsawca07ba01998-10-22 03:25:59 +000052 self.__initfile = initfile
Barry Warsaw0604d721999-04-26 23:17:16 +000053 self.__colordb = None
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000054 self.__optiondb = {}
55 self.__views = []
Barry Warsawa7ba45b1998-10-01 16:46:43 +000056 self.__red = 0
57 self.__green = 0
58 self.__blue = 0
Barry Warsawca07ba01998-10-22 03:25:59 +000059 self.__canceled = 0
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000060 # read the initialization file
61 fp = None
62 if initfile:
63 try:
64 try:
65 fp = open(initfile)
66 self.__optiondb = marshal.load(fp)
Barry Warsaw531e3932002-10-21 14:20:37 +000067 if not isinstance(self.__optiondb, DictType):
Barry Warsawffa926d2001-07-10 21:48:51 +000068 print >> sys.stderr, \
69 'Problem reading options from file:', initfile
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000070 self.__optiondb = {}
Barry Warsawffa926d2001-07-10 21:48:51 +000071 except (IOError, EOFError, ValueError):
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000072 pass
73 finally:
74 if fp:
75 fp.close()
Barry Warsaw987fb921998-09-28 15:59:21 +000076
77 def add_view(self, view):
78 self.__views.append(view)
79
Barry Warsaw1ac18cd1998-09-28 23:41:12 +000080 def update_views(self, red, green, blue):
Barry Warsawa7ba45b1998-10-01 16:46:43 +000081 self.__red = red
82 self.__green = green
83 self.__blue = blue
Barry Warsaw987fb921998-09-28 15:59:21 +000084 for v in self.__views:
Barry Warsaw1ac18cd1998-09-28 23:41:12 +000085 v.update_yourself(red, green, blue)
Barry Warsawfda3ace1998-09-29 20:04:19 +000086
Barry Warsawa7ba45b1998-10-01 16:46:43 +000087 def update_views_current(self):
88 self.update_views(self.__red, self.__green, self.__blue)
89
Barry Warsawcd098671998-10-05 21:14:12 +000090 def current_rgb(self):
91 return self.__red, self.__green, self.__blue
92
Barry Warsawfda3ace1998-09-29 20:04:19 +000093 def colordb(self):
94 return self.__colordb
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000095
Barry Warsaw0604d721999-04-26 23:17:16 +000096 def set_colordb(self, colordb):
97 self.__colordb = colordb
Barry Warsaw2095b2f1999-04-27 18:53:29 +000098 for v in self.__views:
99 if hasattr(v, 'colordb_changed'):
100 v.colordb_changed(colordb)
101 self.update_views_current()
Barry Warsaw0604d721999-04-26 23:17:16 +0000102
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000103 def optiondb(self):
104 return self.__optiondb
105
Barry Warsawca07ba01998-10-22 03:25:59 +0000106 def save_views(self):
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000107 # save the current color
108 self.__optiondb['RED'] = self.__red
109 self.__optiondb['GREEN'] = self.__green
110 self.__optiondb['BLUE'] = self.__blue
111 for v in self.__views:
Barry Warsawca07ba01998-10-22 03:25:59 +0000112 if hasattr(v, 'save_options'):
113 v.save_options(self.__optiondb)
Barry Warsaw0604d721999-04-26 23:17:16 +0000114 # save the name of the file used for the color database. we'll try to
115 # load this first.
116 self.__optiondb['DBFILE'] = self.__colordb.filename()
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000117 fp = None
118 try:
119 try:
Barry Warsawca07ba01998-10-22 03:25:59 +0000120 fp = open(self.__initfile, 'w')
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000121 except IOError:
Barry Warsawffa926d2001-07-10 21:48:51 +0000122 print >> sys.stderr, 'Cannot write options to file:', \
123 self.__initfile
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000124 else:
125 marshal.dump(self.__optiondb, fp)
126 finally:
127 if fp:
128 fp.close()
Barry Warsawca07ba01998-10-22 03:25:59 +0000129
130 def withdraw_views(self):
131 for v in self.__views:
132 if hasattr(v, 'withdraw'):
133 v.withdraw()
134
Barry Warsaw4ab5ae21998-10-22 18:48:01 +0000135 def canceled(self, flag=1):
136 self.__canceled = flag
Barry Warsawca07ba01998-10-22 03:25:59 +0000137
138 def canceled_p(self):
139 return self.__canceled