X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fmacosx%2Fplaylistinfo.m;h=16a51c3350d643c436c4d151c84925b9c93af400;hb=8fecaa83ebb0d4e3ecb4f684598abd8419fb3764;hp=0208aaf63107b0bc4dd31193feb1164fb5c56962;hpb=d0d0541e004aae6cc99c76f4d9d01070f6de0799;p=vlc diff --git a/modules/gui/macosx/playlistinfo.m b/modules/gui/macosx/playlistinfo.m index 0208aaf631..16a51c3350 100644 --- a/modules/gui/macosx/playlistinfo.m +++ b/modules/gui/macosx/playlistinfo.m @@ -1,11 +1,11 @@ /***************************************************************************** r playlistinfo.m: MacOS X interface module ***************************************************************************** - * Copyright (C) 2002-2007 the VideoLAN team + * Copyright (C) 2002-2008 the VideoLAN team * $Id$ * * Authors: Benjamin Pracht - * Felix Kühne + * Felix Paul Kühne * * 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 @@ -36,182 +36,272 @@ @implementation VLCInfo -- (id)init +static VLCInfo *_o_sharedInstance = nil; + ++ (VLCInfo *)sharedInstance { - self = [super init]; + return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init]; +} - if( self != nil ) - { - p_item = NULL; - o_statUpdateTimer = nil; +- (id)init +{ + if( _o_sharedInstance ) { + [self dealloc]; + } else { + _o_sharedInstance = [super init]; + + if( _o_sharedInstance != nil ) + { + p_item = NULL; + o_statUpdateTimer = nil; + [self updatePanelWithItem: NULL]; + rootItem = [[VLCInfoTreeItem alloc] init]; + } } - return( self ); + + return _o_sharedInstance; } - (void)awakeFromNib { [o_info_window setExcludedFromWindowsMenu: TRUE]; - [o_info_window setTitle: _NS("Information")]; - [o_uri_lbl setStringValue: _NS("URI")]; + [o_info_window setTitle: _NS("Media Information")]; + [o_uri_lbl setStringValue: _NS("Location")]; [o_title_lbl setStringValue: _NS("Title")]; - [o_author_lbl setStringValue: _NS("Author")]; - [o_btn_ok setTitle: _NS("OK")]; - [o_btn_cancel setTitle: _NS("Cancel")]; - + [o_author_lbl setStringValue: _NS("Artist")]; + [o_saveMetaData_btn setStringValue: _NS("Save Metadata" )]; + [[o_tab_view tabViewItemAtIndex: 0] setLabel: _NS("General")]; - [[o_tab_view tabViewItemAtIndex: 1] setLabel: _NS("Advanced Information")]; + [[o_tab_view tabViewItemAtIndex: 1] setLabel: _NS("Codec Details")]; [[o_tab_view tabViewItemAtIndex: 2] setLabel: _NS("Statistics")]; [o_tab_view selectTabViewItemAtIndex: 0]; /* constants defined in vlc_meta.h */ [o_genre_lbl setStringValue: _NS(VLC_META_GENRE)]; [o_copyright_lbl setStringValue: _NS(VLC_META_COPYRIGHT)]; - [o_collection_lbl setStringValue: _NS(VLC_META_COLLECTION)]; - [o_seqNum_lbl setStringValue: _NS(VLC_META_SEQ_NUM)]; + [o_collection_lbl setStringValue: _NS(VLC_META_ALBUM)]; + [o_seqNum_lbl setStringValue: _NS(VLC_META_TRACK_NUMBER)]; [o_description_lbl setStringValue: _NS(VLC_META_DESCRIPTION)]; - [o_rating_lbl setStringValue: _NS(VLC_META_RATING)]; [o_date_lbl setStringValue: _NS(VLC_META_DATE)]; [o_language_lbl setStringValue: _NS(VLC_META_LANGUAGE)]; [o_nowPlaying_lbl setStringValue: _NS(VLC_META_NOW_PLAYING)]; [o_publisher_lbl setStringValue: _NS(VLC_META_PUBLISHER)]; - + /* statistics */ [o_input_box setTitle: _NS("Input")]; [o_read_bytes_lbl setStringValue: _NS("Read at media")]; [o_input_bitrate_lbl setStringValue: _NS("Input bitrate")]; [o_demux_bytes_lbl setStringValue: _NS("Demuxed")]; [o_demux_bitrate_lbl setStringValue: _NS("Stream bitrate")]; - + [o_video_box setTitle: _NS("Video")]; [o_video_decoded_lbl setStringValue: _NS("Decoded blocks")]; [o_displayed_lbl setStringValue: _NS("Displayed frames")]; [o_lost_frames_lbl setStringValue: _NS("Lost frames")]; [o_fps_lbl setStringValue: _NS("Frames per Second")]; - + [o_sout_box setTitle: _NS("Streaming")]; [o_sent_packets_lbl setStringValue: _NS("Sent packets")]; [o_sent_bytes_lbl setStringValue: _NS("Sent bytes")]; [o_sent_bitrate_lbl setStringValue: _NS("Send rate")]; - + [o_audio_box setTitle: _NS("Audio")]; [o_audio_decoded_lbl setStringValue: _NS("Decoded blocks")]; [o_played_abuffers_lbl setStringValue: _NS("Played buffers")]; [o_lost_abuffers_lbl setStringValue: _NS("Lost buffers")]; + + [o_info_window setInitialFirstResponder: o_uri_txt]; + [o_info_window setDelegate: self]; + + /* We may be awoken from nib way after initialiwation + * Update ourselves */ + [self updatePanelWithItem:p_item]; } -- (void)dealloc +- (void)stopTimers { /* make sure that the timer is released in any case */ - if( [o_statUpdateTimer isValid] ) + if( o_statUpdateTimer && [o_statUpdateTimer isValid] ) [o_statUpdateTimer invalidate]; - if ( o_statUpdateTimer ) - [o_statUpdateTimer release]; + [rootItem release]; - [super dealloc]; -} - -- (IBAction)togglePlaylistInfoPanel:(id)sender -{ - if( [o_info_window isVisible] ) - { - [self windowShouldClose: nil]; - [o_info_window orderOut: sender]; - } - else - { - p_item = [[[VLCMain sharedInstance] getPlaylist] selectedPlaylistItem]; - [self initPanel:sender]; - } + [o_statUpdateTimer release]; + o_statUpdateTimer = nil; } -- (IBAction)toggleInfoPanel:(id)sender +- (void)dealloc { - if( [o_info_window isVisible] ) - { - [self windowShouldClose: nil]; - [o_info_window orderOut: sender]; - } - else - { - intf_thread_t * p_intf = VLCIntf; - playlist_t * p_playlist = pl_Yield( p_intf ); + /* make sure that the timer is released in any case */ + if( o_statUpdateTimer && [o_statUpdateTimer isValid] ) + [o_statUpdateTimer invalidate]; - p_item = p_playlist->status.p_item; - vlc_object_release( p_playlist ); - - [self initPanel:sender]; - } + [o_statUpdateTimer release]; + + if( p_item ) vlc_gc_decref( p_item ); + + [super dealloc]; } -- (void)initPanel:(id)sender +- (void)windowDidBecomeKey:(NSNotification *)notification { BOOL b_stats = config_GetInt(VLCIntf, "stats"); if( b_stats ) { + if( o_statUpdateTimer ) + { + [o_statUpdateTimer invalidate]; + [o_statUpdateTimer release]; + o_statUpdateTimer = nil; + } o_statUpdateTimer = [NSTimer scheduledTimerWithTimeInterval: 1 target: self selector: @selector(updateStatistics:) userInfo: nil repeats: YES]; [o_statUpdateTimer fire]; [o_statUpdateTimer retain]; } - else +} + +- (BOOL)windowShouldClose:(id)sender +{ + if( [o_statUpdateTimer isValid] ) + [o_statUpdateTimer invalidate]; + + if( o_statUpdateTimer ) + [o_statUpdateTimer release]; + o_statUpdateTimer = nil; + return YES; +} + +- (void)initPanel +{ + BOOL b_stats = config_GetInt(VLCIntf, "stats"); + if( !b_stats ) { if( [o_tab_view numberOfTabViewItems] > 2 ) [o_tab_view removeTabViewItem: [o_tab_view tabViewItemAtIndex: 2]]; } - [self updatePanel]; - [o_info_window makeKeyAndOrderFront: sender]; + [self initMediaPanelStats]; + [o_info_window makeKeyAndOrderFront: self]; } -- (void)updatePanel +- (void)initMediaPanelStats { - /* make sure that we got the current item and not an outdated one */ - intf_thread_t * p_intf = VLCIntf; - playlist_t * p_playlist = pl_Yield( p_intf ); + //Initializing Input Variables + [o_read_bytes_txt setStringValue: [NSString stringWithFormat:@"%8.0f kB", (float)0]]; + [o_input_bitrate_txt setStringValue: [NSString stringWithFormat:@"%6.0f kb/s", (float)0]]; + [o_demux_bytes_txt setStringValue: [NSString stringWithFormat:@"%8.0f kB", (float)0]]; + [o_demux_bitrate_txt setStringValue: [NSString stringWithFormat:@"%6.0f kb/s", (float)0]]; + + //Initializing Video Variables + [o_video_decoded_txt setIntValue:0]; + [o_displayed_txt setIntValue:0]; + [o_lost_frames_txt setIntValue:0]; + [o_fps_txt setFloatValue:0]; + + //Initializing Output Variables + [o_sent_packets_txt setIntValue: 0]; + [o_sent_bytes_txt setStringValue: [NSString stringWithFormat:@"%8.0f kB", (float)0]]; + [o_sent_bitrate_txt setStringValue: [NSString stringWithFormat:@"%6.0f kb/s", (float)0]]; + + //Initializing Audio Variables + [o_audio_decoded_txt setIntValue:0]; + [o_played_abuffers_txt setIntValue: 0]; + [o_lost_abuffers_txt setIntValue: 0]; - p_item = p_playlist->status.p_item; - vlc_object_release( p_playlist ); +} - /* check whether our item is valid, because we would crash if not */ - if(! [self isItemInPlaylist: p_item] ) return; +- (void)updatePanelWithItem:(input_item_t *)_p_item; +{ + if( _p_item != p_item ) + { + if( p_item ) vlc_gc_decref( p_item ); + [o_saveMetaData_btn setEnabled: NO]; + if( _p_item ) vlc_gc_incref( _p_item ); + p_item = _p_item; + } - /* fill uri info */ - char *psz_uri = input_item_GetURI( p_item->p_input ); - if( psz_uri ) + if( !p_item ) { - [o_uri_txt setStringValue: [NSString stringWithUTF8String:psz_uri]]; + /* Erase */ + #define SET( foo ) \ + [self setMeta: "" forLabel: o_##foo##_txt]; + SET( uri ); + SET( title ); + SET( author ); + SET( collection ); + SET( seqNum ); + SET( genre ); + SET( copyright ); + SET( publisher ); + SET( nowPlaying ); + SET( language ); + SET( date ); + SET( description ); + #undef SET + [o_image_well setImage: [NSImage imageNamed: @"noart.png"]]; + } + else + { + if( !input_item_IsPreparsed( p_item ) ) + { + playlist_t * p_playlist = pl_Yield( VLCIntf ); + playlist_PreparseEnqueue( p_playlist, p_item ); + pl_Release( VLCIntf ); + } + + /* fill uri info */ + char * psz_url = input_item_GetURI( p_item ); + [o_uri_txt setStringValue: [NSString stringWithUTF8String: psz_url ? psz_url : "" ]]; + free( psz_url ); + + /* fill title info */ + char * psz_title = input_item_GetTitle( p_item ); + if( !psz_title ) + psz_title = input_item_GetName( p_item ); + [o_title_txt setStringValue: [NSString stringWithUTF8String: psz_title ? : "" ]]; + free( psz_title ); + + #define SET( foo, bar ) \ + char *psz_##foo = input_item_Get##bar ( p_item ); \ + [self setMeta: psz_##foo forLabel: o_##foo##_txt]; \ + FREENULL( psz_##foo ); + + /* fill the other fields */ + SET( author, Artist ); + SET( collection, Album ); + SET( seqNum, TrackNum ); + SET( genre, Genre ); + SET( copyright, Copyright ); + SET( publisher, Publisher ); + SET( nowPlaying, NowPlaying ); + SET( language, Language ); + SET( date, Date ); + SET( description, Description ); + + #undef SET + + char *psz_meta; + NSImage *o_image; + psz_meta = input_item_GetArtURL( p_item ); + if( psz_meta && !strncmp( psz_meta, "file://", 7 ) ) + o_image = [[NSImage alloc] initWithContentsOfFile: [NSString stringWithUTF8String: psz_meta+7]]; + else + o_image = [[NSImage imageNamed: @"noart.png"] retain]; + [o_image_well setImage: o_image]; + [o_image release]; + FREENULL( psz_meta ); } - free( psz_uri ); - -#define SET( foo, bar ) \ - char *psz_##foo = input_item_Get##bar ( p_item->p_input ); \ - [self setMeta: psz_##foo forLabel: o_##foo##_txt]; \ - free( psz_##foo ); - - /* fill the other fields */ - SET( title, Title ); - SET( author, Artist ); - SET( collection, Album ); - SET( seqNum, TrackNum ); - SET( genre, Genre ); - SET( copyright, Copyright ); - SET( rating, Rating ); - SET( publisher, Publisher ); - SET( nowPlaying, NowPlaying ); - SET( language, Language ); - SET( date, Date ); - -#undef SET /* reload the advanced table */ - [[VLCInfoTreeItem rootItem] refresh]; + [rootItem refresh]; [o_outline_view reloadData]; /* update the stats once to display p_item change faster */ [self updateStatistics: nil]; + } - (void)setMeta: (char *)psz_meta forLabel: (id)theItem @@ -219,119 +309,127 @@ if( psz_meta != NULL && *psz_meta) [theItem setStringValue: [NSString stringWithUTF8String:psz_meta]]; else - [theItem setStringValue: @"-"]; + [theItem setStringValue: @""]; } - (void)updateStatistics:(NSTimer*)theTimer { - if( [self isItemInPlaylist: p_item] ) + if( !p_item || !p_item->p_stats ) { - /* we can only do that if there's a valid input around */ - - vlc_mutex_lock( &p_item->p_input->p_stats->lock ); - - /* input */ - [o_read_bytes_txt setStringValue: [NSString stringWithFormat: - @"%8.0f kB", (float)(p_item->p_input->p_stats->i_read_bytes)/1000]]; - [o_input_bitrate_txt setStringValue: [NSString stringWithFormat: - @"%6.0f kb/s", (float)(p_item->p_input->p_stats->f_input_bitrate)*8000]]; - [o_demux_bytes_txt setStringValue: [NSString stringWithFormat: - @"%8.0f kB", (float)(p_item->p_input->p_stats->i_demux_read_bytes)/1000]]; - [o_demux_bitrate_txt setStringValue: [NSString stringWithFormat: - @"%6.0f kb/s", (float)(p_item->p_input->p_stats->f_demux_bitrate)*8000]]; - - /* Video */ - [o_video_decoded_txt setStringValue: [NSString stringWithFormat: @"%5i", - p_item->p_input->p_stats->i_decoded_video]]; - [o_displayed_txt setStringValue: [NSString stringWithFormat: @"%5i", - p_item->p_input->p_stats->i_displayed_pictures]]; - [o_lost_frames_txt setStringValue: [NSString stringWithFormat: @"%5i", - p_item->p_input->p_stats->i_lost_pictures]]; - - /* Sout */ - [o_sent_packets_txt setStringValue: [NSString stringWithFormat: @"%5i", - p_item->p_input->p_stats->i_sent_packets]]; - [o_sent_bytes_txt setStringValue: [NSString stringWithFormat: @"%8.0f kB", - (float)(p_item->p_input->p_stats->i_sent_bytes)/1000]]; - [o_sent_bitrate_txt setStringValue: [NSString stringWithFormat: - @"%6.0f kb/s", (float)(p_item->p_input->p_stats->f_send_bitrate*8)*1000]]; - - /* Audio */ - [o_audio_decoded_txt setStringValue: [NSString stringWithFormat: @"%5i", - p_item->p_input->p_stats->i_decoded_audio]]; - [o_played_abuffers_txt setStringValue: [NSString stringWithFormat: @"%5i", - p_item->p_input->p_stats->i_played_abuffers]]; - [o_lost_abuffers_txt setStringValue: [NSString stringWithFormat: @"%5i", - p_item->p_input->p_stats->i_lost_abuffers]]; - - vlc_mutex_unlock( &p_item->p_input->p_stats->lock ); + [self initMediaPanelStats]; + return; } + + vlc_mutex_lock( &p_item->p_stats->lock ); + + /* input */ + [o_read_bytes_txt setStringValue: [NSString stringWithFormat: + @"%8.0f kB", (float)(p_item->p_stats->i_read_bytes)/1000]]; + [o_input_bitrate_txt setStringValue: [NSString stringWithFormat: + @"%6.0f kb/s", (float)(p_item->p_stats->f_input_bitrate)*8000]]; + [o_demux_bytes_txt setStringValue: [NSString stringWithFormat: + @"%8.0f kB", (float)(p_item->p_stats->i_demux_read_bytes)/1000]]; + [o_demux_bitrate_txt setStringValue: [NSString stringWithFormat: + @"%6.0f kb/s", (float)(p_item->p_stats->f_demux_bitrate)*8000]]; + + /* Video */ + [o_video_decoded_txt setIntValue: p_item->p_stats->i_decoded_video]; + [o_displayed_txt setIntValue: p_item->p_stats->i_displayed_pictures]; + [o_lost_frames_txt setIntValue: p_item->p_stats->i_lost_pictures]; + float f_fps = 0; + /* FIXME: input_Control( p_item, INPUT_GET_VIDEO_FPS, &f_fps ); */ + [o_fps_txt setFloatValue: f_fps]; + + /* Sout */ + [o_sent_packets_txt setIntValue: p_item->p_stats->i_sent_packets]; + [o_sent_bytes_txt setStringValue: [NSString stringWithFormat: @"%8.0f kB", + (float)(p_item->p_stats->i_sent_bytes)/1000]]; + [o_sent_bitrate_txt setStringValue: [NSString stringWithFormat: + @"%6.0f kb/s", (float)(p_item->p_stats->f_send_bitrate*8)*1000]]; + + /* Audio */ + [o_audio_decoded_txt setIntValue: p_item->p_stats->i_decoded_audio]; + [o_played_abuffers_txt setIntValue: p_item->p_stats->i_played_abuffers]; + [o_lost_abuffers_txt setIntValue: p_item->p_stats->i_lost_abuffers]; + + vlc_mutex_unlock( &p_item->p_stats->lock ); } -- (IBAction)infoCancel:(id)sender +- (IBAction)metaFieldChanged:(id)sender { - [self windowShouldClose: nil]; - [o_info_window orderOut: self]; + [o_saveMetaData_btn setEnabled: YES]; } - -- (IBAction)infoOk:(id)sender +- (IBAction)saveMetaData:(id)sender { - intf_thread_t * p_intf = VLCIntf; - playlist_t * p_playlist = pl_Yield( p_intf ); + playlist_t * p_playlist = pl_Yield( VLCIntf ); vlc_value_t val; - if( [self isItemInPlaylist: p_item] ) - { - input_item_SetName( p_item->p_input, (char*) - [[o_title_txt stringValue] UTF8String] ); - input_item_SetURI( p_item->p_input, (char*) - [[o_uri_txt stringValue] UTF8String] ); - input_item_SetArtist( p_item->p_input, (char*) - [[o_author_txt stringValue] UTF8String] ); - - val.b_bool = VLC_TRUE; - var_Set( p_playlist, "intf-change", val ); - } - vlc_object_release( p_playlist ); - [self windowShouldClose: nil]; - [o_info_window orderOut: self]; + if( !p_item ) goto error; + + meta_export_t p_export; + p_export.p_item = p_item; + + /* we can write meta data only in a file */ + vlc_mutex_lock( &p_item->lock ); + int i_type = p_item->i_type; + vlc_mutex_unlock( &p_item->lock ); + + if( i_type != ITEM_TYPE_FILE ) + goto error; + + char *psz_uri_orig = input_item_GetURI( p_item ); + char *psz_uri = psz_uri_orig; + if( !strncmp( psz_uri, "file://", 7 ) ) + psz_uri += 7; /* strlen("file://") = 7 */ + + p_export.psz_file = strndup( psz_uri, PATH_MAX ); + free( psz_uri_orig ); + + #define utf8( o_blub ) \ + [[o_blub stringValue] UTF8String] + + input_item_SetName( p_item, utf8( o_title_txt ) ); + input_item_SetTitle( p_item, utf8( o_title_txt ) ); + input_item_SetArtist( p_item, utf8( o_author_txt ) ); + input_item_SetAlbum( p_item, utf8( o_collection_txt ) ); + input_item_SetGenre( p_item, utf8( o_genre_txt ) ); + input_item_SetTrackNum( p_item, utf8( o_seqNum_txt ) ); + input_item_SetDate( p_item, utf8( o_date_txt ) ); + input_item_SetCopyright( p_item, utf8( o_copyright_txt ) ); + input_item_SetPublisher( p_item, utf8( o_publisher_txt ) ); + input_item_SetDescription( p_item, utf8( o_description_txt ) ); + input_item_SetLanguage( p_item, utf8( o_language_txt ) ); + + PL_LOCK; + p_playlist->p_private = &p_export; + + module_t *p_mod = module_Need( p_playlist, "meta writer", NULL, 0 ); + if( p_mod ) + module_Unneed( p_playlist, p_mod ); + PL_UNLOCK; + + val.b_bool = true; + var_Set( p_playlist, "intf-change", val ); + [self updatePanelWithItem: p_item]; + + pl_Release( VLCIntf ); + [o_saveMetaData_btn setEnabled: NO]; + return; + +error: + pl_Release( VLCIntf ); + NSRunAlertPanel(_NS("Error while saving meta"), + _NS("Impossible to save the meta data."), + _NS("OK"), nil, nil); } -- (playlist_item_t *)getItem +- (input_item_t *)item { + vlc_gc_incref( p_item ); return p_item; } -- (BOOL)isItemInPlaylist:(playlist_item_t *)p_local_item -{ - intf_thread_t * p_intf = VLCIntf; - playlist_t * p_playlist = pl_Yield( p_intf ); - int i; - - for( i = 0 ; i < p_playlist->all_items.i_size ; i++ ) - { - if( ARRAY_VAL( p_playlist->all_items, i ) == p_local_item ) - { - vlc_object_release( p_playlist ); - return YES; - } - } - vlc_object_release( p_playlist ); - return NO; -} - -- (BOOL)windowShouldClose:(id)sender -{ - if( [o_statUpdateTimer isValid] ) - [o_statUpdateTimer invalidate]; - - if( o_statUpdateTimer ) - [o_statUpdateTimer release]; - - return YES; -} - @end @implementation VLCInfo (NSMenuValidation) @@ -340,20 +438,12 @@ { BOOL bEnabled = TRUE; - intf_thread_t * p_intf = VLCIntf; - input_thread_t * p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, - FIND_ANYWHERE ); - if( [[o_mi title] isEqualToString: _NS("Information")] ) { - if( p_input == NULL ) - { - bEnabled = FALSE; - } + return ![[[VLCMain sharedInstance] getPlaylist] isSelectionEmpty]; } - if( p_input ) vlc_object_release( p_input ); - return( bEnabled ); + return TRUE; } @end @@ -362,7 +452,7 @@ - (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { - return (item == nil) ? [[VLCInfoTreeItem rootItem] numberOfChildren] : [item numberOfChildren]; + return (item == nil) ? [rootItem numberOfChildren] : [item numberOfChildren]; } - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { @@ -371,18 +461,18 @@ - (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item { - return (item == nil) ? [[VLCInfoTreeItem rootItem] childAtIndex:index] : (id)[item childAtIndex:index]; + return (item == nil) ? [rootItem childAtIndex:index] : (id)[item childAtIndex:index]; } - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { if ([[tableColumn identifier] isEqualToString:@"0"]) { - return (item == nil) ? @"" : (id)[item getName]; + return (item == nil) ? @"" : (id)[item name]; } else { - return (item == nil) ? @"" : (id)[item getValue]; + return (item == nil) ? @"" : (id)[item value]; } } @@ -391,11 +481,10 @@ @implementation VLCInfoTreeItem -static VLCInfoTreeItem *o_root_item = nil; - #define IsALeafNode ((id)-1) -- (id)initWithName: (NSString *)o_item_name value: (NSString *)o_item_value ID: (int)i_id parent:(VLCInfoTreeItem *)o_parent_item +- (id)initWithName: (NSString *)o_item_name value: (NSString *)o_item_value ID: (int)i_id + parent:(VLCInfoTreeItem *)o_parent_item { self = [super init]; @@ -405,24 +494,23 @@ static VLCInfoTreeItem *o_root_item = nil; o_value = [o_item_value copy]; i_object_id = i_id; o_parent = o_parent_item; - if( [[VLCMain sharedInstance] getInfo] != nil ) - p_item = [[[VLCMain sharedInstance] getInfo] getItem]; - else - p_item = NULL; + p_item = [[[VLCMain sharedInstance] getInfo] item]; + o_children = nil; } return( self ); } -+ (VLCInfoTreeItem *)rootItem { - if( o_root_item == nil ) - o_root_item = [[VLCInfoTreeItem alloc] initWithName:@"main" value: @"" ID: 0 parent:nil]; - return o_root_item; +- (id)init +{ + return [self initWithName:@"main" value:@"" ID:-1 parent:nil]; } - (void)dealloc { if( o_children != IsALeafNode ) [o_children release]; [o_name release]; + [o_value release]; + if( p_item ) vlc_gc_decref( p_item ); [super dealloc]; } @@ -430,77 +518,62 @@ static VLCInfoTreeItem *o_root_item = nil; * Loads children incrementally */ - (NSArray *)children { + if( !p_item ) return nil; + if (o_children == NULL) { int i; - if( [[[VLCMain sharedInstance] getInfo] isItemInPlaylist: p_item] ) + if( i_object_id == -1 ) { - if( self == o_root_item ) - { - vlc_mutex_lock( &p_item->p_input->lock ); - o_children = [[NSMutableArray alloc] initWithCapacity: - p_item->p_input->i_categories]; - for (i = 0 ; i < p_item->p_input->i_categories ; i++) - { - [o_children addObject:[[VLCInfoTreeItem alloc] - initWithName: [NSString stringWithUTF8String: - p_item->p_input->pp_categories[i]->psz_name] - value: @"" - ID: i - parent: self]]; - } - vlc_mutex_unlock( &p_item->p_input->lock ); - } - else if( o_parent == o_root_item ) + vlc_mutex_lock( &p_item->lock ); + o_children = [[NSMutableArray alloc] initWithCapacity: p_item->i_categories]; + for (i = 0 ; i < p_item->i_categories ; i++) { - vlc_mutex_lock( &p_item->p_input->lock ); - o_children = [[NSMutableArray alloc] initWithCapacity: - p_item->p_input->pp_categories[i_object_id]->i_infos]; - - for (i = 0 ; i < p_item->p_input->pp_categories[i_object_id]->i_infos ; i++) - { - [o_children addObject:[[VLCInfoTreeItem alloc] - initWithName: [NSString stringWithUTF8String: - p_item->p_input->pp_categories[i_object_id]->pp_infos[i]->psz_name] - value: [NSString stringWithUTF8String: - p_item->p_input->pp_categories[i_object_id]->pp_infos[i]->psz_value ? : ""] - ID: i - parent: self]]; - } - vlc_mutex_unlock( &p_item->p_input->lock ); + NSString * name = [NSString stringWithUTF8String: p_item->pp_categories[i]->psz_name]; + VLCInfoTreeItem * item = [[VLCInfoTreeItem alloc] initWithName:name value:@"" ID:i parent:self]; + [item autorelease]; + [o_children addObject:item]; } - else + vlc_mutex_unlock( &p_item->lock ); + } + else if( o_parent->i_object_id == -1 ) + { + vlc_mutex_lock( &p_item->lock ); + info_category_t * cat = p_item->pp_categories[i_object_id]; + o_children = [[NSMutableArray alloc] initWithCapacity: cat->i_infos]; + for (i = 0 ; i < cat->i_infos ; i++) { - o_children = IsALeafNode; + NSString * name = [NSString stringWithUTF8String: cat->pp_infos[i]->psz_name]; + NSString * value = [NSString stringWithUTF8String: cat->pp_infos[i]->psz_value ? : ""]; + VLCInfoTreeItem * item = [[VLCInfoTreeItem alloc] initWithName:name value:value ID:i parent:self]; + [item autorelease]; + [o_children addObject:item]; } + vlc_mutex_unlock( &p_item->lock ); + } + else + { + o_children = IsALeafNode; } } return o_children; } -- (NSString *)getName +- (NSString *)name { - return o_name; + return [[o_name retain] autorelease]; } -- (NSString *)getValue +- (NSString *)value { - return o_value; -} - -- (VLCInfoTreeItem *)childAtIndex:(int)i_index { - return [[self children] objectAtIndex:i_index]; -} - -- (int)numberOfChildren { - id i_tmp = [self children]; - return ( i_tmp == IsALeafNode ) ? (-1) : (int)[i_tmp count]; + return [[o_value retain] autorelease]; } - (void)refresh { - p_item = [[[VLCMain sharedInstance] getInfo] getItem]; + if( p_item ) vlc_gc_decref( p_item ); + p_item = [[[VLCMain sharedInstance] getInfo] item]; if( o_children != NULL ) { [o_children release]; @@ -508,5 +581,15 @@ static VLCInfoTreeItem *o_root_item = nil; } } +- (VLCInfoTreeItem *)childAtIndex:(int)i_index { + return [[self children] objectAtIndex:i_index]; +} + +- (int)numberOfChildren { + + id i_tmp = [self children]; + return ( i_tmp == IsALeafNode ) ? (-1) : (int)[i_tmp count]; +} + @end