[test] Replace check_output with low level version
[bitcoinplatinum.git] / src / qt / macdockiconhandler.mm
blob9e7de0f98fbdf7f8c4fd4ee70b50e14baa494c14
1 // Copyright (c) 2011-2013 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include "macdockiconhandler.h"
7 #include <QImageWriter>
8 #include <QMenu>
9 #include <QBuffer>
10 #include <QWidget>
12 #undef slots
13 #include <Cocoa/Cocoa.h>
14 #include <objc/objc.h>
15 #include <objc/message.h>
17 #if QT_VERSION < 0x050000
18 extern void qt_mac_set_dock_menu(QMenu *);
19 #endif
21 static MacDockIconHandler *s_instance = nullptr;
23 bool dockClickHandler(id self,SEL _cmd,...) {
24     Q_UNUSED(self)
25     Q_UNUSED(_cmd)
26     
27     s_instance->handleDockIconClickEvent();
28     
29     // Return NO (false) to suppress the default OS X actions
30     return false;
33 void setupDockClickHandler() {
34     Class cls = objc_getClass("NSApplication");
35     id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication"));
36     
37     if (appInst != nullptr) {
38         id delegate = objc_msgSend(appInst, sel_registerName("delegate"));
39         Class delClass = (Class)objc_msgSend(delegate,  sel_registerName("class"));
40         SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
41         if (class_getInstanceMethod(delClass, shouldHandle))
42             class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:");
43         else
44             class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:");
45     }
49 MacDockIconHandler::MacDockIconHandler() : QObject()
51     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
53     setupDockClickHandler();
54     this->m_dummyWidget = new QWidget();
55     this->m_dockMenu = new QMenu(this->m_dummyWidget);
56     this->setMainWindow(nullptr);
57 #if QT_VERSION < 0x050000
58     qt_mac_set_dock_menu(this->m_dockMenu);
59 #elif QT_VERSION >= 0x050200
60     this->m_dockMenu->setAsDockMenu();
61 #endif
62     [pool release];
65 void MacDockIconHandler::setMainWindow(QMainWindow *window) {
66     this->mainWindow = window;
69 MacDockIconHandler::~MacDockIconHandler()
71     delete this->m_dummyWidget;
72     this->setMainWindow(nullptr);
75 QMenu *MacDockIconHandler::dockMenu()
77     return this->m_dockMenu;
80 void MacDockIconHandler::setIcon(const QIcon &icon)
82     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
83     NSImage *image = nil;
84     if (icon.isNull())
85         image = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
86     else {
87         // generate NSImage from QIcon and use this as dock icon.
88         QSize size = icon.actualSize(QSize(128, 128));
89         QPixmap pixmap = icon.pixmap(size);
91         // Write image into a R/W buffer from raw pixmap, then save the image.
92         QBuffer notificationBuffer;
93         if (!pixmap.isNull() && notificationBuffer.open(QIODevice::ReadWrite)) {
94             QImageWriter writer(&notificationBuffer, "PNG");
95             if (writer.write(pixmap.toImage())) {
96                 NSData* macImgData = [NSData dataWithBytes:notificationBuffer.buffer().data()
97                                              length:notificationBuffer.buffer().size()];
98                 image =  [[NSImage alloc] initWithData:macImgData];
99             }
100         }
102         if(!image) {
103             // if testnet image could not be created, load std. app icon
104             image = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
105         }
106     }
108     [NSApp setApplicationIconImage:image];
109     [image release];
110     [pool release];
113 MacDockIconHandler *MacDockIconHandler::instance()
115     if (!s_instance)
116         s_instance = new MacDockIconHandler();
117     return s_instance;
120 void MacDockIconHandler::cleanup()
122     delete s_instance;
125 void MacDockIconHandler::handleDockIconClickEvent()
127     if (this->mainWindow)
128     {
129         this->mainWindow->activateWindow();
130         this->mainWindow->show();
131     }
133     Q_EMIT this->dockIconClicked();