|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the QtGui module of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qwindowdefs.h" |
|
43 |
|
44 #ifndef QT_NO_FONTDIALOG |
|
45 |
|
46 #include "qfontdialog.h" |
|
47 #include "qfontdialog_p.h" |
|
48 |
|
49 #include <qapplication.h> |
|
50 #include <qcheckbox.h> |
|
51 #include <qcombobox.h> |
|
52 #include <qevent.h> |
|
53 #include <qfontdatabase.h> |
|
54 #include <qgroupbox.h> |
|
55 #include <qlabel.h> |
|
56 #include <qlayout.h> |
|
57 #include <qlineedit.h> |
|
58 #include <qpushbutton.h> |
|
59 #include <qstyle.h> |
|
60 #include <qdialogbuttonbox.h> |
|
61 #include <qheaderview.h> |
|
62 #include <qlistview.h> |
|
63 #include <qstringlistmodel.h> |
|
64 #include <qvalidator.h> |
|
65 #include <private/qdialog_p.h> |
|
66 #include <private/qfont_p.h> |
|
67 |
|
68 #if defined(Q_WS_S60) |
|
69 #include <QtGui/qdesktopwidget.h> |
|
70 #endif |
|
71 |
|
72 QT_BEGIN_NAMESPACE |
|
73 |
|
74 class QFontListView : public QListView |
|
75 { |
|
76 Q_OBJECT |
|
77 public: |
|
78 QFontListView(QWidget *parent); |
|
79 inline QStringListModel *model() const { |
|
80 return static_cast<QStringListModel *>(QListView::model()); |
|
81 } |
|
82 inline void setCurrentItem(int item) { |
|
83 QListView::setCurrentIndex(static_cast<QAbstractListModel*>(model())->index(item)); |
|
84 } |
|
85 inline int currentItem() const { |
|
86 return QListView::currentIndex().row(); |
|
87 } |
|
88 inline int count() const { |
|
89 return model()->rowCount(); |
|
90 } |
|
91 inline QString currentText() const { |
|
92 int row = QListView::currentIndex().row(); |
|
93 return row < 0 ? QString() : model()->stringList().at(row); |
|
94 } |
|
95 void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { |
|
96 QListView::currentChanged(current, previous); |
|
97 if (current.isValid()) |
|
98 emit highlighted(current.row()); |
|
99 } |
|
100 QString text(int i) const { |
|
101 return model()->stringList().at(i); |
|
102 } |
|
103 signals: |
|
104 void highlighted(int); |
|
105 }; |
|
106 |
|
107 QFontListView::QFontListView(QWidget *parent) |
|
108 : QListView(parent) |
|
109 { |
|
110 setModel(new QStringListModel(parent)); |
|
111 setEditTriggers(NoEditTriggers); |
|
112 } |
|
113 |
|
114 static const Qt::WindowFlags DefaultWindowFlags = |
|
115 Qt::Dialog | Qt::WindowSystemMenuHint; |
|
116 |
|
117 /*! |
|
118 \class QFontDialog |
|
119 \ingroup standard-dialogs |
|
120 |
|
121 \brief The QFontDialog class provides a dialog widget for selecting a font. |
|
122 |
|
123 A font dialog is created through one of the static getFont() |
|
124 functions. |
|
125 |
|
126 Examples: |
|
127 |
|
128 \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 0 |
|
129 |
|
130 The dialog can also be used to set a widget's font directly: |
|
131 \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 1 |
|
132 If the user clicks OK the font they chose will be used for myWidget, |
|
133 and if they click Cancel the original font is used. |
|
134 |
|
135 \image plastique-fontdialog.png A font dialog in the Plastique widget style. |
|
136 |
|
137 \sa QFont, QFontInfo, QFontMetrics, QColorDialog, QFileDialog, QPrintDialog, |
|
138 {Standard Dialogs Example} |
|
139 */ |
|
140 |
|
141 /*! |
|
142 \since 4.5 |
|
143 |
|
144 Constructs a standard font dialog. |
|
145 |
|
146 Use setCurrentFont() to set the initial font attributes. |
|
147 |
|
148 The \a parent parameter is passed to the QDialog constructor. |
|
149 |
|
150 \sa getFont() |
|
151 */ |
|
152 QFontDialog::QFontDialog(QWidget *parent) |
|
153 : QDialog(*new QFontDialogPrivate, parent, DefaultWindowFlags) |
|
154 { |
|
155 Q_D(QFontDialog); |
|
156 d->init(); |
|
157 } |
|
158 |
|
159 /*! |
|
160 \since 4.5 |
|
161 |
|
162 Constructs a standard font dialog with the given \a parent and specified |
|
163 \a initial color. |
|
164 */ |
|
165 QFontDialog::QFontDialog(const QFont &initial, QWidget *parent) |
|
166 : QDialog(*new QFontDialogPrivate, parent, DefaultWindowFlags) |
|
167 { |
|
168 Q_D(QFontDialog); |
|
169 d->init(); |
|
170 setCurrentFont(initial); |
|
171 } |
|
172 |
|
173 void QFontDialogPrivate::init() |
|
174 { |
|
175 Q_Q(QFontDialog); |
|
176 |
|
177 q->setSizeGripEnabled(true); |
|
178 q->setWindowTitle(QFontDialog::tr("Select Font")); |
|
179 |
|
180 // grid |
|
181 familyEdit = new QLineEdit(q); |
|
182 familyEdit->setReadOnly(true); |
|
183 familyList = new QFontListView(q); |
|
184 familyEdit->setFocusProxy(familyList); |
|
185 |
|
186 familyAccel = new QLabel(q); |
|
187 #ifndef QT_NO_SHORTCUT |
|
188 familyAccel->setBuddy(familyList); |
|
189 #endif |
|
190 familyAccel->setIndent(2); |
|
191 |
|
192 styleEdit = new QLineEdit(q); |
|
193 styleEdit->setReadOnly(true); |
|
194 styleList = new QFontListView(q); |
|
195 styleEdit->setFocusProxy(styleList); |
|
196 |
|
197 styleAccel = new QLabel(q); |
|
198 #ifndef QT_NO_SHORTCUT |
|
199 styleAccel->setBuddy(styleList); |
|
200 #endif |
|
201 styleAccel->setIndent(2); |
|
202 |
|
203 sizeEdit = new QLineEdit(q); |
|
204 sizeEdit->setFocusPolicy(Qt::ClickFocus); |
|
205 QIntValidator *validator = new QIntValidator(1, 512, q); |
|
206 sizeEdit->setValidator(validator); |
|
207 sizeList = new QFontListView(q); |
|
208 |
|
209 sizeAccel = new QLabel(q); |
|
210 #ifndef QT_NO_SHORTCUT |
|
211 sizeAccel->setBuddy(sizeEdit); |
|
212 #endif |
|
213 sizeAccel->setIndent(2); |
|
214 |
|
215 // effects box |
|
216 effects = new QGroupBox(q); |
|
217 QVBoxLayout *vbox = new QVBoxLayout(effects); |
|
218 strikeout = new QCheckBox(effects); |
|
219 vbox->addWidget(strikeout); |
|
220 underline = new QCheckBox(effects); |
|
221 vbox->addWidget(underline); |
|
222 |
|
223 sample = new QGroupBox(q); |
|
224 QHBoxLayout *hbox = new QHBoxLayout(sample); |
|
225 sampleEdit = new QLineEdit(sample); |
|
226 sampleEdit->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)); |
|
227 sampleEdit->setAlignment(Qt::AlignCenter); |
|
228 // Note that the sample text is *not* translated with tr(), as the |
|
229 // characters used depend on the charset encoding. |
|
230 sampleEdit->setText(QLatin1String("AaBbYyZz")); |
|
231 hbox->addWidget(sampleEdit); |
|
232 |
|
233 writingSystemCombo = new QComboBox(q); |
|
234 |
|
235 writingSystemAccel = new QLabel(q); |
|
236 #ifndef QT_NO_SHORTCUT |
|
237 writingSystemAccel->setBuddy(writingSystemCombo); |
|
238 #endif |
|
239 writingSystemAccel->setIndent(2); |
|
240 |
|
241 size = 0; |
|
242 smoothScalable = false; |
|
243 |
|
244 QObject::connect(writingSystemCombo, SIGNAL(activated(int)), q, SLOT(_q_writingSystemHighlighted(int))); |
|
245 QObject::connect(familyList, SIGNAL(highlighted(int)), q, SLOT(_q_familyHighlighted(int))); |
|
246 QObject::connect(styleList, SIGNAL(highlighted(int)), q, SLOT(_q_styleHighlighted(int))); |
|
247 QObject::connect(sizeList, SIGNAL(highlighted(int)), q, SLOT(_q_sizeHighlighted(int))); |
|
248 QObject::connect(sizeEdit, SIGNAL(textChanged(QString)), q, SLOT(_q_sizeChanged(QString))); |
|
249 |
|
250 QObject::connect(strikeout, SIGNAL(clicked()), q, SLOT(_q_updateSample())); |
|
251 QObject::connect(underline, SIGNAL(clicked()), q, SLOT(_q_updateSample())); |
|
252 |
|
253 for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) { |
|
254 QFontDatabase::WritingSystem ws = QFontDatabase::WritingSystem(i); |
|
255 QString writingSystemName = QFontDatabase::writingSystemName(ws); |
|
256 if (writingSystemName.isEmpty()) |
|
257 break; |
|
258 writingSystemCombo->addItem(writingSystemName); |
|
259 } |
|
260 |
|
261 updateFamilies(); |
|
262 if (familyList->count() != 0) |
|
263 familyList->setCurrentItem(0); |
|
264 |
|
265 // grid layout |
|
266 QGridLayout *mainGrid = new QGridLayout(q); |
|
267 |
|
268 int spacing = mainGrid->spacing(); |
|
269 if (spacing >= 0) { // uniform spacing |
|
270 mainGrid->setSpacing(0); |
|
271 |
|
272 mainGrid->setColumnMinimumWidth(1, spacing); |
|
273 mainGrid->setColumnMinimumWidth(3, spacing); |
|
274 |
|
275 int margin = 0; |
|
276 mainGrid->getContentsMargins(0, 0, 0, &margin); |
|
277 |
|
278 mainGrid->setRowMinimumHeight(3, margin); |
|
279 mainGrid->setRowMinimumHeight(6, 2); |
|
280 mainGrid->setRowMinimumHeight(8, margin); |
|
281 } |
|
282 |
|
283 mainGrid->addWidget(familyAccel, 0, 0); |
|
284 mainGrid->addWidget(familyEdit, 1, 0); |
|
285 mainGrid->addWidget(familyList, 2, 0); |
|
286 |
|
287 mainGrid->addWidget(styleAccel, 0, 2); |
|
288 mainGrid->addWidget(styleEdit, 1, 2); |
|
289 mainGrid->addWidget(styleList, 2, 2); |
|
290 |
|
291 mainGrid->addWidget(sizeAccel, 0, 4); |
|
292 mainGrid->addWidget(sizeEdit, 1, 4); |
|
293 mainGrid->addWidget(sizeList, 2, 4); |
|
294 |
|
295 mainGrid->setColumnStretch(0, 38); |
|
296 mainGrid->setColumnStretch(2, 24); |
|
297 mainGrid->setColumnStretch(4, 10); |
|
298 |
|
299 mainGrid->addWidget(effects, 4, 0); |
|
300 |
|
301 mainGrid->addWidget(sample, 4, 2, 4, 3); |
|
302 |
|
303 mainGrid->addWidget(writingSystemAccel, 5, 0); |
|
304 mainGrid->addWidget(writingSystemCombo, 7, 0); |
|
305 |
|
306 buttonBox = new QDialogButtonBox(q); |
|
307 mainGrid->addWidget(buttonBox, 9, 0, 1, 5); |
|
308 |
|
309 QPushButton *button |
|
310 = static_cast<QPushButton *>(buttonBox->addButton(QDialogButtonBox::Ok)); |
|
311 QObject::connect(buttonBox, SIGNAL(accepted()), q, SLOT(accept())); |
|
312 button->setDefault(true); |
|
313 |
|
314 buttonBox->addButton(QDialogButtonBox::Cancel); |
|
315 QObject::connect(buttonBox, SIGNAL(rejected()), q, SLOT(reject())); |
|
316 |
|
317 #if defined(Q_WS_WINCE) |
|
318 q->resize(180, 120); |
|
319 #elif defined(Q_WS_S60) |
|
320 q->resize(QApplication::desktop()->availableGeometry(QCursor::pos()).size()); |
|
321 #else |
|
322 q->resize(500, 360); |
|
323 #endif // Q_WS_WINCE |
|
324 |
|
325 sizeEdit->installEventFilter(q); |
|
326 familyList->installEventFilter(q); |
|
327 styleList->installEventFilter(q); |
|
328 sizeList->installEventFilter(q); |
|
329 |
|
330 familyList->setFocus(); |
|
331 retranslateStrings(); |
|
332 |
|
333 #ifdef Q_WS_MAC |
|
334 delegate = 0; |
|
335 #endif |
|
336 } |
|
337 |
|
338 /*! |
|
339 \internal |
|
340 Destroys the font dialog and frees up its storage. |
|
341 */ |
|
342 |
|
343 QFontDialog::~QFontDialog() |
|
344 { |
|
345 #ifdef Q_WS_MAC |
|
346 Q_D(QFontDialog); |
|
347 if (d->delegate) { |
|
348 QFontDialogPrivate::closeCocoaFontPanel(d->delegate); |
|
349 QFontDialogPrivate::sharedFontPanelAvailable = true; |
|
350 return; |
|
351 } |
|
352 #endif |
|
353 } |
|
354 |
|
355 /*! |
|
356 Executes a modal font dialog and returns a font. |
|
357 |
|
358 If the user clicks \gui OK, the selected font is returned. If the user |
|
359 clicks \gui Cancel, the \a initial font is returned. |
|
360 |
|
361 The dialog is constructed with the given \a parent and the options specified |
|
362 in \a options. \a title is shown as the window title of the dialog and \a |
|
363 initial is the initially selected font. If the \a ok parameter is not-null, |
|
364 the value it refers to is set to true if the user clicks \gui OK, and set to |
|
365 false if the user clicks \gui Cancel. |
|
366 |
|
367 Examples: |
|
368 \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 2 |
|
369 |
|
370 The dialog can also be used to set a widget's font directly: |
|
371 \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 3 |
|
372 In this example, if the user clicks OK the font they chose will be |
|
373 used, and if they click Cancel the original font is used. |
|
374 |
|
375 \warning Do not delete \a parent during the execution of the dialog. |
|
376 If you want to do this, you should create the dialog |
|
377 yourself using one of the QFontDialog constructors. |
|
378 */ |
|
379 QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent, const QString &title, |
|
380 FontDialogOptions options) |
|
381 { |
|
382 return QFontDialogPrivate::getFont(ok, initial, parent, title, options); |
|
383 } |
|
384 |
|
385 /*! |
|
386 \overload |
|
387 \since 4.5 |
|
388 */ |
|
389 QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent, const QString &title) |
|
390 { |
|
391 return QFontDialogPrivate::getFont(ok, initial, parent, title, 0); |
|
392 } |
|
393 |
|
394 /*! |
|
395 \overload |
|
396 */ |
|
397 QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent) |
|
398 { |
|
399 return QFontDialogPrivate::getFont(ok, initial, parent, QString(), 0); |
|
400 } |
|
401 |
|
402 /*! |
|
403 \overload |
|
404 |
|
405 Executes a modal font dialog and returns a font. |
|
406 |
|
407 If the user clicks \gui OK, the selected font is returned. If the user |
|
408 clicks \gui Cancel, the Qt default font is returned. |
|
409 |
|
410 The dialog is constructed with the given \a parent. |
|
411 If the \a ok parameter is not-null, the value it refers to is set |
|
412 to true if the user clicks \gui OK, and false if the user clicks |
|
413 \gui Cancel. |
|
414 |
|
415 Example: |
|
416 \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 4 |
|
417 |
|
418 \warning Do not delete \a parent during the execution of the dialog. |
|
419 If you want to do this, you should create the dialog |
|
420 yourself using one of the QFontDialog constructors. |
|
421 */ |
|
422 QFont QFontDialog::getFont(bool *ok, QWidget *parent) |
|
423 { |
|
424 QFont initial; |
|
425 return QFontDialogPrivate::getFont(ok, initial, parent, QString(), 0); |
|
426 } |
|
427 |
|
428 QFont QFontDialogPrivate::getFont(bool *ok, const QFont &initial, QWidget *parent, |
|
429 const QString &title, QFontDialog::FontDialogOptions options) |
|
430 { |
|
431 #ifdef Q_WS_MAC |
|
432 if (!(options & QFontDialog::DontUseNativeDialog) |
|
433 && QFontDialogPrivate::sharedFontPanelAvailable) { |
|
434 return QFontDialogPrivate::execCocoaFontPanel(ok, initial, parent, |
|
435 title.isEmpty() ? QFontDialog::tr("Select Font") : title, options); |
|
436 } |
|
437 #endif |
|
438 |
|
439 QFontDialog dlg(parent); |
|
440 dlg.setOptions(options); |
|
441 dlg.setCurrentFont(initial); |
|
442 if (!title.isEmpty()) |
|
443 dlg.setWindowTitle(title); |
|
444 |
|
445 int ret = (dlg.exec() || (options & QFontDialog::NoButtons)); |
|
446 if (ok) |
|
447 *ok = !!ret; |
|
448 if (ret) { |
|
449 return dlg.selectedFont(); |
|
450 } else { |
|
451 return initial; |
|
452 } |
|
453 } |
|
454 |
|
455 /*! |
|
456 \internal |
|
457 An event filter to make the Up, Down, PageUp and PageDown keys work |
|
458 correctly in the line edits. The source of the event is the object |
|
459 \a o and the event is \a e. |
|
460 */ |
|
461 |
|
462 bool QFontDialog::eventFilter(QObject *o , QEvent *e) |
|
463 { |
|
464 Q_D(QFontDialog); |
|
465 if (e->type() == QEvent::KeyPress) { |
|
466 QKeyEvent *k = (QKeyEvent *)e; |
|
467 if (o == d->sizeEdit && |
|
468 (k->key() == Qt::Key_Up || |
|
469 k->key() == Qt::Key_Down || |
|
470 k->key() == Qt::Key_PageUp || |
|
471 k->key() == Qt::Key_PageDown)) { |
|
472 |
|
473 int ci = d->sizeList->currentItem(); |
|
474 (void)QApplication::sendEvent(d->sizeList, k); |
|
475 |
|
476 if (ci != d->sizeList->currentItem() |
|
477 && style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, this)) |
|
478 d->sizeEdit->selectAll(); |
|
479 return true; |
|
480 } else if ((o == d->familyList || o == d->styleList) && |
|
481 (k->key() == Qt::Key_Return || k->key() == Qt::Key_Enter)) { |
|
482 k->accept(); |
|
483 accept(); |
|
484 return true; |
|
485 } |
|
486 } else if (e->type() == QEvent::FocusIn |
|
487 && style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, this)) { |
|
488 if (o == d->familyList) |
|
489 d->familyEdit->selectAll(); |
|
490 else if (o == d->styleList) |
|
491 d->styleEdit->selectAll(); |
|
492 else if (o == d->sizeList) |
|
493 d->sizeEdit->selectAll(); |
|
494 } else if (e->type() == QEvent::MouseButtonPress && o == d->sizeList) { |
|
495 d->sizeEdit->setFocus(); |
|
496 } |
|
497 return QDialog::eventFilter(o, e); |
|
498 } |
|
499 |
|
500 /* |
|
501 Updates the contents of the "font family" list box. This |
|
502 function can be reimplemented if you have special requirements. |
|
503 */ |
|
504 |
|
505 void QFontDialogPrivate::updateFamilies() |
|
506 { |
|
507 Q_Q(QFontDialog); |
|
508 |
|
509 enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 }; |
|
510 |
|
511 QStringList familyNames = fdb.families(writingSystem); |
|
512 |
|
513 familyList->model()->setStringList(familyNames); |
|
514 |
|
515 QString foundryName1, familyName1, foundryName2, familyName2; |
|
516 int bestFamilyMatch = -1; |
|
517 match_t bestFamilyType = MATCH_NONE; |
|
518 |
|
519 QFont f; |
|
520 |
|
521 // ##### do the right thing for a list of family names in the font. |
|
522 QFontDatabase::parseFontName(family, foundryName1, familyName1); |
|
523 |
|
524 QStringList::const_iterator it = familyNames.constBegin(); |
|
525 int i = 0; |
|
526 for(; it != familyNames.constEnd(); ++it, ++i) { |
|
527 QFontDatabase::parseFontName(*it, foundryName2, familyName2); |
|
528 |
|
529 //try to match... |
|
530 if (familyName1 == familyName2) { |
|
531 bestFamilyType = MATCH_FAMILY; |
|
532 if (foundryName1 == foundryName2) { |
|
533 bestFamilyMatch = i; |
|
534 break; |
|
535 } |
|
536 if (bestFamilyMatch < MATCH_FAMILY) |
|
537 bestFamilyMatch = i; |
|
538 } |
|
539 |
|
540 //and try some fall backs |
|
541 match_t type = MATCH_NONE; |
|
542 if (bestFamilyType <= MATCH_NONE && familyName2 == f.lastResortFamily()) |
|
543 type = MATCH_LAST_RESORT; |
|
544 if (bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.family()) |
|
545 type = MATCH_APP; |
|
546 // ### add fallback for writingSystem |
|
547 if (type != MATCH_NONE) { |
|
548 bestFamilyType = type; |
|
549 bestFamilyMatch = i; |
|
550 } |
|
551 } |
|
552 |
|
553 if (i != -1 && bestFamilyType != MATCH_NONE) |
|
554 familyList->setCurrentItem(bestFamilyMatch); |
|
555 else |
|
556 familyList->setCurrentItem(0); |
|
557 familyEdit->setText(familyList->currentText()); |
|
558 if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q) |
|
559 && familyList->hasFocus()) |
|
560 familyEdit->selectAll(); |
|
561 |
|
562 updateStyles(); |
|
563 } |
|
564 |
|
565 /* |
|
566 Updates the contents of the "font style" list box. This |
|
567 function can be reimplemented if you have special requirements. |
|
568 */ |
|
569 void QFontDialogPrivate::updateStyles() |
|
570 { |
|
571 Q_Q(QFontDialog); |
|
572 QStringList styles = fdb.styles(familyList->currentText()); |
|
573 styleList->model()->setStringList(styles); |
|
574 |
|
575 if (styles.isEmpty()) { |
|
576 styleEdit->clear(); |
|
577 smoothScalable = false; |
|
578 } else { |
|
579 if (!style.isEmpty()) { |
|
580 bool found = false; |
|
581 bool first = true; |
|
582 QString cstyle = style; |
|
583 |
|
584 redo: |
|
585 for (int i = 0; i < (int)styleList->count(); i++) { |
|
586 if (cstyle == styleList->text(i)) { |
|
587 styleList->setCurrentItem(i); |
|
588 found = true; |
|
589 break; |
|
590 } |
|
591 } |
|
592 if (!found && first) { |
|
593 if (cstyle.contains(QLatin1String("Italic"))) { |
|
594 cstyle.replace(QLatin1String("Italic"), QLatin1String("Oblique")); |
|
595 first = false; |
|
596 goto redo; |
|
597 } else if (cstyle.contains(QLatin1String("Oblique"))) { |
|
598 cstyle.replace(QLatin1String("Oblique"), QLatin1String("Italic")); |
|
599 first = false; |
|
600 goto redo; |
|
601 } |
|
602 } |
|
603 if (!found) |
|
604 styleList->setCurrentItem(0); |
|
605 } else { |
|
606 styleList->setCurrentItem(0); |
|
607 } |
|
608 |
|
609 styleEdit->setText(styleList->currentText()); |
|
610 if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q) |
|
611 && styleList->hasFocus()) |
|
612 styleEdit->selectAll(); |
|
613 |
|
614 smoothScalable = fdb.isSmoothlyScalable(familyList->currentText(), styleList->currentText()); |
|
615 } |
|
616 |
|
617 updateSizes(); |
|
618 } |
|
619 |
|
620 /*! |
|
621 \internal |
|
622 Updates the contents of the "font size" list box. This |
|
623 function can be reimplemented if you have special requirements. |
|
624 */ |
|
625 |
|
626 void QFontDialogPrivate::updateSizes() |
|
627 { |
|
628 Q_Q(QFontDialog); |
|
629 |
|
630 if (!familyList->currentText().isEmpty()) { |
|
631 QList<int> sizes = fdb.pointSizes(familyList->currentText(), styleList->currentText()); |
|
632 |
|
633 int i = 0; |
|
634 int current = -1; |
|
635 QStringList str_sizes; |
|
636 for(QList<int>::const_iterator it = sizes.constBegin(); it != sizes.constEnd(); ++it) { |
|
637 str_sizes.append(QString::number(*it)); |
|
638 if (current == -1 && *it >= size) |
|
639 current = i; |
|
640 ++i; |
|
641 } |
|
642 sizeList->model()->setStringList(str_sizes); |
|
643 if (current == -1) { |
|
644 // we request a size bigger than the ones in the list, select the biggest one |
|
645 current = sizeList->count() - 1; |
|
646 } |
|
647 sizeList->setCurrentItem(current); |
|
648 |
|
649 sizeEdit->blockSignals(true); |
|
650 sizeEdit->setText((smoothScalable ? QString::number(size) : sizeList->currentText())); |
|
651 if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q) |
|
652 && sizeList->hasFocus()) |
|
653 sizeEdit->selectAll(); |
|
654 sizeEdit->blockSignals(false); |
|
655 } else { |
|
656 sizeEdit->clear(); |
|
657 } |
|
658 |
|
659 _q_updateSample(); |
|
660 } |
|
661 |
|
662 void QFontDialogPrivate::_q_updateSample() |
|
663 { |
|
664 // compute new font |
|
665 int pSize = sizeEdit->text().toInt(); |
|
666 QFont newFont(fdb.font(familyList->currentText(), style, pSize)); |
|
667 newFont.setStrikeOut(strikeout->isChecked()); |
|
668 newFont.setUnderline(underline->isChecked()); |
|
669 |
|
670 if (familyList->currentText().isEmpty()) |
|
671 sampleEdit->clear(); |
|
672 |
|
673 updateSampleFont(newFont); |
|
674 } |
|
675 |
|
676 void QFontDialogPrivate::updateSampleFont(const QFont &newFont) |
|
677 { |
|
678 Q_Q(QFontDialog); |
|
679 if (newFont != sampleEdit->font()) { |
|
680 sampleEdit->setFont(newFont); |
|
681 emit q->currentFontChanged(newFont); |
|
682 } |
|
683 } |
|
684 |
|
685 /*! |
|
686 \internal |
|
687 */ |
|
688 void QFontDialogPrivate::_q_writingSystemHighlighted(int index) |
|
689 { |
|
690 writingSystem = QFontDatabase::WritingSystem(index); |
|
691 sampleEdit->setText(fdb.writingSystemSample(writingSystem)); |
|
692 updateFamilies(); |
|
693 } |
|
694 |
|
695 /*! |
|
696 \internal |
|
697 */ |
|
698 void QFontDialogPrivate::_q_familyHighlighted(int i) |
|
699 { |
|
700 Q_Q(QFontDialog); |
|
701 family = familyList->text(i); |
|
702 familyEdit->setText(family); |
|
703 if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q) |
|
704 && familyList->hasFocus()) |
|
705 familyEdit->selectAll(); |
|
706 |
|
707 updateStyles(); |
|
708 } |
|
709 |
|
710 |
|
711 /*! |
|
712 \internal |
|
713 */ |
|
714 |
|
715 void QFontDialogPrivate::_q_styleHighlighted(int index) |
|
716 { |
|
717 Q_Q(QFontDialog); |
|
718 QString s = styleList->text(index); |
|
719 styleEdit->setText(s); |
|
720 if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q) |
|
721 && styleList->hasFocus()) |
|
722 styleEdit->selectAll(); |
|
723 |
|
724 style = s; |
|
725 |
|
726 updateSizes(); |
|
727 } |
|
728 |
|
729 |
|
730 /*! |
|
731 \internal |
|
732 */ |
|
733 |
|
734 void QFontDialogPrivate::_q_sizeHighlighted(int index) |
|
735 { |
|
736 Q_Q(QFontDialog); |
|
737 QString s = sizeList->text(index); |
|
738 sizeEdit->setText(s); |
|
739 if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q) |
|
740 && sizeEdit->hasFocus()) |
|
741 sizeEdit->selectAll(); |
|
742 |
|
743 size = s.toInt(); |
|
744 _q_updateSample(); |
|
745 } |
|
746 |
|
747 /*! |
|
748 \internal |
|
749 This slot is called if the user changes the font size. |
|
750 The size is passed in the \a s argument as a \e string. |
|
751 */ |
|
752 |
|
753 void QFontDialogPrivate::_q_sizeChanged(const QString &s) |
|
754 { |
|
755 // no need to check if the conversion is valid, since we have an QIntValidator in the size edit |
|
756 int size = s.toInt(); |
|
757 if (this->size == size) |
|
758 return; |
|
759 |
|
760 this->size = size; |
|
761 if (sizeList->count() != 0) { |
|
762 int i; |
|
763 for (i = 0; i < sizeList->count() - 1; i++) { |
|
764 if (sizeList->text(i).toInt() >= this->size) |
|
765 break; |
|
766 } |
|
767 sizeList->blockSignals(true); |
|
768 sizeList->setCurrentItem(i); |
|
769 sizeList->blockSignals(false); |
|
770 } |
|
771 _q_updateSample(); |
|
772 } |
|
773 |
|
774 void QFontDialogPrivate::retranslateStrings() |
|
775 { |
|
776 familyAccel->setText(QFontDialog::tr("&Font")); |
|
777 styleAccel->setText(QFontDialog::tr("Font st&yle")); |
|
778 sizeAccel->setText(QFontDialog::tr("&Size")); |
|
779 #ifndef Q_WS_S60 |
|
780 // Removed the title due to lack of screen estate in small S60 screen. |
|
781 // The effects are descriptive without a title (strikeout, underline). |
|
782 effects->setTitle(QFontDialog::tr("Effects")); |
|
783 #endif |
|
784 strikeout->setText(QFontDialog::tr("Stri&keout")); |
|
785 underline->setText(QFontDialog::tr("&Underline")); |
|
786 sample->setTitle(QFontDialog::tr("Sample")); |
|
787 writingSystemAccel->setText(QFontDialog::tr("Wr&iting System")); |
|
788 } |
|
789 |
|
790 /*! |
|
791 \reimp |
|
792 */ |
|
793 void QFontDialog::changeEvent(QEvent *e) |
|
794 { |
|
795 Q_D(QFontDialog); |
|
796 if (e->type() == QEvent::LanguageChange) { |
|
797 d->retranslateStrings(); |
|
798 } |
|
799 QDialog::changeEvent(e); |
|
800 } |
|
801 |
|
802 /*! |
|
803 \since 4.5 |
|
804 |
|
805 \property QFontDialog::currentFont |
|
806 \brief the current font of the dialog. |
|
807 */ |
|
808 |
|
809 /*! |
|
810 \since 4.5 |
|
811 |
|
812 Sets the font highlighted in the QFontDialog to the given \a font. |
|
813 |
|
814 \sa selectedFont() |
|
815 */ |
|
816 void QFontDialog::setCurrentFont(const QFont &font) |
|
817 { |
|
818 Q_D(QFontDialog); |
|
819 d->family = font.family(); |
|
820 d->style = d->fdb.styleString(font); |
|
821 d->size = font.pointSize(); |
|
822 if (d->size == -1) { |
|
823 QFontInfo fi(font); |
|
824 d->size = fi.pointSize(); |
|
825 } |
|
826 d->strikeout->setChecked(font.strikeOut()); |
|
827 d->underline->setChecked(font.underline()); |
|
828 d->updateFamilies(); |
|
829 |
|
830 #ifdef Q_WS_MAC |
|
831 if (d->delegate) |
|
832 QFontDialogPrivate::setFont(d->delegate, font); |
|
833 #endif |
|
834 } |
|
835 |
|
836 /*! |
|
837 \since 4.5 |
|
838 |
|
839 Returns the current font. |
|
840 |
|
841 \sa selectedFont() |
|
842 */ |
|
843 QFont QFontDialog::currentFont() const |
|
844 { |
|
845 Q_D(const QFontDialog); |
|
846 return d->sampleEdit->font(); |
|
847 } |
|
848 |
|
849 /*! |
|
850 Returns the font that the user selected by clicking the \gui{OK} |
|
851 or equivalent button. |
|
852 |
|
853 \note This font is not always the same as the font held by the |
|
854 \l currentFont property since the user can choose different fonts |
|
855 before finally selecting the one to use. |
|
856 */ |
|
857 QFont QFontDialog::selectedFont() const |
|
858 { |
|
859 Q_D(const QFontDialog); |
|
860 return d->selectedFont; |
|
861 } |
|
862 |
|
863 /*! |
|
864 \enum QFontDialog::FontDialogOption |
|
865 \since 4.5 |
|
866 |
|
867 This enum specifies various options that affect the look and feel |
|
868 of a font dialog. |
|
869 |
|
870 \value NoButtons Don't display \gui{OK} and \gui{Cancel} buttons. (Useful for "live dialogs".) |
|
871 \value DontUseNativeDialog Use Qt's standard font dialog on the Mac instead of Apple's |
|
872 native font panel. (Currently, the native dialog is never used, |
|
873 but this is likely to change in future Qt releases.) |
|
874 |
|
875 \sa options, setOption(), testOption() |
|
876 */ |
|
877 |
|
878 /*! |
|
879 Sets the given \a option to be enabled if \a on is true; |
|
880 otherwise, clears the given \a option. |
|
881 |
|
882 \sa options, testOption() |
|
883 */ |
|
884 void QFontDialog::setOption(FontDialogOption option, bool on) |
|
885 { |
|
886 Q_D(QFontDialog); |
|
887 if (!(d->opts & option) != !on) |
|
888 setOptions(d->opts ^ option); |
|
889 } |
|
890 |
|
891 /*! |
|
892 Returns true if the given \a option is enabled; otherwise, returns |
|
893 false. |
|
894 |
|
895 \sa options, setOption() |
|
896 */ |
|
897 bool QFontDialog::testOption(FontDialogOption option) const |
|
898 { |
|
899 Q_D(const QFontDialog); |
|
900 return (d->opts & option) != 0; |
|
901 } |
|
902 |
|
903 /*! |
|
904 \property QFontDialog::options |
|
905 \brief the various options that affect the look and feel of the dialog |
|
906 \since 4.5 |
|
907 |
|
908 By default, all options are disabled. |
|
909 |
|
910 Options should be set before showing the dialog. Setting them while the |
|
911 dialog is visible is not guaranteed to have an immediate effect on the |
|
912 dialog (depending on the option and on the platform). |
|
913 |
|
914 \sa setOption(), testOption() |
|
915 */ |
|
916 void QFontDialog::setOptions(FontDialogOptions options) |
|
917 { |
|
918 Q_D(QFontDialog); |
|
919 |
|
920 FontDialogOptions changed = (options ^ d->opts); |
|
921 if (!changed) |
|
922 return; |
|
923 |
|
924 d->opts = options; |
|
925 d->buttonBox->setVisible(!(options & NoButtons)); |
|
926 } |
|
927 |
|
928 QFontDialog::FontDialogOptions QFontDialog::options() const |
|
929 { |
|
930 Q_D(const QFontDialog); |
|
931 return d->opts; |
|
932 } |
|
933 |
|
934 #ifdef Q_WS_MAC |
|
935 // can only have one Cocoa font panel active |
|
936 bool QFontDialogPrivate::sharedFontPanelAvailable = true; |
|
937 #endif |
|
938 |
|
939 /*! |
|
940 \since 4.5 |
|
941 \overload |
|
942 |
|
943 Opens the dialog and connects its fontSelected() signal to the slot specified |
|
944 by \a receiver and \a member. |
|
945 |
|
946 The signal will be disconnected from the slot when the dialog is closed. |
|
947 */ |
|
948 void QFontDialog::open(QObject *receiver, const char *member) |
|
949 { |
|
950 Q_D(QFontDialog); |
|
951 connect(this, SIGNAL(fontSelected(const QFont&)), receiver, member); |
|
952 d->receiverToDisconnectOnClose = receiver; |
|
953 d->memberToDisconnectOnClose = member; |
|
954 QDialog::open(); |
|
955 } |
|
956 |
|
957 /*! |
|
958 \since 4.5 |
|
959 |
|
960 \fn void QFontDialog::currentFontChanged(const QFont &font) |
|
961 |
|
962 This signal is emitted when the current font is changed. The new font is |
|
963 specified in \a font. |
|
964 |
|
965 The signal is emitted while a user is selecting a font. Ultimately, the |
|
966 chosen font may differ from the font currently selected. |
|
967 |
|
968 \sa currentFont, fontSelected(), selectedFont() |
|
969 */ |
|
970 |
|
971 /*! |
|
972 \since 4.5 |
|
973 |
|
974 \fn void QFontDialog::fontSelected(const QFont &font) |
|
975 |
|
976 This signal is emitted when a font has been selected. The selected font is |
|
977 specified in \a font. |
|
978 |
|
979 The signal is only emitted when a user has chosen the final font to be |
|
980 used. It is not emitted while the user is changing the current font in the |
|
981 font dialog. |
|
982 |
|
983 \sa selectedFont(), currentFontChanged(), currentFont |
|
984 */ |
|
985 |
|
986 /*! |
|
987 \reimp |
|
988 */ |
|
989 void QFontDialog::setVisible(bool visible) |
|
990 { |
|
991 Q_D(QFontDialog); |
|
992 if (visible) |
|
993 d->selectedFont = QFont(); |
|
994 |
|
995 #if defined(Q_WS_MAC) |
|
996 bool isCurrentlyVisible = (isVisible() || d->delegate); |
|
997 |
|
998 if (!visible == !isCurrentlyVisible) |
|
999 return; |
|
1000 |
|
1001 if (visible) { |
|
1002 if (!(d->opts & DontUseNativeDialog) && QFontDialogPrivate::sharedFontPanelAvailable) { |
|
1003 d->delegate = QFontDialogPrivate::openCocoaFontPanel( |
|
1004 currentFont(), parentWidget(), windowTitle(), options(), d); |
|
1005 QFontDialogPrivate::sharedFontPanelAvailable = false; |
|
1006 return; |
|
1007 } |
|
1008 |
|
1009 setWindowFlags(windowModality() == Qt::WindowModal ? Qt::Sheet : DefaultWindowFlags); |
|
1010 } else { |
|
1011 if (d->delegate) { |
|
1012 QFontDialogPrivate::closeCocoaFontPanel(d->delegate); |
|
1013 d->delegate = 0; |
|
1014 QFontDialogPrivate::sharedFontPanelAvailable = true; |
|
1015 return; |
|
1016 } |
|
1017 } |
|
1018 #endif |
|
1019 |
|
1020 QDialog::setVisible(visible); |
|
1021 } |
|
1022 |
|
1023 /*! |
|
1024 Closes the dialog and sets its result code to \a result. If this dialog |
|
1025 is shown with exec(), done() causes the local event loop to finish, |
|
1026 and exec() to return \a result. |
|
1027 |
|
1028 \sa QDialog::done() |
|
1029 */ |
|
1030 void QFontDialog::done(int result) |
|
1031 { |
|
1032 Q_D(QFontDialog); |
|
1033 QDialog::done(result); |
|
1034 if (result == Accepted) { |
|
1035 d->selectedFont = currentFont(); |
|
1036 emit fontSelected(d->selectedFont); |
|
1037 } else { |
|
1038 d->selectedFont = QFont(); |
|
1039 } |
|
1040 if (d->receiverToDisconnectOnClose) { |
|
1041 disconnect(this, SIGNAL(fontSelected(const QFont&)), |
|
1042 d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose); |
|
1043 d->receiverToDisconnectOnClose = 0; |
|
1044 } |
|
1045 d->memberToDisconnectOnClose.clear(); |
|
1046 } |
|
1047 |
|
1048 /*! |
|
1049 \fn QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget* parent, const char* name) |
|
1050 \since 4.5 |
|
1051 |
|
1052 Call getFont(\a ok, \a initial, \a parent) instead. |
|
1053 |
|
1054 \warning Do not delete \a parent during the execution of the dialog. |
|
1055 If you want to do this, you should create the dialog |
|
1056 yourself using one of the QFontDialog constructors. |
|
1057 |
|
1058 The \a name parameter is ignored. |
|
1059 */ |
|
1060 |
|
1061 /*! |
|
1062 \fn QFont QFontDialog::getFont(bool *ok, QWidget* parent, const char* name) |
|
1063 |
|
1064 Call getFont(\a ok, \a parent) instead. |
|
1065 |
|
1066 \warning Do not delete \a parent during the execution of the dialog. |
|
1067 If you want to do this, you should create the dialog |
|
1068 yourself using one of the QFontDialog constructors. |
|
1069 |
|
1070 The \a name parameter is ignored. |
|
1071 */ |
|
1072 |
|
1073 QT_END_NAMESPACE |
|
1074 |
|
1075 #include "qfontdialog.moc" |
|
1076 #include "moc_qfontdialog.cpp" |
|
1077 |
|
1078 #endif // QT_NO_FONTDIALOG |