src/gui/itemviews/qabstractitemdelegate.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qabstractitemdelegate.h"
       
    43 
       
    44 #ifndef QT_NO_ITEMVIEWS
       
    45 #include <qabstractitemmodel.h>
       
    46 #include <qabstractitemview.h>
       
    47 #include <qfontmetrics.h>
       
    48 #include <qwhatsthis.h>
       
    49 #include <qtooltip.h>
       
    50 #include <qevent.h>
       
    51 #include <qstring.h>
       
    52 #include <qdebug.h>
       
    53 #include <private/qtextengine_p.h>
       
    54 
       
    55 QT_BEGIN_NAMESPACE
       
    56 
       
    57 /*!
       
    58     \class QAbstractItemDelegate
       
    59 
       
    60     \brief The QAbstractItemDelegate class is used to display and edit
       
    61     data items from a model.
       
    62 
       
    63     \ingroup model-view
       
    64 
       
    65 
       
    66     A QAbstractItemDelegate provides the interface and common functionality
       
    67     for delegates in the model/view architecture. Delegates display
       
    68     individual items in views, and handle the editing of model data.
       
    69 
       
    70     The QAbstractItemDelegate class is one of the \l{Model/View Classes}
       
    71     and is part of Qt's \l{Model/View Programming}{model/view framework}.
       
    72 
       
    73     To render an item in a custom way, you must implement paint() and
       
    74     sizeHint(). The QItemDelegate class provides default implementations for
       
    75     these functions; if you do not need custom rendering, subclass that
       
    76     class instead.
       
    77 
       
    78     We give an example of drawing a progress bar in items; in our case
       
    79     for a package management program.
       
    80 
       
    81     \image widgetdelegate.png
       
    82 
       
    83     We create the \c WidgetDelegate class, which inherits from
       
    84     QStyledItemDelegate. We do the drawing in the paint() function:
       
    85 
       
    86     \snippet doc/src/snippets/widgetdelegate.cpp 0
       
    87 
       
    88     Notice that we use a QStyleOptionProgressBar and initialize its
       
    89     members. We can then use the current QStyle to draw it.
       
    90 
       
    91     To provide custom editing, there are two approaches that can be
       
    92     used. The first approach is to create an editor widget and display
       
    93     it directly on top of the item. To do this you must reimplement
       
    94     createEditor() to provide an editor widget, setEditorData() to populate
       
    95     the editor with the data from the model, and setModelData() so that the
       
    96     delegate can update the model with data from the editor.
       
    97 
       
    98     The second approach is to handle user events directly by reimplementing
       
    99     editorEvent().
       
   100 
       
   101     \sa {model-view-programming}{Model/View Programming}, QItemDelegate,
       
   102         {Pixelator Example}, QStyledItemDelegate, QStyle
       
   103 */
       
   104 
       
   105 /*!
       
   106     \enum QAbstractItemDelegate::EndEditHint
       
   107 
       
   108     This enum describes the different hints that the delegate can give to the
       
   109     model and view components to make editing data in a model a comfortable
       
   110     experience for the user.
       
   111 
       
   112     \value NoHint           There is no recommended action to be performed.
       
   113 
       
   114     These hints let the delegate influence the behavior of the view:
       
   115 
       
   116     \value EditNextItem     The view should use the delegate to open an
       
   117                             editor on the next item in the view.
       
   118     \value EditPreviousItem The view should use the delegate to open an
       
   119                             editor on the previous item in the view.
       
   120 
       
   121     Note that custom views may interpret the concepts of next and previous
       
   122     differently.
       
   123 
       
   124     The following hints are most useful when models are used that cache
       
   125     data, such as those that manipulate data locally in order to increase
       
   126     performance or conserve network bandwidth.
       
   127 
       
   128     \value SubmitModelCache If the model caches data, it should write out
       
   129                             cached data to the underlying data store.
       
   130     \value RevertModelCache If the model caches data, it should discard
       
   131                             cached data and replace it with data from the
       
   132                             underlying data store.
       
   133 
       
   134     Although models and views should respond to these hints in appropriate
       
   135     ways, custom components may ignore any or all of them if they are not
       
   136     relevant.
       
   137 */
       
   138 
       
   139 /*!
       
   140   \fn void QAbstractItemDelegate::commitData(QWidget *editor)
       
   141 
       
   142   This signal must be emitted when the \a editor widget has completed
       
   143   editing the data, and wants to write it back into the model.
       
   144 */
       
   145 
       
   146 /*!
       
   147     \fn void QAbstractItemDelegate::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint)
       
   148 
       
   149     This signal is emitted when the user has finished editing an item using
       
   150     the specified \a editor.
       
   151 
       
   152     The \a hint provides a way for the delegate to influence how the model and
       
   153     view behave after editing is completed. It indicates to these components
       
   154     what action should be performed next to provide a comfortable editing
       
   155     experience for the user. For example, if \c EditNextItem is specified,
       
   156     the view should use a delegate to open an editor on the next item in the
       
   157     model.
       
   158 
       
   159     \sa EndEditHint
       
   160 */
       
   161 
       
   162 /*!
       
   163     \fn void QAbstractItemDelegate::sizeHintChanged(const QModelIndex &index)
       
   164     \since 4.4
       
   165 
       
   166     This signal must be emitted when the sizeHint() of \a index changed.
       
   167 
       
   168     Views automatically connect to this signal and relayout items as necessary.
       
   169 */
       
   170 
       
   171 
       
   172 /*!
       
   173     Creates a new abstract item delegate with the given \a parent.
       
   174 */
       
   175 QAbstractItemDelegate::QAbstractItemDelegate(QObject *parent)
       
   176     : QObject(parent)
       
   177 {
       
   178 
       
   179 }
       
   180 
       
   181 /*!
       
   182     \internal
       
   183 
       
   184     Creates a new abstract item delegate with the given \a parent.
       
   185 */
       
   186 QAbstractItemDelegate::QAbstractItemDelegate(QObjectPrivate &dd, QObject *parent)
       
   187     : QObject(dd, parent)
       
   188 {
       
   189 
       
   190 }
       
   191 
       
   192 /*!
       
   193     Destroys the abstract item delegate.
       
   194 */
       
   195 QAbstractItemDelegate::~QAbstractItemDelegate()
       
   196 {
       
   197 
       
   198 }
       
   199 
       
   200 /*!
       
   201     \fn void QAbstractItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const = 0;
       
   202 
       
   203     This pure abstract function must be reimplemented if you want to
       
   204     provide custom rendering. Use the \a painter and style \a option to
       
   205     render the item specified by the item \a index.
       
   206 
       
   207     If you reimplement this you must also reimplement sizeHint().
       
   208 */
       
   209 
       
   210 /*!
       
   211     \fn QSize QAbstractItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const = 0
       
   212 
       
   213     This pure abstract function must be reimplemented if you want to
       
   214     provide custom rendering. The options are specified by \a option
       
   215     and the model item by \a index.
       
   216 
       
   217     If you reimplement this you must also reimplement paint().
       
   218 */
       
   219 
       
   220 /*!
       
   221     Returns the editor to be used for editing the data item with the
       
   222     given \a index. Note that the index contains information about the
       
   223     model being used. The editor's parent widget is specified by \a parent,
       
   224     and the item options by \a option.
       
   225 
       
   226     The base implementation returns 0. If you want custom editing you
       
   227     will need to reimplement this function.
       
   228 
       
   229     The returned editor widget should have Qt::StrongFocus;
       
   230     otherwise, \l{QMouseEvent}s received by the widget will propagate
       
   231     to the view. The view's background will shine through unless the
       
   232     editor paints its own background (e.g., with
       
   233     \l{QWidget::}{setAutoFillBackground()}).
       
   234 
       
   235     \sa setModelData() setEditorData()
       
   236 */
       
   237 QWidget *QAbstractItemDelegate::createEditor(QWidget *,
       
   238                                              const QStyleOptionViewItem &,
       
   239                                              const QModelIndex &) const
       
   240 {
       
   241     return 0;
       
   242 }
       
   243 
       
   244 /*!
       
   245     Sets the contents of the given \a editor to the data for the item
       
   246     at the given \a index. Note that the index contains information
       
   247     about the model being used.
       
   248 
       
   249     The base implementation does nothing. If you want custom editing
       
   250     you will need to reimplement this function.
       
   251 
       
   252     \sa setModelData()
       
   253 */
       
   254 void QAbstractItemDelegate::setEditorData(QWidget *,
       
   255                                           const QModelIndex &) const
       
   256 {
       
   257     // do nothing
       
   258 }
       
   259 
       
   260 /*!
       
   261     Sets the data for the item at the given \a index in the \a model
       
   262     to the contents of the given \a editor.
       
   263 
       
   264     The base implementation does nothing. If you want custom editing
       
   265     you will need to reimplement this function.
       
   266 
       
   267     \sa setEditorData()
       
   268 */
       
   269 void QAbstractItemDelegate::setModelData(QWidget *,
       
   270                                          QAbstractItemModel *,
       
   271                                          const QModelIndex &) const
       
   272 {
       
   273     // do nothing
       
   274 }
       
   275 
       
   276 /*!
       
   277     Updates the geometry of the \a editor for the item with the given
       
   278     \a index, according to the rectangle specified in the \a option.
       
   279     If the item has an internal layout, the editor will be laid out
       
   280     accordingly. Note that the index contains information about the
       
   281     model being used.
       
   282 
       
   283     The base implementation does nothing. If you want custom editing
       
   284     you must reimplement this function.
       
   285 */
       
   286 void QAbstractItemDelegate::updateEditorGeometry(QWidget *,
       
   287                                                  const QStyleOptionViewItem &,
       
   288                                                  const QModelIndex &) const
       
   289 {
       
   290     // do nothing
       
   291 }
       
   292 
       
   293 /*!
       
   294     Whenever an event occurs, this function is called with the \a event
       
   295     \a model \a option and the \a index that corresponds to the item being edited.
       
   296 
       
   297     The base implementation returns false (indicating that it has not
       
   298     handled the event).
       
   299 */
       
   300 bool QAbstractItemDelegate::editorEvent(QEvent *,
       
   301                                         QAbstractItemModel *,
       
   302                                         const QStyleOptionViewItem &,
       
   303                                         const QModelIndex &)
       
   304 {
       
   305     // do nothing
       
   306     return false;
       
   307 }
       
   308 
       
   309 /*!
       
   310     \obsolete
       
   311 
       
   312     Use QFontMetrics::elidedText() instead.
       
   313 
       
   314     \oldcode
       
   315         QFontMetrics fm = ...
       
   316         QString str = QAbstractItemDelegate::elidedText(fm, width, mode, text);
       
   317     \newcode
       
   318         QFontMetrics fm = ...
       
   319         QString str = fm.elidedText(text, mode, width);
       
   320     \endcode
       
   321 */
       
   322 
       
   323 QString QAbstractItemDelegate::elidedText(const QFontMetrics &fontMetrics, int width,
       
   324                                           Qt::TextElideMode mode, const QString &text)
       
   325 {
       
   326     return fontMetrics.elidedText(text, mode, width);
       
   327 }
       
   328 
       
   329 /*!
       
   330     \since 4.3
       
   331     Whenever a help event occurs, this function is called with the \a event
       
   332     \a view \a option and the \a index that corresponds to the item where the
       
   333     event occurs.
       
   334 
       
   335     Returns true if the delegate can handle the event; otherwise returns false.
       
   336     A return value of true indicates that the data obtained using the index had
       
   337     the required role.
       
   338 
       
   339     For QEvent::ToolTip and QEvent::WhatsThis events that were handled successfully,
       
   340     the relevant popup may be shown depending on the user's system configuration.
       
   341 
       
   342     \sa QHelpEvent
       
   343 */
       
   344 // ### Qt 5: Make this a virtual non-slot function
       
   345 bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
       
   346                                       QAbstractItemView *view,
       
   347                                       const QStyleOptionViewItem &option,
       
   348                                       const QModelIndex &index)
       
   349 {
       
   350     Q_UNUSED(option);
       
   351 
       
   352     if (!event || !view)
       
   353         return false;
       
   354     switch (event->type()) {
       
   355 #ifndef QT_NO_TOOLTIP
       
   356     case QEvent::ToolTip: {
       
   357         QHelpEvent *he = static_cast<QHelpEvent*>(event);
       
   358         QVariant tooltip = index.data(Qt::ToolTipRole);
       
   359         if (qVariantCanConvert<QString>(tooltip)) {
       
   360             QToolTip::showText(he->globalPos(), tooltip.toString(), view);
       
   361             return true;
       
   362         }
       
   363         break;}
       
   364 #endif
       
   365 #ifndef QT_NO_WHATSTHIS
       
   366     case QEvent::QueryWhatsThis: {
       
   367         if (index.data(Qt::WhatsThisRole).isValid())
       
   368             return true;
       
   369         break; }
       
   370     case QEvent::WhatsThis: {
       
   371         QHelpEvent *he = static_cast<QHelpEvent*>(event);
       
   372         QVariant whatsthis = index.data(Qt::WhatsThisRole);
       
   373         if (qVariantCanConvert<QString>(whatsthis)) {
       
   374             QWhatsThis::showText(he->globalPos(), whatsthis.toString(), view);
       
   375             return true;
       
   376         }
       
   377         break ; }
       
   378 #endif
       
   379     default:
       
   380         break;
       
   381     }
       
   382     return false;
       
   383 }
       
   384 
       
   385 QT_END_NAMESPACE
       
   386 
       
   387 #endif // QT_NO_ITEMVIEWS