/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwindowdefs.h"
#include "qfontdialog.h"

#include "qfontdialog_p.h"

#include <qapplication.h>
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qevent.h>
#include <qfontdatabase.h>
#include <qgroupbox.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qstyle.h>
#include <qdialogbuttonbox.h>
#include <qheaderview.h>
#include <qlistview.h>
#include <qstringlistmodel.h>
#include <qvalidator.h>
#include <private/qdialog_p.h>
#include <private/qfont_p.h>

QT_BEGIN_NAMESPACE

class QFontListView : public QListView
{
    Q_OBJECT
public:
    QFontListView(QWidget *parent);
    inline QStringListModel *model() const {
        return static_cast<QStringListModel *>(QListView::model());
    }
    inline void setCurrentItem(int item) {
        QListView::setCurrentIndex(static_cast<QAbstractListModel*>(model())->index(item));
    }
    inline int currentItem() const {
        return QListView::currentIndex().row();
    }
    inline int count() const {
        return model()->rowCount();
    }
    inline QString currentText() const {
        int row = QListView::currentIndex().row();
        return row < 0 ? QString() : model()->stringList().at(row);
    }
    void currentChanged(const QModelIndex &current, const QModelIndex &previous) override {
        QListView::currentChanged(current, previous);
        if (current.isValid())
            emit highlighted(current.row());
    }
    QString text(int i) const {
        return model()->stringList().at(i);
    }
signals:
    void highlighted(int);
};

QFontListView::QFontListView(QWidget *parent)
    : QListView(parent)
{
    setModel(new QStringListModel(parent));
    setEditTriggers(NoEditTriggers);
}

static const Qt::WindowFlags DefaultWindowFlags =
        Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;

QFontDialogPrivate::QFontDialogPrivate()
    : writingSystem(QFontDatabase::Any),
      options(QFontDialogOptions::create())
{
}

QFontDialogPrivate::~QFontDialogPrivate()
{
}

/*!
  \class QFontDialog
  \ingroup standard-dialogs
  \inmodule QtWidgets

  \brief The QFontDialog class provides a dialog widget for selecting a font.

    A font dialog is created through one of the static getFont()
    functions.

  Examples:

  \snippet code/src_gui_dialogs_qfontdialog.cpp 0

    The dialog can also be used to set a widget's font directly:
  \snippet code/src_gui_dialogs_qfontdialog.cpp 1
  If the user clicks OK the font they chose will be used for myWidget,
  and if they click Cancel the original font is used.

  \image fusion-fontdialog.png A font dialog in the Fusion widget style.

  \sa QFont, QFontInfo, QFontMetrics, QColorDialog, QFileDialog,
      {Standard Dialogs Example}
*/

/*!
    \since 4.5

    Constructs a standard font dialog.

    Use setCurrentFont() to set the initial font attributes.

    The \a parent parameter is passed to the QDialog constructor.

    \sa getFont()
*/
QFontDialog::QFontDialog(QWidget *parent)
    : QDialog(*new QFontDialogPrivate, parent, DefaultWindowFlags)
{
    Q_D(QFontDialog);
    d->init();
}

/*!
    \since 4.5

    Constructs a standard font dialog with the given \a parent and specified
    \a initial font.
*/
QFontDialog::QFontDialog(const QFont &initial, QWidget *parent)
    : QFontDialog(parent)
{
    setCurrentFont(initial);
}

