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 | } |