1 /*****************************************************************************
2 * bookmarks.m: MacOS X Bookmarks window
3 *****************************************************************************
4 * Copyright (C) 2005 - 2007 the VideoLAN team
7 * Authors: Felix Kühne <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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, 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 *****************************************************************************/
40 #import <vlc_interface.h>
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 *****************************************************************************/
81 vlc_object_release( p_old_input );
88 /* release old input even if GC is enabled on 10.5 */
90 vlc_object_release( p_old_input );
97 /* localise the items */
100 [o_bookmarks_window setTitle: _NS("Bookmarks")];
101 [o_btn_add setTitle: _NS("Add")];
102 [o_btn_clear setTitle: _NS("Clear")];
103 [o_btn_edit setTitle: _NS("Edit")];
104 [o_btn_extract setTitle: _NS("Extract")];
105 [o_btn_rm setTitle: _NS("Remove")];
106 [[[o_tbl_dataTable tableColumnWithIdentifier:@"description"] headerCell]
107 setStringValue: _NS("Description")];
108 [[[o_tbl_dataTable tableColumnWithIdentifier:@"size_offset"] headerCell]
109 setStringValue: _NS("Position")];
110 [[[o_tbl_dataTable tableColumnWithIdentifier:@"time_offset"] headerCell]
111 setStringValue: _NS("Time")];
114 [o_edit_btn_ok setTitle: _NS("OK")];
115 [o_edit_btn_cancel setTitle: _NS("Cancel")];
116 [o_edit_lbl_name setStringValue: _NS("Name")];
117 [o_edit_lbl_time setStringValue: _NS("Time")];
118 [o_edit_lbl_bytes setStringValue: _NS("Position")];
121 - (void)showBookmarks
123 /* show the window, called from intf.m */
124 [o_bookmarks_window displayIfNeeded];
125 [o_bookmarks_window makeKeyAndOrderFront:nil];
128 - (IBAction)add:(id)sender
130 /* add item to list */
131 intf_thread_t * p_intf = VLCIntf;
132 input_thread_t * p_input = (input_thread_t *)vlc_object_find( p_intf,
133 VLC_OBJECT_INPUT, FIND_ANYWHERE );
137 seekpoint_t bookmark;
139 bookmark.psz_name = NULL;
140 bookmark.i_byte_offset = 0;
141 bookmark.i_time_offset = 0;
143 var_Get(p_intf, "position", &pos);
144 bookmark.psz_name = _("Untitled");
145 input_Control( p_input, INPUT_GET_BYTE_POSITION, &bookmark.i_byte_offset );
146 var_Get( p_input, "time", &pos );
147 bookmark.i_time_offset = pos.i_time;
148 input_Control( p_input, INPUT_ADD_BOOKMARK, &bookmark );
150 vlc_object_release( p_input );
152 [o_tbl_dataTable reloadData];
155 - (IBAction)clear:(id)sender
158 intf_thread_t * p_intf = VLCIntf;
159 input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_intf,
160 VLC_OBJECT_INPUT, FIND_ANYWHERE );
165 input_Control( p_input, INPUT_CLEAR_BOOKMARKS );
167 vlc_object_release( p_input );
169 [o_tbl_dataTable reloadData];
172 - (IBAction)edit:(id)sender
174 /* put values to the sheet's fields and show sheet */
175 /* we take the values from the core and not the table, because we cannot
177 intf_thread_t * p_intf = VLCIntf;
178 input_thread_t * p_input = (input_thread_t *)vlc_object_find( p_intf,
179 VLC_OBJECT_INPUT, FIND_ANYWHERE );
180 seekpoint_t **pp_bookmarks;
183 row = [o_tbl_dataTable selectedRow];
189 else if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks,
190 &i_bookmarks ) != VLC_SUCCESS )
192 vlc_object_release( p_input );
197 vlc_object_release( p_input );
200 [o_edit_fld_name setStringValue: [NSString stringWithUTF8String:
201 pp_bookmarks[row]->psz_name]];
202 [o_edit_fld_time setStringValue: [[NSNumber numberWithInt:
203 (pp_bookmarks[row]->i_time_offset / 1000000)] stringValue]];
204 [o_edit_fld_bytes setStringValue: [[NSNumber numberWithInt:
205 pp_bookmarks[row]->i_byte_offset] stringValue]];
208 p_old_input = p_input;
209 vlc_object_release( p_input );
211 [NSApp beginSheet: o_edit_window
212 modalForWindow: o_bookmarks_window
213 modalDelegate: o_edit_window
218 - (IBAction)edit_cancel:(id)sender
221 [NSApp endSheet:o_edit_window];
222 [o_edit_window close];
225 - (IBAction)edit_ok:(id)sender
227 /* save field contents and close sheet */
229 intf_thread_t * p_intf = VLCIntf;
230 seekpoint_t **pp_bookmarks;
232 input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_intf,
233 VLC_OBJECT_INPUT, FIND_ANYWHERE );
237 NSBeginCriticalAlertSheet(_NS("No input"), _NS("OK"),
238 @"", @"", o_bookmarks_window, nil, nil, nil, nil, _NS("No "
239 "input found. A stream must be playing or paused for "
240 "bookmarks to work."));
243 if( p_old_input != p_input )
245 NSBeginCriticalAlertSheet(_NS("Input has changed"), _NS("OK"),
246 @"", @"", o_bookmarks_window, nil, nil, nil, nil, _NS("Input "
247 "has changed, unable to save bookmark. Suspending playback with "
248 "\"Pause\" while editing bookmarks to ensure to keep the same "
250 vlc_object_release( p_input );
254 if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks,
255 &i_bookmarks ) != VLC_SUCCESS )
257 vlc_object_release( p_input );
261 i = [o_tbl_dataTable selectedRow];
263 if( pp_bookmarks[i]->psz_name )
264 free( pp_bookmarks[i]->psz_name );
266 pp_bookmarks[i]->psz_name = strdup([[o_edit_fld_name stringValue] UTF8String]);
267 pp_bookmarks[i]->i_byte_offset = [[o_edit_fld_bytes stringValue] intValue];
268 pp_bookmarks[i]->i_time_offset = ([[o_edit_fld_time stringValue] intValue] * 1000000);
270 if( input_Control( p_input, INPUT_CHANGE_BOOKMARK, pp_bookmarks[i], i )
273 msg_Warn( p_intf, "Unable to change the bookmark");
274 vlc_object_release( p_input );
278 [o_tbl_dataTable reloadData];
279 vlc_object_release( p_input );
282 [NSApp endSheet: o_edit_window];
283 [o_edit_window close];
286 - (IBAction)extract:(id)sender
290 intf_thread_t * p_intf = VLCIntf;
292 if( [o_tbl_dataTable numberOfSelectedRows] < 2 )
294 NSBeginAlertSheet(_NS("Invalid selection"), _NS("OK"),
295 @"", @"", o_bookmarks_window, nil, nil, nil, nil,
296 _NS("Two bookmarks have to be selected."));
299 input_thread_t *p_input =
300 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
304 NSBeginCriticalAlertSheet(_NS("No input found"), _NS("OK"),
305 @"", @"", o_bookmarks_window, nil, nil, nil, nil,
306 _NS("The stream must be playing or paused for bookmarks to work."));
310 seekpoint_t **pp_bookmarks;
318 if([o_tbl_dataTable isRowSelected:x])
325 else if (i_second == -1)
334 msg_Dbg(p_intf, "got the bookmark-indexes");
336 if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks,
337 &i_bookmarks ) != VLC_SUCCESS )
339 vlc_object_release( p_input );
340 msg_Err(p_intf, "already defined bookmarks couldn't be retrieved");
343 msg_Dbg(p_intf, "calling wizard");
345 [[[VLCMain sharedInstance] getWizard] initWithExtractValuesFrom:
346 [[NSNumber numberWithInt:
347 (pp_bookmarks[i_first]->i_time_offset/1000000)] stringValue]
348 to: [[NSNumber numberWithInt:
349 (pp_bookmarks[i_second]->i_time_offset/1000000)] stringValue]
350 ofItem: [NSString stringWithUTF8String:
351 input_GetItem(p_input)->psz_uri]];
352 vlc_object_release( p_input );
353 msg_Dbg(p_intf, "released input");
356 - (IBAction)goToBookmark:(id)sender
358 intf_thread_t * p_intf = VLCIntf;
359 input_thread_t *p_input =
360 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
363 if( !p_input ) return;
365 input_Control( p_input, INPUT_SET_BOOKMARK, [o_tbl_dataTable selectedRow] );
367 vlc_object_release( p_input );
370 - (IBAction)remove:(id)sender
372 /* remove selected item */
373 intf_thread_t * p_intf = VLCIntf;
374 input_thread_t *p_input =
375 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
378 if( !p_input ) return;
380 int i_focused = [o_tbl_dataTable selectedRow];
383 input_Control( p_input, INPUT_DEL_BOOKMARK, i_focused );
385 vlc_object_release( p_input );
387 [o_tbl_dataTable reloadData];
390 /*****************************************************************************
392 *****************************************************************************/
396 return o_tbl_dataTable;
399 /*****************************************************************************
400 * data source methods
401 *****************************************************************************/
403 - (int)numberOfRowsInTableView:(NSTableView *)theDataTable
405 /* return the number of bookmarks */
406 intf_thread_t * p_intf = VLCIntf;
407 input_thread_t * p_input = (input_thread_t *)vlc_object_find( p_intf,
408 VLC_OBJECT_INPUT, FIND_ANYWHERE );
409 seekpoint_t **pp_bookmarks;
412 if( !p_input ) return 0;
413 else if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks,
414 &i_bookmarks ) != VLC_SUCCESS )
416 vlc_object_release( p_input );
420 vlc_object_release( p_input );
425 - (id)tableView:(NSTableView *)theDataTable objectValueForTableColumn:
426 (NSTableColumn *)theTableColumn row: (int)row
428 /* return the corresponding data as NSString */
429 intf_thread_t * p_intf = VLCIntf;
430 input_thread_t * p_input = (input_thread_t *)vlc_object_find( p_intf,
431 VLC_OBJECT_INPUT, FIND_ANYWHERE );
432 seekpoint_t **pp_bookmarks;
435 int i_toBeReturned = 0;
437 if( !p_input ) return @"";
438 else if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks,
439 &i_bookmarks ) != VLC_SUCCESS )
441 vlc_object_release( p_input );
446 if ([[theTableColumn identifier] isEqualToString: @"description"])
448 toBeReturned = pp_bookmarks[row]->psz_name;
449 vlc_object_release( p_input );
450 return [NSString stringWithUTF8String: toBeReturned];
452 else if ([[theTableColumn identifier] isEqualToString: @"size_offset"])
454 i_toBeReturned = pp_bookmarks[row]->i_byte_offset;
455 vlc_object_release( p_input );
456 return [[NSNumber numberWithInt: i_toBeReturned] stringValue];
458 else if ([[theTableColumn identifier] isEqualToString: @"time_offset"])
460 i_toBeReturned = pp_bookmarks[row]->i_time_offset;
461 vlc_object_release( p_input );
462 return [[NSNumber numberWithInt: (i_toBeReturned / 1000000)]
467 /* may not happen, just in case */
468 vlc_object_release( p_input );
469 msg_Err(p_intf, "unknown table column identifier (%s) while "
470 "updating the bookmark table", [[theTableColumn identifier]
472 return @"unknown identifier";
478 /*****************************************************************************
480 *****************************************************************************/
482 - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
484 /* check whether a row is selected and en-/disable the edit/remove buttons */
485 if ([o_tbl_dataTable selectedRow] == -1)
487 /* no row is selected */
488 [o_btn_edit setEnabled: NO];
489 [o_btn_rm setEnabled: NO];
490 [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];