Updated for 2.1a3
[python/dscho.git] / Tools / pynche / Switchboard.py
blobf67a1a951d34194fd6afbf67909405ca40c94af9
1 """Switchboard class.
3 This class is used to coordinate updates among all Viewers. Every Viewer must
4 conform to the following interface:
6 - it must include a method called update_yourself() which takes three
7 arguments; the red, green, and blue values of the selected color.
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.
14 Optionally, Viewers can also implement:
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!
22 - withdraw() which takes no arguments. This is called when Pynche is
23 unmapped. All Viewers should implement this.
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.
30 External Viewers are found dynamically. Viewer modules should have names such
31 as FooViewer.py. If such a named module has a module global variable called
32 ADDTOVIEW and this variable is true, the Viewer will be added dynamically to
33 the `View' menu. ADDTOVIEW contains a string which is used as the menu item
34 to display the Viewer (one kludge: if the string contains a `%', this is used
35 to indicate that the next character will get an underline in the menu,
36 otherwise the first character is underlined).
38 FooViewer.py should contain a class called FooViewer, and its constructor
39 should take two arguments, an instance of Switchboard, and optionally a Tk
40 master window.
42 """
44 import sys
45 from types import DictType
46 import marshal
48 class Switchboard:
49 def __init__(self, initfile):
50 self.__initfile = initfile
51 self.__colordb = None
52 self.__optiondb = {}
53 self.__views = []
54 self.__red = 0
55 self.__green = 0
56 self.__blue = 0
57 self.__canceled = 0
58 # read the initialization file
59 fp = None
60 if initfile:
61 try:
62 try:
63 fp = open(initfile)
64 self.__optiondb = marshal.load(fp)
65 if type(self.__optiondb) <> DictType:
66 sys.stderr.write(
67 'Problem reading options from file: %s\n' %
68 initfile)
69 self.__optiondb = {}
70 except (IOError, EOFError):
71 pass
72 finally:
73 if fp:
74 fp.close()
76 def add_view(self, view):
77 self.__views.append(view)
79 def update_views(self, red, green, blue):
80 self.__red = red
81 self.__green = green
82 self.__blue = blue
83 for v in self.__views:
84 v.update_yourself(red, green, blue)
86 def update_views_current(self):
87 self.update_views(self.__red, self.__green, self.__blue)
89 def current_rgb(self):
90 return self.__red, self.__green, self.__blue
92 def colordb(self):
93 return self.__colordb
95 def set_colordb(self, colordb):
96 self.__colordb = colordb
97 for v in self.__views:
98 if hasattr(v, 'colordb_changed'):
99 v.colordb_changed(colordb)
100 self.update_views_current()
102 def optiondb(self):
103 return self.__optiondb
105 def save_views(self):
106 # save the current color
107 self.__optiondb['RED'] = self.__red
108 self.__optiondb['GREEN'] = self.__green
109 self.__optiondb['BLUE'] = self.__blue
110 for v in self.__views:
111 if hasattr(v, 'save_options'):
112 v.save_options(self.__optiondb)
113 # save the name of the file used for the color database. we'll try to
114 # load this first.
115 self.__optiondb['DBFILE'] = self.__colordb.filename()
116 fp = None
117 try:
118 try:
119 fp = open(self.__initfile, 'w')
120 except IOError:
121 sys.stderr.write('Cannot write options to file: %s\n' %
122 self.__initfile)
123 else:
124 marshal.dump(self.__optiondb, fp)
125 finally:
126 if fp:
127 fp.close()
129 def withdraw_views(self):
130 for v in self.__views:
131 if hasattr(v, 'withdraw'):
132 v.withdraw()
134 def canceled(self, flag=1):
135 self.__canceled = flag
137 def canceled_p(self):
138 return self.__canceled