void QFontDialogPrivate::init()
{
    Q_Q(QFontDialog);

    q->setSizeGripEnabled(true);
    q->setWindowTitle(QFontDialog::tr("Select Font"));

    // grid
    familyEdit = new QLineEdit(q);
    familyEdit->setReadOnly(true);
    familyList = new QFontListView(q);
    familyEdit->setFocusProxy(familyList);

    familyAccel = new QLabel(q);
#ifndef QT_NO_SHORTCUT
    familyAccel->setBuddy(familyList);
#endif
    familyAccel->setIndent(2);

    styleEdit = new QLineEdit(q);
    styleEdit->setReadOnly(true);
    styleList = new QFontListView(q);
    styleEdit->setFocusProxy(styleList);

    styleAccel = new QLabel(q);
#ifndef QT_NO_SHORTCUT
    styleAccel->setBuddy(styleList);
#endif
    styleAccel->setIndent(2);

    sizeEdit = new QLineEdit(q);
    sizeEdit->setFocusPolicy(Qt::ClickFocus);
    QIntValidator *validator = new QIntValidator(1, 512, q);
    sizeEdit->setValidator(validator);
    sizeList = new QFontListView(q);

    sizeAccel = new QLabel(q);
#ifndef QT_NO_SHORTCUT
    sizeAccel->setBuddy(sizeEdit);
#endif
    sizeAccel->setIndent(2);

    // effects box
    effects = new QGroupBox(q);
    QVBoxLayout *vbox = new QVBoxLayout(effects);
    strikeout = new QCheckBox(effects);
    vbox->addWidget(strikeout);
    underline = new QCheckBox(effects);
    vbox->addWidget(underline);

    sample = new QGroupBox(q);
    QHBoxLayout *hbox = new QHBoxLayout(sample);
    sampleEdit = new QLineEdit(sample);
    sampleEdit->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored));
    sampleEdit->setAlignment(Qt::AlignCenter);
    // Note that the sample text is *not* translated with tr(), as the
    // characters used depend on the charset encoding.
    sampleEdit->setText(QLatin1String("AaBbYyZz"));
    hbox->addWidget(sampleEdit);

    writingSystemCombo = new QComboBox(q);

    writingSystemAccel = new QLabel(q);
#ifndef QT_NO_SHORTCUT
    writingSystemAccel->setBuddy(writingSystemCombo);
#endif
    writingSystemAccel->setIndent(2);

    size = 0;
    smoothScalable = false;

    QObject::connect(writingSystemCombo, SIGNAL(activated(int)), q, SLOT(_q_writingSystemHighlighted(int)));
    QObject::connect(familyList, SIGNAL(highlighted(int)), q, SLOT(_q_familyHighlighted(int)));
    QObject::connect(styleList, SIGNAL(highlighted(int)), q, SLOT(_q_styleHighlighted(int)));
    QObject::connect(sizeList, SIGNAL(highlighted(int)), q, SLOT(_q_sizeHighlighted(int)));
    QObject::connect(sizeEdit, SIGNAL(textChanged(QString)), q, SLOT(_q_sizeChanged(QString)));

    QObject::connect(strikeout, SIGNAL(clicked()), q, SLOT(_q_updateSample()));
    QObject::connect(underline, SIGNAL(clicked()), q, SLOT(_q_updateSample()));

    for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
        QFontDatabase::WritingSystem ws = QFontDatabase::WritingSystem(i);
        QString writingSystemName = QFontDatabase::writingSystemName(ws);
        if (writingSystemName.isEmpty())
            break;
        writingSystemCombo->addItem(writingSystemName);
    }

    updateFamilies();
    if (familyList->count() != 0) {
        familyList->setCurrentItem(0);
        sizeList->setCurrentItem(0);
    }

    // grid layout
    QGridLayout *mainGrid = new QGridLayout(q);

    int spacing = mainGrid->spacing();
    if (spacing >= 0) {     // uniform spacing
       mainGrid->setSpacing(0);

       mainGrid->setColumnMinimumWidth(1, spacing);
       mainGrid->setColumnMinimumWidth(3, spacing);

       int margin = 0;
       mainGrid->getContentsMargins(0, 0, 0, &margin);

       mainGrid->setRowMinimumHeight(3, margin);
       mainGrid->setRowMinimumHeight(6, 2);
       mainGrid->setRowMinimumHeight(8, margin);
    }

    mainGrid->addWidget(familyAccel, 0, 0);
    mainGrid->addWidget(familyEdit, 1, 0);
    mainGrid->addWidget(familyList, 2, 0);

    mainGrid->addWidget(styleAccel, 0, 2);
    mainGrid->addWidget(styleEdit, 1, 2);
    mainGrid->addWidget(styleList, 2, 2);

    mainGrid->addWidget(sizeAccel, 0, 4);
    mainGrid->addWidget(sizeEdit, 1, 4);
    mainGrid->addWidget(sizeList, 2, 4);

    mainGrid->setColumnStretch(0, 38);
    mainGrid->setColumnStretch(2, 24);
    mainGrid->setColumnStretch(4, 10);

    mainGrid->addWidget(effects, 4, 0);

    mainGrid->addWidget(sample, 4, 2, 4, 3);

    mainGrid->addWidget(writingSystemAccel, 5, 0);
    mainGrid->addWidget(writingSystemCombo, 7, 0);

    buttonBox = new QDialogButtonBox(q);
    mainGrid->addWidget(buttonBox, 9, 0, 1, 5);

    QPushButton *button
            = static_cast<QPushButton *>(buttonBox->addButton(QDialogButtonBox::Ok));
    QObject::connect(buttonBox, SIGNAL(accepted()), q, SLOT(accept()));
    button->setDefault(true);

    buttonBox->addButton(QDialogButtonBox::Cancel);
    QObject::connect(buttonBox, SIGNAL(rejected()), q, SLOT(reject()));

    q->resize(500, 360);

    sizeEdit->installEventFilter(q);
    familyList->installEventFilter(q);
    styleList->installEventFilter(q);
    sizeList->installEventFilter(q);

    familyList->setFocus();
    retranslateStrings();
    sampleEdit->setObjectName(QLatin1String("qt_fontDialog_sampleEdit"));
}

