1 /*****************************************************************************
2 * controls.m: MacOS X interface module
3 *****************************************************************************
4 * Copyright (C) 2002-2013 VLC authors and VideoLAN
7 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8 * Christophe Massiot <massiot@via.ecp.fr>
9 * Derk-Jan Hartman <hartman at videolan dot org>
10 * Benjamin Pracht <bigben at videolan doit org>
11 * Felix Paul Kühne <fkuehne at videolan dot org>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
28 /*****************************************************************************
30 *****************************************************************************/
31 #include <stdlib.h> /* malloc(), free() */
32 #include <sys/param.h> /* for MAXPATHLEN */
41 #import "CoreInteraction.h"
45 /*****************************************************************************
46 * VLCControls implementation
47 *****************************************************************************/
48 @implementation VLCControls
52 [o_specificTime_mi setTitle: _NS("Jump To Time")];
53 [o_specificTime_cancel_btn setTitle: _NS("Cancel")];
54 [o_specificTime_ok_btn setTitle: _NS("OK")];
55 [o_specificTime_sec_lbl setStringValue: _NS("sec.")];
56 [o_specificTime_goTo_lbl setStringValue: _NS("Jump to time")];
62 [[NSNotificationCenter defaultCenter] removeObserver: self];
67 - (IBAction)play:(id)sender
69 [[VLCCoreInteraction sharedInstance] play];
72 - (IBAction)stop:(id)sender
74 [[VLCCoreInteraction sharedInstance] stop];
77 - (IBAction)prev:(id)sender
79 [[VLCCoreInteraction sharedInstance] previous];
82 - (IBAction)next:(id)sender
84 [[VLCCoreInteraction sharedInstance] next];
87 - (IBAction)random:(id)sender
89 [[VLCCoreInteraction sharedInstance] shuffle];
92 - (IBAction)repeat:(id)sender
95 intf_thread_t * p_intf = VLCIntf;
96 playlist_t * p_playlist = pl_Get(p_intf);
98 var_Get(p_playlist, "repeat", &val);
100 [[VLCCoreInteraction sharedInstance] repeatOne];
102 [[VLCCoreInteraction sharedInstance] repeatOff];
105 - (IBAction)loop:(id)sender
108 intf_thread_t * p_intf = VLCIntf;
109 playlist_t * p_playlist = pl_Get(p_intf);
111 var_Get(p_playlist, "loop", &val);
113 [[VLCCoreInteraction sharedInstance] repeatAll];
115 [[VLCCoreInteraction sharedInstance] repeatOff];
118 - (IBAction)quitAfterPlayback:(id)sender
121 playlist_t * p_playlist = pl_Get(VLCIntf);
122 var_ToggleBool(p_playlist, "play-and-exit");
125 - (IBAction)forward:(id)sender
127 [[VLCCoreInteraction sharedInstance] forward];
130 - (IBAction)backward:(id)sender
132 [[VLCCoreInteraction sharedInstance] backward];
135 - (IBAction)volumeUp:(id)sender
137 [[VLCCoreInteraction sharedInstance] volumeUp];
140 - (IBAction)volumeDown:(id)sender
142 [[VLCCoreInteraction sharedInstance] volumeDown];
145 - (IBAction)mute:(id)sender
147 [[VLCCoreInteraction sharedInstance] setMute: YES];
150 - (IBAction)volumeSliderUpdated:(id)sender
152 [[VLCCoreInteraction sharedInstance] setVolume: [sender intValue]];
155 - (IBAction)showPosition: (id)sender
157 input_thread_t * p_input = pl_CurrentInput(VLCIntf);
158 if (p_input != NULL) {
159 vout_thread_t *p_vout = input_GetVout(p_input);
160 if (p_vout != NULL) {
161 var_SetInteger(VLCIntf->p_libvlc, "key-action", ACTIONID_POSITION);
162 vlc_object_release(p_vout);
164 vlc_object_release(p_input);
168 - (IBAction)telxTransparent:(id)sender
171 p_vbi = (vlc_object_t *) vlc_object_find_name(pl_Get(VLCIntf), "zvbi");
173 var_SetBool(p_vbi, "vbi-opaque", [sender state]);
174 [sender setState: ![sender state]];
175 vlc_object_release(p_vbi);
179 - (IBAction)telxNavLink:(id)sender
181 intf_thread_t * p_intf = VLCIntf;
185 if ([[sender title] isEqualToString: _NS("Index")])
187 else if ([[sender title] isEqualToString: _NS("Red")])
189 else if ([[sender title] isEqualToString: _NS("Green")])
191 else if ([[sender title] isEqualToString: _NS("Yellow")])
193 else if ([[sender title] isEqualToString: _NS("Blue")])
195 if (i_page == 0) return;
197 p_vbi = (vlc_object_t *) vlc_object_find_name(pl_Get(VLCIntf), "zvbi");
199 var_SetInteger(p_vbi, "vbi-page", i_page);
200 vlc_object_release(p_vbi);
204 - (IBAction)lockVideosAspectRatio:(id)sender
206 [[VLCCoreInteraction sharedInstance] setAspectRatioIsLocked: ![sender state]];
207 [sender setState: [[VLCCoreInteraction sharedInstance] aspectRatioIsLocked]];
210 - (IBAction)addSubtitleFile:(id)sender
212 NSInteger i_returnValue = 0;
213 input_thread_t * p_input = pl_CurrentInput(VLCIntf);
217 input_item_t *p_item = input_GetItem(p_input);
219 vlc_object_release(p_input);
223 char *path = input_item_GetURI(p_item);
227 NSOpenPanel * openPanel = [NSOpenPanel openPanel];
228 [openPanel setCanChooseFiles: YES];
229 [openPanel setCanChooseDirectories: NO];
230 [openPanel setAllowsMultipleSelection: YES];
231 [openPanel setAllowedFileTypes: [NSArray arrayWithObjects: @"cdg",@"@idx",@"srt",@"sub",@"utf",@"ass",@"ssa",@"aqt",@"jss",@"psb",@"rt",@"smi",@"txt",@"smil", nil]];
232 [openPanel setDirectoryURL:[NSURL fileURLWithPath:[[NSString stringWithUTF8String:path] stringByExpandingTildeInPath]]];
233 i_returnValue = [openPanel runModal];
236 if (i_returnValue == NSOKButton) {
241 c = [[openPanel URLs] count];
243 for (int i = 0; i < c ; i++) {
244 msg_Dbg(VLCIntf, "loading subs from %s", [[[[openPanel URLs] objectAtIndex: i] path] UTF8String]);
245 if (input_AddSubtitle(p_input, [[[[openPanel URLs] objectAtIndex: i] path] UTF8String], TRUE))
246 msg_Warn(VLCIntf, "unable to load subtitles from '%s'",
247 [[[[openPanel URLs] objectAtIndex: i] path] UTF8String]);
250 vlc_object_release(p_input);
253 - (BOOL)keyEvent:(NSEvent *)o_event
255 BOOL eventHandled = NO;
256 NSString * characters = [o_event charactersIgnoringModifiers];
257 if ([characters length] > 0) {
258 unichar key = [characters characterAtIndex: 0];
261 input_thread_t * p_input = pl_CurrentInput(VLCIntf);
262 if (p_input != NULL) {
263 vout_thread_t *p_vout = input_GetVout(p_input);
265 if (p_vout != NULL) {
267 if (key == (unichar) 0x1b) {
268 if (var_GetBool(p_vout, "fullscreen")) {
269 [[VLCCoreInteraction sharedInstance] toggleFullscreen];
273 else if (key == ' ') {
277 vlc_object_release(p_vout);
279 vlc_object_release(p_input);
286 - (IBAction)goToSpecificTime:(id)sender
288 if (sender == o_specificTime_cancel_btn)
290 [NSApp endSheet: o_specificTime_win];
291 [o_specificTime_win close];
292 } else if (sender == o_specificTime_ok_btn) {
293 input_thread_t * p_input = pl_CurrentInput(VLCIntf);
295 int64_t timeInSec = 0;
296 NSString * fieldContent = [o_specificTime_enter_fld stringValue];
297 if ([[fieldContent componentsSeparatedByString: @":"] count] > 1 &&
298 [[fieldContent componentsSeparatedByString: @":"] count] <= 3) {
299 NSArray * ourTempArray = \
300 [fieldContent componentsSeparatedByString: @":"];
302 if ([[fieldContent componentsSeparatedByString: @":"] count] == 3) {
303 timeInSec += ([[ourTempArray objectAtIndex: 0] intValue] * 3600); //h
304 timeInSec += ([[ourTempArray objectAtIndex: 1] intValue] * 60); //m
305 timeInSec += [[ourTempArray objectAtIndex: 2] intValue]; //s
307 timeInSec += ([[ourTempArray objectAtIndex: 0] intValue] * 60); //m
308 timeInSec += [[ourTempArray objectAtIndex: 1] intValue]; //s
312 timeInSec = [fieldContent intValue];
314 input_Control(p_input, INPUT_SET_TIME, (int64_t)(timeInSec * 1000000));
315 vlc_object_release(p_input);
318 [NSApp endSheet: o_specificTime_win];
319 [o_specificTime_win close];
321 input_thread_t * p_input = pl_CurrentInput(VLCIntf);
323 /* we can obviously only do that if an input is available */
324 vlc_value_t pos, length;
325 var_Get(p_input, "time", &pos);
326 [o_specificTime_enter_fld setIntValue: (pos.i_time / 1000000)];
327 var_Get(p_input, "length", &length);
328 [o_specificTime_stepper setMaxValue: (length.i_time / 1000000)];
330 [NSApp beginSheet: o_specificTime_win modalForWindow: \
331 [NSApp mainWindow] modalDelegate: self didEndSelector: nil \
333 [o_specificTime_win makeKeyWindow];
334 vlc_object_release(p_input);
341 @implementation VLCControls (NSMenuValidation)
343 - (BOOL)validateMenuItem:(NSMenuItem *)o_mi
345 return [[VLCMainMenu sharedInstance] validateMenuItem:o_mi];