if( nib_main_loaded ) return;
[self initStrings];
- [o_window setExcludedFromWindowsMenu: TRUE];
- [o_msgs_panel setExcludedFromWindowsMenu: TRUE];
+
+ [o_window setExcludedFromWindowsMenu: YES];
+ [o_msgs_panel setExcludedFromWindowsMenu: YES];
[o_msgs_panel setDelegate: self];
i_key = config_GetInt( p_intf, "key-quit" );
nib_main_loaded = TRUE;
}
+#pragma mark Toolbar delegate
+/* Our item identifiers */
+static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl";
+
+- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
+{
+ return [NSArray arrayWithObjects:
+// NSToolbarCustomizeToolbarItemIdentifier,
+// NSToolbarFlexibleSpaceItemIdentifier,
+// NSToolbarSpaceItemIdentifier,
+// NSToolbarSeparatorItemIdentifier,
+ VLCToolbarMediaControl,
+ nil ];
+}
+
+- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar
+{
+ return [NSArray arrayWithObjects:
+ VLCToolbarMediaControl,
+ nil ];
+}
+
+- (NSToolbarItem *) toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
+{
+ NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease];
+
+
+ if( [itemIdentifier isEqual: VLCToolbarMediaControl] )
+ {
+ [toolbarItem setLabel:@"Media Controls"];
+ [toolbarItem setPaletteLabel:@"Media Controls"];
+
+ NSSize size = toolbarMediaControl.frame.size;
+ [toolbarItem setView:toolbarMediaControl];
+ [toolbarItem setMinSize:size];
+ size.width += 1000.;
+ [toolbarItem setMaxSize:size];
+
+ // Hack: For some reason we need to make sure
+ // that the those element are on top
+ // Add them again will put them frontmost
+ [toolbarMediaControl addSubview:o_scrollfield];
+ [toolbarMediaControl addSubview:o_timeslider];
+ [toolbarMediaControl addSubview:o_timefield];
+ [toolbarMediaControl addSubview:o_main_pgbar];
+
+ /* TODO: setup a menu */
+ }
+ else
+ {
+ /* itemIdentifier referred to a toolbar item that is not
+ * provided or supported by us or Cocoa
+ * Returning nil will inform the toolbar
+ * that this kind of item is not supported */
+ toolbarItem = nil;
+ }
+ return toolbarItem;
+}
+
+#pragma mark -
+
- (void)controlTintChanged
{
BOOL b_playing = NO;
- (void)initStrings
{
- [o_window setTitle: _NS("VLC - Controller")];
+ [o_window setTitle: _NS("VLC")];
[self setScrollField:_NS("VLC media player") stopAfter:-1];
/* button controls */
/* Handle sleep notification */
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(computerWillSleep:)
name:NSWorkspaceWillSleepNotification object:nil];
+
+ [self performSelectorInBackground:@selector(lookForCrashLog) withObject:NULL];
}
/* Listen to the remote in exclusive mode, only when VLC is the active
/* TODO: fix i_size use */
b_plmul = p_playlist->items.i_size > 1;
- p_input = vlc_object_find( p_playlist, VLC_OBJECT_INPUT,
- FIND_CHILD );
-
+ p_input = playlist_CurrentInput( p_playlist );
+ bool b_buffering = NO;
+
if( ( b_input = ( p_input != NULL ) ) )
{
+ /* seekable streams */
+ int state = input_GetState( p_input );
+ if ( state == INIT_S ||
+ state == OPENING_S ||
+ state == BUFFERING_S )
+ {
+ b_buffering = YES;
+ }
+
/* seekable streams */
b_seekable = var_GetBool( p_input, "seekable" );
}
pl_Release( p_intf );
+ if( b_buffering )
+ {
+ [o_main_pgbar startAnimation:self];
+ [o_main_pgbar setIndeterminate:YES];
+ [o_main_pgbar setHidden:NO];
+ }
+ else
+ {
+ [o_main_pgbar stopAnimation:self];
+ [o_main_pgbar setHidden:YES];
+ }
+
[o_btn_stop setEnabled: b_input];
[o_btn_ff setEnabled: b_seekable];
[o_btn_rewind setEnabled: b_seekable];
[[NSWorkspace sharedWorkspace] openURL: o_url];
}
-- (IBAction)openCrashLog:(id)sender
+#pragma mark Crash Log
+- (void)mailCrashLog:(NSString *)crashLog withUserComment:(NSString *)userComment
+{
+ static char mail[] =
+ "From: vlcuser <vlcuser@videolan.org>\n"
+ "To: VideoLAN Crash Report <apple-bugreport@videolan.org>\n"
+ "Subject: %@\n"
+ "Content-Type: text/plain; charset=ISO-8859-1; format=flowed\n"
+ "Content-Transfer-Encoding: 7bit\n"
+ "\n"
+ "%@\n\n"
+ "User Comment:\n%@\n--------------\n"
+ "\n"
+ "Crash log:\n%@\n--------------\n"
+ "\n"
+ "\n";
+ NSString * mailPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"vlc_crash_mail.eml"];
+ NSString * mailContent = [NSString stringWithFormat:[NSString stringWithUTF8String:mail],
+ _NS("Crash Report (Type Command-shift-D and hit send)"),
+ _NS("Type Command-shift-D (or in Menu \"Message\">\"Send Again\") and hit the \"Send Mail\" button."),
+ userComment, crashLog];
+ BOOL ret = [mailContent writeToFile:mailPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
+ if( !ret )
+ {
+ NSRunAlertPanel(_NS("Error when generating crash report mail."), _NS("Can't prepare crash log mail"), _NS("OK"), nil, nil, nil );
+ return;
+ }
+
+ [[NSWorkspace sharedWorkspace] openFile:mailPath];
+}
+
+
+- (NSString *)latestCrashLogPathPreviouslySeen:(BOOL)previouslySeen
+{
+ NSString * crashReporter = [@"~/Library/Logs/CrashReporter" stringByExpandingTildeInPath];
+ NSDirectoryEnumerator *direnum = [[NSFileManager defaultManager] enumeratorAtPath:crashReporter];
+ NSString *fname;
+ NSString * latestLog = nil;
+ NSInteger year = !previouslySeen ? [[NSUserDefaults standardUserDefaults] integerForKey:@"LatestCrashReportYear"] : 0;
+ NSInteger month = !previouslySeen ? [[NSUserDefaults standardUserDefaults] integerForKey:@"LatestCrashReportMonth"]: 0;
+ NSInteger day = !previouslySeen ? [[NSUserDefaults standardUserDefaults] integerForKey:@"LatestCrashReportDay"] : 0;
+ NSInteger hours = !previouslySeen ? [[NSUserDefaults standardUserDefaults] integerForKey:@"LatestCrashReportHours"]: 0;
+
+ while (fname = [direnum nextObject])
+ {
+ [direnum skipDescendents];
+ if([fname hasPrefix:@"VLC"] && [fname hasSuffix:@"crash"])
+ {
+ NSArray * compo = [fname componentsSeparatedByString:@"_"];
+ if( [compo count] < 3 ) continue;
+ compo = [[compo objectAtIndex:1] componentsSeparatedByString:@"-"];
+ if( [compo count] < 4 ) continue;
+
+ // Dooh. ugly.
+ if( year < [[compo objectAtIndex:0] intValue] ||
+ (year ==[[compo objectAtIndex:0] intValue] &&
+ (month < [[compo objectAtIndex:1] intValue] ||
+ (month ==[[compo objectAtIndex:1] intValue] &&
+ (day < [[compo objectAtIndex:2] intValue] ||
+ (day ==[[compo objectAtIndex:2] intValue] &&
+ hours < [[compo objectAtIndex:3] intValue] ))))))
+ {
+ year = [[compo objectAtIndex:0] intValue];
+ month = [[compo objectAtIndex:1] intValue];
+ day = [[compo objectAtIndex:2] intValue];
+ hours = [[compo objectAtIndex:3] intValue];
+ latestLog = [crashReporter stringByAppendingPathComponent:fname];
+ }
+ }
+ }
+
+ if(!(latestLog && [[NSFileManager defaultManager] fileExistsAtPath:latestLog]))
+ return nil;
+
+ if( !previouslySeen )
+ {
+ [[NSUserDefaults standardUserDefaults] setInteger:year forKey:@"LatestCrashReportYear"];
+ [[NSUserDefaults standardUserDefaults] setInteger:month forKey:@"LatestCrashReportMonth"];
+ [[NSUserDefaults standardUserDefaults] setInteger:day forKey:@"LatestCrashReportDay"];
+ [[NSUserDefaults standardUserDefaults] setInteger:hours forKey:@"LatestCrashReportHours"];
+ }
+ return latestLog;
+}
+
+- (NSString *)latestCrashLogPath
{
- NSString * o_path = [@"~/Library/Logs/CrashReporter/VLC.crash.log"
- stringByExpandingTildeInPath];
+ return [self latestCrashLogPathPreviouslySeen:YES];
+}
+- (void)lookForCrashLog
+{
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
- if( [[NSFileManager defaultManager] fileExistsAtPath: o_path ] )
+ // This pref key doesn't exists? this VLC is an upgrade, and this crash log come from previous version
+ BOOL areCrashLogsTooOld = ![[NSUserDefaults standardUserDefaults] integerForKey:@"LatestCrashReportYear"];
+ NSString * latestLog = [self latestCrashLogPathPreviouslySeen:NO];
+ if( latestLog && !areCrashLogsTooOld )
+ [self performSelectorOnMainThread:@selector(notifyCrashLogToUser:) withObject:latestLog waitUntilDone:NO];
+
+ [pool release];
+}
+
+- (void)notifyCrashLogToUser:(NSString *)crashLogPath
+{
+ int ret = NSRunInformationalAlertPanel(_NS("VLC has previously crashed"),
+ _NS("VLC has previously crashed, do you want to send an email with the crash to VLC's team?"),
+ _NS("Send"), _NS("Don't Send"), nil, nil);
+ if( ret == NSAlertDefaultReturn )
{
- [[NSWorkspace sharedWorkspace] openFile: o_path
- withApplication: @"Console"];
+ [self mailCrashLog:[NSString stringWithContentsOfFile:crashLogPath] withUserComment:_NS("<Explain here what you were doing when VLC crashed, with possibly a link to the failing video>")];
+ }
+}
+
+- (IBAction)openCrashLog:(id)sender
+{
+ NSString * latestLog = [self latestCrashLogPath];
+ if( latestLog )
+ {
+ [[NSWorkspace sharedWorkspace] openFile: latestLog withApplication: @"Console"];
}
else
{
NSBeginInformationalAlertSheet(_NS("No CrashLog found"), _NS("Continue"), nil, nil, o_msgs_panel, self, NULL, NULL, nil, _NS("Couldn't find any trace of a previous crash.") );
-
}
}
+#pragma mark -
+
- (IBAction)viewErrorsAndWarnings:(id)sender
{
[[[self getInteractionList] getErrorPanel] showPanel];