src/gui/dialogs/qfontdialog.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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 &current, 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