File indexing completed on 2025-04-27 03:58:23
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2008-12-23 0007 * Description : a widget to change font properties. 0008 * 0009 * SPDX-FileCopyrightText: 2008-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 1996 by Bernd Johannes Wuebben <wuebben at kde dot org> 0011 * SPDX-FileCopyrightText: 1999 by Preston Brown <pbrown at kde dot org> 0012 * SPDX-FileCopyrightText: 1999 by Mario Weilguni <mweilguni at kde dot org> 0013 * 0014 * SPDX-License-Identifier: GPL-2.0-or-later 0015 * 0016 * ============================================================ */ 0017 0018 #include "dfontproperties.h" 0019 0020 // C++ includes 0021 0022 #include <cmath> 0023 0024 // Qt includes 0025 0026 #include <QCheckBox> 0027 #include <QDoubleSpinBox> 0028 #include <QGuiApplication> 0029 #include <QLabel> 0030 #include <QLayout> 0031 #include <QLocale> 0032 #include <QSplitter> 0033 #include <QScrollBar> 0034 #include <QFontDatabase> 0035 #include <QGroupBox> 0036 #include <QListWidget> 0037 #include <QCoreApplication> 0038 #include <QString> 0039 #include <QHash> 0040 0041 // KDE includes 0042 0043 #include <klocalizedstring.h> 0044 0045 #include "dtextedit.h" 0046 0047 namespace Digikam 0048 { 0049 0050 static bool localeLessThan(const QString& a, const QString& b) 0051 { 0052 return (QString::localeAwareCompare(a, b) < 0); 0053 } 0054 0055 static int minimumListWidth(const QListWidget* list) 0056 { 0057 int w = 0; 0058 0059 for (int i = 0 ; i < list->count() ; ++i) 0060 { 0061 int itemWidth = list->visualItemRect(list->item(i)).width(); 0062 0063 // ...and add a space on both sides for not too tight look. 0064 0065 itemWidth += list->fontMetrics().horizontalAdvance(QLatin1Char(' ')) * 2; 0066 0067 w = qMax(w, itemWidth); 0068 } 0069 0070 if (w == 0) 0071 { 0072 w = 40; 0073 } 0074 0075 w += list->frameWidth() * 2; 0076 w += list->verticalScrollBar()->sizeHint().width(); 0077 0078 return w; 0079 } 0080 0081 static int minimumListHeight(const QListWidget* list, int numVisibleEntry) 0082 { 0083 int w = (list->count() > 0) ? list->visualItemRect(list->item(0)).height() 0084 : list->fontMetrics().lineSpacing(); 0085 0086 if (w < 0) 0087 { 0088 w = 10; 0089 } 0090 0091 if (numVisibleEntry <= 0) 0092 { 0093 numVisibleEntry = 4; 0094 } 0095 0096 return (w * numVisibleEntry + 2 * list->frameWidth()); 0097 } 0098 0099 static QString formatFontSize(qreal size) 0100 { 0101 return QLocale::system().toString(size, 'f', (size == floor(size)) ? 0 : 1); 0102 } 0103 0104 // ----------------------------------------------------------------------------------- 0105 0106 class Q_DECL_HIDDEN DFontProperties::Private 0107 { 0108 public: 0109 0110 explicit Private(DFontProperties* const qq) 0111 : q (qq), 0112 sizeOfFont (nullptr), 0113 sampleEdit (nullptr), 0114 familyLabel (nullptr), 0115 styleLabel (nullptr), 0116 familyCheckbox (nullptr), 0117 styleCheckbox (nullptr), 0118 sizeCheckbox (nullptr), 0119 sizeLabel (nullptr), 0120 familyListBox (nullptr), 0121 styleListBox (nullptr), 0122 sizeListBox (nullptr), 0123 sizeIsRelativeCheckBox(nullptr), 0124 selectedSize (-1), 0125 customSizeRow (-1), 0126 signalsAllowed (true), 0127 usingFixed (true) 0128 { 0129 palette.setColor(QPalette::Active, QPalette::Text, Qt::black); 0130 palette.setColor(QPalette::Active, QPalette::Base, Qt::white); 0131 } 0132 0133 void setFamilyBoxItems(const QStringList& fonts); 0134 void fillFamilyListBox(bool onlyFixedFonts = false); 0135 int nearestSizeRow(qreal val, bool customize); 0136 qreal fillSizeList(const QList<qreal>& sizes = QList<qreal>()); 0137 qreal setupSizeListBox(const QString& family, const QString& style); 0138 void setupDisplay(); 0139 QString styleIdentifier(const QFont& font); 0140 0141 /** 0142 * Split the compound raw font name into family and foundry. 0143 * 0144 * @param name the raw font name reported by Qt 0145 * @param family the storage for family name 0146 * @param foundry the storage for foundry name 0147 */ 0148 void splitFontString(const QString& name, QString* family, QString* foundry = nullptr); 0149 0150 /** 0151 * Translate the font name for the user. 0152 * Primarily for generic fonts like Serif, Sans-Serif, etc. 0153 * 0154 * @param name the raw font name reported by Qt 0155 * @return translated font name 0156 */ 0157 QString translateFontName(const QString& name); 0158 0159 /** 0160 * Compose locale-aware sorted list of translated font names, 0161 * with generic fonts handled in a special way. 0162 * The mapping of translated to raw names can be reported too if required. 0163 * 0164 * @param names raw font names as reported by Qt 0165 * @param trToRawNames storage for mapping of translated to raw names 0166 * @return sorted list of translated font names 0167 */ 0168 QStringList translateFontNameList(const QStringList& names, QHash<QString, QString>* trToRawNames = nullptr); 0169 0170 void _d_toggled_checkbox(); 0171 void _d_family_chosen_slot(const QString&); 0172 void _d_size_chosen_slot(const QString&); 0173 void _d_style_chosen_slot(const QString&); 0174 void _d_displaySample(const QFont& font); 0175 void _d_size_value_slot(double); 0176 0177 public: 0178 0179 DFontProperties* q; 0180 0181 QPalette palette; 0182 QDoubleSpinBox* sizeOfFont; 0183 DTextEdit* sampleEdit; 0184 0185 QLabel* familyLabel; 0186 QLabel* styleLabel; 0187 QCheckBox* familyCheckbox; 0188 QCheckBox* styleCheckbox; 0189 QCheckBox* sizeCheckbox; 0190 QLabel* sizeLabel; 0191 QListWidget* familyListBox; 0192 QListWidget* styleListBox; 0193 QListWidget* sizeListBox; 0194 QCheckBox* sizeIsRelativeCheckBox; 0195 0196 QFont selFont; 0197 0198 QString selectedStyle; 0199 qreal selectedSize; 0200 0201 QString standardSizeAtCustom; 0202 int customSizeRow; 0203 0204 bool signalsAllowed; 0205 bool usingFixed; 0206 0207 /** 0208 * Mappings of translated to Qt originated family and style strings. 0209 */ 0210 QHash<QString, QString> qtFamilies; 0211 QHash<QString, QString> qtStyles; 0212 0213 /** 0214 * Mapping of translated style strings to internal style identifiers. 0215 */ 0216 QHash<QString, QString> styleIDs; 0217 }; 0218 0219 DFontProperties::DFontProperties(QWidget* const parent, 0220 const DisplayFlags& flags, 0221 const QStringList& fontList, 0222 int visibleListSize, 0223 Qt::CheckState* const sizeIsRelativeState) 0224 : QWidget(parent), 0225 d (new DFontProperties::Private(this)) 0226 { 0227 d->usingFixed = flags & FixedFontsOnly; 0228 setWhatsThis(i18nc("@title: font properties", "Here you can choose the font to be used.")); 0229 0230 // The top layout is divided vertically into a splitter with font 0231 // attribute widgets and preview on the top, and XLFD data at the bottom. 0232 0233 QVBoxLayout* const topLayout = new QVBoxLayout(this); 0234 topLayout->setContentsMargins(QMargins()); 0235 const int spacingHint = qMin(style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0236 style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing)); 0237 int checkBoxGap = spacingHint / 2; 0238 0239 // The splitter contains font attribute widgets in the top part, 0240 // and the font preview in the bottom part. 0241 // The splitter is there to allow the user to resize the font preview. 0242 0243 QSplitter* const splitter = new QSplitter(Qt::Vertical, this); 0244 splitter->setChildrenCollapsible(false); 0245 topLayout->addWidget(splitter); 0246 0247 // Build the grid of font attribute widgets for the upper splitter part. 0248 0249 QWidget* page = nullptr; 0250 QGridLayout* gridLayout = nullptr; 0251 int row = 0; 0252 0253 if (flags & DisplayFrame) 0254 { 0255 page = new QGroupBox(i18nc("@title: font properties", "Requested Font"), this); 0256 splitter->addWidget(page); 0257 gridLayout = new QGridLayout(page); 0258 row = 1; 0259 } 0260 else 0261 { 0262 page = new QWidget(this); 0263 splitter->addWidget(page); 0264 gridLayout = new QGridLayout(page); 0265 gridLayout->setContentsMargins(QMargins()); 0266 } 0267 0268 // first, create the labels across the top 0269 0270 QHBoxLayout* const familyLayout = new QHBoxLayout(); 0271 familyLayout->addSpacing(checkBoxGap); 0272 0273 if (flags & ShowDifferences) 0274 { 0275 d->familyCheckbox = new QCheckBox(i18nc("@title: font properties", "Font"), page); 0276 0277 connect(d->familyCheckbox, SIGNAL(toggled(bool)), 0278 this, SLOT(_d_toggled_checkbox())); 0279 0280 familyLayout->addWidget(d->familyCheckbox, 0, Qt::AlignLeft); 0281 d->familyCheckbox->setWhatsThis(i18nc("@info: font properties", "Enable this checkbox to change the font family settings.")); 0282 d->familyCheckbox->setToolTip(i18nc("@info: font properties", "Change font family?")); 0283 d->familyLabel = nullptr; 0284 } 0285 else 0286 { 0287 d->familyCheckbox = nullptr; 0288 d->familyLabel = new QLabel(i18nc("@label: font properties", "Font:"), page); 0289 familyLayout->addWidget(d->familyLabel, 1, Qt::AlignLeft); 0290 } 0291 0292 gridLayout->addLayout(familyLayout, row, 0); 0293 0294 QHBoxLayout* const styleLayout = new QHBoxLayout(); 0295 0296 if (flags & ShowDifferences) 0297 { 0298 d->styleCheckbox = new QCheckBox(i18nc("@title: font properties", "Font style"), page); 0299 0300 connect(d->styleCheckbox, SIGNAL(toggled(bool)), 0301 this, SLOT(_d_toggled_checkbox())); 0302 0303 styleLayout->addWidget(d->styleCheckbox, 0, Qt::AlignLeft); 0304 d->styleCheckbox->setWhatsThis(i18nc("@info: font properties", "Enable this checkbox to change the font style settings.")); 0305 d->styleCheckbox->setToolTip(i18nc("@info: font properties", "Change font style?")); 0306 d->styleLabel = nullptr; 0307 } 0308 else 0309 { 0310 d->styleCheckbox = nullptr; 0311 d->styleLabel = new QLabel(i18nc("@label: font properties", "Font style:"), page); 0312 styleLayout->addWidget(d->styleLabel, 1, Qt::AlignLeft); 0313 } 0314 0315 styleLayout->addSpacing(checkBoxGap); 0316 gridLayout->addLayout(styleLayout, row, 1); 0317 0318 QHBoxLayout* const sizeLayout = new QHBoxLayout(); 0319 0320 if (flags & ShowDifferences) 0321 { 0322 d->sizeCheckbox = new QCheckBox(i18nc("@title: font properties", "Size"), page); 0323 0324 connect(d->sizeCheckbox, SIGNAL(toggled(bool)), 0325 this, SLOT(_d_toggled_checkbox())); 0326 0327 sizeLayout->addWidget(d->sizeCheckbox, 0, Qt::AlignLeft); 0328 d->sizeCheckbox->setWhatsThis(i18nc("@info: font properties", "Enable this checkbox to change the font size settings.")); 0329 d->sizeCheckbox->setToolTip(i18nc("@info: font properties", "Change font size?")); 0330 d->sizeLabel = nullptr; 0331 } 0332 else 0333 { 0334 d->sizeCheckbox = nullptr; 0335 d->sizeLabel = new QLabel(i18nc("@label:listbox Font size", "Size:"), page); 0336 sizeLayout->addWidget(d->sizeLabel, 1, Qt::AlignLeft); 0337 } 0338 0339 sizeLayout->addSpacing(checkBoxGap); 0340 sizeLayout->addSpacing(checkBoxGap); // prevent label from eating border 0341 gridLayout->addLayout(sizeLayout, row, 2); 0342 0343 row ++; 0344 0345 // now create the actual boxes that hold the info 0346 0347 d->familyListBox = new QListWidget(page); 0348 d->familyListBox->setEnabled(flags ^ ShowDifferences); 0349 gridLayout->addWidget(d->familyListBox, row, 0); 0350 QString fontFamilyWhatsThisText(i18nc("@info: font properties", "Here you can choose the font family to be used.")); 0351 d->familyListBox->setWhatsThis(fontFamilyWhatsThisText); 0352 0353 if (flags & ShowDifferences) 0354 { 0355 d->familyCheckbox->setWhatsThis(fontFamilyWhatsThisText); 0356 } 0357 else 0358 { 0359 d->familyLabel->setWhatsThis(fontFamilyWhatsThisText); 0360 } 0361 0362 connect(d->familyListBox, SIGNAL(currentTextChanged(QString)), 0363 this, SLOT(_d_family_chosen_slot(QString))); 0364 0365 if (!fontList.isEmpty()) 0366 { 0367 d->setFamilyBoxItems(fontList); 0368 } 0369 else 0370 { 0371 d->fillFamilyListBox(flags & FixedFontsOnly); 0372 } 0373 0374 d->familyListBox->setMinimumWidth(minimumListWidth(d->familyListBox)); 0375 d->familyListBox->setMinimumHeight(minimumListHeight(d->familyListBox, visibleListSize)); 0376 0377 d->styleListBox = new QListWidget(page); 0378 d->styleListBox->setEnabled(flags ^ ShowDifferences); 0379 gridLayout->addWidget(d->styleListBox, row, 1); 0380 d->styleListBox->setWhatsThis(i18nc("@info: font properties", "Here you can choose the font style to be used.")); 0381 0382 if (flags & ShowDifferences) 0383 { 0384 ((QWidget *)d->styleCheckbox)->setWhatsThis(fontFamilyWhatsThisText); 0385 } 0386 else 0387 { 0388 ((QWidget *)d->styleLabel)->setWhatsThis(fontFamilyWhatsThisText); 0389 } 0390 0391 // Populate usual styles, to determine minimum list width; 0392 // will be replaced later with correct styles. 0393 0394 d->styleListBox->addItem(i18nc("@item: font style", "Normal")); 0395 d->styleListBox->addItem(i18nc("@item: font style", "Italic")); 0396 d->styleListBox->addItem(i18nc("@item: font style", "Oblique")); 0397 d->styleListBox->addItem(i18nc("@item: font style", "Bold")); 0398 d->styleListBox->addItem(i18nc("@item: font style", "Bold Italic")); 0399 d->styleListBox->setMinimumWidth(minimumListWidth(d->styleListBox)); 0400 d->styleListBox->setMinimumHeight(minimumListHeight(d->styleListBox, visibleListSize)); 0401 0402 connect(d->styleListBox, SIGNAL(currentTextChanged(QString)), 0403 this, SLOT(_d_style_chosen_slot(QString))); 0404 0405 d->sizeListBox = new QListWidget(page); 0406 d->sizeOfFont = new QDoubleSpinBox(page); 0407 d->sizeOfFont->setMinimum(4); 0408 d->sizeOfFont->setMaximum(999); 0409 d->sizeOfFont->setDecimals(1); 0410 d->sizeOfFont->setSingleStep(1); 0411 0412 d->sizeListBox->setEnabled(flags ^ ShowDifferences); 0413 d->sizeOfFont->setEnabled(flags ^ ShowDifferences); 0414 0415 if (sizeIsRelativeState) 0416 { 0417 QString sizeIsRelativeCBText = i18nc("@item: font size", "Relative"); 0418 QString sizeIsRelativeCBToolTipText = i18nc("@info: font properties", 0419 "Font size \"fixed\" or \"relative\" to environment"); 0420 QString sizeIsRelativeCBWhatsThisText = i18nc("@info: font properties", "Here you can switch between fixed font size and font size " 0421 "to be calculated dynamically and adjusted to changing " 0422 "environment (e.g. widget dimensions, paper size)."); 0423 d->sizeIsRelativeCheckBox = new QCheckBox(sizeIsRelativeCBText, page); 0424 d->sizeIsRelativeCheckBox->setTristate(flags & ShowDifferences); 0425 QGridLayout* const sizeLayout2 = new QGridLayout(); 0426 sizeLayout2->setSpacing(spacingHint / 2); 0427 gridLayout->addLayout(sizeLayout2, row, 2); 0428 sizeLayout2->setColumnStretch(1, 1); // to prevent text from eating the right border 0429 sizeLayout2->addWidget(d->sizeOfFont, 0, 0, 1, 2); 0430 sizeLayout2->addWidget(d->sizeListBox, 1, 0, 1, 2); 0431 sizeLayout2->addWidget(d->sizeIsRelativeCheckBox, 2, 0, Qt::AlignLeft); 0432 d->sizeIsRelativeCheckBox->setWhatsThis(sizeIsRelativeCBWhatsThisText); 0433 d->sizeIsRelativeCheckBox->setToolTip(sizeIsRelativeCBToolTipText); 0434 } 0435 else 0436 { 0437 d->sizeIsRelativeCheckBox = nullptr; 0438 QGridLayout* const sizeLayout2 = new QGridLayout(); 0439 sizeLayout2->setSpacing(spacingHint / 2); 0440 gridLayout->addLayout(sizeLayout2, row, 2); 0441 sizeLayout2->addWidget(d->sizeOfFont, 0, 0); 0442 sizeLayout2->addWidget(d->sizeListBox, 1, 0); 0443 } 0444 0445 QString fontSizeWhatsThisText = i18nc("@info: font properties", "Here you can choose the font size to be used."); 0446 d->sizeListBox->setWhatsThis(fontSizeWhatsThisText); 0447 0448 if (flags & ShowDifferences) 0449 { 0450 ((QWidget*)d->sizeCheckbox)->setWhatsThis(fontSizeWhatsThisText); 0451 } 0452 else 0453 { 0454 ((QWidget*)d->sizeLabel)->setWhatsThis(fontSizeWhatsThisText); 0455 } 0456 0457 // Populate with usual sizes, to determine minimum list width; 0458 // will be replaced later with correct sizes. 0459 0460 d->fillSizeList(); 0461 d->sizeListBox->setMinimumWidth(minimumListWidth(d->sizeListBox) + d->sizeListBox->fontMetrics().maxWidth()); 0462 d->sizeListBox->setMinimumHeight(minimumListHeight(d->sizeListBox, visibleListSize)); 0463 0464 connect(d->sizeOfFont, SIGNAL(valueChanged(double)), 0465 this, SLOT(_d_size_value_slot(double))); 0466 0467 connect(d->sizeListBox, SIGNAL(currentTextChanged(QString)), 0468 this, SLOT(_d_size_chosen_slot(QString))); 0469 0470 row ++; 0471 0472 // Completed the font attribute grid. 0473 // Add the font preview into the lower part of the splitter. 0474 0475 d->sampleEdit = new DTextEdit(0, page); 0476 d->sampleEdit->setAcceptRichText(false); 0477 QFont tmpFont(font().family(), 64, QFont::Black); 0478 d->sampleEdit->setFont(tmpFont); 0479 d->sampleEdit->setMinimumHeight(d->sampleEdit->fontMetrics().lineSpacing()); 0480 0481 // tr: A classical test phrase, with all letters of the English alphabet. 0482 // Replace it with a sample text in your language, such that it is 0483 // representative of language's writing system. 0484 // If you wish, you can input several lines of text separated by \n. 0485 0486 setSampleText(i18nc("@info: font properties", "The Quick Brown Fox Jumps Over The Lazy Dog")); 0487 d->sampleEdit->setTextCursor(QTextCursor(d->sampleEdit->document())); 0488 QString sampleEditWhatsThisText = i18nc("@info: font properties", "This sample text illustrates the current settings. " 0489 "You may edit it to test special characters."); 0490 d->sampleEdit->setWhatsThis(sampleEditWhatsThisText); 0491 0492 connect(this, SIGNAL(fontSelected(QFont)), 0493 this, SLOT(_d_displaySample(QFont))); 0494 0495 splitter->addWidget(d->sampleEdit); 0496 0497 // Finished setting up the splitter. 0498 // Finished setting up the chooser layout. 0499 // lets initialize the display if possible 0500 0501 if (d->usingFixed) 0502 { 0503 setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont), d->usingFixed); 0504 } 0505 else 0506 { 0507 setFont(QGuiApplication::font(), d->usingFixed); 0508 } 0509 0510 // check or uncheck or gray out the "relative" checkbox 0511 0512 if (sizeIsRelativeState && d->sizeIsRelativeCheckBox) 0513 { 0514 setSizeIsRelative(*sizeIsRelativeState); 0515 } 0516 0517 // Set focus to the size list as this is the most commonly changed property 0518 0519 d->sizeListBox->setFocus(); 0520 } 0521 0522 DFontProperties::~DFontProperties() 0523 { 0524 delete d; 0525 } 0526 0527 void DFontProperties::setColor(const QColor& col) 0528 { 0529 d->palette.setColor(QPalette::Active, QPalette::Text, col); 0530 QPalette pal = d->sampleEdit->palette(); 0531 pal.setColor(QPalette::Active, QPalette::Text, col); 0532 d->sampleEdit->setPalette(pal); 0533 QTextCursor cursor = d->sampleEdit->textCursor(); 0534 d->sampleEdit->selectAll(); 0535 d->sampleEdit->setTextColor(col); 0536 d->sampleEdit->setTextCursor(cursor); 0537 } 0538 0539 QColor DFontProperties::color() const 0540 { 0541 return d->palette.color(QPalette::Active, QPalette::Text); 0542 } 0543 0544 void DFontProperties::setBackgroundColor(const QColor& col) 0545 { 0546 d->palette.setColor(QPalette::Active, QPalette::Base, col); 0547 QPalette pal = d->sampleEdit->palette(); 0548 pal.setColor(QPalette::Active, QPalette::Base, col); 0549 d->sampleEdit->setPalette(pal); 0550 } 0551 0552 QColor DFontProperties::backgroundColor() const 0553 { 0554 return d->palette.color(QPalette::Active, QPalette::Base); 0555 } 0556 0557 void DFontProperties::setSizeIsRelative(Qt::CheckState relative) 0558 { 0559 // check or uncheck or gray out the "relative" checkbox 0560 0561 if (d->sizeIsRelativeCheckBox) 0562 { 0563 if (Qt::PartiallyChecked == relative) 0564 { 0565 d->sizeIsRelativeCheckBox->setCheckState(Qt::PartiallyChecked); 0566 } 0567 else 0568 { 0569 d->sizeIsRelativeCheckBox->setCheckState((Qt::Checked == relative) ? Qt::Checked : Qt::Unchecked); 0570 } 0571 } 0572 } 0573 0574 Qt::CheckState DFontProperties::sizeIsRelative() const 0575 { 0576 return d->sizeIsRelativeCheckBox ? d->sizeIsRelativeCheckBox->checkState() 0577 : Qt::PartiallyChecked; 0578 } 0579 0580 QString DFontProperties::sampleText() const 0581 { 0582 return d->sampleEdit->toPlainText(); 0583 } 0584 0585 void DFontProperties::setSampleText(const QString& text) 0586 { 0587 d->sampleEdit->setPlainText(text); 0588 } 0589 0590 void DFontProperties::setSampleBoxVisible(bool visible) 0591 { 0592 d->sampleEdit->setVisible(visible); 0593 } 0594 0595 QSize DFontProperties::sizeHint(void) const 0596 { 0597 return minimumSizeHint(); 0598 } 0599 0600 void DFontProperties::enableColumn(int column, bool state) 0601 { 0602 if (column & FamilyList) 0603 { 0604 d->familyListBox->setEnabled(state); 0605 } 0606 0607 if (column & StyleList) 0608 { 0609 d->styleListBox->setEnabled(state); 0610 } 0611 0612 if (column & SizeList) 0613 { 0614 d->sizeListBox->setEnabled(state); 0615 d->sizeOfFont->setEnabled(state); 0616 } 0617 } 0618 0619 void DFontProperties::makeColumnVisible(int column, bool state) 0620 { 0621 if (column & FamilyList) 0622 { 0623 d->familyListBox->setVisible(state); 0624 d->familyLabel->setVisible(state); 0625 } 0626 0627 if (column & StyleList) 0628 { 0629 d->styleListBox->setVisible(state); 0630 d->styleLabel->setVisible(state); 0631 } 0632 0633 if (column & SizeList) 0634 { 0635 d->sizeListBox->setVisible(state); 0636 d->sizeOfFont->setVisible(state); 0637 d->sizeLabel->setVisible(state); 0638 } 0639 0640 } 0641 void DFontProperties::setFont(const QFont& aFont, bool onlyFixed) 0642 { 0643 d->selFont = aFont; 0644 d->selectedSize = aFont.pointSizeF(); 0645 0646 if (d->selectedSize == -1) 0647 { 0648 d->selectedSize = QFontInfo(aFont).pointSizeF(); 0649 } 0650 0651 if (onlyFixed != d->usingFixed) 0652 { 0653 d->usingFixed = onlyFixed; 0654 d->fillFamilyListBox(d->usingFixed); 0655 } 0656 0657 d->setupDisplay(); 0658 } 0659 0660 DFontProperties::FontDiffFlags DFontProperties::fontDiffFlags() const 0661 { 0662 FontDiffFlags diffFlags = NoFontDiffFlags; 0663 0664 if (d->familyCheckbox && d->familyCheckbox->isChecked()) 0665 { 0666 diffFlags |= FontDiffFamily; 0667 } 0668 0669 if (d->styleCheckbox && d->styleCheckbox->isChecked()) 0670 { 0671 diffFlags |= FontDiffStyle; 0672 } 0673 0674 if (d->sizeCheckbox && d->sizeCheckbox->isChecked()) 0675 { 0676 diffFlags |= FontDiffSize; 0677 } 0678 0679 return diffFlags; 0680 } 0681 0682 QFont DFontProperties::font() const 0683 { 0684 return d->selFont; 0685 } 0686 0687 void DFontProperties::Private::_d_toggled_checkbox() 0688 { 0689 familyListBox->setEnabled(familyCheckbox->isChecked()); 0690 styleListBox->setEnabled(styleCheckbox->isChecked()); 0691 sizeListBox->setEnabled(sizeCheckbox->isChecked()); 0692 sizeOfFont->setEnabled(sizeCheckbox->isChecked()); 0693 } 0694 0695 void DFontProperties::Private::_d_family_chosen_slot(const QString& family) 0696 { 0697 if (!signalsAllowed) 0698 { 0699 return; 0700 } 0701 0702 signalsAllowed = false; 0703 0704 QString currentFamily; 0705 0706 if (family.isEmpty()) 0707 { 0708 Q_ASSERT(familyListBox->currentItem()); 0709 0710 if (familyListBox->currentItem()) 0711 { 0712 currentFamily = qtFamilies[familyListBox->currentItem()->text()]; 0713 } 0714 } 0715 else 0716 { 0717 currentFamily = qtFamilies[family]; 0718 } 0719 0720 // Get the list of styles available in this family. 0721 0722 QFontDatabase dbase; 0723 QStringList styles = dbase.styles(currentFamily); 0724 0725 if (styles.isEmpty()) 0726 { 0727 styles.append(i18nc("@info: font style", "Normal")); 0728 } 0729 0730 // Filter style strings and add to the listbox. 0731 0732 QString pureFamily; 0733 splitFontString(family, &pureFamily); 0734 QStringList filteredStyles; 0735 qtStyles.clear(); 0736 styleIDs.clear(); 0737 0738 Q_FOREACH (const QString& style, styles) 0739 { 0740 // Sometimes the font database will report an invalid style, 0741 // that falls back to another when set. 0742 // Remove such styles, by checking set/get round-trip. 0743 0744 QFont testFont = dbase.font(currentFamily, style, 10); 0745 0746 if (dbase.styleString(testFont) != style) 0747 { 0748 styles.removeAll(style); 0749 continue; 0750 } 0751 0752 QString fstyle = style; 0753 0754 if (!filteredStyles.contains(fstyle)) 0755 { 0756 filteredStyles.append(fstyle); 0757 qtStyles.insert(fstyle, style); 0758 styleIDs.insert(fstyle, styleIdentifier(testFont)); 0759 } 0760 } 0761 0762 styleListBox->clear(); 0763 styleListBox->addItems(filteredStyles); 0764 0765 // Try to set the current style in the listbox to that previous. 0766 0767 int listPos = filteredStyles.indexOf(selectedStyle.isEmpty() ? i18nc("@info: font style", "Normal") : selectedStyle); 0768 0769 if (listPos < 0) 0770 { 0771 // Make extra effort to have Italic selected when Oblique was chosen, 0772 // and vice versa, as that is what the user would probably want. 0773 0774 QString styleIt = i18nc("@info: font style", "Italic"); 0775 QString styleOb = i18nc("@info: font style", "Oblique"); 0776 0777 for (int i = 0 ; i < 2 ; ++i) 0778 { 0779 int pos = selectedStyle.indexOf(styleIt); 0780 0781 if (pos >= 0) 0782 { 0783 QString style = selectedStyle; 0784 style.replace(pos, styleIt.length(), styleOb); 0785 listPos = filteredStyles.indexOf(style); 0786 0787 if (listPos >= 0) 0788 { 0789 break; 0790 } 0791 } 0792 0793 std::swap(styleIt, styleOb); 0794 } 0795 } 0796 0797 styleListBox->setCurrentRow(listPos >= 0 ? listPos : 0); 0798 QString currentStyle = qtStyles[styleListBox->currentItem()->text()]; 0799 0800 // Recompute the size listbox for this family/style. 0801 0802 qreal currentSize = setupSizeListBox(currentFamily, currentStyle); 0803 sizeOfFont->setValue(currentSize); 0804 0805 selFont = dbase.font(currentFamily, currentStyle, int(currentSize)); 0806 0807 if (dbase.isSmoothlyScalable(currentFamily, currentStyle) && selFont.pointSize() == floor(currentSize)) 0808 { 0809 selFont.setPointSizeF(currentSize); 0810 } 0811 0812 Q_EMIT q->fontSelected(selFont); 0813 0814 signalsAllowed = true; 0815 } 0816 0817 void DFontProperties::Private::_d_style_chosen_slot(const QString& style) 0818 { 0819 if (!signalsAllowed) 0820 { 0821 return; 0822 } 0823 0824 signalsAllowed = false; 0825 0826 QFontDatabase dbase; 0827 QString currentFamily = qtFamilies[familyListBox->currentItem()->text()]; 0828 QString currentStyle; 0829 0830 if (style.isEmpty()) 0831 { 0832 currentStyle = qtStyles[styleListBox->currentItem()->text()]; 0833 } 0834 else 0835 { 0836 currentStyle = qtStyles[style]; 0837 } 0838 0839 // Recompute the size listbox for this family/style. 0840 0841 qreal currentSize = setupSizeListBox(currentFamily, currentStyle); 0842 sizeOfFont->setValue(currentSize); 0843 0844 selFont = dbase.font(currentFamily, currentStyle, int(currentSize)); 0845 0846 if (dbase.isSmoothlyScalable(currentFamily, currentStyle) && selFont.pointSize() == floor(currentSize)) 0847 { 0848 selFont.setPointSizeF(currentSize); 0849 } 0850 0851 Q_EMIT q->fontSelected(selFont); 0852 0853 if (!style.isEmpty()) 0854 { 0855 selectedStyle = currentStyle; 0856 } 0857 0858 signalsAllowed = true; 0859 } 0860 0861 void DFontProperties::Private::_d_size_chosen_slot(const QString& size) 0862 { 0863 if (!signalsAllowed) 0864 { 0865 return; 0866 } 0867 0868 signalsAllowed = false; 0869 0870 qreal currentSize; 0871 0872 if (size.isEmpty()) 0873 { 0874 currentSize = QLocale::system().toDouble(sizeListBox->currentItem()->text()); 0875 } 0876 else 0877 { 0878 currentSize = QLocale::system().toDouble(size); 0879 } 0880 0881 // Reset the customized size slot in the list if not needed. 0882 0883 if (customSizeRow >= 0 && selFont.pointSizeF() != currentSize) 0884 { 0885 sizeListBox->item(customSizeRow)->setText(standardSizeAtCustom); 0886 customSizeRow = -1; 0887 } 0888 0889 sizeOfFont->setValue(currentSize); 0890 selFont.setPointSizeF(currentSize); 0891 Q_EMIT q->fontSelected(selFont); 0892 0893 if (!size.isEmpty()) 0894 { 0895 selectedSize = currentSize; 0896 } 0897 0898 signalsAllowed = true; 0899 } 0900 0901 void DFontProperties::Private::_d_size_value_slot(double dval) 0902 { 0903 if (!signalsAllowed) 0904 { 0905 return; 0906 } 0907 0908 signalsAllowed = false; 0909 0910 // We compare with qreal, so convert for platforms where qreal != double. 0911 0912 qreal val = qreal(dval); 0913 QFontDatabase dbase; 0914 QString family = qtFamilies[familyListBox->currentItem()->text()]; 0915 QString style = qtStyles[styleListBox->currentItem()->text()]; 0916 0917 // Reset current size slot in list if it was customized. 0918 0919 if ((customSizeRow >= 0) && (sizeListBox->currentRow() == customSizeRow)) 0920 { 0921 sizeListBox->item(customSizeRow)->setText(standardSizeAtCustom); 0922 customSizeRow = -1; 0923 } 0924 0925 bool canCustomize = true; 0926 0927 // For Qt-bad-sizes workaround: skip this block unconditionally 0928 0929 if (!dbase.isSmoothlyScalable(family, style)) 0930 { 0931 // Bitmap font, allow only discrete sizes. 0932 // Determine the nearest in the direction of change. 0933 0934 canCustomize = false; 0935 int nrows = sizeListBox->count(); 0936 int row = sizeListBox->currentRow(); 0937 int nrow; 0938 0939 if (val - selFont.pointSizeF() > 0) 0940 { 0941 for (nrow = row + 1 ; nrow < nrows ; ++nrow) 0942 { 0943 if (QLocale::system().toDouble(sizeListBox->item(nrow)->text()) >= val) 0944 { 0945 break; 0946 } 0947 } 0948 } 0949 else 0950 { 0951 for (nrow = row - 1 ; nrow >= 0 ; --nrow) 0952 { 0953 if (QLocale::system().toDouble(sizeListBox->item(nrow)->text()) <= val) 0954 { 0955 break; 0956 } 0957 } 0958 } 0959 0960 // Make sure the new row is not out of bounds. 0961 0962 nrow = nrow < 0 ? 0 : nrow >= nrows ? nrows - 1 : nrow; 0963 0964 // Get the size from the new row and set the spinbox to that size. 0965 0966 val = QLocale::system().toDouble(sizeListBox->item(nrow)->text()); 0967 sizeOfFont->setValue(val); 0968 } 0969 0970 // Set the current size in the size listbox. 0971 0972 int row = nearestSizeRow(val, canCustomize); 0973 sizeListBox->setCurrentRow(row); 0974 0975 selectedSize = val; 0976 selFont.setPointSizeF(val); 0977 Q_EMIT q->fontSelected(selFont); 0978 0979 signalsAllowed = true; 0980 } 0981 0982 void DFontProperties::Private::_d_displaySample(const QFont& font) 0983 { 0984 sampleEdit->setFont(font); 0985 } 0986 0987 int DFontProperties::Private::nearestSizeRow(qreal val, bool customize) 0988 { 0989 qreal diff = 1000; 0990 int row = 0; 0991 0992 for (int r = 0 ; r < sizeListBox->count() ; ++r) 0993 { 0994 qreal cval = QLocale::system().toDouble(sizeListBox->item(r)->text()); 0995 0996 if (qAbs(cval - val) < diff) 0997 { 0998 diff = qAbs(cval - val); 0999 row = r; 1000 } 1001 } 1002 1003 // For Qt-bad-sizes workaround: ignore value of customize, use true 1004 1005 if (customize && diff > 0) 1006 { 1007 customSizeRow = row; 1008 standardSizeAtCustom = sizeListBox->item(row)->text(); 1009 sizeListBox->item(row)->setText(formatFontSize(val)); 1010 } 1011 1012 return row; 1013 } 1014 1015 qreal DFontProperties::Private::fillSizeList(const QList<qreal>& sizes_) 1016 { 1017 if (!sizeListBox) 1018 { 1019 return 0; 1020 } 1021 1022 QList<qreal> sizes = sizes_; 1023 bool canCustomize = false; 1024 1025 if (sizes.count() == 0) 1026 { 1027 static const int c[] = 1028 { 1029 4, 5, 6, 7, 1030 8, 9, 10, 11, 1031 12, 13, 14, 15, 1032 16, 17, 18, 19, 1033 20, 22, 24, 26, 1034 28, 32, 48, 64, 1035 72, 80, 96, 128, 1036 0 1037 }; 1038 1039 for (int i = 0 ; c[i] ; ++i) 1040 { 1041 sizes.append(c[i]); 1042 } 1043 1044 // Since sizes were not supplied, this is a vector font, 1045 // and size slot customization is allowed. 1046 1047 canCustomize = true; 1048 } 1049 1050 // Insert sizes into the listbox. 1051 1052 sizeListBox->clear(); 1053 1054 std::sort(sizes.begin(), sizes.end()); 1055 1056 Q_FOREACH (qreal size, sizes) 1057 { 1058 sizeListBox->addItem(formatFontSize(size)); 1059 } 1060 1061 // Return the nearest to selected size. 1062 // If the font is vector, the nearest size is always same as selected, 1063 // thus size slot customization is allowed. 1064 // If the font is bitmap, the nearest size need not be same as selected, 1065 // thus size slot customization is not allowed. 1066 1067 customSizeRow = -1; 1068 int row = nearestSizeRow(selectedSize, canCustomize); 1069 1070 return QLocale::system().toDouble(sizeListBox->item(row)->text()); 1071 } 1072 1073 qreal DFontProperties::Private::setupSizeListBox(const QString& family, const QString& style) 1074 { 1075 QFontDatabase dbase; 1076 QList<qreal> sizes; 1077 1078 if (dbase.isSmoothlyScalable(family, style)) 1079 { 1080 // A vector font. 1081 //sampleEdit->setPaletteBackgroundPixmap( VectorPixmap ); // TODO 1082 } 1083 else 1084 { 1085 // A bitmap font. 1086 //sampleEdit->setPaletteBackgroundPixmap( BitmapPixmap ); // TODO 1087 1088 QList<int> smoothSizes = dbase.smoothSizes(family, style); 1089 1090 Q_FOREACH (int size, smoothSizes) 1091 { 1092 sizes.append(size); 1093 } 1094 } 1095 1096 // Fill the listbox (uses default list of sizes if the given is empty). 1097 // Collect the best fitting size to selected size, to use if not smooth. 1098 1099 qreal bestFitSize = fillSizeList(sizes); 1100 1101 // Set the best fit size as current in the listbox if available. 1102 1103 const QList<QListWidgetItem*> selectedSizeList = sizeListBox->findItems(formatFontSize(bestFitSize), 1104 Qt::MatchExactly); 1105 if (!selectedSizeList.isEmpty()) 1106 { 1107 sizeListBox->setCurrentItem(selectedSizeList.first()); 1108 } 1109 1110 return bestFitSize; 1111 } 1112 1113 void DFontProperties::Private::setupDisplay() 1114 { 1115 QFontDatabase dbase; 1116 QString family = selFont.family().toLower(); 1117 QString styleID = styleIdentifier(selFont); 1118 qreal size = selFont.pointSizeF(); 1119 1120 if (size == -1) 1121 { 1122 size = QFontInfo(selFont).pointSizeF(); 1123 } 1124 1125 int numEntries, i; 1126 1127 // Direct family match. 1128 1129 numEntries = familyListBox->count(); 1130 1131 for (i = 0 ; i < numEntries ; ++i) 1132 { 1133 if (family == qtFamilies[familyListBox->item(i)->text()].toLower()) 1134 { 1135 familyListBox->setCurrentRow(i); 1136 break; 1137 } 1138 } 1139 1140 // 1st family fallback. 1141 1142 if (i == numEntries) 1143 { 1144 if (family.contains(QLatin1Char('['))) 1145 { 1146 family = family.left(family.indexOf(QLatin1Char('['))).trimmed(); 1147 1148 for (i = 0 ; i < numEntries ; ++i) 1149 { 1150 if (family == qtFamilies[familyListBox->item(i)->text()].toLower()) 1151 { 1152 familyListBox->setCurrentRow(i); 1153 break; 1154 } 1155 } 1156 } 1157 } 1158 1159 // 2nd family fallback. 1160 1161 if (i == numEntries) 1162 { 1163 QString fallback = family + QLatin1String(" ["); 1164 1165 for (i = 0 ; i < numEntries ; ++i) 1166 { 1167 if (qtFamilies[familyListBox->item(i)->text()].toLower().startsWith(fallback)) 1168 { 1169 familyListBox->setCurrentRow(i); 1170 break; 1171 } 1172 } 1173 } 1174 1175 // 3rd family fallback. 1176 1177 if (i == numEntries) 1178 { 1179 for (i = 0 ; i < numEntries ; ++i) 1180 { 1181 if (qtFamilies[familyListBox->item(i)->text()].toLower().startsWith(family)) 1182 { 1183 familyListBox->setCurrentRow(i); 1184 break; 1185 } 1186 } 1187 } 1188 1189 // Family fallback in case nothing matched. Otherwise, diff doesn't work 1190 1191 if (i == numEntries) 1192 { 1193 familyListBox->setCurrentRow(0); 1194 } 1195 1196 // By setting the current item in the family box, the available 1197 // styles and sizes for that family have been collected. 1198 // Try now to set the current items in the style and size boxes. 1199 1200 // Set current style in the listbox. 1201 1202 numEntries = styleListBox->count(); 1203 1204 for (i = 0 ; i < numEntries ; ++i) 1205 { 1206 if (styleID == styleIDs[styleListBox->item(i)->text()]) 1207 { 1208 styleListBox->setCurrentRow(i); 1209 break; 1210 } 1211 } 1212 1213 if (i == numEntries) 1214 { 1215 // Style not found, fallback. 1216 1217 styleListBox->setCurrentRow(0); 1218 } 1219 1220 // Set current size in the listbox. 1221 // If smoothly scalable, allow customizing one of the standard size slots, 1222 // otherwise just select the nearest available size. 1223 1224 QString currentFamily = qtFamilies[familyListBox->currentItem()->text()]; 1225 QString currentStyle = qtStyles[styleListBox->currentItem()->text()]; 1226 bool canCustomize = dbase.isSmoothlyScalable(currentFamily, currentStyle); 1227 sizeListBox->setCurrentRow(nearestSizeRow(size, canCustomize)); 1228 1229 // Set current size in the spinbox. 1230 1231 sizeOfFont->setValue(QLocale::system().toDouble(sizeListBox->currentItem()->text())); 1232 } 1233 1234 void DFontProperties::getFontList(QStringList& list, uint fontListCriteria) 1235 { 1236 QFontDatabase dbase; 1237 QStringList lstSys(dbase.families()); 1238 1239 // if we have criteria; then check fonts before adding 1240 1241 if (fontListCriteria) 1242 { 1243 QStringList lstFonts; 1244 1245 for (QStringList::const_iterator it = lstSys.constBegin() ; it != lstSys.constEnd() ; ++it) 1246 { 1247 if ((fontListCriteria & FixedWidthFonts) > 0 && !dbase.isFixedPitch(*it)) 1248 { 1249 continue; 1250 } 1251 1252 if (((fontListCriteria & (SmoothScalableFonts | ScalableFonts)) == ScalableFonts) && 1253 !dbase.isBitmapScalable(*it)) 1254 { 1255 continue; 1256 } 1257 1258 if (((fontListCriteria & SmoothScalableFonts) > 0) && !dbase.isSmoothlyScalable(*it)) 1259 { 1260 continue; 1261 } 1262 1263 lstFonts.append(*it); 1264 } 1265 1266 if ((fontListCriteria & FixedWidthFonts) > 0) 1267 { 1268 // Fallback.. if there are no fixed fonts found, it's probably a 1269 // bug in the font server or Qt. In this case, just use 'fixed' 1270 1271 if (lstFonts.count() == 0) 1272 { 1273 lstFonts.append(QLatin1String("fixed")); 1274 } 1275 } 1276 1277 lstSys = lstFonts; 1278 } 1279 1280 lstSys.sort(); 1281 1282 list = lstSys; 1283 } 1284 1285 void DFontProperties::Private::setFamilyBoxItems(const QStringList& fonts) 1286 { 1287 signalsAllowed = false; 1288 QStringList trfonts = translateFontNameList(fonts, &qtFamilies); 1289 familyListBox->clear(); 1290 familyListBox->addItems(trfonts); 1291 1292 signalsAllowed = true; 1293 } 1294 1295 void DFontProperties::Private::fillFamilyListBox(bool onlyFixedFonts) 1296 { 1297 QStringList fontList; 1298 getFontList(fontList, onlyFixedFonts ? FixedWidthFonts : 0); 1299 setFamilyBoxItems(fontList); 1300 } 1301 1302 /** 1303 * Human-readable style identifiers returned by QFontDatabase::styleString() 1304 * do not always survive round trip of QFont serialization/deserialization, 1305 * causing wrong style in the style box to be highlighted when 1306 * the chooser dialog is opened. This will cause the style to be changed 1307 * when the dialog is closed and the user did not touch the style box. 1308 * Hence, construct custom style identifiers sufficient for the purpose. 1309 */ 1310 QString DFontProperties::Private::styleIdentifier(const QFont& font) 1311 { 1312 const QChar comma(QLatin1Char(',')); 1313 1314 return ( 1315 QString::number(font.weight()) + comma + 1316 QString::number((int)font.style()) + comma + 1317 QString::number(font.stretch()) 1318 ); 1319 } 1320 1321 void DFontProperties::Private::splitFontString(const QString& name, QString* family, QString* foundry) 1322 { 1323 int p1 = name.indexOf(QLatin1Char('[')); 1324 1325 if (p1 < 0) 1326 { 1327 if (family) 1328 { 1329 *family = name.trimmed(); 1330 } 1331 1332 if (foundry) 1333 { 1334 foundry->clear(); 1335 } 1336 } 1337 else 1338 { 1339 int p2 = name.indexOf(QLatin1Char(']'), p1); 1340 p2 = (p2 > p1) ? p2 : name.length(); 1341 1342 if (family) 1343 { 1344 *family = name.left(p1).trimmed(); 1345 } 1346 1347 if (foundry) 1348 { 1349 *foundry = name.mid(p1 + 1, p2 - p1 - 1).trimmed(); 1350 } 1351 } 1352 } 1353 1354 QString DFontProperties::Private::translateFontName(const QString& name) 1355 { 1356 QString family, foundry; 1357 splitFontString(name, &family, &foundry); 1358 1359 // Obtain any regular translations for the family and foundry. 1360 1361 QString trFamily = QCoreApplication::translate("FontHelpers", 1362 family.toUtf8().constData(), 1363 "@item Font name"); 1364 QString trFoundry = foundry; 1365 1366 if (!foundry.isEmpty()) 1367 { 1368 trFoundry = QCoreApplication::translate("FontHelpers", 1369 foundry.toUtf8().constData(), 1370 "@item Font foundry"); 1371 } 1372 1373 // Assemble full translation. 1374 1375 QString trfont; 1376 1377 if (foundry.isEmpty()) 1378 { 1379 // i18n: Filter by which the translators can translate, or otherwise 1380 // operate on the font names not put up for regular translation. 1381 1382 trfont = QCoreApplication::translate("FontHelpers", "%1", "@item Font name").arg(trFamily); 1383 } 1384 else 1385 { 1386 // i18n: Filter by which the translators can translate, or otherwise 1387 // operate on the font names not put up for regular translation. 1388 1389 trfont = QCoreApplication::translate("FontHelpers", "%1 [%2]", "@item Font name [foundry]") 1390 .arg(trFamily).arg(trFoundry); 1391 } 1392 1393 return trfont; 1394 } 1395 1396 QStringList DFontProperties::Private::translateFontNameList(const QStringList& names, 1397 QHash<QString, QString>* trToRawNames) 1398 { 1399 // Generic fonts, in the inverse of desired order. 1400 1401 QStringList genericNames; 1402 genericNames.append(QLatin1String("Monospace")); 1403 genericNames.append(QLatin1String("Serif")); 1404 genericNames.append(QLatin1String("Sans Serif")); 1405 1406 // Translate fonts, but do not add generics to the list right away. 1407 1408 QStringList trNames; 1409 QHash<QString, QString> trMap; 1410 1411 Q_FOREACH (const QString& name, names) 1412 { 1413 QString trName = translateFontName(name); 1414 1415 if (!genericNames.contains(name)) 1416 { 1417 trNames.append(trName); 1418 } 1419 1420 trMap.insert(trName, name); 1421 } 1422 1423 // Sort real fonts alphabetically. 1424 1425 std::sort(trNames.begin(), trNames.end(), localeLessThan); 1426 1427 // Prepend generic fonts, in the predefined order. 1428 1429 Q_FOREACH (const QString& genericName, genericNames) 1430 { 1431 QString trGenericName = translateFontName(genericName); 1432 1433 if (trMap.contains(trGenericName)) 1434 { 1435 trNames.prepend(trGenericName); 1436 } 1437 } 1438 1439 if (trToRawNames) 1440 { 1441 *trToRawNames = trMap; 1442 } 1443 1444 return trNames; 1445 } 1446 1447 } // namespace Digikam 1448 1449 #include "moc_dfontproperties.cpp"