00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 from Koo.Common import Common
00030 from Koo import Rpc
00031
00032 from Koo.View.AbstractView import *
00033 from Koo.Fields.AbstractFieldWidget import *
00034 from PyQt4.QtGui import *
00035 from PyQt4.QtCore import *
00036 from PyQt4.QtWebKit import *
00037
00038
00039
00040
00041
00042 class FormTabWidget( QTabWidget ):
00043 def __init__(self, parent=None):
00044 QTabWidget.__init__(self, parent)
00045
00046 def setTabValid(self, index, value):
00047 if value:
00048 self.setTabIcon( index, QIcon() )
00049 else:
00050 self.setTabIcon( index, QIcon( ':/images/warning.png' ) )
00051
00052
00053
00054
00055 class FormContainer( QWidget ):
00056 def __init__(self, parent=None, maxColumns=4):
00057 QWidget.__init__(self, parent)
00058 self.row = 0
00059 self.column = 0
00060 self.layout = QGridLayout( self )
00061 self.layout.setContentsMargins( 0, 0, 0, 0 )
00062 self.layout.setVerticalSpacing( 0 )
00063 self.layout.setAlignment( Qt.AlignTop )
00064 self.maxColumns = maxColumns
00065 self.isTab = False
00066 if isinstance( parent, FormTabWidget ):
00067 self.tabWidget = parent
00068 else:
00069 self.tabWidget = None
00070 self.fieldWidgets = []
00071 self.containerWidgets = []
00072
00073 def setTabEnabled(self, value):
00074 if self.tabWidget:
00075 self.tabWidget.setTabEnabled( self.tabWidget.indexOf( self ), value )
00076
00077 def setTabValid(self, value):
00078 if self.tabWidget:
00079 self.tabWidget.setTabValid( self.tabWidget.indexOf( self ), value )
00080
00081 def isValid(self, record):
00082 valid = True
00083 if not record:
00084 return valid
00085
00086 for w in self.fieldWidgets:
00087 if not record.isFieldValid( w.name ):
00088 valid = False
00089 break
00090
00091 if valid:
00092 for c in self.containerWidgets:
00093 if not c.isValid( record ):
00094 valid = False
00095 break
00096 return valid
00097
00098 def addWidget(self, widget, attributes={}, labelText=None):
00099 if widget.inherits( 'AbstractFieldWidget' ):
00100 self.fieldWidgets.append( widget )
00101 if widget.inherits( 'FormContainer' ):
00102 self.containerWidgets.append( widget )
00103
00104 colspan = int(attributes.get( 'colspan', 1 ))
00105 helpText = attributes.get( 'help', False )
00106 stylesheet = attributes.get( 'stylesheet', False )
00107
00108 if colspan > self.maxColumns:
00109 colspan = self.maxColumns
00110
00111 a = labelText and 1 or 0
00112 colspan -= a
00113 colspan = max(colspan, 1)
00114 if colspan + self.column + a > self.maxColumns:
00115 self.newRow()
00116
00117 if labelText:
00118 label = QLabel( self )
00119 label.setText( unicode( Common.normalizeLabel( labelText ) ) )
00120 label.setAlignment( Qt.AlignRight | Qt.AlignVCenter )
00121 label.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed )
00122 if helpText:
00123 color = 'blue'
00124 helpText = '<b>%s</b><br/>%s' % (labelText, helpText)
00125 label.setToolTip( helpText )
00126 label.setWhatsThis( helpText )
00127 widget.setWhatsThis( helpText )
00128 else:
00129 color = 'black'
00130
00131 label.setText( unicode( '<small><a style="color: %s" href="help">?</a></small> %s' % (color, labelText ) ) )
00132 self.connect( label, SIGNAL('linkActivated(QString)'), widget.showHelp )
00133
00134 self.layout.addWidget( label, self.row, self.column )
00135 self.column = self.column + 1
00136
00137 self.layout.addWidget( widget, self.row, self.column, 1, colspan )
00138
00139 if stylesheet:
00140 widget.setStyleSheet( stylesheet )
00141 self.column += colspan
00142
00143 def newRow(self):
00144 self.row = self.row + 1
00145 self.column = 0
00146
00147
00148 class FormView( AbstractView ):
00149 def __init__(self, parent=None):
00150 AbstractView.__init__( self, parent )
00151
00152 self.screen = parent
00153 self.title = ""
00154 self.record = None
00155 self._readOnly = False
00156
00157 self.layout = QHBoxLayout( self )
00158 self.layout.setContentsMargins( 0, 0, 0, 0 )
00159 self.layout.setAlignment( Qt.AlignTop )
00160
00161
00162 self.widgets = {}
00163
00164
00165 self.stateWidgets = []
00166
00167 def viewType(self):
00168 return 'form'
00169
00170 def setWidget(self, widget):
00171 self.widget = widget
00172 self.layout.addWidget( self.widget, 10 )
00173
00174
00175
00176 def ensureFieldVisible(self, fieldName):
00177 if not fieldName in self.widgets:
00178 return
00179
00180 previousContainer = None
00181 widget = self.widgets[fieldName].parent()
00182 while widget:
00183 if isinstance( widget, FormTabWidget ):
00184 widget.setCurrentWidget( previousContainer )
00185 if isinstance( widget, FormContainer ):
00186 previousContainer = widget
00187 widget = widget.parent()
00188
00189 def __getitem__(self, name):
00190 return self.widgets[name]
00191
00192 def store(self):
00193 if not self.record:
00194 return
00195
00196 for name in self.widgets:
00197 if self.widgets[name].record:
00198 self.widgets[name].store()
00199 else:
00200
00201 print "NO MODEL SET FOR WIDGET: ", name
00202
00203 def selectedRecords(self):
00204 if self.record:
00205 return [self.record]
00206 return []
00207
00208 def reset(self):
00209 for name, widget in self.widgets.items():
00210 widget.reset()
00211
00212 def display(self, currentRecord, records):
00213
00214
00215
00216
00217
00218
00219
00220
00221 if self.record:
00222 self.disconnect(self.record,SIGNAL('recordChanged(PyQt_PyObject)'),self.updateDisplay)
00223 self.disconnect(self.record,SIGNAL('setFocus(QString)'),self.setFieldFocus)
00224 self.record = currentRecord
00225 if self.record:
00226 self.connect(self.record,SIGNAL('recordChanged(PyQt_PyObject)'),self.updateDisplay)
00227 self.connect(self.record,SIGNAL('setFocus(QString)'),self.setFieldFocus)
00228 self.updateDisplay(self.record)
00229
00230 def setFieldFocus(self, fieldName):
00231 fieldName = unicode( fieldName )
00232 if not fieldName in self.widgets:
00233 return
00234 self.widgets[fieldName].setFocus()
00235
00236 def updateDisplay(self, record):
00237
00238
00239 for name in self.widgets:
00240 self.widgets[name].setReadOnly( False )
00241 if self.record:
00242 self.widgets[name].load(self.record)
00243 else:
00244 self.widgets[name].load(None)
00245
00246
00247 for widget in self.stateWidgets:
00248 widgetGui = widget['widget']
00249
00250
00251 for attribute, condition in widget['attributes'].iteritems():
00252 if self.record:
00253 value = self.record.evaluateCondition( condition )
00254 else:
00255 value = False
00256 if attribute == 'invisible':
00257 self.setWidgetVisible( widgetGui, not value )
00258 elif attribute == 'readonly':
00259 self.setWidgetReadOnly( widgetGui, value )
00260
00261 if widget['states']:
00262 if self.record and self.record.fieldExists('state'):
00263 state = self.record.value('state')
00264 else:
00265 state = ''
00266 if state in widget['states']:
00267 self.setWidgetVisible( widgetGui, True )
00268 else:
00269 self.setWidgetVisible( widgetGui, False )
00270
00271 if isinstance(widgetGui, FormContainer):
00272 if widgetGui.isTab:
00273 widgetGui.setTabValid( widgetGui.isValid( record ) )
00274
00275 if self._readOnly:
00276 for name in self.widgets:
00277 self.widgets[name].setReadOnly( True )
00278
00279 def setWidgetVisible(self, widget, value):
00280
00281
00282
00283
00284 if isinstance(widget, FormContainer) and widget.isTab:
00285 widget.setTabEnabled( value )
00286 else:
00287 widget.setVisible( value )
00288
00289 def setWidgetReadOnly(self, widget, value):
00290
00291
00292
00293 if isinstance(widget, FormContainer) and widget.isTab:
00294 widget.setTabEnabled( not value )
00295 else:
00296 widget.setEnabled( not value )
00297
00298 def addStateWidget(self, widget, attributes, states):
00299 if not attributes:
00300 attributes = "{}"
00301 attributes = eval( attributes )
00302 if states:
00303 states = states.split(',')
00304 else:
00305 states = []
00306 self.stateWidgets.append({
00307 'widget': widget,
00308 'attributes': attributes,
00309 'states': states
00310 })
00311
00312 def setReadOnly(self, value):
00313 self._readOnly = value
00314
00315 def viewSettings(self):
00316 splitters = self.findChildren( QSplitter )
00317 data = QByteArray()
00318 stream = QDataStream( data, QIODevice.WriteOnly )
00319 for x in splitters:
00320 stream << x.saveState()
00321 for x in sorted( self.widgets.keys() ):
00322 stream << self.widgets[x].saveState()
00323 return str( data.toBase64() )
00324
00325 def setViewSettings(self, settings):
00326 if not settings:
00327 return
00328 splitters = self.findChildren( QSplitter )
00329 data = QByteArray.fromBase64( settings )
00330 stream = QDataStream( data )
00331 for x in splitters:
00332 if stream.atEnd():
00333 return
00334 value = QByteArray()
00335 stream >> value
00336 x.restoreState( value )
00337 for x in sorted( self.widgets.keys() ):
00338 if stream.atEnd():
00339 return
00340 value = QByteArray()
00341 stream >> value
00342 self.widgets[x].restoreState( value )
00343
00344 def showsMultipleRecords(self):
00345 return False