Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/hyperstake/HyperStake
Browse files Browse the repository at this point in the history
  • Loading branch information
presstab committed Feb 13, 2015
2 parents e998e8e + 6aa991b commit c4b5456
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 56 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -128,3 +128,5 @@ src/qt/test/.deps
src/qt/forms/ui_blockbrowser.h
src/qt/forms/ui_calcdialog.h
src/qt/forms/ui_charitydialog.h
moc_macnotificationhandler.cpp
hyperstake/hyperstake.xcodeproj
5 changes: 4 additions & 1 deletion src/Makefile.qt.include
Expand Up @@ -43,6 +43,7 @@ QT_MOC_CPP = \
qt/moc_editaddressdialog.cpp \
qt/moc_guiutil.cpp \
qt/moc_macdockiconhandler.cpp \
qt/moc_macnotificationhandler.cpp \
qt/moc_monitoreddatamapper.cpp \
qt/moc_notificator.cpp \
qt/moc_optionsdialog.cpp \
Expand All @@ -64,7 +65,8 @@ QT_MOC_CPP = \
qt/moc_walletmodel.cpp

BITCOIN_MM = \
qt/macdockiconhandler.mm
qt/macdockiconhandler.mm \
qt/macnotificationhandler.mm

QT_MOC = \
qt/bitcoin.moc \
Expand Down Expand Up @@ -95,6 +97,7 @@ BITCOIN_QT_H = \
qt/guiconstants.h \
qt/guiutil.h \
qt/macdockiconhandler.h \
qt/macnotificationhandler.h \
qt/monitoreddatamapper.h \
qt/notificator.h \
qt/optionsdialog.h \
Expand Down
2 changes: 1 addition & 1 deletion src/qt/bitcoingui.cpp
Expand Up @@ -570,7 +570,7 @@ void BitcoinGUI::createTrayIcon()
trayIconMenu->addAction(quitAction);
#endif

notificator = new Notificator(qApp->applicationName(), trayIcon);
notificator = new Notificator(qApp->applicationName(), trayIcon, this);
}

#ifndef Q_OS_MAC
Expand Down
13 changes: 8 additions & 5 deletions src/qt/macdockiconhandler.h
@@ -1,11 +1,14 @@
#ifndef MACDOCKICONHANDLER_H
#define MACDOCKICONHANDLER_H

#include <QtCore/QObject>
#include <QMainWindow>
#include <QObject>

class QMenu;
QT_BEGIN_NAMESPACE
class QIcon;
class QMenu;
class QWidget;
QT_END_NAMESPACE

#ifdef __OBJC__
@class DockIconClickEventHandler;
Expand All @@ -18,27 +21,27 @@ class DockIconClickEventHandler;
class MacDockIconHandler : public QObject
{
Q_OBJECT

public:
~MacDockIconHandler();

QMenu *dockMenu();
void setIcon(const QIcon &icon);

void setMainWindow(QMainWindow *window);
static MacDockIconHandler *instance();

void handleDockIconClickEvent();

signals:
void dockIconClicked();

public slots:

private:
MacDockIconHandler();

DockIconClickEventHandler *m_dockIconClickEventHandler;
QWidget *m_dummyWidget;
QMenu *m_dockMenu;
QMainWindow *mainWindow;
};

#endif // MACDOCKICONCLICKHANDLER_H
50 changes: 41 additions & 9 deletions src/qt/macdockiconhandler.mm
@@ -1,14 +1,17 @@

#include "macdockiconhandler.h"

#include <QImageWriter>
#include <QMenu>
#include <QBuffer>
#include <QWidget>

extern void qt_mac_set_dock_menu(QMenu*);

#undef slots
#include <Cocoa/Cocoa.h>

#if QT_VERSION < 0x050000
extern void qt_mac_set_dock_menu(QMenu *);
#endif

@interface DockIconClickEventHandler : NSObject
{
MacDockIconHandler* dockIconHandler;
Expand Down Expand Up @@ -38,27 +41,36 @@ - (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAp
Q_UNUSED(event)
Q_UNUSED(replyEvent)

if (dockIconHandler)
if (dockIconHandler) {
dockIconHandler->handleDockIconClickEvent();
}
}

@end

MacDockIconHandler::MacDockIconHandler() : QObject()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
this->m_dockIconClickEventHandler = [[DockIconClickEventHandler alloc] initWithDockIconHandler:this];

this->m_dockIconClickEventHandler = [[DockIconClickEventHandler alloc] initWithDockIconHandler:this];
this->m_dummyWidget = new QWidget();
this->m_dockMenu = new QMenu(this->m_dummyWidget);
this->setMainWindow(NULL);
#if QT_VERSION < 0x050000
qt_mac_set_dock_menu(this->m_dockMenu);
#endif
[pool release];
}

void MacDockIconHandler::setMainWindow(QMainWindow *window) {
this->mainWindow = window;
}

MacDockIconHandler::~MacDockIconHandler()
{
[this->m_dockIconClickEventHandler release];
delete this->m_dummyWidget;
this->setMainWindow(NULL);
}

