Subversion Repositories Scribus

Rev

Rev 24826 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
33 Franz 7
/***************************************************************************
8
                          fontcombo.cpp  -  description
9
                             -------------------
10
    begin                : Die Jun 17 2003
11
    copyright            : (C) 2003 by Franz Schmid
12
    email                : Franz.Schmid@altmuehlnet.de
13
 ***************************************************************************/
14
 
15
/***************************************************************************
16
 *                                                                         *
17
 *   This program is free software; you can redistribute it and/or modify  *
18
 *   it under the terms of the GNU General Public License as published by  *
19
 *   the Free Software Foundation; either version 2 of the License, or     *
20
 *   (at your option) any later version.                                   *
21
 *                                                                         *
22
 ***************************************************************************/
9834 fschmid 23
 
10859 cbradney 24
#include <QAbstractItemView>
25
#include <QEvent>
26
#include <QFont>
21871 craig 27
#include <QFontInfo>
8693 fschmid 28
#include <QGridLayout>
10859 cbradney 29
#include <QLabel>
8501 cbradney 30
#include <QPixmap>
24727 jghali 31
#include <QPixmapCache>
9834 fschmid 32
#include <QStringList>
22671 jghali 33
#include <QToolTip>
3457 avox 34
 
16736 jghali 35
#include "fontcombo.h"
20185 craig 36
#include "iconmanager.h"
16736 jghali 37
#include "prefsmanager.h"
38
#include "scpage.h"
21873 jghali 39
#include "scribusapp.h"
714 cbradney 40
#include "scribusdoc.h"
10648 fschmid 41
#include "util.h"
33 Franz 42
 
21875 jghali 43
#include "fonts/scface.h"
44
 
23060 craig 45
FontCombo::FontCombo(QWidget* pa) : QComboBox(pa),
46
                                                                        prefsManager(PrefsManager::instance())
33 Franz 47
{
23474 jghali 48
        iconSetChange();
21563 jghali 49
        setEditable(true);
22424 jghali 50
        setValidator(new FontComboValidator(this));
51
        setInsertPolicy(QComboBox::NoInsert);
21883 craig 52
        setItemDelegate(new FontFamilyDelegate(this));
22603 craig 53
        RebuildList(nullptr);
23474 jghali 54
 
55
        connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
33 Franz 56
}
68 Franz 57
 
23474 jghali 58
void FontCombo::iconSetChange()
59
{
60
        IconManager& iconManager = IconManager::instance();
61
        ttfFont = iconManager.loadPixmap("font_truetype16.png");
62
        otfFont = iconManager.loadPixmap("font_otf16.png");
63
        psFont = iconManager.loadPixmap("font_type1_16.png");
64
        substFont = iconManager.loadPixmap("font_subst16.png");
65
}
66
 
8775 cbradney 67
void FontCombo::RebuildList(ScribusDoc *currentDoc, bool forAnnotation, bool forSubstitute)
68 Franz 68
{
69
        clear();
4533 fschmid 70
        QMap<QString, QString> rlist;
23060 craig 71
        SCFontsIterator it(prefsManager.appPrefs.fontPrefs.AvailFonts);
5980 avox 72
        for ( ; it.hasNext(); it.next())
718 cbradney 73
        {
5980 avox 74
                if (it.current().usable())
494 fschmid 75
                {
22521 craig 76
                        if (currentDoc != nullptr)
718 cbradney 77
                        {
22832 craig 78
                                if (currentDoc->documentFileName() == it.current().localForDocument() || it.current().localForDocument().isEmpty())
10398 cbradney 79
                                        rlist.insert(it.currentKey().toLower(), it.currentKey());
718 cbradney 80
                        }
494 fschmid 81
                        else
10398 cbradney 82
                                rlist.insert(it.currentKey().toLower(), it.currentKey());
7626 jghali 83
                }
718 cbradney 84
        }
4533 fschmid 85
        for (QMap<QString,QString>::Iterator it2 = rlist.begin(); it2 != rlist.end(); ++it2)
4481 fschmid 86
        {
23060 craig 87
                ScFace fon = prefsManager.appPrefs.fontPrefs.AvailFonts[it2.value()];
5980 avox 88
                if (! fon.usable() )
5702 avox 89
                        continue;
5980 avox 90
                ScFace::FontType type = fon.type();
8454 fschmid 91
                if ((forAnnotation) && ((type == ScFace::TYPE1) || (type == ScFace::OTF) || fon.subset()))
8104 fschmid 92
                        continue;
8775 cbradney 93
                if (forSubstitute && fon.isReplacement())
94
                        continue;
95
                if (fon.isReplacement())
10394 cbradney 96
                        addItem(substFont, it2.value());
8775 cbradney 97
                else if (type == ScFace::OTF)
10394 cbradney 98
                        addItem(otfFont, it2.value());
5980 avox 99
                else if (type == ScFace::TYPE1)
10394 cbradney 100
                        addItem(psFont, it2.value());
5980 avox 101
                else if (type == ScFace::TTF)
10394 cbradney 102
                        addItem(ttfFont, it2.value());
4481 fschmid 103
        }
8693 fschmid 104
        QAbstractItemView *tmpView = view();
8642 tsoots 105
        int tmpWidth = tmpView->sizeHintForColumn(0);
106
        if (tmpWidth > 0)
107
                tmpView->setMinimumWidth(tmpWidth + 24);
68 Franz 108
}
2508 fschmid 109
 
