Rev 25053 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
For general Scribus (>=1.3.2) copyright and licensing information please refer
to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Scribus 1.3.2
for which a new license (GPL+exception) is in place.
*/
/***************************************************************************
fontcombo.cpp - description
-------------------
begin : Die Jun 17 2003
copyright : (C) 2003 by Franz Schmid
email : Franz.Schmid@altmuehlnet.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <QAbstractItemView>
#include <QEvent>
#include <QFont>
#include <QFontInfo>
#include <QFontDatabase>
#include <QGridLayout>
#include <QLabel>
#include <QPixmap>
#include <QPixmapCache>
#include <QStringList>
#include <QToolTip>
#include "fontcombo.h"
#include "iconmanager.h"
#include "prefsmanager.h"
#include "scribusapp.h"
#include "scribusdoc.h"
#include "util.h"
#include "fonts/scface.h"
FontCombo::FontCombo(QWidget* pa) : QComboBox(pa),
prefsManager(PrefsManager::instance())
{
iconSetChange();
setEditable(true);
setValidator(new FontComboValidator(this));
setInsertPolicy(QComboBox::NoInsert);
setItemDelegate(new FontFamilyDelegate(this));
RebuildList(nullptr);
connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
}
void FontCombo::iconSetChange()
{
IconManager& iconManager = IconManager::instance();
ttfFont = iconManager.loadPixmap("font_truetype16.png");
otfFont = iconManager.loadPixmap("font_otf16.png");
psFont = iconManager.loadPixmap("font_type1_16.png");
substFont = iconManager.loadPixmap("font_subst16.png");
}
void FontCombo::RebuildList(ScribusDoc *currentDoc, bool forAnnotation, bool forSubstitute)
{
clear();
QMap<QString, QString> rlist;
SCFontsIterator it(prefsManager.appPrefs.fontPrefs.AvailFonts);
for ( ; it.hasNext(); it.next())
{
if (it.current().usable())
{
if (currentDoc != nullptr)
{
if (currentDoc->documentFileName() == it.current().localForDocument() || it.current().localForDocument().isEmpty())
rlist.insert(it.currentKey().toLower(), it.currentKey());
}
else
rlist.insert(it.currentKey().toLower(), it.currentKey());
}
}
for (QMap<QString,QString>::Iterator it2 = rlist.begin(); it2 != rlist.end(); ++it2)
{
ScFace fon = prefsManager.appPrefs.fontPrefs.AvailFonts[it2.value()];
if (! fon.usable() )
continue;
ScFace::FontType type = fon.type();
if ((forAnnotation) && ((type == ScFace::TYPE1) || (type == ScFace::OTF) || fon.subset()))
continue;
if (forSubstitute && fon.isReplacement())
continue;
if (fon.isReplacement())
addItem(substFont, it2.value());
else if (type == ScFace::OTF)
addItem(otfFont, it2.value());
else if (type == ScFace::TYPE1)
addItem(psFont, it2.value());
else if (type == ScFace::TTF)
addItem(ttfFont, it2.value());
}
QAbstractItemView *tmpView = view();
int tmpWidth = tmpView->sizeHintForColumn(0);
if (tmpWidth > 0)
tmpView->setMinimumWidth(tmpWidth + 24);
}
FontComboH::FontComboH(QWidget* parent, bool labels) :
QWidget(parent),
prefsManager(PrefsManager::instance()),
showLabels(labels)
{
ttfFont = IconManager::instance().loadPixmap("font_truetype16.png");
otfFont = IconManager::instance().loadPixmap("font_otf16.png");
psFont = IconManager::instance().loadPixmap("font_type1_16.png");
substFont = IconManager::instance().loadPixmap("font_subst16.png");
fontComboLayout = new QGridLayout(this);
fontComboLayout->setContentsMargins(0, 0, 0, 0);
if (showLabels)
fontComboLayout->setSpacing(6);
else
fontComboLayout->setSpacing(3);
int col = 0;
if (showLabels)
{
fontFaceLabel = new QLabel(this);
fontStyleLabel = new QLabel(this);
fontComboLayout->addWidget(fontFaceLabel, 0, 0);
fontComboLayout->addWidget(fontStyleLabel, 1, 0);
fontComboLayout->setColumnStretch(1, 10);
col = 1;
}
fontFamily = new QComboBox(this);
fontFamily->setEditable(true);
fontFamily->setValidator(new FontComboValidator(fontFamily));
fontFamily->setInsertPolicy(QComboBox::NoInsert);
fontFamily->setItemDelegate(new FontFamilyDelegate(this));
fontComboLayout->addWidget(fontFamily, 0, col);
fontStyle = new QComboBox(this);
fontComboLayout->addWidget(fontStyle, 1, col);
isForAnnotation = true; // this is merely to ensure that the list is rebuilt
rebuildList(nullptr);
connect(fontFamily, SIGNAL(activated(int)), this, SLOT(familySelected(int)));
connect(fontStyle, SIGNAL(activated(int)), this, SLOT(styleSelected(int)));
languageChange();
}
void FontComboH::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange)
languageChange();
else
QWidget::changeEvent(e);
}
void FontComboH::languageChange()
{
if (showLabels)
{
fontFaceLabel->setText( tr("Family:"));
fontStyleLabel->setText( tr("Style:"));
}
fontFamily->setToolTip( tr("Font Family of Selected Text or Text Frame"));
fontStyle->setToolTip( tr("Font Style of Selected Text or Text Frame"));
}
void FontComboH::familySelected(int id)
{
disconnect(fontStyle, SIGNAL(activated(int)), this, SLOT(styleSelected(int)));
QString curr = fontStyle->currentText();
fontStyle->clear();
QString fntFamily = fontFamily->itemText(id);
QStringList slist, styleList = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap[fntFamily];
for (QStringList::ConstIterator it = styleList.constBegin(); it != styleList.constEnd(); ++it)
{
SCFonts::ConstIterator fIt = prefsManager.appPrefs.fontPrefs.AvailFonts.find(fntFamily + " " + *it);
if (fIt != prefsManager.appPrefs.fontPrefs.AvailFonts.constEnd())
{
if (!fIt->usable() || fIt->isReplacement())
continue;
slist.append(*it);
}
}
slist.sort();
fontStyle->addItems(slist);
if (slist.contains(curr))
setCurrentComboItem(fontStyle, curr);
else if (slist.contains("Regular"))
setCurrentComboItem(fontStyle, "Regular");
else if (slist.contains("Roman"))
setCurrentComboItem(fontStyle, "Roman");
emit fontSelected(fontFamily->itemText(id) + " " + fontStyle->currentText());
connect(fontStyle, SIGNAL(activated(int)), this, SLOT(styleSelected(int)));
}
void FontComboH::styleSelected(int id)
{
emit fontSelected(fontFamily->currentText() + " " + fontStyle->itemText(id));
}
QString FontComboH::currentFont() const
{
return fontFamily->currentText() + " " + fontStyle->currentText();
}
void FontComboH::setCurrentFont(const QString& f)
{
QString family = prefsManager.appPrefs.fontPrefs.AvailFonts[f].family();
QString style = prefsManager.appPrefs.fontPrefs.AvailFonts[f].style();
// If we already have the correct font+style, nothing to do
if ((fontFamily->currentText() == family) && (fontStyle->currentText() == style))
return;
bool familySigBlocked = fontFamily->blockSignals(true);
bool styleSigBlocked = fontStyle->blockSignals(true);
setCurrentComboItem(fontFamily, family);
fontStyle->clear();
QStringList slist = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap[family];
slist.sort();
QStringList ilist;
if (currDoc != nullptr)
{
for (QStringList::ConstIterator it3 = slist.constBegin(); it3 != slist.constEnd(); ++it3)
{
SCFonts::ConstIterator fIt = prefsManager.appPrefs.fontPrefs.AvailFonts.find(family + " " + *it3);
if (fIt != prefsManager.appPrefs.fontPrefs.AvailFonts.constEnd())
{
if (!fIt->usable() || fIt->isReplacement())
continue;
if ((currDoc->documentFileName() == fIt->localForDocument()) || (fIt->localForDocument().isEmpty()))
ilist.append(*it3);
}
}
fontStyle->addItems(ilist);
}
else
fontStyle->addItems(slist);
setCurrentComboItem(fontStyle, style);
fontFamily->blockSignals(familySigBlocked);
fontStyle->blockSignals(styleSigBlocked);
}
void FontComboH::rebuildList(ScribusDoc *currentDoc, bool forAnnotation, bool forSubstitute)
{
// if we already have the proper fonts loaded, we need to do nothing
if ((currDoc == currentDoc) && (forAnnotation == isForAnnotation) && (isForSubstitute == forSubstitute))
return;
currDoc = currentDoc;
isForAnnotation = forAnnotation;
isForSubstitute = forSubstitute;
bool familySigBlocked = fontFamily->blockSignals(true);
bool styleSigBlocked = fontStyle->blockSignals(true);
fontFamily->clear();
fontStyle->clear();
QStringList rlist = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap.keys();
QMap<QString, ScFace::FontType> flist;
flist.clear();
for (QStringList::ConstIterator it2 = rlist.constBegin(); it2 != rlist.constEnd(); ++it2)
{
if (currentDoc != nullptr)
{
QStringList slist = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap[*it2];
slist.sort();
for (QStringList::ConstIterator it3 = slist.constBegin(); it3 != slist.constEnd(); ++it3)
{
if ( prefsManager.appPrefs.fontPrefs.AvailFonts.contains(*it2 + " " + *it3))
{
const ScFace& fon(prefsManager.appPrefs.fontPrefs.AvailFonts[*it2 + " " + *it3]);
ScFace::FontType type = fon.type();
if (!fon.usable() || fon.isReplacement() || !(currentDoc->documentFileName() == fon.localForDocument() || fon.localForDocument().isEmpty()))
continue;
if ((forAnnotation) && ((type == ScFace::TYPE1) || (type == ScFace::OTF) || (fon.subset())))
continue;
if ((forSubstitute) && fon.isReplacement())
continue;
flist.insert(*it2, fon.type());
break;
}
}
}
else
{
QMap<QString, QStringList>::ConstIterator fmIt = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap.find(*it2);
if (fmIt == prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap.constEnd())
continue;
if (fmIt->count() <= 0)
continue;
QString fullFontName = (*it2) + " " + fmIt->at(0);
ScFace fon = prefsManager.appPrefs.fontPrefs.AvailFonts[fullFontName];
if ( !fon.usable() || fon.isReplacement() )
continue;
ScFace::FontType type = fon.type();
if ((forAnnotation) && ((type == ScFace::TYPE1) || (type == ScFace::OTF) || (fon.subset())))
continue;
if ((forSubstitute) && fon.isReplacement())
continue;
flist.insert(*it2, fon.type());
}
}
for (QMap<QString, ScFace::FontType>::Iterator it2a = flist.begin(); it2a != flist.end(); ++it2a)
{
ScFace::FontType type = it2a.value();
// Replacement fonts were systematically discarded in previous code
/*if (fon.isReplacement())
fontFamily->addItem(substFont, it2a.value());
else */
if (type == ScFace::OTF)
fontFamily->addItem(otfFont, it2a.key());
else if (type == ScFace::TYPE1)
fontFamily->addItem(psFont, it2a.key());
else if (type == ScFace::TTF)
fontFamily->addItem(ttfFont, it2a.key());
}
QString family = fontFamily->currentText();
QStringList slist = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap[family];
slist.sort();
QStringList ilist;
if (currentDoc != nullptr)
{
for (QStringList::ConstIterator it = slist.constBegin(); it != slist.constEnd(); ++it)
{
SCFonts::ConstIterator fIt = prefsManager.appPrefs.fontPrefs.AvailFonts.find(family + " " + *it);
if (fIt != prefsManager.appPrefs.fontPrefs.AvailFonts.constEnd())
{
if (!fIt->usable() || fIt->isReplacement())
continue;
ilist.append(*it);
}
}
fontStyle->addItems(ilist);
}
else
fontStyle->addItems(slist);
fontFamily->blockSignals(familySigBlocked);
fontStyle->blockSignals(styleSigBlocked);
}
// This code borrowed from Qt project qfontcombobox.cpp
static QFontDatabase::WritingSystem writingSystemFromScript(QLocale::Script script)
{
switch (script) {
case QLocale::ArabicScript:
return QFontDatabase::Arabic;
case QLocale::CyrillicScript:
return QFontDatabase::Cyrillic;
case QLocale::GurmukhiScript:
return QFontDatabase::Gurmukhi;
case QLocale::SimplifiedHanScript:
return QFontDatabase::SimplifiedChinese;
case QLocale::TraditionalHanScript:
return QFontDatabase::TraditionalChinese;
case QLocale::LatinScript:
return QFontDatabase::Latin;
case QLocale::ArmenianScript:
return QFontDatabase::Armenian;
case QLocale::BengaliScript:
return QFontDatabase::Bengali;
case QLocale::DevanagariScript:
return QFontDatabase::Devanagari;
case QLocale::GeorgianScript:
return QFontDatabase::Georgian;
case QLocale::GreekScript:
return QFontDatabase::Greek;
case QLocale::GujaratiScript:
return QFontDatabase::Gujarati;
case QLocale::HebrewScript:
return QFontDatabase::Hebrew;
case QLocale::JapaneseScript:
return QFontDatabase::Japanese;
case QLocale::KhmerScript:
return QFontDatabase::Khmer;
case QLocale::KannadaScript:
return QFontDatabase::Kannada;
case QLocale::KoreanScript:
return QFontDatabase::Korean;
case QLocale::LaoScript:
return QFontDatabase::Lao;
case QLocale::MalayalamScript:
return QFontDatabase::Malayalam;
case QLocale::MyanmarScript:
return QFontDatabase::Myanmar;
case QLocale::TamilScript:
return QFontDatabase::Tamil;
case QLocale::TeluguScript:
return QFontDatabase::Telugu;
case QLocale::ThaanaScript:
return QFontDatabase::Thaana;
case QLocale::ThaiScript:
return QFontDatabase::Thai;
case QLocale::TibetanScript:
return QFontDatabase::Tibetan;
case QLocale::SinhalaScript:
return QFontDatabase::Sinhala;
case QLocale::SyriacScript:
return QFontDatabase::Syriac;
case QLocale::OriyaScript:
return QFontDatabase::Oriya;
case QLocale::OghamScript:
return QFontDatabase::Ogham;
case QLocale::RunicScript:
return QFontDatabase::Runic;
case QLocale::NkoScript:
return QFontDatabase::Nko;
default:
return QFontDatabase::Any;
}
}
static QFontDatabase::WritingSystem writingSystemFromLocale()
{
QStringList uiLanguages = QLocale::system().uiLanguages();
QLocale::Script script;
if (!uiLanguages.isEmpty())
script = QLocale(uiLanguages.at(0)).script();
else
script = QLocale::system().script();
return writingSystemFromScript(script);
}
QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool *hasLatin)
{
QList<QFontDatabase::WritingSystem> writingSystems = QFontDatabase::writingSystems(font.family());
// this just confuses the algorithm below. Vietnamese is Latin with lots of special chars
writingSystems.removeOne(QFontDatabase::Vietnamese);
*hasLatin = writingSystems.removeOne(QFontDatabase::Latin);
if (writingSystems.isEmpty())
return QFontDatabase::Any;
QFontDatabase::WritingSystem system = writingSystemFromLocale();
if (writingSystems.contains(system))
return system;
if (system == QFontDatabase::TraditionalChinese && writingSystems.contains(QFontDatabase::SimplifiedChinese))
return QFontDatabase::SimplifiedChinese;
if (system == QFontDatabase::SimplifiedChinese && writingSystems.contains(QFontDatabase::TraditionalChinese))
return QFontDatabase::TraditionalChinese;
system = writingSystems.last();
if (!*hasLatin)
// we need to show something
return system;
if (writingSystems.count() == 1 && system > QFontDatabase::Cyrillic)
return system;
if (writingSystems.count() <= 2 && system > QFontDatabase::Armenian && system < QFontDatabase::Vietnamese)
return system;
if (writingSystems.count() <= 5 && system >= QFontDatabase::SimplifiedChinese && system <= QFontDatabase::Korean)
return system;
return QFontDatabase::Any;
}
const ScFace& getScFace(const QString& className, const QString& text)
{
SCFonts& availableFonts = PrefsManager::instance().appPrefs.fontPrefs.AvailFonts;
// Handle FontComboH class witch has only Family names in the combo class.
if (className == "FontComboH" || className == "SMFontComboH")
{
// SMFontComboH's "Use Parent Font" case
if (!availableFonts.fontMap.contains(text))
return ScFace::none();
QStringList styles = availableFonts.fontMap[text];
QString style = styles[0];
if (styles.contains("Regular"))
style = "Regular";
else if (styles.contains("Roman"))
style = "Roman";
else if (styles.contains("Medium"))
style = "Medium";
else if (styles.contains("Book"))
style = "Book";
const ScFace& fon = availableFonts.findFont(text, style);
if (!QFontDatabase::families().contains(text))
QFontDatabase::addApplicationFont(fon.fontFilePath());
return fon;
}
const ScFace& scFace = availableFonts.findFont(text);
if (!QFontDatabase::families().contains(scFace.family()))
QFontDatabase::addApplicationFont(scFace.fontFilePath());
return scFace;
}
FontFamilyDelegate::FontFamilyDelegate(QObject *parent)
: QAbstractItemDelegate(parent)
{
QPixmapCache::setCacheLimit(64 * 1024);
}
void FontFamilyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
double pixelRatio = painter->device()->devicePixelRatioF();
int pixmapW = qRound(pixelRatio * option.rect.width());
int pixmapH = qRound(pixelRatio * option.rect.height());
QString text(index.data(Qt::DisplayRole).toString());
QString wh = QString("-w%1h%2").arg(pixmapW).arg(pixmapH);
QPixmap cachedPixmap;
QString cacheKey(text + wh);
QString findKey(cacheKey);
if (option.state & QStyle::State_Selected)
findKey += "-selected";
if (QPixmapCache::find(findKey, &cachedPixmap))
{
painter->drawPixmap(option.rect.x(), option.rect.y(), cachedPixmap);
return;
}
const ScFace& scFace = getScFace(this->parent()->metaObject()->className(), text);
QPixmap pixmap(pixmapW, pixmapH);
QPixmap invPixmap(pixmapW, pixmapH);
pixmap.setDevicePixelRatio(pixelRatio);
invPixmap.setDevicePixelRatio(pixelRatio);
QPainter pixPainter(&pixmap);
QPainter invpixPainter(&invPixmap);
QRect r(0, 0, option.rect.width(), option.rect.height());
pixPainter.fillRect(r, option.palette.window());
invpixPainter.fillRect(r, option.palette.window());
QFont font = option.font;
font.setPointSize(QFontInfo(font).pointSize() * 3 / 2.0);
QFont font2 = option.font;
if (!scFace.isNone())
{
font2 = QFontDatabase::font(scFace.family(), scFace.style(), QFontInfo(option.font).pointSize());
font2.setPointSize(QFontInfo(font2).pointSize() * 3 / 2.0);
}
bool hasLatin;
QFontDatabase::WritingSystem system = writingSystemForFont(font2, &hasLatin);
if (hasLatin)
font = font2;
pixPainter.setPen(QPen(option.palette.text(), 0));
invpixPainter.setBrush(option.palette.highlight());
invpixPainter.setPen(Qt::NoPen);
invpixPainter.drawRect(0, 0, option.rect.width(), option.rect.height());
invpixPainter.setPen(QPen(option.palette.highlightedText(), 0));
QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
QSize actualSize(icon.actualSize(r.size()));
icon.paint(&pixPainter, r, Qt::AlignLeft|Qt::AlignVCenter);
icon.paint(&invpixPainter, r, Qt::AlignLeft|Qt::AlignVCenter);
if (option.direction == Qt::RightToLeft)
r.setRight(r.right() - actualSize.width() - 4);
else
r.setLeft(r.left() + actualSize.width() + 4);
pixPainter.setFont(font);
invpixPainter.setFont(font);
// If the ascent of the font is larger than the height of the rect,
// we will clip the text, so it's better to align the tight bounding rect in this case
// This is specifically for fonts where the ascent is very large compared to
// the descent, like certain of the Stix family.
QFontMetricsF fontMetrics(font);
if (fontMetrics.ascent() > r.height())
{
QRectF tbr = fontMetrics.tightBoundingRect(text);
QRectF rr (r.x(), r.y() - (tbr.bottom() + r.height()/2), r.width(),(r.height() + tbr.height()));
pixPainter.drawText(rr, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, text);
invpixPainter.drawText(rr, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, text);
}
else
{
pixPainter.drawText(r, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, text);
invpixPainter.drawText(r, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, text);
}
if (writingSystem != QFontDatabase::Any)
system = writingSystem;
if (system != QFontDatabase::Any)
{
int w = pixPainter.fontMetrics().horizontalAdvance(text + QLatin1String(" "));
pixPainter.setFont(font2);
invpixPainter.setFont(font2);
QString sample = QFontDatabase::writingSystemSample(system);
if (system == QFontDatabase::Arabic)
sample = "أبجدية عربية";
if (fontMetrics.ascent() > r.height())
{
QRectF tbr = fontMetrics.tightBoundingRect(sample);
QRectF rr (r.x(), r.y() - (tbr.bottom() + r.height()/2), r.width(), (r.height() + tbr.height()));
if (option.direction == Qt::RightToLeft)
rr.setRight(rr.right() - w);
else
{
rr.setRight(rr.right() - 4);
rr.setLeft(rr.left() + w);
}
pixPainter.drawText(rr, Qt::AlignVCenter|Qt::AlignRight|Qt::TextSingleLine, sample);
invpixPainter.drawText(rr, Qt::AlignVCenter|Qt::AlignRight|Qt::TextSingleLine, sample);
}
else
{
if (option.direction == Qt::RightToLeft)
r.setRight(r.right() - w);
else
{
r.setRight(r.right() - 4);
r.setLeft(r.left() + w);
}
pixPainter.drawText(r, Qt::AlignVCenter|Qt::AlignRight|Qt::TextSingleLine, sample);
invpixPainter.drawText(r, Qt::AlignVCenter|Qt::AlignRight|Qt::TextSingleLine, sample);
}
}
if (option.state & QStyle::State_Selected)
painter->drawPixmap(option.rect.x(), option.rect.y(), invPixmap);
else
painter->drawPixmap(option.rect.x(), option.rect.y(), pixmap);
QPixmapCache::insert(cacheKey, pixmap);
QPixmapCache::insert(cacheKey + "-selected", invPixmap);
}
bool FontFamilyDelegate::helpEvent(QHelpEvent * event, QAbstractItemView * view,
const QStyleOptionViewItem & option, const QModelIndex & index)
{
if (!event || !view)
return false;
if (event->type() == QEvent::ToolTip)
{
QString text(index.data(Qt::DisplayRole).toString());
QString className = this->parent()->metaObject()->className();
const ScFace& scFace = getScFace(className, text);
if (!scFace.isNone())
{
QString tooltip = scFace.family();
if (className == QLatin1String("FontCombo"))
{
tooltip += QLatin1String(" ");
tooltip += scFace.style();
}
QHelpEvent *helpEvent = static_cast<QHelpEvent*>(event);
QToolTip::showText(helpEvent->globalPos(), tooltip, view);
return true;
}
}
return QAbstractItemDelegate::helpEvent(event, view, option, index);
}
QSize FontFamilyDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QString text(index.data(Qt::DisplayRole).toString());
QFont font(option.font);
font.setPointSize(QFontInfo(font).pointSize() * 3/2);
QFontMetrics fontMetrics(font);
return QSize(fontMetrics.horizontalAdvance(text), fontMetrics.height() + 5);
}
FontComboValidator::FontComboValidator(QObject* parent)
: QValidator(parent)
{
}
QValidator::State FontComboValidator::validate(QString & input, int & pos) const
{
QComboBox* comboBox = qobject_cast<QComboBox*>(this->parent());
if (!comboBox)
return QValidator::Invalid;
int index = comboBox->findText(input, Qt::MatchFixedString);
if (index >= 0)
{
input = comboBox->itemText(index); // Matching is performed case insensitively
return QValidator::Acceptable;
}
for (int i = 0; i < comboBox->count(); ++i)
{
QString itemText = comboBox->itemText(i);
if (itemText.startsWith(input, Qt::CaseInsensitive))
return QValidator::Intermediate;
}
return QValidator::Invalid;
}