Merge branch 'master' of github.com:jeena/Bungloo

This commit is contained in:
Jeena Paradies 2013-02-15 19:12:29 +01:00
commit f0f564a577
39 changed files with 850 additions and 849 deletions

View file

@ -13,109 +13,109 @@
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
d = [NSUserDefaults standardUserDefaults];
//[d removeObjectForKey:@"user_access_token"];
}
return self;
self = [super init];
if (self) {
// Initialization code here.
d = [NSUserDefaults standardUserDefaults];
//[d removeObjectForKey:@"user_access_token"];
}
return self;
}
- (void)setString:(NSString *)string forKey:(NSString *)aKey
{
[d setObject:string forKey:aKey];
[d synchronize];
[d setObject:string forKey:aKey];
[d synchronize];
}
- (NSString *)stringForKey:(NSString *)aKey
{
return [d objectForKey:aKey];
return [d objectForKey:aKey];
}
- (void)setAccessToken:(NSString *)_accessToken
{
[d synchronize];
[d synchronize];
}
- (NSString *)accessToken
{
return [d objectForKey:@"accessToken"];
return [d objectForKey:@"accessToken"];
}
- (void)setSecret:(NSString *)_secret
{
UInt32 _passwordLength = 0;
char *_password = nil;
SecKeychainItemRef item = nil;
SecKeychainFindGenericPassword(NULL, 6, "Bungloo", 17, "BunglooUserAccount", &_passwordLength, (void **)&_password, &item);
OSStatus status;
void * passwordData = (void*)[_secret cStringUsingEncoding:NSUTF8StringEncoding];
UInt32 passwordLength = strlen((char*)passwordData);
if (!item)
{
status = SecKeychainAddGenericPassword(
NULL, // default keychain
6, // length of service name
"Bungloo", // service name
17, // length of account name
"BunglooUserAccount", // account name
passwordLength, // length of password
passwordData, // pointer to password data
NULL // the item reference
);
}
else
{
status = SecKeychainItemModifyContent(
item,
NULL,
passwordLength,
passwordData
);
}
NSLog(@"%@",(NSString *)SecCopyErrorMessageString (status,NULL));
UInt32 _passwordLength = 0;
char *_password = nil;
SecKeychainItemRef item = nil;
SecKeychainFindGenericPassword(NULL, 6, "Bungloo", 17, "BunglooUserAccount", &_passwordLength, (void **)&_password, &item);
OSStatus status;
void * passwordData = (void*)[_secret cStringUsingEncoding:NSUTF8StringEncoding];
UInt32 passwordLength = strlen((char*)passwordData);
if (!item)
{
status = SecKeychainAddGenericPassword(
NULL, // default keychain
6, // length of service name
"Bungloo", // service name
17, // length of account name
"BunglooUserAccount", // account name
passwordLength, // length of password
passwordData, // pointer to password data
NULL // the item reference
);
}
else
{
status = SecKeychainItemModifyContent(
item,
NULL,
passwordLength,
passwordData
);
}
NSLog(@"%@",(NSString *)SecCopyErrorMessageString (status,NULL));
}
- (NSString *)secret
{
UInt32 passwordLength = 0;
char *password = nil;
SecKeychainItemRef item = nil;
SecKeychainFindGenericPassword(NULL, 6, "Bungloo", 17, "BunglooUserAccount", &passwordLength, (void **)&password, &item);
if (!item) {
return nil;
}
//Get password
NSString *passwordString = [[[NSString alloc] initWithData:[NSData dataWithBytes:password length:passwordLength] encoding:NSUTF8StringEncoding] autorelease];
SecKeychainItemFreeContent(NULL, password);
return passwordString;
UInt32 passwordLength = 0;
char *password = nil;
SecKeychainItemRef item = nil;
SecKeychainFindGenericPassword(NULL, 6, "Bungloo", 17, "BunglooUserAccount", &passwordLength, (void **)&password, &item);
if (!item) {
return nil;
}
//Get password
NSString *passwordString = [[[NSString alloc] initWithData:[NSData dataWithBytes:password length:passwordLength] encoding:NSUTF8StringEncoding] autorelease];
SecKeychainItemFreeContent(NULL, password);
return passwordString;
}
- (void)setUserId:(NSString *)_userId
{
[d setObject:_userId forKey:@"userId"];
[d synchronize];
[d setObject:_userId forKey:@"userId"];
[d synchronize];
}
- (NSString *)userId
{
return [d objectForKey:@"userId"];
return [d objectForKey:@"userId"];
}
- (void)setScreenName:(NSString *)_screenName
{
[d setObject:_screenName forKey:@"screenName"];
[d synchronize];
[d setObject:_screenName forKey:@"screenName"];
[d synchronize];
}
- (NSString *)screenName
{
return [d objectForKey:@"screenName"];
return [d objectForKey:@"screenName"];
}
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector {

View file

@ -3,5 +3,5 @@
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#import <Cocoa/Cocoa.h>
#endif

View file

@ -213,7 +213,7 @@
string = nil;
break;
}
return string;
}

View file

@ -21,20 +21,20 @@
IBOutlet NSWindow *timelineViewWindow;
IBOutlet WebView *mentionsView;
IBOutlet NSWindow *mentionsViewWindow;
IBOutlet WebView *conversationView;
IBOutlet NSWindow *conversationViewWindow;
WebView *profileView;
NSWindow *profileViewWindow;
NSPanel *openProfileWindow;
NSWindow *loginViewWindow;
NSTextField *loginEntityTextField;
NSProgressIndicator *loginActivityIndicator;
IBOutlet WebView *conversationView;
IBOutlet NSWindow *conversationViewWindow;
WebView *profileView;
NSWindow *profileViewWindow;
NSPanel *openProfileWindow;
NSWindow *loginViewWindow;
NSTextField *loginEntityTextField;
NSProgressIndicator *loginActivityIndicator;
IBOutlet NSMenuItem *globalHotkeyMenuItem;
IBOutlet NSImageView *logoLayer;
ViewDelegate *viewDelegate;
WebView *oauthView;
AccessToken *accessToken;
NSTextField *showProfileTextField;
WebView *oauthView;
AccessToken *accessToken;
NSTextField *showProfileTextField;
}

View file

