Package camelot :: Package camelot :: Package view :: Module forms
[hide private]
[frames] | no frames]

Source Code for Module camelot.camelot.view.forms

  1  #  ============================================================================ 
  2  # 
  3  #  Copyright (C) 2007-2008 Conceptive Engineering bvba. All rights reserved. 
  4  #  www.conceptive.be / project-camelot@conceptive.be 
  5  # 
  6  #  This file is part of the Camelot Library. 
  7  # 
  8  #  This file may be used under the terms of the GNU General Public 
  9  #  License version 2.0 as published by the Free Software Foundation 
 10  #  and appearing in the file LICENSE.GPL included in the packaging of 
 11  #  this file.  Please review the following information to ensure GNU 
 12  #  General Public Licensing requirements will be met: 
 13  #  http://www.trolltech.com/products/qt/opensource.html 
 14  # 
 15  #  If you are unsure which license is appropriate for your use, please 
 16  #  review the following information: 
 17  #  http://www.trolltech.com/products/qt/licensing.html or contact 
 18  #  project-camelot@conceptive.be. 
 19  # 
 20  #  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 
 21  #  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 
 22  # 
 23  #  For use of this library in commercial applications, please contact 
 24  #  project-camelot@conceptive.be 
 25  # 
 26  #  ============================================================================ 
 27   
 28  """Python structures to represent interface forms. 
 29   
 30  These structures can be transformed to QT forms. 
 31  """ 
 32   
 33  import logging 
 34  logger = logging.getLogger('camelot.view.forms') 
 35   
