~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/itemviews/qabstractitemdelegate.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the item views module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qabstractitemdelegate.h"
 
30
#include <qabstractitemmodel.h>
 
31
#include <qfontmetrics.h>
 
32
#include <qstring.h>
 
33
#include <qdebug.h>
 
34
 
 
35
/*!
 
36
    \class QAbstractItemDelegate qabstractitemdelegate.h
 
37
 
 
38
    \brief The QAbstractItemDelegate class is used to display and edit
 
39
    data items from a model.
 
40
 
 
41
    \ingroup model-view
 
42
    \mainclass
 
43
 
 
44
    A QAbstractItemDelegate provides the interface and common functionality
 
45
    for delegates in the model/view architecture. Delegates display
 
46
    individual items in views, and handle the editing of model data.
 
47
 
 
48
    The QAbstractItemDelegate class is one of the \l{Model/View Classes}
 
49
    and is part of Qt's \l{Model/View Programming}{model/view framework}.
 
50
 
 
51
    To render an item in a custom way, you must implement paint() and
 
52
    sizeHint(). The QItemDelegate class provides default implementations for
 
53
    these functions; if you do not need custom rendering, subclass that
 
54
    class instead.
 
55
 
 
56
    To provide custom editing, there are two approaches that can be
 
57
    used. The first approach is to create an editor widget and display
 
58
    it directly on top of the item. To do this you must reimplement
 
59
    createEditor() to provide an editor widget, setEditorData() to populate
 
60
    the editor with the data from the model, and setModelData() so that the
 
61
    delegate can update the model with data from the editor.
 
62
 
 
63
    The second approach is to handle user events directly by reimplementing
 
64
    editorEvent().
 
65
 
 
66
    \sa \link model-view-programming.html Model/View Programming\endlink QItemDelegate
 
67
*/
 
68
 
 
69
/*!
 
70
    \enum QAbstractItemDelegate::EndEditHint
 
71
 
 
72
    This enum describes the different hints that the delegate can give to the
 
73
    model and view components to make editing data in a model a comfortable
 
74
    experience for the user.
 
75
 
 
76
    \value NoHint           There is no recommended action to be performed.
 
77
 
 
78
    These hints let the delegate influence the behavior of the view:
 
79
 
 
80
    \value EditNextItem     The view should use the delegate to open an
 
81
                            editor on the next item in the view.
 
82
    \value EditPreviousItem The view should use the delegate to open an
 
83
                            editor on the previous item in the view.
 
84
 
 
85
    Note that custom views may interpret the concepts of next and previous
 
86
    differently.
 
87
 
 
88
    The following hints are most useful when models are used that cache
 
89
    data, such as those that manipulate date locally in order to increase
 
90
    performance or conserve network bandwidth.
 
91
 
 
92
    \value SubmitModelCache If the model caches data, it should write out
 
93
                            cached data to the underlying data store.
 
94
    \value RevertModelCache If the model caches data, it should discard
 
95
                            cached data and replace it with data from the
 
96
                            underlying data store.
 
97
 
 
98
    Although models and views should respond to these hints in appropriate
 
99
    ways, custom components may ignore any or all of them if they are not
 
100
    relevant.
 
101
*/
 
102
 
 
103
/*!
 
104
  \fn void QAbstractItemDelegate::commitData(QWidget *editor)
 
105
 
 
106
  This signal must be emitted when the \a editor widget has completed
 
107
  editing the data, and wants to write it back into the model.
 
108
*/
 
109
 
 
110
/*!
 
111
    \fn void QAbstractItemDelegate::closeEditor(QWidget *editor, EndEditHint hint)
 
112
 
 
113
    This signal is emitted when the user has finished editing an item using
 
114
    the specified \a editor.
 
115
 
 
116
    The \a hint provides a way for the delegate to influence how the model and
 
117
    view behave after editing is completed. It indicates to these components
 
118
    what action should be performed next to provide a comfortable editing
 
119
    experience for the user. For example, if \c EditNextItem is specified,
 
120
    the view should use a delegate to open an editor on the next item in the
 
121
    model.
 
122
 
 
123
    \sa EndEditHint
 
124
*/
 
125
 
 
126
/*!
 
127
    Creates a new abstract item delegate with the given \a parent.
 
128
*/
 
129
QAbstractItemDelegate::QAbstractItemDelegate(QObject *parent)
 
130
    : QObject(parent)
 
131
{
 
132
 
 
133
}
 
134
 
 
135
/*!
 
136
    \internal
 
137
 
 
138
    Creates a new abstract item delegate with the given \a parent.
 
139
*/
 
140
QAbstractItemDelegate::QAbstractItemDelegate(QObjectPrivate &dd, QObject *parent)
 
141
    : QObject(dd, parent)
 
142
{
 
143
 
 
144
}
 
145
 
 
146
/*!
 
147
    Destroys the abstract item delegate.
 
148
*/
 
149
QAbstractItemDelegate::~QAbstractItemDelegate()
 
150
{
 
151
 
 
152
}
 
153
 
 
154
/*!
 
155
    \fn void QAbstractItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const = 0;
 
156
 
 
157
    This pure abstract function must be reimplemented if you want to
 
158
    provide custom rendering. Use the \a painter and style \a option to
 
159
    render the item specified by the item \a index.
 
160
 
 
161
    If you reimplement this you must also reimplement sizeHint().
 
162
*/
 
163
 
 
164
/*!
 
165
    \fn QSize QAbstractItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const = 0
 
166
 
 
167
    This pure abstract function must be reimplemented if you want to
 
168
    provide custom rendering. The options are specified by \a option
 
169
    and the model item by \a index.
 
170
 
 
171
    If you reimplement this you must also reimplement paint().
 
172
*/
 