@ -24,59 +24,59 @@
- (void)awakeFromNib
{
[timelineViewWindow setExcludedFromWindowsMenu:YES];
[mentionsViewWindow setExcludedFromWindowsMenu:YES];
[timelineViewWindow setExcludedFromWindowsMenu:YES];
[mentionsViewWindow setExcludedFromWindowsMenu:YES];
[self initHotKeys];
[GrowlApplicationBridge setGrowlDelegate:self];
[GrowlApplicationBridge setGrowlDelegate:self];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(openNewMessageWindow:)
[nc addObserver:self
selector:@selector(openNewMessageWindow:)
name:@"openNewMessageWindow"
object:nil];
[nc addObserver:self
selector:@selector(sendTweet:)
[nc addObserver:self
selector:@selector(sendTweet:)
name:@"sendTweet"
object:nil];
[nc addObserver:self
selector:@selector(authentificationSucceded:)
[nc addObserver:self
selector:@selector(authentificationSucceded:)
name:@"authentificationSucceded"
object:nil];
[nc addObserver:self
selector:@selector(getTweetUpdates:)
[nc addObserver:self
selector:@selector(getTweetUpdates:)
name:@"getTweetUpdates"
object:nil];
NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
[appleEventManager setEventHandler:self
andSelector:@selector(handleGetURLEvent:withReplyEvent:)
forEventClass:kInternetEventClass
andEventID:kAEGetURL];
viewDelegate = [[ViewDelegate alloc] init];
accessToken = [[AccessToken alloc] init];
BOOL forceLogin = NO;
/*
if (![accessToken stringForKey:@"version-0.6.0-new-login"]) {
[self logout:self];
forceLogin = YES;
[accessToken setString:nil forKey:@"entity"];
[accessToken setString:@"yes" forKey:@"version-0.6.0-new-login"];
}*/
if (forceLogin || ![accessToken stringForKey:@"user_access_token"] || ![accessToken secret]) {
[timelineViewWindow performClose:self];
[mentionsViewWindow performClose:self];
[self.loginViewWindow makeKeyAndOrderFront:self];
[self initOauth];
} else {
[timelineViewWindow makeKeyAndOrderFront:self];
[self initWebViews];
}
viewDelegate = [[ViewDelegate alloc] init];
accessToken = [[AccessToken alloc] init];
BOOL forceLogin = NO;
/*
if (![accessToken stringForKey:@"version-0.6.0-new-login"]) {
[self logout:self];
forceLogin = YES;
[accessToken setString:nil forKey:@"entity"];
[accessToken setString:@"yes" forKey:@"version-0.6.0-new-login"];
}*/
if (forceLogin || ![accessToken stringForKey:@"user_access_token"] || ![accessToken secret]) {
[timelineViewWindow performClose:self];
[mentionsViewWindow performClose:self];
[self.loginViewWindow makeKeyAndOrderFront:self];
[self initOauth];
} else {
[timelineViewWindow makeKeyAndOrderFront:self];
[self initWebViews];
}
}
# pragma mark Init
@ -85,113 +85,113 @@
- (void)initOauth
{
if (!oauthView) {
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Webkit/"];
NSURL *url = [NSURL fileURLWithPath:path];
NSString *index_string = [NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%@index.html", path] encoding:NSUTF8StringEncoding error:nil];
oauthView = [[WebView alloc] init];
viewDelegate.oauthView = oauthView;
[[oauthView mainFrame] loadHTMLString:index_string baseURL:url];
[oauthView setFrameLoadDelegate:viewDelegate];
[oauthView setPolicyDelegate:viewDelegate];
[oauthView setUIDelegate:viewDelegate];
[[oauthView windowScriptObject] setValue:self forKey:@"controller"];
if (!oauthView) {
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Webkit/"];
NSURL *url = [NSURL fileURLWithPath:path];
NSString *index_string = [NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%@index.html", path] encoding:NSUTF8StringEncoding error:nil];
}
oauthView = [[WebView alloc] init];
viewDelegate.oauthView = oauthView;
[[oauthView mainFrame] loadHTMLString:index_string baseURL:url];
[oauthView setFrameLoadDelegate:viewDelegate];
[oauthView setPolicyDelegate:viewDelegate];
[oauthView setUIDelegate:viewDelegate];
[[oauthView windowScriptObject] setValue:self forKey:@"controller"];
}
}
- (void)initWebViews
{
if (viewDelegate.timelineView != timelineView)
{
[self initOauth];
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Webkit/"];
NSURL *url = [NSURL fileURLWithPath:path];
NSString *index_string = [NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%@index.html", path] encoding:NSUTF8StringEncoding error:nil];
viewDelegate.timelineView = timelineView;
[[timelineView mainFrame] loadHTMLString:index_string baseURL:url];
[timelineView setFrameLoadDelegate:viewDelegate];
[timelineView setPolicyDelegate:viewDelegate];
[timelineView setUIDelegate:viewDelegate];
[[timelineView windowScriptObject] setValue:self forKey:@"controller"];
//WebPreferences* prefs = [timelineView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
viewDelegate.mentionsView = mentionsView;
[[mentionsView mainFrame] loadHTMLString:index_string baseURL:url];
[mentionsView setFrameLoadDelegate:viewDelegate];
[mentionsView setPolicyDelegate:viewDelegate];
[mentionsView setUIDelegate:viewDelegate];
[[mentionsView windowScriptObject] setValue:self forKey:@"controller"];
//prefs = [mentionsView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
viewDelegate.conversationView = conversationView;
[[conversationView mainFrame] loadHTMLString:index_string baseURL:url];
[conversationView setFrameLoadDelegate:viewDelegate];
[conversationView setPolicyDelegate:viewDelegate];
[conversationView setUIDelegate:viewDelegate];
[[conversationView windowScriptObject] setValue:self forKey:@"controller"];
//prefs = [conversationView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
viewDelegate.profileView = profileView;
[[profileView mainFrame] loadHTMLString:index_string baseURL:url];
[profileView setFrameLoadDelegate:viewDelegate];
[profileView setPolicyDelegate:viewDelegate];
[profileView setUIDelegate:viewDelegate];
[[profileView windowScriptObject] setValue:self forKey:@"controller"];
//prefs = [profileView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
if (viewDelegate.timelineView != timelineView)
{
[self initOauth];
}
else
{
[timelineView stringByEvaluatingJavaScriptFromString:@"start('timeline')"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"start('mentions')"];
[conversationView stringByEvaluatingJavaScriptFromString:@"start('conversation')"];
[profileView stringByEvaluatingJavaScriptFromString:@"start('profile')"];
}
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Webkit/"];
NSURL *url = [NSURL fileURLWithPath:path];
NSString *index_string = [NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%@index.html", path] encoding:NSUTF8StringEncoding error:nil];
viewDelegate.timelineView = timelineView;
[[timelineView mainFrame] loadHTMLString:index_string baseURL:url];
[timelineView setFrameLoadDelegate:viewDelegate];
[timelineView setPolicyDelegate:viewDelegate];
[timelineView setUIDelegate:viewDelegate];
[[timelineView windowScriptObject] setValue:self forKey:@"controller"];
//WebPreferences* prefs = [timelineView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
viewDelegate.mentionsView = mentionsView;
[[mentionsView mainFrame] loadHTMLString:index_string baseURL:url];
[mentionsView setFrameLoadDelegate:viewDelegate];
[mentionsView setPolicyDelegate:viewDelegate];
[mentionsView setUIDelegate:viewDelegate];
[[mentionsView windowScriptObject] setValue:self forKey:@"controller"];
//prefs = [mentionsView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
viewDelegate.conversationView = conversationView;
[[conversationView mainFrame] loadHTMLString:index_string baseURL:url];
[conversationView setFrameLoadDelegate:viewDelegate];
[conversationView setPolicyDelegate:viewDelegate];
[conversationView setUIDelegate:viewDelegate];
[[conversationView windowScriptObject] setValue:self forKey:@"controller"];
//prefs = [conversationView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
viewDelegate.profileView = profileView;
[[profileView mainFrame] loadHTMLString:index_string baseURL:url];
[profileView setFrameLoadDelegate:viewDelegate];
[profileView setPolicyDelegate:viewDelegate];
[profileView setUIDelegate:viewDelegate];
[[profileView windowScriptObject] setValue:self forKey:@"controller"];
//prefs = [profileView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
}
else
{
[timelineView stringByEvaluatingJavaScriptFromString:@"start('timeline')"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"start('mentions')"];
[conversationView stringByEvaluatingJavaScriptFromString:@"start('conversation')"];
[profileView stringByEvaluatingJavaScriptFromString:@"start('profile')"];
}
}
- (void)initHotKeys
{
NSInteger newTweetKey = kVK_ANSI_M; // http://boredzo.org/blog/archives/2007-05-22/virtual-key-codes
NSInteger newTweetModifierKey = controlKey + cmdKey + optionKey; // cmdKey 256, shitfKey 512, optionKey 2048, controlKey 4096
NSInteger newTweetModifierKey = controlKey + cmdKey + optionKey; // cmdKey 256, shitfKey 512, optionKey 2048, controlKey 4096
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger defaultsNewTweetKey = (NSInteger)[defaults integerForKey:@"newTweetKey"];
if ([defaults objectForKey:@"newTweetKey"] != nil)
{
{
newTweetKey = defaultsNewTweetKey;
}
else
{
else
{
[defaults setInteger:newTweetKey forKey:@"newTweetKey"];
}
NSInteger defaultsNewTweetModifierKey = (NSInteger)[defaults integerForKey:@"newTweetModifierKey"];
if ([defaults objectForKey:@"newTweetModifierKey"] != nil)
{
{
newTweetModifierKey = defaultsNewTweetModifierKey;
}
else
{
else
{
[defaults setInteger:newTweetModifierKey forKey:@"newTweetModifierKey"];
}
[defaults synchronize];
NSUInteger cocoaModifiers = 0;
if (newTweetModifierKey & shiftKey) cocoaModifiers = cocoaModifiers | NSShiftKeyMask;
if (newTweetModifierKey & optionKey) cocoaModifiers = cocoaModifiers | NSAlternateKeyMask;
@ -200,44 +200,44 @@
[globalHotkeyMenuItem setKeyEquivalent:[Constants stringFromVirtualKeyCode:newTweetKey]];
[globalHotkeyMenuItem setKeyEquivalentModifierMask:cocoaModifiers];
/* CARBON from http://github.com/Xjs/drama-button/blob/carbon/Drama_ButtonAppDelegate.m */
EventTypeSpec eventType;
eventType.eventClass = kEventClassKeyboard;
eventType.eventKind = kEventHotKeyPressed;
InstallApplicationEventHandler(&handler, 1, &eventType, NULL, NULL);
EventHotKeyID g_HotKeyID;
g_HotKeyID.id = 1;
EventHotKeyRef g_HotKeyRef;
RegisterEventHotKey(newTweetKey, newTweetModifierKey, g_HotKeyID, GetApplicationEventTarget(), 0, &g_HotKeyRef);
/* end CARBON */
}
- (void)alertTitle:(NSString *)title withMessage:(NSString *)message
{
NSAlert *alert = [NSAlert alertWithMessageText:title
defaultButton:@"OK" alternateButton:nil otherButton:nil
informativeTextWithFormat:@"%@", message];
[alert runModal];
NSAlert *alert = [NSAlert alertWithMessageText:title
defaultButton:@"OK" alternateButton:nil otherButton:nil
informativeTextWithFormat:@"%@", message];
[alert runModal];
}
- (void)authentificationSucceded:(id)sender
{
[loginActivityIndicator stopAnimation:self];
[loginActivityIndicator stopAnimation:self];
[self initWebViews];
[loginViewWindow performClose:self];
[loginViewWindow performClose:self];
}
- (void)authentificationDidNotSucceed:(NSString *)errorMessage
{
[loginActivityIndicator stopAnimation:self];
[self alertTitle:@"Authenication error" withMessage:errorMessage];
[loginActivityIndicator stopAnimation:self];
[self alertTitle:@"Authenication error" withMessage:errorMessage];
}
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
@ -252,21 +252,21 @@
- (void)setString:(NSString *)string forKey:(NSString *)aKey
{
[self.accessToken setString:string forKey:aKey];
[self.accessToken setString:string forKey:aKey];
}
- (void)setSecret:(NSString *)string
{
[self.accessToken setSecret:string];
[self.accessToken setSecret:string];
}
- (NSString *)secret
{
return [self.accessToken secret];
return [self.accessToken secret];
}
- (NSString *)stringForKey:(NSString *)aKey
{
return [self.accessToken stringForKey:aKey];
return [self.accessToken stringForKey:aKey];
}
@ -274,43 +274,43 @@
-(BOOL)applicationShouldOpenUntitledFile:(NSApplication *)theApplication
{
return NO;
return NO;
}
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
{
[timelineViewWindow makeKeyAndOrderFront:self];
return NO;
[timelineViewWindow makeKeyAndOrderFront:self];
return NO;
}
- (IBAction)openNewMessageWindow:(id)sender
{
[NSApp activateIgnoringOtherApps:YES];
[[NSDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:nil];
[NSApp activateIgnoringOtherApps:YES];
[[NSDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:nil];
}
- (void)openNewMessageWindowInReplyTo:(NSString *)userName statusId:(NSString *)statusId withString:(NSString *)string isPrivate:(BOOL)isPrivate
{
[NSApp activateIgnoringOtherApps:YES];
[NSApp activateIgnoringOtherApps:YES];
NewMessageWindow *newMessage = (NewMessageWindow *)[[NSDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:nil];
[newMessage inReplyTo:userName statusId:statusId withString:string];
[newMessage setIsPrivate:isPrivate];
[newMessage setIsPrivate:isPrivate];
}
- (void)openNewMessageWindowWithString:(NSString *)aString
{
[NSApp activateIgnoringOtherApps:YES];
NSRange range = [aString rangeOfString:@"oauthtoken"];
if (range.length > 0)
{
[oauthView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"bungloo_instance.requestAccessToken('%@')", aString]];
{
[oauthView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"bungloo_instance.requestAccessToken('%@')", aString]];
}
else
{
else
{
NewMessageWindow *newTweet = (NewMessageWindow *)[[NSDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:nil];
[newTweet withString:aString];
[newTweet withString:aString];
}
}
@ -323,47 +323,47 @@
- (IBAction)sendTweet:(id)sender
{
PostModel *post = (PostModel *)[sender object];
NSString *text = [[post.text stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"] stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
text = [text stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"];
NSString *locationObject = @"null";
if (post.location) {
locationObject = [NSString stringWithFormat:@"[%f, %f]", post.location.coordinate.latitude, post.location.coordinate.longitude];
}
NSString *imageFilePath = @"null";
if (post.imageFilePath) {
NSError *error;
NSString *mimeType = [MimeType mimeTypeForFileAtPath:post.imageFilePath error:&error];
NSData *data = [[NSData alloc] initWithContentsOfFile:post.imageFilePath];
NSString *base64 = [data base64Encoding_xcd];
[data release];
imageFilePath = [NSString stringWithFormat:@"\"data:%@;base64,%@\"", mimeType, base64];
}
NSString *isPrivate = @"false";
if (post.isPrivate) {
isPrivate = @"true";
}
NSString *func = [NSString stringWithFormat:@"bungloo_instance.sendNewMessage(\"%@\", \"%@\", \"%@\", %@, %@, %@)",
text,
post.inReplyTostatusId,
post.inReplyToEntity,
locationObject,
imageFilePath,
isPrivate];
NSString *text = [[post.text stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"] stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
text = [text stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"];
[timelineView stringByEvaluatingJavaScriptFromString:func];
NSString *locationObject = @"null";
if (post.location) {
locationObject = [NSString stringWithFormat:@"[%f, %f]", post.location.coordinate.latitude, post.location.coordinate.longitude];
}
NSString *imageFilePath = @"null";
if (post.imageFilePath) {
NSError *error;
NSString *mimeType = [MimeType mimeTypeForFileAtPath:post.imageFilePath error:&error];
NSData *data = [[NSData alloc] initWithContentsOfFile:post.imageFilePath];
NSString *base64 = [data base64Encoding_xcd];
[data release];
imageFilePath = [NSString stringWithFormat:@"\"data:%@;base64,%@\"", mimeType, base64];
}
NSString *isPrivate = @"false";
if (post.isPrivate) {
isPrivate = @"true";
}
NSString *func = [NSString stringWithFormat:@"bungloo_instance.sendNewMessage(\"%@\", \"%@\", \"%@\", %@, %@, %@)",
text,
post.inReplyTostatusId,
post.inReplyToEntity,
locationObject,
imageFilePath,
isPrivate];
[timelineView stringByEvaluatingJavaScriptFromString:func];
}
- (NSString *)pluginURL
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *pathToPlugin = [@"~/Library/Application Support/Bungloo/Plugin.js" stringByExpandingTildeInPath];
if([fileManager fileExistsAtPath:pathToPlugin])
{
if([fileManager fileExistsAtPath:pathToPlugin])
{
return [NSString stringWithFormat:@"%@", [NSURL fileURLWithPath:pathToPlugin]];
}
return nil;
@ -372,12 +372,12 @@
- (void)unreadMentions:(int)count
{
if (![mentionsViewWindow isVisible] && count > 0)
{
{
[timelineViewWindow setTitle:[NSString stringWithFormat:@"Bungloo (^%i)", count]];
[[[NSApplication sharedApplication] dockTile] setBadgeLabel:[NSString stringWithFormat:@"%i", count]];
}
else
{
else
{
[timelineViewWindow setTitle:[NSString stringWithFormat:@"Bungloo"]];
[[[NSApplication sharedApplication] dockTile] setBadgeLabel:nil];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.unread_mentions = 0;"];
@ -386,95 +386,95 @@
- (void)notificateUserAboutMention:(NSString *)text fromName:(NSString *)name withPostId:(NSString *)postId andEntity:(NSString *)entity
{
[GrowlApplicationBridge
notifyWithTitle:[NSString stringWithFormat:@"Mentioned by %@ on Tent", name]
description:text
notificationName:@"Mention"
iconData:nil
priority:0
isSticky:NO
clickContext:[NSDictionary dictionaryWithObjectsAndKeys:
entity, @"entity",
postId, @"postId", nil]];
[GrowlApplicationBridge
notifyWithTitle:[NSString stringWithFormat:@"Mentioned by %@ on Tent", name]
description:text
notificationName:@"Mention"
iconData:nil
priority:0
isSticky:NO
clickContext:[NSDictionary dictionaryWithObjectsAndKeys:
entity, @"entity",
postId, @"postId", nil]];
}
- (void)openURL:(NSString *)url
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
}
- (IBAction)showProfile:(id)sender
{
NSString *entity = [self.showProfileTextField stringValue];
if ([entity rangeOfString:@"."].location != NSNotFound && ([entity hasPrefix:@"http://"] || [entity hasPrefix:@"https://"])) {
NSString *func = [NSString stringWithFormat:@"bungloo_instance.showProfileForEntity('%@')", entity];
[profileView stringByEvaluatingJavaScriptFromString:func];
[profileViewWindow makeKeyAndOrderFront:self];
[openProfileWindow performClose:self];
}
NSString *entity = [self.showProfileTextField stringValue];
if ([entity rangeOfString:@"."].location != NSNotFound && ([entity hasPrefix:@"http://"] || [entity hasPrefix:@"https://"])) {
NSString *func = [NSString stringWithFormat:@"bungloo_instance.showProfileForEntity('%@')", entity];
[profileView stringByEvaluatingJavaScriptFromString:func];
[profileViewWindow makeKeyAndOrderFront:self];
[openProfileWindow performClose:self];
}
}
- (void)notificateViewsAboutDeletedPostWithId:(NSString *)postId byEntity:(NSString*)entity
{
NSString *fun = [NSString stringWithFormat:@"bungloo_instance.postDeleted('%@', '%@')", postId, entity];
[timelineView stringByEvaluatingJavaScriptFromString:fun];
[mentionsView stringByEvaluatingJavaScriptFromString:fun];
[conversationView stringByEvaluatingJavaScriptFromString:fun];
[profileView stringByEvaluatingJavaScriptFromString:fun];
NSString *fun = [NSString stringWithFormat:@"bungloo_instance.postDeleted('%@', '%@')", postId, entity];
[timelineView stringByEvaluatingJavaScriptFromString:fun];
[mentionsView stringByEvaluatingJavaScriptFromString:fun];
[conversationView stringByEvaluatingJavaScriptFromString:fun];
[profileView stringByEvaluatingJavaScriptFromString:fun];
}
/*
- (void)storeAccessToken:(NSString *)_accessToken secret:(NSString *)secret userId:(NSString *)userId andScreenName:(NSString *)screenName
{
self.accessToken.accessToken = _accessToken;
self.accessToken.secret = secret;
self.accessToken.userId = userId;
self.accessToken.screenName = screenName;
[timelineViewWindow makeKeyAndOrderFront:self];
[[NSNotificationCenter defaultCenter] postNotificationName:@"authentificationSucceded" object:nil];
self.accessToken.accessToken = _accessToken;
self.accessToken.secret = secret;
self.accessToken.userId = userId;
self.accessToken.screenName = screenName;
[timelineViewWindow makeKeyAndOrderFront:self];
[[NSNotificationCenter defaultCenter] postNotificationName:@"authentificationSucceded" object:nil];
}*/
- (void)loggedIn
{
[loginActivityIndicator stopAnimation:self];
[loginActivityIndicator stopAnimation:self];
[self initWebViews];
[loginViewWindow performClose:self];
[timelineViewWindow makeKeyAndOrderFront:self];
[loginViewWindow performClose:self];
[timelineViewWindow makeKeyAndOrderFront:self];
}
- (IBAction)login:(id)sender
{
if ([[loginEntityTextField stringValue] length] > 0) {
[[loginEntityTextField window] makeFirstResponder:nil];
[loginActivityIndicator startAnimation:self];
[oauthView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.authenticate();"];
}
if ([[loginEntityTextField stringValue] length] > 0) {
[[loginEntityTextField window] makeFirstResponder:nil];
[loginActivityIndicator startAnimation:self];
[oauthView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.authenticate();"];
}
}
- (IBAction)logout:(id)sender
{
[oauthView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"];
[timelineViewWindow performClose:self];
[mentionsViewWindow performClose:self];
[conversationViewWindow performClose:self];
[profileViewWindow performClose:self];
[self.loginViewWindow makeKeyAndOrderFront:self];
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"];
[oauthView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"];
[timelineViewWindow performClose:self];
[mentionsViewWindow performClose:self];
[conversationViewWindow performClose:self];
[profileViewWindow performClose:self];
[self.loginViewWindow makeKeyAndOrderFront:self];
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"];
}
// Mentions window has been visible
- (void)windowDidBecomeKey:(NSNotification *)notification
{
if ([notification object] == mentionsViewWindow)
{
{
//[self unreadMentions:0];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.setAllMentionsRead();"];
}
}
}
- (void)getTweetUpdates:(id)sender
@ -485,39 +485,39 @@
- (IBAction)showConversationForPostId:(NSString *)postId andEntity:(NSString *)entity
{
NSString *js = [NSString stringWithFormat:@"bungloo_instance.showStatus('%@', '%@');", postId, entity];
[conversationView stringByEvaluatingJavaScriptFromString:js];
[conversationViewWindow makeKeyAndOrderFront:self];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
NSString *js = [NSString stringWithFormat:@"bungloo_instance.showStatus('%@', '%@');", postId, entity];
[conversationView stringByEvaluatingJavaScriptFromString:js];
[conversationViewWindow makeKeyAndOrderFront:self];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
}
- (IBAction)clearCache:(id)sender
{
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.cache.clear()"];
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.cache.clear()"];
}
- (IBAction)showProfileForEntity:(NSString *)entity
{
NSString *js = [NSString stringWithFormat:@"bungloo_instance.showProfileForEntity('%@');", entity];
[profileView stringByEvaluatingJavaScriptFromString:js];
[profileViewWindow makeKeyAndOrderFront:self];
NSString *js = [NSString stringWithFormat:@"bungloo_instance.showProfileForEntity('%@');", entity];
[profileView stringByEvaluatingJavaScriptFromString:js];
[profileViewWindow makeKeyAndOrderFront:self];
}
- (void)growlNotificationWasClicked:(id)clickContext
{
NSDictionary *userInfo = (NSDictionary *)clickContext;
NSString *postId = [userInfo objectForKey:@"postId"];
NSString *entity = [userInfo objectForKey:@"entity"];
[self showConversationForPostId:postId andEntity:entity];
NSString *js = [NSString stringWithFormat:@"bungloo_instance.mentionRead('%@', '%@');", postId, entity];
[mentionsView stringByEvaluatingJavaScriptFromString:js];
NSDictionary *userInfo = (NSDictionary *)clickContext;
NSString *postId = [userInfo objectForKey:@"postId"];
NSString *entity = [userInfo objectForKey:@"entity"];
[self showConversationForPostId:postId andEntity:entity];
NSString *js = [NSString stringWithFormat:@"bungloo_instance.mentionRead('%@', '%@');", postId, entity];
[mentionsView stringByEvaluatingJavaScriptFromString:js];
}
- (NSString *) applicationNameForGrowl
{
return @"Bungloo";
return @"Bungloo";
}
/* CARBON */

View file

@ -390,8 +390,8 @@
/*! @brief Tries to fill in missing keys in a notification dictionary.
* @param notifDict The dictionary to fill in.
* @return The dictionary with the keys filled in. This will be a separate instance from \a notifDict.
* @discussion This function examines the \a notifDict for missing keys, and
* tries to get them from the last known registration dictionary. As of 1.1,
* @discussion This function examines the \a notifDict for missing keys, and
* tries to get them from the last known registration dictionary. As of 1.1,
* the keys that it will look for are:
*
* \li <code>GROWL_APP_NAME</code>
@ -410,8 +410,8 @@
*@abstract Lets the app know whether growl:// is registered on the system, used for certain methods below this
*@return Returns whether growl:// is registered on the system
*@discussion Methods such as openGrowlPreferences rely on the growl:// URL scheme to function
* Further, this method can provide a check on whether Growl is installed,
* however, the framework will not be relying on this method for choosing when/how to notify,
* Further, this method can provide a check on whether Growl is installed,
* however, the framework will not be relying on this method for choosing when/how to notify,
* and it is not recommended that the app rely on it for other than whether to use growl:// methods
*@since Growl.framework 1.4
*/
@ -421,7 +421,7 @@
* @method openGrowlPreferences:
* @abstract Open Growl preferences, optionally to this app's settings, growl:// method
* @param showApp Whether to show the application's settings, otherwise just opens to the last position
* @return Return's whether opening the URL was succesfull or not.
* @return Return's whether opening the URL was succesfull or not.
* @discussion Will launch if Growl is installed, but not running, and open the preferences window
* Uses growl:// URL scheme
* @since Growl.framework 1.4

View file

@ -11,17 +11,17 @@
@implementation MimeType
+(NSString *)mimeTypeForFileAtPath:(NSString *)path error:(NSError **)err {
NSString *uti, *mimeType = nil;
if (!(uti = [[NSWorkspace sharedWorkspace] typeOfFile:path error:err]))
return nil;
if (err)
*err = nil;
if ((mimeType = (NSString *)UTTypeCopyPreferredTagWithClass((CFStringRef)uti, kUTTagClassMIMEType)))
mimeType = NSMakeCollectable(mimeType);
return mimeType;
NSString *uti, *mimeType = nil;
if (!(uti = [[NSWorkspace sharedWorkspace] typeOfFile:path error:err]))
return nil;
if (err)
*err = nil;
if ((mimeType = (NSString *)UTTypeCopyPreferredTagWithClass((CFStringRef)uti, kUTTagClassMIMEType)))
mimeType = NSMakeCollectable(mimeType);
return mimeType;
}
@end

View file

@ -15,7 +15,7 @@
{
if ([base64Encoding length] % 4 != 0)
return nil;
NSString *plist = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?><plist version=\"1.0\"><data>%@</data></plist>", base64Encoding];
return [NSPropertyListSerialization propertyListWithData:[plist dataUsingEncoding:NSASCIIStringEncoding] options:0 format:NULL error:NULL];
}
@ -28,14 +28,14 @@
NSRange endRange = [plist rangeOfData:[@"</data>" dataUsingEncoding:NSASCIIStringEncoding] options:NSDataSearchBackwards range:fullRange];
if (startRange.location == NSNotFound || endRange.location == NSNotFound)
return nil;
NSUInteger base64Location = startRange.location + startRange.length;
NSUInteger base64length = endRange.location - base64Location;
NSData *base64Data = [NSData dataWithBytesNoCopy:(void *)((uintptr_t)base64Location + (uintptr_t)[plist bytes]) length:base64length freeWhenDone:NO];
NSString *base64Encoding = [[NSString alloc] initWithData:base64Data encoding:NSASCIIStringEncoding];
base64Encoding = [base64Encoding stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
base64Encoding = [base64Encoding stringByReplacingOccurrencesOfString:@"\n" withString:@""];
#if __has_feature(objc_arc)
return base64Encoding;
#else

View file

@ -15,15 +15,15 @@
{
IBOutlet NSTextField *textField;
IBOutlet NSTextField *counter;
NSMenu *addMenu;
NSButton *addMenuButton;
NSMenu *addMenu;
NSButton *addMenuButton;
NSString *inReplyTostatusId;
NSString *inReplyToEntity;
NSMenuItem *addImage;
CLLocationManager *locationManager;
CLLocation *currentLocation;
NSString *imageFilePath;
NSButton *togglePrivateButton;
NSString *inReplyToEntity;
NSMenuItem *addImage;
CLLocationManager *locationManager;
CLLocation *currentLocation;
NSString *imageFilePath;
NSButton *togglePrivateButton;
}
@property (nonatomic, retain) IBOutlet NSTextField *textField;

View file

@ -27,31 +27,31 @@
- (void)dealloc
{
[locationManager stopUpdatingLocation];
[locationManager release];
[currentLocation release];
[imageFilePath release];
[super dealloc];
[locationManager stopUpdatingLocation];
[locationManager release];
[currentLocation release];
[imageFilePath release];
[super dealloc];
}
- (id)init
{
self = [super init];
if (self)
{
// Add your subclass-specific initialization here.
// If an error occurs here, send a [self release] message and return nil.
self = [super init];
if (self)
{
// Add your subclass-specific initialization here.
// If an error occurs here, send a [self release] message and return nil.
inReplyTostatusId = @"";
inReplyToEntity = @"";
}
return self;
inReplyToEntity = @"";
}
return self;
}
- (NSString *)windowNibName
{
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return @"NewMessageWindow";
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return @"NewMessageWindow";
}
- (NSString *)displayName
@ -61,24 +61,24 @@
- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
[super windowControllerDidLoadNib:aController];
// Add any code here that needs to be executed once the windowController has loaded the document's window.
[textField becomeFirstResponder];
[super windowControllerDidLoadNib:aController];
// Add any code here that needs to be executed once the windowController has loaded the document's window.
[textField becomeFirstResponder];
// Enable Continous Spelling
NSTextView *textView = (NSTextView *)[[[self.windowControllers objectAtIndex:0] window] firstResponder];;
[textView setContinuousSpellCheckingEnabled:YES];
// Enable Continous Spelling
NSTextView *textView = (NSTextView *)[[[self.windowControllers objectAtIndex:0] window] firstResponder];;
[textView setContinuousSpellCheckingEnabled:YES];
}
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
// Insert code here to write your document to data of the specified type. If the given outError != NULL, ensure that you set *outError when returning nil.
// Insert code here to write your document to data of the specified type. If the given outError != NULL, ensure that you set *outError when returning nil.
// You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
// You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
// For applications targeted for Panther or earlier systems, you should use the deprecated API -dataRepresentationOfType:. In this case you can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
// For applications targeted for Panther or earlier systems, you should use the deprecated API -dataRepresentationOfType:. In this case you can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
if ( outError != NULL ) {
if ( outError != NULL ) {
*outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
}
return nil;
@ -86,42 +86,42 @@
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
// Insert code here to read your document from the given data of the specified type. If the given outError != NULL, ensure that you set *outError when returning NO.
// Insert code here to read your document from the given data of the specified type. If the given outError != NULL, ensure that you set *outError when returning NO.
// You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
// For applications targeted for Panther or earlier systems, you should use the deprecated API -loadDataRepresentation:ofType. In this case you can also choose to override -readFromFile:ofType: or -loadFileWrapperRepresentation:ofType: instead.
if ( outError != NULL )
{
// You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
// For applications targeted for Panther or earlier systems, you should use the deprecated API -loadDataRepresentation:ofType. In this case you can also choose to override -readFromFile:ofType: or -loadFileWrapperRepresentation:ofType: instead.
if ( outError != NULL )
{
*outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
}
return YES;
return YES;
}
- (void)inReplyTo:(NSString *)entity statusId:(NSString *)statusId withString:(NSString *)string
{
[textField setStringValue:string];
NSInteger location = [string rangeOfString:@" "].location;
NSInteger length = 0;
if (location != NSNotFound) {
length = [[textField stringValue] length] - location - 1;
}
NSInteger location = [string rangeOfString:@" "].location;
NSInteger length = 0;
if (location != NSNotFound) {
length = [[textField stringValue] length] - location - 1;
}
NSRange range = {location + 1, length};
[[textField currentEditor] setSelectedRange:range];
[inReplyTostatusId release];
inReplyTostatusId = statusId;
[inReplyTostatusId retain];
[inReplyToEntity release];
inReplyToEntity = entity;
[inReplyToEntity retain];
[self controlTextDidChange:nil];
[inReplyToEntity release];
inReplyToEntity = entity;
[inReplyToEntity retain];
[self controlTextDidChange:nil];
}
- (void)withString:(NSString *)aString
@ -129,59 +129,59 @@
[textField setStringValue:aString];
NSRange range = {[[textField stringValue] length] , 0};
[[textField currentEditor] setSelectedRange:range];
NSLog(@"BB");
[self controlTextDidChange:nil];
NSLog(@"BB");
[self controlTextDidChange:nil];
}
- (IBAction)addCurrentLocation:(id)sender
{
NSMenuItem *menuItem = (NSMenuItem *)sender;
if (!self.locationManager)
{
[menuItem setTitle:@"Current location not available"];
[self initLocationManager];
}
else
{
[self.locationManager stopUpdatingLocation];
self.currentLocation = nil;
self.locationManager = nil;
[menuItem setTitle:@"Add current location"];
}
NSMenuItem *menuItem = (NSMenuItem *)sender;
if (!self.locationManager)
{
[menuItem setTitle:@"Current location not available"];
[self initLocationManager];
}
else
{
[self.locationManager stopUpdatingLocation];
self.currentLocation = nil;
self.locationManager = nil;
[menuItem setTitle:@"Add current location"];
}
}
- (IBAction)openAddMenu:(id)sender
{
NSRect frame = [(NSButton *)sender frame];
NSPoint menuOrigin = [[(NSButton *)sender superview] convertPoint:NSMakePoint(frame.origin.x, frame.origin.y+frame.size.height) toView:nil];
NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDown
location:menuOrigin
modifierFlags:NSLeftMouseDownMask // 0x100
timestamp:NSTimeIntervalSince1970
windowNumber:[[(NSButton *)sender window] windowNumber]
context:[[(NSButton *)sender window] graphicsContext]
eventNumber:0
clickCount:1
pressure:1];
[NSMenu popUpContextMenu:self.addMenu withEvent:event forView:self.addMenuButton];
NSRect frame = [(NSButton *)sender frame];
NSPoint menuOrigin = [[(NSButton *)sender superview] convertPoint:NSMakePoint(frame.origin.x, frame.origin.y+frame.size.height) toView:nil];
NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDown
location:menuOrigin
modifierFlags:NSLeftMouseDownMask // 0x100
timestamp:NSTimeIntervalSince1970
windowNumber:[[(NSButton *)sender window] windowNumber]
context:[[(NSButton *)sender window] graphicsContext]
eventNumber:0
clickCount:1
pressure:1];
[NSMenu popUpContextMenu:self.addMenu withEvent:event forView:self.addMenuButton];
}
- (IBAction)togglePrivate:(id)sender
{
NSImage *image = [NSImage imageNamed:NSImageNameLockLockedTemplate];
if (self.togglePrivateButton.image == [NSImage imageNamed:NSImageNameLockLockedTemplate])
{
image = [NSImage imageNamed:NSImageNameLockUnlockedTemplate];
}
[self.togglePrivateButton setImage:image];
NSImage *image = [NSImage imageNamed:NSImageNameLockLockedTemplate];
if (self.togglePrivateButton.image == [NSImage imageNamed:NSImageNameLockLockedTemplate])
{
image = [NSImage imageNamed:NSImageNameLockUnlockedTemplate];
}
[self.togglePrivateButton setImage:image];
}
- (void)setIsPrivate:(BOOL)isPrivate {
NSImage *image = [NSImage imageNamed:(isPrivate ? NSImageNameLockLockedTemplate : NSImageNameLockUnlockedTemplate)];
[self.togglePrivateButton setImage:image];
NSImage *image = [NSImage imageNamed:(isPrivate ? NSImageNameLockLockedTemplate : NSImageNameLockUnlockedTemplate)];
[self.togglePrivateButton setImage:image];
}
-(void)controlTextDidChange:(NSNotification *)aNotification {
@ -190,50 +190,50 @@
if(c < 0) {
[counter setTextColor:[NSColor redColor]];
} else {
[counter setTextColor:[NSColor controlTextColor]];
[counter setTextColor:[NSColor controlTextColor]];
}
}
- (void)initLocationManager
{
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
[self.locationManager startUpdatingLocation];
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
self.currentLocation = newLocation;
NSMenuItem *menuItem = [self.addMenu itemAtIndex:0];
[menuItem setTitle:@"Remove current location"];
self.currentLocation = newLocation;
NSMenuItem *menuItem = [self.addMenu itemAtIndex:0];
[menuItem setTitle:@"Remove current location"];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(@"CLLocationManager Error: %@", error);
NSMenuItem *menuItem = [self.addMenu itemAtIndex:0];
[menuItem setTitle:@"Current location not available"];
NSLog(@"CLLocationManager Error: %@", error);
NSMenuItem *menuItem = [self.addMenu itemAtIndex:0];
[menuItem setTitle:@"Current location not available"];
}
- (IBAction)sendPostButtonPressed:(id)sender
{
[self sendPost:self.textField];
[self sendPost:self.textField];
}
#pragma mark Keyboard delegate methods
- (IBAction)sendPost:(NSControl *)control {
BOOL emptyIsOk = self.currentLocation || self.imageFilePath;
BOOL emptyIsOk = self.currentLocation || self.imageFilePath;
if (emptyIsOk || ([[control stringValue] length] <= MESSAGE_MAX_LENGTH && [[control stringValue] length] > 0)) {
PostModel *post = [[[PostModel alloc] init] autorelease];
post.text = [control stringValue];
post.inReplyTostatusId = inReplyTostatusId;
post.inReplyToEntity = inReplyToEntity;
post.location = self.currentLocation;
post.imageFilePath = self.imageFilePath;
post.isPrivate = self.togglePrivateButton.image == [NSImage imageNamed:NSImageNameLockLockedTemplate];
post.inReplyToEntity = inReplyToEntity;
post.location = self.currentLocation;
post.imageFilePath = self.imageFilePath;
post.isPrivate = self.togglePrivateButton.image == [NSImage imageNamed:NSImageNameLockLockedTemplate];
[[NSNotificationCenter defaultCenter] postNotificationName:@"sendTweet" object:post];
[self close];
} else {
@ -243,102 +243,102 @@
}
- (BOOL)isCommandEnterEvent:(NSEvent *)e {
NSUInteger flags = (e.modifierFlags & NSDeviceIndependentModifierFlagsMask);
BOOL isCommand = (flags & NSCommandKeyMask) == NSCommandKeyMask;
BOOL isEnter = (e.keyCode == 0x24); // VK_RETURN
return (isCommand && isEnter);
NSUInteger flags = (e.modifierFlags & NSDeviceIndependentModifierFlagsMask);
BOOL isCommand = (flags & NSCommandKeyMask) == NSCommandKeyMask;
BOOL isEnter = (e.keyCode == 0x24); // VK_RETURN
return (isCommand && isEnter);
}
- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector
{
BOOL retval = NO;
BOOL isEnter = [[NSApp currentEvent] keyCode] == 76;
if (commandSelector == @selector(insertNewline:) && !isEnter) {
NSText *text = [[textField window] fieldEditor:YES forObject:nil];
NSRange range = [text selectedRange];
NSString *stringBefore = [textField.stringValue substringToIndex:range.location];
NSString *stringAfter = [textField.stringValue substringFromIndex:range.location + range.length];
textField.stringValue = [NSString stringWithFormat:@"%@\n%@", stringBefore, stringAfter];
BOOL retval = NO;
NSRange r = NSMakeRange(range.location + 1, 0);
[text scrollRangeToVisible:r];
[text setSelectedRange:r];
BOOL isEnter = [[NSApp currentEvent] keyCode] == 76;
retval = YES; // causes Apple to NOT fire the default enter action
}
else if (commandSelector == @selector(noop:) && isEnter) {
retval = YES;
[self sendPost:control];
}
return retval;
if (commandSelector == @selector(insertNewline:) && !isEnter) {
NSText *text = [[textField window] fieldEditor:YES forObject:nil];
NSRange range = [text selectedRange];
NSString *stringBefore = [textField.stringValue substringToIndex:range.location];
NSString *stringAfter = [textField.stringValue substringFromIndex:range.location + range.length];
textField.stringValue = [NSString stringWithFormat:@"%@\n%@", stringBefore, stringAfter];
NSRange r = NSMakeRange(range.location + 1, 0);
[text scrollRangeToVisible:r];
[text setSelectedRange:r];
retval = YES; // causes Apple to NOT fire the default enter action
}
else if (commandSelector == @selector(noop:) && isEnter) {
retval = YES;
[self sendPost:control];
}
return retval;
}
#pragma mark Add images
- (IBAction)addImage:(id)sender
{
NSMenuItem *menuItem = (NSMenuItem *)sender;
NSMenuItem *menuItem = (NSMenuItem *)sender;
if (!self.imageFilePath)
{
[menuItem setTitle:@"Remove photo"];
NSOpenPanel* openDlg = [NSOpenPanel openPanel];
[openDlg setPrompt:@"Select"];
[openDlg setDelegate:self];
// Enable the selection of files in the dialog.
[openDlg setCanChooseFiles:YES];
// Enable the selection of directories in the dialog.
[openDlg setCanChooseDirectories:NO];
// Display the dialog. If the OK button was pressed,
// process the files.
if ( [openDlg runModalForDirectory:nil file:nil] == NSOKButton )
{
// Get an array containing the full filenames of all
// files and directories selected.
NSArray* files = [openDlg filenames];
// Loop through all the files and process them.
for( int i = 0; i < [files count]; i++ )
{
self.imageFilePath = [files objectAtIndex:i];
}
}
}
else
{
self.imageFilePath = nil;
[menuItem setTitle:@"Add photo"];
}
if (!self.imageFilePath)
{
[menuItem setTitle:@"Remove photo"];
NSOpenPanel* openDlg = [NSOpenPanel openPanel];
[openDlg setPrompt:@"Select"];
[openDlg setDelegate:self];
// Enable the selection of files in the dialog.
[openDlg setCanChooseFiles:YES];
// Enable the selection of directories in the dialog.
[openDlg setCanChooseDirectories:NO];
// Display the dialog. If the OK button was pressed,
// process the files.
if ( [openDlg runModalForDirectory:nil file:nil] == NSOKButton )
{
// Get an array containing the full filenames of all
// files and directories selected.
NSArray* files = [openDlg filenames];
// Loop through all the files and process them.
for( int i = 0; i < [files count]; i++ )
{
self.imageFilePath = [files objectAtIndex:i];
}
}
}
else
{
self.imageFilePath = nil;
[menuItem setTitle:@"Add photo"];
}
}
-(BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename
{
NSString* ext = [filename pathExtension];
if ([ext isEqualToString:@""] || [ext isEqualToString:@"/"] || ext == nil || ext == NULL || [ext length] < 1) {
return YES;
}
NSEnumerator* tagEnumerator = [[NSArray arrayWithObjects:@"png", @"jpg", @"gif", @"jpeg", nil] objectEnumerator];
NSString* allowedExt;
while ((allowedExt = [tagEnumerator nextObject]))
{
if ([ext caseInsensitiveCompare:allowedExt] == NSOrderedSame)
{
return YES;
}
}
return NO;
NSString* ext = [filename pathExtension];
if ([ext isEqualToString:@""] || [ext isEqualToString:@"/"] || ext == nil || ext == NULL || [ext length] < 1) {
return YES;
}
NSEnumerator* tagEnumerator = [[NSArray arrayWithObjects:@"png", @"jpg", @"gif", @"jpeg", nil] objectEnumerator];
NSString* allowedExt;
while ((allowedExt = [tagEnumerator nextObject]))
{
if ([ext caseInsensitiveCompare:allowedExt] == NSOrderedSame)
{
return YES;
}
}
return NO;
}
@end

View file

@ -12,10 +12,10 @@
@interface PostModel : NSObject {
NSString *text;
NSString *inReplyTostatusId;
NSString *inReplyToEntity;
CLLocation *location;
NSString *imageFilePath;
BOOL isPrivate;
NSString *inReplyToEntity;
CLLocation *location;
NSString *imageFilePath;
BOOL isPrivate;
}
@property (nonatomic, retain) NSString *text;

View file

@ -17,9 +17,9 @@
{
[text release];
[inReplyTostatusId release];
[inReplyToEntity release];
[location release];
[imageFilePath release];
[inReplyToEntity release];
[location release];
[imageFilePath release];
[super dealloc];
}

View file

@ -13,16 +13,16 @@
NSString *title;
NSDate *date;
NSString *itemDescription;
NSURL *releaseNotesURL;
NSString *DSASignature;
NSString *DSASignature;
NSString *minimumSystemVersion;
NSURL *fileURL;
NSString *versionString;
NSString *displayVersionString;
NSDictionary *propertiesDictionary;
}

View file

@ -15,7 +15,7 @@
@interface SUUpdater : NSObject {
NSTimer *checkTimer;
SUUpdateDriver *driver;
SUHost *host;
IBOutlet id delegate;
}

View file

@ -16,7 +16,7 @@
@protocol SUVersionComparison
/*!
@method
@method
@abstract An abstract method to compare two version strings.
@discussion Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, and NSOrderedSame if they are equivalent.
*/

View file

@ -13,9 +13,9 @@
@interface ViewDelegate : NSObject {
WebView *timelineView;
WebView *mentionsView;
WebView *conversationView;
WebView *profileView;
WebView *oauthView;
WebView *conversationView;
WebView *profileView;
WebView *oauthView;
}
@property (nonatomic, assign) WebView *timelineView;

View file

@ -16,15 +16,15 @@
- (void)webView:(WebView *)sender addMessageToConsole:(NSDictionary *)message;{
if (![message isKindOfClass:[NSDictionary class]]) return;
NSString *viewName = @"TimelineView";
if (sender == mentionsView) viewName = @"MentionsView";
if (sender == conversationView) viewName = @"ConversationView";
if (sender == oauthView) viewName = @"OauthView";
if (sender == profileView) viewName = @"ProfileView";
NSString *viewName = @"TimelineView";
if (sender == mentionsView) viewName = @"MentionsView";
if (sender == conversationView) viewName = @"ConversationView";
if (sender == oauthView) viewName = @"OauthView";
if (sender == profileView) viewName = @"ProfileView";
NSLog(@"js<%@>: %@:%@: %@",
viewName,
viewName,
[[message objectForKey:@"sourceURL"] lastPathComponent],
[message objectForKey:@"lineNumber"],
[message objectForKey:@"message"]
@ -32,103 +32,103 @@
}
- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame {
NSString *viewName = @"TimelineView";
if (sender == mentionsView) viewName = @"MentionsView";
if (sender == conversationView) viewName = @"ConversationView";
if (sender == oauthView) viewName = @"OauthView";
NSString *viewName = @"TimelineView";
if (sender == mentionsView) viewName = @"MentionsView";
if (sender == conversationView) viewName = @"ConversationView";
if (sender == oauthView) viewName = @"OauthView";
NSLog(@"jsa<%@>: %@", viewName, message);
}
- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame {
NSInteger result = NSRunCriticalAlertPanel(NSLocalizedString(@"Bungloo", @""), // title
message, // message
NSLocalizedString(@"OK", @""), // default button
NSLocalizedString(@"Cancel", @""), // alt button
nil);
return NSAlertDefaultReturn == result;
return NO;
NSInteger result = NSRunCriticalAlertPanel(NSLocalizedString(@"Bungloo", @""), // title
message, // message
NSLocalizedString(@"OK", @""), // default button
NSLocalizedString(@"Cancel", @""), // alt button
nil);
return NSAlertDefaultReturn == result;
return NO;
}
- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id <WebPolicyDecisionListener>)listener {
[listener ignore];
[[NSWorkspace sharedWorkspace] openURL:[request URL]];
[[NSWorkspace sharedWorkspace] openURL:[request URL]];
}
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *pathToJsPlugin = [@"~/Library/Application Support/bungloo/Plugin.js" stringByExpandingTildeInPath];
NSString *pathToCssPlugin = [@"~/Library/Application Support/bungloo/Plugin.css" stringByExpandingTildeInPath];
if([fileManager fileExistsAtPath:pathToCssPlugin])
{
[sender stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"setTimeout(function() { loadCssPlugin('file://localhost%@') }, 1000);", pathToCssPlugin]];
}
if([fileManager fileExistsAtPath:pathToJsPlugin])
{
[sender stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"setTimeout(function() { loadJsPlugin('file://localhost%@') }, 1000);", pathToJsPlugin]];
}
[sender stringByEvaluatingJavaScriptFromString:@"var OS_TYPE = 'mac';"];
if (sender == oauthView) {
[oauthView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('oauth') }"];
if([fileManager fileExistsAtPath:pathToCssPlugin])
{
[sender stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"setTimeout(function() { loadCssPlugin('file://localhost%@') }, 1000);", pathToCssPlugin]];
}
} else if(sender == conversationView) {
[conversationView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('conversation') }"];
} else if(sender == profileView) {
[profileView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('profile') }"];
} else {
NSString *action = @"timeline";
NSString *delay = @"1";
if (sender == mentionsView) {
action = @"mentions";
delay = @"1000";
}
[sender stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"function HostAppGo() { start('%@') }", action]];
}
if([fileManager fileExistsAtPath:pathToJsPlugin])
{
[sender stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"setTimeout(function() { loadJsPlugin('file://localhost%@') }, 1000);", pathToJsPlugin]];
}
[sender stringByEvaluatingJavaScriptFromString:@"var OS_TYPE = 'mac';"];
if (sender == oauthView) {
[oauthView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('oauth') }"];
} else if(sender == conversationView) {
[conversationView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('conversation') }"];
} else if(sender == profileView) {
[profileView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('profile') }"];
} else {
NSString *action = @"timeline";
NSString *delay = @"1";
if (sender == mentionsView) {
action = @"mentions";
delay = @"1000";
}
[sender stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"function HostAppGo() { start('%@') }", action]];
}
}
- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems
{
// FIXME
/*
NSMutableArray *menuItems = [NSMutableArray arrayWithArray:defaultMenuItems];
for (NSMenuItem*item in defaultMenuItems) {
if ([[item title] isEqualToString:@"Reload"]) {
//[item setAction:@selector(reload:)];
//[item setTarget:self];
} else {
[menuItems addObject:item];
}
}*/
return defaultMenuItems;
// FIXME
/*
NSMutableArray *menuItems = [NSMutableArray arrayWithArray:defaultMenuItems];
for (NSMenuItem*item in defaultMenuItems) {
if ([[item title] isEqualToString:@"Reload"]) {
//[item setAction:@selector(reload:)];
//[item setTarget:self];
} else {
[menuItems addObject:item];
}
}*/
return defaultMenuItems;
}
- (void)reload:(id)sender {
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData();"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData();"];
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData();"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData();"];
}
- (NSString *)pluginURL
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *pathToPlugin = [@"~/Library/Application Support/Bungloo/Plugin.js" stringByExpandingTildeInPath];
if([fileManager fileExistsAtPath:pathToPlugin])
{
if([fileManager fileExistsAtPath:pathToPlugin])
{
return [NSString stringWithFormat:@"%@", [NSURL fileURLWithPath:pathToPlugin]];
}
return nil;

View file

@ -10,5 +10,5 @@
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **) argv);
return NSApplicationMain(argc, (const char **) argv);
}

View file

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Bungloo's Changelog</title>
<link>http://jabs.nu/Bungloo/download/Appcast.xml</link>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>Version 1.0.0</title>
<channel>
<title>Bungloo's Changelog</title>
<link>http://jabs.nu/Bungloo/download/Appcast.xml</link>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>Version 1.0.0</title>
<sparkle:minimumSystemVersion>10.5.0</sparkle:minimumSystemVersion>
<sparkle:releaseNotesLink>http://jabs.nu/bungloo/download/ReleaseNotes.html</sparkle:releaseNotesLink>
<pubDate>Mon, 11 Feb 2013 00:29:41 +0100</pubDate>
@ -15,6 +15,6 @@
length="1101694"
type="application/octet-stream"
sparkle:dsaSignature="MCwCFB1JIQINycvbZblob0PHy6Be1nVzAhQ2zkoVqoOjJsDjcnZYjI1qY7oX1Q==" />
</item>
</channel>
</item>
</channel>
</rss>

View file

@ -1,5 +1,4 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!DOCTYPE html>
<html>
<head>
<title>Tentia Release Notes</title>
@ -8,8 +7,8 @@
h1 { font-size: 1.2em; }
h2 { font-size: 1em; margin-top: 2em; }
hr { margin: 2em 0; }
p { margin: 0; padding: 0; }
strong { color: red; }
p { margin: 0; padding: 0; }
strong { color: red; }
</style>
</head>
<body>
@ -175,7 +174,7 @@
<p>Moved reply icon to left so it is easier to use when the scrollbar is shown</p>
<p>Login with the [Login] button now works</p>
<p>Fixed automatic updates so it will work next time again.</p>
<hr />
<h1>Tentia 0.2.0</h2>
@ -192,15 +191,15 @@
<p>Mentions now appear as realnames</p>
<hr />
<h1>Tentia 0.1.1</h1>
<p>Bugfixes</p>
<p>Changed to send on Cmd+Enter.</p>
<hr />
<h1>Tentia 0.1.0</h1>
<p>First attempt to rewrite the old Twitter client Twittia to a new and shiny Tent client Tentia.</p>
</body>
</html>

View file

@ -2,10 +2,10 @@
require 'time'
def test var, message
unless var
puts message
exit
end
unless var
puts message
exit
end
end
path = File.dirname File.expand_path(__FILE__)
@ -28,13 +28,13 @@ end
xml = <<XML
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Bungloo's Changelog</title>
<link>http://jabs.nu/Bungloo/download/Appcast.xml</link>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>Version #{version}</title>
<channel>
<title>Bungloo's Changelog</title>
<link>http://jabs.nu/Bungloo/download/Appcast.xml</link>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>Version #{version}</title>
<sparkle:minimumSystemVersion>10.5.0</sparkle:minimumSystemVersion>
<sparkle:releaseNotesLink>http://jabs.nu/bungloo/download/ReleaseNotes.html</sparkle:releaseNotesLink>
<pubDate>#{Time.now.rfc2822}</pubDate>
@ -43,8 +43,8 @@ xml = <<XML
length="#{length}"
type="application/octet-stream"
sparkle:dsaSignature="#{signature}" />
</item>
</channel>
</item>
</channel>
</rss>
XML