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., 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 *****************************************************************************/
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 );
129 seekpoint_t bookmark;
131 bookmark.psz_name = NULL;
132 bookmark.i_byte_offset = 0;
133 bookmark.i_time_offset = 0;
135 var_Get(p_intf, "position", &pos);
136 bookmark.psz_name = _("Untitled");
137 input_Control( p_input, INPUT_GET_BYTE_POSITION, &bookmark.i_byte_offset );
138 var_Get( p_input, "time", &pos );
139 bookmark.i_time_offset = pos.i_time;
140 input_Control( p_input, INPUT_ADD_BOOKMARK, &bookmark );
142 vlc_object_release( p_input );
144 [o_tbl_dataTable reloadData];
147 - (IBAction)clear:(id)sender
150 intf_thread_t * p_intf = VLCIntf;
151 input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_intf, \
152 VLC_OBJECT_INPUT, FIND_ANYWHERE );
157 input_Control( p_input, INPUT_CLEAR_BOOKMARKS );
159 vlc_object_release( p_input );
161 [o_tbl_dataTable reloadData];
164 - (IBAction)edit:(id)sender
166 /* put values to the sheet's fields and show sheet */
167 /* we take the values from the core and not the table, because we cannot
169 intf_thread_t * p_intf = VLCIntf;
170 input_thread_t * p_input = (input_thread_t *)vlc_object_find( p_intf, \
171 VLC_OBJECT_INPUT, FIND_ANYWHERE );
172 seekpoint_t **pp_bookmarks;
179 row = [o_tbl_dataTable selectedRow];
185 else if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks, \
186 &i_bookmarks ) != VLC_SUCCESS )
188 vlc_object_release( p_input );
193 vlc_object_release( p_input );
196 [o_edit_fld_name setStringValue: [NSString stringWithUTF8String: \
197 pp_bookmarks[row]->psz_name]];
198 [o_edit_fld_time setStringValue: [[NSNumber numberWithInt: \
199 (pp_bookmarks[row]->i_time_offset / 1000000)] stringValue]];
200 [o_edit_fld_bytes setStringValue: [[NSNumber numberWithInt: \
201 pp_bookmarks[row]->i_byte_offset] stringValue]];
204 p_old_input = p_input;
205 vlc_object_release( p_input );
207 [NSApp beginSheet: o_edit_window
208 modalForWindow: o_bookmarks_window
209 modalDelegate: o_edit_window
214 - (IBAction)edit_cancel:(id)sender
217 [NSApp endSheet:o_edit_window];
218 [o_edit_window close];
221 - (IBAction)edit_ok:(id)sender
223 /* save field contents and close sheet */
225 intf_thread_t * p_intf = VLCIntf;
226 seekpoint_t **pp_bookmarks;
228 input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_intf, \
229 VLC_OBJECT_INPUT, FIND_ANYWHERE );
233 NSBeginCriticalAlertSheet(_NS("No input"), _NS("OK"), \
234 @"", @"", o_bookmarks_window, nil, nil, nil, nil, _NS("No " \
235 "input found. The stream must be playing or paused for " \
236 "bookmarks to work."));
239 if( p_old_input != p_input )
241 NSBeginCriticalAlertSheet(_NS("Input has changed"), _NS("OK"), \
242 @"", @"", o_bookmarks_window, nil, nil, nil, nil, _NS("Input " \
243 "has changed, unable to save bookmark. Use \"Pause\" while " \
244 "editing bookmarks to keep the same input."));
245 vlc_object_release( p_input );
249 if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks, \
250 &i_bookmarks ) != VLC_SUCCESS )
252 vlc_object_release( p_input );
256 i = [o_tbl_dataTable selectedRow];
258 if( pp_bookmarks[i]->psz_name )
260 free( pp_bookmarks[i]->psz_name );
263 pp_bookmarks[i]->psz_name = strdup([[o_edit_fld_name stringValue] UTF8String]);
264 pp_bookmarks[i]->i_byte_offset = [[o_edit_fld_bytes stringValue] intValue];
265 pp_bookmarks[i]->i_time_offset = ([[o_edit_fld_time stringValue] intValue] * 1000000);
267 if( input_Control( p_input, INPUT_CHANGE_BOOKMARK, pp_bookmarks[i], i ) \
270 msg_Warn( p_intf, "VLCBookmarks: changing bookmark failed");
271 vlc_object_release( p_input );
275 [o_tbl_dataTable reloadData];
276 vlc_object_release( p_input );
279 [NSApp endSheet: o_edit_window];
280 [o_edit_window close];
283 - (IBAction)extract:(id)sender
287 intf_thread_t * p_intf = VLCIntf;
289 if( [o_tbl_dataTable numberOfSelectedRows] < 2 )
291 NSBeginAlertSheet(_NS("Invalid selection"), _NS("OK"), \
292 @"", @"", o_bookmarks_window, nil, nil, nil, nil, _NS("" \
293 "You have to select two bookmarks."));
296 input_thread_t *p_input =
297 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
301 NSBeginCriticalAlertSheet(_NS("No input found"), _NS("OK"), \
302 @"", @"", o_bookmarks_window, nil, nil, nil, nil, _NS("" \
303 "The stream must be playing or paused for bookmarks to work."));
307 seekpoint_t **pp_bookmarks;
315 if([o_tbl_dataTable isRowSelected:x])
322 else if (i_second == -1)
331 msg_Dbg(p_intf, "got the bookmark-indexes");
333 if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks, \
334 &i_bookmarks ) != VLC_SUCCESS )
336 vlc_object_release( p_input );
337 msg_Err(p_intf, "bookmarks couldn't be retrieved from core");
340 msg_Dbg(p_intf, "calling wizard");
342 [[[VLCMain sharedInstance] getWizard] initWithExtractValuesFrom: \
343 [[NSNumber numberWithInt: \
344 (pp_bookmarks[i_first]->i_time_offset/1000000)] stringValue] \
345 to: [[NSNumber numberWithInt: \
346 (pp_bookmarks[i_second]->i_time_offset/1000000)] stringValue] \
347 ofItem: [NSString stringWithUTF8String: \
348 p_input->input.p_item->psz_uri]];
349 vlc_object_release( p_input );
350 msg_Dbg(p_intf, "released input");
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;
415 else if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks, \
416 &i_bookmarks ) != VLC_SUCCESS )
418 vlc_object_release( p_input );
422 vlc_object_release( p_input );
427 - (id)tableView:(NSTableView *)theDataTable objectValueForTableColumn: \
428 (NSTableColumn *)theTableColumn row: (int)row
430 /* return the corresponding data as NSString */
431 intf_thread_t * p_intf = VLCIntf;
432 input_thread_t * p_input = (input_thread_t *)vlc_object_find( p_intf, \
433 VLC_OBJECT_INPUT, FIND_ANYWHERE );
434 seekpoint_t **pp_bookmarks;
445 else if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks, \
446 &i_bookmarks ) != VLC_SUCCESS )
448 vlc_object_release( p_input );
453 if ([[theTableColumn identifier] isEqualToString: @"description"])
455 toBeReturned = pp_bookmarks[row]->psz_name;
456 vlc_object_release( p_input );
457 return [NSString stringWithUTF8String: toBeReturned];
459 else if ([[theTableColumn identifier] isEqualToString: @"size_offset"])
461 i_toBeReturned = pp_bookmarks[row]->i_byte_offset;
462 vlc_object_release( p_input );
463 return [[NSNumber numberWithInt: i_toBeReturned] stringValue];
465 else if ([[theTableColumn identifier] isEqualToString: @"time_offset"])
467 i_toBeReturned = pp_bookmarks[row]->i_time_offset;
468 vlc_object_release( p_input );
469 return [[NSNumber numberWithInt: (i_toBeReturned / 1000000)] \
474 /* may not happen, but just in case */
475 vlc_object_release( p_input );
476 msg_Err(p_intf, "VLCBookmarks: unknown table column identifier " \
477 "(%s) while updating table", [[theTableColumn identifier] \
479 return @"unknown identifier";
485 /*****************************************************************************
487 *****************************************************************************/
489 - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
491 /* check whether a row is selected and en-/disable the edit/remove buttons */
492 if ([o_tbl_dataTable selectedRow] == -1)
494 /* no row is selected */
495 [o_btn_edit setEnabled: NO];
496 [o_btn_rm setEnabled: NO];
497 [o_btn_extract setEnabled: NO];
501 /* a row is selected */
502 [o_btn_edit setEnabled: YES];
503 [o_btn_rm setEnabled: YES];
504 if ([o_tbl_dataTable numberOfSelectedRows] == 2)
506 [o_btn_extract setEnabled: YES];