Remove unused Mac OS X code from QtWidgets

qcolordialog_mac.mm, qfiledialog_mac.mm, qfontdialog_mac.mm, and
qnspanelproxy_mac.mm are unused, remove them. The functionality they
used to provide is already included in the Cocoa platform plugin.

Change-Id: I2815d119687fd8d8dd421da36563afbd645ee000
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
This commit is contained in:
Bradley T. Hughes 2012-05-02 13:47:05 +02:00 committed by Qt by Nokia
parent 98ac56676a
commit af0df2d047
5 changed files with 0 additions and 2171 deletions

View File

@ -20,27 +20,6 @@ HEADERS += \
dialogs/qfileinfogatherer_p.h \
dialogs/qwizard.h
# TODO
false:mac {
OBJECTIVE_SOURCES += dialogs/qfiledialog_mac.mm \
dialogs/qfontdialog_mac.mm \
dialogs/qnspanelproxy_mac.mm
# Compile qcolordialog_mac.mm with exception support, disregarding the -no-exceptions
# configure option. (qcolordialog_mac needs to catch exceptions thrown by cocoa)
EXCEPTION_SOURCES = dialogs/qcolordialog_mac.mm
exceptions_compiler.commands = $$QMAKE_CXX -c
exceptions_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
exceptions_compiler.commands += -fexceptions
exceptions_compiler.dependency_type = TYPE_C
exceptions_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
exceptions_compiler.input = EXCEPTION_SOURCES
exceptions_compiler.variable_out = OBJECTS
exceptions_compiler.name = compiling[exceptopns] ${QMAKE_FILE_IN}
silent:exceptions_compiler.commands = @echo compiling[exceptopns] ${QMAKE_FILE_IN} && $$exceptions_compiler.commands
QMAKE_EXTRA_COMPILERS += exceptions_compiler
}
win32 {
HEADERS += dialogs/qwizard_win_p.h
SOURCES += dialogs/qwizard_win.cpp

View File

@ -1,505 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qcolordialog_p.h"
#if !defined(QT_NO_COLORDIALOG) && defined(Q_WS_MAC)
#include <qapplication.h>
#include <qtimer.h>
#include <qdialogbuttonbox.h>
#include <qabstracteventdispatcher.h>
#include <private/qapplication_p.h>
#include <private/qt_mac_p.h>
#include <qdebug.h>
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#if !CGFLOAT_DEFINED
typedef float CGFloat; // Should only not be defined on 32-bit platforms
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
@protocol NSWindowDelegate <NSObject>
- (void)windowDidResize:(NSNotification *)notification;
- (BOOL)windowShouldClose:(id)window;
@end
#endif
QT_USE_NAMESPACE
@class QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate);
@interface QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) : NSObject<NSWindowDelegate> {
NSColorPanel *mColorPanel;
NSView *mStolenContentView;
NSButton *mOkButton;
NSButton *mCancelButton;
QColorDialogPrivate *mPriv;
QColor *mQtColor;
CGFloat mMinWidth; // currently unused
CGFloat mExtraHeight; // currently unused
BOOL mHackedPanel;
NSInteger mResultCode;
BOOL mDialogIsExecuting;
BOOL mResultSet;
}
- (id)initWithColorPanel:(NSColorPanel *)panel
stolenContentView:(NSView *)stolenContentView
okButton:(NSButton *)okButton
cancelButton:(NSButton *)cancelButton
priv:(QColorDialogPrivate *)priv;
- (void)colorChanged:(NSNotification *)notification;
- (void)relayout;
- (void)onOkClicked;
- (void)onCancelClicked;
- (void)updateQtColor;
- (NSColorPanel *)colorPanel;
- (QColor)qtColor;
- (void)finishOffWithCode:(NSInteger)result;
- (void)showColorPanel;
- (void)exec;
- (void)setResultSet:(BOOL)result;
@end
@implementation QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate)
- (id)initWithColorPanel:(NSColorPanel *)panel
stolenContentView:(NSView *)stolenContentView
okButton:(NSButton *)okButton
cancelButton:(NSButton *)cancelButton
priv:(QColorDialogPrivate *)priv
{
self = [super init];
mColorPanel = panel;
mStolenContentView = stolenContentView;
mOkButton = okButton;
mCancelButton = cancelButton;
mPriv = priv;
mMinWidth = 0.0;
mExtraHeight = 0.0;
mHackedPanel = (okButton != 0);
mResultCode = NSCancelButton;
mDialogIsExecuting = false;
mResultSet = false;
if (mHackedPanel) {
[self relayout];
[okButton setAction:@selector(onOkClicked)];
[okButton setTarget:self];
[cancelButton setAction:@selector(onCancelClicked)];
[cancelButton setTarget:self];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(colorChanged:)
name:NSColorPanelColorDidChangeNotification
object:mColorPanel];
mQtColor = new QColor();
return self;
}
- (void)dealloc
{
QMacCocoaAutoReleasePool pool;
if (mHackedPanel) {
NSView *ourContentView = [mColorPanel contentView];
// return stolen stuff to its rightful owner
[mStolenContentView removeFromSuperview];
[mColorPanel setContentView:mStolenContentView];
[mOkButton release];
[mCancelButton release];
[ourContentView release];
}
[mColorPanel setDelegate:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self];
delete mQtColor;
[super dealloc];
}
- (void)setResultSet:(BOOL)result
{
mResultSet = result;
}
- (BOOL)windowShouldClose:(id)window
{
Q_UNUSED(window);
if (!mHackedPanel)
[self updateQtColor];
if (mDialogIsExecuting) {
[self finishOffWithCode:NSCancelButton];
} else {
mResultSet = true;
mPriv->colorDialog()->reject();
}
return true;
}
- (void)windowDidResize:(NSNotification *)notification
{
Q_UNUSED(notification);
if (mHackedPanel)
[self relayout];
}
- (void)colorChanged:(NSNotification *)notification
{
Q_UNUSED(notification);
[self updateQtColor];
}
- (void)relayout
{
Q_ASSERT(mHackedPanel);
NSRect rect = [[mStolenContentView superview] frame];
// should a priori be kept in sync with qfontdialog_mac.mm
const CGFloat ButtonMinWidth = 78.0; // 84.0 for Carbon
const CGFloat ButtonMinHeight = 32.0;
const CGFloat ButtonSpacing = 0.0;
const CGFloat ButtonTopMargin = 0.0;
const CGFloat ButtonBottomMargin = 7.0;
const CGFloat ButtonSideMargin = 9.0;
[mOkButton sizeToFit];
NSSize okSizeHint = [mOkButton frame].size;
[mCancelButton sizeToFit];
NSSize cancelSizeHint = [mCancelButton frame].size;
const CGFloat ButtonWidth = qMin(qMax(ButtonMinWidth,
qMax(okSizeHint.width, cancelSizeHint.width)),
CGFloat((rect.size.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5));
const CGFloat ButtonHeight = qMax(ButtonMinHeight,
qMax(okSizeHint.height, cancelSizeHint.height));
NSRect okRect = { { rect.size.width - ButtonSideMargin - ButtonWidth,
ButtonBottomMargin },
{ ButtonWidth, ButtonHeight } };
[mOkButton setFrame:okRect];
[mOkButton setNeedsDisplay:YES];
NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - ButtonWidth,
ButtonBottomMargin },
{ ButtonWidth, ButtonHeight } };
[mCancelButton setFrame:cancelRect];
[mCancelButton setNeedsDisplay:YES];
const CGFloat Y = ButtonBottomMargin + ButtonHeight + ButtonTopMargin;
NSRect stolenCVRect = { { 0.0, Y },
{ rect.size.width, rect.size.height - Y } };
[mStolenContentView setFrame:stolenCVRect];
[mStolenContentView setNeedsDisplay:YES];
[[mStolenContentView superview] setNeedsDisplay:YES];
mMinWidth = 2 * ButtonSideMargin + ButtonSpacing + 2 * ButtonWidth;
mExtraHeight = Y;
}
- (void)onOkClicked
{
Q_ASSERT(mHackedPanel);
[[mStolenContentView window] close];
[self updateQtColor];
[self finishOffWithCode:NSOKButton];
}
- (void)onCancelClicked
{
if (mHackedPanel) {
[[mStolenContentView window] close];
delete mQtColor;
mQtColor = new QColor();
[self finishOffWithCode:NSCancelButton];
}
}
- (void)updateQtColor
{
delete mQtColor;
mQtColor = new QColor();
NSColor *color = [mColorPanel color];
NSString *colorSpaceName = [color colorSpaceName];
if (colorSpaceName == NSDeviceCMYKColorSpace) {
CGFloat cyan = 0, magenta = 0, yellow = 0, black = 0, alpha = 0;
[color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha];
mQtColor->setCmykF(cyan, magenta, yellow, black, alpha);
} else if (colorSpaceName == NSCalibratedRGBColorSpace || colorSpaceName == NSDeviceRGBColorSpace) {
CGFloat red = 0, green = 0, blue = 0, alpha = 0;
[color getRed:&red green:&green blue:&blue alpha:&alpha];
mQtColor->setRgbF(red, green, blue, alpha);
} else if (colorSpaceName == NSNamedColorSpace) {
NSColor *tmpColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
CGFloat red = 0, green = 0, blue = 0, alpha = 0;
[tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
mQtColor->setRgbF(red, green, blue, alpha);
} else {
NSColorSpace *colorSpace = [color colorSpace];
if ([colorSpace colorSpaceModel] == NSCMYKColorSpaceModel && [color numberOfComponents] == 5){
CGFloat components[5];
[color getComponents:components];
mQtColor->setCmykF(components[0], components[1], components[2], components[3], components[4]);
} else {
NSColor *tmpColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
CGFloat red = 0, green = 0, blue = 0, alpha = 0;
[tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
mQtColor->setRgbF(red, green, blue, alpha);
}
}
mPriv->setCurrentQColor(*mQtColor);
}
- (NSColorPanel *)colorPanel
{
return mColorPanel;
}
- (QColor)qtColor
{
return *mQtColor;
}
- (void)finishOffWithCode:(NSInteger)code
{
mResultCode = code;
if (mDialogIsExecuting) {
// We stop the current modal event loop. The control
// will then return inside -(void)exec below.
// It's important that the modal event loop is stopped before
// we accept/reject QColorDialog, since QColorDialog has its
// own event loop that needs to be stopped last.
[NSApp stopModalWithCode:code];
} else {
// Since we are not in a modal event loop, we can safely close
// down QColorDialog
// Calling accept() or reject() can in turn call closeCocoaColorPanel.
// This check will prevent any such recursion.
if (!mResultSet) {
mResultSet = true;
if (mResultCode == NSCancelButton) {
mPriv->colorDialog()->reject();
} else {
mPriv->colorDialog()->accept();
}
}
}
}
- (void)showColorPanel
{
mDialogIsExecuting = false;
[mColorPanel makeKeyAndOrderFront:mColorPanel];
}
- (void)exec
{
QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
QMacCocoaAutoReleasePool pool;
mDialogIsExecuting = true;
bool modalEnded = false;
while (!modalEnded) {
#ifndef QT_NO_EXCEPTIONS
@try {
[NSApp runModalForWindow:mColorPanel];
modalEnded = true;
} @catch (NSException *) {
// For some reason, NSColorPanel throws an exception when
// clicking on 'SelectedMenuItemColor' from the 'Developer'
// palette (tab three).
}
#else
[NSApp runModalForWindow:mColorPanel];
modalEnded = true;
#endif
}
QAbstractEventDispatcher::instance()->interrupt();
if (mResultCode == NSCancelButton)
mPriv->colorDialog()->reject();
else
mPriv->colorDialog()->accept();
}
@end
QT_BEGIN_NAMESPACE
extern void macStartInterceptNSPanelCtor();
extern void macStopInterceptNSPanelCtor();
extern NSButton *macCreateButton(const char *text, NSView *superview);
void QColorDialogPrivate::openCocoaColorPanel(const QColor &initial,
QWidget *parent, const QString &title, QColorDialog::ColorDialogOptions options)
{
Q_UNUSED(parent); // we would use the parent if only NSColorPanel could be a sheet
QMacCocoaAutoReleasePool pool;
if (!delegate) {
/*
The standard Cocoa color panel has no OK or Cancel button and
is created as a utility window, whereas we want something like
the Carbon color panel. We need to take the following steps:
1. Intercept the color panel constructor to turn off the
NSUtilityWindowMask flag. This is done by temporarily
replacing initWithContentRect:styleMask:backing:defer:
in NSPanel by our own method.
2. Modify the color panel so that its content view is part
of a new content view that contains it as well as two
buttons (OK and Cancel).
3. Lay out the original content view and the buttons when
the color panel is shown and whenever it is resized.
4. Clean up after ourselves.
*/
bool hackColorPanel = !(options & QColorDialog::NoButtons);
if (hackColorPanel)
macStartInterceptNSPanelCtor();
NSColorPanel *colorPanel = [NSColorPanel sharedColorPanel];
if (hackColorPanel)
macStopInterceptNSPanelCtor();
[colorPanel setHidesOnDeactivate:false];
// set up the Cocoa color panel
[colorPanel setShowsAlpha:options & QColorDialog::ShowAlphaChannel];
[colorPanel setTitle:(NSString*)(CFStringRef)QCFString(title)];
NSView *stolenContentView = 0;
NSButton *okButton = 0;
NSButton *cancelButton = 0;
if (hackColorPanel) {
// steal the color panel's contents view
stolenContentView = [colorPanel contentView];
[stolenContentView retain];
[colorPanel 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);
[colorPanel setContentView:ourContentView];
[colorPanel setDefaultButtonCell:[okButton cell]];
}
delegate = [[QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) alloc] initWithColorPanel:colorPanel
stolenContentView:stolenContentView
okButton:okButton
cancelButton:cancelButton
priv:this];
[colorPanel setDelegate:static_cast<QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) *>(delegate)];
}
[static_cast<QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) *>(delegate) setResultSet:NO];
setCocoaPanelColor(initial);
[static_cast<QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) *>(delegate) showColorPanel];
}
void QColorDialogPrivate::closeCocoaColorPanel()
{
[static_cast<QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) *>(delegate) onCancelClicked];
}
void QColorDialogPrivate::releaseCocoaColorPanelDelegate()
{
[static_cast<QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) *>(delegate) release];
}
void QColorDialogPrivate::mac_nativeDialogModalHelp()
{
// 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 (delegate){
Q_Q(QColorDialog);
QTimer::singleShot(1, q, SLOT(_q_macRunNativeAppModalPanel()));
}
}
void QColorDialogPrivate::_q_macRunNativeAppModalPanel()
{
[static_cast<QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) *>(delegate) exec];
}
void QColorDialogPrivate::setCocoaPanelColor(const QColor &color)
{
QMacCocoaAutoReleasePool pool;
QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) *theDelegate = static_cast<QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) *>(delegate);
NSColor *nsColor;
const QColor::Spec spec = color.spec();
if (spec == QColor::Cmyk) {
nsColor = [NSColor colorWithDeviceCyan:color.cyanF()
magenta:color.magentaF()
yellow:color.yellowF()
black:color.blackF()
alpha:color.alphaF()];
} else {
nsColor = [NSColor colorWithCalibratedRed:color.redF()
green:color.greenF()
blue:color.blueF()
alpha:color.alphaF()];
}
[[theDelegate colorPanel] setColor:nsColor];
}
QT_END_NAMESPACE
#endif