36 -def structure_to_form(structure):
37 """Convert a python data structure to a form, using the following rules : 38 39 if structure is an instance of Form, return structure 40 if structure is a list, create a Form from this list 41 """ 42 if isinstance(structure, Form): 43 return structure 44 return Form(structure)
45 46
47 -class Form(object):
48 """Use the QFormLayout widget to render a form""" 49
50 - def __init__(self, content, scrollbars=False):
51 """@param content: a list with the field names and forms to render""" 52 assert isinstance(content, list) 53 self._content = content 54 self._scrollbars = scrollbars 55 self._fields = [] 56 for c in content: 57 if isinstance(c, Form): 58 self._fields.extend(c.get_fields()) 59 else: 60 assert isinstance(c, (str, unicode)) 61 self._fields.append(c)
62
63 - def get_fields(self):
64 """@return : the fields, visible in this form""" 65 return self._fields
66
67 - def render(self, widgets, parent=None, nomargins=False):
68 """@param widgets: a dictionary mapping each field in this form to a tuple 69 of (label, widget editor) 70 71 @return : a QWidget into which the form is rendered 72 """ 73 logger.debug('rendering %s' % self.__class__.__name__) 74 from camelot.view.controls.editors import One2ManyEditor 75 from camelot.view.controls.editors import RichTextEditor 76 77 from PyQt4 import QtGui 78 from PyQt4.QtCore import Qt 79 80 #form_layout = QtGui.QFormLayout() 81 #form_layout.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow) 82 #for field in self._content: 83 # if isinstance(field, Form): 84 # form_layout.addRow(field.render(widgets, parent, True)) 85 # elif field in widgets: 86 # label, editor = widgets[field] 87 # if isinstance(editor, One2ManyEditor) or\ 88 # isinstance(editor, RichTextEditor): 89 # form_layout.addRow(label) 90 # form_layout.addRow(editor) 91 # else: 92 # form_layout.addRow(label, editor) 93 94 form_layout = QtGui.QGridLayout() 95 row = 0 96 for field in self._content: 97 if isinstance(field, Form): 98 col = 0 99 row_span = 1 100 col_span = 2 101 f = field.render(widgets, parent, True) 102 if isinstance(f, QtGui.QLayout): 103 form_layout.addLayout(f, row, col, row_span, col_span) 104 else: 105 form_layout.addWidget(f, row, col, row_span, col_span) 106 row += 1 107 elif field in widgets: 108 col = 0 109 row_span = 1 110 label, editor = widgets[field] 111 if isinstance(editor, (One2ManyEditor, RichTextEditor)): 112 col_span = 2 113 form_layout.addWidget(label, row, col, row_span, col_span) 114 row += 1 115 form_layout.addWidget(editor, row, col, row_span, col_span) 116 row += 1 117 else: 118 col_span = 1 119 form_layout.addWidget(label, row, col, row_span, col_span) 120 form_layout.addWidget(editor, row, col + 1, row_span, col_span) 121 row += 1 122 123 # get last item in the layout 124 last_item = form_layout.itemAt(form_layout.count() - 1) 125 126 # if last item does not contain a widget, 0 is returned 127 # which is fine with the isinstance test 128 w = last_item.widget() 129 130 # add stretch only if last item is not expandable 131 if isinstance(w, (One2ManyEditor, RichTextEditor)): 132 pass 133 else: 134 form_layout.setRowStretch(form_layout.rowCount(), 1) 135 136 form_widget = QtGui.QWidget() 137 138 # fix embedded forms 139 if nomargins: 140 form_layout.setContentsMargins(0, 0, 0, 0) 141 142 form_widget.setSizePolicy(QtGui.QSizePolicy.Expanding, 143 QtGui.QSizePolicy.Expanding) 144 form_widget.setLayout(form_layout) 145 146 if self._scrollbars: 147 scroll_area = QtGui.QScrollArea() 148 scroll_area.setWidget(form_widget) 149 scroll_area.setWidgetResizable(True) 150 scroll_area.setFrameStyle(QtGui.QFrame.NoFrame) 151 return scroll_area 152 153 return form_widget
154 155
156 -class TabForm(Form):
157 """Render forms within a QTabWidget""" 158
159 - def __init__(self, tabs):
160 """@param tabs: a list of tuples of (tab_label, tab_form)""" 161 assert isinstance(tabs, list) 162 for tab in tabs: 163 assert isinstance(tab, tuple) 164 self.tabs = [(tab_label, structure_to_form(tab_form)) 165 for tab_label, tab_form in tabs] 166 super(TabForm, self).__init__(sum((tab_form.get_fields() 167 for tab_label, tab_form in self.tabs), []))
168
169 - def render(self, widgets, parent=None, nomargins=False):
170 logger.debug('rendering %s' % self.__class__.__name__) 171 from PyQt4 import QtGui 172 from PyQt4.QtCore import Qt 173 widget = QtGui.QTabWidget(parent) 174 for tab_label, tab_form in self.tabs: 175 #form = tab_form.render(widgets, widget) 176 #print form.height() 177 #widget.addTab(form, tab_label) 178 widget.addTab(tab_form.render(widgets, widget), tab_label) 179 return widget
180 181
182 -class HBoxForm(Form):
183 """Render different forms in a horizontal box""" 184
185 - def __init__(self, columns):
186 """@param columns: a list of forms to display in the different columns 187 of the horizontal box""" 188 assert isinstance(columns, list) 189 self.columns = [structure_to_form(col) for col in columns] 190 super(HBoxForm, self).__init__(sum((column_form.get_fields() 191 for column_form in self.columns), []))
192
193 - def render(self, widgets, parent=None, nomargins=False):
194 logger.debug('rendering %s' % self.__class__.__name__) 195 from PyQt4 import QtGui 196 from PyQt4.QtCore import Qt 197 widget = QtGui.QHBoxLayout() 198 for form in self.columns: 199 widget.addWidget(form.render(widgets, parent, nomargins)) 200 return widget
201 202
203 -class VBoxForm(Form):
204 """Render different forms or widgets in a vertical box""" 205
206 - def __init__(self, rows):
207 """@param rows: a list of forms to display in the different columns 208 of the horizontal box 209 """ 210 assert isinstance(rows, list) 211 self.rows = [structure_to_form(row) for row in rows] 212 super(VBoxForm, self).__init__(sum((row_form.get_fields() for row_form in self.rows), []))
213
214 - def render(self, widgets, parent=None, nomargins=False):
215 logger.debug('rendering %s' % self.__class__.__name__) 216 from PyQt4 import QtGui 217 from PyQt4.QtCore import Qt 218 widget = QtGui.QVBoxLayout() 219 for form in self.rows: 220 widget.addWidget(form.render(widgets, parent, nomargins)) 221 return widget
222 223
224 -class WidgetOnlyForm(Form):
225 """Renders a single widget without its label, typically a one2many widget""" 226
227 - def __init__(self, field):
228 assert isinstance(field, (str, unicode)) 229 super(WidgetOnlyForm, self).__init__([field])
230
231 - def render(self, widgets, parent=None, nomargins=False):
232 logger.debug('rendering %s' % self.__class__.__name__) 233 label, editor = widgets[self.get_fields()[0]] 234 return editor
235