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