/*!
  \internal
 Destroys the font dialog and frees up its storage.
*/

QFontDialog::~QFontDialog()
{
}

/*!
  Executes a modal font dialog and returns a font.

  If the user clicks \uicontrol OK, the selected font is returned. If the user
  clicks \uicontrol Cancel, the \a initial font is returned.

  The dialog is constructed with the given \a parent and the options specified
  in \a options. \a title is shown as the window title of the dialog and  \a
  initial is the initially selected font. If the \a ok parameter is not-null,
  the value it refers to is set to true if the user clicks \uicontrol OK, and set to
  false if the user clicks \uicontrol Cancel.

  Examples:
  \snippet code/src_gui_dialogs_qfontdialog.cpp 2

    The dialog can also be used to set a widget's font directly:
  \snippet code/src_gui_dialogs_qfontdialog.cpp 3
  In this example, if the user clicks OK the font they chose will be
  used, and if they click Cancel the original font is used.

  \warning Do not delete \a parent during the execution of the dialog.
           If you want to do this, you should create the dialog
           yourself using one of the QFontDialog constructors.
*/
QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent, const QString &title,
                           FontDialogOptions options)
{
    return QFontDialogPrivate::getFont(ok, initial, parent, title, options);
}

/*!
    \overload

  Executes a modal font dialog and returns a font.

  If the user clicks \uicontrol OK, the selected font is returned. If the user
  clicks \uicontrol Cancel, the Qt default font is returned.

  The dialog is constructed with the given \a parent.
  If the \a ok parameter is not-null, the value it refers to is set
  to true if the user clicks \uicontrol OK, and false if the user clicks
  \uicontrol Cancel.

  Example:
  \snippet code/src_gui_dialogs_qfontdialog.cpp 4

  \warning Do not delete \a parent during the execution of the dialog.
           If you want to do this, you should create the dialog
           yourself using one of the QFontDialog constructors.
*/
QFont QFontDialog::getFont(bool *ok, QWidget *parent)
{
    QFont initial;
    return QFontDialogPrivate::getFont(ok, initial, parent, QString(), 0);
}

