Package mcbase :: Package widgets :: Module mcscreen
[hide private]
[frames] | no frames]

Source Code for Module mcbase.widgets.mcscreen

  1  # -*- coding: utf-8 -*- 
  2   
  3  ############################################################################ 
  4  # mcscreen.py 
  5  # 
  6  # MOCOP Screen Widget, screens are main unit of forms used in MOCOP 
  7  # 
  8  # (C) 2008 Likya Software Ltd. 
  9  ############################################################################ 
 10   
 11  from twisted.internet import defer, reactor 
 12   
 13  from PyQt4.Qt import * 
 14   
 15  from mc import MC 
 16  from util import Util 
17 18 -def _client():
19 return MC.BASE_GUI_CLIENT.client()
20
21 -def _parent():
22 return MC.BASE_GUI_CLIENT
23
24 -class MCScreen(object):
25 ''' 26 Base screen class, includes common methods used by all screens. 27 '''
28 - def __init__(self):
29 ''' 30 Initializes the mcwindow widget 31 ''' 32 self._screenID = Util.uniq() 33 self._modified = False 34 self._mode = None
35
36 - def setScreenIcon(self, iconPath):
37 ''' 38 Sets the icon of the tab widget that includes this screen. 39 ''' 40 try: 41 currentTabPage = self.parent().parent() 42 tabWidget = currentTabPage.parent().parent() 43 screenIndex = tabWidget.indexOf(currentTabPage) 44 tabWidget.setTabIcon(screenIndex, QIcon(iconPath)) 45 except AttributeError: 46 pass
47
48 - def setMode(self, mode):
49 ''' 50 Sets the screen mode 51 ''' 52 self._mode = mode
53
54 - def mode(self):
55 ''' 56 Returns the screen mode 57 ''' 58 return self._mode
59
60 - def screenID(self):
61 ''' 62 Returns the unique id of this screen. 63 ''' 64 return self._screenID
65
66 - def findScreen(self, rootObj, screenID):
67 ''' 68 Find and return reference for a screen represented by screen ID 69 screenID. Search will be made starting from rootObj. 70 71 @param rootObj: Root of search 72 @type rootObj: QWidget 73 @param screenID: Unique id of screen 74 @type screenID: str 75 @return: Screen having screen id of screenID, None if not found 76 ''' 77 for obj in rootObj.findChildren(MCScreen): 78 if obj.screenID() == screenID: 79 return obj 80 81 return None
82
83 - def getScreenClass(self, screenPath):
84 ''' 85 Gets the class for a given screen defined by screenPath. 86 87 @param screenPath: Path defining the screen 88 @type screenPath: str 89 @return: A class object for the screen 90 ''' 91 return _parent().getScreenClass(screenPath)
92
93 - def setScreenDisabled(self):
94 ''' 95 Disables screen visual updates. 96 ''' 97 self.setUpdatesEnabled(False) 98 self.setDisabled(True)
99
100 - def setScreenEnabled(self):
101 ''' 102 Enables screen visual updates. 103 ''' 104 self.setEnabled(True) 105 self.setUpdatesEnabled(True)
106 107 @defer.inlineCallbacks
108 - def setScreenBusy(self, remoteCallActive=True):
109 ''' 110 Sets the screen as busy, screen is disabled after this call 111 112 @param changeIcon: If True, the default, sets a busy icon in the 113 related tab for this screen. 114 @type changeIcon: bool 115 ''' 116 if remoteCallActive: 117 MC.MAIN_WINDOW.incRemoteCallCount() 118 self.setScreenIcon(':/icons/busy.png') 119 # This yield gives chance to qt main loop to update the tab widget 120 # without clearing up the widget area. 121 yield Util.deferredSleep(0.01) 122 123 self.setScreenDisabled()
124 125 @defer.inlineCallbacks
126 - def setScreenAvailable(self):
127 ''' 128 Sets the screen as available, screen is enabled after this call 129 ''' 130 if self._modified: 131 self.setScreenIcon(':/icons/modified.png') 132 else: 133 self.setScreenIcon(':/icons/avail.png') 134 # This yield gives chance to qt main loop to update the tab widget 135 # without clearing up the widget area. 136 yield Util.deferredSleep(0.01) 137 138 self.setScreenEnabled() 139 140 MC.MAIN_WINDOW.decRemoteCallCount()
141 142 @defer.inlineCallbacks
143 - def execute(self, taskPath, *prm, **kw):
144 ''' 145 Executes the given remote code on the server. Returns the result of the call. 146 147 @type taskPath: C{string} 148 @param taskPath: Remote code location in distribution hierarchy, 149 i.e. "mcbase.controllers.perform.SampleClass:run" 150 @param args: Remote call parameters 151 @param kw: Remote call keyword parameters 152 @return: Result of the remote execution 153 ''' 154 yield self.setScreenBusy() 155 # Just make sure that we always enable our screen again, regardless 156 # of the remote call status 157 try: 158 result = yield _client().execute(taskPath, *prm, **kw) 159 yield self.setScreenAvailable() 160 except Exception, e: 161 print '*** ERROR in execute:', e 162 yield self.setScreenAvailable() 163 # Re-raise the original exception after restoring screen updates 164 raise e 165 166 defer.returnValue(result)
167 168 @defer.inlineCallbacks
169 - def getRemoteCode(self, codePath):
170 ''' 171 Gets mobile code from the remote server according to the given codePath 172 173 @type codePath: C{string} 174 @param codePath: String representing the code path to be transferred 175 ''' 176 yield self.setScreenBusy() 177 # Just make sure that we always enable our screen again, regardless 178 # of the remote call status 179 try: 180 yield _client().getRemoteCode(codePath) 181 yield self.setScreenAvailable() 182 except: 183 yield self.setScreenAvailable() 184 # Re-raise the original exception after restoring screen updates 185 raise
186 187 @defer.inlineCallbacks
188 - def sendMsg(self, taskPath, *prm, **kw):
189 ''' 190 Sends the given message to other clients under this user's domain. 191 Executes the given remote code on the server. Returns the result of the call. 192 193 @type taskPath: C{string} 194 @param taskPath: Message identifier, should be similar to 'a.b.c' 195 @param args: Message parameters 196 @param kw: Message keyword parameters 197 ''' 198 yield _client().sendMsg(taskPath, *prm, **kw)
199
200 - def autoPrepareFields(self, *classes):
201 ''' 202 Automatically prepares the screen fields according to given class(es). 203 Class <-> Field matching is done by looking at field's object names. 204 205 @param classes: Arbitrary number of classes whose metadata will be 206 used to prepare the screen fields. 207 ''' 208 for classObj in classes: 209 # For each class, search for widgets starting with the class name 210 candidateWidgets = self.findChildren(QWidget, QRegExp('^%s_.*' % classObj.__name__, Qt.CaseInsensitive)) 211 212 for widget in candidateWidgets: 213 widget.applyModelConstraints(classObj)
214
215 - def autoFillFields(self, instance):
216 ''' 217 Automatically fills the screen fields according to given instance. 218 Instance <-> Field matching is done by looking at field's object names. 219 220 @param instance: Instance whose metadata will be used to fill the 221 related fields on the screen. 222 ''' 223 # Search for widgets starting with the class name 224 candidateWidgets = self.findChildren(QWidget, QRegExp('^%s_.*' % instance.__class__.__name__, Qt.CaseInsensitive)) 225 226 for widget in candidateWidgets: 227 widget.set(getattr(instance, '_'.join(str(widget.objectName()).split('_')[1:])))
228
229 - def createModelObject(self, klass):
230 ''' 231 Automatically creates an object of class C{class} and assigns attributes 232 using on screen information. Widget object names are used to discover 233 class name and attributes. 234 235 @param klass: Class whose metadata will be used to create a model 236 object. 237 @returns: Newly created object 238 ''' 239 newObject = klass() 240 # Search for widgets starting with the class name 241 candidateWidgets = self.findChildren(QWidget, QRegExp('^%s_.*' % klass.__name__, Qt.CaseInsensitive)) 242 243 for widget in candidateWidgets: 244 setattr(newObject, '_'.join(str(widget.objectName()).split('_')[1:]), widget.get()) 245 246 return newObject
247
248 - def updateModelObject(self, obj):
249 ''' 250 Automatically updates an object C{obj} and assigns attributes using on 251 screen information. Widget object names are used to discover class name 252 and attributes. 253 254 @param obj: Object which will be updated using on screen information 255 @returns: Updated object 256 ''' 257 # Search for widgets starting with the class name 258 candidateWidgets = self.findChildren(QWidget, QRegExp('^%s_.*' % obj.__class__.__name__, Qt.CaseInsensitive)) 259 260 for widget in candidateWidgets: 261 setattr(obj, '_'.join(str(widget.objectName()).split('_')[1:]), widget.get()) 262 263 return obj
264
265 - def openInCurrentTab(self, *args, **kw):
266 return MC.MAIN_WINDOW.openInCurrentTab(*args, **kw)
267
268 - def openNewTab(self, *args, **kw):
269 return MC.MAIN_WINDOW.openNewTab(*args, **kw)
270 271 @defer.inlineCallbacks
272 - def closeScreen(self, result=None):
273 ''' 274 Instructs the main window to close this screen. Any result is passed 275 to main window. 276 ''' 277 yield self.setScreenBusy(remoteCallActive=False) 278 reactor.callLater(0.01, MC.MAIN_WINDOW.closeScreen, self.screenID()) 279 280 self.emit(SIGNAL('screenClosed(PyQt_PyObject)'), result)
281
282 - def errorDialog(self, caption=tr('Error'), shortMsg='', longMsg=''):
283 pass
284