Subversion Repositories Scribus

Rev

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