QFont QFontDialogPrivate::getFont(bool *ok, const QFont &initial, QWidget *parent,
                                  const QString &title, QFontDialog::FontDialogOptions options)
{
    QFontDialog dlg(parent);
    dlg.setOptions(options);
    dlg.setCurrentFont(initial);
    if (!title.isEmpty())
        dlg.setWindowTitle(title);

    int ret = (dlg.exec() || (options & QFontDialog::NoButtons));
    if (ok)
        *ok = !!ret;
    if (ret) {
        return dlg.selectedFont();
    } else {
        return initial;
    }
}

/*!
    \internal
    An event filter to make the Up, Down, PageUp and PageDown keys work
    correctly in the line edits. The source of the event is the object
    \a o and the event is \a e.
*/

bool QFontDialog::eventFilter(QObject *o , QEvent *e)
{
    Q_D(QFontDialog);
    if (e->type() == QEvent::KeyPress) {
        QKeyEvent *k = (QKeyEvent *)e;
        if (o == d->sizeEdit &&
        (k->key() == Qt::Key_Up ||
             k->key() == Qt::Key_Down ||
         k->key() == Qt::Key_PageUp ||
         k->key() == Qt::Key_PageDown)) {

            int ci = d->sizeList->currentItem();
            QCoreApplication::sendEvent(d->sizeList, k);

            if (ci != d->sizeList->currentItem()
                    && style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, this))
                d->sizeEdit->selectAll();
            return true;
        } else if ((o == d->familyList || o == d->styleList) &&
                    (k->key() == Qt::Key_Return || k->key() == Qt::Key_Enter)) {
            k->accept();
        accept();
            return true;
        }
    } else if (e->type() == QEvent::FocusIn
               && style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, this)) {
        if (o == d->familyList)
            d->familyEdit->selectAll();
        else if (o == d->styleList)
            d->styleEdit->selectAll();
        else if (o == d->sizeList)
            d->sizeEdit->selectAll();
    } else if (e->type() == QEvent::MouseButtonPress && o == d->sizeList) {
            d->sizeEdit->setFocus();
    }
    return QDialog::eventFilter(o, e);
}

void QFontDialogPrivate::initHelper(QPlatformDialogHelper *h)
{
    QFontDialog *d = q_func();
    QObject::connect(h, SIGNAL(currentFontChanged(QFont)), d, SIGNAL(currentFontChanged(QFont)));
    QObject::connect(h, SIGNAL(fontSelected(QFont)), d, SIGNAL(fontSelected(QFont)));
    static_cast<QPlatformFontDialogHelper *>(h)->setOptions(options);
}

void QFontDialogPrivate::helperPrepareShow(QPlatformDialogHelper *)
{
    options->setWindowTitle(q_func()->windowTitle());
}

/*
    Updates the contents of the "font family" list box. This
    function can be reimplemented if you have special requirements.
*/

