X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fmacosx%2Fupdate.m;h=e111cc87ac02fcd957438dc171441598117ed11f;hb=3646783cd4862a71c0ae29ee114918cdc98fafeb;hp=ff08a8c40ac719084e8ecb3ef096c40e3b357d1d;hpb=a9b12caead48117116f3a55afcff670c05337778;p=vlc diff --git a/modules/gui/macosx/update.m b/modules/gui/macosx/update.m index ff08a8c40a..e111cc87ac 100644 --- a/modules/gui/macosx/update.m +++ b/modules/gui/macosx/update.m @@ -1,10 +1,11 @@ /***************************************************************************** * update.m: MacOS X Check-For-Update window ***************************************************************************** - * Copyright (C) 2005-2006 the VideoLAN team + * Copyright © 2005-2008 the VideoLAN team * $Id$ * - * Authors: Felix KŸhne + * Authors: Felix Kühne + * Rafaël Carré * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,19 +22,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ +#import "update.h" -/***************************************************************************** - * Note: the code used to communicate with VLC's core was inspired by - * ../wxwidgets/dialogs/updatevlc.cpp, written by Antoine Cellerier. - *****************************************************************************/ +#ifdef UPDATE_CHECK +#include /***************************************************************************** * Preamble *****************************************************************************/ -#import "update.h" -#import "intf.h" +static NSString * kPrefUpdateOnStartup = @"UpdateOnStartup"; +static NSString * kPrefUpdateLastTimeChecked = @"UpdateLastTimeChecked"; /***************************************************************************** * VLCExtended implementation @@ -50,10 +50,20 @@ static VLCUpdate *_o_sharedInstance = nil; - (id)init { - if (_o_sharedInstance) { + if( _o_sharedInstance ) { [self dealloc]; } else { _o_sharedInstance = [super init]; + b_checked = false; + + /* clean the interface */ + [o_fld_releaseNote setString: @""]; + [o_fld_currentVersion setString: @""]; + /* translate strings to the user's language */ + [o_update_window setTitle: _NS("Check for Updates")]; + [o_btn_DownloadNow setTitle: _NS("Download now")]; + [o_btn_okay setTitle: _NS("OK")]; + [o_chk_updateOnStartup setTitle: _NS("Automatically check for updates")]; } return _o_sharedInstance; @@ -61,45 +71,58 @@ static VLCUpdate *_o_sharedInstance = nil; - (void)awakeFromNib { - /* get up */ - p_intf = VLCIntf; - - /* clean the interface */ - [o_fld_releaseNote setString: @""]; - - [self initStrings]; + /* we don't use - (BOOL)shouldCheckUpdateOnStartup because we don't want + * the Alert panel to pop up at this time */ + [o_chk_updateOnStartup setState: [[NSUserDefaults standardUserDefaults] boolForKey: kPrefUpdateOnStartup]]; } -- (void)dealloc +- (void)setShouldCheckUpdate: (BOOL)check { - if( o_urlOfBinary ) - [o_urlOfBinary release]; - - [super dealloc]; + [[NSUserDefaults standardUserDefaults] setBool: check forKey: kPrefUpdateOnStartup]; + [o_chk_updateOnStartup setState: check]; } -- (void)initStrings +- (BOOL)shouldCheckForUpdate { - /* translate strings to the user's language */ - [o_update_window setTitle: _NS("Check for Updates")]; - [o_btn_DownloadNow setTitle: _NS("Download now")]; - [o_btn_okay setTitle: _NS("OK")]; + NSDate *o_last_update; + NSDate *o_next_update; + + if( ![[NSUserDefaults standardUserDefaults] objectForKey: kPrefUpdateOnStartup] ) + { + /* We don't have any preferences stored, ask the user. */ + int res = NSRunInformationalAlertPanel( _NS("Do you want VLC to check for updates automatically?"), + _NS("You can change this option in VLC's update window later on."), _NS("Yes"), _NS("No"), nil ); + [self setShouldCheckUpdate: res]; + } + + if( ![[NSUserDefaults standardUserDefaults] boolForKey: kPrefUpdateOnStartup] ) + return NO; + + o_last_update = [[NSUserDefaults standardUserDefaults] objectForKey: kPrefUpdateLastTimeChecked]; + if( !o_last_update ) + return YES; + + o_next_update = [[[NSDate alloc] initWithTimeInterval: 60*60*24*2 /* every two days */ sinceDate: o_last_update] autorelease]; + if( !o_next_update ) + return YES; + + return [o_next_update compare: [NSDate date]] == NSOrderedAscending; } - (void)showUpdateWindow { /* show the window and check for a potential update */ - [o_fld_status setStringValue: _NS("Checking for Updates...")]; - [o_fld_currentVersionAndSize setStringValue: @""]; - [o_fld_releaseNote setString: @""]; - [o_update_window center]; [o_update_window displayIfNeeded]; [o_update_window makeKeyAndOrderFront:nil]; - [o_bar_checking startAnimation: self]; - [self checkForUpdate]; - [o_bar_checking stopAnimation: self]; + if( !b_checked ) + { + [o_bar_checking startAnimation: self]; + [self checkForUpdate]; + b_checked = true; + [o_bar_checking stopAnimation: self]; + } } - (IBAction)download:(id)sender @@ -107,20 +130,25 @@ static VLCUpdate *_o_sharedInstance = nil; /* provide a save dialogue */ SEL sel = @selector(getLocationForSaving:returnCode:contextInfo:); NSSavePanel * saveFilePanel = [[NSSavePanel alloc] init]; - + [saveFilePanel setRequiredFileType: @"dmg"]; [saveFilePanel setCanSelectHiddenExtension: YES]; [saveFilePanel setCanCreateDirectories: YES]; - [saveFilePanel beginSheetForDirectory:nil file: \ - [[o_urlOfBinary componentsSeparatedByString:@"/"] lastObject] \ - modalForWindow: o_update_window modalDelegate:self didEndSelector:sel \ - contextInfo:nil]; + update_release_t *p_release = update_GetRelease( p_u ); + assert( p_release ); + [saveFilePanel beginSheetForDirectory:nil file: + [[[NSString stringWithUTF8String: p_release->psz_url] componentsSeparatedByString:@"/"] lastObject] + modalForWindow: o_update_window + modalDelegate:self + didEndSelector:sel + contextInfo:nil]; } -- (void)getLocationForSaving: (NSSavePanel *)sheet returnCode: \ - (int)returnCode contextInfo: (void *)contextInfo +- (void)getLocationForSaving: (NSSavePanel *)sheet + returnCode: (int)returnCode + contextInfo: (void *)contextInfo { - if (returnCode == NSOKButton) + if( returnCode == NSOKButton ) { /* perform download and pass the selected path */ [self performDownload: [sheet filename]]; @@ -130,168 +158,67 @@ static VLCUpdate *_o_sharedInstance = nil; - (IBAction)okay:(id)sender { - /* just close the window */ - [o_update_window close]; + /* just hides the window */ + [o_update_window orderOut: self]; } -- (void)checkForUpdate +- (IBAction)changeCheckUpdateOnStartup:(id)sender { - p_u = update_New( p_intf ); - update_Check( p_u, VLC_FALSE ); - update_iterator_t *p_uit = update_iterator_New( p_u ); - BOOL releaseChecked = NO; - BOOL gettingReleaseNote = NO; - int x = 0; - NSString * pathToReleaseNote; - pathToReleaseNote = [NSString stringWithFormat: \ - @"/tmp/vlc_releasenote_%d.tmp", mdate()]; - - if( p_uit ) - { - p_uit->i_rs = UPDATE_RELEASE_STATUS_NEWER; - p_uit->i_t = UPDATE_FILE_TYPE_ALL; - update_iterator_Action( p_uit, UPDATE_MIRROR ); - - while( update_iterator_Action( p_uit, UPDATE_FILE) != UPDATE_FAIL ) - { - msg_Dbg( p_intf, "parsing available updates, run %i", x ); - /* if the announced item is of the type "binary", keep it and display - * its details to the user. Do similar stuff on "info". Do both - * only if the file is announced as stable */ - if( p_uit->release.i_type == UPDATE_RELEASE_TYPE_STABLE ) - { - if( p_uit->file.i_type == UPDATE_FILE_TYPE_INFO ) - { - msg_Dbg( p_intf, "release note found, desc = %s", - p_uit->file.psz_description ); - [o_fld_releaseNote setString: \ - [NSString stringWithUTF8String: \ - (p_uit->file.psz_description)]]; - /* download our release note - * We will read the temp file after this loop */ - update_download( p_uit, (char *)[pathToReleaseNote UTF8String] ); - gettingReleaseNote = YES; - } - else if( p_uit->file.i_type == UPDATE_FILE_TYPE_BINARY ) - { - msg_Dbg( p_intf, "binary found, version = %s, " \ - "url=%s, size=%i MB", p_uit->release.psz_version, \ - p_uit->file.psz_url, \ - (int)((p_uit->file.l_size / 1024) / 1024) ); - [o_fld_currentVersionAndSize setStringValue: [NSString \ - stringWithFormat: \ - _NS("The latest VLC media player release " \ - "is %s (%i MB to download)."), \ - p_uit->release.psz_version, ((p_uit->file.l_size \ - / 1024) / 1024)]]; - - if( o_urlOfBinary ) - [o_urlOfBinary release]; - o_urlOfBinary = [[NSString alloc] initWithUTF8String: \ - p_uit->file.psz_url]; - } - if( p_uit->release.i_status == UPDATE_RELEASE_STATUS_NEWER && - !releaseChecked ) - { - /* our version is outdated, let the user download the new - * release */ - [o_fld_status setStringValue: _NS("This version of VLC " \ - "is outdated.")]; - [o_btn_DownloadNow setEnabled: YES]; - msg_Dbg( p_intf, "this version of VLC is outdated" ); - /* put the mirror information */ - msg_Dbg( p_intf, "used mirror: %s, %s [%s]", \ - p_uit->mirror.psz_name, p_uit->mirror.psz_location,\ - p_uit->mirror.psz_type ); - /* make sure that we perform this check only once */ - releaseChecked = YES; - } - else if(! releaseChecked ) - { - [o_fld_status setStringValue: _NS("This version of VLC " \ - "is latest available.")]; - [o_btn_DownloadNow setEnabled: NO]; - msg_Dbg( p_intf, "current version is up-to-date" ); - releaseChecked = YES; - } - } - x += 1; - } - - update_iterator_Delete( p_uit ); - - /* wait for our release notes if necessary, since the download is done - * by another thread -- this does usually take 300000 to 500000 ms */ - if( gettingReleaseNote ) - { - int i = 0; - while( [[NSFileManager defaultManager] fileExistsAtPath: pathToReleaseNote] == NO ) - { - msleep( 100000 ); - i += 1; - if( i == 150 ) - { - /* if this takes more than 15 sec, exit */ - msg_Warn( p_intf, "download took more than 15 sec, exiting" ); - break; - } - } - msg_Dbg( p_intf, "waited %i ms for the release notes", (i * 100000) ); - msleep( 500000 ); - - /* let's open our cached release note and display it - * we can't use NSString stringWithContentsOfFile:encoding:error: - * since it is Tiger only */ - NSString * releaseNote = [[NSString alloc] initWithData: \ - [NSData dataWithContentsOfFile: pathToReleaseNote] \ - encoding: NSISOLatin1StringEncoding]; - if( releaseNote ) - [o_fld_releaseNote setString: releaseNote]; - - /* delete the file since it isn't needed anymore */ - BOOL myBOOL = NO; - myBOOL = [[NSFileManager defaultManager] removeFileAtPath: \ - pathToReleaseNote handler: nil]; - } - else - { - /* don't confuse the user, but make her happy */ - [o_fld_status setStringValue: _NS("This version of VLC " \ - "is latest available.")]; - [o_btn_DownloadNow setEnabled: NO]; - msg_Dbg( p_intf, "current version is up-to-date" ); - msg_Warn( p_intf, "retrieving current release notes failed!" ); - } - } + [self setShouldCheckUpdate: [sender state]]; } -- (void)performDownload:(NSString *)path +- (void)setUpToDate:(BOOL)uptodate { - update_iterator_t *p_uit = update_iterator_New( p_u ); - if( p_uit ) + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + if( uptodate ) + { + [o_fld_releaseNote setString: @""]; + [o_fld_currentVersion setStringValue: @""]; + [o_fld_status setStringValue: _NS("This version of VLC is the latest available.")]; + [o_btn_DownloadNow setEnabled: NO]; + } + else { - update_iterator_Action( p_uit, UPDATE_MIRROR ); - - while( update_iterator_Action( p_uit, UPDATE_FILE) != UPDATE_FAIL ) - { - if( p_uit->release.i_type == UPDATE_RELEASE_TYPE_STABLE && - p_uit->release.i_status == UPDATE_RELEASE_STATUS_NEWER && - p_uit->file.i_type == UPDATE_FILE_TYPE_BINARY ) - { - /* put the mirror information */ - msg_Dbg( p_intf, "used mirror: %s, %s [%s]", \ - p_uit->mirror.psz_name, p_uit->mirror.psz_location, \ - p_uit->mirror.psz_type ); - - /* that's our binary */ - update_download( p_uit, (char *)[path UTF8String] ); - } - } - - update_iterator_Delete( p_uit ); + update_release_t *p_release = update_GetRelease( p_u ); + [o_fld_releaseNote setString: [NSString stringWithUTF8String: (p_release->psz_desc ? p_release->psz_desc : "" )]]; + [o_fld_status setStringValue: _NS("This version of VLC is outdated.")]; + [o_fld_currentVersion setStringValue: [NSString stringWithFormat: + _NS("The current release is %d.%d.%d%c."), p_release->i_major, + p_release->i_minor, p_release->i_revision, p_release->extra]]; + [o_btn_DownloadNow setEnabled: YES]; + /* Make sure the update window is showed in case we have something */ + [o_update_window center]; + [o_update_window displayIfNeeded]; + [o_update_window makeKeyAndOrderFront: self]; } - [o_update_window close]; + [pool release]; +} + +static void updateCallback( void * p_data, bool b_success ) +{ + [(id)p_data setUpToDate: !b_success || !update_NeedUpgrade( ((VLCUpdate*)p_data)->p_u )]; +} + +- (void)checkForUpdate +{ + p_u = update_New( VLCIntf ); + if( !p_u ) + return; + update_Check( p_u, updateCallback, self ); + + [[NSUserDefaults standardUserDefaults] setObject: [NSDate date] forKey: kPrefUpdateLastTimeChecked]; +} + +- (void)performDownload:(NSString *)path +{ + update_Download( p_u, [path UTF8String] ); + [o_btn_DownloadNow setEnabled: NO]; + [o_update_window orderOut: self]; + update_Delete( p_u ); } @end + +#endif