def addWidget(self, widget, attributes=None, labelText=None): if attributes is None: attributes = {} colspan = int(attributes.get('colspan', 1)) helpText = attributes.get('help', False) if Settings.value('koo.developer_mode', False) and isinstance(widget, AbstractFieldWidget): helpText = (helpText or '') + \ _('<p><i>Field name: %s</i></p>') % widget.name helpAttributes = attributes.copy() helpAttributes.update(self.fields.get(widget.name, {})) helpAttributes = ['<b>%s</b>: %s<br/>' % (x, helpAttributes[x]) for x in sorted(helpAttributes.keys())] helpAttributes = '\n'.join(helpAttributes) helpText += _('<p><i>Attributes:<br/>%s</i></p>') % helpAttributes attributes['help'] = helpText stylesheet = attributes.get('stylesheet', False) # Get colspan if colspan > self.maxColumns: colspan = self.maxColumns a = labelText and 1 or 0 colspan -= a colspan = max(colspan, 1) if colspan + self.column + a > self.maxColumns: self.newRow() # Get rowspan rowspan = int(attributes.get('rowspan', 1)) if labelText: label = QLabel(self) label.setText(str(Common.normalizeLabel(labelText))) label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) if helpText: color = 'blue' helpText = '<b>%s</b><br/>%s' % (labelText, helpText) label.setToolTip(helpText) label.setWhatsThis(helpText) widget.setWhatsThis(helpText) else: color = 'black' label.setText(str( '<small><a style="color: %s" href="help">?</a></small> %s' % (color, labelText))) label.linkActivated['QString'].connect(widget.showHelp) self.layout.addWidget(label, self.row, self.column) self.column = self.column + 1 self.layout.addWidget(widget, self.row, self.column, rowspan, colspan) if stylesheet: widget.setStyleSheet(stylesheet) self.column += colspan
def __init__(self, arch, fields, state, name, datas, parent=None): QDialog.__init__(self, parent) self.setModal(True) buttons = [] self.datas = datas self.buttonsLayout = QHBoxLayout() self.buttonsLayout.addStretch() for x in state: but = QPushButton(Common.normalizeLabel(x[1])) # We store the value to return into objectName property but.setObjectName(x[0]) # The third element is the gtk-icon if len(x) >= 3: but.setIcon(Icons.kdeIcon(x[2])) # The forth element is True if the button is the default one if len(x) >= 4 and x[3]: but.setDefault(True) self.buttonsLayout.addWidget(but) but.clicked.connect(self.slotPush) val = {} for f in fields: if 'value' in fields[f]: val[f] = fields[f]['value'] self.group = RecordGroup('wizard.' + name) # Do not allow record loading as most probably 'wizard.'+name model # won't exist in the server self.group.setDomainForEmptyGroup() self.screen = Screen(self) self.screen.setRecordGroup(self.group) self.screen.new(default=False) # We don't want the toolbar to be shown at the wizard self.screen.setToolbarVisible(False) self.screen.addView(arch, fields, display=True) # Set default values self.screen.currentRecord().set(val) # Set already stored values self.screen.currentRecord().set(self.datas) self.screen.display() # Set minimum and maximum dialog size size = self.screen.sizeHint() self.setMinimumSize(size.width() + 100, min(600, size.height() + 25)) size = QApplication.desktop().availableGeometry(self).size() size -= QSize(50, 50) self.setMaximumSize(size) self.layout = QVBoxLayout(self) self.layout.addWidget(self.screen) self.layout.addLayout(self.buttonsLayout) self.setWindowTitle(self.screen.currentView().title)
def __init__(self, parent, view, attributes): AbstractFieldWidget.__init__(self, parent, view, attributes) self.button = QPushButton(self) layout = QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.button) self.button.setText( Common.normalizeLabel(attributes.get('string', 'unknown'))) if 'icon' in attributes: self.button.setIcon(Icons.kdeIcon(attributes['icon'])) self.connect(self.button, SIGNAL('clicked()'), self.click)
def create(parent, definition, model): if not definition: # If definition is not set we initialize it appropiately # to be able to add the 'Print Screen' action. definition = {'print': [], 'action': [], 'relate': []} # We always add the 'Print Screen' action. definition['print'].append({ 'name': 'Print Screen', 'string': _('Print Screen'), 'report_name': 'printscreen.list', 'type': 'ir.actions.report.xml' }) actions = [] auto_shortcuts = Settings.value('koo.auto_shortcuts', False, bool) for icontype in ('print', 'action', 'relate'): for tool in definition[icontype]: action = Action(parent) action.setIcon(QIcon(":/images/%s.png" % icontype)) action.setText(Common.normalizeLabel(tool['string'])) action.setType(icontype) action.setData(tool) action.setModel(model) number = len(actions) shortcut = 'Ctrl+' if auto_shortcuts and number > 9: shortcut += 'Shift+' number -= 10 if auto_shortcuts and number < 10: shortcut += str(number) action.setShortcut(QKeySequence(shortcut)) action.setToolTip(action.text() + ' (%s)' % shortcut) actions.append(action) plugs = Plugins.list(model) for p in sorted(plugs.keys(), key=lambda x: plugs[x].get('string', '')): action = Action(parent) action.setIcon(QIcon(":/images/exec.png")) action.setText(unicode(plugs[p]['string'])) action.setData(p) action.setType('plugin') action.setModel(model) actions.append(action) return actions
def headerData(self, section, orientation, role): if orientation == Qt.Vertical: return QVariant() if role == Qt.DisplayRole: field = self.fields.get(self.field(section)) if not field: field = self.buttons.get(self.field(section)) return QVariant(Common.normalizeLabel(str(field['string']))) elif role == Qt.FontRole and not self._readOnly: fieldName = self.field(section) if self.group.fieldExists( fieldName) and self.group.isFieldRequired(fieldName): font = QFont() font.setBold(True) return QVariant(font) return QVariant()
def create(parent, definition, model): """ Creates a list of Action objects given a parent, model and definition. The 'definition' parameter is the 'toolbar' parameter returned by server function fields_view_get. :param parent: :param definition: :param model: :return: """ if not definition: # If definition is not set we initialize it appropiately # to be able to add the 'Print Screen' action. definition = {'print': [], 'action': [], 'relate': []} # Save action definition['action'].append({ 'name': 'save', 'string': _('Save'), 'action': parent.parentWidget().save, }) # Cancel action definition['action'].append({ 'name': 'cancel', 'string': _('Cancel'), 'action': parent.parentWidget().cancel, }) actions = [] for tool in definition['action']: action = Action(parent) if tool['name'] in ("save", "cancel"): action.setIcon(QIcon(":/images/{}.png".format(tool['name']))) else: action.setIcon(QIcon(":/images/{}.png".format('action'))) action.setText(Common.normalizeLabel(tool['string'])) action.setType('action') action.setData(tool) action.setModel(model) if 'action' in tool: action.triggered.connect(tool['action']) actions.append(action) return actions
def headerData(self, section, orientation, role): if orientation == Qt.Vertical: return QVariant() if role == Qt.DisplayRole: field = self.fields.get(self.field(section), None) if not field: field = self.buttons.get(self.field(section)) if not field: self._log.warning("Could not get field %s: %s for %s header display role" % \ (section, self.field(section) or 'in %d fields' % len(self.visibleFields), self.group.resource)) return QVariant() return QVariant(Common.normalizeLabel(unicode(field['string']))) elif role == Qt.FontRole and not self._readOnly: fieldName = self.field(section) if self.group.fieldExists( fieldName) and self.group.isFieldRequired(fieldName): font = QFont() font.setBold(True) return QVariant(font) return QVariant()
def parse(self, root_node, fields, notebook=None, container=None): attrs = Common.nodeAttributes(root_node) onWriteFunction = attrs.get('on_write', '') if container == None: parent = self.view if notebook: parent = notebook # We want FormContainer parent to be the notebook for the case # when it's a QTabWidget. This way FormContainer can enable/disable # the tab when necessary. container = FormContainer(parent, int(attrs.get('col', 4)), fields) if not self.view.title: self.view.title = attrs.get('string', 'Unknown') for node in root_node.childNodes: if not node.nodeType == node.ELEMENT_NODE: continue attrs = Common.nodeAttributes(node) if node.localName == 'image': icon = QLabel(container) icon.setPixmap(Icons.kdePixmap(attrs['name'])) container.addWidget(icon, attrs) elif node.localName == 'separator': caption = attrs.get('string', '') separator = QWidget(container) label = QLabel(separator) label.setText(caption) font = label.font() font.setBold(True) label.setFont(font) line = QFrame(separator) line.setFrameShadow(QFrame.Plain) if attrs.get('orientation') == 'vertical': line.setFrameShape(QFrame.VLine) separator.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Expanding) layout = QHBoxLayout(separator) else: line.setFrameShape(QFrame.HLine) separator.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed) layout = QVBoxLayout(separator) layout.setAlignment(Qt.AlignTop) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(label) layout.addWidget(line) self.view.addStateWidget( separator, attrs.get('attrs'), attrs.get('states')) container.addWidget(separator, attrs) elif node.localName == 'label': text = attrs.get('string', '') if not text: for node in node.childNodes: if node.nodeType == node.TEXT_NODE: text += node.data else: text += node.toxml() label = QLabel(text, container) label.setWordWrap(True) if 'width' in attrs: label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) label.setMinimumWidth(int(attrs['width'])) label.setMaximumWidth(int(attrs['width'])) else: label.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Fixed) container.addWidget(label, attrs) elif node.localName == 'newline': container.newRow() elif node.localName == 'button': if not self.isWidgetVisible(attrs): continue button = FieldWidgetFactory.create( 'button', container, self.view, attrs) name = attrs.get('name') if not name: name = 'unnamed_%d' % self.unnamed self.unnamed += 1 self.view.widgets[name] = button self.view.addStateWidget( button, attrs.get('attrs'), attrs.get('states')) container.addWidget(button, attrs) elif node.localName == 'notebook': if not self.isWidgetVisible(attrs): continue tab = FormTabWidget(container) if attrs and 'tabpos' in attrs: pos = { 'up': QTabWidget.North, 'down': QTabWidget.South, 'left': QTabWidget.West, 'right': QTabWidget.East }[attrs['tabpos']] else: pos = { 'left': QTabWidget.West, 'top': QTabWidget.North, 'right': QTabWidget.East, 'bottom': QTabWidget.South }[Settings.value('koo.tabs_position')] tab.setTabPosition(pos) attrs['colspan'] = attrs.get('colspan', 3) container.addWidget(tab, attrs) # We pass a container because othewise a new container would # be created by parse() and we don't want that because the tab # itself doesn't have a container: it's each of it's pages # that will have a container. _, onWriteFunction = self.parse(node, fields, tab, container) elif node.localName == 'page': if not self.isWidgetVisible(attrs): continue widget, onWriteFunction = self.parse(node, fields, notebook) # Mark the container as the main widget in a Tab. This way # we can enable/disable the whole tab easily. widget.isTab = True self.view.addStateWidget( widget, attrs.get('attrs'), attrs.get('states')) notebook.addTab(widget, Common.normalizeLabel( attrs.get('string', ''))) elif node.localName == 'hpaned': widget = QSplitter(Qt.Horizontal, container) container.addWidget(widget, attrs) self.parse(node, fields, widget, container) elif node.localName == 'vpaned': widget = QSplitter(Qt.Vertical, container) container.addWidget(widget, attrs) self.parse(node, fields, widget, container) elif node.localName == 'child1': widget, onWriteFunction = self.parse(node, fields) notebook.addWidget(widget) elif node.localName == 'child2': widget, onWriteFunction = self.parse(node, fields) notebook.addWidget(widget) elif node.localName == 'action': name = str(attrs['name']) widget = FieldWidgetFactory.create( 'action', container, self.view, attrs) attrs['colspan'] = attrs.get('colspan', 3) self.view.widgets[name] = widget container.addWidget(widget, attrs) elif node.localName == 'field': if not self.isWidgetVisible(attrs): continue name = attrs['name'] del attrs['name'] type = attrs.get('widget', fields[name]['type']) fields[name].update(attrs) fields[name]['model'] = self.viewModel # Create the appropiate widget for the given field type widget = FieldWidgetFactory.create( type, container, self.view, fields[name]) if not widget: continue fields[name]['name'] = name if self.filter: widget.node = node self.widgetList.append(widget) label = None if not int(attrs.get('nolabel', 0)): label = fields[name]['string'] + ' :' self.view.widgets[name] = widget #attrs['colspan'] = int(attrs.get('colspan', widgets_type[ type ][1])) if not 'help' in attrs: attrs['help'] = fields[name].get('help', False) container.addWidget(widget, attrs, label) elif node.localName == 'group': if not self.isWidgetVisible(attrs): continue widget, onWriteFunction = self.parse(node, fields, notebook) if 'string' in attrs: group = QGroupBox(notebook) group.setTitle(attrs['string']) layout = QHBoxLayout(group) layout.setAlignment(Qt.AlignTop) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(widget) widget = group self.view.addStateWidget( widget, attrs.get('attrs'), attrs.get('states')) container.addWidget(widget, attrs) return container, onWriteFunction
def create(parent, definition, model): """ Creates a list of Action objects given a parent, model and definition. The 'definition' parameter is the 'toolbar' parameter returned by server function fields_view_get. :param parent: :param definition: :param model: :return: """ if not definition: # If definition is not set we initialize it appropiately # to be able to add the 'Print Screen' action. definition = {'print': [], 'action': [], 'relate': []} # We always add the 'Print Screen' action. definition['print'].append({ 'name': 'Print Screen', 'string': _('Print Screen'), 'report_name': 'printscreen.list', 'type': 'ir.actions.report.xml' }) fwidget = parent.parentWidget() hasReadonly = getattr(fwidget, "isReadonly", None) if hasReadonly and not fwidget.isReadonly(): # Save action definition['action'].append({ 'name': 'save', 'string': _('Save'), 'shortcut': 'S', 'action': parent.parentWidget().save, }) # Cancel action definition['action'].append({ 'name': 'cancel', 'string': _('Cancel'), 'shortcut': 'C', 'action': parent.parentWidget().cancel, }) actions = [] for icontype in ('print', 'action', 'relate'): for tool in definition[icontype]: action = Action(parent) action.setIcon(QIcon(":/images/%s.png" % icontype)) action.setText(Common.normalizeLabel(tool['string'])) action.setType(icontype) action.setData(tool) action.setModel(model) number = len(actions) shortcut = 'Ctrl+' # Add save shortcut with Ctrl + S if tool['name'] in ["save", "cancel"]: shortcut += tool['shortcut'] action.setShortcut(QKeySequence(shortcut)) action.setToolTip(action.text() + ' (%s)' % shortcut) action.setIcon( QIcon(":/images/{}.png".format(tool['name']))) action.triggered.connect(tool['action']) else: if number > 9: shortcut += 'Shift+' number -= 10 if number < 10: shortcut += str(number) action.setShortcut(QKeySequence(shortcut)) action.setToolTip(action.text() + ' (%s)' % shortcut) actions.append(action) plugs = Plugins.list(model) for p in sorted(list(plugs.keys()), key=lambda x: plugs[x].get('string', '')): action = Action(parent) action.setIcon(QIcon(":/images/exec.png")) action.setText(str(plugs[p]['string'])) action.setData(p) action.setType('plugin') action.setModel(model) actions.append(action) return actions