void QFontDialogPrivate::updateFamilies()
{
    Q_Q(QFontDialog);

    enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 };

    const QFontDialog::FontDialogOptions scalableMask = (QFontDialog::ScalableFonts | QFontDialog::NonScalableFonts);
    const QFontDialog::FontDialogOptions spacingMask = (QFontDialog::ProportionalFonts | QFontDialog::MonospacedFonts);
    const QFontDialog::FontDialogOptions options = q->options();

    QFontDatabase fdb;

    QStringList familyNames;
    const auto families = fdb.families(writingSystem);
    for (const QString &family : families) {
        if (fdb.isPrivateFamily(family))
            continue;

        if ((options & scalableMask) && (options & scalableMask) != scalableMask) {
            if (bool(options & QFontDialog::ScalableFonts) != fdb.isSmoothlyScalable(family))
                continue;
        }
        if ((options & spacingMask) && (options & spacingMask) != spacingMask) {
            if (bool(options & QFontDialog::MonospacedFonts) != fdb.isFixedPitch(family))
                continue;
        }
        familyNames << family;
    }

    familyList->model()->setStringList(familyNames);

    QString foundryName1, familyName1, foundryName2, familyName2;
    int bestFamilyMatch = -1;
    match_t bestFamilyType = MATCH_NONE;

    QFont f;

    // ##### do the right thing for a list of family names in the font.
    QFontDatabase::parseFontName(family, foundryName1, familyName1);

    QStringList::const_iterator it = familyNames.constBegin();
    int i = 0;
    for(; it != familyNames.constEnd(); ++it, ++i) {
        QFontDatabase::parseFontName(*it, foundryName2, familyName2);

        //try to match...
        if (familyName1 == familyName2) {
            bestFamilyType = MATCH_FAMILY;
            if (foundryName1 == foundryName2) {
                bestFamilyMatch = i;
                break;
            }
            if (bestFamilyMatch < MATCH_FAMILY)
                bestFamilyMatch = i;
        }

        //and try some fall backs
        match_t type = MATCH_NONE;
        if (bestFamilyType <= MATCH_NONE && familyName2 == QStringLiteral("helvetica"))
            type = MATCH_LAST_RESORT;
        if (bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.family())
            type = MATCH_APP;
        // ### add fallback for writingSystem
        if (type != MATCH_NONE) {
            bestFamilyType = type;
            bestFamilyMatch = i;
        }
    }

    if (i != -1 && bestFamilyType != MATCH_NONE)
        familyList->setCurrentItem(bestFamilyMatch);
    else
        familyList->setCurrentItem(0);
    familyEdit->setText(familyList->currentText());
    if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
            && familyList->hasFocus())
        familyEdit->selectAll();

    updateStyles();
}

/*
    Updates the contents of the "font style" list box. This
    function can be reimplemented if you have special requirements.
*/
void QFontDialogPrivate::updateStyles()
{
    Q_Q(QFontDialog);
    QStringList styles = fdb.styles(familyList->currentText());
    styleList->model()->setStringList(styles);

    if (styles.isEmpty()) {
        styleEdit->clear();
        smoothScalable = false;
    } else {
        if (!style.isEmpty()) {
            bool found = false;
            bool first = true;
            QString cstyle = style;

        redo:
            for (int i = 0; i < (int)styleList->count(); i++) {
                if (cstyle == styleList->text(i)) {
                     styleList->setCurrentItem(i);
                     found = true;
                     break;
                 }
            }
            if (!found && first) {
                if (cstyle.contains(QLatin1String("Italic"))) {
                    cstyle.replace(QLatin1String("Italic"), QLatin1String("Oblique"));
                    first = false;
                    goto redo;
                } else if (cstyle.contains(QLatin1String("Oblique"))) {
                    cstyle.replace(QLatin1String("Oblique"), QLatin1String("Italic"));
                    first = false;
                    goto redo;
                }
            }
            if (!found)
                styleList->setCurrentItem(0);
        } else {
            styleList->setCurrentItem(0);
        }

        styleEdit->setText(styleList->currentText());
        if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
                && styleList->hasFocus())
            styleEdit->selectAll();

        smoothScalable = fdb.isSmoothlyScalable(familyList->currentText(), styleList->currentText());
    }

    updateSizes();
}

/*!
    \internal
    Updates the contents of the "font size" list box. This
  function can be reimplemented if you have special requirements.
*/