8369 cbradney 110
FontComboH::FontComboH(QWidget* parent, bool labels) :
10510 fschmid 111
                QWidget(parent),
23281 jghali 112
                prefsManager(PrefsManager::instance()),
113
                showLabels(labels)
2508 fschmid 114
{
23054 craig 115
        ttfFont = IconManager::instance().loadPixmap("font_truetype16.png");
116
        otfFont = IconManager::instance().loadPixmap("font_otf16.png");
117
        psFont = IconManager::instance().loadPixmap("font_type1_16.png");
118
        substFont = IconManager::instance().loadPixmap("font_subst16.png");
8693 fschmid 119
        fontComboLayout = new QGridLayout(this);
24545 craig 120
        fontComboLayout->setContentsMargins(0, 0, 0, 0);
24547 jghali 121
        if (showLabels)
122
                fontComboLayout->setSpacing(6);
123
        else
124
                fontComboLayout->setSpacing(3);
24522 jghali 125
        int col = 0;
8369 cbradney 126
        if (showLabels)
127
        {
24523 jghali 128
                fontFaceLabel = new QLabel(this);
129
                fontStyleLabel = new QLabel(this);
24522 jghali 130
                fontComboLayout->addWidget(fontFaceLabel, 0, 0);
131
                fontComboLayout->addWidget(fontStyleLabel, 1, 0);
132
                fontComboLayout->setColumnStretch(1, 10);
133
                col = 1;
8369 cbradney 134
        }
23354 jghali 135
        fontFamily = new QComboBox(this);
21563 jghali 136
        fontFamily->setEditable(true);
22424 jghali 137
        fontFamily->setValidator(new FontComboValidator(fontFamily));
138
        fontFamily->setInsertPolicy(QComboBox::NoInsert);
21883 craig 139
        fontFamily->setItemDelegate(new FontFamilyDelegate(this));
24522 jghali 140
        fontComboLayout->addWidget(fontFamily, 0, col);
23354 jghali 141
        fontStyle = new QComboBox(this);
24522 jghali 142
        fontComboLayout->addWidget(fontStyle, 1, col);
16765 fschmid 143
        isForAnnotation = true;  // this is merely to ensure that the list is rebuilt
22603 craig 144
        rebuildList(nullptr);
2508 fschmid 145
        connect(fontFamily, SIGNAL(activated(int)), this, SLOT(familySelected(int)));
146
        connect(fontStyle, SIGNAL(activated(int)), this, SLOT(styleSelected(int)));
8369 cbradney 147
        languageChange();
2508 fschmid 148
}
149
 
10859 cbradney 150
void FontComboH::changeEvent(QEvent *e)
151
{
152
        if (e->type() == QEvent::LanguageChange)
153
                languageChange();
10903 cbradney 154
        else
155
                QWidget::changeEvent(e);
10859 cbradney 156
}
157
 
8369 cbradney 158
void FontComboH::languageChange()
159
{
22721 jghali 160
        if (showLabels)
8369 cbradney 161
        {
14105 cbradney 162
                fontFaceLabel->setText( tr("Family:"));
8369 cbradney 163
                fontStyleLabel->setText( tr("Style:"));
164
        }
14106 cbradney 165
        fontFamily->setToolTip( tr("Font Family of Selected Text or Text Frame"));
166
        fontStyle->setToolTip( tr("Font Style of Selected Text or Text Frame"));
8369 cbradney 167
}
168
 
2508 fschmid 169
void FontComboH::familySelected(int id)
170
{
171
        disconnect(fontStyle, SIGNAL(activated(int)), this, SLOT(styleSelected(int)));
172
        QString curr = fontStyle->currentText();
173
        fontStyle->clear();
14312 jghali 174
        QString fntFamily = fontFamily->itemText(id);
23060 craig 175
        QStringList slist, styleList = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap[fntFamily];
23670 craig 176
        for (QStringList::ConstIterator it = styleList.constBegin(); it != styleList.constEnd(); ++it)
14312 jghali 177
        {
23060 craig 178
                SCFonts::ConstIterator fIt = prefsManager.appPrefs.fontPrefs.AvailFonts.find(fntFamily + " " + *it);
24137 craig 179
                if (fIt != prefsManager.appPrefs.fontPrefs.AvailFonts.constEnd())
14312 jghali 180
                {
181
                        if (!fIt->usable() || fIt->isReplacement())
182
                                continue;
183
                        slist.append(*it);
184
                }
185
        }
2508 fschmid 186
        slist.sort();
8693 fschmid 187
        fontStyle->addItems(slist);
2508 fschmid 188
        if (slist.contains(curr))
10648 fschmid 189
                setCurrentComboItem(fontStyle, curr);
24522 jghali 190
        else if (slist.contains("Regular"))
191
                setCurrentComboItem(fontStyle, "Regular");
192
        else if (slist.contains("Roman"))
193
                setCurrentComboItem(fontStyle, "Roman");
10510 fschmid 194
        emit fontSelected(fontFamily->itemText(id) + " " + fontStyle->currentText());
2508 fschmid 195
        connect(fontStyle, SIGNAL(activated(int)), this, SLOT(styleSelected(int)));
196
}
197
 
198
void FontComboH::styleSelected(int id)
199
{
10510 fschmid 200
        emit fontSelected(fontFamily->currentText() + " " + fontStyle->itemText(id));
2508 fschmid 201
}
202
 
24727 jghali 203
QString FontComboH::currentFont() const
2508 fschmid 204
{
205
        return fontFamily->currentText() + " " + fontStyle->currentText();
206
}
207
 
22635 craig 208
void FontComboH::setCurrentFont(const QString& f)
2508 fschmid 209
{
23060 craig 210
        QString family = prefsManager.appPrefs.fontPrefs.AvailFonts[f].family();
211
        QString style = prefsManager.appPrefs.fontPrefs.AvailFonts[f].style();
16765 fschmid 212
        // If we already have the correct font+style, nothing to do
213
        if ((fontFamily->currentText() == family) && (fontStyle->currentText() == style))
214
                return;
19292 jghali 215
        bool familySigBlocked = fontFamily->blockSignals(true);
216
        bool styleSigBlocked = fontStyle->blockSignals(true);
10648 fschmid 217
        setCurrentComboItem(fontFamily, family);
2508 fschmid 218
        fontStyle->clear();
23060 craig 219
        QStringList slist = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap[family];
2508 fschmid 220
        slist.sort();
221
        QStringList ilist;
22521 craig 222
        if (currDoc != nullptr)
2508 fschmid 223
        {
23670 craig 224
                for (QStringList::ConstIterator it3 = slist.constBegin(); it3 != slist.constEnd(); ++it3)
2508 fschmid 225
                {
23060 craig 226
                        SCFonts::ConstIterator fIt = prefsManager.appPrefs.fontPrefs.AvailFonts.find(family + " " + *it3);
24137 craig 227
                        if (fIt != prefsManager.appPrefs.fontPrefs.AvailFonts.constEnd())
14312 jghali 228
                        {
229
                                if (!fIt->usable() || fIt->isReplacement())
230
                                        continue;
22832 craig 231
                                if ((currDoc->documentFileName() == fIt->localForDocument()) || (fIt->localForDocument().isEmpty()))
14312 jghali 232
                                        ilist.append(*it3);
233
                        }
2508 fschmid 234
                }
8693 fschmid 235
                fontStyle->addItems(ilist);
2508 fschmid 236
        }
237
        else
8693 fschmid 238
                fontStyle->addItems(slist);
10648 fschmid 239
        setCurrentComboItem(fontStyle, style);
19292 jghali 240
        fontFamily->blockSignals(familySigBlocked);
241
        fontStyle->blockSignals(styleSigBlocked);
2508 fschmid 242
}
243
 
