source: subsurface/desktop-widgets/modeldelegates.cpp @ 99351b7

Last change on this file since 99351b7 was 99351b7, checked in by Dirk Hohndel <dirk@…>, 7 months ago

Allow cylinder names to be edited

The same ComboBoxDelegate? is used for picking a cylinder model
and picking a gas in the planner waypoint table. In the former
case we want to allow the user to edit the string in the second
we don't.

The difference is not if we are in the planner but which use of
the class. So add a bool allowEdit to the constructor.

Fixes #272

Signed-off-by: Robert C. Helling <helling@…>

  • Property mode set to 100644
File size: 20.3 KB
Line 
1#include "desktop-widgets/modeldelegates.h"
2#include "core/dive.h"
3#include "core/gettextfromc.h"
4#include "desktop-widgets/mainwindow.h"
5#include "qt-models/cylindermodel.h"
6#include "qt-models/models.h"
7#include "desktop-widgets/starwidget.h"
8#include "profile-widget/profilewidget2.h"
9#include "qt-models/tankinfomodel.h"
10#include "qt-models/weigthsysteminfomodel.h"
11#include "qt-models/weightmodel.h"
12#include "qt-models/divetripmodel.h"
13#include "core/qthelper.h"
14#ifndef NO_MARBLE
15#include "desktop-widgets/globe.h"
16#endif
17
18#include <QCompleter>
19#include <QKeyEvent>
20#include <QTextDocument>
21#include <QApplication>
22#include <QFont>
23#include <QBrush>
24#include <QColor>
25#include <QAbstractProxyModel>
26
27QSize DiveListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
28{
29        Q_UNUSED(option)
30        Q_UNUSED(index)
31        return QSize(50, 22);
32}
33
34// Gets the index of the model in the currentRow and column.
35// currCombo is defined below.
36#define IDX(_XX) mymodel->index(currCombo.currRow, (_XX))
37static bool keyboardFinished = false;
38
39StarWidgetsDelegate::StarWidgetsDelegate(QWidget *parent) : QStyledItemDelegate(parent),
40        parentWidget(parent)
41{
42        const IconMetrics& metrics = defaultIconMetrics();
43        minStarSize = QSize(metrics.sz_small * TOTALSTARS + metrics.spacing * (TOTALSTARS - 1), metrics.sz_small);
44}
45
46void StarWidgetsDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
47{
48        QStyledItemDelegate::paint(painter, option, index);
49        if (!index.isValid())
50                return;
51
52        QVariant value = index.model()->data(index, DiveTripModel::STAR_ROLE);
53        if (!value.isValid())
54                return;
55
56        int rating = value.toInt();
57        int deltaY = option.rect.height() / 2 - StarWidget::starActive().height() / 2;
58        painter->save();
59        painter->setRenderHint(QPainter::Antialiasing, true);
60        const QPixmap active = QPixmap::fromImage(StarWidget::starActive());
61        const QPixmap inactive = QPixmap::fromImage(StarWidget::starInactive());
62        const IconMetrics& metrics = defaultIconMetrics();
63
64        for (int i = 0; i < rating; i++)
65                painter->drawPixmap(option.rect.x() + i * metrics.sz_small + metrics.spacing, option.rect.y() + deltaY, active);
66        for (int i = rating; i < TOTALSTARS; i++)
67                painter->drawPixmap(option.rect.x() + i * metrics.sz_small + metrics.spacing, option.rect.y() + deltaY, inactive);
68        painter->restore();
69}
70
71QSize StarWidgetsDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
72{
73        Q_UNUSED(option)
74        Q_UNUSED(index)
75        return minStarSize;
76}
77
78const QSize& StarWidgetsDelegate::starSize() const
79{
80        return minStarSize;
81}
82
83ComboBoxDelegate::ComboBoxDelegate(QAbstractItemModel *model, QObject *parent, bool allowEdit) : QStyledItemDelegate(parent), model(model)
84{
85        editable = allowEdit;
86        connect(this, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)),
87                this, SLOT(revertModelData(QWidget *, QAbstractItemDelegate::EndEditHint)));
88        connect(this, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)),
89                this, SLOT(fixTabBehavior()));
90}
91
92void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
93{
94        QComboBox *c = qobject_cast<QComboBox *>(editor);
95        QString data = index.model()->data(index, Qt::DisplayRole).toString();
96        int i = c->findText(data);
97        if (i != -1)
98                c->setCurrentIndex(i);
99        else
100                c->setEditText(data);
101        c->lineEdit()->setSelection(0, c->lineEdit()->text().length());
102}
103
104struct CurrSelected {
105        QComboBox *comboEditor;
106        int currRow;
107        QString activeText;
108        QAbstractItemModel *model;
109        bool ignoreSelection;
110} currCombo;
111
112QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
113{
114        Q_UNUSED(option)
115        MainWindow *m = MainWindow::instance();
116        QComboBox *comboDelegate = new QComboBox(parent);
117        comboDelegate->setModel(model);
118        comboDelegate->setEditable(true);
119        comboDelegate->setAutoCompletion(true);
120        comboDelegate->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive);
121        comboDelegate->completer()->setCompletionMode(QCompleter::PopupCompletion);
122        comboDelegate->view()->setEditTriggers(QAbstractItemView::AllEditTriggers);
123        comboDelegate->lineEdit()->installEventFilter(const_cast<QObject *>(qobject_cast<const QObject *>(this)));
124        comboDelegate->lineEdit()->setEnabled(editable);
125        comboDelegate->view()->installEventFilter(const_cast<QObject *>(qobject_cast<const QObject *>(this)));
126        QAbstractItemView *comboPopup = comboDelegate->lineEdit()->completer()->popup();
127        comboPopup->setMouseTracking(true);
128        connect(comboDelegate, SIGNAL(highlighted(QString)), this, SLOT(testActivation(QString)));
129        connect(comboDelegate, SIGNAL(activated(QString)), this, SLOT(fakeActivation()));
130        connect(comboPopup, SIGNAL(entered(QModelIndex)), this, SLOT(testActivation(QModelIndex)));
131        connect(comboPopup, SIGNAL(activated(QModelIndex)), this, SLOT(fakeActivation()));
132        currCombo.comboEditor = comboDelegate;
133        currCombo.currRow = index.row();
134        currCombo.model = const_cast<QAbstractItemModel *>(index.model());
135        keyboardFinished = false;
136
137        // Current display of things on Gnome3 looks like shit, so
138        // let`s fix that.
139        if (isGnome3Session()) {
140                QPalette p;
141                p.setColor(QPalette::Window, QColor(Qt::white));
142                p.setColor(QPalette::Base, QColor(Qt::white));
143                comboDelegate->lineEdit()->setPalette(p);
144                comboDelegate->setPalette(p);
145        }
146        return comboDelegate;
147}
148
149/* This Method is being called when the user *writes* something and press enter or tab,
150 * and it`s also called when the mouse walks over the list of choices from the ComboBox,
151 * One thing is important, if the user writes a *new* cylinder or weight type, it will
152 * be ADDED to the list, and the user will need to fill the other data.
153 */
154void ComboBoxDelegate::testActivation(const QString &currText)
155{
156        currCombo.activeText = currText.isEmpty() ? currCombo.comboEditor->currentText() : currText;
157        setModelData(currCombo.comboEditor, currCombo.model, QModelIndex());
158}
159
160void ComboBoxDelegate::testActivation(const QModelIndex &currIndex)
161{
162        testActivation(currIndex.data().toString());
163}
164
165// HACK, send a fake event so Qt thinks we hit 'enter' on the line edit.
166void ComboBoxDelegate::fakeActivation()
167{
168        /* this test is needed because as soon as I show the selector,
169         * the first item gots selected, this sending an activated signal,
170         * calling this fakeActivation code and setting as the current,
171         * thig that we don't want. so, let's just set the ignoreSelection
172         * to false and be happy, because the next activation  ( by click
173         * or keypress) is real.
174         */
175        if (currCombo.ignoreSelection) {
176                currCombo.ignoreSelection = false;
177                return;
178        }
179        QKeyEvent ev(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
180        QStyledItemDelegate::eventFilter(currCombo.comboEditor, &ev);
181}
182
183// This 'reverts' the model data to what we actually choosed,
184// becaus e a TAB is being understood by Qt as 'cancel' while
185// we are on a QComboBox ( but not on a QLineEdit.
186void ComboBoxDelegate::fixTabBehavior()
187{
188        if (keyboardFinished) {
189                setModelData(0, 0, QModelIndex());
190        }
191}
192
193bool ComboBoxDelegate::eventFilter(QObject *object, QEvent *event)
194{
195        // Reacts on Key_UP and Key_DOWN to show the QComboBox - list of choices.
196        if (event->type() == QEvent::KeyPress || event->type() == QEvent::ShortcutOverride) {
197                if (object == currCombo.comboEditor) { // the 'LineEdit' part
198                        QKeyEvent *ev = static_cast<QKeyEvent *>(event);
199                        if (ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down) {
200                                currCombo.ignoreSelection = true;
201                                if (!currCombo.comboEditor->completer()->popup()->isVisible()) {
202                                        currCombo.comboEditor->showPopup();
203                                        return true;
204                                }
205                        }
206                        if (ev->key() == Qt::Key_Tab || ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return) {
207                                currCombo.activeText = currCombo.comboEditor->currentText();
208                                keyboardFinished = true;
209                        }
210                } else { // the 'Drop Down Menu' part.
211                        QKeyEvent *ev = static_cast<QKeyEvent *>(event);
212                        if (ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return ||
213                            ev->key() == Qt::Key_Tab || ev->key() == Qt::Key_Backtab ||
214                            ev->key() == Qt::Key_Escape) {
215                                // treat Qt as a silly little boy - pretending that the key_return nwas pressed on the combo,
216                                // instead of the list of choices. this can be extended later for
217                                // other imputs, like tab navigation and esc.
218                                QStyledItemDelegate::eventFilter(currCombo.comboEditor, event);
219                        }
220                }
221        }
222
223        return QStyledItemDelegate::eventFilter(object, event);
224}
225
226void ComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
227{
228        Q_UNUSED(index)
229        QRect defaultRect = option.rect;
230        defaultRect.setX(defaultRect.x() - 1);
231        defaultRect.setY(defaultRect.y() - 1);
232        defaultRect.setWidth(defaultRect.width() + 2);
233        defaultRect.setHeight(defaultRect.height() + 2);
234        editor->setGeometry(defaultRect);
235}
236
237struct RevertCylinderData {
238        QString type;
239        int pressure;
240        int size;
241} currCylinderData;
242
243void TankInfoDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &thisindex) const
244{
245        Q_UNUSED(model)
246        Q_UNUSED(editor)
247        Q_UNUSED(thisindex)
248
249        CylindersModel *mymodel = qobject_cast<CylindersModel *>(currCombo.model);
250        TankInfoModel *tanks = TankInfoModel::instance();
251        QModelIndexList matches = tanks->match(tanks->index(0, 0), Qt::DisplayRole, currCombo.activeText);
252        int row;
253        QString cylinderName = currCombo.activeText;
254        if (matches.isEmpty()) {
255                tanks->insertRows(tanks->rowCount(), 1);
256                tanks->setData(tanks->index(tanks->rowCount() - 1, 0), currCombo.activeText);
257                row = tanks->rowCount() - 1;
258        } else {
259                row = matches.first().row();
260                cylinderName = matches.first().data().toString();
261        }
262        int tankSize = tanks->data(tanks->index(row, TankInfoModel::ML)).toInt();
263        int tankPressure = tanks->data(tanks->index(row, TankInfoModel::BAR)).toInt();
264
265        mymodel->setData(IDX(CylindersModel::TYPE), cylinderName, Qt::EditRole);
266        mymodel->passInData(IDX(CylindersModel::WORKINGPRESS), tankPressure);
267        mymodel->passInData(IDX(CylindersModel::SIZE), tankSize);
268}
269
270TankInfoDelegate::TankInfoDelegate(QObject *parent) : ComboBoxDelegate(TankInfoModel::instance(), parent, true)
271{
272        connect(this, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)),
273                this, SLOT(reenableReplot(QWidget *, QAbstractItemDelegate::EndEditHint)));
274}
275
276void TankInfoDelegate::reenableReplot(QWidget *widget, QAbstractItemDelegate::EndEditHint hint)
277{
278        Q_UNUSED(widget)
279        Q_UNUSED(hint)
280        MainWindow::instance()->graphics()->setReplot(true);
281        // FIXME: We need to replot after a cylinder is selected but the replot below overwrites
282        //        the newly selected cylinder.
283        //      MainWindow::instance()->graphics()->replot();
284}
285
286void TankInfoDelegate::revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint)
287{
288        Q_UNUSED(widget)
289        if (hint == QAbstractItemDelegate::NoHint ||
290            hint == QAbstractItemDelegate::RevertModelCache) {
291                CylindersModel *mymodel = qobject_cast<CylindersModel *>(currCombo.model);
292                mymodel->setData(IDX(CylindersModel::TYPE), currCylinderData.type, Qt::EditRole);
293                mymodel->passInData(IDX(CylindersModel::WORKINGPRESS), currCylinderData.pressure);
294                mymodel->passInData(IDX(CylindersModel::SIZE), currCylinderData.size);
295        }
296}
297
298QWidget *TankInfoDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
299{
300        // ncreate editor needs to be called before because it will populate a few
301        // things in the currCombo global var.
302        QWidget *delegate = ComboBoxDelegate::createEditor(parent, option, index);
303        CylindersModel *mymodel = qobject_cast<CylindersModel *>(currCombo.model);
304        cylinder_t *cyl = mymodel->cylinderAt(index);
305        currCylinderData.type = copy_string(cyl->type.description);
306        currCylinderData.pressure = cyl->type.workingpressure.mbar;
307        currCylinderData.size = cyl->type.size.mliter;
308        MainWindow::instance()->graphics()->setReplot(false);
309        return delegate;
310}
311
312TankUseDelegate::TankUseDelegate(QObject *parent) : QStyledItemDelegate(parent)
313{
314}
315
316QWidget *TankUseDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const
317{
318        Q_UNUSED(option)
319        Q_UNUSED(index)
320        QComboBox *comboBox = new QComboBox(parent);
321        for (int i = 0; i < NUM_GAS_USE; i++)
322                comboBox->addItem(gettextFromC::instance()->trGettext(cylinderuse_text[i]));
323        return comboBox;
324}
325
326void TankUseDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const
327{
328        QComboBox *comboBox = qobject_cast<QComboBox*>(editor);
329        QString indexString = index.data().toString();
330        comboBox->setCurrentIndex(cylinderuse_from_text(indexString.toUtf8().data()));
331}
332
333void TankUseDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const
334{
335        QComboBox *comboBox = qobject_cast<QComboBox*>(editor);
336        model->setData(index, comboBox->currentIndex());
337}
338
339struct RevertWeightData {
340        QString type;
341        int weight;
342} currWeight;
343
344void WSInfoDelegate::revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint)
345{
346        Q_UNUSED(widget)
347        if (hint == QAbstractItemDelegate::NoHint ||
348            hint == QAbstractItemDelegate::RevertModelCache) {
349                WeightModel *mymodel = qobject_cast<WeightModel *>(currCombo.model);
350                mymodel->setData(IDX(WeightModel::TYPE), currWeight.type, Qt::EditRole);
351                mymodel->passInData(IDX(WeightModel::WEIGHT), currWeight.weight);
352        }
353}
354
355void WSInfoDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &thisindex) const
356{
357        Q_UNUSED(editor)
358        Q_UNUSED(model)
359        Q_UNUSED(thisindex)
360
361        WeightModel *mymodel = qobject_cast<WeightModel *>(currCombo.model);
362        WSInfoModel *wsim = WSInfoModel::instance();
363        QModelIndexList matches = wsim->match(wsim->index(0, 0), Qt::DisplayRole, currCombo.activeText);
364        int row;
365        if (matches.isEmpty()) {
366                // we need to add this puppy
367                wsim->insertRows(wsim->rowCount(), 1);
368                wsim->setData(wsim->index(wsim->rowCount() - 1, 0), currCombo.activeText);
369                row = wsim->rowCount() - 1;
370        } else {
371                row = matches.first().row();
372        }
373        int grams = wsim->data(wsim->index(row, WSInfoModel::GR)).toInt();
374        QVariant v = QString(currCombo.activeText);
375
376        mymodel->setData(IDX(WeightModel::TYPE), v, Qt::EditRole);
377        mymodel->passInData(IDX(WeightModel::WEIGHT), grams);
378}
379
380WSInfoDelegate::WSInfoDelegate(QObject *parent) : ComboBoxDelegate(WSInfoModel::instance(), parent, false)
381{
382}
383
384QWidget *WSInfoDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
385{
386        /* First, call the combobox-create editor, it will setup our globals. */
387        QWidget *editor = ComboBoxDelegate::createEditor(parent, option, index);
388        WeightModel *mymodel = qobject_cast<WeightModel *>(currCombo.model);
389        weightsystem_t *ws = mymodel->weightSystemAt(index);
390        currWeight.type = copy_string(ws->description);
391        currWeight.weight = ws->weight.grams;
392        return editor;
393}
394
395void AirTypesDelegate::revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint)
396{
397        Q_UNUSED(widget)
398        Q_UNUSED(hint)
399}
400
401void AirTypesDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
402{
403        if (!index.isValid())
404                return;
405        QComboBox *combo = qobject_cast<QComboBox *>(editor);
406        model->setData(index, QVariant(combo->currentIndex()));
407}
408
409AirTypesDelegate::AirTypesDelegate(QObject *parent) : ComboBoxDelegate(GasSelectionModel::instance(), parent, false)
410{
411}
412
413SpinBoxDelegate::SpinBoxDelegate(int min, int max, int step, QObject *parent):
414        QStyledItemDelegate(parent),
415        min(min),
416        max(max),
417        step(step)
418{
419}
420
421QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
422{
423        QSpinBox *w = qobject_cast<QSpinBox*>(QStyledItemDelegate::createEditor(parent, option, index));
424        w->setRange(min,max);
425        w->setSingleStep(step);
426        return w;
427}
428
429DoubleSpinBoxDelegate::DoubleSpinBoxDelegate(double min, double max, double step, QObject *parent):
430        QStyledItemDelegate(parent),
431        min(min),
432        max(max),
433        step(step)
434{
435}
436
437QWidget *DoubleSpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
438{
439        QDoubleSpinBox *w = qobject_cast<QDoubleSpinBox*>(QStyledItemDelegate::createEditor(parent, option, index));
440        w->setRange(min,max);
441        w->setSingleStep(step);
442        return w;
443}
444
445LocationFilterDelegate::LocationFilterDelegate(QObject *parent)
446{
447        Q_UNUSED(parent)
448}
449
450void LocationFilterDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &origIdx) const
451{
452        QFont fontBigger = qApp->font();
453        QFont fontSmaller = qApp->font();
454        QFontMetrics fmBigger(fontBigger);
455        QStyleOptionViewItemV4 opt = option;
456        const QAbstractProxyModel *proxyModel = dynamic_cast<const QAbstractProxyModel*>(origIdx.model());
457        QModelIndex index = proxyModel->mapToSource(origIdx);
458        QStyledItemDelegate::initStyleOption(&opt, index);
459        QString diveSiteName = index.data().toString();
460        QString bottomText;
461        QIcon icon = index.data(Qt::DecorationRole).value<QIcon>();
462        struct dive_site *ds = get_dive_site_by_uuid(
463                index.model()->data(index.model()->index(index.row(),0)).toInt()
464        );
465        //Special case: do not show name, but instead, show
466        if (index.row() < 2) {
467                diveSiteName = index.data().toString();
468                bottomText = index.data(Qt::ToolTipRole).toString();
469                goto print_part;
470        }
471
472        if (!ds)
473                return;
474
475        for (int i = 0; i < 3; i++) {
476                if (prefs.geocoding.category[i] == TC_NONE)
477                        continue;
478                int idx = taxonomy_index_for_category(&ds->taxonomy, prefs.geocoding.category[i]);
479                if (idx == -1)
480                        continue;
481                if(!bottomText.isEmpty())
482                        bottomText += " / ";
483                bottomText += QString(ds->taxonomy.category[idx].value);
484        }
485
486        if (bottomText.isEmpty()) {
487                const char *gpsCoords = printGPSCoords(ds->latitude.udeg, ds->longitude.udeg);
488                bottomText = QString(gpsCoords);
489                free( (void*) gpsCoords);
490        }
491
492        if (dive_site_has_gps_location(ds) && dive_site_has_gps_location(&displayed_dive_site)) {
493                // so we are showing a completion and both the current dive site and the completion
494                // have a GPS fix... so let's show the distance
495                if (ds->latitude.udeg == displayed_dive_site.latitude.udeg &&
496                    ds->longitude.udeg == displayed_dive_site.longitude.udeg) {
497                        bottomText += tr(" (same GPS fix)");
498                } else {
499                        int distanceMeters = get_distance(ds->latitude, ds->longitude, displayed_dive_site.latitude, displayed_dive_site.longitude);
500                        QString distance = distance_string(distanceMeters);
501                        int nr = nr_of_dives_at_dive_site(ds->uuid, false);
502                        bottomText += tr(" (~%1 away").arg(distance);
503                        bottomText += tr(", %n dive(s) here)", "", nr);
504                }
505        }
506        if (bottomText.isEmpty()) {
507                if (dive_site_has_gps_location(&displayed_dive_site))
508                        bottomText = tr("(no existing GPS data, add GPS fix from this dive)");
509                else
510                        bottomText = tr("(no GPS data)");
511        }
512        bottomText = tr("Pick site: ") + bottomText;
513
514print_part:
515
516        fontBigger.setPointSize(fontBigger.pointSize() + 1);
517        fontBigger.setBold(true);
518        QPen textPen = QPen(option.state & QStyle::State_Selected ? option.palette.highlightedText().color() : option.palette.text().color(), 1);
519
520        initStyleOption(&opt, index);
521        opt.text = QString();
522        opt.icon = QIcon();
523        painter->setClipRect(option.rect);
524
525        painter->save();
526        if (option.state & QStyle::State_Selected) {
527                painter->setPen(QPen(opt.palette.highlight().color().darker()));
528                painter->setBrush(opt.palette.highlight());
529                const int pad = 1;
530                const int pad2 = pad * 2;
531                const int rounding = 5;
532                painter->drawRoundedRect(option.rect.x() + pad,
533                                        option.rect.y() + pad,
534                                        option.rect.width() - pad2,
535                                        option.rect.height() - pad2,
536                                        rounding, rounding);
537        }
538        painter->setPen(textPen);
539        painter->setFont(fontBigger);
540        const int textPad = 5;
541        painter->drawText(option.rect.x() + textPad, option.rect.y() + fmBigger.boundingRect("YH").height(), diveSiteName);
542        double pointSize = fontSmaller.pointSizeF();
543        fontSmaller.setPointSizeF(0.9 * pointSize);
544        painter->setFont(fontSmaller);
545        painter->drawText(option.rect.x() + textPad, option.rect.y() + fmBigger.boundingRect("YH").height() * 2, bottomText);
546        painter->restore();
547
548        if (!icon.isNull()) {
549                painter->save();
550                painter->drawPixmap(
551                        option.rect.x() + option.rect.width() - 24,
552                        option.rect.y() + option.rect.height() - 24, icon.pixmap(20,20));
553                painter->restore();
554        }
555}
556
557QSize LocationFilterDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
558{
559        QFont fontBigger = qApp->font();
560        fontBigger.setPointSize(fontBigger.pointSize());
561        fontBigger.setBold(true);
562
563        QFontMetrics fmBigger(fontBigger);
564
565        QFont fontSmaller = qApp->font();
566        QFontMetrics fmSmaller(fontSmaller);
567
568        QSize retSize = QStyledItemDelegate::sizeHint(option, index);
569        retSize.setHeight(
570                fmBigger.boundingRect("Yellow House").height() + 5 /*spacing*/ +
571                fmSmaller.boundingRect("Yellow House").height());
572
573        return retSize;
574}
Note: See TracBrowser for help on using the repository browser.