| 1 | // |
|---|
| 2 | // SUUpdatePermissionPrompt.m |
|---|
| 3 | // Sparkle |
|---|
| 4 | // |
|---|
| 5 | // Created by Andy Matuschak on 1/24/08. |
|---|
| 6 | // Copyright 2008 Andy Matuschak. All rights reserved. |
|---|
| 7 | // |
|---|
| 8 | |
|---|
| 9 | #import "SUUpdatePermissionPrompt.h" |
|---|
| 10 | |
|---|
| 11 | #import "SUHost.h" |
|---|
| 12 | |
|---|
| 13 | @implementation SUUpdatePermissionPrompt |
|---|
| 14 | |
|---|
| 15 | - (BOOL)shouldAskAboutProfile |
|---|
| 16 | { |
|---|
| 17 | return [[host objectForInfoDictionaryKey:SUEnableSystemProfilingKey] boolValue]; |
|---|
| 18 | } |
|---|
| 19 | |
|---|
| 20 | - (id)initWithHost:(SUHost *)aHost systemProfile:(NSArray *)profile delegate:(id)d |
|---|
| 21 | { |
|---|
| 22 | self = [super initWithHost:aHost windowNibName:@"SUUpdatePermissionPrompt"]; |
|---|
| 23 | if (self) |
|---|
| 24 | { |
|---|
| 25 | host = [aHost retain]; |
|---|
| 26 | delegate = d; |
|---|
| 27 | isShowingMoreInfo = NO; |
|---|
| 28 | shouldSendProfile = [self shouldAskAboutProfile]; |
|---|
| 29 | systemProfileInformationArray = [profile retain]; |
|---|
| 30 | [self setShouldCascadeWindows:NO]; |
|---|
| 31 | } |
|---|
| 32 | return self; |
|---|
| 33 | } |
|---|
| 34 | |
|---|
| 35 | + (void)promptWithHost:(SUHost *)aHost systemProfile:(NSArray *)profile delegate:(id)d |
|---|
| 36 | { |
|---|
| 37 | // If this is a background application we need to focus it in order to bring the prompt |
|---|
| 38 | // to the user's attention. Otherwise the prompt would be hidden behind other applications and |
|---|
| 39 | // the user would not know why the application was paused. |
|---|
| 40 | if ([aHost isBackgroundApplication]) { [NSApp activateIgnoringOtherApps:YES]; } |
|---|
| 41 | |
|---|
| 42 | id prompt = [[[self class] alloc] initWithHost:aHost systemProfile:profile delegate:d]; |
|---|
| 43 | [NSApp runModalForWindow:[prompt window]]; |
|---|
| 44 | } |
|---|
| 45 | |
|---|
| 46 | - (NSString *)description { return [NSString stringWithFormat:@"%@ <%@>", [self class], [host bundlePath]]; } |
|---|
| 47 | |
|---|
| 48 | - (void)awakeFromNib |
|---|
| 49 | { |
|---|
| 50 | if (![self shouldAskAboutProfile]) |
|---|
| 51 | { |
|---|
| 52 | NSRect frame = [[self window] frame]; |
|---|
| 53 | frame.size.height -= [moreInfoButton frame].size.height; |
|---|
| 54 | [[self window] setFrame:frame display:YES]; |
|---|
| 55 | } |
|---|
| 56 | } |
|---|
| 57 | |
|---|
| 58 | - (void)dealloc |
|---|
| 59 | { |
|---|
| 60 | [host release]; |
|---|
| 61 | [systemProfileInformationArray release]; |
|---|
| 62 | [super dealloc]; |
|---|
| 63 | } |
|---|
| 64 | |
|---|
| 65 | - (NSImage *)icon |
|---|
| 66 | { |
|---|
| 67 | return [host icon]; |
|---|
| 68 | } |
|---|
| 69 | |
|---|
| 70 | - (NSString *)promptDescription |
|---|
| 71 | { |
|---|
| 72 | return [NSString stringWithFormat:SULocalizedString(@"Should %1$@ automatically check for updates? You can always check for updates manually from the %1$@ menu.", nil), [host name]]; |
|---|
| 73 | } |
|---|
| 74 | |
|---|
| 75 | - (IBAction)toggleMoreInfo:(id)sender |
|---|
| 76 | { |
|---|
| 77 | [self willChangeValueForKey:@"isShowingMoreInfo"]; |
|---|
| 78 | isShowingMoreInfo = !isShowingMoreInfo; |
|---|
| 79 | [self didChangeValueForKey:@"isShowingMoreInfo"]; |
|---|
| 80 | |
|---|
| 81 | NSView *contentView = [[self window] contentView]; |
|---|
| 82 | NSRect contentViewFrame = [contentView frame]; |
|---|
| 83 | NSRect windowFrame = [[self window] frame]; |
|---|
| 84 | |
|---|
| 85 | NSRect profileMoreInfoViewFrame = [moreInfoView frame]; |
|---|
| 86 | NSRect profileMoreInfoButtonFrame = [moreInfoButton frame]; |
|---|
| 87 | NSRect descriptionFrame = [descriptionTextField frame]; |
|---|
| 88 | |
|---|
| 89 | if (isShowingMoreInfo) |
|---|
| 90 | { |
|---|
| 91 | // Add the subview |
|---|
| 92 | contentViewFrame.size.height += profileMoreInfoViewFrame.size.height; |
|---|
| 93 | profileMoreInfoViewFrame.origin.y = profileMoreInfoButtonFrame.origin.y - profileMoreInfoViewFrame.size.height; |
|---|
| 94 | profileMoreInfoViewFrame.origin.x = descriptionFrame.origin.x; |
|---|
| 95 | profileMoreInfoViewFrame.size.width = descriptionFrame.size.width; |
|---|
| 96 | |
|---|
| 97 | windowFrame.size.height += profileMoreInfoViewFrame.size.height; |
|---|
| 98 | windowFrame.origin.y -= profileMoreInfoViewFrame.size.height; |
|---|
| 99 | |
|---|
| 100 | [moreInfoView setFrame:profileMoreInfoViewFrame]; |
|---|
| 101 | [moreInfoView setHidden:YES]; |
|---|
| 102 | [contentView addSubview:moreInfoView |
|---|
| 103 | positioned:NSWindowBelow |
|---|
| 104 | relativeTo:moreInfoButton]; |
|---|
| 105 | } else { |
|---|
| 106 | // Remove the subview |
|---|
| 107 | [moreInfoView setHidden:NO]; |
|---|
| 108 | [moreInfoView removeFromSuperview]; |
|---|
| 109 | contentViewFrame.size.height -= profileMoreInfoViewFrame.size.height; |
|---|
| 110 | |
|---|
| 111 | windowFrame.size.height -= profileMoreInfoViewFrame.size.height; |
|---|
| 112 | windowFrame.origin.y += profileMoreInfoViewFrame.size.height; |
|---|
| 113 | } |
|---|
| 114 | [[self window] setFrame:windowFrame display:YES animate:YES]; |
|---|
| 115 | [contentView setFrame:contentViewFrame]; |
|---|
| 116 | [contentView setNeedsDisplay:YES]; |
|---|
| 117 | [moreInfoView setHidden:(!isShowingMoreInfo)]; |
|---|
| 118 | } |
|---|
| 119 | |
|---|
| 120 | - (IBAction)finishPrompt:(id)sender |
|---|
| 121 | { |
|---|
| 122 | if (![delegate respondsToSelector:@selector(updatePermissionPromptFinishedWithResult:)]) |
|---|
| 123 | [NSException raise:@"SUInvalidDelegate" format:@"SUUpdatePermissionPrompt's delegate (%@) doesn't respond to updatePermissionPromptFinishedWithResult:!", delegate]; |
|---|
| 124 | [host setBool:shouldSendProfile forUserDefaultsKey:SUSendProfileInfoKey]; |
|---|
| 125 | [delegate updatePermissionPromptFinishedWithResult:([sender tag] == 1 ? SUAutomaticallyCheck : SUDoNotAutomaticallyCheck)]; |
|---|
| 126 | [[self window] close]; |
|---|
| 127 | [NSApp stopModal]; |
|---|
| 128 | [self autorelease]; |
|---|
| 129 | } |
|---|
| 130 | |
|---|
| 131 | @end |
|---|