22603 craig 244
void FontComboH::rebuildList(ScribusDoc *currentDoc, bool forAnnotation, bool forSubstitute)
2508 fschmid 245
{
16765 fschmid 246
        // if we already have the proper fonts loaded, we need to do nothing
247
        if ((currDoc == currentDoc) && (forAnnotation == isForAnnotation) && (isForSubstitute == forSubstitute))
248
                return;
2508 fschmid 249
        currDoc = currentDoc;
16765 fschmid 250
        isForAnnotation = forAnnotation;
251
        isForSubstitute = forSubstitute;
19292 jghali 252
        bool familySigBlocked = fontFamily->blockSignals(true);
253
        bool styleSigBlocked = fontStyle->blockSignals(true);
2508 fschmid 254
        fontFamily->clear();
255
        fontStyle->clear();
23060 craig 256
        QStringList rlist = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap.keys();
14312 jghali 257
        QMap<QString, ScFace::FontType> flist;
2508 fschmid 258
        flist.clear();
23670 craig 259
        for (QStringList::ConstIterator it2 = rlist.constBegin(); it2 != rlist.constEnd(); ++it2)
2508 fschmid 260
        {
22521 craig 261
                if (currentDoc != nullptr)
2508 fschmid 262
                {
23060 craig 263
                        QStringList slist = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap[*it2];
2508 fschmid 264
                        slist.sort();
23670 craig 265
                        for (QStringList::ConstIterator it3 = slist.constBegin(); it3 != slist.constEnd(); ++it3)
2508 fschmid 266
                        {
23060 craig 267
                                if ( prefsManager.appPrefs.fontPrefs.AvailFonts.contains(*it2 + " " + *it3))
7182 avox 268
                                {
23060 craig 269
                                        const ScFace& fon(prefsManager.appPrefs.fontPrefs.AvailFonts[*it2 + " " + *it3]);
14312 jghali 270
                                        ScFace::FontType type = fon.type();
22832 craig 271
                                        if (!fon.usable() || fon.isReplacement() || !(currentDoc->documentFileName() == fon.localForDocument() || fon.localForDocument().isEmpty()))
14312 jghali 272
                                                continue;
273
                                        if ((forAnnotation) && ((type == ScFace::TYPE1) || (type == ScFace::OTF) || (fon.subset())))
274
                                                continue;
275
                                        if ((forSubstitute) && fon.isReplacement())
276
                                                continue;
277
                                        flist.insert(*it2, fon.type());
278
                                        break;
7182 avox 279
                                }
2508 fschmid 280
                        }
281
                }
282
                else
14312 jghali 283
                {
23060 craig 284
                        QMap<QString, QStringList>::ConstIterator fmIt = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap.find(*it2);
24137 craig 285
                        if (fmIt == prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap.constEnd())
14312 jghali 286
                                continue;
287
                        if (fmIt->count() <= 0)
288
                                continue;
289
                        QString fullFontName = (*it2) + " " + fmIt->at(0);
23060 craig 290
                        ScFace fon = prefsManager.appPrefs.fontPrefs.AvailFonts[fullFontName];
14312 jghali 291
                        if ( !fon.usable() || fon.isReplacement() )
292
                                continue;
293
                        ScFace::FontType type = fon.type();
294
                        if ((forAnnotation) && ((type == ScFace::TYPE1) || (type == ScFace::OTF) || (fon.subset())))
295
                                continue;
296
                        if ((forSubstitute) && fon.isReplacement())
297
                                continue;
298
                        flist.insert(*it2, fon.type());
299
                }
2508 fschmid 300
        }
14312 jghali 301
        for (QMap<QString, ScFace::FontType>::Iterator it2a = flist.begin(); it2a != flist.end(); ++it2a)
4481 fschmid 302
        {
14312 jghali 303
                ScFace::FontType type = it2a.value();
304
                // Replacement fonts were systematically discarded in previous code
305
                /*if (fon.isReplacement())
10394 cbradney 306
                        fontFamily->addItem(substFont, it2a.value());
22638 craig 307
                else */
308
                if (type == ScFace::OTF)
14312 jghali 309
                        fontFamily->addItem(otfFont, it2a.key());
5980 avox 310
                else if (type == ScFace::TYPE1)
14312 jghali 311
                        fontFamily->addItem(psFont, it2a.key());
5980 avox 312
                else if (type == ScFace::TTF)
14312 jghali 313
                        fontFamily->addItem(ttfFont, it2a.key());
4481 fschmid 314
        }
2508 fschmid 315
        QString family = fontFamily->currentText();
23060 craig 316
        QStringList slist = prefsManager.appPrefs.fontPrefs.AvailFonts.fontMap[family];
2508 fschmid 317
        slist.sort();
318
        QStringList ilist;
22521 craig 319
        if (currentDoc != nullptr)
2508 fschmid 320
        {
23670 craig 321
                for (QStringList::ConstIterator it = slist.constBegin(); it != slist.constEnd(); ++it)
2508 fschmid 322
                {
23060 craig 323
                        SCFonts::ConstIterator fIt = prefsManager.appPrefs.fontPrefs.AvailFonts.find(family + " " + *it);
24137 craig 324
                        if (fIt != prefsManager.appPrefs.fontPrefs.AvailFonts.constEnd())
14312 jghali 325
                        {
326
                                if (!fIt->usable() || fIt->isReplacement())
327
                                        continue;
328
                                ilist.append(*it);
329
                        }
2508 fschmid 330
                }
8693 fschmid 331
                fontStyle->addItems(ilist);
2508 fschmid 332
        }
333
        else
10510 fschmid 334
                fontStyle->addItems(slist);
19292 jghali 335
        fontFamily->blockSignals(familySigBlocked);
336
        fontStyle->blockSignals(styleSigBlocked);
2508 fschmid 337
}
21563 jghali 338
 
