Qt 4.8
qfontcombobox.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qfontcombobox.h"
43 
44 #ifndef QT_NO_FONTCOMBOBOX
45 
46 #include <qstringlistmodel.h>
47 #include <qitemdelegate.h>
48 #include <qlistview.h>
49 #include <qpainter.h>
50 #include <qevent.h>
51 #include <qapplication.h>
52 #include <private/qcombobox_p.h>
53 #include <qdebug.h>
54 
56 
57 static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool *hasLatin)
58 {
59  *hasLatin = true;
60 
62 // qDebug() << font.family() << writingSystems;
63 
64  // this just confuses the algorithm below. Vietnamese is Latin with lots of special chars
65  writingSystems.removeAll(QFontDatabase::Vietnamese);
66 
68 
69  if (!writingSystems.contains(QFontDatabase::Latin)) {
70  *hasLatin = false;
71  // we need to show something
72  if (writingSystems.count())
73  system = writingSystems.last();
74  } else {
75  writingSystems.removeAll(QFontDatabase::Latin);
76  }
77 
78  if (writingSystems.isEmpty())
79  return system;
80 
81  if (writingSystems.count() == 1 && writingSystems.at(0) > QFontDatabase::Cyrillic) {
82  system = writingSystems.at(0);
83  return system;
84  }
85 
86  if (writingSystems.count() <= 2
87  && writingSystems.last() > QFontDatabase::Armenian
88  && writingSystems.last() < QFontDatabase::Vietnamese) {
89  system = writingSystems.last();
90  return system;
91  }
92 
93  if (writingSystems.count() <= 5
94  && writingSystems.last() >= QFontDatabase::SimplifiedChinese
95  && writingSystems.last() <= QFontDatabase::Korean)
96  system = writingSystems.last();
97 
98  return system;
99 }
100 
102 {
103  Q_OBJECT
104 public:
106 
107  // painting
108  void paint(QPainter *painter,
109  const QStyleOptionViewItem &option,
110  const QModelIndex &index) const;
111 
112  QSize sizeHint(const QStyleOptionViewItem &option,
113  const QModelIndex &index) const;
114 
118 };
119 
121  : QAbstractItemDelegate(parent)
122 {
123  truetype = QIcon(QLatin1String(":/trolltech/styles/commonstyle/images/fonttruetype-16.png"));
124  bitmap = QIcon(QLatin1String(":/trolltech/styles/commonstyle/images/fontbitmap-16.png"));
126 }
127 
129  const QStyleOptionViewItem &option,
130  const QModelIndex &index) const
131 {
133  QFont font(option.font);
134  font.setPointSize(QFontInfo(font).pointSize() * 3 / 2);
135  QFont font2 = font;
136  font2.setFamily(text);
137 
138  bool hasLatin;
139  QFontDatabase::WritingSystem system = writingSystemForFont(font2, &hasLatin);
140  if (hasLatin)
141  font = font2;
142 
143  QRect r = option.rect;
144 
145  if (option.state & QStyle::State_Selected) {
146  painter->save();
147  painter->setBrush(option.palette.highlight());
148  painter->setPen(Qt::NoPen);
149  painter->drawRect(option.rect);
150  painter->setPen(QPen(option.palette.highlightedText(), 0));
151  }
152 
153  const QIcon *icon = &bitmap;
154  if (QFontDatabase().isSmoothlyScalable(text)) {
155  icon = &truetype;
156  }
157  QSize actualSize = icon->actualSize(r.size());
158 
159  icon->paint(painter, r, Qt::AlignLeft|Qt::AlignVCenter);
160  if (option.direction == Qt::RightToLeft)
161  r.setRight(r.right() - actualSize.width() - 4);
162  else
163  r.setLeft(r.left() + actualSize.width() + 4);
164 
165  QFont old = painter->font();
166  painter->setFont(font);
167 
168  // If the ascent of the font is larger than the height of the rect,
169  // we will clip the text, so it's better to align the tight bounding rect in this case
170  // This is specifically for fonts where the ascent is very large compared to
171  // the descent, like certain of the Stix family.
172  QFontMetricsF fontMetrics(font);
173  if (fontMetrics.ascent() > r.height()) {
174  QRectF tbr = fontMetrics.tightBoundingRect(text);
175  painter->drawText(r.x(), r.y() + (r.height() + tbr.height()) / 2.0, text);
176  } else {
178  }
179 
181  system = writingSystem;
182 
183  if (system != QFontDatabase::Any) {
184  int w = painter->fontMetrics().width(text + QLatin1String(" "));
185  painter->setFont(font2);
186  QString sample = QFontDatabase().writingSystemSample(system);
187  if (option.direction == Qt::RightToLeft)
188  r.setRight(r.right() - w);
189  else
190  r.setLeft(r.left() + w);
192  }
193  painter->setFont(old);
194 
195  if (option.state & QStyle::State_Selected)
196  painter->restore();
197 
198 }
199 
201  const QModelIndex &index) const
202 {
204  QFont font(option.font);
205 // font.setFamily(text);
206  font.setPointSize(QFontInfo(font).pointSize() * 3/2);
207  QFontMetrics fontMetrics(font);
208  return QSize(fontMetrics.width(text), fontMetrics.height());
209 }
210 
211 
213 {
214 public:
216 
217  QFontComboBox::FontFilters filters;
219 
220  void _q_updateModel();
221  void _q_currentChanged(const QString &);
222 
224 };
225 
226 
228 {
232 
233  QStringListModel *m = qobject_cast<QStringListModel *>(q->model());
234  if (!m)
235  return;
236  QFontFamilyDelegate *delegate = qobject_cast<QFontFamilyDelegate *>(q->view()->itemDelegate());
237  QFontDatabase::WritingSystem system = delegate ? delegate->writingSystem : QFontDatabase::Any;
238 
239  QFontDatabase fdb;
240  QStringList list = fdb.families(system);
241  QStringList result;
242 
243  int offset = 0;
244  QFontInfo fi(currentFont);
245 
246  for (int i = 0; i < list.size(); ++i) {
247  if ((filters & scalableMask) && (filters & scalableMask) != scalableMask) {
248  if (bool(filters & QFontComboBox::ScalableFonts) != fdb.isSmoothlyScalable(list.at(i)))
249  continue;
250  }
251  if ((filters & spacingMask) && (filters & spacingMask) != spacingMask) {
252  if (bool(filters & QFontComboBox::MonospacedFonts) != fdb.isFixedPitch(list.at(i)))
253  continue;
254  }
255  result += list.at(i);
256  if (list.at(i) == fi.family() || list.at(i).startsWith(fi.family() + QLatin1String(" [")))
257  offset = result.count() - 1;
258  }
259  list = result;
260 
261  //we need to block the signals so that the model doesn't emit reset
262  //this prevents the current index from changing
263  //it will be updated just after this
265  const bool old = m->blockSignals(true);
266  m->setStringList(list);
267  m->blockSignals(old);
268 
269  if (list.isEmpty()) {
270  if (currentFont != QFont()) {
271  currentFont = QFont();
272  emit q->currentFontChanged(currentFont);
273  }
274  } else {
275  q->setCurrentIndex(offset);
276  }
277 }
278 
279 
281 {
283  if (currentFont.family() != text) {
284  currentFont.setFamily(text);
285  emit q->currentFontChanged(currentFont);
286  }
287 }
288 
336  : QComboBox(*new QFontComboBoxPrivate, parent)
337 {
339  d->currentFont = font();
340  setEditable(true);
341 
342  QStringListModel *m = new QStringListModel(this);
343  setModel(m);
345  QListView *lview = qobject_cast<QListView*>(view());
346  if (lview)
347  lview->setUniformItemSizes(true);
349 
351  this, SLOT(_q_currentChanged(QString)));
352 
353  connect(qApp, SIGNAL(fontDatabaseChanged()),
354  this, SLOT(_q_updateModel()));
355 }
356 
357 
362 {
363 }
364 
379 {
382  if (delegate)
383  delegate->writingSystem = script;
384  d->_q_updateModel();
385 }
386 
388 {
390  if (delegate)
391  return delegate->writingSystem;
392  return QFontDatabase::Any;
393 }
394 
395 
423 {
425  d->filters = filters;
426  d->_q_updateModel();
427 }
428 
429 QFontComboBox::FontFilters QFontComboBox::fontFilters() const
430 {
431  Q_D(const QFontComboBox);
432  return d->filters;
433 }
434 
445 {
446  Q_D(const QFontComboBox);
447  return d->currentFont;
448 }
449 
451 {
453  if (font != d->currentFont) {
454  d->currentFont = font;
455  d->_q_updateModel();
456  if (d->currentFont == font) { //else the signal has already be emitted by _q_updateModel
457  emit currentFontChanged(d->currentFont);
458  }
459  }
460 }
461 
478 {
479  if (e->type() == QEvent::Resize) {
480  QListView *lview = qobject_cast<QListView*>(view());
481  if (lview)
482  lview->window()->setFixedWidth(width() * 5 / 3);
483  }
484  return QComboBox::event(e);
485 }
486 
491 {
492  QSize sz = QComboBox::sizeHint();
493  QFontMetrics fm(font());
494  sz.setWidth(fm.width(QLatin1Char('m'))*14);
495  return sz;
496 }
497 
499 
500 #include "qfontcombobox.moc"
501 #include "moc_qfontcombobox.cpp"
502 
503 #endif // QT_NO_FONTCOMBOBOX
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
void currentFontChanged(const QFont &f)
This signal is emitted whenever the current font changes, with the new font.
double d
Definition: qnumeric_p.h:62
void setPointSize(int)
Sets the point size to pointSize.
Definition: qfont.cpp:1099
bool event(QEvent *event)
Reimplemented Function
Definition: qcombobox.cpp:2940
const QBrush & highlight() const
Returns the highlight brush of the current color group.
Definition: qpalette.h:140
The QAbstractItemDelegate class is used to display and edit data items from a model.
int width(const QString &, int len=-1) const
Returns the width in pixels of the first len characters of text.
bool blockSignals(bool b)
If block is true, signals emitted by this object are blocked (i.e., emitting a signal will not invoke...
Definition: qobject.cpp:1406
QFontComboBox(QWidget *parent=0)
Constructs a font combobox with the given parent.
QFont font
the font used for the item
Definition: qstyleoption.h:552
The QFontMetrics class provides font metrics information.
Definition: qfontmetrics.h:65
void setItemDelegate(QAbstractItemDelegate *delegate)
Sets the item delegate for the popup list view.
Definition: qcombobox.cpp:1954
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QFontFamilyDelegate(QObject *parent)
bool event(QEvent *e)
Reimplemented Function
qreal ascent() const
Returns the ascent of the font.
QVariant data(int role=Qt::DisplayRole) const
Returns the data for the given role for the item referred to by the index.
QStyle::State state
the style flags that are used when drawing the control
Definition: qstyleoption.h:88
#define SLOT(a)
Definition: qobjectdefs.h:226
void restore()
Restores the current painter state (pops a saved state off the stack).
Definition: qpainter.cpp:1620
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
This pure abstract function must be reimplemented if you want to provide custom rendering.
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
QSize sizeHint() const
Reimplemented Function
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
QRectF tightBoundingRect(const QString &text) const
Returns a tight bounding rectangle around the characters in the string specified by text...
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
void currentIndexChanged(int index)
This signal is sent whenever the currentIndex in the combobox changes either through user interaction...
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QFontComboBox widget is a combobox that lets the user select a font family.
Definition: qfontcombobox.h:58
static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool *hasLatin)
QList< WritingSystem > writingSystems() const
Returns a sorted list of the available writing systems.
void setCurrentFont(const QFont &f)
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
The QString class provides a Unicode character string.
Definition: qstring.h:83
QAbstractItemDelegate * itemDelegate() const
Returns the item delegate used by this view and model.
T * qobject_cast(QObject *object)
Definition: qobject.h:375
The QStringListModel class provides a model that supplies strings to views.
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
FontFilters fontFilters() const
#define Q_D(Class)
Definition: qglobal.h:2482
The QPen class defines how a QPainter should draw lines and outlines of shapes.
Definition: qpen.h:64
void setFontFilters(FontFilters filters)
void setUniformItemSizes(bool enable)
Definition: qlistview.cpp:1615
void save()
Saves the current painter state (pushes the state onto a stack).
Definition: qpainter.cpp:1590
void setFixedWidth(int w)
Sets both the minimum and maximum width of the widget to w without changing the heights.
Definition: qwidget.cpp:4368
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
#define Q_Q(Class)
Definition: qglobal.h:2483
void setFamily(const QString &)
Sets the family name of the font.
Definition: qfont.cpp:924
void setWidth(int w)
Sets the width to the given width.
Definition: qsize.h:132
#define SIGNAL(a)
Definition: qobjectdefs.h:227
int width() const
Returns the width.
Definition: qsize.h:126
void drawText(const QPointF &p, const QString &s)
Draws the given text with the currently defined text direction, beginning at the given position...
Definition: qpainter.cpp:6231
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QFontMetrics fontMetrics() const
Returns the font metrics for the painter if the painter is active.
Definition: qpainter.cpp:2077
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
~QFontComboBox()
Destroys the combobox.
QBool contains(const T &t) const
Returns true if the list contains an occurrence of value; otherwise returns false.
Definition: qlist.h:880
The QFontDatabase class provides information about the fonts available in the underlying window syste...
Definition: qfontdatabase.h:66
QStringList families(WritingSystem writingSystem=Any) const
Returns a sorted list of the available font families which support the writingSystem.
void setStringList(const QStringList &strings)
Sets the model&#39;s internal string list to strings.
void setEditable(bool editable)
Definition: qcombobox.cpp:1759
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
#define qApp
int width() const
const QFont & font() const
Returns the currently set font used for drawing text.
Definition: qpainter.cpp:4312
qreal height() const
Returns the height of the rectangle.
Definition: qrect.h:710
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
#define emit
Definition: qobjectdefs.h:76
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
void setRight(int pos)
Sets the right edge of the rectangle to the given x coordinate.
Definition: qrect.h:264
The QComboBox widget is a combined button and popup list.
Definition: qcombobox.h:62
void setWritingSystem(QFontDatabase::WritingSystem)
QFont currentFont() const
The QFontInfo class provides general information about fonts.
Definition: qfontinfo.h:54
Q_CORE_EXPORT int QT_FASTCALL script(uint ucs4)
#define Q_OBJECT
Definition: qobjectdefs.h:157
static QString writingSystemSample(WritingSystem writingSystem)
Returns a string with sample characters from writingSystem.
QPalette palette
the palette that should be used when painting the control
Definition: qstyleoption.h:92
QFontDatabase::WritingSystem writingSystem
static const char *const filters[3]
QSize sizeHint() const
This implementation caches the size hint to avoid resizing when the contents change dynamically...
Definition: qcombobox.cpp:2432
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
The QListView class provides a list or icon view onto a model.
Definition: qlistview.h:57
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
void setModel(QAbstractItemModel *model)
Sets the model to be model.
Definition: qcombobox.cpp:1984
void setLeft(int pos)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:258
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
const QBrush & highlightedText() const
Returns the highlighted text brush of the current color group.
Definition: qpalette.h:141
QString family() const
Returns the requested font family name, i.e.
Definition: qfont.cpp:906
QSize actualSize(const QSize &size, Mode mode=Normal, State state=Off) const
Returns the actual size of the icon for the requested size, mode, and state.
Definition: qicon.cpp:730
QAbstractItemView * view() const
Returns the list view used for the combobox popup.
Definition: qcombobox.cpp:2385
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
void setBrush(const QBrush &brush)
Sets the painter&#39;s brush to the given brush.
Definition: qpainter.cpp:4171
T & last()
Returns a reference to the last item in the list.
Definition: qlist.h:284
The QModelIndex class is used to locate data in a data model.
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
void setPen(const QColor &color)
Sets the painter&#39;s pen to have style Qt::SolidLine, width 0 and the specified color.
Definition: qpainter.cpp:4047
void _q_currentChanged(const QString &)
Qt::LayoutDirection direction
the text layout direction that should be used when drawing text in the control
Definition: qstyleoption.h:89
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
void drawRect(const QRectF &rect)
Draws the current rectangle with the current pen and brush.
Definition: qpainter.h:650
quint16 index
bool isFixedPitch(const QString &family, const QString &style=QString()) const
Returns true if the font that has family family and style style is fixed pitch; otherwise returns fal...
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
The QFontMetricsF class provides font metrics information.
Definition: qfontmetrics.h:145
const QFont & font() const
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
void setFont(const QFont &f)
Sets the painter&#39;s font to the given font.
Definition: qpainter.cpp:4288
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
This pure abstract function must be reimplemented if you want to provide custom rendering.
The QStyleOptionViewItem class is used to describe the parameters used to draw an item in a view widg...
Definition: qstyleoption.h:539
int height() const
Returns the height of the font.
bool isSmoothlyScalable(const QString &family, const QString &style=QString()) const
Returns true if the font that has family family and style style is smoothly scalable; otherwise retur...
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QRect rect
the area that should be used for various calculations and painting
Definition: qstyleoption.h:90
static float pointSize(const QFontDef &fd, int dpi)
Definition: qfont_win.cpp:90
QFontDatabase::WritingSystem writingSystem() const
#define text
Definition: qobjectdefs.h:80
void paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment=Qt::AlignCenter, Mode mode=Normal, State state=Off) const
Uses the painter to paint the icon with specified alignment, required mode, and state into the rectan...
Definition: qicon.cpp:744
QString family() const
Returns the family name of the matched window system font.
Definition: qfont.cpp:2668
int removeAll(const T &t)
Removes all occurrences of value in the list and returns the number of entries removed.
Definition: qlist.h:770
QFontComboBox::FontFilters filters
The QIcon class provides scalable icons in different modes and states.
Definition: qicon.h:60