Commit 155ea0e4 authored by Felix Paul Kühne's avatar Felix Paul Kühne

* new CheckForUpdate panel (closes #310)

- the actual download is currently done by your default browser since the needed notification window isn't available on OSX yet
    - download through VLC is implemented, but commented for the moment
- needs some checking once a complete Status.xml is available
parent 8ca8d346
......@@ -194,6 +194,9 @@ EXTRA_DIST += \
extras/MacOSX/Resources/English.lproj/SFilters.nib/classes.nib \
extras/MacOSX/Resources/English.lproj/SFilters.nib/info.nib \
extras/MacOSX/Resources/English.lproj/SFilters.nib/keyedobjects.nib \
extras/MacOSX/Resources/English.lproj/Update.nib/classes.nib \
extras/MacOSX/Resources/English.lproj/Update.nib/info.nib \
extras/MacOSX/Resources/English.lproj/Update.nib/keyedobjects.nib \
extras/MacOSX/Resources/English.lproj/InfoPlist.strings \
extras/MacOSX/Resources/a52.icns \
extras/MacOSX/Resources/aac.icns \
......
......@@ -113,6 +113,7 @@
},
{
ACTIONS = {
checkForUpdate = id;
clearRecentItems = id;
closeError = id;
intfOpenDisc = id;
......@@ -171,6 +172,7 @@
"o_mi_bwd" = id;
"o_mi_channels" = id;
"o_mi_chapter" = id;
"o_mi_checkForUpdate" = id;
"o_mi_clear" = id;
"o_mi_close_window" = id;
"o_mi_controller" = id;
......
......@@ -21,11 +21,11 @@
<array/>
<key>IBOpenObjects</key>
<array>
<integer>2197</integer>
<integer>29</integer>
<integer>21</integer>
<integer>2197</integer>
</array>
<key>IBSystem Version</key>
<string>8G32</string>
<string>8H14</string>
</dict>
</plist>
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
ACTIONS = {download = id; okay = id; };
CLASS = VLCUpdate;
LANGUAGE = ObjC;
OUTLETS = {
"o_bar_checking" = id;
"o_btn_DownloadNow" = id;
"o_btn_okay" = id;
"o_fld_currentVersionAndSize" = id;
"o_fld_releaseNote" = id;
"o_fld_status" = id;
"o_update_window" = id;
};
SUPERCLASS = NSObject;
}
);
IBVersion = 1;
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>19 61 356 240 0 0 1440 878 </string>
<key>IBFramework Version</key>
<string>443.0</string>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>8H14</string>
</dict>
</plist>
......@@ -72,6 +72,7 @@
C2F2A707095AE51700018C74 /* play_embedded_blue.png in Resources */ = {isa = PBXBuildFile; fileRef = C2F2A703095AE51600018C74 /* play_embedded_blue.png */; };
C2F2A708095AE51700018C74 /* skip_forward_embedded_blue.png in Resources */ = {isa = PBXBuildFile; fileRef = C2F2A704095AE51600018C74 /* skip_forward_embedded_blue.png */; };
C2F2A709095AE51700018C74 /* skip_previous_embedded_blue.png in Resources */ = {isa = PBXBuildFile; fileRef = C2F2A705095AE51600018C74 /* skip_previous_embedded_blue.png */; };
CC26BF2C09A7A05000E94D62 /* Update.nib in Resources */ = {isa = PBXBuildFile; fileRef = CC26BF2A09A7A05000E94D62 /* Update.nib */; };
CCF3C64C0923B99D00401862 /* SFilters.nib in Resources */ = {isa = PBXBuildFile; fileRef = CCF3C64A0923B99D00401862 /* SFilters.nib */; };
DC7F46ED08A183FC0027DB24 /* Extended.nib in Resources */ = {isa = PBXBuildFile; fileRef = DC7F46EB08A183FC0027DB24 /* Extended.nib */; };
DCA00AA9075F948800E6BF46 /* About.nib in Resources */ = {isa = PBXBuildFile; fileRef = DCA00AA7075F948800E6BF46 /* About.nib */; };
......@@ -868,7 +869,6 @@
8E9CC7B1046EFD700059A3A7 /* THANKS */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = text; name = THANKS; path = ../../THANKS; sourceTree = SOURCE_ROOT; };
8EBF3FA303F13FFB0059A3A7 /* vlc.scriptSuite */ = {isa = PBXFileReference; lastKnownFileType = text; name = vlc.scriptSuite; path = Resources/vlc.scriptSuite; sourceTree = SOURCE_ROOT; };
8EBF3FA503F140960059A3A7 /* vlc.scriptTerminology */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = vlc.scriptTerminology; path = Resources/vlc.scriptTerminology; sourceTree = SOURCE_ROOT; };
8ED6C27A03E2EB1C0059A3A7 /* coreaudio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = coreaudio.c; path = ../../modules/audio_output/coreaudio.c; sourceTree = SOURCE_ROOT; };
8ED6C27B03E2EB1C0059A3A7 /* controls.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = controls.m; path = ../../modules/gui/macosx/controls.m; sourceTree = SOURCE_ROOT; };
8ED6C27C03E2EB1C0059A3A7 /* intf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = intf.h; path = ../../modules/gui/macosx/intf.h; sourceTree = SOURCE_ROOT; };
8ED6C27D03E2EB1C0059A3A7 /* intf.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = intf.m; path = ../../modules/gui/macosx/intf.m; sourceTree = SOURCE_ROOT; };
......@@ -897,6 +897,11 @@
C2F2A703095AE51600018C74 /* play_embedded_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = play_embedded_blue.png; path = Resources/play_embedded_blue.png; sourceTree = "<group>"; };
C2F2A704095AE51600018C74 /* skip_forward_embedded_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = skip_forward_embedded_blue.png; path = Resources/skip_forward_embedded_blue.png; sourceTree = "<group>"; };
C2F2A705095AE51600018C74 /* skip_previous_embedded_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = skip_previous_embedded_blue.png; path = Resources/skip_previous_embedded_blue.png; sourceTree = "<group>"; };
CC26BF2B09A7A05000E94D62 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = Resources/English.lproj/Update.nib; sourceTree = "<group>"; };
CC26BF3109A7A08C00E94D62 /* update.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = update.h; path = ../../modules/gui/macosx/update.h; sourceTree = SOURCE_ROOT; };
CC26BF3209A7A08C00E94D62 /* update.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = update.m; path = ../../modules/gui/macosx/update.m; sourceTree = SOURCE_ROOT; };
CC26BF3309A7A0A300E94D62 /* interaction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = interaction.h; path = ../../modules/gui/macosx/interaction.h; sourceTree = SOURCE_ROOT; };
CC26BF3409A7A0A300E94D62 /* interaction.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = interaction.m; path = ../../modules/gui/macosx/interaction.m; sourceTree = SOURCE_ROOT; };
CCF3C64B0923B99D00401862 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = Resources/English.lproj/SFilters.nib; sourceTree = "<group>"; };
CCF3C6500923B9D100401862 /* sfilters.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sfilters.h; path = ../../modules/gui/macosx/sfilters.h; sourceTree = SOURCE_ROOT; };
CCF3C6510923B9D100401862 /* sfilters.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = sfilters.m; path = ../../modules/gui/macosx/sfilters.m; sourceTree = SOURCE_ROOT; };
......@@ -981,6 +986,8 @@
8ED6C27E03E2EB1C0059A3A7 /* macosx.m */,
8ED6C27C03E2EB1C0059A3A7 /* intf.h */,
8ED6C27D03E2EB1C0059A3A7 /* intf.m */,
CC26BF3309A7A0A300E94D62 /* interaction.h */,
CC26BF3409A7A0A300E94D62 /* interaction.m */,
8E6BC6FA041684EC0059A3A7 /* controls.h */,
8ED6C27B03E2EB1C0059A3A7 /* controls.m */,
8E6BC6F6041643860059A3A7 /* applescript.h */,
......@@ -1003,7 +1010,6 @@
8E55FB800459B0FD00FB3317 /* output.m */,
2A16E03F06C4F08700C87B09 /* equalizer.h */,
2A16E04006C4F08700C87B09 /* equalizer.m */,
8ED6C27A03E2EB1C0059A3A7 /* coreaudio.c */,
8ED6C28703E2EB1C0059A3A7 /* vout.h */,
8ED6C28803E2EB1C0059A3A7 /* vout.m */,
8E9CA1A506D7DEE800B7186C /* voutgl.m */,
......@@ -1016,6 +1022,8 @@
DCE7BD0608A5724D007B10AE /* bookmarks.m */,
CCF3C6500923B9D100401862 /* sfilters.h */,
CCF3C6510923B9D100401862 /* sfilters.m */,
CC26BF3109A7A08C00E94D62 /* update.h */,
CC26BF3209A7A08C00E94D62 /* update.m */,
);
name = Classes;
sourceTree = "<group>";
......@@ -1135,6 +1143,7 @@
DC7F46EB08A183FC0027DB24 /* Extended.nib */,
DCE7BD0308A56C8B007B10AE /* Bookmarks.nib */,
CCF3C64A0923B99D00401862 /* SFilters.nib */,
CC26BF2A09A7A05000E94D62 /* Update.nib */,
);
name = nibs;
sourceTree = "<group>";
......@@ -1247,6 +1256,7 @@
C2F2A707095AE51700018C74 /* play_embedded_blue.png in Resources */,
C2F2A708095AE51700018C74 /* skip_forward_embedded_blue.png in Resources */,
C2F2A709095AE51700018C74 /* skip_previous_embedded_blue.png in Resources */,
CC26BF2C09A7A05000E94D62 /* Update.nib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -1263,6 +1273,14 @@
/* End PBXRezBuildPhase section */
/* Begin PBXVariantGroup section */
CC26BF2A09A7A05000E94D62 /* Update.nib */ = {
isa = PBXVariantGroup;
children = (
CC26BF2B09A7A05000E94D62 /* English */,
);
name = Update.nib;
sourceTree = "<group>";
};
CCF3C64A0923B99D00401862 /* SFilters.nib */ = {
isa = PBXVariantGroup;
children = (
......
......@@ -97,7 +97,7 @@ struct intf_sys_t
id o_embedded_list; /* VLCEmbeddedList*/
id o_interaction_list; /* VLCInteractionList*/
id o_sfilters; /* VLCsFilters */
/*id o_update; VLCUpdate */
id o_update; /* VLCUpdate */
BOOL nib_main_loaded; /* reference to the main-nib */
BOOL nib_open_loaded; /* reference to the open-nib */
BOOL nib_about_loaded; /* reference to the about-nib */
......@@ -105,7 +105,7 @@ struct intf_sys_t
BOOL nib_extended_loaded; /* reference to the extended-nib */
BOOL nib_bookmarks_loaded; /* reference to the bookmarks-nib */
BOOL nib_sfilters_loaded; /* reference to the sfilters-nib */
/*BOOL nib_update_loaded; reference to the update-nib */
BOOL nib_update_loaded; /* reference to the update-nib */
IBOutlet id o_window; /* main window */
IBOutlet id o_playlist_view;/* playlist view */
......@@ -155,7 +155,7 @@ struct intf_sys_t
IBOutlet id o_mi_about;
IBOutlet id o_mi_prefs;
/*IBOutlet id o_mi_checkForUpdate;*/
IBOutlet id o_mi_checkForUpdate;
IBOutlet id o_mi_add_intf;
IBOutlet id o_mu_add_intf;
IBOutlet id o_mi_services;
......@@ -319,7 +319,7 @@ struct intf_sys_t
- (IBAction)viewAbout:(id)sender;
- (IBAction)viewPreferences:(id)sender;
/*- (IBAction)checkForUpdate:(id)sender;*/
- (IBAction)checkForUpdate:(id)sender;
- (IBAction)closeError:(id)sender;
- (IBAction)openReadMe:(id)sender;
- (IBAction)openDocumentation:(id)sender;
......
......@@ -44,7 +44,7 @@
#include "sfilters.h"
#include "interaction.h"
#include "embeddedwindow.h"
/*#include "update.h"*/
#include "update.h"
/*****************************************************************************
* Local prototypes.
......@@ -327,7 +327,7 @@ static VLCMain *_o_sharedMainInstance = nil;
o_embedded_list = [[VLCEmbeddedList alloc] init];
o_interaction_list = [[VLCInteractionList alloc] init];
o_sfilters = nil;
/*o_update = [[VLCUpdate alloc] init];*/
o_update = [[VLCUpdate alloc] init];
i_lastShownVolume = -1;
return _o_sharedMainInstance;
......@@ -486,7 +486,7 @@ static VLCMain *_o_sharedMainInstance = nil;
/* main menu */
[o_mi_about setTitle: [_NS("About VLC media player") \
stringByAppendingString: @"..."]];
/* [o_mi_checkForUpdate setTitle: _NS("Check for Update...")];*/
[o_mi_checkForUpdate setTitle: _NS("Check for Update...")];
[o_mi_prefs setTitle: _NS("Preferences...")];
[o_mi_add_intf setTitle: _NS("Add Interface")];
[o_mu_add_intf setTitle: _NS("Add Interface")];
......@@ -1638,7 +1638,7 @@ static VLCMain *_o_sharedMainInstance = nil;
[o_prefs showPrefs];
}
/*- (IBAction)checkForUpdate:(id)sender
- (IBAction)checkForUpdate:(id)sender
{
if (!nib_update_loaded)
{
......@@ -1647,7 +1647,7 @@ static VLCMain *_o_sharedMainInstance = nil;
} else {
[o_update showUpdateWindow];
}
}*/
}
- (IBAction)closeError:(id)sender
{
......
/*****************************************************************************
* update.h: MacOS X Check-For-Update window
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
* $Id$
*
* Authors: Felix Khne <fkuehne@users.sf.net>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <vlc_update.h>
@interface VLCUpdate : NSObject
{
IBOutlet id o_btn_DownloadNow;
IBOutlet id o_btn_okay;
IBOutlet id o_fld_releaseNote;
IBOutlet id o_fld_source;
IBOutlet id o_fld_currentVersionAndSize;
IBOutlet id o_fld_status;
IBOutlet id o_update_window;
IBOutlet id o_bar_checking;
IBOutlet id o_lbl_checkForUpdate;
NSString * o_hashOfOurBinary;
NSString * o_urlOfBinary;
update_t * p_u;
}
- (IBAction)download:(id)sender;
- (IBAction)okay:(id)sender;
- (void)showUpdateWindow;
- (void)initStrings;
- (void)checkForUpdate;
- (void)performDownload:(NSString *)path;
+ (VLCUpdate *)sharedInstance;
@end
/*****************************************************************************
* update.m: MacOS X Check-For-Update window
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
* $Id$
*
* Authors: Felix Khne <fkuehne@users.sf.net>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Note: the code used to communicate with VLC's core was inspired by
* ../wxwidgets/dialogs/updatevlc.cpp, written by Antoine Cellerier.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#import "update.h"
#import "intf.h"
/*****************************************************************************
* VLCExtended implementation
*****************************************************************************/
@implementation VLCUpdate
static VLCUpdate *_o_sharedInstance = nil;
+ (VLCUpdate *)sharedInstance
{
return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
}
- (id)init
{
if (_o_sharedInstance) {
[self dealloc];
} else {
_o_sharedInstance = [super init];
}
return _o_sharedInstance;
}
- (void)awakeFromNib
{
/* clean the interface */
[o_fld_releaseNote setString: @""];
[self initStrings];
}
- (void)dealloc
{
if( o_hashOfOurBinary )
[o_hashOfOurBinary release];
if( o_urlOfBinary )
[o_urlOfBinary release];
[super dealloc];
}
- (void)initStrings
{
/* translate strings to the user's language */
[o_update_window setTitle: _NS("Check for update")];
[o_btn_DownloadNow setTitle: _NS("Download now")];
[o_btn_okay setTitle: _NS("OK")];
}
- (void)showUpdateWindow
{
/* show the window and check for a potential update */
[o_fld_status setStringValue: _NS("Checking for Update...")];
[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];
[o_lbl_checkForUpdate setHidden: YES];
}
- (IBAction)download:(id)sender
{
/* enable the following once full notification support is available
* 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:nil modalForWindow: \
o_update_window modalDelegate:self didEndSelector:sel contextInfo:nil];*/
/* delete this afterwards */
[self performDownload: @""];
}
- (void)getLocationForSaving: (NSSavePanel *)sheet returnCode: \
(int)returnCode contextInfo: (void *)contextInfo
{
if (returnCode == NSOKButton)
{
/* perform download and pass the selected path */
[self performDownload: [sheet filename]];
}
[sheet release];
}
- (IBAction)okay:(id)sender
{
/* just close the window */
[o_update_window close];
}
- (void)checkForUpdate
{
p_u = update_New( VLCIntf );
update_Check( p_u, VLC_FALSE );
update_iterator_t *p_uit = update_iterator_New( p_u );
BOOL releaseChecked = NO;
int x = 0;
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 )
{
/* 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 )
{
[o_fld_releaseNote setString: \
[NSString stringWithUTF8String: \
(p_uit->file.psz_description)]];
}
else if( p_uit->file.i_type == UPDATE_FILE_TYPE_BINARY )
{
msg_Dbg( VLCIntf, "binary found, version = %s" \
", hash=%s", p_uit->release.psz_version, \
p_uit->file.psz_md5 );
[o_fld_currentVersionAndSize setStringValue: \
[NSString stringWithFormat: \
@"The current release is %s (%i MB to download).", \
p_uit->release.psz_version, p_uit->file.l_size]];
if( o_urlOfBinary )
[o_urlOfBinary release];
o_urlOfBinary = [[NSString alloc] initWithUTF8String: \
p_uit->file.psz_url];
/* save the hash of our file, if available */
if( p_uit->file.psz_md5 )
{
if( o_hashOfOurBinary )
[o_hashOfOurBinary release];
o_hashOfOurBinary = [[NSString alloc] \
initWithUTF8String: p_uit->file.psz_md5];
}
}
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("Your version of VLC " \
"is outdated.")];
[o_btn_DownloadNow setEnabled: YES];
msg_Dbg( VLCIntf, "this version of VLC is outdated" );
/* put the mirror information */
msg_Dbg( VLCIntf, "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("Your version of VLC " \
"is up-to-date.")];
[o_btn_DownloadNow setEnabled: NO];
msg_Dbg( VLCIntf, "current version is up-to-date" );
releaseChecked = YES;
}
}
x += 1;
}
update_iterator_Delete( p_uit );
}
}
- (void)performDownload:(NSString *)path
{
/* enable this once notifications are completely available on OSX
update_iterator_t *p_uit = update_iterator_New( p_u );
if( p_uit )
{
update_iterator_Action( p_uit, UPDATE_MIRROR );
int i_count = 0;
while( update_iterator_Action( p_uit, UPDATE_FILE ) != UPDATE_FAIL )
{
if( p_uit->file.psz_url == [o_hashOfOurBinary UTF8String] )
break;
i_count += 1;
}
update_download( p_uit, (char *)[path UTF8String] );
update_iterator_Delete( p_uit );
}*/
/* delete the following afterwards */
msg_Dbg( VLCIntf, "url is %s, using default browser for download", \
[o_urlOfBinary UTF8String] );
NSURL * o_url = [NSURL URLWithString: o_urlOfBinary];
[[NSWorkspace sharedWorkspace] openURL: o_url];
[o_update_window close];
}
@end
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