PageRenderTime 13ms CodeModel.GetById 2ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/Tools/pynche/Switchboard.py

http://unladen-swallow.googlecode.com/
Python | 139 lines | 117 code | 3 blank | 19 comment | 5 complexity | 3cf5e760888771b90df9c7cc31b3efe7 MD5 | raw file
  1"""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.  Note that the
 11      Viewer typically does *not* update itself before calling update_views(),
 12      since this would cause it to get updated twice.
 13
 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
 42"""
 43
 44import sys
 45from types import DictType
 46import marshal
 47
 48
 49
 50class Switchboard:
 51    def __init__(self, initfile):
 52        self.__initfile = initfile
 53        self.__colordb = None
 54        self.__optiondb = {}
 55        self.__views = []
 56        self.__red = 0
 57        self.__green = 0
 58        self.__blue = 0
 59        self.__canceled = 0
 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 not isinstance(self.__optiondb, DictType):
 68                        print >> sys.stderr, \
 69                              'Problem reading options from file:', initfile
 70                        self.__optiondb = {}
 71                except (IOError, EOFError, ValueError):
 72                    pass
 73            finally:
 74                if fp:
 75                    fp.close()
 76
 77    def add_view(self, view):
 78        self.__views.append(view)
 79
 80    def update_views(self, red, green, blue):
 81        self.__red = red
 82        self.__green = green
 83        self.__blue = blue
 84        for v in self.__views:
 85            v.update_yourself(red, green, blue)
 86
 87    def update_views_current(self):
 88        self.update_views(self.__red, self.__green, self.__blue)
 89
 90    def current_rgb(self):
 91        return self.__red, self.__green, self.__blue
 92
 93    def colordb(self):
 94        return self.__colordb
 95
 96    def set_colordb(self, colordb):
 97        self.__colordb = colordb
 98        for v in self.__views:
 99            if hasattr(v, 'colordb_changed'):
100                v.colordb_changed(colordb)
101        self.update_views_current()
102
103    def optiondb(self):
104        return self.__optiondb
105
106    def save_views(self):
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:
112            if hasattr(v, 'save_options'):
113                v.save_options(self.__optiondb)
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()
117        fp = None
118        try:
119            try:
120                fp = open(self.__initfile, 'w')
121            except IOError:
122                print >> sys.stderr, 'Cannot write options to file:', \
123                      self.__initfile
124            else:
125                marshal.dump(self.__optiondb, fp)
126        finally:
127            if fp:
128                fp.close()
129
130    def withdraw_views(self):
131        for v in self.__views:
132            if hasattr(v, 'withdraw'):
133                v.withdraw()
134
135    def canceled(self, flag=1):
136        self.__canceled = flag
137
138    def canceled_p(self):
139        return self.__canceled