From 1f049c91f91e069a975a72c1087a279d011535a5 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Sun, 21 Feb 2010 19:47:01 +0100 Subject: loopback network example: Make use of bytesToWrite() Reviewed-by: TrustMe --- examples/network/loopback/dialog.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/network/loopback/dialog.cpp b/examples/network/loopback/dialog.cpp index 27cff31..b504e36 100644 --- a/examples/network/loopback/dialog.cpp +++ b/examples/network/loopback/dialog.cpp @@ -44,12 +44,12 @@ #include "dialog.h" -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) static const int TotalBytes = 50 * 1024 * 1024; #else static const int TotalBytes = 5 * 1024 * 1024; #endif -static const int PayloadSize = 65536; +static const int PayloadSize = 64 * 1024; // 64 KB Dialog::Dialog(QWidget *parent) : QDialog(parent) @@ -130,6 +130,7 @@ void Dialog::acceptConnection() void Dialog::startTransfer() { + // called when the TCP client connected to the loopback server bytesToWrite = TotalBytes - (int)tcpClient.write(QByteArray(PayloadSize, '@')); clientStatusLabel->setText(tr("Connected")); } @@ -155,8 +156,11 @@ void Dialog::updateServerProgress() void Dialog::updateClientProgress(qint64 numBytes) { + // callen when the TCP client has written some bytes bytesWritten += (int)numBytes; - if (bytesToWrite > 0) + + // only write more if not finished and when the Qt write buffer is below a certain size. + if (bytesToWrite > 0 && tcpClient.bytesToWrite() <= 4*PayloadSize) bytesToWrite -= (int)tcpClient.write(QByteArray(qMin(bytesToWrite, PayloadSize), '@')); clientProgressBar->setMaximum(TotalBytes); -- cgit v0.12 From 4f2d34ed13bd63413e726229fd50c4b33f2d0127 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 22 Feb 2010 12:36:30 +0100 Subject: Port http example to QNetworkAccessManager QHttp. Must. Die. Reviewed-by: Peter Hartmann --- examples/network/http/httpwindow.cpp | 129 ++++++++++++++++++----------------- examples/network/http/httpwindow.h | 23 ++++--- examples/network/http/main.cpp | 1 - 3 files changed, 82 insertions(+), 71 deletions(-) diff --git a/examples/network/http/httpwindow.cpp b/examples/network/http/httpwindow.cpp index 95fc82f..ec7cd33 100644 --- a/examples/network/http/httpwindow.cpp +++ b/examples/network/http/httpwindow.cpp @@ -49,9 +49,9 @@ HttpWindow::HttpWindow(QWidget *parent) : QDialog(parent) { #ifndef QT_NO_OPENSSL - urlLineEdit = new QLineEdit("https://"); + urlLineEdit = new QLineEdit("https://qt.nokia.com/"); #else - urlLineEdit = new QLineEdit("http://"); + urlLineEdit = new QLineEdit("http://qt.nokia.com/"); #endif urlLabel = new QLabel(tr("&URL:")); @@ -70,21 +70,14 @@ HttpWindow::HttpWindow(QWidget *parent) progressDialog = new QProgressDialog(this); - http = new QHttp(this); - connect(urlLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableDownloadButton())); - connect(http, SIGNAL(requestFinished(int,bool)), - this, SLOT(httpRequestFinished(int,bool))); - connect(http, SIGNAL(dataReadProgress(int,int)), - this, SLOT(updateDataReadProgress(int,int))); - connect(http, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), - this, SLOT(readResponseHeader(QHttpResponseHeader))); - connect(http, SIGNAL(authenticationRequired(QString,quint16,QAuthenticator*)), - this, SLOT(slotAuthenticationRequired(QString,quint16,QAuthenticator*))); + + connect(&qnam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*))); #ifndef QT_NO_OPENSSL - connect(http, SIGNAL(sslErrors(QList)), - this, SLOT(sslErrors(QList))); + connect(&qnam, SIGNAL(sslErrors(QNetworkReply*,QList)), + this, SLOT(sslErrors(QNetworkReply*,QList))); #endif connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelDownload())); connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile())); @@ -104,9 +97,21 @@ HttpWindow::HttpWindow(QWidget *parent) urlLineEdit->setFocus(); } +void HttpWindow::startRequest(QUrl url) +{ + reply = qnam.get(QNetworkRequest(url)); + connect(reply, SIGNAL(finished()), + this, SLOT(httpFinished())); + connect(reply, SIGNAL(readyRead()), + this, SLOT(httpReadyRead())); + connect(reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(updateDataReadProgress(qint64,qint64))); +} + void HttpWindow::downloadFile() { - QUrl url(urlLineEdit->text()); + url = urlLineEdit->text(); + QFileInfo fileInfo(url.path()); QString fileName = fileInfo.fileName(); if (fileName.isEmpty()) @@ -132,35 +137,26 @@ void HttpWindow::downloadFile() return; } - QHttp::ConnectionMode mode = url.scheme().toLower() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp; - http->setHost(url.host(), mode, url.port() == -1 ? 0 : url.port()); - - if (!url.userName().isEmpty()) - http->setUser(url.userName(), url.password()); - - httpRequestAborted = false; - QByteArray path = QUrl::toPercentEncoding(url.path(), "!$&'()*+,;=:@/"); - if (path.isEmpty()) - path = "/"; - httpGetId = http->get(path, file); progressDialog->setWindowTitle(tr("HTTP")); progressDialog->setLabelText(tr("Downloading %1.").arg(fileName)); downloadButton->setEnabled(false); + + // schedule the request + httpRequestAborted = false; + startRequest(url); } void HttpWindow::cancelDownload() { statusLabel->setText(tr("Download canceled.")); httpRequestAborted = true; - http->abort(); + reply->abort(); downloadButton->setEnabled(true); } -void HttpWindow::httpRequestFinished(int requestId, bool error) +void HttpWindow::httpFinished() { - if (requestId != httpGetId) - return; if (httpRequestAborted) { if (file) { file->close(); @@ -168,54 +164,58 @@ void HttpWindow::httpRequestFinished(int requestId, bool error) delete file; file = 0; } - + reply->deleteLater(); progressDialog->hide(); return; } - if (requestId != httpGetId) - return; - progressDialog->hide(); + file->flush(); file->close(); - if (error) { + + QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (reply->error()) { file->remove(); QMessageBox::information(this, tr("HTTP"), tr("Download failed: %1.") - .arg(http->errorString())); + .arg(reply->errorString())); + downloadButton->setEnabled(true); + } else if (!redirectionTarget.isNull()) { + QUrl newUrl = url.resolved(redirectionTarget.toUrl()); + if (QMessageBox::question(this, tr("HTTP"), + tr("Redirect to %1 ?").arg(newUrl.toString()), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + url = newUrl; + reply->deleteLater(); + file->open(QIODevice::WriteOnly); + file->resize(0); + startRequest(url); + return; + } } else { QString fileName = QFileInfo(QUrl(urlLineEdit->text()).path()).fileName(); statusLabel->setText(tr("Downloaded %1 to current directory.").arg(fileName)); + downloadButton->setEnabled(true); } - downloadButton->setEnabled(true); + reply->deleteLater(); + reply = 0; delete file; file = 0; } -void HttpWindow::readResponseHeader(const QHttpResponseHeader &responseHeader) +void HttpWindow::httpReadyRead() { - switch (responseHeader.statusCode()) { - case 200: // Ok - case 301: // Moved Permanently - case 302: // Found - case 303: // See Other - case 307: // Temporary Redirect - // these are not error conditions - break; - - default: - QMessageBox::information(this, tr("HTTP"), - tr("Download failed: %1.") - .arg(responseHeader.reasonPhrase())); - httpRequestAborted = true; - progressDialog->hide(); - http->abort(); - } + // this slot gets called everytime the QNetworkReply has new data. + // We read all of its new data and write it into the file. + // That way we use less RAM than when reading it at the finished() + // signal of the QNetworkReply + if (file) + file->write(reply->readAll()); } -void HttpWindow::updateDataReadProgress(int bytesRead, int totalBytes) +void HttpWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes) { if (httpRequestAborted) return; @@ -229,14 +229,19 @@ void HttpWindow::enableDownloadButton() downloadButton->setEnabled(!urlLineEdit->text().isEmpty()); } -void HttpWindow::slotAuthenticationRequired(const QString &hostName, quint16, QAuthenticator *authenticator) +void HttpWindow::slotAuthenticationRequired(QNetworkReply*,QAuthenticator *authenticator) { QDialog dlg; Ui::Dialog ui; ui.setupUi(&dlg); dlg.adjustSize(); - ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm()).arg(hostName)); - + ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm()).arg(url.host())); + + // Did the URL have information? Fill the UI + // This is only relevant if the URL-supplied credentials were wrong + ui.userEdit->setText(url.userName()); + ui.passwordEdit->setText(url.password()); + if (dlg.exec() == QDialog::Accepted) { authenticator->setUser(ui.userEdit->text()); authenticator->setPassword(ui.passwordEdit->text()); @@ -244,7 +249,7 @@ void HttpWindow::slotAuthenticationRequired(const QString &hostName, quint16, QA } #ifndef QT_NO_OPENSSL -void HttpWindow::sslErrors(const QList &errors) +void HttpWindow::sslErrors(QNetworkReply*,const QList &errors) { QString errorString; foreach (const QSslError &error, errors) { @@ -253,10 +258,10 @@ void HttpWindow::sslErrors(const QList &errors) errorString += error.errorString(); } - if (QMessageBox::warning(this, tr("HTTP Example"), + if (QMessageBox::warning(this, tr("HTTP"), tr("One or more SSL errors has occurred: %1").arg(errorString), QMessageBox::Ignore | QMessageBox::Abort) == QMessageBox::Ignore) { - http->ignoreSslErrors(); + reply->ignoreSslErrors(); } } #endif diff --git a/examples/network/http/httpwindow.h b/examples/network/http/httpwindow.h index 9dca8a5..83898af 100644 --- a/examples/network/http/httpwindow.h +++ b/examples/network/http/httpwindow.h @@ -43,18 +43,21 @@ #define HTTPWINDOW_H #include +#include +#include QT_BEGIN_NAMESPACE class QDialogButtonBox; class QFile; -class QHttp; -class QHttpResponseHeader; class QLabel; class QLineEdit; class QProgressDialog; class QPushButton; class QSslError; class QAuthenticator; +class QNetworkReply; + + QT_END_NAMESPACE class HttpWindow : public QDialog @@ -64,16 +67,18 @@ class HttpWindow : public QDialog public: HttpWindow(QWidget *parent = 0); + void startRequest(QUrl url); + private slots: void downloadFile(); void cancelDownload(); - void httpRequestFinished(int requestId, bool error); - void readResponseHeader(const QHttpResponseHeader &responseHeader); - void updateDataReadProgress(int bytesRead, int totalBytes); + void httpFinished(); + void httpReadyRead(); + void updateDataReadProgress(qint64 bytesRead, qint64 totalBytes); void enableDownloadButton(); - void slotAuthenticationRequired(const QString &, quint16, QAuthenticator *); + void slotAuthenticationRequired(QNetworkReply*,QAuthenticator *); #ifndef QT_NO_OPENSSL - void sslErrors(const QList &errors); + void sslErrors(QNetworkReply*,const QList &errors); #endif private: @@ -85,7 +90,9 @@ private: QPushButton *quitButton; QDialogButtonBox *buttonBox; - QHttp *http; + QUrl url; + QNetworkAccessManager qnam; + QNetworkReply *reply; QFile *file; int httpGetId; bool httpRequestAborted; diff --git a/examples/network/http/main.cpp b/examples/network/http/main.cpp index ecbe100..817b2be 100644 --- a/examples/network/http/main.cpp +++ b/examples/network/http/main.cpp @@ -46,7 +46,6 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); - qWarning("The usage of QHttp is not recommended anymore, please use QNetworkAccessManager."); HttpWindow httpWin; httpWin.show(); return httpWin.exec(); -- cgit v0.12 From 5e95e1bb510d24b9b7889191144a4842fd8569c1 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 22 Feb 2010 12:43:57 +0100 Subject: QNetworkRequest: Doc enhancement Reviewed-by: David Boddie --- src/network/access/qnetworkrequest.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index a2bef67..c4ff24d 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -138,6 +138,8 @@ QT_BEGIN_NAMESPACE default follow redirections: it's up to the application to determine if the requested redirection should be allowed, according to its security policies. + The returned URL might be relative. Use QUrl::resolved() + to create an absolute URL out of it. \value ConnectionEncryptedAttribute Replies only, type: QVariant::Bool (default: false) -- cgit v0.12 From 976a2b6ad1f95175d8d0be2d1eb7603cf4e4026a Mon Sep 17 00:00:00 2001 From: Carlos Manuel Duclos Vergara Date: Mon, 22 Feb 2010 14:58:41 +0100 Subject: QFontDialog::exec() never returns on OSX The problem is the fact that this dialog is never meant to be used this way. Instead it should be called through the static function ::getFont(...). I reimplemented this code path and made sure that this works. Task-number: QTBUG-7769 Reviewed-by: Richard Moe Gustavsen --- src/gui/dialogs/qfontdialog.cpp | 58 ++++++++------- src/gui/dialogs/qfontdialog.h | 3 + src/gui/dialogs/qfontdialog_mac.mm | 148 ++++++++++++++++++++++++++++++++++++- src/gui/dialogs/qfontdialog_p.h | 6 ++ 4 files changed, 188 insertions(+), 27 deletions(-) diff --git a/src/gui/dialogs/qfontdialog.cpp b/src/gui/dialogs/qfontdialog.cpp index 56580a9..4358313 100644 --- a/src/gui/dialogs/qfontdialog.cpp +++ b/src/gui/dialogs/qfontdialog.cpp @@ -989,33 +989,23 @@ void QFontDialog::open(QObject *receiver, const char *member) void QFontDialog::setVisible(bool visible) { Q_D(QFontDialog); - if (visible) - d->selectedFont = QFont(); - -#if defined(Q_WS_MAC) - bool isCurrentlyVisible = (isVisible() || d->delegate); - - if (!visible == !isCurrentlyVisible) - return; - if (visible) { - if (!(d->opts & DontUseNativeDialog) && QFontDialogPrivate::sharedFontPanelAvailable) { - d->delegate = QFontDialogPrivate::openCocoaFontPanel( - currentFont(), parentWidget(), windowTitle(), options(), d); - QFontDialogPrivate::sharedFontPanelAvailable = false; + if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden)) return; - } + } else if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden)) + return; - setWindowFlags(windowModality() == Qt::WindowModal ? Qt::Sheet : DefaultWindowFlags); - } else { - if (d->delegate) { - QFontDialogPrivate::closeCocoaFontPanel(d->delegate); - d->delegate = 0; - QFontDialogPrivate::sharedFontPanelAvailable = true; - return; + if (d->canBeNativeDialog()){ + if (d->setVisible_sys(visible)){ + d->nativeDialogInUse = true; + // 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); } } -#endif QDialog::setVisible(visible); } @@ -1032,11 +1022,14 @@ void QFontDialog::done(int result) Q_D(QFontDialog); QDialog::done(result); if (result == Accepted) { - d->selectedFont = currentFont(); + // 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 { + } else d->selectedFont = QFont(); - } if (d->receiverToDisconnectOnClose) { disconnect(this, SIGNAL(fontSelected(QFont)), d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose); @@ -1045,6 +1038,21 @@ void QFontDialog::done(int result) d->memberToDisconnectOnClose.clear(); } +bool QFontDialogPrivate::canBeNativeDialog() +{ + Q_Q(QFontDialog); + if (nativeDialogInUse) + return true; + if (q->testAttribute(Qt::WA_DontShowOnScreen)) + return false; + if (opts & QFontDialog::DontUseNativeDialog) + return false; + + QLatin1String staticName(QFontDialog::staticMetaObject.className()); + QLatin1String dynamicName(q->metaObject()->className()); + return (staticName == dynamicName); +} + /*! \fn QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget* parent, const char* name) \since 4.5 diff --git a/src/gui/dialogs/qfontdialog.h b/src/gui/dialogs/qfontdialog.h index e6f209e..6035a3a 100644 --- a/src/gui/dialogs/qfontdialog.h +++ b/src/gui/dialogs/qfontdialog.h @@ -131,6 +131,9 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_styleHighlighted(int)) Q_PRIVATE_SLOT(d_func(), void _q_sizeHighlighted(int)) Q_PRIVATE_SLOT(d_func(), void _q_updateSample()) +#if defined(Q_WS_MAC) + Q_PRIVATE_SLOT(d_func(), void _q_macRunNativeAppModalPanel()) +#endif }; Q_DECLARE_OPERATORS_FOR_FLAGS(QFontDialog::FontDialogOptions) diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index 68f5f00..67d32b8 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -49,6 +49,7 @@ #include #include #include +#include #include #import #import @@ -372,7 +373,12 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) [NSApp endModalSession:mModalSession]; mModalSession = 0; } - + // Hack alert! + // Since this code path was never intended to be followed when starting from exec + // we need to force the dialog to communicate the new font, otherwise the signal + // won't get emitted. + if(code == NSOKButton) + mPriv->sampleEdit->setFont([self qtFont]); mPriv->done((code == NSOKButton) ? QDialog::Accepted : QDialog::Rejected); } else { [NSApp stopModalWithCode:code]; @@ -567,7 +573,6 @@ void *QFontDialogPrivate::openCocoaFontPanel(const QFont &initial, [ourPanel makeKeyAndOrderFront:ourPanel]; } } - return delegate; } @@ -640,6 +645,145 @@ void QFontDialogPrivate::setFont(void *delegate, const QFont &font) [static_cast(delegate) setQtFont:font]; } +void *QFontDialogPrivate::_q_constructNativePanel() +{ + QMacCocoaAutoReleasePool pool; + + bool sharedFontPanelExisted = [NSFontPanel sharedFontPanelExists]; + NSFontPanel *sharedFontPanel = [NSFontPanel sharedFontPanel]; + [sharedFontPanel setHidesOnDeactivate:false]; + + // hack to ensure that QCocoaApplication's validModesForFontPanel: + // implementation is honored + if (!sharedFontPanelExisted) { + [sharedFontPanel makeKeyAndOrderFront:sharedFontPanel]; + [sharedFontPanel close]; + } + + NSPanel *ourPanel = 0; + NSView *stolenContentView = 0; + NSButton *okButton = 0; + NSButton *cancelButton = 0; + + CGFloat dialogExtraWidth = 0.0; + CGFloat dialogExtraHeight = 0.0; + + // compute dialogExtra{Width,Height} + dialogExtraWidth = 2.0 * DialogSideMargin; + dialogExtraHeight = DialogTopMargin + ButtonTopMargin + ButtonMinHeight + + ButtonBottomMargin; + + // compute initial contents rectangle + NSRect contentRect = [sharedFontPanel contentRectForFrameRect:[sharedFontPanel frame]]; + contentRect.size.width += dialogExtraWidth; + contentRect.size.height += dialogExtraHeight; + + // create the new panel + ourPanel = [[NSPanel alloc] initWithContentRect:contentRect + styleMask:StyleMask + backing:NSBackingStoreBuffered + defer:YES]; + [ourPanel setReleasedWhenClosed:YES]; + + stolenContentView = [sharedFontPanel contentView]; + + // steal the font panel's contents view + [stolenContentView retain]; + [sharedFontPanel setContentView:0]; + + { + // create a new content view and add the stolen one as a subview + NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; + NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect]; + [ourContentView addSubview:stolenContentView]; + + // create OK and Cancel buttons and add these as subviews + okButton = macCreateButton("&OK", ourContentView); + cancelButton = macCreateButton("Cancel", ourContentView); + + [ourPanel setContentView:ourContentView]; + [ourPanel setDefaultButtonCell:[okButton cell]]; + } + // create a delegate and set it + QCocoaFontPanelDelegate *delegate = + [[QCocoaFontPanelDelegate alloc] initWithFontPanel:sharedFontPanel + stolenContentView:stolenContentView + okButton:okButton + cancelButton:cancelButton + priv:this + extraWidth:dialogExtraWidth + extraHeight:dialogExtraHeight]; + [ourPanel setDelegate:delegate]; + [[NSFontManager sharedFontManager] setDelegate:delegate]; +#ifdef QT_MAC_USE_COCOA + [[NSFontManager sharedFontManager] setTarget:delegate]; +#endif + setFont(delegate, QApplication::font()); + + { + // hack to get correct initial layout + NSRect frameRect = [ourPanel frame]; + frameRect.size.width += 1.0; + [ourPanel setFrame:frameRect display:NO]; + frameRect.size.width -= 1.0; + frameRect.size = [delegate windowWillResize:ourPanel toSize:frameRect.size]; + [ourPanel setFrame:frameRect display:NO]; + [ourPanel center]; + } + NSString *title = @"Select font"; + [ourPanel setTitle:title]; + + [delegate setModalSession:[NSApp beginModalSessionForWindow:ourPanel]]; + return delegate; +} + +void QFontDialogPrivate::mac_nativeDialogModalHelp() +{ + // Copied from QFileDialogPrivate + // Do a queued meta-call to open the native modal dialog so it opens after the new + // event loop has started to execute (in QDialog::exec). Using a timer rather than + // a queued meta call is intentional to ensure that the call is only delivered when + // [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not + // running (which is the case if e.g a top-most QEventLoop has been + // interrupted, and the second-most event loop has not yet been reactivated (regardless + // if [NSApp run] is still on the stack)), showing a native modal dialog will fail. + if (nativeDialogInUse) { + Q_Q(QFontDialog); + QTimer::singleShot(1, q, SLOT(_q_macRunNativeAppModalPanel())); + } +} + +// The problem with the native font dialog is that OS X does not +// offer a proper dialog, but a panel (i.e. without Ok and Cancel buttons). +// This means we need to "construct" a native dialog by taking the panel +// and "adding" the buttons. +void QFontDialogPrivate::_q_macRunNativeAppModalPanel() +{ + QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active); + Q_Q(QFontDialog); + QCocoaFontPanelDelegate *delegate = (QCocoaFontPanelDelegate *)_q_constructNativePanel(); + NSWindow *ourPanel = [delegate actualPanel]; + [ourPanel retain]; + int rval = [NSApp runModalForWindow:ourPanel]; + QAbstractEventDispatcher::instance()->interrupt(); + [ourPanel release]; + [delegate cleanUpAfterMyself]; + [delegate release]; + bool isOk = (rval == NSOKButton); + if(isOk) + rescode = QDialog::Accepted; + else + rescode = QDialog::Rejected; +} + +bool QFontDialogPrivate::setVisible_sys(bool visible) +{ + Q_Q(QFontDialog); + if (!visible == q->isHidden()) + return false; + return visible; +} + QT_END_NAMESPACE #endif diff --git a/src/gui/dialogs/qfontdialog_p.h b/src/gui/dialogs/qfontdialog_p.h index ca2b10b..7654a80 100644 --- a/src/gui/dialogs/qfontdialog_p.h +++ b/src/gui/dialogs/qfontdialog_p.h @@ -152,6 +152,12 @@ public: inline QFontDialog *fontDialog() { return q_func(); } void *delegate; + bool nativeDialogInUse; + bool canBeNativeDialog(); + bool setVisible_sys(bool visible); + void *_q_constructNativePanel(); + void _q_macRunNativeAppModalPanel(); + void mac_nativeDialogModalHelp(); static bool sharedFontPanelAvailable; #endif -- cgit v0.12