1 /*****************************************************************************
2 * bookmarks.m: MacOS X Bookmarks window
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
7 * Authors: Felix K
\9fhne <fkuehne@users.sf.net>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
25 /*****************************************************************************
27 * the code used to bind with VLC's modules is heavily based upon
28 * ../wxwidgets/bookmarks.cpp, written by Gildas Bazin.
29 * (he is a member of the VideoLAN team)
30 *****************************************************************************/
33 /*****************************************************************************
35 *****************************************************************************/
42 /*****************************************************************************
43 * VLCExtended implementation
45 * implements the GUI functions for the window, the data source and the
46 * delegate for o_tbl_dataTable
47 *****************************************************************************/
49 @implementation VLCBookmarks
51 static VLCBookmarks *_o_sharedInstance = nil;
53 + (VLCBookmarks *)sharedInstance
55 return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
60 if (_o_sharedInstance) {
63 _o_sharedInstance = [super init];
66 return _o_sharedInstance;
69 /*****************************************************************************
71 *****************************************************************************/
89 /* localise the items */
92 [o_bookmarks_window setTitle: _NS("Bookmarks")];
93 [o_btn_add setTitle: _NS("Add")];
94 [o_btn_clear setTitle: _NS("Clear")];
95 [o_btn_edit setTitle: _NS("Edit")];
96 [o_btn_extract setTitle: _NS("Extract")];
97 [o_btn_rm setTitle: _NS("Remove")];
98 [[[o_tbl_dataTable tableColumnWithIdentifier:@"description"] headerCell] \
99 setStringValue: _NS("Description")];
100 [[[o_tbl_dataTable tableColumnWithIdentifier:@"size_offset"] headerCell] \
101 setStringValue: _NS("Size offset")];
102 [[[o_tbl_dataTable tableColumnWithIdentifier:@"time_offset"] headerCell] \
103 setStringValue: _NS("Time offset")];
106 [o_edit_btn_ok setTitle: _NS("OK")];
107 [o_edit_btn_cancel setTitle: _NS("Cancel")];
108 [o_edit_lbl_name setStringValue: _NS("Name")];
109 [o_edit_lbl_time setStringValue: _NS("Time")];
110 [o_edit_lbl_bytes setStringValue: _NS("Bytes")];
113 - (void)showBookmarks
115 /* show the window, called from intf.m */
116 [o_bookmarks_window displayIfNeeded];
117 [o_bookmarks_window makeKeyAndOrderFront:nil];
120 - (IBAction)add:(id)sender
122 /* add item to list */
123 intf_thread_t * p_intf = VLCIntf;
124 input_thread_t * p_input = (input_thread_t *)vlc_object_find (p_intf, \
125 VLC_OBJECT_INPUT, FIND_ANYWHERE);
126 if (!p_input) return;
128 seekpoint_t bookmark;
130 bookmark.psz_name = NULL;
131 bookmark.i_byte_offset = 0;
132 bookmark.i_time_offset = 0;
134 var_Get(p_intf, "position", &pos);
135 bookmark.psz_name = _("Untitled");
136 input_Control( p_input, INPUT_GET_BYTE_POSITION, &bookmark.i_byte_offset );
137 var_Get( p_input, "time", &pos );
138 bookmark.i_time_offset = pos.i_time;
139 input_Control( p_input, INPUT_ADD_BOOKMARK, &bookmark );
141 vlc_object_release( p_input );
143 [o_tbl_dataTable reloadData];
146 - (IBAction)clear:(id)sender
149 intf_thread_t * p_intf = VLCIntf;
150 input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_intf, \
151 VLC_OBJECT_INPUT, FIND_ANYWHERE );
153 if( !p_input ) return;
155 input_Control( p_input, INPUT_CLEAR_BOOKMARKS );
157 vlc_object_release( p_input );
159 [o_tbl_dataTable reloadData];
162 - (IBAction)edit:(id)sender
164 /* put values to the sheet's fields and show sheet */
165 /* we take the values from the core and not the table, because we cannot
167 intf_thread_t * p_intf = VLCIntf;
168 input_thread_t * p_input = (input_thread_t *)vlc_object_find( p_intf, \
169 VLC_OBJECT_INPUT, FIND_ANYWHERE );
170 seekpoint_t **pp_bookmarks;
177 row = [o_tbl_dataTable selectedRow];
183 else if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks, \
184 &i_bookmarks ) != VLC_SUCCESS )
186 vlc_object_release( p_input );
191 vlc_object_release( p_input );
194 [o_edit_fld_name setStringValue: [NSString stringWithUTF8String: \
195 pp_bookmarks[row]->psz_name]];
196 [o_edit_fld_time setStringValue: [[NSNumber numberWithInt: \
197 (pp_bookmarks[row]->i_time_offset / 1000000)] stringValue]];
198 [o_edit_fld_bytes setStringValue: [[NSNumber numberWithInt: \
199 pp_bookmarks[row]->i_byte_offset] stringValue]];
202 p_old_input = p_input;
203 vlc_object_release( p_input );
205 [NSApp beginSheet: o_edit_window
206 modalForWindow: o_bookmarks_window
207 modalDelegate: o_edit_window
212 - (IBAction)edit_cancel:(id)sender
215 [NSApp endSheet:o_edit_window];
216 [o_edit_window close];
219 - (IBAction)edit_ok:(id)sender
221 /* save field contents and close sheet */
223 intf_thread_t * p_intf = VLCIntf;
224 seekpoint_t **pp_bookmarks;
226 input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_intf, \
227 VLC_OBJECT_INPUT, FIND_ANYWHERE );
231 NSBeginCriticalAlertSheet(_NS("No input"), _NS("OK"), \
232 @"", @"", o_bookmarks_window, nil, nil, nil, nil, _NS("No " \
233 "input found. The stream must be playing or paused for " \
234 "bookmarks to work."));
237 if( p_old_input != p_input )
239 NSBeginCriticalAlertSheet(_NS("Input has changed"), _NS("OK"), \
240 @"", @"", o_bookmarks_window, nil, nil, nil, nil, _NS("Input " \
241 "has changed, unable to save bookmark. Use \"pause\" while " \
242 "editing bookmarks to keep the same input."));
243 vlc_object_release( p_input );
247 if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks, \
248 &i_bookmarks ) != VLC_SUCCESS )
250 vlc_object_release( p_input );
255 i = [o_tbl_dataTable selectedRow];
257 if( pp_bookmarks[i]->psz_name )
259 free( pp_bookmarks[i]->psz_name );
261 /* FIXME: putting the name to core does not work!! -- FK*/
262 pp_bookmarks[i]->psz_name = strdup([[o_edit_fld_name stringValue] UTF8String]);
263 pp_bookmarks[i]->i_byte_offset = [[o_edit_fld_bytes stringValue] intValue];
264 pp_bookmarks[i]->i_time_offset = ([[o_edit_fld_time stringValue] intValue] * 1000000);
266 if( input_Control( p_input, INPUT_CHANGE_BOOKMARK, pp_bookmarks[i], i ) \
269 msg_Warn( p_intf, "VLCBookmarks: changing bookmark failed");
270 vlc_object_release( p_input );
274 [o_tbl_dataTable reloadData];
275 vlc_object_release( p_input );
278 [NSApp endSheet: o_edit_window];
279 [o_edit_window close];
282 - (IBAction)extract:(id)sender
286 intf_thread_t * p_intf = VLCIntf;
288 if( [o_tbl_dataTable numberOfSelectedRows] < 2 )
290 NSBeginAlertSheet(_NS("Invalid selection"), _NS("OK"), \
291 @"", @"", o_bookmarks_window, nil, nil, nil, nil, _NS("" \
292 "You must select two bookmarks"));
295 input_thread_t *p_input =
296 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
300 NSBeginCriticalAlertSheet(_NS("No input found"), _NS("OK"), \
301 @"", @"", o_bookmarks_window, nil, nil, nil, nil, _NS("" \
302 "The stream must be playing or paused for bookmarks to work"));
306 seekpoint_t **pp_bookmarks;
314 if([o_tbl_dataTable isRowSelected:x])
322 else if (i_second == -1)
332 if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks, \
333 &i_bookmarks ) != VLC_SUCCESS )
335 vlc_object_release( p_input );
336 msg_Err(p_intf, "bookmarks couldn't be retrieved from core");
339 msg_Dbg(p_intf, "calling for wizard");
341 [[[VLCMain sharedInstance] getWizard] initWithExtractValuesFrom: \
342 [[NSNumber numberWithInt: \
343 (pp_bookmarks[i_first]->i_time_offset/1000000)] stringValue] \
344 to: [[NSNumber numberWithInt: \
345 (pp_bookmarks[i_second]->i_time_offset/1000000)] stringValue] \
346 ofItem: [NSString stringWithUTF8String: \
347 p_input->input.p_item->psz_uri]];
348 vlc_object_release( p_input );
349 msg_Dbg(p_intf, "released input");*/
350 msg_Err(p_intf, "not implemented yet, sorry");
353 - (IBAction)goToBookmark:(id)sender
355 intf_thread_t * p_intf = VLCIntf;
356 input_thread_t *p_input =
357 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
364 input_Control( p_input, INPUT_SET_BOOKMARK, [o_tbl_dataTable selectedRow] );
366 vlc_object_release( p_input );
369 - (IBAction)remove:(id)sender
371 /* remove selected item */
372 intf_thread_t * p_intf = VLCIntf;
373 input_thread_t *p_input =
374 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
376 if( !p_input ) return;
378 int i_focused = [o_tbl_dataTable selectedRow];
381 input_Control( p_input, INPUT_DEL_BOOKMARK, i_focused );
384 vlc_object_release( p_input );
386 [o_tbl_dataTable reloadData];
389 /*****************************************************************************
391 *****************************************************************************/
395 return o_tbl_dataTable;
398 /*****************************************************************************
399 * data source methods
400 *****************************************************************************/
402 - (int)numberOfRowsInTableView:(NSTableView *)theDataTable
404 /* return the number of bookmarks */
405 intf_thread_t * p_intf = VLCIntf;
406 input_thread_t * p_input = (input_thread_t *)vlc_object_find( p_intf, \
407 VLC_OBJECT_INPUT, FIND_ANYWHERE );
408 seekpoint_t **pp_bookmarks;
414 } else if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks, \
415 &i_bookmarks ) != VLC_SUCCESS )
417 vlc_object_release( p_input );
424 - (id)tableView:(NSTableView *)theDataTable objectValueForTableColumn: \
425 (NSTableColumn *)theTableColumn row: (int)row
427 /* return the corresponding data as NSString */
428 intf_thread_t * p_intf = VLCIntf;
429 input_thread_t * p_input = (input_thread_t *)vlc_object_find( p_intf, \
430 VLC_OBJECT_INPUT, FIND_ANYWHERE );
431 seekpoint_t **pp_bookmarks;
442 else if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks, \
443 &i_bookmarks ) != VLC_SUCCESS )
445 vlc_object_release( p_input );
448 if ([[theTableColumn identifier] isEqualToString: @"description"])
450 toBeReturned = pp_bookmarks[row]->psz_name;
451 vlc_object_release( p_input );
452 return [NSString stringWithUTF8String: toBeReturned];
454 else if ([[theTableColumn identifier] isEqualToString: @"size_offset"])
456 i_toBeReturned = pp_bookmarks[row]->i_byte_offset;
457 vlc_object_release( p_input );
458 return [[NSNumber numberWithInt: i_toBeReturned] stringValue];
460 else if ([[theTableColumn identifier] isEqualToString: @"time_offset"])
462 i_toBeReturned = pp_bookmarks[row]->i_time_offset;
463 vlc_object_release( p_input );
464 return [[NSNumber numberWithInt: (i_toBeReturned / 1000000)] \
469 /* may not happen, but just in case */
470 vlc_object_release( p_input );
471 msg_Err(p_intf, "VLCBookmarks: unknown table column identifier " \
472 "(%s) while updating table", [[theTableColumn identifier] \
474 return @"unknown identifier";
480 /*****************************************************************************
482 *****************************************************************************/
484 - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
486 /* check whether a row is selected and en-/disable the edit/remove buttons */
487 if ([o_tbl_dataTable selectedRow] == -1)
489 /* no row is selected */
490 [o_btn_edit setEnabled: NO];
491 [o_btn_rm setEnabled: NO];
492 [o_btn_extract setEnabled: NO];
494 /* a row is selected */
495 [o_btn_edit setEnabled: YES];
496 [o_btn_rm setEnabled: YES];
497 if ([o_tbl_dataTable numberOfSelectedRows] == 2)
499 [o_btn_extract setEnabled: YES];