summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r--src/plugins/platforms/cocoa/qcocoacolordialoghelper.h9
-rw-r--r--src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm263
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm34
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm3
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm6
9 files changed, 181 insertions, 145 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h
index e30f1d7425..59e029769d 100644
--- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h
+++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h
@@ -59,15 +59,6 @@ public:
void setCurrentColor(const QColor&);
QColor currentColor() const;
-
-public:
- bool showCocoaColorPanel(Qt::WindowModality windowModality, QWindow *parent);
- bool hideCocoaColorPanel();
-
- void createNSColorPanelDelegate();
-
-private:
- void *mDelegate;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
index 13b4203f7f..d90d77ec1d 100644
--- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
@@ -91,11 +91,14 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
@implementation QNSColorPanelDelegate
-- (id)initWithDialogHelper:(QCocoaColorDialogHelper *)helper
+- (id)init
{
self = [super init];
mColorPanel = [NSColorPanel sharedColorPanel];
- mHelper = helper;
+ mHelper = 0;
+ mStolenContentView = 0;
+ mOkButton = 0;
+ mCancelButton = 0;
mResultCode = NSCancelButton;
mDialogIsExecuting = false;
mResultSet = false;
@@ -105,11 +108,31 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
[mColorPanel setRestorable:NO];
#endif
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(colorChanged:)
+ name:NSColorPanelColorDidChangeNotification
+ object:mColorPanel];
+
+ [mColorPanel retain];
+ return self;
+}
+
+- (void)dealloc
+{
+ [self restoreOriginalContentView];
+ [mColorPanel setDelegate:nil];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ [super dealloc];
+}
+
+- (void)setDialogHelper:(QCocoaColorDialogHelper *)helper
+{
+ mHelper = helper;
+ [mColorPanel setShowsAlpha:mHelper->options()->testOption(QColorDialogOptions::ShowAlphaChannel)];
if (mHelper->options()->testOption(QColorDialogOptions::NoButtons)) {
- mStolenContentView = 0;
- mOkButton = 0;
- mCancelButton = 0;
- } else {
+ [self restoreOriginalContentView];
+ } else if (!mStolenContentView) {
// steal the color panel's contents view
mStolenContentView = [mColorPanel contentView];
[mStolenContentView retain];
@@ -134,33 +157,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
[mCancelButton setAction:@selector(onCancelClicked)];
[mCancelButton setTarget:self];
}
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(colorChanged:)
- name:NSColorPanelColorDidChangeNotification
- object:mColorPanel];
-
- [mColorPanel retain];
- return self;
-}
-
-- (void)dealloc
-{
- if (mOkButton) {
- 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];
-
- [super dealloc];
}
- (void)closePanel
@@ -178,7 +174,25 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
{
Q_UNUSED(notification);
[self updateQtColor];
- emit mHelper->colorSelected(mQtColor);
+ if (mHelper)
+ emit mHelper->colorSelected(mQtColor);
+}
+
+- (void)restoreOriginalContentView
+{
+ if (mStolenContentView) {
+ NSView *ourContentView = [mColorPanel contentView];
+
+ // return stolen stuff to its rightful owner
+ [mStolenContentView removeFromSuperview];
+ [mColorPanel setContentView:mStolenContentView];
+ [mOkButton release];
+ [mCancelButton release];
+ [ourContentView release];
+ mOkButton = 0;
+ mCancelButton = 0;
+ mStolenContentView = 0;
+ }
}
- (void)relayout
@@ -275,7 +289,8 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
mQtColor.setRgbF(red, green, blue, alpha);
}
}
- emit mHelper->currentColorChanged(mQtColor);
+ if (mHelper)
+ emit mHelper->currentColorChanged(mQtColor);
}
- (void)showModelessPanel
@@ -313,7 +328,8 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
[self finishOffWithCode:NSCancelButton];
} else {
mResultSet = true;
- emit mHelper->reject();
+ if (mHelper)
+ emit mHelper->reject();
}
return true;
}
@@ -348,27 +364,101 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
QT_BEGIN_NAMESPACE
-QCocoaColorDialogHelper::QCocoaColorDialogHelper() :
- mDelegate(0)
+class QCocoaColorPanel
+{
+public:
+ QCocoaColorPanel()
+ {
+ mDelegate = [[QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) alloc] init];
+ }
+
+ ~QCocoaColorPanel()
+ {
+ [mDelegate release];
+ }
+
+ void init(QCocoaColorDialogHelper *helper)
+ {
+ [mDelegate setDialogHelper:helper];
+ }
+
+ void cleanup(QCocoaColorDialogHelper *helper)
+ {
+ if (mDelegate->mHelper == helper)
+ mDelegate->mHelper = 0;
+ }
+
+ bool exec()
+ {
+ // Note: 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.
+ return [mDelegate runApplicationModalPanel];
+ }
+
+ bool show(Qt::WindowModality windowModality, QWindow *parent)
+ {
+ Q_UNUSED(parent);
+ if (windowModality != Qt::WindowModal)
+ [mDelegate showModelessPanel];
+ // no need to show a Qt::WindowModal dialog here, because it's necessary to call exec() in that case
+ return true;
+ }
+
+ void hide()
+ {
+ [mDelegate closePanel];
+ }
+
+ QColor currentColor() const
+ {
+ return mDelegate->mQtColor;
+ }
+
+ void setCurrentColor(const QColor &color)
+ {
+ // make sure that if ShowAlphaChannel option is set then also setShowsAlpha
+ // needs to be set, otherwise alpha value is omitted
+ if (color.alpha() < 255)
+ [mDelegate->mColorPanel setShowsAlpha:YES];
+
+ 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()];
+ }
+ mDelegate->mQtColor = color;
+ [mDelegate->mColorPanel setColor:nsColor];
+ }
+
+private:
+ QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *mDelegate;
+};
+
+Q_GLOBAL_STATIC(QCocoaColorPanel, sharedColorPanel)
+
+QCocoaColorDialogHelper::QCocoaColorDialogHelper()
{
}
QCocoaColorDialogHelper::~QCocoaColorDialogHelper()
{
- if (!mDelegate)
- return;
- [reinterpret_cast<QNSColorPanelDelegate *>(mDelegate) release];
- mDelegate = 0;
+ sharedColorPanel()->cleanup(this);
}
void QCocoaColorDialogHelper::exec()
{
- // Note: 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.
- QNSColorPanelDelegate *delegate = static_cast<QNSColorPanelDelegate *>(mDelegate);
- if ([delegate runApplicationModalPanel])
+ if (sharedColorPanel()->exec())
emit accept();
else
emit reject();
@@ -378,89 +468,24 @@ bool QCocoaColorDialogHelper::show(Qt::WindowFlags, Qt::WindowModality windowMod
{
if (windowModality == Qt::WindowModal)
windowModality = Qt::ApplicationModal;
- return showCocoaColorPanel(windowModality, parent);
+ sharedColorPanel()->init(this);
+ return sharedColorPanel()->show(windowModality, parent);
}
void QCocoaColorDialogHelper::hide()
{
- if (!mDelegate)
- return;
- QNSColorPanelDelegate *delegate = static_cast<QNSColorPanelDelegate *>(mDelegate);
- if (![delegate->mColorPanel isVisible])
- return;
- if (delegate->mDialogIsExecuting)
- [delegate->mColorPanel performClose:delegate];
- else
- [delegate->mColorPanel close];
+ sharedColorPanel()->hide();
}
void QCocoaColorDialogHelper::setCurrentColor(const QColor &color)
{
- if (!mDelegate)
- createNSColorPanelDelegate();
- QNSColorPanelDelegate *delegate = static_cast<QNSColorPanelDelegate *>(mDelegate);
-
- // make sure that if ShowAlphaChannel option is set then also setShowsAlpha
- // needs to be set, otherwise alpha value is omitted
- [delegate->mColorPanel setShowsAlpha:options()->testOption(QColorDialogOptions::ShowAlphaChannel)];
-
- 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()];
- }
- delegate->mQtColor = color;
- [delegate->mColorPanel setColor:nsColor];
+ sharedColorPanel()->init(this);
+ sharedColorPanel()->setCurrentColor(color);
}
QColor QCocoaColorDialogHelper::currentColor() const
{
- if (!mDelegate)
- return QColor();
- return reinterpret_cast<QNSColorPanelDelegate *>(mDelegate)->mQtColor;
-}
-
-void QCocoaColorDialogHelper::createNSColorPanelDelegate()
-{
- if (mDelegate)
- return;
-
- QNSColorPanelDelegate *delegate = [[QNSColorPanelDelegate alloc]
- initWithDialogHelper:this];
-
- mDelegate = delegate;
-}
-
-bool QCocoaColorDialogHelper::showCocoaColorPanel(Qt::WindowModality windowModality, QWindow *parent)
-{
- Q_UNUSED(parent);
- createNSColorPanelDelegate();
- QNSColorPanelDelegate *delegate = static_cast<QNSColorPanelDelegate *>(mDelegate);
- [delegate->mColorPanel setShowsAlpha:options()->testOption(QColorDialogOptions::ShowAlphaChannel)];
- if (windowModality != Qt::WindowModal)
- [delegate showModelessPanel];
- // no need to show a Qt::WindowModal dialog here, because it's necessary to call exec() in that case
- return true;
-}
-
-bool QCocoaColorDialogHelper::hideCocoaColorPanel()
-{
- if (!mDelegate){
- return false;
- } else {
- QNSColorPanelDelegate *delegate = static_cast<QNSColorPanelDelegate *>(mDelegate);
- [delegate closePanel];
- return true;
- }
+ return sharedColorPanel()->currentColor();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index c801d9d926..3e402673f3 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -71,6 +71,7 @@ inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qst
CGImageRef qt_mac_image_to_cgimage(const QImage &image);
NSImage *qt_mac_cgimage_to_nsimage(CGImageRef iamge);
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
+NSImage *qt_mac_create_nsimage(const QIcon &icon);
NSSize qt_mac_toNSSize(const QSize &qtSize);
NSRect qt_mac_toNSRect(const QRect &rect);
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 8ab1d9b579..3be294de7e 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -84,11 +84,8 @@ static void drawImageReleaseData (void *info, const void *, size_t)
CGImageRef qt_mac_image_to_cgimage(const QImage &img)
{
- if (img.width() <= 0 || img.height() <= 0) {
- qWarning() << Q_FUNC_INFO <<
- "trying to set" << img.width() << "x" << img.height() << "size for CGImage";
+ if (img.isNull())
return 0;
- }
QImage *image;
if (img.depth() != 32)
@@ -124,16 +121,7 @@ CGImageRef qt_mac_image_to_cgimage(const QImage &img)
NSImage *qt_mac_cgimage_to_nsimage(CGImageRef image)
{
- QCocoaAutoReleasePool pool;
- NSImage *newImage = 0;
- NSRect imageRect = NSMakeRect(0.0, 0.0, CGImageGetWidth(image), CGImageGetHeight(image));
- newImage = [[NSImage alloc] initWithSize:imageRect.size];
- [newImage lockFocus];
- {
- CGContextRef imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
- CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image);
- }
- [newImage unlockFocus];
+ NSImage *newImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize];
return newImage;
}
@@ -148,6 +136,24 @@ NSImage *qt_mac_create_nsimage(const QPixmap &pm)
return nsImage;
}
+NSImage *qt_mac_create_nsimage(const QIcon &icon)
+{
+ if (icon.isNull())
+ return nil;
+
+ NSImage *nsImage = [[NSImage alloc] init];
+ foreach (QSize size, icon.availableSizes()) {
+ QPixmap pm = icon.pixmap(size);
+ QImage image = pm.toImage();
+ CGImageRef cgImage = qt_mac_image_to_cgimage(image);
+ NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
+ [nsImage addRepresentation:imageRep];
+ [imageRep release];
+ CGImageRelease(cgImage);
+ }
+ return nsImage;
+}
+
HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion &region)
{
HIMutableShapeRef shape = HIShapeCreateMutable();
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index f6378d126f..8c4325a775 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -49,6 +49,7 @@
#include <QtGui/private/qguiapplication_p.h>
#include "qcocoaapplication.h"
#include "qcocoamenuloader.h"
+#include "qcocoamenubar.h"
#include "qcocoawindow.h"
#import "qnsview.h"
@@ -540,6 +541,7 @@ void QCocoaMenu::syncModalState(bool modal)
void QCocoaMenu::setMenuBar(QCocoaMenuBar *menuBar)
{
m_menuBar = menuBar;
+ setParent(menuBar);
}
QCocoaMenuBar *QCocoaMenu::menuBar() const
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index 52bfdfa385..da2704f19c 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -203,6 +203,11 @@ void QCocoaMenuBar::updateMenuBarImmediately()
QCocoaAutoReleasePool pool;
QCocoaMenuBar *mb = findGlobalMenubar();
QCocoaWindow *cw = findWindowForMenubar();
+
+ QWindow *win = cw ? cw->window() : 0;
+ if (win && (win->flags() & Qt::Popup) == Qt::Popup)
+ return; // context menus, comboboxes, etc. don't need to update the menubar
+
if (cw && cw->menubar())
mb = cw->menubar();
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 4fb79f6c93..013f9931ff 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -310,7 +310,8 @@ NSMenuItem *QCocoaMenuItem::sync()
}
if (!m_icon.isNull()) {
- NSImage *img = static_cast<NSImage *>(qt_mac_create_nsimage(m_icon.pixmap(16, QIcon::Normal)));
+ NSImage *img = qt_mac_create_nsimage(m_icon);
+ [img setSize:NSMakeSize(16, 16)];
[m_native setImage: img];
[img release];
}
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index 5a5b2bc51f..1484ae2ba3 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -260,8 +260,9 @@ QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &siz
return QPixmap();
NSRect iconRect = NSMakeRect(0, 0, size.width(), size.height());
+ NSGraphicsContext *gc = [NSGraphicsContext currentContext];
CGImageRef cgImage = [iconImage CGImageForProposedRect:&iconRect
- context:[NSGraphicsContext currentContext]
+ context:([gc graphicsPort] ? gc : nil)
hints:nil];
QPixmap pixmap = QPixmap::fromImage(qt_mac_toQImage(cgImage));
return pixmap;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 70b08c7feb..288d4b4742 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -916,6 +916,7 @@ static QTouchDevice *touchDevice = 0;
ulong timestamp = [nsevent timestamp] * 1000;
ulong nativeModifiers = [nsevent modifierFlags];
Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers: nativeModifiers];
+ NSString *charactersIgnoringModifiers = [nsevent charactersIgnoringModifiers];
NSString *characters = [nsevent characters];
// There is no way to get the scan code from carbon/cocoa. But we cannot
@@ -927,7 +928,10 @@ static QTouchDevice *touchDevice = 0;
QChar ch = QChar::ReplacementCharacter;
int keyCode = Qt::Key_unknown;
if ([characters length] != 0) {
- ch = QChar([characters characterAtIndex:0]);
+ if ((modifiers & Qt::MetaModifier) && ([charactersIgnoringModifiers length] != 0))
+ ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
+ else
+ ch = QChar([characters characterAtIndex:0]);
keyCode = [self convertKeyCode:ch];
}