339
// This code borrowed from Qt project qfontcombobox.cpp
340
 
341
static QFontDatabase::WritingSystem writingSystemFromScript(QLocale::Script script)
342
{
343
        switch (script) {
344
        case QLocale::ArabicScript:
345
                return QFontDatabase::Arabic;
346
        case QLocale::CyrillicScript:
347
                return QFontDatabase::Cyrillic;
348
        case QLocale::GurmukhiScript:
349
                return QFontDatabase::Gurmukhi;
350
        case QLocale::SimplifiedHanScript:
351
                return QFontDatabase::SimplifiedChinese;
352
        case QLocale::TraditionalHanScript:
353
                return QFontDatabase::TraditionalChinese;
354
        case QLocale::LatinScript:
355
                return QFontDatabase::Latin;
356
        case QLocale::ArmenianScript:
357
                return QFontDatabase::Armenian;
358
        case QLocale::BengaliScript:
359
                return QFontDatabase::Bengali;
360
        case QLocale::DevanagariScript:
361
                return QFontDatabase::Devanagari;
362
        case QLocale::GeorgianScript:
363
                return QFontDatabase::Georgian;
364
        case QLocale::GreekScript:
365
                return QFontDatabase::Greek;
366
        case QLocale::GujaratiScript:
367
                return QFontDatabase::Gujarati;
368
        case QLocale::HebrewScript:
369
                return QFontDatabase::Hebrew;
370
        case QLocale::JapaneseScript:
371
                return QFontDatabase::Japanese;
372
        case QLocale::KhmerScript:
373
                return QFontDatabase::Khmer;
374
        case QLocale::KannadaScript:
375
                return QFontDatabase::Kannada;
376
        case QLocale::KoreanScript:
377
                return QFontDatabase::Korean;
378
        case QLocale::LaoScript:
379
                return QFontDatabase::Lao;
380
        case QLocale::MalayalamScript:
381
                return QFontDatabase::Malayalam;
382
        case QLocale::MyanmarScript:
383
                return QFontDatabase::Myanmar;
384
        case QLocale::TamilScript:
385
                return QFontDatabase::Tamil;
386
        case QLocale::TeluguScript:
387
                return QFontDatabase::Telugu;
388
        case QLocale::ThaanaScript:
389
                return QFontDatabase::Thaana;
390
        case QLocale::ThaiScript:
391
                return QFontDatabase::Thai;
392
        case QLocale::TibetanScript:
393
                return QFontDatabase::Tibetan;
394
        case QLocale::SinhalaScript:
395
                return QFontDatabase::Sinhala;
396
        case QLocale::SyriacScript:
397
                return QFontDatabase::Syriac;
398
        case QLocale::OriyaScript:
399
                return QFontDatabase::Oriya;
400
        case QLocale::OghamScript:
401
                return QFontDatabase::Ogham;
402
        case QLocale::RunicScript:
403
                return QFontDatabase::Runic;
404
        case QLocale::NkoScript:
405
                return QFontDatabase::Nko;
406
        default:
407
                return QFontDatabase::Any;
408
        }
409
}
410
 
411
static QFontDatabase::WritingSystem writingSystemFromLocale()
412
{
413
        QStringList uiLanguages = QLocale::system().uiLanguages();
414
        QLocale::Script script;
415
        if (!uiLanguages.isEmpty())
416
                script = QLocale(uiLanguages.at(0)).script();
417
        else
418
                script = QLocale::system().script();
419
 
420
        return writingSystemFromScript(script);
421
}
422
 
