class CcCommentsDelegate(QStyledItemDelegate): # {{{ ''' Delegate for comments data. ''' def __init__(self, parent): QStyledItemDelegate.__init__(self, parent) self.document = QTextDocument() def paint(self, painter, option, index): self.initStyleOption(option, index) style = QApplication.style() if option.widget is None \ else option.widget.style() self.document.setHtml(option.text) style.drawPrimitive(QStyle.PE_PanelItemViewItem, option, painter, widget=option.widget) rect = style.subElementRect(QStyle.SE_ItemViewItemDecoration, option, self.parent()) ic = option.icon if rect.isValid() and not ic.isNull(): sz = ic.actualSize(option.decorationSize) painter.drawPixmap(rect.topLeft(), ic.pixmap(sz)) ctx = QAbstractTextDocumentLayout.PaintContext() ctx.palette = option.palette if option.state & QStyle.State_Selected: ctx.palette.setColor( ctx.palette.Text, ctx.palette.color(ctx.palette.HighlightedText)) textRect = style.subElementRect(QStyle.SE_ItemViewItemText, option, self.parent()) painter.save() painter.translate(textRect.topLeft()) painter.setClipRect(textRect.translated(-textRect.topLeft())) self.document.documentLayout().draw(painter, ctx) painter.restore() def createEditor(self, parent, option, index): m = index.model() col = m.column_map[index.column()] if check_key_modifier(Qt.ControlModifier): text = '' else: text = m.db.data[index.row()][m.custom_columns[col]['rec_index']] editor = CommentsDialog(parent, text, column_name=m.custom_columns[col]['name']) d = editor.exec_() if d: m.setData(index, (editor.textbox.html), Qt.EditRole) return None def setModelData(self, editor, model, index): model.setData(index, (editor.textbox.html), Qt.EditRole)
class CcCommentsDelegate(QStyledItemDelegate): # {{{ ''' Delegate for comments data. ''' def __init__(self, parent): QStyledItemDelegate.__init__(self, parent) self.document = QTextDocument() def paint(self, painter, option, index): self.initStyleOption(option, index) style = QApplication.style() if option.widget is None \ else option.widget.style() self.document.setHtml(option.text) style.drawPrimitive(QStyle.PE_PanelItemViewItem, option, painter, widget=option.widget) rect = style.subElementRect(QStyle.SE_ItemViewItemDecoration, option, self.parent()) ic = option.icon if rect.isValid() and not ic.isNull(): sz = ic.actualSize(option.decorationSize) painter.drawPixmap(rect.topLeft(), ic.pixmap(sz)) ctx = QAbstractTextDocumentLayout.PaintContext() ctx.palette = option.palette if option.state & QStyle.State_Selected: ctx.palette.setColor(ctx.palette.Text, ctx.palette.color(ctx.palette.HighlightedText)) textRect = style.subElementRect(QStyle.SE_ItemViewItemText, option, self.parent()) painter.save() painter.translate(textRect.topLeft()) painter.setClipRect(textRect.translated(-textRect.topLeft())) self.document.documentLayout().draw(painter, ctx) painter.restore() def createEditor(self, parent, option, index): m = index.model() col = m.column_map[index.column()] if check_key_modifier(Qt.ControlModifier): text = '' else: text = m.db.data[index.row()][m.custom_columns[col]['rec_index']] editor = CommentsDialog(parent, text, column_name=m.custom_columns[col]['name']) d = editor.exec_() if d: m.setData(index, (editor.textbox.html), Qt.EditRole) return None def setModelData(self, editor, model, index): model.setData(index, (editor.textbox.html), Qt.EditRole)
class CcCommentsDelegate(QStyledItemDelegate): # {{{ ''' Delegate for comments data. ''' def __init__(self, parent): QStyledItemDelegate.__init__(self, parent) self.document = QTextDocument() def paint(self, painter, option, index): self.initStyleOption(option, index) style = QApplication.style() if option.widget is None \ else option.widget.style() self.document.setHtml(option.text) option.text = u'' if hasattr(QStyle, 'CE_ItemViewItem'): style.drawControl(QStyle.CE_ItemViewItem, option, painter) ctx = QAbstractTextDocumentLayout.PaintContext() ctx.palette = option.palette # .setColor(QPalette.Text, QColor("red")); if hasattr(QStyle, 'SE_ItemViewItemText'): textRect = style.subElementRect(QStyle.SE_ItemViewItemText, option) painter.save() painter.translate(textRect.topLeft()) painter.setClipRect(textRect.translated(-textRect.topLeft())) self.document.documentLayout().draw(painter, ctx) painter.restore() def createEditor(self, parent, option, index): m = index.model() col = m.column_map[index.column()] text = m.db.data[index.row()][m.custom_columns[col]['rec_index']] editor = CommentsDialog(parent, text, column_name=m.custom_columns[col]['name']) d = editor.exec_() if d: m.setData(index, (editor.textbox.html), Qt.EditRole) return None def setModelData(self, editor, model, index): model.setData(index, (editor.textbox.html), Qt.EditRole)
class DocumentFactory: def __init__(self, contentPath, formatManager): self.formatManager = formatManager self.contentPath = contentPath def createDocument(self, rootFrame): # Create empty document self.document = QTextDocument() self.document.setUndoRedoEnabled(False) self.document.setIndentWidth(20) # Register a renderer for custom text objects mo = CustomObjectRenderer() mo.setParent(self.document) self.document.documentLayout().registerHandler(QTextCharFormat.UserObject+1, mo); self.cursor = QTextCursor(self.document) self.listLevel = 0 self.paraFormat = None # add all root paragraphs for n in rootFrame.children: self.addNode(n) # Clean up the first paragraph if document is not empty self.cursor.movePosition(QTextCursor.Start) b = self.cursor.block() if b.length() == 1: cursor = QTextCursor(self.document.findBlockByLineNumber(0)) cursor.select(QTextCursor.BlockUnderCursor) cursor.deleteChar() return self.document def addNode(self, node): if type(node) == Paragraph: self.paraFormat = self.formatManager.getFormat(node.style) # NOTE: "The block char format is the format used when inserting # text at the beginning of an empty block." # See also below. self.cursor.insertBlock(self.paraFormat.getBlockFormat(), self.paraFormat.getCharFormat()) # self.cursor.insertFragment(QTextDocumentFragment.fromPlainText('')) if self.listLevel > 0: # TODO: use list style from list node - requires a stack, though ... listStyle = ('itemizedlist', 'level', str(self.listLevel)) newList = self.cursor.createList(self.formatManager.getFormat(listStyle).getListFormat()) for n in node.children: self.addNode(n) elif type(node) == List: self.listLevel += 1 for n in node.children: self.addNode(n) self.listLevel -= 1 elif type(node) is ImageFragment: imageObject = ImageObject() imagePath = os.path.join(self.contentPath, node.image) imageObject.setName(imagePath) imageObjectFormat = QTextCharFormat() imageObjectFormat.setObjectType(QTextFormat.UserObject + 1) imageObjectFormat.setProperty(QTextFormat.UserProperty + 1, imageObject) self.cursor.insertText('\ufffc', imageObjectFormat); elif type(node) is MathFragment: mathFormula = MathFormulaObject() mathFormula.setFormula(node.text) mathFormula.image = node.image # renderFormula() mathObjectFormat = QTextCharFormat() mathObjectFormat.setObjectType(QTextFormat.UserObject + 1) mathObjectFormat.setVerticalAlignment(QTextCharFormat.AlignMiddle) mathObjectFormat.setProperty(QTextFormat.UserProperty + 1, mathFormula) self.cursor.insertText('\ufffc', mathObjectFormat); elif type(node) is TextFragment: text = node.text.replace('\n', '\u2028') if node.href is not None: fmt = self.formatManager.getFormat(('link', None, None)) # TODO! charFmt = fmt.getCharFormat() charFmt.setAnchorHref(node.href) self.cursor.insertText(text, charFmt) else: # "The block char format is the format used when inserting text at the beginning of an empty block. # Hence, the block char format is only useful for the first fragment - # once a fragment is inserted with a different style, and afterwards # another fragment is inserted with no specific style, we need to reset # the char format to the block's char format explicitly! if node.style is not None: fmt = self.formatManager.getFormat(node.style) else: fmt = self.paraFormat self.cursor.insertText(text, fmt.getCharFormat())