blob: 0ad7c63900ea1da907966973b73944dcdfae90fd [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
10 should call update_views() on the Switchboard object. Not that the
11 Viewer typically does *not* update itself before calling update_views(),
12 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
26 ColorDB. This is called whenever the color name database is changed and
27 gives a chance for the Viewers to do something on those events. See
28 ListViewer for details.
29
30External Viewers are found dynamically. Viewer modules should have names such
31as 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)
67 if type(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