void QFontDialogPrivate::updateSizes()
{
    Q_Q(QFontDialog);

    if (!familyList->currentText().isEmpty()) {
        QList<int> sizes = fdb.pointSizes(familyList->currentText(), styleList->currentText());

        int i = 0;
        int current = -1;
        QStringList str_sizes;
        str_sizes.reserve(sizes.size());
        for(QList<int>::const_iterator it = sizes.constBegin(); it != sizes.constEnd(); ++it) {
            str_sizes.append(QString::number(*it));
            if (current == -1 && *it == size)
                current = i;
            ++i;
        }
        sizeList->model()->setStringList(str_sizes);
        if (current != -1)
            sizeList->setCurrentItem(current);

        const QSignalBlocker blocker(sizeEdit);
        sizeEdit->setText((smoothScalable ? QString::number(size) : sizeList->currentText()));
        if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
                && sizeList->hasFocus())
            sizeEdit->selectAll();
    } else {
        sizeEdit->clear();
    }

    _q_updateSample();
}

void QFontDialogPrivate::_q_updateSample()
{
    // compute new font
    int pSize = sizeEdit->text().toInt();
    QFont newFont(fdb.font(familyList->currentText(), style, pSize));
    newFont.setStrikeOut(strikeout->isChecked());
    newFont.setUnderline(underline->isChecked());

    if (familyList->currentText().isEmpty())
        sampleEdit->clear();

    updateSampleFont(newFont);
}

void QFontDialogPrivate::updateSampleFont(const QFont &newFont)
{
    Q_Q(QFontDialog);
    if (newFont != sampleEdit->font()) {
        sampleEdit->setFont(newFont);
        emit q->currentFontChanged(newFont);
    }
}

/*!
    \internal
*/
void QFontDialogPrivate::_q_writingSystemHighlighted(int index)
{
    writingSystem = QFontDatabase::WritingSystem(index);
    sampleEdit->setText(QFontDatabase::writingSystemSample(writingSystem));
    updateFamilies();
}

/*!
    \internal
*/
void QFontDialogPrivate::_q_familyHighlighted(int i)
{
    Q_Q(QFontDialog);
    family = familyList->text(i);
    familyEdit->setText(family);
    if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
            && familyList->hasFocus())
        familyEdit->selectAll();

    updateStyles();
}


/*!
    \internal
*/

void QFontDialogPrivate::_q_styleHighlighted(int index)
{
    Q_Q(QFontDialog);
    QString s = styleList->text(index);
    styleEdit->setText(s);
    if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
            && styleList->hasFocus())
        styleEdit->selectAll();

    style = s;

    updateSizes();
}


/*!
    \internal
*/

void QFontDialogPrivate::_q_sizeHighlighted(int index)
{
    Q_Q(QFontDialog);
    QString s = sizeList->text(index);
    sizeEdit->setText(s);
    if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
            && sizeEdit->hasFocus())
        sizeEdit->selectAll();

    size = s.toInt();
    _q_updateSample();
}

/*!
    \internal
    This slot is called if the user changes the font size.
    The size is passed in the \a s argument as a \e string.
*/

void QFontDialogPrivate::_q_sizeChanged(const QString &s)
{
    // no need to check if the conversion is valid, since we have an QIntValidator in the size edit
    int size = s.toInt();
    if (this->size == size)
        return;

    this->size = size;
    if (sizeList->count() != 0) {
        int i;
        for (i = 0; i < sizeList->count() - 1; i++) {
            if (sizeList->text(i).toInt() >= this->size)
                break;
        }
        const QSignalBlocker blocker(sizeList);
        if (sizeList->text(i).toInt() == this->size)
            sizeList->setCurrentItem(i);
        else
            sizeList->clearSelection();
    }
    _q_updateSample();
}

void QFontDialogPrivate::retranslateStrings()
{
    familyAccel->setText(QFontDialog::tr("&Font"));
    styleAccel->setText(QFontDialog::tr("Font st&yle"));
    sizeAccel->setText(QFontDialog::tr("&Size"));
    effects->setTitle(QFontDialog::tr("Effects"));
    strikeout->setText(QFontDialog::tr("Stri&keout"));
    underline->setText(QFontDialog::tr("&Underline"));
    sample->setTitle(QFontDialog::tr("Sample"));
    writingSystemAccel->setText(QFontDialog::tr("Wr&iting System"));
}