21880 jghali 423
QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool *hasLatin)
21563 jghali 424
{
21880 jghali 425
        QFontDatabase& fontDb = ScQApp->qtFontDatabase();
426
        QList<QFontDatabase::WritingSystem> writingSystems = fontDb.writingSystems(font.family());
427
 
428
        // this just confuses the algorithm below. Vietnamese is Latin with lots of special chars
429
        writingSystems.removeOne(QFontDatabase::Vietnamese);
430
        *hasLatin = writingSystems.removeOne(QFontDatabase::Latin);
431
 
432
        if (writingSystems.isEmpty())
433
                return QFontDatabase::Any;
434
 
435
        QFontDatabase::WritingSystem system = writingSystemFromLocale();
436
 
437
        if (writingSystems.contains(system))
438
                return system;
439
 
440
        if (system == QFontDatabase::TraditionalChinese && writingSystems.contains(QFontDatabase::SimplifiedChinese))
441
                return QFontDatabase::SimplifiedChinese;
442
 
443
        if (system == QFontDatabase::SimplifiedChinese && writingSystems.contains(QFontDatabase::TraditionalChinese))
444
                return QFontDatabase::TraditionalChinese;
445
 
446
        system = writingSystems.last();
447
 
448
        if (!*hasLatin)
449
                // we need to show something
450
                return system;
451
 
452
        if (writingSystems.count() == 1 && system > QFontDatabase::Cyrillic)
453
                return system;
454
 
455
        if (writingSystems.count() <= 2 && system > QFontDatabase::Armenian && system < QFontDatabase::Vietnamese)
456
                return system;
457
 
458
        if (writingSystems.count() <= 5 && system >= QFontDatabase::SimplifiedChinese && system <= QFontDatabase::Korean)
459
                return system;
460
 
461
        return QFontDatabase::Any;
21563 jghali 462
}
463
 
22664 jghali 464
const ScFace& getScFace(const QString& className, const QString& text)
21563 jghali 465
{
21873 jghali 466
        QFontDatabase& fontDb = ScQApp->qtFontDatabase();
23060 craig 467
        SCFonts& availableFonts = PrefsManager::instance().appPrefs.fontPrefs.AvailFonts;
21563 jghali 468
 
21731 jghali 469
        // Handle FontComboH class witch has only Family names in the combo class.
22664 jghali 470
        if (className == "FontComboH" || className == "SMFontComboH")
21563 jghali 471
        {
22467 jghali 472
                // SMFontComboH's "Use Parent Font" case
473
                if (!availableFonts.fontMap.contains(text))
474
                        return ScFace::none();
475
                QStringList styles = availableFonts.fontMap[text];
21872 jghali 476
                QString style = styles[0];
477
                if (styles.contains("Regular"))
478
                        style = "Regular";
479
                else if (styles.contains("Roman"))
480
                        style = "Roman";
481
                else if (styles.contains("Medium"))
482
                        style = "Medium";
483
                else if (styles.contains("Book"))
484
                        style = "Book";
22467 jghali 485
                const ScFace& fon = availableFonts.findFont(text, style);
21873 jghali 486
                if (!fontDb.families().contains(text))
487
                        QFontDatabase::addApplicationFont(fon.fontFilePath());
21563 jghali 488
                return fon;
489
        }
22638 craig 490
        const ScFace& scFace = availableFonts.findFont(text);
491
        if (!fontDb.families().contains(scFace.family()))
492
                QFontDatabase::addApplicationFont(scFace.fontFilePath());
493
        return scFace;
21563 jghali 494
}
495
 
21883 craig 496
FontFamilyDelegate::FontFamilyDelegate(QObject *parent)
21880 jghali 497
        : QAbstractItemDelegate(parent)
498
{
24727 jghali 499
        QPixmapCache::setCacheLimit(64 * 1024);
21880 jghali 500
}
501
 
