5#include <AppKit/AppKit.h>
7#include <QtCore/qtimer.h>
8#include <QtGui/qfontdatabase.h>
9#include <qpa/qplatformtheme.h>
11#include <private/qfont_p.h>
12#include <private/qfontengine_p.h>
13#include <private/qfontengine_coretext_p.h>
26static QFont qfontForCocoaFont(NSFont *cocoaFont,
const QFont &resolveFont)
30 int pSize = qRound([cocoaFont pointSize]);
31 QCFType<CTFontDescriptorRef> font(CTFontCopyFontDescriptor((CTFontRef)cocoaFont));
32 QString family(QCFString((CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute)));
33 QString style(QCFString(((CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute))));
35 newFont = QFontDatabase::font(family, style, pSize);
36 newFont.setUnderline(resolveFont.underline());
37 newFont.setStrikeOut(resolveFont.strikeOut());
42@interface QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) : NSObject<NSWindowDelegate, QNSPanelDelegate>
43- (
void)restoreOriginalContentView;
45- (
void)changeFont:(id)sender;
46- (
void)finishOffWithCode:(NSInteger)code;
49QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
51@implementation QNSFontPanelDelegate {
53 NSFontPanel *mFontPanel;
54 QCocoaFontDialogHelper *mHelper;
55 NSView *mStolenContentView;
56 QNSPanelContentsWrapper *mPanelButtons;
58 NSInteger mResultCode;
59 BOOL mDialogIsExecuting;
65 if ((self = [super init])) {
66 mFontPanel = [NSFontPanel sharedFontPanel];
68 mStolenContentView = nil;
70 mResultCode = NSModalResponseCancel;
71 mDialogIsExecuting =
false;
74 [mFontPanel setRestorable:NO];
75 [mFontPanel setDelegate:self];
84 [mStolenContentView release];
85 [mFontPanel setDelegate:nil];
86 [[NSNotificationCenter defaultCenter] removeObserver:self];
91- (
void)setDialogHelper:(QCocoaFontDialogHelper *)helper
95 [mFontPanel setTitle:helper->options()->windowTitle().toNSString()];
97 if (mHelper->options()->testOption(QFontDialogOptions::NoButtons)) {
98 [self restoreOriginalContentView];
99 }
else if (!mStolenContentView) {
101 mStolenContentView = mFontPanel.contentView;
102 [mStolenContentView retain];
103 mFontPanel.contentView = nil;
106 mPanelButtons = [[QNSPanelContentsWrapper alloc] initWithPanelDelegate:self];
107 [mPanelButtons addSubview:mStolenContentView];
108 mPanelButtons.panelContentsMargins = NSEdgeInsetsMake(0, 0, 7, 0);
109 mFontPanel.contentView = mPanelButtons;
110 mFontPanel.defaultButtonCell = mPanelButtons.okButton.cell;
119- (
void)restoreOriginalContentView
121 if (mStolenContentView) {
123 [mStolenContentView removeFromSuperview];
124 [mFontPanel setContentView:mStolenContentView];
125 mStolenContentView = nil;
126 [mPanelButtons release];
134 [self finishOffWithCode:NSModalResponseOK];
137- (
void)onCancelClicked
142 [self finishOffWithCode:NSModalResponseCancel];
146- (
void)changeFont:(id)sender
155 NSFontManager *fontManager = [NSFontManager sharedFontManager];
156 NSFont *selectedFont = [fontManager selectedFont];
158 selectedFont = [NSFont systemFontOfSize:[NSFont systemFontSize]];
160 NSFont *panelFont = [fontManager convertFont:selectedFont];
161 mQtFont = qfontForCocoaFont(panelFont, mQtFont);
164 emit mHelper->currentFontChanged(mQtFont);
167- (
void)showModelessPanel
169 mDialogIsExecuting =
false;
179 dispatch_async(dispatch_get_main_queue(), ^{
180 [mFontPanel makeKeyAndOrderFront:mFontPanel];
184- (BOOL)runApplicationModalPanel
186 mDialogIsExecuting =
true;
190 qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
193 QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();
195 [NSApp runModalForWindow:mFontPanel];
196 mDialogIsExecuting =
false;
200 QCoreApplication::eventDispatcher()->wakeUp();
202 return (mResultCode == NSModalResponseOK);
207- (BOOL)worksWhenModal
212- (QPlatformDialogHelper::DialogCode)dialogResultCode
214 return (mResultCode == NSModalResponseOK) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
217- (BOOL)windowShouldClose:(id)window
222 if (mDialogIsExecuting) {
223 [self finishOffWithCode:NSModalResponseCancel];
227 emit mHelper->reject();
232- (
void)finishOffWithCode:(NSInteger)code
235 if (mDialogIsExecuting) {
241 [NSApp stopModalWithCode:code];
249 if (mResultCode == NSModalResponseCancel) {
250 emit mHelper->reject();
252 emit mHelper->accept();
260@interface QNSView (FontPanel)
261- (
void)changeFont:(id)sender;
264@implementation QNSView (FontPanel)
265- (
void)changeFont:(id)sender
267 if (
auto *delegate = qt_objc_cast<QNSFontPanelDelegate*>(NSFontPanel.sharedFontPanel.delegate))
268 [delegate changeFont:sender];
279 mDelegate = [[QNSFontPanelDelegate alloc] init];
287 void init(QCocoaFontDialogHelper *helper)
289 [mDelegate setDialogHelper:helper];
292 void cleanup(QCocoaFontDialogHelper *helper)
294 if (mDelegate->mHelper == helper)
295 mDelegate->mHelper =
nullptr;
304 return [mDelegate runApplicationModalPanel];
307 bool show(Qt::WindowModality windowModality, QWindow *parent)
310 if (windowModality != Qt::ApplicationModal)
311 [mDelegate showModelessPanel];
318 [mDelegate closePanel];
321 QFont currentFont()
const
323 return mDelegate->mQtFont;
326 void setCurrentFont(
const QFont &font)
328 NSFontManager *mgr = [NSFontManager sharedFontManager];
329 NSFont *nsFont = nil;
332 NSFontTraitMask mask = 0;
333 if (font.style() == QFont::StyleItalic) {
334 mask |= NSItalicFontMask;
336 if (font.weight() == QFont::Bold) {
338 mask |= NSBoldFontMask;
341 QFontInfo fontInfo(font);
342 nsFont = [mgr fontWithFamily:fontInfo.family().toNSString()
345 size:fontInfo.pointSize()];
347 [mgr setSelectedFont:nsFont isMultiple:NO];
348 mDelegate->mQtFont = font;
352 QNSFontPanelDelegate *mDelegate;
357QCocoaFontDialogHelper::QCocoaFontDialogHelper()
361QCocoaFontDialogHelper::~QCocoaFontDialogHelper()
363 sharedFontPanel()->cleanup(
this);
366void QCocoaFontDialogHelper::exec()
368 if (sharedFontPanel()->exec())
374bool QCocoaFontDialogHelper::show(Qt::WindowFlags, Qt::WindowModality windowModality, QWindow *parent)
376 if (windowModality == Qt::ApplicationModal)
377 windowModality = Qt::WindowModal;
378 sharedFontPanel()->init(
this);
379 return sharedFontPanel()->show(windowModality, parent);
382void QCocoaFontDialogHelper::hide()
384 sharedFontPanel()->hide();
387void QCocoaFontDialogHelper::setCurrentFont(
const QFont &font)
389 sharedFontPanel()->init(
this);
390 sharedFontPanel()->setCurrentFont(font);
393QFont QCocoaFontDialogHelper::currentFont()
const
395 return sharedFontPanel()->currentFont();
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)