/*!
    \reimp
*/
void QFontDialog::changeEvent(QEvent *e)
{
    Q_D(QFontDialog);
    if (e->type() == QEvent::LanguageChange) {
        d->retranslateStrings();
    }
    QDialog::changeEvent(e);
}

/*!
    \since 4.5

    \property QFontDialog::currentFont
    \brief the current font of the dialog.
*/

/*!
    \since 4.5

    Sets the font highlighted in the QFontDialog to the given \a font.

    \sa selectedFont()
*/
void QFontDialog::setCurrentFont(const QFont &font)
{
    Q_D(QFontDialog);
    d->family = font.family();
    d->style = d->fdb.styleString(font);
    d->size = font.pointSize();
    if (d->size == -1) {
        QFontInfo fi(font);
        d->size = fi.pointSize();
    }
    d->strikeout->setChecked(font.strikeOut());
    d->underline->setChecked(font.underline());
    d->updateFamilies();
    if (QPlatformFontDialogHelper *helper = d->platformFontDialogHelper())
        helper->setCurrentFont(font);
}

/*!
    \since 4.5

    Returns the current font.

    \sa selectedFont()
*/
QFont QFontDialog::currentFont() const
{
    Q_D(const QFontDialog);
    if (const QPlatformFontDialogHelper *helper = d->platformFontDialogHelper())
        return helper->currentFont();
    return d->sampleEdit->font();
}

/*!
    Returns the font that the user selected by clicking the \uicontrol{OK}
    or equivalent button.

    \note This font is not always the same as the font held by the
    \l currentFont property since the user can choose different fonts
    before finally selecting the one to use.
*/
QFont QFontDialog::selectedFont() const
{
    Q_D(const QFontDialog);
    return d->selectedFont;
}

/*!
    \enum QFontDialog::FontDialogOption
    \since 4.5

    This enum specifies various options that affect the look and feel
    of a font dialog.

    For instance, it allows to specify which type of font should be
    displayed. If none are specified all fonts available will be listed.

    Note that the font filtering options might not be supported on some
    platforms (e.g. Mac). They are always supported by the non native
    dialog (used on Windows or Linux).

    \value NoButtons Don't display \uicontrol{OK} and \uicontrol{Cancel} buttons. (Useful for "live dialogs".)
    \value DontUseNativeDialog Use Qt's standard font dialog on the Mac instead of Apple's
                               native font panel.
    \value ScalableFonts Show scalable fonts
    \value NonScalableFonts Show non scalable fonts
    \value MonospacedFonts Show monospaced fonts
    \value ProportionalFonts Show proportional fonts

    \sa options, setOption(), testOption()
*/

/*!
    Sets the given \a option to be enabled if \a on is true;
    otherwise, clears the given \a option.

    \sa options, testOption()
*/
void QFontDialog::setOption(FontDialogOption option, bool on)
{
    const QFontDialog::FontDialogOptions previousOptions = options();
    if (!(previousOptions & option) != !on)
        setOptions(previousOptions ^ option);
}

/*!
    Returns \c true if the given \a option is enabled; otherwise, returns
    false.

    \sa options, setOption()
*/
bool QFontDialog::testOption(FontDialogOption option) const
{
    Q_D(const QFontDialog);
    return d->options->testOption(static_cast<QFontDialogOptions::FontDialogOption>(option));
}

/*!
    \property QFontDialog::options
    \brief the various options that affect the look and feel of the dialog
    \since 4.5

    By default, all options are disabled.

    Options should be set before showing the dialog. Setting them while the
    dialog is visible is not guaranteed to have an immediate effect on the
    dialog (depending on the option and on the platform).

    \sa setOption(), testOption()
*/
void QFontDialog::setOptions(FontDialogOptions options)
{
    Q_D(QFontDialog);

    if (QFontDialog::options() == options)
        return;

    d->options->setOptions(QFontDialogOptions::FontDialogOptions(int(options)));
    d->buttonBox->setVisible(!(options & NoButtons));
}

