blob: 013bb0138913916832f5a7085304f12230d9781c [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 +000045import marshal
46
Barry Warsawffa926d2001-07-10 21:48:51 +000047
48
Barry Warsaw987fb921998-09-28 15:59:21 +000049class Switchboard:
Barry Warsaw0604d721999-04-26 23:17:16 +000050 def __init__(self, initfile):
Barry Warsawca07ba01998-10-22 03:25:59 +000051 self.__initfile = initfile
Barry Warsaw0604d721999-04-26 23:17:16 +000052 self.__colordb = None
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000053 self.__optiondb = {}
54 self.__views = []
Barry Warsawa7ba45b1998-10-01 16:46:43 +000055 self.__red = 0
56 self.__green = 0
57 self.__blue = 0
Barry Warsawca07ba01998-10-22 03:25:59 +000058 self.__canceled = 0
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000059 # read the initialization file
60 fp = None
61 if initfile:
62 try:
63 try:
Georg Brandlbf76ce12010-08-02 22:08:58 +000064 fp = open(initfile, 'rb')
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000065 self.__optiondb = marshal.load(fp)
Georg Brandlbf76ce12010-08-02 22:08:58 +000066 if not isinstance(self.__optiondb, dict):
67 print('Problem reading options from file:', initfile,
68 file=sys.stderr)
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000069 self.__optiondb = {}
Barry Warsawffa926d2001-07-10 21:48:51 +000070 except (IOError, EOFError, ValueError):
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000071 pass
72 finally:
73 if fp:
74 fp.close()
Barry Warsaw987fb921998-09-28 15:59:21 +000075
76 def add_view(self, view):
77 self.__views.append(view)
78
Barry Warsaw1ac18cd1998-09-28 23:41:12 +000079 def update_views(self, red, green, blue):
Barry Warsawa7ba45b1998-10-01 16:46:43 +000080 self.__red = red
81 self.__green = green
82 self.__blue = blue
Barry Warsaw987fb921998-09-28 15:59:21 +000083 for v in self.__views:
Barry Warsaw1ac18cd1998-09-28 23:41:12 +000084 v.update_yourself(red, green, blue)
Barry Warsawfda3ace1998-09-29 20:04:19 +000085
Barry Warsawa7ba45b1998-10-01 16:46:43 +000086 def update_views_current(self):
87 self.update_views(self.__red, self.__green, self.__blue)
88
Barry Warsawcd098671998-10-05 21:14:12 +000089 def current_rgb(self):
90 return self.__red, self.__green, self.__blue
91
Barry Warsawfda3ace1998-09-29 20:04:19 +000092 def colordb(self):
93 return self.__colordb
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000094
Barry Warsaw0604d721999-04-26 23:17:16 +000095 def set_colordb(self, colordb):
96 self.__colordb = colordb
Barry Warsaw2095b2f1999-04-27 18:53:29 +000097 for v in self.__views:
98 if hasattr(v, 'colordb_changed'):
99 v.colordb_changed(colordb)
100 self.update_views_current()
Barry Warsaw0604d721999-04-26 23:17:16 +0000101
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000102 def optiondb(self):
103 return self.__optiondb
104
Barry Warsawca07ba01998-10-22 03:25:59 +0000105 def save_views(self):
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000106 # 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:
Barry Warsawca07ba01998-10-22 03:25:59 +0000111 if hasattr(v, 'save_options'):
112 v.save_options(self.__optiondb)
Barry Warsaw0604d721999-04-26 23:17:16 +0000113 # 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()
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000116 fp = None
117 try:
118 try:
Georg Brandlbf76ce12010-08-02 22:08:58 +0000119 fp = open(self.__initfile, 'wb')
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000120 except IOError:
Collin Winter6afaeb72007-08-03 17:06:41 +0000121 print('Cannot write options to file:', \
122 self.__initfile, file=sys.stderr)
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000123 else:
124 marshal.dump(self.__optiondb, fp)
125 finally:
126 if fp:
127 fp.close()
Barry Warsawca07ba01998-10-22 03:25:59 +0000128
129 def withdraw_views(self):
130 for v in self.__views:
131 if hasattr(v, 'withdraw'):
132 v.withdraw()
133
Barry Warsaw4ab5ae21998-10-22 18:48:01 +0000134 def canceled(self, flag=1):
135 self.__canceled = flag
Barry Warsawca07ba01998-10-22 03:25:59 +0000136
137 def canceled_p(self):
138 return self.__canceled