VLCMainMenu.m 59.4 KB
Newer Older
1
/*****************************************************************************
2
 *MainMenu.m: MacOS X interface module
3
 *****************************************************************************
4
 *Copyright (C) 2011-2018 Felix Paul Kühne
5
 *$Id$
6
 *
7
 *Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
8
 *
9 10 11 12
 *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
 *the Free Software Foundation; either version 2 of the License, or
 *(at your option) any later version.
13
 *
14 15 16 17
 *This program is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *GNU General Public License for more details.
18
 *
19 20 21
 *You should have received a copy of the GNU General Public License
 *along with this program; if not, write to the Free Software
 *Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 23
 *****************************************************************************/

24
#import "VLCMainMenu.h"
25
#import "VLCMain.h"
26

27 28
#import <vlc_common.h>
#import <vlc_playlist.h>
29
#import <vlc_input.h>
30

31
#import "VLCAboutWindowController.h"
32
#import "VLCOpenWindowController.h"
33
#import "VLCAudioEffectsWindowController.h"
34
#import "VLCErrorWindowController.h"
35
#import "VLCTrackSynchronizationWindowController.h"
36
#import "VLCHelpWindowController.h"
37
#import "VLCVideoEffectsWindowController.h"
38
#import "VLCBookmarksWindowController.h"
39
#import "VLCSimplePrefsController.h"
40 41
#import "VLCPlaylist.h"
#import "VLCPlaylistInfo.h"
42
#import "VLCVoutView.h"
43
#import "VLCCoreDialogProvider.h"
44
#import "VLCCoreInteraction.h"
45
#import "VLCMainWindow.h"
46
#import "VLCMainWindowControlsBar.h"
47
#import "VLCExtensionsManager.h"
48
#import "VLCConvertAndSaveWindowController.h"
49
#import "VLCLogWindowController.h"
50
#import "VLCAddonsWindowController.h"
51
#import "VLCTimeSelectionPanelController.h"
52
#import "NSScreen+VLCAdditions.h"
53
#import "VLCRendererMenuController.h"
54

55
#ifdef HAVE_SPARKLE
56 57 58
#import <Sparkle/Sparkle.h>
#endif

59
@interface VLCMainMenu() <NSMenuDelegate>
60
{
61
    VLCAboutWindowController *_aboutWindowController;
62
    VLCHelpWindowController  *_helpWindowController;
63
    VLCAddonsWindowController *_addonsController;
64 65
    VLCRendererMenuController *_rendererMenuController;
    NSTimer *_cancelRendererDiscoveryTimer;
66

67
    NSMenu *_playlistTableColumnsContextMenu;
68 69

    __strong VLCTimeSelectionPanelController *_timeSelectionPanel;
70 71 72
}
@end

73 74
@implementation VLCMainMenu

75
#pragma mark - Initialization
76 77 78

- (void)dealloc
{
79
    msg_Dbg(getIntf(), "Deinitializing main menu");
80
    [[NSNotificationCenter defaultCenter] removeObserver: self];
81

82
    [self releaseRepresentedObjects:[NSApp mainMenu]];
83 84 85 86
}