QFontDialog::FontDialogOptions QFontDialog::options() const
{
    Q_D(const QFontDialog);
    return QFontDialog::FontDialogOptions(int(d->options->options()));
}

/*!
    \since 4.5

    Opens the dialog and connects its fontSelected() signal to the slot specified
    by \a receiver and \a member.

    The signal will be disconnected from the slot when the dialog is closed.
*/
void QFontDialog::open(QObject *receiver, const char *member)
{
    Q_D(QFontDialog);
    connect(this, SIGNAL(fontSelected(QFont)), receiver, member);
    d->receiverToDisconnectOnClose = receiver;
    d->memberToDisconnectOnClose = member;
    QDialog::open();
}

/*!
    \since 4.5

    \fn void QFontDialog::currentFontChanged(const QFont &font)

    This signal is emitted when the current font is changed. The new font is
    specified in \a font.

    The signal is emitted while a user is selecting a font. Ultimately, the
    chosen font may differ from the font currently selected.

    \sa currentFont, fontSelected(), selectedFont()
*/

/*!
    \since 4.5

    \fn void QFontDialog::fontSelected(const QFont &font)

    This signal is emitted when a font has been selected. The selected font is
    specified in \a font.

    The signal is only emitted when a user has chosen the final font to be
    used. It is not emitted while the user is changing the current font in the
    font dialog.

    \sa selectedFont(), currentFontChanged(), currentFont
*/

/*!
    \reimp
*/
void QFontDialog::setVisible(bool visible)
{
    if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden) != visible)
        return;
    Q_D(QFontDialog);
    if (d->canBeNativeDialog())
        d->setNativeDialogVisible(visible);
    if (d->nativeDialogInUse) {
        // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
        // updates the state correctly, but skips showing the non-native version:
        setAttribute(Qt::WA_DontShowOnScreen, true);
    } else {
        d->nativeDialogInUse = false;
        setAttribute(Qt::WA_DontShowOnScreen, false);
    }
    QDialog::setVisible(visible);
}

/*!
  Closes the dialog and sets its result code to \a result. If this dialog
  is shown with exec(), done() causes the local event loop to finish,
  and exec() to return \a result.

  \sa QDialog::done()
*/
void QFontDialog::done(int result)
{
    Q_D(QFontDialog);
    QDialog::done(result);
    if (result == Accepted) {
        // We check if this is the same font we had before, if so we emit currentFontChanged
        QFont selectedFont = currentFont();
        if(selectedFont != d->selectedFont)
            emit(currentFontChanged(selectedFont));
        d->selectedFont = selectedFont;
        emit fontSelected(d->selectedFont);
    } else
        d->selectedFont = QFont();
    if (d->receiverToDisconnectOnClose) {
        disconnect(this, SIGNAL(fontSelected(QFont)),
                   d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
        d->receiverToDisconnectOnClose = 0;
    }
    d->memberToDisconnectOnClose.clear();
}

bool QFontDialogPrivate::canBeNativeDialog() const
{
    // Don't use Q_Q here! This function is called from ~QDialog,
    // so Q_Q calling q_func() invokes undefined behavior (invalid cast in q_func()).
    const QDialog * const q = static_cast<const QDialog*>(q_ptr);
    if (nativeDialogInUse)
        return true;
    if (QCoreApplication::testAttribute(Qt::AA_DontUseNativeDialogs)
        || q->testAttribute(Qt::WA_DontShowOnScreen)
        || (options->options() & QFontDialog::DontUseNativeDialog)) {
        return false;
    }

    QLatin1String staticName(QFontDialog::staticMetaObject.className());
    QLatin1String dynamicName(q->metaObject()->className());
    return (staticName == dynamicName);
}

QT_END_NAMESPACE

#include "qfontdialog.moc"
#include "moc_qfontdialog.cpp"
