source: trunk/src/gui/dialogs/qfontdialog.cpp@ 182

Last change on this file since 182 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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