Barry Warsaw | 4638c5b | 1998-10-02 16:20:14 +0000 | [diff] [blame] | 1 | """Switchboard class. |
| 2 | |
| 3 | This class is used to coordinate updates among all Viewers. Every Viewer must |
| 4 | conform 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 Warsaw | 2095b2f | 1999-04-27 18:53:29 +0000 | [diff] [blame] | 13 | |
| 14 | Optionally, 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 | |
| 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). |
| 37 | |
| 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. |
| 41 | |
Barry Warsaw | 4638c5b | 1998-10-02 16:20:14 +0000 | [diff] [blame] | 42 | """ |
| 43 | |
Barry Warsaw | 4ab5ae2 | 1998-10-22 18:48:01 +0000 | [diff] [blame] | 44 | import sys |
Barry Warsaw | 8a09e1c | 1998-10-20 20:45:46 +0000 | [diff] [blame] | 45 | from types import DictType |
| 46 | import marshal |
| 47 | |
Barry Warsaw | ffa926d | 2001-07-10 21:48:51 +0000 | [diff] [blame] | 48 | |
| 49 | |
Barry Warsaw | 987fb92 | 1998-09-28 15:59:21 +0000 | [diff] [blame] | 50 | class Switchboard: |
Barry Warsaw | 0604d72 | 1999-04-26 23:17:16 +0000 | [diff] [blame] | 51 | def __init__(self, initfile): |
Barry Warsaw | ca07ba0 | 1998-10-22 03:25:59 +0000 | [diff] [blame] | 52 | self.__initfile = initfile |
Barry Warsaw | 0604d72 | 1999-04-26 23:17:16 +0000 | [diff] [blame] | 53 | self.__colordb = None |
Barry Warsaw | 8a09e1c | 1998-10-20 20:45:46 +0000 | [diff] [blame] | 54 | self.__optiondb = {} |
| 55 | self.__views = [] |
Barry Warsaw | a7ba45b | 1998-10-01 16:46:43 +0000 | [diff] [blame] | 56 | self.__red = 0 |
| 57 | self.__green = 0 |
| 58 | self.__blue = 0 |
Barry Warsaw | ca07ba0 | 1998-10-22 03:25:59 +0000 | [diff] [blame] | 59 | self.__canceled = 0 |
Barry Warsaw | 8a09e1c | 1998-10-20 20:45:46 +0000 | [diff] [blame] | 60 | # 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 Warsaw | ffa926d | 2001-07-10 21:48:51 +0000 | [diff] [blame] | 68 | print >> sys.stderr, \ |
| 69 | 'Problem reading options from file:', initfile |
Barry Warsaw | 8a09e1c | 1998-10-20 20:45:46 +0000 | [diff] [blame] | 70 | self.__optiondb = {} |
Barry Warsaw | ffa926d | 2001-07-10 21:48:51 +0000 | [diff] [blame] | 71 | except (IOError, EOFError, ValueError): |
Barry Warsaw | 8a09e1c | 1998-10-20 20:45:46 +0000 | [diff] [blame] | 72 | pass |
| 73 | finally: |
| 74 | if fp: |
| 75 | fp.close() |
Barry Warsaw | 987fb92 | 1998-09-28 15:59:21 +0000 | [diff] [blame] | 76 | |
| 77 | def add_view(self, view): |
| 78 | self.__views.append(view) |
| 79 | |
Barry Warsaw | 1ac18cd | 1998-09-28 23:41:12 +0000 | [diff] [blame] | 80 | def update_views(self, red, green, blue): |
Barry Warsaw | a7ba45b | 1998-10-01 16:46:43 +0000 | [diff] [blame] | 81 | self.__red = red |
| 82 | self.__green = green |
| 83 | self.__blue = blue |
Barry Warsaw | 987fb92 | 1998-09-28 15:59:21 +0000 | [diff] [blame] | 84 | for v in self.__views: |
Barry Warsaw | 1ac18cd | 1998-09-28 23:41:12 +0000 | [diff] [blame] | 85 | v.update_yourself(red, green, blue) |
Barry Warsaw | fda3ace | 1998-09-29 20:04:19 +0000 | [diff] [blame] | 86 | |
Barry Warsaw | a7ba45b | 1998-10-01 16:46:43 +0000 | [diff] [blame] | 87 | def update_views_current(self): |
| 88 | self.update_views(self.__red, self.__green, self.__blue) |
| 89 | |
Barry Warsaw | cd09867 | 1998-10-05 21:14:12 +0000 | [diff] [blame] | 90 | def current_rgb(self): |
| 91 | return self.__red, self.__green, self.__blue |
| 92 | |
Barry Warsaw | fda3ace | 1998-09-29 20:04:19 +0000 | [diff] [blame] | 93 | def colordb(self): |
| 94 | return self.__colordb |
Barry Warsaw | 8a09e1c | 1998-10-20 20:45:46 +0000 | [diff] [blame] | 95 | |
Barry Warsaw | 0604d72 | 1999-04-26 23:17:16 +0000 | [diff] [blame] | 96 | def set_colordb(self, colordb): |
| 97 | self.__colordb = colordb |
Barry Warsaw | 2095b2f | 1999-04-27 18:53:29 +0000 | [diff] [blame] | 98 | for v in self.__views: |
| 99 | if hasattr(v, 'colordb_changed'): |
| 100 | v.colordb_changed(colordb) |
| 101 | self.update_views_current() |
Barry Warsaw | 0604d72 | 1999-04-26 23:17:16 +0000 | [diff] [blame] | 102 | |
Barry Warsaw | 8a09e1c | 1998-10-20 20:45:46 +0000 | [diff] [blame] | 103 | def optiondb(self): |
| 104 | return self.__optiondb |
| 105 | |
Barry Warsaw | ca07ba0 | 1998-10-22 03:25:59 +0000 | [diff] [blame] | 106 | def save_views(self): |
Barry Warsaw | 8a09e1c | 1998-10-20 20:45:46 +0000 | [diff] [blame] | 107 | # 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 Warsaw | ca07ba0 | 1998-10-22 03:25:59 +0000 | [diff] [blame] | 112 | if hasattr(v, 'save_options'): |
| 113 | v.save_options(self.__optiondb) |
Barry Warsaw | 0604d72 | 1999-04-26 23:17:16 +0000 | [diff] [blame] | 114 | # 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 Warsaw | 8a09e1c | 1998-10-20 20:45:46 +0000 | [diff] [blame] | 117 | fp = None |
| 118 | try: |
| 119 | try: |
Barry Warsaw | ca07ba0 | 1998-10-22 03:25:59 +0000 | [diff] [blame] | 120 | fp = open(self.__initfile, 'w') |
Barry Warsaw | 8a09e1c | 1998-10-20 20:45:46 +0000 | [diff] [blame] | 121 | except IOError: |
Barry Warsaw | ffa926d | 2001-07-10 21:48:51 +0000 | [diff] [blame] | 122 | print >> sys.stderr, 'Cannot write options to file:', \ |
| 123 | self.__initfile |
Barry Warsaw | 8a09e1c | 1998-10-20 20:45:46 +0000 | [diff] [blame] | 124 | else: |
| 125 | marshal.dump(self.__optiondb, fp) |
| 126 | finally: |
| 127 | if fp: |
| 128 | fp.close() |
Barry Warsaw | ca07ba0 | 1998-10-22 03:25:59 +0000 | [diff] [blame] | 129 | |
| 130 | def withdraw_views(self): |
| 131 | for v in self.__views: |
| 132 | if hasattr(v, 'withdraw'): |
| 133 | v.withdraw() |
| 134 | |
Barry Warsaw | 4ab5ae2 | 1998-10-22 18:48:01 +0000 | [diff] [blame] | 135 | def canceled(self, flag=1): |
| 136 | self.__canceled = flag |
Barry Warsaw | ca07ba0 | 1998-10-22 03:25:59 +0000 | [diff] [blame] | 137 | |
| 138 | def canceled_p(self): |
| 139 | return self.__canceled |