21883 craig 502
void FontFamilyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
21563 jghali 503
{
24308 jghali 504
        double pixelRatio = painter->device()->devicePixelRatioF();
505
        int pixmapW = qRound(pixelRatio * option.rect.width());
506
        int pixmapH = qRound(pixelRatio * option.rect.height());
21871 craig 507
        QString text(index.data(Qt::DisplayRole).toString());
24308 jghali 508
        QString wh = QString("-w%1h%2").arg(pixmapW).arg(pixmapH);
21871 craig 509
        QPixmap cachedPixmap;
25151 craig 510
        QString cacheKey(text + wh);
511
        QString findKey(cacheKey);
21871 craig 512
        if (option.state & QStyle::State_Selected)
25151 craig 513
                findKey += "-selected";
514
        if (QPixmapCache::find(findKey, &cachedPixmap))
21871 craig 515
        {
516
                painter->drawPixmap(option.rect.x(), option.rect.y(), cachedPixmap);
517
                return;
518
        }
519
 
24727 jghali 520
        const QFontDatabase& fontDb = ScQApp->qtFontDatabase();
21873 jghali 521
        const ScFace& scFace = getScFace(this->parent()->metaObject()->className(), text);
21563 jghali 522
 
24308 jghali 523
        QPixmap  pixmap(pixmapW, pixmapH);
524
        QPixmap  invPixmap(pixmapW, pixmapH);
525
        pixmap.setDevicePixelRatio(pixelRatio);
526
        invPixmap.setDevicePixelRatio(pixelRatio);
527
 
21871 craig 528
        QPainter pixPainter(&pixmap);
529
        QPainter invpixPainter(&invPixmap);
530
 
531
        QRect r(0, 0, option.rect.width(), option.rect.height());
23651 craig 532
        pixPainter.fillRect(r, option.palette.window());
533
        invpixPainter.fillRect(r, option.palette.window());
21871 craig 534
 
21563 jghali 535
        QFont font = option.font;
22467 jghali 536
        font.setPointSize(QFontInfo(font).pointSize() * 3 / 2.0);
21563 jghali 537
 
22467 jghali 538
        QFont font2 = option.font;
539
        if (!scFace.isNone())
540
        {
541
                font2 = fontDb.font(scFace.family(), scFace.style(), QFontInfo(option.font).pointSize());
542
                font2.setPointSize(QFontInfo(font2).pointSize() * 3 / 2.0);
543
        }
21563 jghali 544
 
545
        bool hasLatin;
546
        QFontDatabase::WritingSystem system = writingSystemForFont(font2, &hasLatin);
547
        if (hasLatin)
548
                font = font2;
549
 
23877 jghali 550
        pixPainter.setPen(QPen(option.palette.text(), 0));
551
 
21871 craig 552
        invpixPainter.setBrush(option.palette.highlight());
553
        invpixPainter.setPen(Qt::NoPen);
554
        invpixPainter.drawRect(0, 0, option.rect.width(), option.rect.height());
555
        invpixPainter.setPen(QPen(option.palette.highlightedText(), 0));
21563 jghali 556
 
557
        QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
21871 craig 558
        QSize actualSize(icon.actualSize(r.size()));
559
        icon.paint(&pixPainter, r, Qt::AlignLeft|Qt::AlignVCenter);
560
        icon.paint(&invpixPainter, r, Qt::AlignLeft|Qt::AlignVCenter);
21563 jghali 561
        if (option.direction == Qt::RightToLeft)
562
                r.setRight(r.right() - actualSize.width() - 4);
563
        else
564
                r.setLeft(r.left() + actualSize.width() + 4);
565
 
21871 craig 566
        pixPainter.setFont(font);
567
        invpixPainter.setFont(font);
21563 jghali 568
        // If the ascent of the font is larger than the height of the rect,
569
        // we will clip the text, so it's better to align the tight bounding rect in this case
570
        // This is specifically for fonts where the ascent is very large compared to
571
        // the descent, like certain of the Stix family.
572
        QFontMetricsF fontMetrics(font);
21871 craig 573
        if (fontMetrics.ascent() > r.height())
574
        {
21563 jghali 575
                QRectF tbr = fontMetrics.tightBoundingRect(text);
576
                QRectF rr (r.x(), r.y() - (tbr.bottom() + r.height()/2), r.width(),(r.height() + tbr.height()));
21871 craig 577
                pixPainter.drawText(rr, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, text);
578
                invpixPainter.drawText(rr, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, text);
21563 jghali 579
        }
21871 craig 580
        else
581
        {
582
                pixPainter.drawText(r, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, text);
583
                invpixPainter.drawText(r, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, text);
584
        }
21563 jghali 585
 
586
        if (writingSystem != QFontDatabase::Any)
587
                system = writingSystem;
588
 
21871 craig 589
        if (system != QFontDatabase::Any)
590
        {
23596 craig 591
                int w = pixPainter.fontMetrics().horizontalAdvance(text + QLatin1String("  "));
21871 craig 592
                pixPainter.setFont(font2);
593
                invpixPainter.setFont(font2);
24727 jghali 594
                QString sample = QFontDatabase::writingSystemSample(system);
21563 jghali 595
                if (system == QFontDatabase::Arabic)
596
                        sample = "أبجدية عربية";
597
 
21871 craig 598
                if (fontMetrics.ascent() > r.height())
599
                {
21563 jghali 600
                        QRectF tbr = fontMetrics.tightBoundingRect(sample);
21871 craig 601
                        QRectF rr (r.x(), r.y() - (tbr.bottom() + r.height()/2), r.width(), (r.height() + tbr.height()));
21563 jghali 602
                        if (option.direction == Qt::RightToLeft)
603
                                rr.setRight(rr.right() - w);
604
                        else
605
                        {
606
                                rr.setRight(rr.right() - 4);
607
                                rr.setLeft(rr.left() + w);
608
                        }
21871 craig 609
                        pixPainter.drawText(rr, Qt::AlignVCenter|Qt::AlignRight|Qt::TextSingleLine, sample);
610
                        invpixPainter.drawText(rr, Qt::AlignVCenter|Qt::AlignRight|Qt::TextSingleLine, sample);
21563 jghali 611
                }
612
                else
613
                {
614
                        if (option.direction == Qt::RightToLeft)
615
                                r.setRight(r.right() - w);
616
                        else
617
                        {
618
                                r.setRight(r.right() - 4);
619
                                r.setLeft(r.left() + w);
620
                        }
21871 craig 621
                        pixPainter.drawText(r, Qt::AlignVCenter|Qt::AlignRight|Qt::TextSingleLine, sample);
622
                        invpixPainter.drawText(r, Qt::AlignVCenter|Qt::AlignRight|Qt::TextSingleLine, sample);
21563 jghali 623
                }
624
        }
625
        if (option.state & QStyle::State_Selected)
21871 craig 626
                painter->drawPixmap(option.rect.x(), option.rect.y(), invPixmap);
627
        else
628
                painter->drawPixmap(option.rect.x(), option.rect.y(), pixmap);
24727 jghali 629
        QPixmapCache::insert(cacheKey, pixmap);
630
        QPixmapCache::insert(cacheKey + "-selected", invPixmap);
21563 jghali 631
}
632
 
