1 /*
2   This file is part of the Grantlee template system.
3 
4   Copyright (c) 2010 Stephen Kelly <steveire@gmail.com>
5 
6   This library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Lesser General Public
8   License as published by the Free Software Foundation; either version
9   2.1 of the Licence, or (at your option) any later version.
10 
11   This library is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   Lesser General Public License for more details.
15 
16   You should have received a copy of the GNU Lesser General Public
17   License along with this library.  If not, see <http://www.gnu.org/licenses/>.
18 
19 */
20 
21 #include "comboboxdelegate.h"
22 #include "comboboxdelegate_p.h"
23 
24 #include <QApplication>
25 #include <QDebug>
26 
ComboBoxEditorCreator(const QStringList & data,ComboBoxDelegate::Type type)27 ComboBoxEditorCreator::ComboBoxEditorCreator(const QStringList &data,
28                                              ComboBoxDelegate::Type type)
29     : QItemEditorCreatorBase(), m_data(data), m_type(type)
30 {
31 }
32 
~ComboBoxEditorCreator()33 ComboBoxEditorCreator::~ComboBoxEditorCreator() {}
34 
createWidget(QWidget * parent) const35 QWidget *ComboBoxEditorCreator::createWidget(QWidget *parent) const
36 {
37   ViewComboBox *vcb = new ViewComboBox(parent);
38   vcb->addItems(m_data);
39 
40   if (m_type == ComboBoxDelegate::Editable)
41     vcb->setEditable(true);
42 
43   return vcb;
44 }
45 
valuePropertyName() const46 QByteArray ComboBoxEditorCreator::valuePropertyName() const
47 {
48   return QByteArray("choice");
49 }
50 
ViewComboBox(QWidget * parent)51 ViewComboBox::ViewComboBox(QWidget *parent) : QComboBox(parent) {}
52 
choice() const53 QString ViewComboBox::choice() const { return currentText(); }
54 
setChoice(const QString & choice)55 void ViewComboBox::setChoice(const QString &choice)
56 {
57   const int index = findData(choice, Qt::DisplayRole, Qt::MatchFixedString);
58   if (index >= 0)
59     setCurrentIndex(index);
60   else
61     setEditText(choice);
62 }
63 
ComboBoxDelegate(const QStringList & data,Type type,QObject * parent)64 ComboBoxDelegate::ComboBoxDelegate(const QStringList &data, Type type,
65                                    QObject *parent)
66     : QItemDelegate(parent)
67 {
68   QItemEditorFactory *factory = new QItemEditorFactory;
69   QItemEditorCreatorBase *creator = new ComboBoxEditorCreator(data, type);
70   factory->registerEditor(QVariant::String, creator);
71 
72   setItemEditorFactory(factory);
73 }
74 
createEditor(QWidget * parent,const QStyleOptionViewItem & option,const QModelIndex & index) const75 QWidget *ComboBoxDelegate::createEditor(QWidget *parent,
76                                         const QStyleOptionViewItem &option,
77                                         const QModelIndex &index) const
78 {
79   QWidget *w = QItemDelegate::createEditor(parent, option, index);
80   ViewComboBox *viewComboBox = qobject_cast<ViewComboBox *>(w);
81   Q_ASSERT(viewComboBox);
82   return viewComboBox;
83 }
84 
textSize(const QFont & font,const QString & text)85 static QSize textSize(const QFont &font, const QString &text)
86 {
87   QFontMetrics fm(font);
88   QSize size = fm.size(Qt::TextSingleLine, text);
89   const int textMargin
90       = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
91   return QSize(size.width() + 2 * textMargin, size.height());
92 }
93 
sizeHint(const QStyleOptionViewItem & option,const QModelIndex & index) const94 QSize ComboBoxDelegate::sizeHint(const QStyleOptionViewItem &option,
95                                  const QModelIndex &index) const
96 {
97   if (m_sizes.contains(index.row())) {
98     return m_sizes.value(index.row());
99   }
100   QSize sz;
101   QVariant fontData = index.data(Qt::FontRole);
102   QFont fnt = qvariant_cast<QFont>(fontData).resolve(option.font);
103   for (int i = 0; i < sizeof sTypes / sizeof *sTypes; ++i) {
104     QString text = *(sTypes + i);
105     QSize s = textSize(fnt, text);
106     sz = sz.expandedTo(s);
107   }
108 
109   QStyleOptionComboBox opt;
110   opt.editable = true;
111   opt.frame = true;
112   opt.currentText = index.data().toString();
113 
114   sz = qApp->style()->sizeFromContents(QStyle::CT_ComboBox, &opt, sz);
115   m_sizes.insert(index.row(), sz);
116 
117   return sz;
118 }
119 
120 #include "moc_comboboxdelegate_p.cpp"
121