Commit fd0d6c84 authored by Alexandre Lision's avatar Alexandre Lision

qrcode: display qrcode on main page

Relies on libqrencode, cloned and compiled by cmake

Tuleap: #616
Change-Id: I2cb9281289478321751a947fc8828bf0ba5c6f27
parent 261f1b91
[submodule "sparkle/Sparkle"]
path = sparkle/Sparkle
url = https://github.com/sparkle-project/Sparkle.git
[submodule "libqrencode"]
path = libqrencode
url = https://github.com/fukuchi/libqrencode.git
......@@ -25,6 +25,25 @@ FIND_PACKAGE(Qt5MacExtras REQUIRED)
FIND_PACKAGE(Qt5Widgets REQUIRED)
FIND_PACKAGE(LibRingClient REQUIRED)
EXECUTE_PROCESS(COMMAND git submodule update --init
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
INCLUDE(ExternalProject)
ExternalProject_Add(libqrencode
GIT_SUBMODULES libqrencode
SOURCE_DIR ${CMAKE_SOURCE_DIR}/libqrencode
BINARY_DIR ${CMAKE_SOURCE_DIR}/libqrencode
INSTALL_DIR ${CMAKE_SOURCE_DIR}/libqrencode
CONFIGURE_COMMAND
#hack to fix incomplete config.h on first run
COMMAND ./autogen.sh
COMMAND ./autogen.sh && ./configure --prefix=${CMAKE_SOURCE_DIR}/libqrencode
BUILD_COMMAND make
INSTALL_COMMAND make install)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/libqrencode/include)
LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/libqrencode/lib)
IF(NOT (${ENABLE_SPARKLE} MATCHES false))
MESSAGE("Sparkle auto-update enabled")
......@@ -39,7 +58,6 @@ IF(NOT (${ENABLE_SPARKLE} MATCHES false))
ADD_DEFINITIONS(-DENABLE_SPARKLE=1)
MESSAGE("Sparkle is here:" ${SPARKLE_FRAMEWORK})
FIND_PATH(SPARKLE_INCLUDE_DIR Sparkle.h HINTS ${SPARKLE_FRAMEWORK}/Headers)
MESSAGE("INCLUDE " ${SPARKLE_INCLUDE_DIR})
# we need to copy the public key to check the updates
SET(PUBLIC_KEY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/sparkle/dsa_pub.pem")
IF(EXISTS ${PUBLIC_KEY_PATH})
......@@ -217,6 +235,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_history.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/general.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/video.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_delete.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/qrcode.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_action_video.png)
SET_SOURCE_FILES_PROPERTIES(${ring_ICONS} PROPERTIES
......@@ -304,6 +323,8 @@ ENDIF(ENABLE_SPARKLE)
ADD_EXECUTABLE(${PROJ_NAME} MACOSX_BUNDLE ${TO_ADD})
ADD_DEPENDENCIES(${PROJ_NAME} libqrencode)
# Follow Xcode hierarchy principles
SOURCE_GROUP("Controllers" FILES ${ringclient_CONTROLLERS})
SOURCE_GROUP("Backends" FILES ${ringclient_BACKENDS})
......@@ -322,6 +343,7 @@ TARGET_LINK_LIBRARIES( ${PROJ_NAME}
${Qt5Core_LIBRARIES}
${Qt5MacExtras_LIBRARIES}
${Qt5Widgets_LIBRARIES}
-lqrencode
)
IF(ENABLE_SPARKLE)
......@@ -406,7 +428,10 @@ FOREACH(plugin ${QT_PLUGINS_IMAGEFORMAT})
ENDFOREACH()
# directories to look for dependencies
SET(DIRS ${CMAKE_INSTALL_PREFIX}/lib ${QT_LIB_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/sparkle)
SET(DIRS ${CMAKE_INSTALL_PREFIX}/lib
${QT_LIB_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/sparkle
${CMAKE_CURRENT_SOURCE_DIR}/libqrencode/lib)
INSTALL(CODE "
file(GLOB_RECURSE QTPLUGINS
......
Subproject commit 0ddcbc25ec5070ec6172eb86a0fe08fcb68bcf5f
......@@ -19,7 +19,7 @@
#import <Cocoa/Cocoa.h>
#import "HistoryVC.h"
@interface RingWindowController : NSWindowController {
@interface RingWindowController : NSWindowController <NSSharingServicePickerDelegate> {
IBOutlet NSView *currentView;
}
......
......@@ -18,7 +18,7 @@
*/
#import "RingWindowController.h"
#import <QuartzCore/QuartzCore.h>
#include <qrencode.h>
//Qt
#import <QItemSelectionModel>
......@@ -37,15 +37,20 @@
#import "ConversationVC.h"
#import "PreferencesWC.h"
#import "views/IconButton.h"
#import "views/NSColor+RingTheme.h"
@implementation RingWindowController {
__unsafe_unretained IBOutlet NSLayoutConstraint* centerYQRCodeConstraint;
__unsafe_unretained IBOutlet NSLayoutConstraint* centerYWelcomeContainerConstraint;
__unsafe_unretained IBOutlet NSView* welcomeContainer;
__unsafe_unretained IBOutlet NSView* callView;
__unsafe_unretained IBOutlet NSTextField* ringIDLabel;
__unsafe_unretained IBOutlet NSButton* shareButton;
__unsafe_unretained IBOutlet NSImageView* qrcodeView;
PreferencesWC *preferencesWC;
PreferencesWC* preferencesWC;
CurrentCallVC* currentCallVC;
ConversationVC* offlineVC;
}
......@@ -154,11 +159,106 @@ static NSString* const kPreferencesIdentifier = @"PreferencesIdentifier";
- (IBAction)shareRingID:(id)sender {
NSSharingServicePicker* sharingServicePicker = [[NSSharingServicePicker alloc] initWithItems:[NSArray arrayWithObject:[ringIDLabel stringValue]]];
[sharingServicePicker setDelegate:self];
[sharingServicePicker showRelativeToRect:[sender bounds]
ofView:sender
preferredEdge:NSMinYEdge];
}
- (IBAction)toggleQRCode:(id)sender {
// Toggle pressed state of QRCode button
[sender setPressed:![sender isPressed]];
if (![sender isPressed]) {
// Recenter welcome view
[self showQRCode:NO];
return;
}
auto qrCode = QRcode_encodeString(ringIDLabel.stringValue.UTF8String,
0,
QR_ECLEVEL_L, // Lowest level of error correction
QR_MODE_8, // 8-bit data mode
1);
if (!qrCode) {
return;
}
CGFloat size = qrcodeView.frame.size.width;
// create context
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(0, size, size, 8, size * 4, colorSpace, kCGImageAlphaPremultipliedLast);
CGAffineTransform translateTransform = CGAffineTransformMakeTranslation(0, -size);
CGAffineTransform scaleTransform = CGAffineTransformMakeScale(1, -1);
CGContextConcatCTM(ctx, CGAffineTransformConcat(translateTransform, scaleTransform));
// draw QR on this context
[self drawQRCode:qrCode context:ctx size:size];
// get image
auto qrCGImage = CGBitmapContextCreateImage(ctx);
auto qrImage = [[NSImage alloc] initWithCGImage:qrCGImage size:qrcodeView.frame.size];
// some releases
CGContextRelease(ctx);
CGImageRelease(qrCGImage);
CGColorSpaceRelease(colorSpace);
QRcode_free(qrCode);
[qrcodeView setImage:qrImage];
[self showQRCode:YES];
}
/**
* @param code the previously generated QRCode
* @param ctx current drawing context
* @param size the output size in which to draw
*/
- (void)drawQRCode:(QRcode *)code context:(CGContextRef)ctx size:(CGFloat)size {
unsigned char *data = 0;
int width;
data = code->data;
width = code->width;
int qr_margin = 3;
float zoom = ceil((double)size / (code->width + 2.0 * qr_margin));
CGRect rectDraw = CGRectMake(0, 0, zoom, zoom);
int ran;
for(int i = 0; i < width; ++i) {
for(int j = 0; j < width; ++j) {
if(*data & 1) {
CGContextSetFillColorWithColor(ctx, [NSColor ringDarkGrey].CGColor);
rectDraw.origin = CGPointMake((j + qr_margin) * zoom,(i + qr_margin) * zoom);
CGContextAddRect(ctx, rectDraw);
CGContextFillPath(ctx);
} else {
CGContextSetFillColorWithColor(ctx, [NSColor windowBackgroundColor].CGColor);
rectDraw.origin = CGPointMake((j + qr_margin) * zoom,(i + qr_margin) * zoom);
CGContextAddRect(ctx, rectDraw);
CGContextFillPath(ctx);
}
++data;
}
}
}
/**
* Start the in/out animation displaying the QRCode
* @param show should the QRCode be animated in or out
*/
- (void) showQRCode:(BOOL) show
{
static const NSInteger offset = 110;
[NSAnimationContext beginGrouping];
NSAnimationContext.currentContext.duration = 0.5;
[[NSAnimationContext currentContext] setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
qrcodeView.animator.alphaValue = show ? 1.0 : 0.0;
[centerYQRCodeConstraint.animator setConstant: show ? offset : 0];
[centerYWelcomeContainerConstraint.animator setConstant:show ? -offset : 0];
[NSAnimationContext endGrouping];
}
- (IBAction)openPreferences:(id)sender
{
preferencesWC = [[PreferencesWC alloc] initWithWindowNibName:@"PreferencesWindow"];
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment