Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added delegate that can implement custom feedback reporting.

If the delegate is given to OpenFeedback object, it is sent a message before sending feedback. The delegate can return NO to indicate it did or will report feedback itself using arbitrary protocol. In such way, OFSubmitFeedbackURL key can be ommited from info.plist.
  • Loading branch information...
commit 6e0dc4fcd207f4c03d6a1bf6bfa64856fcfc8de1 1 parent 1328134
@tomaz tomaz authored committed
View
9 OFController.h
@@ -10,6 +10,8 @@
#import <AddressBook/AddressBook.h>
#import "OFUtilities.h"
+@protocol OpenFeedbackDelegate;
+
@interface OFController : NSWindowController {
// Fake Tab Control
IBOutlet NSSegmentedControl *tabs;
@@ -42,6 +44,10 @@
IBOutlet NSProgressIndicator *piStatus;
IBOutlet NSButton *btnSend;
BOOL _crashReportMode;
+
+ // Miscellaneous
+ id openFeedback;
+ id<OpenFeedbackDelegate> delegate;
}
- (IBAction)presentFeedbackPanelForSupport:(id)sender;
@@ -57,4 +63,7 @@
- (IBAction)sendFeedback:(id)sender;
NSString *urlEscape(NSString *str);
+@property (assign) id openFeedback;
+@property (assign) id<OpenFeedbackDelegate> delegate;
+
@end
View
43 OFController.m
@@ -6,6 +6,7 @@
// Copyright 2009 Click On Tyler, LLC. All rights reserved.
//
+#import "OpenFeedback.h"
#import "OFController.h"
@interface OFController ()
@@ -159,19 +160,21 @@ - (void) populateEmailAddresses
- (IBAction)sendFeedback:(id)sender
{
+ BOOL delegateCanHandle = (self.delegate != nil);
+
// Grab the URL to submit to...
NSDictionary *infoPlist = [[NSBundle mainBundle] infoDictionary];
NSString *submitFeedbackURL = [infoPlist objectForKey:@"OFSubmitFeedbackURL"];
- if(submitFeedbackURL == nil) {
+ if(submitFeedbackURL == nil && !delegateCanHandle) {
NSLog(@"OpenFeedback Error: You must set OFSubmitFeedbackURL in Info.plist");
return;
}
[piStatus startAnimation:self];
-
+
// Build our POST data dictionary
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
-
+
[dict setValue:OFHostAppName() forKey:@"appname"];
[dict setValue:OFHostAppVersion() forKey:@"appversion"];
[dict setValue:OFCurrentSystemVersionString() forKey:@"systemversion"];
@@ -207,7 +210,16 @@ - (IBAction)sendFeedback:(id)sender
}
break;
}
-
+
+ // Ask the delegate to handle the request. If the delegate returns NO, we should not handle request ourselves.
+ if (delegateCanHandle) {
+ if (![self.delegate openFeedback:self.openFeedback willSendData:dict]) {
+ [piStatus stopAnimation:self];
+ [[self window] close];
+ return;
+ }
+ }
+
// Flatten dict into a url query string (this needs to be tested with special characters and other character enocdings)
NSMutableArray *info = [NSMutableArray array];
NSEnumerator *e = [dict keyEnumerator];
@@ -215,7 +227,7 @@ - (IBAction)sendFeedback:(id)sender
while(key = [e nextObject]) {
[info addObject:[NSString stringWithFormat:@"%@=%@", key, urlEscape([dict valueForKey:key])]];
}
-
+
NSString *post = [info componentsJoinedByString:@"&"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
@@ -230,15 +242,6 @@ - (IBAction)sendFeedback:(id)sender
[NSURLConnection connectionWithRequest:request delegate:self];
}
-NSString *urlEscape(NSString *str)
-{
- // I doubt this is super robust, but it works for now :-)
- NSMutableString *ret = [NSMutableString stringWithString:str];
- [ret replaceOccurrencesOfString:@"&" withString:@"%26" options:NSLiteralSearch range:NSMakeRange(0, [ret length])];
- [ret replaceOccurrencesOfString:@"=" withString:@"%3d" options:NSLiteralSearch range:NSMakeRange(0, [ret length])];
- return ret;
-}
-
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[piStatus stopAnimation:self];
@@ -276,4 +279,16 @@ - (void)sheetDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(voi
}
}
+NSString *urlEscape(NSString *str)
+{
+ // I doubt this is super robust, but it works for now :-)
+ NSMutableString *ret = [NSMutableString stringWithString:str];
+ [ret replaceOccurrencesOfString:@"&" withString:@"%26" options:NSLiteralSearch range:NSMakeRange(0, [ret length])];
+ [ret replaceOccurrencesOfString:@"=" withString:@"%3d" options:NSLiteralSearch range:NSMakeRange(0, [ret length])];
+ return ret;
+}
+
+@synthesize openFeedback;
+@synthesize delegate;
+
@end
View
8 OpenFeedback.h
@@ -9,14 +9,22 @@
#import <Cocoa/Cocoa.h>
@class OFController;
+@class OpenFeedback;
+
+@protocol OpenFeedbackDelegate
+- (BOOL)openFeedback:(OpenFeedback *)feedback willSendData:(NSDictionary *)data;
+@end
@interface OpenFeedback : NSObject {
OFController *windowController;
+ id delegate;
}
- (IBAction)presentFeedbackPanelForSupport:(id)sender;
- (IBAction)presentFeedbackPanelForFeature:(id)sender;
- (IBAction)presentFeedbackPanelForBug:(id)sender;
- (void)presentFeedbackPanelIfCrashed;
+@property (assign) id<OpenFeedbackDelegate> delegate;
@end
+
View
7 OpenFeedback.m
@@ -38,20 +38,24 @@ - (void)awakeFromNib
path = [framework pathForResource:@"OpenFeedback" ofType:@"nib"];
}
windowController = [[OFController alloc] initWithWindowNibName:@"OpenFeedback"];
+ windowController.openFeedback = self;
}
- (IBAction)presentFeedbackPanelForSupport:(id)sender
{
+ windowController.delegate = self.delegate;
[windowController presentFeedbackPanelForSupport:self];
}
- (IBAction)presentFeedbackPanelForFeature:(id)sender
{
+ windowController.delegate = self.delegate;
[windowController presentFeedbackPanelForFeature:self];
}
- (IBAction)presentFeedbackPanelForBug:(id)sender
{
+ windowController.delegate = self.delegate;
[windowController presentFeedbackPanelForBug:self];
}
@@ -61,11 +65,14 @@ - (void)presentFeedbackPanelIfCrashed
if ([logs count] > 0)
{
NSString *report = [self latestCrashLogContents:logs];
+ windowController.openFeedback = self;
[windowController presentFeedbackPanelForCrash:report];
}
self.lastCrashCheckTime = [NSDate date];
}
+@synthesize delegate;
+
@end
#pragma mark -
View
1  OpenFeedback.xcodeproj/project.pbxproj
@@ -332,6 +332,7 @@
FRAMEWORK_VERSION = A;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_OBJC_GC = supported;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
Please sign in to comment.
Something went wrong with that request. Please try again.