View File

@ -1,741 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qfiledialog.h"
#ifndef QT_NO_FILEDIALOG
/*****************************************************************************
QFileDialog debug facilities
*****************************************************************************/
//#define DEBUG_FILEDIALOG_FILTERS
#include <qapplication.h>
#include <private/qapplication_p.h>
#include <private/qfiledialog_p.h>
#include <private/qt_mac_p.h>
#include <private/qt_cocoa_helpers_mac_p.h>
#include <qregexp.h>
#include <qbuffer.h>
#include <qdebug.h>
#include <qstringlist.h>
#include <qaction.h>
#include <qtextcodec.h>
#include <qvarlengtharray.h>
#include <qdesktopwidget.h>
#include <stdlib.h>
#include <qabstracteventdispatcher.h>
#import <AppKit/NSSavePanel.h>
#include "ui_qfiledialog.h"
QT_BEGIN_NAMESPACE
extern QStringList qt_make_filter_list(const QString &filter); // qfiledialog.cpp
extern QStringList qt_clean_filter_list(const QString &filter); // qfiledialog.cpp
extern const char *qt_file_dialog_filter_reg_exp; // qfiledialog.cpp
extern bool qt_mac_is_macsheet(const QWidget *w); // qwidget_mac.mm
QT_END_NAMESPACE
QT_FORWARD_DECLARE_CLASS(QFileDialogPrivate)
QT_FORWARD_DECLARE_CLASS(QString)
QT_FORWARD_DECLARE_CLASS(QStringList)
QT_FORWARD_DECLARE_CLASS(QWidget)
QT_FORWARD_DECLARE_CLASS(QAction)
QT_FORWARD_DECLARE_CLASS(QFileInfo)
QT_USE_NAMESPACE
@class QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate);
@interface QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
: NSObject<NSOpenSavePanelDelegate>
#else
: NSObject
#endif
{
@public
NSOpenPanel *mOpenPanel;
NSSavePanel *mSavePanel;
NSView *mAccessoryView;
NSPopUpButton *mPopUpButton;
NSTextField *mTextField;
QFileDialogPrivate *mPriv;
NSString *mCurrentDir;
bool mConfirmOverwrite;
int mReturnCode;
QT_PREPEND_NAMESPACE(QFileDialog::AcceptMode) mAcceptMode;
QT_PREPEND_NAMESPACE(QDir::Filters) *mQDirFilter;
QT_PREPEND_NAMESPACE(QFileDialog::FileMode) mFileMode;
QT_PREPEND_NAMESPACE(QFileDialog::Options) *mFileOptions;
QString *mLastFilterCheckPath;
QString *mCurrentSelection;
QStringList *mQDirFilterEntryList;
QStringList *mNameFilterDropDownList;
QStringList *mSelectedNameFilter;
}
- (NSString *)strip:(const QString &)label;
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename;
- (void)filterChanged:(id)sender;
- (void)showModelessPanel;
- (BOOL)runApplicationModalPanel;
- (void)showWindowModalSheet:(QWidget *)docWidget;
- (void)updateProperties;
- (QStringList)acceptableExtensionsForSave;
- (QString)removeExtensions:(const QString &)filter;
- (void)createTextField;
- (void)createPopUpButton:(const QString &)selectedFilter hideDetails:(BOOL)hideDetails;
- (QStringList)findStrippedFilterWithVisualFilterName:(QString)name;
- (void)createAccessory;
@end
@implementation QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate)
- (id)initWithAcceptMode:(QT_PREPEND_NAMESPACE(QFileDialog::AcceptMode))acceptMode
title:(const QString &)title
hideNameFilterDetails:(bool)hideNameFilterDetails
qDirFilter:(QT_PREPEND_NAMESPACE(QDir::Filters))qDirFilter
fileOptions:(QT_PREPEND_NAMESPACE(QFileDialog::Options))fileOptions
fileMode:(QT_PREPEND_NAMESPACE(QFileDialog::FileMode))fileMode
selectFile:(const QString &)selectFile
confirmOverwrite:(bool)confirm
priv:(QFileDialogPrivate *)priv
{
self = [super init];
mAcceptMode = acceptMode;
if (mAcceptMode == QT_PREPEND_NAMESPACE(QFileDialog::AcceptOpen)){
mOpenPanel = [NSOpenPanel openPanel];
mSavePanel = mOpenPanel;
} else {
mSavePanel = [NSSavePanel savePanel];
mOpenPanel = 0;
}
[mSavePanel setLevel:NSModalPanelWindowLevel];
[mSavePanel setDelegate:self];
mQDirFilter = new QT_PREPEND_NAMESPACE(QDir::Filters)(qDirFilter);
mFileOptions = new QT_PREPEND_NAMESPACE(QFileDialog::Options)(fileOptions);
mFileMode = fileMode;
mConfirmOverwrite = confirm;
mReturnCode = -1;
mPriv = priv;
mLastFilterCheckPath = new QString;
mQDirFilterEntryList = new QStringList;
mNameFilterDropDownList = new QStringList(priv->nameFilters);
QString selectedVisualNameFilter = priv->qFileDialogUi->fileTypeCombo->currentText();
mSelectedNameFilter = new QStringList([self findStrippedFilterWithVisualFilterName:selectedVisualNameFilter]);
QFileInfo sel(selectFile);
if (sel.isDir()){
mCurrentDir = [qt_mac_QStringToNSString(sel.absoluteFilePath()) retain];
mCurrentSelection = new QString;
} else {
mCurrentDir = [qt_mac_QStringToNSString(sel.absolutePath()) retain];
mCurrentSelection = new QString(sel.absoluteFilePath());
}
[mSavePanel setTitle:qt_mac_QStringToNSString(title)];
[self createPopUpButton:selectedVisualNameFilter hideDetails:hideNameFilterDetails];
[self createTextField];
[self createAccessory];
[mSavePanel setAccessoryView:mNameFilterDropDownList->size() > 1 ? mAccessoryView : nil];
if (mPriv){
[mSavePanel setPrompt:[self strip:mPriv->acceptLabel]];
if (mPriv->fileNameLabelExplicitlySat)
[mSavePanel setNameFieldLabel:[self strip:mPriv->qFileDialogUi->fileNameLabel->text()]];
}
[self updateProperties];
[mSavePanel retain];
return self;
}
- (void)dealloc
{
delete mQDirFilter;
delete mFileOptions;
delete mLastFilterCheckPath;
delete mQDirFilterEntryList;
delete mNameFilterDropDownList;
delete mSelectedNameFilter;
delete mCurrentSelection;
[mSavePanel orderOut:mSavePanel];
[mSavePanel setAccessoryView:nil];
[mPopUpButton release];
[mTextField release];
[mAccessoryView release];
[mSavePanel setDelegate:nil];
[mSavePanel release];
[mCurrentDir release];
[super dealloc];
}
- (NSString *)strip:(const QString &)label
{
QAction a(label, 0);
return qt_mac_QStringToNSString(a.iconText());
}
- (void)closePanel
{
*mCurrentSelection = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)([mSavePanel filename]);
[mSavePanel close];
}
- (void)showModelessPanel
{
if (mOpenPanel){
QFileInfo info(*mCurrentSelection);
NSString *filename = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.fileName());
NSString *filepath = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.filePath());
bool selectable = (mAcceptMode == QFileDialog::AcceptSave)
|| [self panel:nil shouldShowFilename:filepath];
[mOpenPanel
beginForDirectory:mCurrentDir
file:selectable ? filename : nil
types:nil
modelessDelegate:self
didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
}
- (BOOL)runApplicationModalPanel
{
QFileInfo info(*mCurrentSelection);
NSString *filename = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.fileName());
NSString *filepath = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.filePath());
bool selectable = (mAcceptMode == QFileDialog::AcceptSave)
|| [self panel:nil shouldShowFilename:filepath];
mReturnCode = [mSavePanel
runModalForDirectory:mCurrentDir
file:selectable ? filename : @"untitled"];
QAbstractEventDispatcher::instance()->interrupt();
return (mReturnCode == NSOKButton);
}
- (QT_PREPEND_NAMESPACE(QDialog::DialogCode))dialogResultCode
{
return (mReturnCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QDialog::Accepted) : QT_PREPEND_NAMESPACE(QDialog::Rejected);
}
- (void)showWindowModalSheet:(QWidget *)docWidget
{
Q_UNUSED(docWidget);
QFileInfo info(*mCurrentSelection);
NSString *filename = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.fileName());
NSString *filepath = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.filePath());
bool selectable = (mAcceptMode == QFileDialog::AcceptSave)
|| [self panel:nil shouldShowFilename:filepath];
[mSavePanel
beginSheetForDirectory:mCurrentDir
file:selectable ? filename : nil
modalForWindow:QT_PREPEND_NAMESPACE(qt_mac_window_for)(docWidget)
modalDelegate:self
didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename
{
Q_UNUSED(sender);
if ([filename length] == 0)
return NO;
// Always accept directories regardless of their names (unless it is a bundle):
BOOL isDir;
if ([[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isDir] && isDir) {
if ([mSavePanel treatsFilePackagesAsDirectories] == NO) {
if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename] == NO)
return YES;
}
}
QString qtFileName = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)(filename);
QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C)));
QString path = info.absolutePath();
if (path != *mLastFilterCheckPath){
*mLastFilterCheckPath = path;
*mQDirFilterEntryList = info.dir().entryList(*mQDirFilter);
}
// Check if the QDir filter accepts the file:
if (!mQDirFilterEntryList->contains(info.fileName()))
return NO;
// No filter means accept everything
if (mSelectedNameFilter->isEmpty())
return YES;
// Check if the current file name filter accepts the file:
for (int i=0; i<mSelectedNameFilter->size(); ++i) {
if (QDir::match(mSelectedNameFilter->at(i), qtFileName))
return YES;
}
return NO;
}
- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag
{
Q_UNUSED(sender);
if (!okFlag)
return filename;
if (mConfirmOverwrite)
return filename;
// User has clicked save, and no overwrite confirmation should occur.
// To get the latter, we need to change the name we return (hence the prefix):
return [@"___qt_very_unlikely_prefix_" stringByAppendingString:filename];
}
- (void)setNameFilters:(const QStringList &)filters hideDetails:(BOOL)hideDetails
{
[mPopUpButton removeAllItems];
*mNameFilterDropDownList = filters;
if (filters.size() > 0){
for (int i=0; i<filters.size(); ++i) {
QString filter = hideDetails ? [self removeExtensions:filters.at(i)] : filters.at(i);
[mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(filter)];
}
[mPopUpButton selectItemAtIndex:0];
[mSavePanel setAccessoryView:mAccessoryView];
} else
[mSavePanel setAccessoryView:nil];
[self filterChanged:self];
}
- (void)filterChanged:(id)sender
{
// This mDelegate function is called when the _name_ filter changes.
Q_UNUSED(sender);
QString selection = mNameFilterDropDownList->value([mPopUpButton indexOfSelectedItem]);
*mSelectedNameFilter = [self findStrippedFilterWithVisualFilterName:selection];
[mSavePanel validateVisibleColumns];
[self updateProperties];
if (mPriv)
mPriv->QNSOpenSavePanelDelegate_filterSelected([mPopUpButton indexOfSelectedItem]);
}
- (QString)currentNameFilter
{
return mNameFilterDropDownList->value([mPopUpButton indexOfSelectedItem]);
}
- (QStringList)selectedFiles
{
if (mOpenPanel)
return QT_PREPEND_NAMESPACE(qt_mac_NSArrayToQStringList)([mOpenPanel filenames]);
else{
QStringList result;
QString filename = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)([mSavePanel filename]);
result << filename.remove(QLatin1String("___qt_very_unlikely_prefix_"));
return result;
}
}
- (void)updateProperties
{
// Call this functions if mFileMode, mFileOptions,
// mNameFilterDropDownList or mQDirFilter changes.
// The savepanel does not contain the neccessary functions for this.
bool chooseFilesOnly = mFileMode == QT_PREPEND_NAMESPACE(QFileDialog::ExistingFile)
|| mFileMode == QT_PREPEND_NAMESPACE(QFileDialog::ExistingFiles);
bool chooseDirsOnly = mFileMode == QT_PREPEND_NAMESPACE(QFileDialog::Directory)
|| mFileMode == QT_PREPEND_NAMESPACE(QFileDialog::DirectoryOnly)
|| *mFileOptions & QT_PREPEND_NAMESPACE(QFileDialog::ShowDirsOnly);
[mOpenPanel setCanChooseFiles:!chooseDirsOnly];
[mOpenPanel setCanChooseDirectories:!chooseFilesOnly];
[mSavePanel setCanCreateDirectories:!(*mFileOptions & QT_PREPEND_NAMESPACE(QFileDialog::ReadOnly))];
[mOpenPanel setAllowsMultipleSelection:(mFileMode == QT_PREPEND_NAMESPACE(QFileDialog::ExistingFiles))];
[mOpenPanel setResolvesAliases:!(*mFileOptions & QT_PREPEND_NAMESPACE(QFileDialog::DontResolveSymlinks))];
QStringList ext = [self acceptableExtensionsForSave];
if (mPriv && !ext.isEmpty() && !mPriv->defaultSuffix.isEmpty())
ext.prepend(mPriv->defaultSuffix);
[mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : QT_PREPEND_NAMESPACE(qt_mac_QStringListToNSMutableArray(ext))];
if ([mSavePanel isVisible])
[mOpenPanel validateVisibleColumns];
}
- (void)panelSelectionDidChange:(id)sender
{
Q_UNUSED(sender);
if (mPriv) {
QString selection = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString([mSavePanel filename]));
if (selection != mCurrentSelection) {
*mCurrentSelection = selection;
mPriv->QNSOpenSavePanelDelegate_selectionChanged(selection);
}
}
}
- (void)openPanelDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
Q_UNUSED(panel);
Q_UNUSED(contextInfo);
mReturnCode = returnCode;
if (mPriv)
mPriv->QNSOpenSavePanelDelegate_panelClosed(returnCode == NSOKButton);
}
- (void)panel:(id)sender directoryDidChange:(NSString *)path
{
Q_UNUSED(sender);
if (!mPriv)
return;
if ([path isEqualToString:mCurrentDir])
return;
[mCurrentDir release];
mCurrentDir = [path retain];
mPriv->QNSOpenSavePanelDelegate_directoryEntered(QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString(mCurrentDir)));
}
/*
Returns a list of extensions (e.g. "png", "jpg", "gif")
for the current name filter. If a filter do not conform
to the format *.xyz or * or *.*, an empty list
is returned meaning accept everything.
*/
- (QStringList)acceptableExtensionsForSave
{
QStringList result;
for (int i=0; i<mSelectedNameFilter->count(); ++i) {
const QString &filter = mSelectedNameFilter->at(i);
if (filter.startsWith(QLatin1String("*."))
&& !filter.contains(QLatin1Char('?'))
&& filter.count(QLatin1Char('*')) == 1) {
result += filter.mid(2);
} else {
return QStringList(); // Accept everything
}
}
return result;
}
- (QString)removeExtensions:(const QString &)filter
{
QRegExp regExp(QT_PREPEND_NAMESPACE(QString::fromLatin1)(QT_PREPEND_NAMESPACE(qt_file_dialog_filter_reg_exp)));
if (regExp.indexIn(filter) != -1)
return regExp.cap(1).trimmed();
return filter;
}
- (void)createTextField
{
NSRect textRect = { { 0.0, 3.0 }, { 100.0, 25.0 } };
mTextField = [[NSTextField alloc] initWithFrame:textRect];
[[mTextField cell] setFont:[NSFont systemFontOfSize:
[NSFont systemFontSizeForControlSize:NSRegularControlSize]]];
[mTextField setAlignment:NSRightTextAlignment];
[mTextField setEditable:false];
[mTextField setSelectable:false];
[mTextField setBordered:false];
[mTextField setDrawsBackground:false];
if (mPriv){
[mTextField setStringValue:[self strip:mPriv->qFileDialogUi->fileTypeLabel->text()]];
} else
[mTextField setStringValue:QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(QT_PREPEND_NAMESPACE(QFileDialog::tr)("Files of type:"))];
}
- (void)createPopUpButton:(const QString &)selectedFilter hideDetails:(BOOL)hideDetails
{
NSRect popUpRect = { { 100.0, 5.0 }, { 250.0, 25.0 } };
mPopUpButton = [[NSPopUpButton alloc] initWithFrame:popUpRect pullsDown:NO];
[mPopUpButton setTarget:self];
[mPopUpButton setAction:@selector(filterChanged:)];
QStringList *filters = mNameFilterDropDownList;
if (filters->size() > 0){
for (int i=0; i<mNameFilterDropDownList->size(); ++i) {
QString filter = hideDetails ? [self removeExtensions:filters->at(i)] : filters->at(i);
[mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(filter)];
if (filters->at(i).startsWith(selectedFilter))
[mPopUpButton selectItemAtIndex:i];
}
}
}
- (QStringList) findStrippedFilterWithVisualFilterName:(QString)name
{
for (int i=0; i<mNameFilterDropDownList->size(); ++i) {
if (mNameFilterDropDownList->at(i).startsWith(name))
return qt_clean_filter_list(mNameFilterDropDownList->at(i));
}
return QStringList();
}
- (void)createAccessory
{
NSRect accessoryRect = { { 0.0, 0.0 }, { 450.0, 33.0 } };
mAccessoryView = [[NSView alloc] initWithFrame:accessoryRect];
[mAccessoryView addSubview:mTextField];
[mAccessoryView addSubview:mPopUpButton];
}
@end
QT_BEGIN_NAMESPACE
void QFileDialogPrivate::QNSOpenSavePanelDelegate_selectionChanged(const QString &newPath)
{
emit q_func()->currentChanged(newPath);
}
void QFileDialogPrivate::QNSOpenSavePanelDelegate_panelClosed(bool accepted)
{
if (accepted)
q_func()->accept();
else
q_func()->reject();
}
void QFileDialogPrivate::QNSOpenSavePanelDelegate_directoryEntered(const QString &newDir)
{
setLastVisitedDirectory(newDir);
emit q_func()->directoryEntered(newDir);
}
void QFileDialogPrivate::QNSOpenSavePanelDelegate_filterSelected(int menuIndex)
{
emit q_func()->filterSelected(nameFilters.at(menuIndex));
}
extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1); // qglobal.cpp
void QFileDialogPrivate::setDirectory_sys(const QString &directory)
{
QMacCocoaAutoReleasePool pool;
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
[delegate->mSavePanel setDirectory:qt_mac_QStringToNSString(directory)];
}
QString QFileDialogPrivate::directory_sys() const
{
QMacCocoaAutoReleasePool pool;
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
return qt_mac_NSStringToQString([delegate->mSavePanel directory]);
}
void QFileDialogPrivate::selectFile_sys(const QString &filename)
{
QString filePath = filename;
if (QDir::isRelativePath(filePath))
filePath = QFileInfo(directory_sys(), filePath).filePath();
// There seems to no way to select a file once the dialog is running.
// So do the next best thing, set the file's directory:
setDirectory_sys(QFileInfo(filePath).absolutePath());
}
QStringList QFileDialogPrivate::selectedFiles_sys() const
{
QMacCocoaAutoReleasePool pool;
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
return [delegate selectedFiles];
}
void QFileDialogPrivate::setNameFilters_sys(const QStringList &filters)
{
QMacCocoaAutoReleasePool pool;
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
bool hideDetails = q_func()->testOption(QFileDialog::HideNameFilterDetails);
[delegate setNameFilters:filters hideDetails:hideDetails];
}
void QFileDialogPrivate::setFilter_sys()
{
Q_Q(QFileDialog);
QMacCocoaAutoReleasePool pool;
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
*(delegate->mQDirFilter) = model->filter();
delegate->mFileMode = fileMode;
[delegate->mSavePanel setTitle:qt_mac_QStringToNSString(q->windowTitle())];
[delegate->mSavePanel setPrompt:[delegate strip:acceptLabel]];
if (fileNameLabelExplicitlySat)
[delegate->mSavePanel setNameFieldLabel:[delegate strip:qFileDialogUi->fileNameLabel->text()]];
[delegate updateProperties];
}
void QFileDialogPrivate::selectNameFilter_sys(const QString &filter)
{
int index = nameFilters.indexOf(filter);
if (index != -1) {
QMacCocoaAutoReleasePool pool;
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
[delegate->mPopUpButton selectItemAtIndex:index];
[delegate filterChanged:nil];
}
}
QString QFileDialogPrivate::selectedNameFilter_sys() const
{
QMacCocoaAutoReleasePool pool;
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
int index = [delegate->mPopUpButton indexOfSelectedItem];
return index != -1 ? nameFilters.at(index) : QString();
}
void QFileDialogPrivate::deleteNativeDialog_sys()
{
QMacCocoaAutoReleasePool pool;
[reinterpret_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate) release];
mDelegate = 0;
nativeDialogInUse = false;
}
bool QFileDialogPrivate::setVisible_sys(bool visible)
{
Q_Q(QFileDialog);
if (!visible == q->isHidden())
return false;
if (q->windowFlags() & Qt::WindowStaysOnTopHint) {
// The native file dialog tries all it can to stay
// on the NSModalPanel level. And it might also show
// its own "create directory" dialog that we cannot control.
// So we need to use the non-native version in this case...
return false;
}
return visible ? showCocoaFilePanel() : hideCocoaFilePanel();
}
void QFileDialogPrivate::createNSOpenSavePanelDelegate()
{
Q_Q(QFileDialog);
if (mDelegate)
return;
bool selectDir = q->selectedFiles().isEmpty();
QString selection(selectDir ? q->directory().absolutePath() : q->selectedFiles().value(0));
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) alloc]
initWithAcceptMode:acceptMode
title:q->windowTitle()
hideNameFilterDetails:q->testOption(QFileDialog::HideNameFilterDetails)
qDirFilter:model->filter()
fileOptions:opts
fileMode:fileMode
selectFile:selection
confirmOverwrite:!q->testOption(QFileDialog::DontConfirmOverwrite)
priv:this];
mDelegate = delegate;
}
bool QFileDialogPrivate::showCocoaFilePanel()
{
Q_Q(QFileDialog);
QMacCocoaAutoReleasePool pool;
createNSOpenSavePanelDelegate();
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
if (qt_mac_is_macsheet(q))
[delegate showWindowModalSheet:q->parentWidget()];
else
[delegate showModelessPanel];
return true;
}
bool QFileDialogPrivate::hideCocoaFilePanel()
{
if (!mDelegate){
// Nothing to do. We return false to leave the question
// open regarding whether or not to go native:
return false;
} else {
QMacCocoaAutoReleasePool pool;
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
[delegate closePanel];
// Even when we hide it, we are still using a
// native dialog, so return true:
return true;
}
}
void QFileDialogPrivate::platformNativeDialogModalHelp()
{
// 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(QFileDialog);
QTimer::singleShot(1, q, SLOT(_q_macRunNativeAppModalPanel()));
}
}
void QFileDialogPrivate::_q_macRunNativeAppModalPanel()
{
QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
Q_Q(QFileDialog);
QMacCocoaAutoReleasePool pool;
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
[delegate runApplicationModalPanel];
dialogResultCode_sys() == QDialog::Accepted ? q->accept() : q->reject();
}
QDialog::DialogCode QFileDialogPrivate::dialogResultCode_sys()
{
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
return [delegate dialogResultCode];
}
QT_END_NAMESPACE
#endif // QT_NO_FILEDIALOG

