Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 1.9, 1.9.1, and 1.9.2

htmltreeview: introduce a read-only multi-line HTML tree view

Changeset 7fa4e363ff1d

Parent bb7933700ac5

by Steve Borho

Changes to one file · Browse files at 7fa4e363ff1d Showing diff from parent bb7933700ac5 Diff from another changeset...

Change 1 of 1 Show Entire File tortoisehg/​hgqt/​htmllistview.py Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
@@ -0,0 +1,122 @@
+# htmllistview.py - QListView based widget for selectable read-only HTML +# +# Copyright 2010 Steve Borho <steve@borho.org> +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2, incorporated herein by reference. + +import sys + +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +class HtmlModel(QAbstractListModel): + + def __init__(self, strings): + QAbstractTableModel.__init__(self) + self.strings = strings + + def rowCount(self, parent): + if not parent.isValid(): + return len(self.strings) + return 0 + + def data(self, index, role): + if not index.isValid() or role != Qt.DisplayRole: + return QVariant() + if index.row() < 0 or index.row() >= len(self.strings): + return QVariant() + return QVariant(self.strings[index.row()]) + + def headerData(self, col, orientation, role): + if col != 0 or role != Qt.DisplayRole or orientation != Qt.Horizontal: + return QVariant() + else: + return QVariant("Multiline Rich-Text List") + + def flags(self, index): + return Qt.ItemIsSelectable | Qt.ItemIsEnabled + +class HtmlListView(QListView): + def __init__(self, model): + QListView.__init__(self) + self.setWindowTitle('HtmlListView') + self.setModel(model) + self.setSelectionBehavior(QAbstractItemView.SelectItems) + self.setSelectionMode(QAbstractItemView.ExtendedSelection) + self.resize(600, 200) + self.setItemDelegate(HTMLDelegate(self)) + self._supportsSelection = QApplication.clipboard().supportsSelection() + + def selectionChanged(self, selected, deselected): + QListView.selectionChanged(self, selected, deselected) + self.copySelection( QClipboard.Selection ) + + def keyPressEvent(self, event): + if event.matches(QKeySequence.Cut) or event.matches(QKeySequence.Copy): + self.copySelection(QClipboard.Clipboard) + else: + QListView.keyPressEvent(self, event) + + def copySelection(self, mode): + if mode == QClipboard.Selection and not self._supportsSelection: + return + + maxCol = 0 + sel = [] + for index in self.selectionModel().selectedIndexes(): + if maxCol < index.column(): + maxCol = index.column() + sel.append((index.row(), index.column(), index)) + sel.sort() + + selectionText = '' + for item in sel: + data = self.model().data(item[2], Qt.DisplayRole).toString() + data.replace('\n', '\\n') + selectionText += data + if item[1] == maxCol: + selectionText += '\n' + else: + selectionText += '\t' + + QApplication.clipboard().setText(selectionText, mode) + + +class HTMLDelegate(QStyledItemDelegate): + def __init__(self, parent=0): + QItemDelegate.__init__(self, parent) + + def paint(self, painter, option, index): + options = QStyleOptionViewItemV4(option) + doc = QTextDocument() + doc.setHtml(index.data().toString()) + + painter.save() + options.widget.style().drawControl(QStyle.CE_ItemViewItem, + options, painter) + painter.translate(options.rect.left(), options.rect.top()) + clip = QRectF(0, 0, options.rect.width(), options.rect.height()) + doc.drawContents(painter, clip) + painter.restore() + + def sizeHint(self, option, index): + options = QStyleOptionViewItemV4(option) + doc = QTextDocument() + doc.setHtml(index.data().toString()) + doc.setTextWidth(options.rect.width()) + return QSize(doc.idealWidth(), doc.size().height()) + + +if __name__ == "__main__": + items = [ 'item0', + '<pre style="color: green">just this text from this item</pre>', + 'what does a multi<br>line cell look like?', + 'what <b>does</b> a multi<br>line cell<br>look<br>like?', + 'item2' ] + app = QApplication(sys.argv) + tm = HtmlModel(items) + tv1 = HtmlListView( tm ) + tv1.show() + app.connect(app, SIGNAL('lastWindowClosed()'), app, SLOT('quit()')) + sys.exit(app.exec_())