~kvilhaugsvik/qbzr/qshelve_all

916.2.1 by Ian Clatworthy
Basic qplugins implementation
1
# Copyright (C) 2009 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
18
from PyQt4 import QtGui
19
from PyQt4.QtCore import Qt, QVariant
20
21
22
class QBzrConditionalDataView(QtGui.QFrame):
23
    """A list/table/tree with a label.
24
    
25
    Only the label is shown when the data model is empty.
26
    """
27
28
    def __init__(self, type, listmode_or_headers, label_text,
29
            details, parent=None):
30
        """Construct the view.
31
32
        :param type: one of list, table, tree
33
        :param listmode_or_headers: For lists, set the initial list view
34
          mode: True => list, False => icon.
35
          For tables and trees, the list of headers.
36
        :param label_text: text for label. May contain %(rows)d to substitute
37
          the row count.
38
        :param details: if non-None, a QWidget to show in a details panel.
39
        :param parent: parent widget
40
        """
41
        QtGui.QFrame.__init__(self, parent)
42
43
        # Build the model & view for the data
44
        self._type = type
45
        columns = listmode_or_headers
46
        if type == 'list':
47
            self._view = QtGui.QListView()
48
            self._view.setResizeMode(QtGui.QListView.Adjust)
49
            self._view.setWrapping(True)
50
            if listmode_or_headers:
51
                self._view.setViewMode(QtGui.QListView.ListMode)
52
            else:
53
                self._view.setViewMode(QtGui.QListView.IconMode)
54
            columns = ['Name']
55
            # TODO: we could add a combo-box here letting the user decide
56
            # on list vs icons. Would we need a way to switch it off?
57
        elif type == 'tree':
58
            self._view = QtGui.QTreeView()
59
        elif type == 'table':
60
            self._view = QtGui.QTableView()
61
        self._model = QtGui.QStandardItemModel(0, len(columns))
62
        self._model.setHorizontalHeaderLabels(columns)
63
        # Make the view read-only, and enable multi-selection of items
64
        self._view.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
65
        self._view.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
66
        self._view.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
67
        self._view.setModel(self._model)
68
69
        # Build the label
70
        self._label_text = label_text
71
        if label_text:
72
            self._label = QtGui.QLabel()
73
            self._update_label_text()
74
75
        # Put them together
76
        layout = QtGui.QVBoxLayout()
77
        if details:
78
            splitter = QtGui.QSplitter()
79
            splitter.setOrientation(Qt.Vertical)
80
            splitter.addWidget(self._view)
81
            splitter.addWidget(details)
82
            layout.addWidget(splitter)
83
        else:
84
            layout.addWidget(self._view)
85
        if label_text:
86
            layout.addWidget(self._label)
87
        self.setLayout(layout)
88
89
    def view(self):
90
        """Get the view object (QAbstractItemView)."""
91
        return self._view
92
93
    def label(self):
94
        """Get the label object (QLabel)."""
95
        return self._label
96
97
    def setData(self, tuple_list, decoration_provider=None):
98
        """Reset the model to have the data shown.
99
100
        :param tuple_list: a list of tuples. Each tuple should have
101
          len(headers) items.
102
        :param decoration_provider: a callable taking the row number
103
          and record. It returns the icon to display in the first column
104
          or None if none.
105
        """
106
        # Update the model
107
        row_count = len(tuple_list)
108
        model = self._model
109
        model.setRowCount(row_count)
110
        cell_role = Qt.DisplayRole
111
        for row, record in enumerate(tuple_list):
112
            if decoration_provider:
113
                icon = decoration_provider(row, record)
114
                if icon:
115
                    index = model.index(row, 0)
116
                    model.setData(index, QVariant(icon), Qt.DecorationRole)
117
            for col, value in enumerate(record):
118
                #print "putting %s into %d,%d" % (value, row, col)
119
                index = model.index(row, col)
120
                model.setData(index, QVariant(value or ''), cell_role)
121
122
        # Update the view & label
123
        self._view.setVisible(row_count > 0)
124
        if self._type in ['tree', 'table']:
125
            self._view.resizeColumnToContents(0)
126
        self._update_label_text(row_count)
127
128
    def _update_label_text(self, row_count=0):
129
        if self._label_text:
130
            text = self._label_text % {'rows': row_count}
131
            self._label.setText(text)