View File

@ -1,676 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qfontdialog_p.h"
#if !defined(QT_NO_FONTDIALOG) && defined(Q_WS_MAC)
#include <qapplication.h>
#include <qdialogbuttonbox.h>
#include <qlineedit.h>
#include <private/qapplication_p.h>
#include <private/qfont_p.h>
#include <private/qfontengine_p.h>
#include <private/qt_cocoa_helpers_mac_p.h>
#include <private/qt_mac_p.h>
#include <qabstracteventdispatcher.h>
#include <qdebug.h>
#include <private/qfontengine_coretext_p.h>
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#if !CGFLOAT_DEFINED
typedef float CGFloat; // Should only not be defined on 32-bit platforms
#endif
QT_BEGIN_NAMESPACE
extern void macStartInterceptNSPanelCtor();
extern void macStopInterceptNSPanelCtor();
extern NSButton *macCreateButton(const char *text, NSView *superview);
extern bool qt_mac_is_macsheet(const QWidget *w); // qwidget_mac.mm
QT_END_NAMESPACE
QT_USE_NAMESPACE
// should a priori be kept in sync with qcolordialog_mac.mm
const CGFloat ButtonMinWidth = 78.0;
const CGFloat ButtonMinHeight = 32.0;
const CGFloat ButtonSpacing = 0.0;
const CGFloat ButtonTopMargin = 0.0;
const CGFloat ButtonBottomMargin = 7.0;
const CGFloat ButtonSideMargin = 9.0;
// looks better with some margins
const CGFloat DialogTopMargin = 7.0;
const CGFloat DialogSideMargin = 9.0;
const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
@class QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate);
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
@protocol NSWindowDelegate <NSObject>
- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize;
@end
#endif
@interface QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) : NSObject <NSWindowDelegate> {
NSFontPanel *mFontPanel;
NSView *mStolenContentView;
NSButton *mOkButton;
NSButton *mCancelButton;
QFontDialogPrivate *mPriv;
QFont *mQtFont;
BOOL mPanelHackedWithButtons;
CGFloat mDialogExtraWidth;
CGFloat mDialogExtraHeight;
int mReturnCode;
BOOL mAppModal;
}
- (id)initWithFontPanel:(NSFontPanel *)panel
stolenContentView:(NSView *)stolenContentView
okButton:(NSButton *)okButton
cancelButton:(NSButton *)cancelButton
priv:(QFontDialogPrivate *)priv
extraWidth:(CGFloat)extraWidth
extraHeight:(CGFloat)extraHeight;
- (void)showModelessPanel;
- (void)showWindowModalSheet:(QWidget *)docWidget;
- (void)runApplicationModalPanel;
- (BOOL)isAppModal;
- (void)changeFont:(id)sender;
- (void)changeAttributes:(id)sender;
- (BOOL)windowShouldClose:(id)window;
- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize;
- (void)relayout;
- (void)relayoutToContentSize:(NSSize)frameSize;
- (void)onOkClicked;
- (void)onCancelClicked;
- (NSFontPanel *)fontPanel;
- (NSWindow *)actualPanel;
- (NSSize)dialogExtraSize;
- (void)setQtFont:(const QFont &)newFont;
- (QFont)qtFont;
- (void)finishOffWithCode:(NSInteger)result;
- (void)cleanUpAfterMyself;
- (void)setSubwindowStacking;
@end
static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
{
QFont newFont;
if (cocoaFont) {
int pSize = qRound([cocoaFont pointSize]);
QString family(qt_mac_NSStringToQString([cocoaFont familyName]));
QString typeface(qt_mac_NSStringToQString([cocoaFont fontName]));
int hyphenPos = typeface.indexOf(QLatin1Char('-'));
if (hyphenPos != -1) {
typeface.remove(0, hyphenPos + 1);
} else {
typeface = QLatin1String("Normal");
}
newFont = QFontDatabase().font(family, typeface, pSize);
newFont.setUnderline(resolveFont.underline());
newFont.setStrikeOut(resolveFont.strikeOut());
}
return newFont;
}
@implementation QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate)
- (id)initWithFontPanel:(NSFontPanel *)panel
stolenContentView:(NSView *)stolenContentView
okButton:(NSButton *)okButton
cancelButton:(NSButton *)cancelButton
priv:(QFontDialogPrivate *)priv
extraWidth:(CGFloat)extraWidth
extraHeight:(CGFloat)extraHeight
{
self = [super init];
mFontPanel = panel;
mStolenContentView = stolenContentView;
mOkButton = okButton;
mCancelButton = cancelButton;
mPriv = priv;
mPanelHackedWithButtons = (okButton != 0);
mDialogExtraWidth = extraWidth;
mDialogExtraHeight = extraHeight;
mReturnCode = -1;
mAppModal = false;
if (mPanelHackedWithButtons) {
[self relayout];
[okButton setAction:@selector(onOkClicked)];
[okButton setTarget:self];
[cancelButton setAction:@selector(onCancelClicked)];
[cancelButton setTarget:self];
}
mQtFont = new QFont();
return self;
}
- (void)setSubwindowStacking
{
// Stack the native dialog in front of its parent, if any:
QFontDialog *q = mPriv->fontDialog();
if (!qt_mac_is_macsheet(q)) {
if (QWidget *parent = q->parentWidget()) {
if (parent->isWindow()) {
[qt_mac_window_for(parent)
addChildWindow:[mStolenContentView window] ordered:NSWindowAbove];
}
}
}
}
- (void)dealloc
{
delete mQtFont;
[super dealloc];
}
- (void)showModelessPanel
{
mAppModal = false;
NSWindow *ourPanel = [mStolenContentView window];
[ourPanel makeKeyAndOrderFront:self];
}
- (void)runApplicationModalPanel
{
QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
mAppModal = true;
NSWindow *ourPanel = [mStolenContentView window];
[ourPanel setReleasedWhenClosed:NO];
[NSApp runModalForWindow:ourPanel];
QAbstractEventDispatcher::instance()->interrupt();
if (mReturnCode == NSOKButton)
mPriv->fontDialog()->accept();
else
mPriv->fontDialog()->reject();
}
- (BOOL)isAppModal
{
return mAppModal;
}
- (void)showWindowModalSheet:(QWidget *)docWidget
{
NSWindow *window = qt_mac_window_for(docWidget);
mAppModal = false;
NSWindow *ourPanel = [mStolenContentView window];
[NSApp beginSheet:ourPanel
modalForWindow:window
modalDelegate:0
didEndSelector:0
contextInfo:0 ];
}
- (void)changeFont:(id)sender
{
NSFont *dummyFont = [NSFont userFontOfSize:12.0];
[self setQtFont:qfontForCocoaFont([sender convertFont:dummyFont], *mQtFont)];
if (mPriv)
mPriv->updateSampleFont(*mQtFont);
}
- (void)changeAttributes:(id)sender
{
NSDictionary *dummyAttribs = [NSDictionary dictionary];
NSDictionary *attribs = [sender convertAttributes:dummyAttribs];
for (id key in attribs) {
NSNumber *number = static_cast<NSNumber *>([attribs objectForKey:key]);
if ([key isEqual:NSUnderlineStyleAttributeName]) {
mQtFont->setUnderline([number intValue] != NSUnderlineStyleNone);
} else if ([key isEqual:NSStrikethroughStyleAttributeName]) {
mQtFont->setStrikeOut([number intValue] != NSUnderlineStyleNone);
}
}
if (mPriv)
mPriv->updateSampleFont(*mQtFont);
}
- (BOOL)windowShouldClose:(id)window
{
Q_UNUSED(window);
if (mPanelHackedWithButtons) {
[self onCancelClicked];
} else {
[self finishOffWithCode:NSCancelButton];
}
return true;
}
- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize
{
if (mFontPanel == window) {
proposedFrameSize = [static_cast<id <NSWindowDelegate> >(mFontPanel) windowWillResize:mFontPanel toSize:proposedFrameSize];
} else {
/*
Ugly hack: NSFontPanel rearranges the layout of its main
component in windowWillResize:toSize:. So we temporarily
restore the stolen content view to its rightful owner,
call windowWillResize:toSize:, and steal the content view
again.
*/
[mStolenContentView removeFromSuperview];
[mFontPanel setContentView:mStolenContentView];
NSSize extraSize = [self dialogExtraSize];
proposedFrameSize.width -= extraSize.width;
proposedFrameSize.height -= extraSize.height;
proposedFrameSize = [static_cast<id <NSWindowDelegate> >(mFontPanel) windowWillResize:mFontPanel toSize:proposedFrameSize];
NSRect frameRect = { { 0.0, 0.0 }, proposedFrameSize };
[mFontPanel setFrame:frameRect display:NO];
[mFontPanel setContentView:0];
[[window contentView] addSubview:mStolenContentView];
proposedFrameSize.width += extraSize.width;
proposedFrameSize.height += extraSize.height;
}
if (mPanelHackedWithButtons) {
NSRect frameRect = { { 0.0, 0.0 }, proposedFrameSize };
NSRect contentRect = [NSWindow contentRectForFrameRect:frameRect styleMask:[window styleMask]];
[self relayoutToContentSize:contentRect.size];
}
return proposedFrameSize;
}
- (void)relayout
{
[self relayoutToContentSize:[[mStolenContentView superview] frame].size];
}
- (void)relayoutToContentSize:(NSSize)frameSize
{
Q_ASSERT(mPanelHackedWithButtons);
[mOkButton sizeToFit];
NSSize okSizeHint = [mOkButton frame].size;
[mCancelButton sizeToFit];
NSSize cancelSizeHint = [mCancelButton frame].size;
const CGFloat ButtonWidth = qMin(qMax(ButtonMinWidth,
qMax(okSizeHint.width, cancelSizeHint.width)),
CGFloat((frameSize.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5));
const CGFloat ButtonHeight = qMax(ButtonMinHeight,
qMax(okSizeHint.height, cancelSizeHint.height));
const CGFloat X = DialogSideMargin;
const CGFloat Y = ButtonBottomMargin + ButtonHeight + ButtonTopMargin;
NSRect okRect = { { frameSize.width - ButtonSideMargin - ButtonWidth,
ButtonBottomMargin },
{ ButtonWidth, ButtonHeight } };
[mOkButton setFrame:okRect];
[mOkButton setNeedsDisplay:YES];
NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - ButtonWidth,
ButtonBottomMargin },
{ ButtonWidth, ButtonHeight } };
[mCancelButton setFrame:cancelRect];
[mCancelButton setNeedsDisplay:YES];
NSRect stolenCVRect = { { X, Y },
{ frameSize.width - X - X, frameSize.height - Y - DialogTopMargin } };
[mStolenContentView setFrame:stolenCVRect];
[mStolenContentView setNeedsDisplay:YES];
[[mStolenContentView superview] setNeedsDisplay:YES];
}
- (void)onOkClicked
{
Q_ASSERT(mPanelHackedWithButtons);
NSFontManager *fontManager = [NSFontManager sharedFontManager];
[self setQtFont:qfontForCocoaFont([fontManager convertFont:[fontManager selectedFont]],
*mQtFont)];
[self finishOffWithCode:NSOKButton];
}
- (void)onCancelClicked
{
Q_ASSERT(mPanelHackedWithButtons);
[self finishOffWithCode:NSCancelButton];
}
- (NSFontPanel *)fontPanel
{
return mFontPanel;
}
- (NSWindow *)actualPanel
{
return [mStolenContentView window];
}
- (NSSize)dialogExtraSize
{
// this must be recomputed each time, because sometimes the
// NSFontPanel has the NSDocModalWindowMask flag set, and sometimes
// not -- which affects the frame rect vs. content rect measurements
// take the different frame rectangles into account for dialogExtra{Width,Height}
NSRect someRect = { { 0.0, 0.0 }, { 100000.0, 100000.0 } };
NSRect sharedFontPanelContentRect = [mFontPanel contentRectForFrameRect:someRect];
NSRect ourPanelContentRect = [NSWindow contentRectForFrameRect:someRect styleMask:StyleMask];
NSSize result = { mDialogExtraWidth, mDialogExtraHeight };
result.width -= ourPanelContentRect.size.width - sharedFontPanelContentRect.size.width;
result.height -= ourPanelContentRect.size.height - sharedFontPanelContentRect.size.height;
return result;
}
- (void)setQtFont:(const QFont &)newFont
{
delete mQtFont;
mQtFont = new QFont(newFont);
}
- (QFont)qtFont
{
return *mQtFont;
}
- (void)finishOffWithCode:(NSInteger)code
{
QFontDialog *q = mPriv->fontDialog();
if (QWidget *parent = q->parentWidget()) {
if (parent->isWindow()) {
[qt_mac_window_for(parent) removeChildWindow:[mStolenContentView window]];
}
}
if(code == NSOKButton)
mPriv->sampleEdit->setFont([self qtFont]);
if (mAppModal) {
mReturnCode = code;
[NSApp stopModalWithCode:code];
} else {
if (code == NSOKButton)
mPriv->fontDialog()->accept();
else
mPriv->fontDialog()->reject();
}
}
- (void)cleanUpAfterMyself
{
if (mPanelHackedWithButtons) {
NSView *ourContentView = [mFontPanel contentView];
// return stolen stuff to its rightful owner
[mStolenContentView removeFromSuperview];
[mFontPanel setContentView:mStolenContentView];
[mOkButton release];
[mCancelButton release];
[ourContentView release];
}
[mFontPanel setDelegate:nil];
[[NSFontManager sharedFontManager] setDelegate:nil];
[[NSFontManager sharedFontManager] setTarget:nil];
}
@end
QT_BEGIN_NAMESPACE
void QFontDialogPrivate::closeCocoaFontPanel()
{
QMacCocoaAutoReleasePool pool;
QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *theDelegate = static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate);
NSWindow *ourPanel = [theDelegate actualPanel];
[ourPanel close];
if ([theDelegate isAppModal])
[ourPanel release];
[theDelegate cleanUpAfterMyself];
[theDelegate release];
this->delegate = 0;
sharedFontPanelAvailable = true;
}
void QFontDialogPrivate::setFont(void *delegate, const QFont &font)
{
QMacCocoaAutoReleasePool pool;
QFontEngine *fe = font.d->engineForScript(QUnicodeTables::Common);
NSFontManager *mgr = [NSFontManager sharedFontManager];
const NSFont *nsFont = 0;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
if (qstrcmp(fe->name(), "CoreText") == 0) {
nsFont = reinterpret_cast<const NSFont *>(static_cast<QCoreTextFontEngineMulti *>(fe)->ctfont);
} else
#endif
{
int weight = 5;
NSFontTraitMask mask = 0;
if (font.style() == QFont::StyleItalic) {
mask |= NSItalicFontMask;
}
if (font.weight() == QFont::Bold) {
weight = 9;
mask |= NSBoldFontMask;
}
NSFontManager *mgr = [NSFontManager sharedFontManager];
QFontInfo fontInfo(font);
nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(fontInfo.family())
traits:mask
weight:weight
size:fontInfo.pointSize()];
}
[mgr setSelectedFont:const_cast<NSFont *>(nsFont) isMultiple:NO];
[static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate) setQtFont:font];
}
void QFontDialogPrivate::createNSFontPanelDelegate()
{
if (delegate)
return;
sharedFontPanelAvailable = false;
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 the delegate and set it
QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = [[QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) alloc] initWithFontPanel:sharedFontPanel
stolenContentView:stolenContentView
okButton:okButton
cancelButton:cancelButton
priv:this
extraWidth:dialogExtraWidth
extraHeight:dialogExtraHeight];
delegate = del;
[ourPanel setDelegate:del];
[[NSFontManager sharedFontManager] setDelegate:del];
[[NSFontManager sharedFontManager] setTarget:del];
setFont(del, q_func()->currentFont());
{
// 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 = [del windowWillResize:ourPanel toSize:frameRect.size];
[ourPanel setFrame:frameRect display:NO];
[ourPanel center];
}
[del setSubwindowStacking];
NSString *title = @"Select font";
[ourPanel setTitle:title];
}
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()
{
createNSFontPanelDelegate();
QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate);
[del runApplicationModalPanel];
}
bool QFontDialogPrivate::showCocoaFontPanel()
{
if (!sharedFontPanelAvailable)
return false;
Q_Q(QFontDialog);
QMacCocoaAutoReleasePool pool;
createNSFontPanelDelegate();
QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate);
if (qt_mac_is_macsheet(q))
[del showWindowModalSheet:q->parentWidget()];
else
[del showModelessPanel];
return true;
}
bool QFontDialogPrivate::hideCocoaFontPanel()
{
if (!delegate){
// Nothing to do. We return false to leave the question
// open regarding whether or not to go native:
return false;
} else {
closeCocoaFontPanel();
// Even when we hide it, we are still using a
// native dialog, so return true:
return true;
}
}
bool QFontDialogPrivate::setVisible_sys(bool visible)
{
Q_Q(QFontDialog);
if (!visible == q->isHidden())
return false;
return visible ? showCocoaFontPanel() : hideCocoaFontPanel();
}
QT_END_NAMESPACE
#endif