173
 
 
174
/*!
 
175
    Returns the editor to be used for editing the data item with the
 
176
    given \a index. Note that the index contains information about the
 
177
    model being used. The editor's parent widget is specified by \a parent,
 
178
    and the item options by \a option.
 
179
 
 
180
    The base implementation returns 0. If you want custom editing you
 
181
    will need to reimplement this function.
 
182
 
 
183
    \sa setModelData() setEditorData()
 
184
*/
 
185
QWidget *QAbstractItemDelegate::createEditor(QWidget *,
 
186
                                             const QStyleOptionViewItem &,
 
187
                                             const QModelIndex &) const
 
188
{
 
189
    return 0;
 
190
}
 
191
 
 
192
/*!
 
193
    Sets the contents of the given \a editor to the data for the item
 
194
    at the given \a index. Note that the index contains information
 
195
    about the model being used.
 
196
 
 
197
    The base implementation does nothing. If you want custom editing
 
198
    you will need to reimplement this function.
 
199
 
 
200
    \sa setModelData()
 
201
*/
 
202
void QAbstractItemDelegate::setEditorData(QWidget *,
 
203
                                          const QModelIndex &) const
 
204
{
 
205
    // do nothing
 
206
}
 
207
 
 
208
/*!
 
209
    Sets the data for the item at the given \a index in the \a model
 
210
    to the contents of the given \a editor.
 
211
 
 
212
    The base implementation does nothing. If you want custom editing
 
213
    you will need to reimplement this function.
 
214
 
 
215
    \sa setEditorData()
 
216
*/
 
217
void QAbstractItemDelegate::setModelData(QWidget *,
 
218
                                         QAbstractItemModel *,
 
219
                                         const QModelIndex &) const
 
220
{
 
221
    // do nothing
 
222
}
 
223
 
 
224
/*!
 
225
    Updates the geometry of the \a editor for the item with the given
 
226
    \a index, according to the rectangle specified in the \a option.
 
227
    If the item has an internal layout, the editor will be laid out
 
228
    accordingly. Note that the index contains information about the
 
229
    model being used.
 
230
 
 
231
    The base implementation does nothing. If you want custom editing
 
232
    you must reimplement this function.
 
233
*/
 
234
void QAbstractItemDelegate::updateEditorGeometry(QWidget *,
 
235
                                                 const QStyleOptionViewItem &,
 
236
                                                 const QModelIndex &) const
 
237
{
 
238
    // do nothing
 
239
}
 
240
 
 
241
/*!
 
242
    Whenever an event occurs, this function is called with the \a event
 
243
    \a model \a option and the \a index that corresponds to the item being edited.
 
244
 
 
245
    The base implementation returns false (indicating that it has not
 
246
    handled the event).
 
247
*/
 
248
bool QAbstractItemDelegate::editorEvent(QEvent *,
 
249
                                        QAbstractItemModel *,
 
250
                                        const QStyleOptionViewItem &,
 
251
                                        const QModelIndex &)
 
252
{
 
253
    // do nothing
 
254
    return false;
 
255
}
 
256
 
 
257
/*!
 
258
    If the string \a text is wider than \a width, returns an elided
 
259
    version of the string (i.e., a string with "..." in it).
 
260
    Otherwise, returns the original string.
 
261
 
 
262
    The \a mode parameter specifies whether the text is elided on the
 
263
    left (e.g., "...tech"), in the middle (e.g., "Tr...ch"), or on
 
264
    the right (e.g., "Trol...").
 
265
 
 
266
    The \a width is specified in pixels, not characters. The font
 
267
    metrics to be used are given by \a fontMetrics.
 
268
*/
 
269
 
 
270
QString QAbstractItemDelegate::elidedText(const QFontMetrics &fontMetrics, int width,
 
271
                                          Qt::TextElideMode mode, const QString &text)
 
272
{
 
273
    const QLatin1String ellipsis("...");
 
274
    int ellipsisWidth = fontMetrics.width(ellipsis);
 
275
    int length = text.length();
 
276
    int i = 0;
 
277
 
 
278
    if (fontMetrics.width(text) < width)
 
279
        return text;
 
280
 
 
281
    if (mode == Qt::ElideMiddle) {
 
282
        QString left, right;
 
283
        i = (length / 2) - 1;
 
284
        do {
 
285
            left = text.left(i);
 
286
            right = text.right(i);
 
287
        } while (--i > -1 &&
 
288
                 fontMetrics.width(left) + ellipsisWidth + fontMetrics.width(right) > width);
 
289
        return left + ellipsis + right;
 
290
    }
 
291
 
 
292
    int offset = (mode ==  Qt::ElideLeft) ? length - 1 : 0;
 
293
    QString elided;
 
294
        
 
295
    while (i < length && fontMetrics.width(elided + text.at(offset)) + ellipsisWidth < width) {
 
296
        if (mode == Qt::ElideLeft) {
 
297
            elided.prepend(text.at(offset));
 
298
            offset = (length - 1) - ++i;
 
299
        } else {
 
300
            elided.append(text.at(offset));
 
301
            offset = ++i;
 
302
        }
 
303
    }
 
304
    
 
305
    if (mode == Qt::ElideLeft) {
 
306
        if (elided.isEmpty())
 
307
            elided = text.right(1);
 
308
        elided.prepend(ellipsis);
 
309
    } else {
 
310
        if (elided.isEmpty())
 
311
            elided = text.left(1);
 
312
        elided.append(ellipsis);
 
313
    }
 
314
    
 
315
    return elided;
 
316
}