22664 jghali 633
bool FontFamilyDelegate::helpEvent(QHelpEvent * event, QAbstractItemView * view,
634
        const QStyleOptionViewItem & option, const QModelIndex & index)
635
{
636
        if (!event || !view)
637
                return false;
638
 
639
        if (event->type() == QEvent::ToolTip)
640
        {
641
                QString text(index.data(Qt::DisplayRole).toString());
642
                QString className = this->parent()->metaObject()->className();
643
                const ScFace& scFace = getScFace(className, text);
644
                if (!scFace.isNone())
645
                {
646
                        QString tooltip = scFace.family();
647
                        if (className == QLatin1String("FontCombo"))
648
                        {
649
                                tooltip += QLatin1String(" ");
650
                                tooltip += scFace.style();
651
                        }
652
                        QHelpEvent *helpEvent = static_cast<QHelpEvent*>(event);
653
                        QToolTip::showText(helpEvent->globalPos(), tooltip, view);
654
                        return true;
655
                }
656
        }
657
 
658
        return QAbstractItemDelegate::helpEvent(event, view, option, index);
659
}
660
 
22700 craig 661
QSize FontFamilyDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
21563 jghali 662
{
21871 craig 663
        QString text(index.data(Qt::DisplayRole).toString());
21563 jghali 664
        QFont font(option.font);
665
        font.setPointSize(QFontInfo(font).pointSize() * 3/2);
666
        QFontMetrics fontMetrics(font);
23508 jghali 667
        return QSize(fontMetrics.horizontalAdvance(text), fontMetrics.height() + 5);
21563 jghali 668
}
669
 
21873 jghali 670
 
22424 jghali 671
FontComboValidator::FontComboValidator(QObject* parent)
672
        : QValidator(parent)
673
{
674
}
675
 
676
QValidator::State FontComboValidator::validate(QString & input, int & pos) const
677
{
24137 craig 678
        QComboBox* comboBox = qobject_cast<QComboBox*>(this->parent());
22424 jghali 679
        if (!comboBox)
680
                return QValidator::Invalid;
681
 
682
        int index = comboBox->findText(input, Qt::MatchFixedString);
683
        if (index >= 0)
684
        {
685
                input = comboBox->itemText(index); // Matching is performed case insensitively
686
                return QValidator::Acceptable;
687
        }
688
 
689
        for (int i = 0; i < comboBox->count(); ++i)
690
        {
691
                QString itemText = comboBox->itemText(i);
692
                if (itemText.startsWith(input, Qt::CaseInsensitive))
693
                        return QValidator::Intermediate;
694
        }
695
 
696
        return QValidator::Invalid;
22521 craig 697
}