Attachment 'presenters.py'

Download

   1 #----------------------------------------------------------------------------
   2 # Name:         presenters.py
   3 # Purpose:      Hold the application logic
   4 #
   5 # Author:       Peter Damoc (peter at sigmacore.net)
   6 #               adapted from Martin Fowler's MVP example
   7 # Created:      January 2006
   8 # Version:      0.2 
   9 # Licence:      wxWindows license
  10 
  11 import models
  12 
  13 class AlbumPresenter(object):
  14     '''
  15     This is the object that takes care of the logic of your application.
  16     It also creates a "higher level language" in which you express what happens 
  17     inside your application.
  18     '''
  19     def __init__(self, albums, view, interactor):
  20         self.albums = albums
  21         self.view = view
  22         interactor.Install(self, view)
  23         self.isListening = True
  24         self.order = 1
  25         self.albums.sort(lambda a, b: cmp(a.title, b.title))
  26         self.initView()
  27         view.start()
  28         
  29     def initView(self):
  30         '''
  31         Upon first start, load the albums, set the selection on the first album and update the view.
  32         '''
  33         self.view.setAlbums(self.albums)
  34         self.view.setSelectedAlbum(0)
  35         self.loadViewFromModel()
  36     
  37     def loadViewFromModel(self):
  38         '''
  39         1. guard against recursive call caused by events generated uppon loading of the data
  40         2. update the view data with the information from the model
  41         '''
  42         if self.isListening:
  43             self.isListening = False
  44             self.refreshAlbumList()
  45             self.view.setTitle(self.selectedAlbum.title)
  46             self.updateWindowTitle()
  47             self.view.setArtist(self.selectedAlbum.artist)
  48             self.view.setClassical(self.selectedAlbum.isClassical)
  49             if self.selectedAlbum.isClassical:
  50                 self.view.setComposer(self.selectedAlbum.composer)
  51             else:
  52                 self.view.setComposer("")
  53             
  54             if self.order is -1:
  55                 self.view.setOrderLabel("A->Z")
  56             else:
  57                 self.view.setOrderLabel("Z->A")
  58             self.view.setComposerEnabled(self.selectedAlbum.isClassical)
  59             self.enableApplyAndCancel(False)
  60             self.isListening = True
  61             
  62     def refreshAlbumList(self):
  63         '''
  64         1. save the selection
  65         2. sort the list
  66         3. update the list
  67         4. restore the selection
  68         '''
  69         currentAlbum = self.view.getSelectedAlbum()
  70         self.selectedAlbum = self.albums[currentAlbum]
  71         self.albums.sort(lambda a, b:self.order*cmp(a.title, b.title))
  72         self.view.setAlbums(self.albums)
  73         self.view.setSelectedAlbum(self.albums.index(self.selectedAlbum))
  74         
  75     def updateWindowTitle(self):
  76         self.view.setWindowTitle("Album: " + self.view.getTitle())
  77         
  78     def enableApplyAndCancel(self, enabled):
  79         self.view.setApplyEnabled(enabled)
  80         self.view.setCancelEnabled(enabled)
  81         
  82     def toggleOrder(self):
  83         self.order = -1*self.order
  84         self.loadViewFromModel()
  85         
  86     def addNewAlbum(self):
  87         newAlbum = models.Album("Unknown Artist", "New Album Title")
  88         self.albums.append(newAlbum)
  89         self.view.setAlbums(self.albums)
  90         self.view.setSelectedAlbum(self.albums.index(newAlbum))
  91         self.loadViewFromModel()
  92         
  93     def updateModel(self):
  94         '''
  95         Saves the data from the view in the model
  96         Disable the Apply/Cancel buttons and resync the view
  97         '''
  98         self.selectedAlbum.title = self.view.getTitle()
  99         self.selectedAlbum.artist = self.view.getArtist()
 100         self.selectedAlbum.isClassical = self.view.isClassical()
 101         if self.view.isClassical:
 102             self.selectedAlbum.composer = self.view.getComposer()
 103         else:
 104             self.selectedAlbum.composer = None
 105         self.enableApplyAndCancel(False)
 106         self.loadViewFromModel()
 107         
 108     def dataFieldUpdated(self):
 109         '''
 110         Upon a change in the view, enables the Apply/Cancel buttons and the composer field
 111         Since the Album title might have been changed we also update the title of the frame
 112         Optimisation: If the data is updated by the loadViewFromModel ignore the call
 113         '''
 114         if self.isListening:
 115             self.enableApplyAndCancel(True)
 116             self.view.setComposerEnabled(self.view.isClassical())
 117             self.updateWindowTitle()

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2009-10-04 09:16:02, 0.7 KB) [[attachment:albums.pyw]]
  • [get | view] (2009-10-04 09:16:02, 1.5 KB) [[attachment:interactors.py]]
  • [get | view] (2009-10-04 09:16:02, 2.3 KB) [[attachment:mock_objects.py]]
  • [get | view] (2009-10-04 09:16:02, 1.1 KB) [[attachment:models.py]]
  • [get | view] (2009-10-04 09:16:02, 12.4 KB) [[attachment:mvp.png]]
  • [get | view] (2009-10-04 09:16:02, 5.5 KB) [[attachment:mvp.zip]]
  • [get | view] (2009-10-04 09:16:02, 12.9 KB) [[attachment:mvp2.png]]
  • [get | view] (2009-10-04 09:16:02, 5.9 KB) [[attachment:mvp2.zip]]
  • [get | view] (2009-10-04 09:16:02, 3.8 KB) [[attachment:package.zip]]
  • [get | view] (2009-10-04 09:16:02, 4.4 KB) [[attachment:presenters.py]]
  • [get | view] (2009-10-04 09:16:02, 2.2 KB) [[attachment:test_presenters.py]]
  • [get | view] (2009-10-04 09:16:02, 4.3 KB) [[attachment:views.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.