QMenu *MacDockIconHandler::dockMenu()
Expand All @@ -69,15 +81,29 @@ - (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAp
void MacDockIconHandler::setIcon(const QIcon &icon)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSImage *image;
NSImage *image = nil;
if (icon.isNull())
image = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
else {
// generate NSImage from QIcon and use this as dock icon.
QSize size = icon.actualSize(QSize(128, 128));
QPixmap pixmap = icon.pixmap(size);
CGImageRef cgImage = pixmap.toMacCGImageRef();
image = [[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize];
CFRelease(cgImage);

// Write image into a R/W buffer from raw pixmap, then save the image.
QBuffer notificationBuffer;
if (!pixmap.isNull() && notificationBuffer.open(QIODevice::ReadWrite)) {
QImageWriter writer(&notificationBuffer, "PNG");
if (writer.write(pixmap.toImage())) {
NSData* macImgData = [NSData dataWithBytes:notificationBuffer.buffer().data()
length:notificationBuffer.buffer().size()];
image = [[NSImage alloc] initWithData:macImgData];
}
}

if(!image) {
// if testnet image could not be created, load std. app icon
image = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
}
}

[NSApp setApplicationIconImage:image];
Expand All @@ -95,5 +121,11 @@ - (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAp

void MacDockIconHandler::handleDockIconClickEvent()
{
if (this->mainWindow)
{
this->mainWindow->activateWindow();
this->mainWindow->show();
}

emit this->dockIconClicked();
}
30 changes: 30 additions & 0 deletions src/qt/macnotificationhandler.h
@@ -0,0 +1,30 @@
// Copyright (c) 2011-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_QT_MACNOTIFICATIONHANDLER_H
#define BITCOIN_QT_MACNOTIFICATIONHANDLER_H

#include <QObject>

/** Macintosh-specific notification handler (supports UserNotificationCenter and Growl).
*/
class MacNotificationHandler : public QObject
{
Q_OBJECT

public:
/** shows a 10.8+ UserNotification in the UserNotificationCenter
*/
void showNotification(const QString &title, const QString &text);

/** executes AppleScript */
void sendAppleScript(const QString &script);

/** check if OS can handle UserNotifications */
bool hasUserNotificationCenterSupport(void);
static MacNotificationHandler *instance();
};


#endif // BITCOIN_QT_MACNOTIFICATIONHANDLER_H
91 changes: 91 additions & 0 deletions src/qt/macnotificationhandler.mm
@@ -0,0 +1,91 @@
// Copyright (c) 2011-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "macnotificationhandler.h"

#undef slots
#import <objc/runtime.h>
#include <Cocoa/Cocoa.h>

// Add an obj-c category (extension) to return the expected bundle identifier
@implementation NSBundle(returnCorrectIdentifier)
- (NSString *)__bundleIdentifier
{
if (self == [NSBundle mainBundle]) {
return @"org.hyperstake.HyperStake-Qt";
} else {
return [self __bundleIdentifier];
}
}
@end

void MacNotificationHandler::showNotification(const QString &title, const QString &text)
{
// check if users OS has support for NSUserNotification
if(this->hasUserNotificationCenterSupport()) {
// okay, seems like 10.8+
QByteArray utf8 = title.toUtf8();
char* cString = (char *)utf8.constData();
NSString *titleMac = [[NSString alloc] initWithUTF8String:cString];

utf8 = text.toUtf8();
cString = (char *)utf8.constData();
NSString *textMac = [[NSString alloc] initWithUTF8String:cString];

// do everything weak linked (because we will keep <10.8 compatibility)
id userNotification = [[NSClassFromString(@"NSUserNotification") alloc] init];
[userNotification performSelector:@selector(setTitle:) withObject:titleMac];
[userNotification performSelector:@selector(setInformativeText:) withObject:textMac];

id notificationCenterInstance = [NSClassFromString(@"NSUserNotificationCenter") performSelector:@selector(defaultUserNotificationCenter)];
[notificationCenterInstance performSelector:@selector(deliverNotification:) withObject:userNotification];

[titleMac release];
[textMac release];
[userNotification release];
}
}

// sendAppleScript just take a QString and executes it as apple script
void MacNotificationHandler::sendAppleScript(const QString &script)
{
QByteArray utf8 = script.toUtf8();
char* cString = (char *)utf8.constData();
NSString *scriptApple = [[NSString alloc] initWithUTF8String:cString];

NSAppleScript *as = [[NSAppleScript alloc] initWithSource:scriptApple];
NSDictionary *err = nil;
[as executeAndReturnError:&err];
[as release];
[scriptApple release];
}

bool MacNotificationHandler::hasUserNotificationCenterSupport(void)
{
Class possibleClass = NSClassFromString(@"NSUserNotificationCenter");

// check if users OS has support for NSUserNotification
if(possibleClass!=nil) {
return true;
}
return false;
}


MacNotificationHandler *MacNotificationHandler::instance()
{
static MacNotificationHandler *s_instance = NULL;
if (!s_instance) {
s_instance = new MacNotificationHandler();

Class aPossibleClass = objc_getClass("NSBundle");
if (aPossibleClass) {
// change NSBundle -bundleIdentifier method to return a correct bundle identifier
// a bundle identifier is required to use OSXs User Notification Center
method_exchangeImplementations(class_getInstanceMethod(aPossibleClass, @selector(bundleIdentifier)),
class_getInstanceMethod(aPossibleClass, @selector(__bundleIdentifier)));
}
}
return s_instance;
}

0 comments on commit c4b5456

Please sign in to comment.