- (void)awakeFromNib
{
87 88
    _timeSelectionPanel = [[VLCTimeSelectionPanelController alloc] init];

89 90
    /* check whether the user runs OSX with a RTL language */
    NSArray* languages = [NSLocale preferredLanguages];
91
    NSString* preferredLanguage = [languages firstObject];
92 93

    if ([NSLocale characterDirectionForLanguage:preferredLanguage] == NSLocaleLanguageDirectionRightToLeft) {
94
        msg_Dbg(getIntf(), "adapting interface since '%s' is a RTL language", [preferredLanguage UTF8String]);
95
        [_rateTextField setAlignment: NSLeftTextAlignment];
96
    }
97 98

    [self setRateControlsEnabled:NO];
99

100
#ifdef HAVE_SPARKLE
101 102
    [_checkForUpdate setAction:@selector(checkForUpdates:)];
    [_checkForUpdate setTarget:[SUUpdater sharedUpdater]];
103
#else
104
    [_checkForUpdate setEnabled:NO];
105
#endif
106

107
    NSString* keyString;
108
    vlc_value_t val;
109 110
    VLCStringUtility *stringUtility = [VLCStringUtility sharedInstance];
    char *key;
111

112
    /* Get ExtensionsManager */
113
    intf_thread_t *p_intf = getIntf();
114

115 116
    [self initStrings];

117
    key = config_GetPsz(p_intf, "key-quit");
118 119 120
    keyString = [NSString stringWithFormat:@"%s", key];
    [_quit setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_quit setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
121
    FREENULL(key);
122

123
    // do not assign play/pause key
124

125
    key = config_GetPsz(p_intf, "key-stop");
126 127 128
    keyString = [NSString stringWithFormat:@"%s", key];
    [_stop setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_stop setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
129
    FREENULL(key);
130

131
    key = config_GetPsz(p_intf, "key-prev");
132 133 134
    keyString = [NSString stringWithFormat:@"%s", key];
    [_previous setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_previous setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
135
    FREENULL(key);
136

137
    key = config_GetPsz(p_intf, "key-next");
138 139 140
    keyString = [NSString stringWithFormat:@"%s", key];
    [_next setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_next setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
141
    FREENULL(key);
142

143
    key = config_GetPsz(p_intf, "key-jump+short");
144 145 146
    keyString = [NSString stringWithFormat:@"%s", key];
    [_fwd setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_fwd setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
147
    FREENULL(key);
148

149
    key = config_GetPsz(p_intf, "key-jump-short");
150 151 152
    keyString = [NSString stringWithFormat:@"%s", key];
    [_bwd setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_bwd setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
153
    FREENULL(key);
154

155
    key = config_GetPsz(p_intf, "key-vol-up");
156 157 158
    keyString = [NSString stringWithFormat:@"%s", key];
    [_vol_up setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_vol_up setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
159
    FREENULL(key);
160

161
    key = config_GetPsz(p_intf, "key-vol-down");
162 163 164
    keyString = [NSString stringWithFormat:@"%s", key];
    [_vol_down setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_vol_down setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
165
    FREENULL(key);
166

167
    key = config_GetPsz(p_intf, "key-vol-mute");
168 169 170
    keyString = [NSString stringWithFormat:@"%s", key];
    [_mute setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_mute setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
171
    FREENULL(key);
172

173
    key = config_GetPsz(p_intf, "key-toggle-fullscreen");
174 175 176
    keyString = [NSString stringWithFormat:@"%s", key];
    [_fullscreenItem setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_fullscreenItem setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
177
    FREENULL(key);
178

179
    key = config_GetPsz(p_intf, "key-snapshot");
180 181 182
    keyString = [NSString stringWithFormat:@"%s", key];
    [_snapshot setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_snapshot setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
183
    FREENULL(key);
184

185
    key = config_GetPsz(p_intf, "key-random");
186 187 188
    keyString = [NSString stringWithFormat:@"%s", key];
    [_random setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_random setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
189
    FREENULL(key);
190

191
    key = config_GetPsz(p_intf, "key-zoom-half");
192 193 194
    keyString = [NSString stringWithFormat:@"%s", key];
    [_half_window setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_half_window setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
195
    FREENULL(key);
196

197
    key = config_GetPsz(p_intf, "key-zoom-original");
198 199 200
    keyString = [NSString stringWithFormat:@"%s", key];
    [_normal_window setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_normal_window setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
201
    FREENULL(key);
202

203
    key = config_GetPsz(p_intf, "key-zoom-double");
204 205 206
    keyString = [NSString stringWithFormat:@"%s", key];
    [_double_window setKeyEquivalent: [stringUtility VLCKeyToString: keyString]];
    [_double_window setKeyEquivalentModifierMask: [stringUtility VLCModifiersToCocoa:keyString]];
207
    FREENULL(key);
208 209 210

    [self setSubmenusEnabled: FALSE];

211 212 213 214 215 216 217
    /* configure playback / controls menu */
    self.controlsMenu.delegate = self;
    [_rendererNoneItem setState:NSOnState];
    _rendererMenuController = [[VLCRendererMenuController alloc] init];
    _rendererMenuController.rendererNoneItem = _rendererNoneItem;
    _rendererMenuController.rendererMenu = _rendererMenu;

218 219 220 221 222
    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector(refreshVoutDeviceMenu:)
                                                 name: NSApplicationDidChangeScreenParametersNotification
                                               object: nil];

223 224
    [self setupVarMenuItem:_add_intf target: (vlc_object_t *)p_intf
                             var:"intf-add" selector: @selector(toggleVar:)];
225

226 227
    /* setup extensions menu */
    /* Let the ExtensionsManager itself build the menu */
228
    VLCExtensionsManager *extMgr = [[VLCMain sharedInstance] extensionsManager];
229
    [extMgr buildMenu:_extensionsMenu];
230
    [_extensions setEnabled: ([_extensionsMenu numberOfItems] > 0)];
231

232
    // FIXME: Implement preference for autoloading extensions on mac
233 234
    if (![extMgr isLoaded] && ![extMgr cannotLoad])
        [extMgr loadExtensions];
235

236
    /* setup post-proc menu */
237
    NSUInteger count = (NSUInteger) [_postprocessingMenu numberOfItems];
238
    if (count > 0)
239 240 241 242 243 244 245 246 247
        [_postprocessingMenu removeAllItems];

    NSMenuItem *mitem;
    [_postprocessingMenu setAutoenablesItems: YES];
    [_postprocessingMenu addItemWithTitle: _NS("Disable") action:@selector(togglePostProcessing:) keyEquivalent:@""];
    mitem = [_postprocessingMenu itemAtIndex: 0];
    [mitem setTag: -1];
    [mitem setEnabled: YES];
    [mitem setTarget: self];
248
    for (NSUInteger x = 1; x < 7; x++) {
249
        [_postprocessingMenu addItemWithTitle:[NSString stringWithFormat:_NS("Level %i"), x]
250 251
                                               action:@selector(togglePostProcessing:)
                                        keyEquivalent:@""];
252 253 254 255
        mitem = [_postprocessingMenu itemAtIndex:x];
        [mitem setEnabled:YES];
        [mitem setTag:x];
        [mitem setTarget:self];
256 257 258
    }
    char *psz_config = config_GetPsz(p_intf, "video-filter");
    if (psz_config) {
259
        if (!strstr(psz_config, "postproc"))
260
            [[_postprocessingMenu itemAtIndex:0] setState:NSOnState];
261
        else
262
            [[_postprocessingMenu itemWithTag:config_GetInt(p_intf, "postproc-q")] setState:NSOnState];
263 264
        free(psz_config);
    } else
265 266
        [[_postprocessingMenu itemAtIndex:0] setState:NSOnState];
    [_postprocessing setEnabled: NO];
267

268
    [self refreshAudioDeviceList];
269 270

    /* setup subtitles menu */
271 272 273 274 275 276 277
    // Persist those variables on the playlist
    playlist_t *p_playlist = pl_Get(getIntf());
    var_Create(p_playlist, "freetype-color", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create(p_playlist, "freetype-background-opacity", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create(p_playlist, "freetype-background-color", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create(p_playlist, "freetype-outline-thickness", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);

278 279 280 281
    [self setupMenu: _subtitle_textcolorMenu withIntList:"freetype-color" andSelector:@selector(switchSubtitleOption:)];
    [_subtitle_bgopacity_sld setIntValue: config_GetInt(VLC_OBJECT(p_intf), "freetype-background-opacity")];
    [self setupMenu: _subtitle_bgcolorMenu withIntList:"freetype-background-color" andSelector:@selector(switchSubtitleOption:)];
    [self setupMenu: _subtitle_outlinethicknessMenu withIntList:"freetype-outline-thickness" andSelector:@selector(switchSubtitleOption:)];
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300

    /* Build size menu based on different scale factors */
    struct {
        const char *const name;
        int scaleValue;
    } scaleValues[] = {
        { N_("Smaller"), 50},
        { N_("Small"),   75},
        { N_("Normal"), 100},
        { N_("Large"),  125},
        { N_("Larger"), 150},
        { NULL, 0 }
    };

    for(int i = 0; scaleValues[i].name; i++) {
        NSMenuItem *menuItem = [_subtitle_sizeMenu addItemWithTitle: _NS(scaleValues[i].name) action:@selector(switchSubtitleSize:) keyEquivalent:@""];
        [menuItem setTag:scaleValues[i].scaleValue];
        [menuItem setTarget: self];
    }
301 302 303 304 305 306 307
}

- (void)setupMenu: (NSMenu*)menu withIntList: (char *)psz_name andSelector:(SEL)selector
{
    module_config_t *p_item;

    [menu removeAllItems];
308
    p_item = config_FindConfig(psz_name);
309

310 311 312 313
    if (!p_item) {
        msg_Err(getIntf(), "couldn't create menu int list for item '%s' as it does not exist", psz_name);
        return;
    }
314 315 316 317 318 319 320

    for (int i = 0; i < p_item->list_count; i++) {
        NSMenuItem *mi;
        if (p_item->list_text != NULL)
            mi = [[NSMenuItem alloc] initWithTitle: _NS(p_item->list_text[i]) action:NULL keyEquivalent: @""];
        else if (p_item->list.i[i])
            mi = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"%d", p_item->list.i[i]] action:NULL keyEquivalent: @""];
321
        else {
322
            msg_Err(getIntf(), "item %d of pref %s failed to be created", i, psz_name);
323 324 325
            continue;
        }

326 327 328
        [mi setTarget:self];
        [mi setAction:selector];
        [mi setTag:p_item->list.i[i]];
329
        [mi setRepresentedObject:toNSStr(psz_name)];
330
        [menu addItem:mi];
331 332 333
        if (p_item->value.i == p_item->list.i[i])
            [mi setState:NSOnState];
    }
334 335 336 337 338
}

- (void)initStrings
{
    /* main menu */
339
    [_about setTitle: [_NS("About VLC media player") \
340
                           stringByAppendingString: @"..."]];
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
    [_checkForUpdate setTitle: _NS("Check for Update...")];
    [_prefs setTitle: _NS("Preferences...")];
    [_extensions setTitle: _NS("Extensions")];
    [_extensionsMenu setTitle: _NS("Extensions")];
    [_addonManager setTitle: _NS("Addons Manager")];
    [_add_intf setTitle: _NS("Add Interface")];
    [_add_intfMenu setTitle: _NS("Add Interface")];
    [_services setTitle: _NS("Services")];
    [_hide setTitle: _NS("Hide VLC")];
    [_hide_others setTitle: _NS("Hide Others")];
    [_show_all setTitle: _NS("Show All")];
    [_quit setTitle: _NS("Quit VLC")];

    [_fileMenu setTitle: _ANS("1:File")];
    [_open_generic setTitle: _NS("Advanced Open File...")];
    [_open_file setTitle: _NS("Open File...")];
    [_open_disc setTitle: _NS("Open Disc...")];
    [_open_net setTitle: _NS("Open Network...")];
    [_open_capture setTitle: _NS("Open Capture Device...")];
    [_open_recent setTitle: _NS("Open Recent")];
    [_close_window setTitle: _NS("Close Window")];
    [_convertandsave setTitle: _NS("Convert / Stream...")];
    [_save_playlist setTitle: _NS("Save Playlist...")];
    [_revealInFinder setTitle: _NS("Reveal in Finder")];

    [_editMenu setTitle: _NS("Edit")];
    [_cutItem setTitle: _NS("Cut")];
    [_mcopyItem setTitle: _NS("Copy")];
    [_pasteItem setTitle: _NS("Paste")];
370
    [_clearItem setTitle: _NS("Delete")];
371
    [_select_all setTitle: _NS("Select All")];
372
    [_findItem setTitle: _NS("Find")];
373 374 375

    [_viewMenu setTitle: _NS("View")];
    [_toggleJumpButtons setTitle: _NS("Show Previous & Next Buttons")];
376
    [_toggleJumpButtons setState: var_InheritBool(getIntf(), "macosx-show-playback-buttons")];
377
    [_togglePlaymodeButtons setTitle: _NS("Show Shuffle & Repeat Buttons")];
378
    [_togglePlaymodeButtons setState: var_InheritBool(getIntf(), "macosx-show-playmode-buttons")];
379
    [_toggleEffectsButton setTitle: _NS("Show Audio Effects Button")];
380
    [_toggleEffectsButton setState: var_InheritBool(getIntf(), "macosx-show-effects-button")];
381 382 383 384 385 386 387
    [_toggleSidebar setTitle: _NS("Show Sidebar")];
    [_playlistTableColumns setTitle: _NS("Playlist Table Columns")];

    [_controlsMenu setTitle: _NS("Playback")];
    [_play setTitle: _NS("Play")];
    [_stop setTitle: _NS("Stop")];
    [_record setTitle: _NS("Record")];
388
    [_rate_view setAutoresizingMask:NSViewWidthSizable];
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
    [_rate setView: _rate_view];
    [_rateLabel setStringValue: _NS("Playback Speed")];
    [_rate_slowerLabel setStringValue: _NS("Slower")];
    [_rate_normalLabel setStringValue: _NS("Normal")];
    [_rate_fasterLabel setStringValue: _NS("Faster")];
    [_trackSynchronization setTitle: _NS("Track Synchronization")];
    [_previous setTitle: _NS("Previous")];
    [_next setTitle: _NS("Next")];
    [_random setTitle: _NS("Random")];
    [_repeat setTitle: _NS("Repeat One")];
    [_loop setTitle: _NS("Repeat All")];
    [_AtoBloop setTitle: _NS("A→B Loop")];
    [_quitAfterPB setTitle: _NS("Quit after Playback")];
    [_fwd setTitle: _NS("Step Forward")];
    [_bwd setTitle: _NS("Step Backward")];
    [_jumpToTime setTitle: _NS("Jump to Time")];
405 406
    [_rendererMenuItem setTitle:_NS("Renderer")];
    [_rendererNoneItem setTitle:_NS("No renderer")];
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
    [_program setTitle: _NS("Program")];
    [_programMenu setTitle: _NS("Program")];
    [_title setTitle: _NS("Title")];
    [_titleMenu setTitle: _NS("Title")];
    [_chapter setTitle: _NS("Chapter")];
    [_chapterMenu setTitle: _NS("Chapter")];

    [_audioMenu setTitle: _NS("Audio")];
    [_vol_up setTitle: _NS("Increase Volume")];
    [_vol_down setTitle: _NS("Decrease Volume")];
    [_mute setTitle: _NS("Mute")];
    [_audiotrack setTitle: _NS("Audio Track")];
    [_audiotrackMenu setTitle: _NS("Audio Track")];
    [_channels setTitle: _NS("Stereo audio mode")];
    [_channelsMenu setTitle: _NS("Stereo audio mode")];
    [_audioDevice setTitle: _NS("Audio Device")];
    [_audioDeviceMenu setTitle: _NS("Audio Device")];
    [_visual setTitle: _NS("Visualizations")];
    [_visualMenu setTitle: _NS("Visualizations")];

    [_videoMenu setTitle: _NS("Video")];
    [_half_window setTitle: _NS("Half Size")];
    [_normal_window setTitle: _NS("Normal Size")];
    [_double_window setTitle: _NS("Double Size")];
    [_fittoscreen setTitle: _NS("Fit to Screen")];
    [_fullscreenItem setTitle: _NS("Fullscreen")];
    [_floatontop setTitle: _NS("Float on Top")];
    [_snapshot setTitle: _NS("Snapshot")];
    [_videotrack setTitle: _NS("Video Track")];
    [_videotrackMenu setTitle: _NS("Video Track")];
    [_aspect_ratio setTitle: _NS("Aspect ratio")];
    [_aspect_ratioMenu setTitle: _NS("Aspect ratio")];
    [_crop setTitle: _NS("Crop")];
    [_cropMenu setTitle: _NS("Crop")];
    [_screen setTitle: _NS("Fullscreen Video Device")];
    [_screenMenu setTitle: _NS("Fullscreen Video Device")];
    [_deinterlace setTitle: _NS("Deinterlace")];
    [_deinterlaceMenu setTitle: _NS("Deinterlace")];
    [_deinterlace_mode setTitle: _NS("Deinterlace mode")];
    [_deinterlace_modeMenu setTitle: _NS("Deinterlace mode")];
    [_postprocessing setTitle: _NS("Post processing")];
    [_postprocessingMenu setTitle: _NS("Post processing")];

    [_subtitlesMenu setTitle:_NS("Subtitles")];
    [_openSubtitleFile setTitle: _NS("Add Subtitle File...")];
    [_subtitle_track setTitle: _NS("Subtitles Track")];
    [_subtitle_tracksMenu setTitle: _NS("Subtitles Track")];
    [_subtitle_size setTitle: _NS("Text Size")];
    [_subtitle_textcolor setTitle: _NS("Text Color")];
    [_subtitle_outlinethickness setTitle: _NS("Outline Thickness")];
457 458 459 460

    // Autoresizing with constraints does not work on 10.7,
    // translate autoresizing mask to constriaints for now
    [_subtitle_bgopacity_view setAutoresizingMask:NSViewWidthSizable];
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
    [_subtitle_bgopacity setView: _subtitle_bgopacity_view];
    [_subtitle_bgopacityLabel setStringValue: _NS("Background Opacity")];
    [_subtitle_bgopacityLabel_gray setStringValue: _NS("Background Opacity")];
    [_subtitle_bgcolor setTitle: _NS("Background Color")];
    [_teletext setTitle: _NS("Teletext")];
    [_teletext_transparent setTitle: _NS("Transparent")];
    [_teletext_index setTitle: _NS("Index")];
    [_teletext_red setTitle: _NS("Red")];
    [_teletext_green setTitle: _NS("Green")];
    [_teletext_yellow setTitle: _NS("Yellow")];
    [_teletext_blue setTitle: _NS("Blue")];

    [_windowMenu setTitle: _NS("Window")];
    [_minimize setTitle: _NS("Minimize")];
    [_zoom_window setTitle: _NS("Zoom")];
    [_player setTitle: _NS("Player...")];
    [_controller setTitle: _NS("Main Window...")];
    [_audioeffects setTitle: _NS("Audio Effects...")];
    [_videoeffects setTitle: _NS("Video Effects...")];
    [_bookmarks setTitle: _NS("Bookmarks...")];
    [_playlist setTitle: _NS("Playlist...")];
    [_info setTitle: _NS("Media Information...")];
    [_messages setTitle: _NS("Messages...")];
    [_errorsAndWarnings setTitle: _NS("Errors and Warnings...")];

    [_bring_atf setTitle: _NS("Bring All to Front")];

    [_helpMenu setTitle: _NS("Help")];
    [_help setTitle: _NS("VLC media player Help...")];
    [_license setTitle: _NS("License")];
    [_documentation setTitle: _NS("Online Documentation...")];
    [_website setTitle: _NS("VideoLAN Website...")];
    [_donation setTitle: _NS("Make a donation...")];
    [_forum setTitle: _NS("Online Forum...")];
495 496

    /* dock menu */
497 498 499 500 501
    [_dockMenuplay setTitle: _NS("Play")];
    [_dockMenustop setTitle: _NS("Stop")];
    [_dockMenunext setTitle: _NS("Next")];
    [_dockMenuprevious setTitle: _NS("Previous")];
    [_dockMenumute setTitle: _NS("Mute")];
502 503

    /* vout menu */
504 505 506 507 508 509 510 511 512
    [_voutMenuplay setTitle: _NS("Play")];
    [_voutMenustop setTitle: _NS("Stop")];
    [_voutMenuprev setTitle: _NS("Previous")];
    [_voutMenunext setTitle: _NS("Next")];
    [_voutMenuvolup setTitle: _NS("Volume Up")];
    [_voutMenuvoldown setTitle: _NS("Volume Down")];
    [_voutMenumute setTitle: _NS("Mute")];
    [_voutMenufullscreen setTitle: _NS("Fullscreen")];
    [_voutMenusnapshot setTitle: _NS("Snapshot")];
513 514
}

515
#pragma mark - Termination
516 517 518 519

- (void)releaseRepresentedObjects:(NSMenu *)the_menu
{
    NSArray *menuitems_array = [the_menu itemArray];
520
    NSUInteger menuItemCount = [menuitems_array count];
521
    for (NSUInteger i=0; i < menuItemCount; i++) {
522
        NSMenuItem *one_item = [menuitems_array objectAtIndex:i];
523
        if ([one_item hasSubmenu])
524 525 526 527 528 529
            [self releaseRepresentedObjects: [one_item submenu]];

        [one_item setRepresentedObject:NULL];
    }
}

530
#pragma mark - Interface update
531 532 533

- (void)setupMenus
{
534
    playlist_t *p_playlist = pl_Get(getIntf());
535
    input_thread_t *p_input = playlist_CurrentInput(p_playlist);
536
    if (p_input != NULL) {
537 538
        [self setupVarMenuItem:_program target: (vlc_object_t *)p_input
                                 var:"program" selector: @selector(toggleVar:)];
539

540 541
        [self setupVarMenuItem:_title target: (vlc_object_t *)p_input
                                 var:"title" selector: @selector(toggleVar:)];
542

543 544
        [self setupVarMenuItem:_chapter target: (vlc_object_t *)p_input
                                 var:"chapter" selector: @selector(toggleVar:)];
545

546 547
        [self setupVarMenuItem:_audiotrack target: (vlc_object_t *)p_input
                                 var:"audio-es" selector: @selector(toggleVar:)];
548

549 550
        [self setupVarMenuItem:_videotrack target: (vlc_object_t *)p_input
                                 var:"video-es" selector: @selector(toggleVar:)];
551

552 553
        [self setupVarMenuItem:_subtitle_track target: (vlc_object_t *)p_input
                                 var:"spu-es" selector: @selector(toggleVar:)];
554

555
        audio_output_t *p_aout = playlist_GetAout(p_playlist);
556
        if (p_aout != NULL) {
557 558
            [self setupVarMenuItem:_channels target: (vlc_object_t *)p_aout
                                     var:"stereo-mode" selector: @selector(toggleVar:)];
559

560 561
            [self setupVarMenuItem:_visual target: (vlc_object_t *)p_aout
                                     var:"visual" selector: @selector(toggleVar:)];
562
            vlc_object_release(p_aout);
563 564
        }

565
        vout_thread_t *p_vout = getVoutForActiveWindow();
566

567
        if (p_vout != NULL) {
568 569
            [self setupVarMenuItem:_aspect_ratio target: (vlc_object_t *)p_vout
                                     var:"aspect-ratio" selector: @selector(toggleVar:)];
570

571 572
            [self setupVarMenuItem:_crop target: (vlc_object_t *) p_vout
                                     var:"crop" selector: @selector(toggleVar:)];
573

574 575
            [self setupVarMenuItem:_deinterlace target: (vlc_object_t *)p_vout
                                     var:"deinterlace" selector: @selector(toggleVar:)];
576

577 578
            [self setupVarMenuItem:_deinterlace_mode target: (vlc_object_t *)p_vout
                                     var:"deinterlace-mode" selector: @selector(toggleVar:)];
579

580
            vlc_object_release(p_vout);
581 582

            [self refreshVoutDeviceMenu:nil];
583
        }
584
        [_postprocessing setEnabled:YES];
585
        vlc_object_release(p_input);
586
    } else {
587
        [_postprocessing setEnabled:NO];
588
    }
589 590
}

591
- (void)refreshVoutDeviceMenu:(NSNotification *)notification
592
{
593 594
    NSUInteger count = (NSUInteger) [_screenMenu numberOfItems];
    NSMenu *submenu = _screenMenu;
595
    if (count > 0)
596 597 598 599 600 601 602 603 604 605 606
        [submenu removeAllItems];

    NSArray *screens = [NSScreen screens];
    NSMenuItem *mitem;
    count = [screens count];
    [_screen setEnabled: YES];
    [submenu addItemWithTitle: _NS("Default") action:@selector(toggleFullscreenDevice:) keyEquivalent:@""];
    mitem = [submenu itemAtIndex: 0];
    [mitem setTag: 0];
    [mitem setEnabled: YES];
    [mitem setTarget: self];
607
    NSRect s_rect;
608
    for (NSUInteger i = 0; i < count; i++) {
609 610
        s_rect = [[screens objectAtIndex:i] frame];
        [submenu addItemWithTitle: [NSString stringWithFormat: @"%@ %li (%ix%i)", _NS("Screen"), i+1,
611
                                      (int)s_rect.size.width, (int)s_rect.size.height] action:@selector(toggleFullscreenDevice:) keyEquivalent:@""];
612 613 614 615
        mitem = [submenu itemAtIndex:i+1];
        [mitem setTag: (int)[[screens objectAtIndex:i] displayID]];
        [mitem setEnabled: YES];
        [mitem setTarget: self];
616
    }
617
    [[submenu itemWithTag: var_InheritInteger(getIntf(), "macosx-vdev")] setState: NSOnState];
618 619 620 621
}

- (void)setSubmenusEnabled:(BOOL)b_enabled
{
622 623 624 625 626 627 628 629 630 631 632 633 634
    [_program setEnabled: b_enabled];
    [_title setEnabled: b_enabled];
    [_chapter setEnabled: b_enabled];
    [_audiotrack setEnabled: b_enabled];
    [_visual setEnabled: b_enabled];
    [_videotrack setEnabled: b_enabled];
    [_subtitle_track setEnabled: b_enabled];
    [_channels setEnabled: b_enabled];
    [_deinterlace setEnabled: b_enabled];
    [_deinterlace_mode setEnabled: b_enabled];
    [_screen setEnabled: b_enabled];
    [_aspect_ratio setEnabled: b_enabled];
    [_crop setEnabled: b_enabled];
635 636 637 638
}

- (void)setSubtitleMenuEnabled:(BOOL)b_enabled
{
639
    [_openSubtitleFile setEnabled: b_enabled];
640
    if (b_enabled) {
641 642
        [_subtitle_bgopacityLabel_gray setHidden: YES];
        [_subtitle_bgopacityLabel setHidden: NO];
643
    } else {
644 645
        [_subtitle_bgopacityLabel_gray setHidden: NO];
        [_subtitle_bgopacityLabel setHidden: YES];
646
    }
647 648
    [_subtitle_bgopacity_sld setEnabled: b_enabled];
    [_teletext setEnabled: b_enabled];
649 650
}

651 652
- (void)setRateControlsEnabled:(BOOL)b_enabled
{
653 654
    [_rate_sld setEnabled: b_enabled];
    [_rate_sld setIntValue: [[VLCCoreInteraction sharedInstance] playbackRate]];
655
    int i = [[VLCCoreInteraction sharedInstance] playbackRate];
656
    double speed =  pow(2, (double)i / 17);
657
    [_rateTextField setStringValue: [NSString stringWithFormat:@"%.2fx", speed]];
658

659
    NSColor *color = b_enabled ? [NSColor controlTextColor] : [NSColor disabledControlTextColor];
660

661 662 663 664 665
    [_rateLabel setTextColor:color];
    [_rate_slowerLabel setTextColor:color];
    [_rate_normalLabel setTextColor:color];
    [_rate_fasterLabel setTextColor:color];
    [_rateTextField setTextColor:color];
666

667
    [self setSubtitleMenuEnabled: b_enabled];
668 669
}

670
#pragma mark - View
671 672 673

- (IBAction)toggleEffectsButton:(id)sender
{
674
    BOOL b_value = !var_InheritBool(getIntf(), "macosx-show-effects-button");
675
    config_PutInt(getIntf(), "macosx-show-effects-button", b_value);
676
    [(VLCMainWindowControlsBar *)[[[VLCMain sharedInstance] mainWindow] controlsBar] toggleEffectsButton];
677
    [_toggleEffectsButton setState: b_value];
678 679
}

680 681
- (IBAction)toggleJumpButtons:(id)sender
{
682
    BOOL b_value = !var_InheritBool(getIntf(), "macosx-show-playback-buttons");
683
    config_PutInt(getIntf(), "macosx-show-playback-buttons", b_value);
684

685
    [(VLCMainWindowControlsBar *)[[[VLCMain sharedInstance] mainWindow] controlsBar] toggleJumpButtons];
686 687
    [[[VLCMain sharedInstance] voutController] updateWindowsUsingBlock:^(VLCVideoWindowCommon *window) {
        [[window controlsBar] toggleForwardBackwardMode: b_value];
688 689
    }];

690
    [_toggleJumpButtons setState: b_value];
691 692
}

693 694
- (IBAction)togglePlaymodeButtons:(id)sender
{
695
    BOOL b_value = !var_InheritBool(getIntf(), "macosx-show-playmode-buttons");
696
    config_PutInt(getIntf(), "macosx-show-playmode-buttons", b_value);
697
    [(VLCMainWindowControlsBar *)[[[VLCMain sharedInstance] mainWindow] controlsBar] togglePlaymodeButtons];
698
    [_togglePlaymodeButtons setState: b_value];
699 700
}

701 702 703 704 705
- (IBAction)toggleSidebar:(id)sender
{
    [[[VLCMain sharedInstance] mainWindow] toggleLeftSubSplitView];
}

706
- (void)updateSidebarMenuItem:(BOOL)show;
707
{
708
    [_toggleSidebar setState:show];
709 710
}

711
#pragma mark - Playback
712

713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740
- (IBAction)play:(id)sender
{
    [[VLCCoreInteraction sharedInstance] playOrPause];
}

- (IBAction)stop:(id)sender
{
    [[VLCCoreInteraction sharedInstance] stop];
}

- (IBAction)prev:(id)sender
{
    [[VLCCoreInteraction sharedInstance] previous];
}

- (IBAction)next:(id)sender
{
    [[VLCCoreInteraction sharedInstance] next];
}

- (IBAction)random:(id)sender
{
    [[VLCCoreInteraction sharedInstance] shuffle];
}

- (IBAction)repeat:(id)sender
{
    vlc_value_t val;
741
    intf_thread_t *p_intf = getIntf();
742 743 744 745 746 747 748 749 750 751 752 753
    playlist_t *p_playlist = pl_Get(p_intf);

    var_Get(p_playlist, "repeat", &val);
    if (! val.b_bool)
        [[VLCCoreInteraction sharedInstance] repeatOne];
    else
        [[VLCCoreInteraction sharedInstance] repeatOff];
}

- (IBAction)loop:(id)sender
{
    vlc_value_t val;
754
    intf_thread_t *p_intf = getIntf();
755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
    playlist_t *p_playlist = pl_Get(p_intf);

    var_Get(p_playlist, "loop", &val);
    if (! val.b_bool)
        [[VLCCoreInteraction sharedInstance] repeatAll];
    else
        [[VLCCoreInteraction sharedInstance] repeatOff];
}

- (IBAction)forward:(id)sender
{
    [[VLCCoreInteraction sharedInstance] forward];
}

- (IBAction)backward:(id)sender
{
    [[VLCCoreInteraction sharedInstance] backward];
}

- (IBAction)volumeUp:(id)sender
{
    [[VLCCoreInteraction sharedInstance] volumeUp];
}

- (IBAction)volumeDown:(id)sender
{
    [[VLCCoreInteraction sharedInstance] volumeDown];
}

- (IBAction)mute:(id)sender
{
    [[VLCCoreInteraction sharedInstance] toggleMute];
}

- (void)lockVideosAspectRatio:(id)sender
{
    [[VLCCoreInteraction sharedInstance] setAspectRatioIsLocked: ![sender state]];
    [sender setState: [[VLCCoreInteraction sharedInstance] aspectRatioIsLocked]];
}

795 796
- (IBAction)quitAfterPlayback:(id)sender
{
797
    playlist_t *p_playlist = pl_Get(getIntf());
798 799
    bool b_value = !var_CreateGetBool(p_playlist, "play-and-exit");
    var_SetBool(p_playlist, "play-and-exit", b_value);
800
    config_PutInt(getIntf(), "play-and-exit", b_value);
801 802
}

803 804 805 806 807 808 809
- (IBAction)toggleRecord:(id)sender
{
    [[VLCCoreInteraction sharedInstance] toggleRecord];
}

- (void)updateRecordState:(BOOL)b_value
{
810
    [_record setState:b_value];
811 812 813 814
}

- (IBAction)setPlaybackRate:(id)sender
{
815
    [[VLCCoreInteraction sharedInstance] setPlaybackRate: [_rate_sld intValue]];
816
    int i = [[VLCCoreInteraction sharedInstance] playbackRate];
817
    double speed =  pow(2, (double)i / 17);
818
    [_rateTextField setStringValue: [NSString stringWithFormat:@"%.2fx", speed]];
819 820 821 822 823
}

- (void)updatePlaybackRate
{
    int i = [[VLCCoreInteraction sharedInstance] playbackRate];
824
    double speed =  pow(2, (double)i / 17);
825 826
    [_rateTextField setStringValue: [NSString stringWithFormat:@"%.2fx", speed]];
    [_rate_sld setIntValue: i];
827 828
}

829 830 831 832 833
- (IBAction)toggleAtoBloop:(id)sender
{
    [[VLCCoreInteraction sharedInstance] setAtoB];
}

834 835
- (IBAction)goToSpecificTime:(id)sender
{
836
    input_thread_t *p_input = pl_CurrentInput(getIntf());
837 838 839 840 841 842 843 844 845 846 847 848
    if (p_input) {
        /* we can obviously only do that if an input is available */
        int64_t length = var_GetInteger(p_input, "length");
        [_timeSelectionPanel setMaxValue:(length / CLOCK_FREQ)];
        int64_t pos = var_GetInteger(p_input, "time");
        [_timeSelectionPanel setJumpTimeValue: (pos / CLOCK_FREQ)];
        [_timeSelectionPanel runModalForWindow:[NSApp mainWindow]
                             completionHandler:^(NSInteger returnCode, int64_t returnTime) {

            if (returnCode != NSOKButton)
                return;

849
            input_thread_t *p_input = pl_CurrentInput(getIntf());
850 851 852
            if (p_input) {
                input_Control(p_input, INPUT_SET_TIME, (int64_t)(returnTime *1000000));
                vlc_object_release(p_input);
853
            }
854
        }];
855

856
        vlc_object_release(p_input);
857 858 859
    }
}

860 861 862 863 864
- (IBAction)selectRenderer:(id)sender
{
    [_rendererMenuController selectRenderer:sender];
}

865 866
#pragma mark - audio menu

867 868 869 870 871
- (void)refreshAudioDeviceList
{
    char **ids, **names;
    char *currentDevice;

872
    [_audioDeviceMenu removeAllItems];
873

874
    audio_output_t *p_aout = getAout();
875 876 877 878
    if (!p_aout)
        return;

    int n = aout_DevicesList(p_aout, &ids, &names);
879 880
    if (n == -1) {
        vlc_object_release(p_aout);
881
        return;
882
    }
883 884

    currentDevice = aout_DeviceGet(p_aout);
885
    NSMenuItem *_tmp;
886 887

    for (NSUInteger x = 0; x < n; x++) {
888 889 890
        _tmp = [_audioDeviceMenu addItemWithTitle:toNSStr(names[x]) action:@selector(toggleAudioDevice:) keyEquivalent:@""];
        [_tmp setTarget:self];
        [_tmp setTag:[[NSString stringWithFormat:@"%s", ids[x]] intValue]];
891 892 893
    }
    vlc_object_release(p_aout);

894
    [[_audioDeviceMenu itemWithTag:[[NSString stringWithFormat:@"%s", currentDevice] intValue]] setState:NSOnState];
895

896 897
    free(currentDevice);

898 899 900 901 902 903 904
    for (NSUInteger x = 0; x < n; x++) {
        free(ids[x]);
        free(names[x]);
    }
    free(ids);
    free(names);

905 906
    [_audioDeviceMenu setAutoenablesItems:YES];
    [_audioDevice setEnabled:YES];
907 908
}

909
- (void)toggleAudioDevice:(id)sender
910
{
911
    audio_output_t *p_aout = getAout();
912 913
    if (!p_aout)
        return;
914 915 916 917

    int returnValue = 0;

    if ([sender tag] > 0)
918
        returnValue = aout_DeviceSet(p_aout, [[NSString stringWithFormat:@"%li", [sender tag]] UTF8String]);
919
    else
920
        returnValue = aout_DeviceSet(p_aout, NULL);
921 922

    if (returnValue != 0)
923
        msg_Warn(getIntf(), "failed to set audio device %li", [sender tag]);
924

925
    vlc_object_release(p_aout);
926 927 928
    [self refreshAudioDeviceList];
}

929
#pragma mark - video menu
930

931 932 933 934 935 936 937
- (IBAction)toggleFullscreen:(id)sender
{
    [[VLCCoreInteraction sharedInstance] toggleFullscreen];
}

- (IBAction)resizeVideoWindow:(id)sender
{
938
    input_thread_t *p_input = pl_CurrentInput(getIntf());
939
    if (p_input) {
940
        vout_thread_t *p_vout = getVoutForActiveWindow();
941
        if (p_vout) {
942
            if (sender == _half_window)
943
                var_SetFloat(p_vout, "zoom", 0.5);
944
            else if (sender == _normal_window)
945
                var_SetFloat(p_vout, "zoom", 1.0);
946
            else if (sender == _double_window)
947
                var_SetFloat(p_vout, "zoom", 2.0);
948 949
            else
            {
950
                [[NSApp keyWindow] performZoom:sender];
951
            }
952
            vlc_object_release(p_vout);
953
        }
954
        vlc_object_release(p_input);
955 956 957 958 959
    }
}

- (IBAction)floatOnTop:(id)sender
{
960
    input_thread_t *p_input = pl_CurrentInput(getIntf());
961
    if (p_input) {
962
        vout_thread_t *p_vout = getVoutForActiveWindow();
963
        if (p_vout) {
964
            BOOL b_fs = var_ToggleBool(p_vout, "video-on-top");
965
            var_SetBool(pl_Get(getIntf()), "video-on-top", b_fs);
966

967
            vlc_object_release(p_vout);
968
        }
969
        vlc_object_release(p_input);
970 971 972 973 974
    }
}

- (IBAction)createVideoSnapshot:(id)sender
{
975
    input_thread_t *p_input = pl_CurrentInput(getIntf());
976
    if (p_input) {
977
        vout_thread_t *p_vout = getVoutForActiveWindow();
978 979 980
        if (p_vout) {
            var_TriggerCallback(p_vout, "video-snapshot");
            vlc_object_release(p_vout);
981
        }
982
        vlc_object_release(p_input);
983 984 985
    }
}

986 987
- (void)_disablePostProcessing
{
988
    [[VLCCoreInteraction sharedInstance] setVideoFilter:"postproc" on:false];
989 990 991 992
}

- (void)_enablePostProcessing
{
993
    [[VLCCoreInteraction sharedInstance] setVideoFilter:"postproc" on:true];
994 995
}

996
- (void)togglePostProcessing:(id)sender
997
{
998
    char *psz_name = "postproc";
999
    NSInteger count = [_postprocessingMenu numberOfItems];
1000
    for (NSUInteger x = 0; x < count; x++)
1001
        [[_postprocessingMenu itemAtIndex:x] setState:NSOffState];
1002 1003 1004 1005 1006 1007 1008 1009

    if ([sender tag] == -1) {
        [self _disablePostProcessing];
        [sender setState:NSOnState];
    } else {
        [self _enablePostProcessing];
        [sender setState:NSOnState];

1010
        [[VLCCoreInteraction sharedInstance] setVideoFilterProperty:"postproc-q" forFilter:"postproc" withValue:(vlc_value_t){ .i_int = [sender tag] }];
1011 1012 1013
    }
}

1014
- (void)toggleFullscreenDevice:(id)sender
1015
{
1016
    config_PutInt(getIntf(), "macosx-vdev", [sender tag]);
1017 1018 1019
    [self refreshVoutDeviceMenu: nil];
}

1020
#pragma mark - Subtitles Menu
1021

1022 1023 1024
- (IBAction)addSubtitleFile:(id)sender
{
    NSInteger i_returnValue = 0;
1025
    input_thread_t *p_input = pl_CurrentInput(getIntf());
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
    if (!p_input)
        return;

    input_item_t *p_item = input_GetItem(p_input);
    if (!p_item) {
        vlc_object_release(p_input);
        return;
    }

    char *path = input_item_GetURI(p_item);
1036

1037 1038 1039
    if (!path)
        path = strdup("");

1040
    NSOpenPanel *openPanel = [NSOpenPanel openPanel];
1041 1042 1043
    [openPanel setCanChooseFiles: YES];
    [openPanel setCanChooseDirectories: NO];
    [openPanel setAllowsMultipleSelection: YES];
1044

1045
    [openPanel setAllowedFileTypes: [NSArray arrayWithObjects:@"cdg",@"idx",@"srt",@"sub",@"utf",@"ass",@"ssa",@"aqt",@"jss",@"psb",@"rt",@"smi",@"txt",@"smil",@"stl",@"usf",@"dks",@"pjs",@"mpl2",@"mks",@"vtt",@"ttml",@"dfxp",nil]];
1046

1047
    NSURL *url = [NSURL URLWithString:[toNSStr(path) stringByExpandingTildeInPath]];
1048 1049
    url = [url URLByDeletingLastPathComponent];
    [openPanel setDirectoryURL: url];
1050
    free(path);
1051
    vlc_object_release(p_input);
1052

1053 1054
    i_returnValue = [openPanel runModal];

1055 1056
    if (i_returnValue == NSOKButton)
        [[VLCCoreInteraction sharedInstance] addSubtitlesToCurrentInput:[openPanel URLs]];
1057 1058
}

1059 1060 1061
- (void)switchSubtitleSize:(id)sender
{
    int intValue = [sender tag];
1062
    var_SetInteger(pl_Get(getIntf()), "sub-text-scale", intValue);
1063 1064 1065
}


1066
- (void)switchSubtitleOption:(id)sender
1067 1068 1069 1070
{
    int intValue = [sender tag];
    NSString *representedObject = [sender representedObject];

1071
    var_SetInteger(pl_Get(getIntf()), [representedObject UTF8String], intValue);
1072 1073

    NSMenu *menu = [sender menu];
1074
    NSUInteger count = (NSUInteger) [menu numberOfItems];
1075 1076 1077
    for (NSUInteger x = 0; x < count; x++)
        [[menu itemAtIndex:x] setState:NSOffState];
    [[menu itemWithTag:intValue] setState:NSOnState];
1078 1079 1080 1081
}

- (IBAction)switchSubtitleBackgroundOpacity:(id)sender
{
1082
    var_SetInteger(pl_Get(getIntf()), "freetype-background-opacity", [sender intValue]);
1083 1084
}

1085 1086 1087
- (IBAction)telxTransparent:(id)sender
{
    vlc_object_t *p_vbi;
1088
    p_vbi = (vlc_object_t *) vlc_object_find_name(pl_Get(getIntf()), "zvbi");
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
    if (p_vbi) {
        var_SetBool(p_vbi, "vbi-opaque", [sender state]);
        [sender setState: ![sender state]];
        vlc_object_release(p_vbi);
    }
}

- (IBAction)telxNavLink:(id)sender
{
    vlc_object_t *p_vbi;
    int i_page = 0;

    if ([[sender title] isEqualToString: _NS("Index")])
        i_page = 'i' << 16;
    else if ([[sender title] isEqualToString: _NS("Red")])
        i_page = 'r' << 16;
    else if ([[sender title] isEqualToString: _NS("Green")])
        i_page = 'g' << 16;
    else if ([[sender title] isEqualToString: _NS("Yellow")])
        i_page = 'y' << 16;
    else if ([[sender title] isEqualToString: _NS("Blue")])
        i_page = 'b' << 16;
    if (i_page == 0) return;

1113
    p_vbi = (vlc_object_t *) vlc_object_find_name(pl_Get(getIntf()), "zvbi");
1114 1115 1116 1117 1118 1119
    if (p_vbi) {
        var_SetInteger(p_vbi, "vbi-page", i_page);
        vlc_object_release(p_vbi);
    }
}

1120
#pragma mark - Panels
1121 1122 1123

- (IBAction)intfOpenFile:(id)sender
{
1124 1125 1126
    [[[VLCMain sharedInstance] open] openFileWithAction:^(NSArray *files) {
        [[[VLCMain sharedInstance] playlist] addPlaylistItems:files];
    }];
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
}

- (IBAction)intfOpenFileGeneric:(id)sender
{
    [[[VLCMain sharedInstance] open] openFileGeneric];
}

- (IBAction)intfOpenDisc:(id)sender
{
    [[[VLCMain sharedInstance] open] openDisc];
}

- (IBAction)intfOpenNet:(id)sender
{
    [[[VLCMain sharedInstance] open] openNet];
}

- (IBAction)intfOpenCapture:(id)sender
{
    [[[VLCMain sharedInstance] open] openCapture];
}

1149 1150
- (IBAction)savePlaylist:(id)sender
{
1151
    playlist_t *p_playlist = pl_Get(getIntf());
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183

    NSSavePanel *savePanel = [NSSavePanel savePanel];
    NSString * name = [NSString stringWithFormat: @"%@", _NS("Untitled")];

    [NSBundle loadNibNamed:@"PlaylistAccessoryView" owner:self];

    [_playlistSaveAccessoryText setStringValue: _NS("File Format:")];
    [[_playlistSaveAccessoryPopup itemAtIndex:0] setTitle: _NS("Extended M3U")];
    [[_playlistSaveAccessoryPopup itemAtIndex:1] setTitle: _NS("XML Shareable Playlist Format (XSPF)")];
    [[_playlistSaveAccessoryPopup itemAtIndex:2] setTitle: _NS("HTML playlist")];

    [savePanel setTitle: _NS("Save Playlist")];
    [savePanel setPrompt: _NS("Save")];
    [savePanel setAccessoryView: _playlistSaveAccessoryView];
    [savePanel setNameFieldStringValue: name];

    if ([savePanel runModal] == NSFileHandlingPanelOKButton) {
        NSString *filename = [[savePanel URL] path];

        if ([_playlistSaveAccessoryPopup indexOfSelectedItem] == 0) {
            NSString *actualFilename;
            NSRange range;
            range.location = [filename length] - [@".m3u" length];
            range.length = [@".m3u" length];

            if ([filename compare:@".m3u" options: NSCaseInsensitiveSearch range: range] != NSOrderedSame)
                actualFilename = [NSString stringWithFormat: @"%@.m3u", filename];
            else
                actualFilename = filename;

            playlist_Export(p_playlist,
                            [actualFilename fileSystemRepresentation],
1184
                            true, "export-m3u");
1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197
        } else if ([_playlistSaveAccessoryPopup indexOfSelectedItem] == 1) {
            NSString *actualFilename;
            NSRange range;
            range.location = [filename length] - [@".xspf" length];
            range.length = [@".xspf" length];

            if ([filename compare:@".xspf" options: NSCaseInsensitiveSearch range: range] != NSOrderedSame)
                actualFilename = [NSString stringWithFormat: @"%@.xspf", filename];
            else
                actualFilename = filename;

            playlist_Export(p_playlist,
                            [actualFilename fileSystemRepresentation],
1198
                            true, "export-xspf");
1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211
        } else {
            NSString *actualFilename;
            NSRange range;
            range.location = [filename length] - [@".html" length];
            range.length = [@".html" length];

            if ([filename compare:@".html" options: NSCaseInsensitiveSearch range: range] != NSOrderedSame)
                actualFilename = [NSString stringWithFormat: @"%@.html", filename];
            else
                actualFilename = filename;

            playlist_Export(p_playlist,
                            [actualFilename fileSystemRepresentation],
1212
                            true, "export-html");
1213 1214
        }
    }
Felix Paul Kühne's avatar