View File

@ -1,228 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qdialogbuttonbox.h>
#if defined(Q_WS_MAC)
#include <private/qt_mac_p.h>
#include <private/qcocoaintrospection_p.h>
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <objc/objc-class.h>
QT_BEGIN_NAMESPACE
static QWidget *currentWindow = 0;
QT_END_NAMESPACE
QT_USE_NAMESPACE
@class QT_MANGLE_NAMESPACE(QNSPanelProxy);
@interface QT_MANGLE_NAMESPACE(QNSPanelProxy) : NSWindow {
}
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation;
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation screen:(NSScreen *)screen;
- (id)qt_fakeInitWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation;
- (id)qt_fakeInitWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation screen:(NSScreen *)screen;
@end
@implementation QT_MANGLE_NAMESPACE(QNSPanelProxy)
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
{
// remove evil flag
windowStyle &= ~NSUtilityWindowMask;
self = [self qt_fakeInitWithContentRect:contentRect styleMask:windowStyle
backing:bufferingType defer:deferCreation];
return self;
}
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation screen:(NSScreen *)screen
{
// remove evil flag
windowStyle &= ~NSUtilityWindowMask;
return [self qt_fakeInitWithContentRect:contentRect styleMask:windowStyle
backing:bufferingType defer:deferCreation screen:screen];
}
- (id)qt_fakeInitWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
{
Q_UNUSED(contentRect);
Q_UNUSED(windowStyle);
Q_UNUSED(bufferingType);
Q_UNUSED(deferCreation);
return nil;
}
- (id)qt_fakeInitWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation screen:(NSScreen *)screen
{
Q_UNUSED(contentRect);
Q_UNUSED(windowStyle);
Q_UNUSED(bufferingType);
Q_UNUSED(deferCreation);
Q_UNUSED(screen);
return nil;
}
@end
@class QT_MANGLE_NAMESPACE(QNSWindowProxy);
@interface QT_MANGLE_NAMESPACE(QNSWindowProxy) : NSWindow {
}
- (void)setTitle:(NSString *)title;
- (void)qt_fakeSetTitle:(NSString *)title;
@end
@implementation QT_MANGLE_NAMESPACE(QNSWindowProxy)
- (void)setTitle:(NSString *)title
{
QCFString cftitle(currentWindow->windowTitle());
// evil reverse engineering
if ([title isEqualToString:@"Print"]
|| [title isEqualToString:@"Page Setup"]
|| [[self className] isEqualToString:@"PMPrintingWindow"])
title = (NSString *)(static_cast<CFStringRef>(cftitle));
return [self qt_fakeSetTitle:title];
}
- (void)qt_fakeSetTitle:(NSString *)title
{
Q_UNUSED(title);
}
@end
QT_BEGIN_NAMESPACE
/*
Intercept the NSColorPanel constructor if the shared
color panel doesn't exist yet. What's going on here is
quite wacky, because we want to override the NSPanel
constructor and at the same time call the old NSPanel
constructor. So what we do is we effectively rename the
old NSPanel constructor qt_fakeInitWithContentRect:...
and have the new one call the old one.
*/
void macStartInterceptNSPanelCtor()
{
qt_cocoa_change_implementation(
[NSPanel class],
@selector(initWithContentRect:styleMask:backing:defer:),
[QT_MANGLE_NAMESPACE(QNSPanelProxy) class],
@selector(initWithContentRect:styleMask:backing:defer:),
@selector(qt_fakeInitWithContentRect:styleMask:backing:defer:));
qt_cocoa_change_implementation(
[NSPanel class],
@selector(initWithContentRect:styleMask:backing:defer:screen:),
[QT_MANGLE_NAMESPACE(QNSPanelProxy) class],
@selector(initWithContentRect:styleMask:backing:defer:screen:),
@selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:));
}
/*
Restore things as they were.
*/
void macStopInterceptNSPanelCtor()
{
qt_cocoa_change_back_implementation(
[NSPanel class],
@selector(initWithContentRect:styleMask:backing:defer:screen:),
@selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:));
qt_cocoa_change_back_implementation(
[NSPanel class],
@selector(initWithContentRect:styleMask:backing:defer:),
@selector(qt_fakeInitWithContentRect:styleMask:backing:defer:));
}
/*
Intercept the NSPrintPanel and NSPageLayout setTitle: calls. The
hack is similar as for NSColorPanel above.
*/
void macStartInterceptWindowTitle(QWidget *window)
{
currentWindow = window;
qt_cocoa_change_implementation(
[NSWindow class],
@selector(setTitle:),
[QT_MANGLE_NAMESPACE(QNSWindowProxy) class],
@selector(setTitle:),
@selector(qt_fakeSetTitle:));
}
/*
Restore things as they were.
*/
void macStopInterceptWindowTitle()
{
currentWindow = 0;
qt_cocoa_change_back_implementation(
[NSWindow class],
@selector(setTitle:),
@selector(qt_fakeSetTitle:));
}
/*
Doesn't really belong in here.
*/
NSButton *macCreateButton(const char *text, NSView *superview)
{
static const NSRect buttonFrameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } };
NSButton *button = [[NSButton alloc] initWithFrame:buttonFrameRect];
[button setButtonType:NSMomentaryLightButton];
[button setBezelStyle:NSRoundedBezelStyle];
[button setTitle:(NSString*)(CFStringRef)QCFString(QDialogButtonBox::tr(text)
.remove(QLatin1Char('&')))];
[[button cell] setFont:[NSFont systemFontOfSize:
[NSFont systemFontSizeForControlSize:NSRegularControlSize]]];
[superview addSubview:button];
return button;
}
QT_END_NAMESPACE
#endif