]> git.sesse.net Git - vlc/blob - modules/gui/macosx/ConvertAndSave.m
macosx: CAS: implemented information retrieval from the customization panel
[vlc] / modules / gui / macosx / ConvertAndSave.m
1 /*****************************************************************************
2  * ConvertAndSave.h: MacOS X interface module
3  *****************************************************************************
4  * Copyright (C) 2012 Felix Paul Kühne
5  * $Id$
6  *
7  * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 #import "ConvertAndSave.h"
25 #import "intf.h"
26 #import <vlc_common.h>
27 #import <vlc_url.h>
28
29 /* mini doc:
30  * the used NSMatrix includes a bunch of cells referenced most easily by tags. There you go: */
31 #define MPEGTS 0
32 #define WEBM 1
33 #define OGG 2
34 #define MP4 3
35 #define MPEGPS 4
36 #define MJPEG 5
37 #define WAV 6
38 #define FLV 7
39 #define MPEG1 8
40 #define MKV 9
41 #define RAW 10
42 #define AVI 11
43 #define ASF 12
44 /* 13-15 are present, but not set */
45
46 @implementation VLCConvertAndSave
47
48 @synthesize MRL=_MRL, outputDestination=_outputDestination, profileNames=_profileNames, profileValueList=_profileValueList, currentProfile=_currentProfile;
49
50 static VLCConvertAndSave *_o_sharedInstance = nil;
51
52 #pragma mark -
53 #pragma mark Initialization
54
55 + (void)initialize{
56     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
57
58     /* We are using the same format as the Qt4 intf here:
59      * Container(string), transcode video(bool), transcode audio(bool),
60      * use subtitles(bool), video codec(string), video bitrate(integer),
61      * scale(float), fps(float), width(integer, height(integer),
62      * audio codec(string), audio bitrate(integer), channels(integer),
63      * samplerate(integer), subtitle codec(string), subtitle overlay(bool) */
64     NSArray * defaultProfiles = [[NSArray alloc] initWithObjects:
65                                  @"mp4;1;1;0;h264;0;0;0;0;0;mpga;128;2;44100;0;1",
66                                  @"webm;1;1;0;VP80;2000;0;0;0;0;vorb;128;2;44100;0;1",
67                                  @"ts;1;1;0;h264;800;1;0;0;0;mpga;128;2;44100;0;0",
68                                  @"ts;1;1;0;drac;800;1;0;0;0;mpga;128;2;44100;0;0",
69                                  @"ogg;1;1;0;theo;800;1;0;0;0;vorb;128;2;44100;0;0",
70                                  @"ogg;1;1;0;theo;800;1;0;0;0;flac;128;2;44100;0;0",
71                                  @"ts;1;1;0;mp2v;800;1;0;0;0;mpga;128;2;44100;0;0",
72                                  @"asf;1;1;0;WMV2;800;1;0;0;0;wma2;128;2;44100;0;0",
73                                  @"asf;1;1;0;DIV3;800;1;0;0;0;mp3;128;2;44100;0;0",
74                                  @"ogg;1;1;0;none;800;1;0;0;0;vorb;128;2;44100;none;0",
75                                  @"raw;1;1;0;none;800;1;0;0;0;mp3;128;2;44100;none;0",
76                                  @"mp4;1;1;0;none;800;1;0;0;0;mpga;128;2;44100;none;0",
77                                  @"raw;1;1;0;none;800;1;0;0;0;flac;128;2;44100;none;0",
78                                  @"wav;1;1;0;none;800;1;0;0;0;s16l;128;2;44100;none;0", nil];
79
80     NSArray * defaultProfileNames = [[NSArray alloc] initWithObjects:
81                                      @"Video - H.264 + MP3 (MP4)",
82                                      @"Video - VP80 + Vorbis (Webm)",
83                                      @"Video - H.264 + MP3 (TS)",
84                                      @"Video - Dirac + MP3 (TS)",
85                                      @"Video - Theora + Vorbis (OGG)",
86                                      @"Video - Theora + Flac (OGG)",
87                                      @"Video - MPEG-2 + MPGA (TS)",
88                                      @"Video - WMV + WMA (ASF)",
89                                      @"Video - DIV3 + MP3 (ASF)",
90                                      @"Audio - Vorbis (OGG)",
91                                      @"Audio - MP3",
92                                      @"Audio - MP3 (MP4)",
93                                      @"Audio - FLAC",
94                                      @"Audio - CD",
95                                      nil];
96
97     NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:defaultProfiles, @"CASProfiles", defaultProfileNames, @"CASProfileNames", nil];
98
99     [defaults registerDefaults:appDefaults];
100     [defaultProfiles release];
101 }
102
103 + (VLCConvertAndSave *)sharedInstance
104 {
105     return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
106 }
107
108 - (id)init
109 {
110     if (_o_sharedInstance) {
111         [self dealloc];
112     } else {
113         _o_sharedInstance = [super init];
114     }
115
116     return _o_sharedInstance;
117 }
118
119 - (void)dealloc
120 {
121     if (_currentProfile)
122         [_currentProfile release];
123
124     [_profileNames release];
125     [_profileValueList release];
126     [_videoCodecs release];
127     [_audioCodecs release];
128     [_subsCodecs release];
129
130     [super dealloc];
131 }
132
133 - (void)awakeFromNib
134 {
135     [_window setTitle: _NS("Convert & Save")];
136     [_cancel_btn setTitle: _NS("Cancel")];
137     [_ok_btn setTitle: _NS("Save")];
138     [_drop_lbl setStringValue: _NS("Drop media here")];
139     [_drop_btn setTitle: _NS("Open media...")];
140     [_profile_lbl setStringValue: _NS("Choose Profile")];
141     [_profile_btn setTitle: _NS("Customize")];
142     [_destination_lbl setStringValue: _NS("Choose Destination")];
143     [_destination_filename_stub_lbl setStringValue: _NS("Choose an output location")];
144     [_destination_filename_lbl setHidden: YES];
145     [_customize_ok_btn setTitle: _NS("Apply")];
146     [_customize_cancel_btn setTitle: _NS("Cancel")];
147     [[_customize_tabview tabViewItemAtIndex:0] setLabel: _NS("Encapsulation")];
148     [[_customize_tabview tabViewItemAtIndex:1] setLabel: _NS("Video codec")];
149     [[_customize_tabview tabViewItemAtIndex:2] setLabel: _NS("Audio codec")];
150     [[_customize_tabview tabViewItemAtIndex:3] setLabel: _NS("Subtitles")];
151     [_customize_tabview selectTabViewItemAtIndex: 0];
152     [_customize_vid_ckb setTitle: _NS("Video")];
153     [_customize_vid_keep_ckb setTitle: _NS("Keep original video track")];
154     [_customize_vid_codec_lbl setStringValue: _NS("Codec")];
155     [_customize_vid_bitrate_lbl setStringValue: _NS("Bitrate")];
156     [_customize_vid_framerate_lbl setStringValue: _NS("Frame Rate")];
157     [_customize_vid_res_box setTitle: _NS("Resolution")];
158     [_customize_vid_res_lbl setStringValue: _NS("You just need to fill one of the three following parameters, VLC will autodetect the other using the original aspect ratio")];
159     [_customize_vid_width_lbl setStringValue: _NS("Width")];
160     [_customize_vid_height_lbl setStringValue: _NS("Height")];
161     [_customize_vid_scale_lbl setStringValue: _NS("Scale")];
162     [_customize_aud_ckb setTitle: _NS("Audio")];
163     [_customize_aud_keep_ckb setTitle: _NS("Keep original audio track")];
164     [_customize_aud_codec_lbl setStringValue: _NS("Codec")];
165     [_customize_aud_bitrate_lbl setStringValue: _NS("Bitrate")];
166     [_customize_aud_channels_lbl setStringValue: _NS("Channels")];
167     [_customize_aud_samplerate_lbl setStringValue: _NS("Sample Rate")];
168     [_customize_subs_ckb setTitle: _NS("Subtitles")];
169     [_customize_subs_overlay_ckb setTitle: _NS("Overlay subtitles on the video")];
170
171     /* there is no way to hide single cells, so replace the existing ones with empty cells.. */
172     id blankCell = [[[NSCell alloc] init] autorelease];
173     [blankCell setEnabled:NO];
174     [_customize_encap_matrix putCell:blankCell atRow:3 column:1];
175     [_customize_encap_matrix putCell:blankCell atRow:3 column:2];
176     [_customize_encap_matrix putCell:blankCell atRow:3 column:3];
177
178     /* fetch profiles from defaults */
179     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
180     _profileValueList = [[defaults arrayForKey:@"CASProfiles"] retain];
181     _profileNames = [[defaults arrayForKey:@"CASProfileNames"] retain];
182
183     [_profile_pop removeAllItems];
184     [_profile_pop addItemsWithTitles:_profileNames];
185     [_profile_pop addItemWithTitle:_NS("Custom")];
186
187     _videoCodecs = [[NSArray alloc] initWithObjects:
188                     [NSArray arrayWithObjects:@"MPEG-1", @"MPEG-2", @"MPEG-4", @"DIVX 1", @"DIVX 2", @"DIVX 3", @"H.263", @"H.264", @"VP8", @"WMV1", @"WMV2", @"M-JPEG", @"Theora", @"Dirac", nil],
189                     [NSArray arrayWithObjects:@"mpgv", @"mp2v", @"mp4v", @"DIV1", @"DIV2", @"DIV3", @"H263", @"h264", @"VP80", @"WMV1", @"WMV2", @"MJPG", @"theo", @"drac", nil],
190                     nil];
191     _audioCodecs = [[NSArray alloc] initWithObjects:
192                     [NSArray arrayWithObjects:@"MPEG Audio", @"MP3", @"MPEG 4 Audio (AAC)", @"A52/AC-3", @"Vorbis", @"Flac", @"Speex", @"WAV", @"WMA2", nil],
193                     [NSArray arrayWithObjects:@"mpga", @"mp3", @"mp4a", @"a52", @"vorb", @"flac", @"spx", @"s16l", @"wma2", nil],
194                     nil];
195     _subsCodecs = [[NSArray alloc] initWithObjects:
196                    [NSArray arrayWithObjects:@"DVB subtitle", @"T.140", nil],
197                    [NSArray arrayWithObjects:@"dvbs", @"t140", nil],
198                    nil];
199
200     [_customize_vid_codec_pop removeAllItems];
201     [_customize_vid_scale_pop removeAllItems];
202     [_customize_aud_codec_pop removeAllItems];
203     [_customize_aud_samplerate_pop removeAllItems];
204     [_customize_subs_pop removeAllItems];
205
206     [_customize_vid_codec_pop addItemsWithTitles:[_videoCodecs objectAtIndex:0]];
207     [_customize_aud_codec_pop addItemsWithTitles:[_audioCodecs objectAtIndex:0]];
208     [_customize_subs_pop addItemsWithTitles:[_subsCodecs objectAtIndex:0]];
209
210     [_customize_aud_samplerate_pop addItemWithTitle:@"8000"];
211     [_customize_aud_samplerate_pop addItemWithTitle:@"11025"];
212     [_customize_aud_samplerate_pop addItemWithTitle:@"22050"];
213     [_customize_aud_samplerate_pop addItemWithTitle:@"44100"];
214     [_customize_aud_samplerate_pop addItemWithTitle:@"48000"];
215
216     [_customize_vid_scale_pop addItemWithTitle:@"1"];
217     [_customize_vid_scale_pop addItemWithTitle:@"0.25"];
218     [_customize_vid_scale_pop addItemWithTitle:@"0.5"];
219     [_customize_vid_scale_pop addItemWithTitle:@"0.75"];
220     [_customize_vid_scale_pop addItemWithTitle:@"1.25"];
221     [_customize_vid_scale_pop addItemWithTitle:@"1.5"];
222     [_customize_vid_scale_pop addItemWithTitle:@"1.75"];
223     [_customize_vid_scale_pop addItemWithTitle:@"2"];
224
225     [_ok_btn setEnabled: NO];
226 }
227
228 # pragma mark -
229 # pragma mark Code to Communicate with other objects
230
231 - (void)toggleWindow
232 {
233     [_window makeKeyAndOrderFront: nil];
234 }
235
236 # pragma mark -
237 # pragma mark User Interaction
238
239 - (IBAction)windowButtonAction:(id)sender
240 {
241 }
242
243 - (IBAction)openMedia:(id)sender
244 {
245     /* preliminary implementation until the open panel is cleaned up */
246     NSOpenPanel * openPanel = [NSOpenPanel openPanel];
247     [openPanel setCanChooseDirectories:NO];
248     [openPanel setResolvesAliases:YES];
249     [openPanel setAllowsMultipleSelection:NO];
250     [openPanel beginSheetForDirectory:nil file:nil types:nil modalForWindow: _window modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
251 }
252
253 - (void)openPanelDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode  contextInfo:(void  *)contextInfo
254 {
255     if (returnCode == NSOKButton)
256     {
257         [self setMRL: [NSString stringWithUTF8String:make_URI([[[panel URL] path] UTF8String], NULL)]];
258         [self updateOKButton];
259         [self updateDropView];
260     }
261 }
262
263 - (IBAction)customizeProfile:(id)sender
264 {
265     NSUInteger index = [_profile_pop indexOfSelectedItem];
266     if (index < ([_profileValueList count] - 1))
267         [self resetCustomizationSheetBasedOnProfile:[_profileValueList objectAtIndex:index]];
268
269     [NSApp beginSheet:_customize_panel modalForWindow:_window modalDelegate:self didEndSelector:NULL contextInfo:nil];
270 }
271
272 - (IBAction)closeCustomizationSheet:(id)sender
273 {
274     [_customize_panel orderOut:sender];
275     [NSApp endSheet: _customize_panel];
276
277     /* update current profile based upon the sheet's values */
278     /* Container(string), transcode video(bool), transcode audio(bool),
279      * use subtitles(bool), video codec(string), video bitrate(integer),
280      * scale(float), fps(float), width(integer, height(integer),
281      * audio codec(string), audio bitrate(integer), channels(integer),
282      * samplerate(integer), subtitle codec(string), subtitle overlay(bool) */
283
284     if (sender == _customize_ok_btn && [_currentProfile count] == 16) {
285         NSInteger i;
286         [_currentProfile replaceObjectAtIndex:0 withObject:[self currentEncapsulationFormat]];
287         [_currentProfile replaceObjectAtIndex:1 withObject:[NSString stringWithFormat:@"%li", [_customize_vid_ckb state]]];
288         [_currentProfile replaceObjectAtIndex:2 withObject:[NSString stringWithFormat:@"%li", [_customize_aud_ckb state]]];
289         [_currentProfile replaceObjectAtIndex:3 withObject:[NSString stringWithFormat:@"%li", [_customize_subs_ckb state]]];
290         i = [_customize_vid_codec_pop indexOfSelectedItem];
291         if (i >= 0)
292             [_currentProfile replaceObjectAtIndex:4 withObject:[_videoCodecs objectAtIndex:i]];
293         else
294             [_currentProfile replaceObjectAtIndex:4 withObject:@"none"];
295         [_currentProfile replaceObjectAtIndex:5 withObject:[_customize_vid_bitrate_fld stringValue]];
296         [_currentProfile replaceObjectAtIndex:6 withObject:[[_customize_vid_scale_pop selectedItem] title]];
297         [_currentProfile replaceObjectAtIndex:7 withObject:[_customize_vid_framerate_fld stringValue]];
298         [_currentProfile replaceObjectAtIndex:8 withObject:[_customize_vid_width_fld stringValue]];
299         [_currentProfile replaceObjectAtIndex:9 withObject:[_customize_vid_height_fld stringValue]];
300         i = [_customize_aud_codec_pop indexOfSelectedItem];
301         if (i >= 0)
302             [_currentProfile replaceObjectAtIndex:10 withObject:[_audioCodecs objectAtIndex:i]];
303         else
304             [_currentProfile replaceObjectAtIndex:10 withObject:@"none"];
305         [_currentProfile replaceObjectAtIndex:11 withObject:[_customize_aud_bitrate_fld stringValue]];
306         [_currentProfile replaceObjectAtIndex:12 withObject:[_customize_aud_channels_fld stringValue]];
307         [_currentProfile replaceObjectAtIndex:13 withObject:[[_customize_aud_samplerate_pop selectedItem] title]];
308         i = [_customize_subs_pop indexOfSelectedItem];
309         if (i >= 0)
310             [_currentProfile replaceObjectAtIndex:14 withObject:[_subsCodecs objectAtIndex:i]];
311         else
312             [_currentProfile replaceObjectAtIndex:14 withObject:@"none"];
313         [_currentProfile replaceObjectAtIndex:15 withObject:[NSString stringWithFormat:@"%li", [_customize_subs_overlay_ckb state]]];
314     }
315 }
316
317 - (IBAction)chooseDestination:(id)sender
318 {
319     NSSavePanel * saveFilePanel = [NSSavePanel savePanel];
320     [saveFilePanel setCanSelectHiddenExtension: YES];
321     [saveFilePanel setCanCreateDirectories: YES];
322     [saveFilePanel beginSheetForDirectory:nil file:nil modalForWindow:_window modalDelegate:self didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
323 }
324
325 - (void)savePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
326 {
327     if (returnCode == NSOKButton) {
328         _outputDestination = [[sheet URL] path];
329         [_destination_filename_lbl setStringValue: [[NSFileManager defaultManager] displayNameAtPath:_outputDestination]];
330         [[_destination_filename_stub_lbl animator] setHidden: YES];
331         [[_destination_filename_lbl animator] setHidden: NO];
332     } else {
333         _outputDestination = @"";
334         [[_destination_filename_lbl animator] setHidden: YES];
335         [[_destination_filename_stub_lbl animator] setHidden: NO];
336     }
337     [self updateOKButton];
338 }
339
340 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
341 {
342     NSPasteboard *paste = [sender draggingPasteboard];
343     NSArray *types = [NSArray arrayWithObject: NSFilenamesPboardType];
344     NSString *desired_type = [paste availableTypeFromArray: types];
345     NSData *carried_data = [paste dataForType: desired_type];
346
347     if( carried_data ) {
348         if( [desired_type isEqualToString:NSFilenamesPboardType] ) {
349             NSArray *values = [[paste propertyListForType: NSFilenamesPboardType] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
350
351             if ([values count] > 0) {
352                 [self setMRL: [NSString stringWithUTF8String:make_URI([[values objectAtIndex:0] UTF8String], NULL)]];
353                 [self updateOKButton];
354                 [self updateDropView];
355                 return YES;
356             }
357         }
358     }
359     return NO;
360 }
361
362 # pragma mark -
363 # pragma mark Private Functionality
364 - (void)updateDropView
365 {
366     if ([_MRL length] > 0) {
367         NSString * path = [[NSURL URLWithString:_MRL] path];
368         [_dropin_media_lbl setStringValue: [[NSFileManager defaultManager] displayNameAtPath: path]];
369         NSImage * image = [[NSWorkspace sharedWorkspace] iconForFile: path];
370         [image setSize:NSMakeSize(128,128)];
371         [_dropin_icon_view setImage: image];
372
373         if (![_dropin_view superview]) {
374             NSRect boxFrame = [_drop_box frame];
375             NSRect subViewFrame = [_dropin_view frame];
376             subViewFrame.origin.x = (boxFrame.size.width - subViewFrame.size.width) / 2;
377             subViewFrame.origin.y = (boxFrame.size.height - subViewFrame.size.height) / 2;
378             [_dropin_view setFrame: subViewFrame];
379             [[_drop_image_view animator] setHidden: YES];
380             [_drop_box performSelector:@selector(addSubview:) withObject:_dropin_view afterDelay:0.6];
381         }
382     } else {
383         [_dropin_view removeFromSuperview];
384         [[_drop_image_view animator] setHidden: NO];
385     }
386 }
387
388 - (void)updateOKButton
389 {
390     if ([_outputDestination length] > 0 && [_MRL length] > 0)
391         [_ok_btn setEnabled: YES];
392     else
393         [_ok_btn setEnabled: NO];
394 }
395
396 - (void)resetCustomizationSheetBasedOnProfile:(NSString *)profileString
397 {
398     /* Container(string), transcode video(bool), transcode audio(bool),
399     * use subtitles(bool), video codec(string), video bitrate(integer),
400     * scale(float), fps(float), width(integer, height(integer),
401     * audio codec(string), audio bitrate(integer), channels(integer),
402     * samplerate(integer), subtitle codec(string), subtitle overlay(bool) */
403
404     NSArray * components = [profileString componentsSeparatedByString:@";"];
405     if ([components count] != 16) {
406         msg_Err(VLCIntf, "CAS: the requested profile '%s' is invalid", [profileString UTF8String]);
407         return;
408     }
409
410     [self selectCellByEncapsulationFormat:[components objectAtIndex:0]];
411     [_customize_vid_ckb setState:[[components objectAtIndex:1] intValue]];
412     [_customize_aud_ckb setState:[[components objectAtIndex:2] intValue]];
413     [_customize_subs_ckb setState:[[components objectAtIndex:3] intValue]];
414     [_customize_vid_bitrate_fld setStringValue:[components objectAtIndex:5]];
415     [_customize_vid_scale_pop selectItemWithTitle:[components objectAtIndex:6]];
416     [_customize_vid_framerate_fld setStringValue:[components objectAtIndex:7]];
417     [_customize_vid_width_fld setStringValue:[components objectAtIndex:8]];
418     [_customize_vid_height_fld setStringValue:[components objectAtIndex:9]];
419     [_customize_aud_bitrate_fld setStringValue:[components objectAtIndex:11]];
420     [_customize_aud_channels_fld setStringValue:[components objectAtIndex:12]];
421     [_customize_aud_samplerate_pop selectItemWithTitle:[components objectAtIndex:13]];
422     [_customize_subs_overlay_ckb setState:[[components objectAtIndex:15] intValue]];
423
424     /* since there is no proper lookup mechanism in arrays, we need to implement a string specific one ourselves */
425     NSArray * tempArray = [_videoCodecs objectAtIndex:1];
426     NSUInteger count = [tempArray count];
427     NSString * searchString = [components objectAtIndex:4];
428     if ([searchString isEqualToString:@"none"] || [searchString isEqualToString:@"0"]) {
429         [_customize_vid_codec_pop selectItemAtIndex:-1];
430     } else {
431         for (NSUInteger x = 0; x < count; x++) {
432             if ([[tempArray objectAtIndex:x] isEqualToString: searchString]) {
433                 [_customize_vid_codec_pop selectItemAtIndex:x];
434                 break;
435             }
436         }
437     }
438
439     tempArray = [_audioCodecs objectAtIndex:1];
440     count = [tempArray count];
441     searchString = [components objectAtIndex:10];
442     if ([searchString isEqualToString:@"none"] || [searchString isEqualToString:@"0"]) {
443         [_customize_aud_codec_pop selectItemAtIndex:-1];
444     } else {
445         for (NSUInteger x = 0; x < count; x++) {
446             if ([[tempArray objectAtIndex:x] isEqualToString: searchString]) {
447                 [_customize_aud_codec_pop selectItemAtIndex:x];
448                 break;
449             }
450         }
451     }
452
453     tempArray = [_subsCodecs objectAtIndex:1];
454     count = [tempArray count];
455     searchString = [components objectAtIndex:14];
456     if ([searchString isEqualToString:@"none"] || [searchString isEqualToString:@"0"]) {
457         [_customize_subs_pop selectItemAtIndex:-1];
458     } else {
459         for (NSUInteger x = 0; x < count; x++) {
460             if ([[tempArray objectAtIndex:x] isEqualToString: searchString]) {
461                 [_customize_subs_pop selectItemAtIndex:x];
462                 break;
463             }
464         }
465     }
466
467     if (_currentProfile)
468         [_currentProfile release];
469     _currentProfile = [[NSMutableArray alloc] initWithArray: [profileString componentsSeparatedByString:@";"]];
470 }
471
472 - (void)selectCellByEncapsulationFormat:(NSString *)format
473 {
474     if ([format isEqualToString:@"ts"])
475         [_customize_encap_matrix selectCellWithTag:MPEGTS];
476     else if([format isEqualToString:@"webm"])
477         [_customize_encap_matrix selectCellWithTag:WEBM];
478     else if([format isEqualToString:@"ogg"])
479         [_customize_encap_matrix selectCellWithTag:OGG];
480     else if([format isEqualToString:@"ogm"])
481         [_customize_encap_matrix selectCellWithTag:OGG];
482     else if([format isEqualToString:@"mp4"])
483         [_customize_encap_matrix selectCellWithTag:MP4];
484     else if([format isEqualToString:@"mov"])
485         [_customize_encap_matrix selectCellWithTag:MP4];
486     else if([format isEqualToString:@"ps"])
487         [_customize_encap_matrix selectCellWithTag:MPEGPS];
488     else if([format isEqualToString:@"mjpeg"])
489         [_customize_encap_matrix selectCellWithTag:MJPEG];
490     else if([format isEqualToString:@"wav"])
491         [_customize_encap_matrix selectCellWithTag:WAV];
492     else if([format isEqualToString:@"flv"])
493         [_customize_encap_matrix selectCellWithTag:FLV];
494     else if([format isEqualToString:@"mpg"])
495         [_customize_encap_matrix selectCellWithTag:MPEG1];
496     else if([format isEqualToString:@"mkv"])
497         [_customize_encap_matrix selectCellWithTag:MKV];
498     else if([format isEqualToString:@"raw"])
499         [_customize_encap_matrix selectCellWithTag:RAW];
500     else if([format isEqualToString:@"avi"])
501         [_customize_encap_matrix selectCellWithTag:AVI];
502     else if([format isEqualToString:@"asf"])
503         [_customize_encap_matrix selectCellWithTag:ASF];
504     else if([format isEqualToString:@"wmv"])
505         [_customize_encap_matrix selectCellWithTag:ASF];
506     else
507         msg_Err(VLCIntf, "CAS: unknown encap format requested for customization");
508 }
509
510 - (NSString *)currentEncapsulationFormat
511 {
512     NSUInteger cellTag = [[_customize_encap_matrix selectedCell] tag];
513     NSString * returnValue;
514     switch (cellTag) {
515         case MPEGTS:
516             returnValue = @"ts";
517             break;
518         case WEBM:
519             returnValue = @"webm";
520             break;
521         case OGG:
522             returnValue = @"ogg";
523             break;
524         case MP4:
525             returnValue = @"mp4";
526             break;
527         case MPEGPS:
528             returnValue = @"ps";
529             break;
530         case MJPEG:
531             returnValue = @"mjpeg";
532             break;
533         case WAV:
534             returnValue = @"wav";
535             break;
536         case FLV:
537             returnValue = @"flv";
538             break;
539         case MPEG1:
540             returnValue = @"mpg";
541             break;
542         case MKV:
543             returnValue = @"mkv";
544             break;
545         case RAW:
546             returnValue = @"raw";
547             break;
548         case AVI:
549             returnValue = @"avi";
550             break;
551         case ASF:
552             returnValue = @"asf";
553             break;
554
555         default:
556             returnValue = @"none";
557             break;
558     }
559
560     return returnValue;
561 }
562
563 @end
564
565 # pragma mark -
566 # pragma mark Drag and drop handling
567
568 @implementation VLCDropEnabledBox
569
570 - (void)awakeFromNib
571 {
572     [self registerForDraggedTypes:[NSArray arrayWithObject: NSFilenamesPboardType]];
573 }
574
575 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
576 {
577     if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric)
578         return NSDragOperationGeneric;
579
580     return NSDragOperationNone;
581 }
582
583 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
584 {
585     return YES;
586 }
587
588 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
589 {
590     return [[VLCConvertAndSave sharedInstance] performDragOperation: sender];
591 }
592
593 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
594 {
595     [self setNeedsDisplay:YES];
596 }
597
598 @end
599
600 @implementation VLCDropEnabledImageView
601
602 - (void)awakeFromNib
603 {
604     [self registerForDraggedTypes:[NSArray arrayWithObject: NSFilenamesPboardType]];
605 }
606
607 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
608 {
609     if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric)
610         return NSDragOperationGeneric;
611
612     return NSDragOperationNone;
613 }
614
615 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
616 {
617     return YES;
618 }
619
620 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
621 {
622     return [[VLCConvertAndSave sharedInstance] performDragOperation: sender];
623 }
624
625 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
626 {
627     [self setNeedsDisplay:YES];
628 }
629
630 @end
631
632 @implementation VLCDropEnabledButton
633
634 - (void)awakeFromNib
635 {
636     [self registerForDraggedTypes:[NSArray arrayWithObject: NSFilenamesPboardType]];
637 }
638
639 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
640 {
641     if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric)
642         return NSDragOperationGeneric;
643
644     return NSDragOperationNone;
645 }
646
647 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
648 {
649     return YES;
650 }
651
652 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
653 {
654     return [[VLCConvertAndSave sharedInstance] performDragOperation: sender];
655 }
656
657 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
658 {
659     [self setNeedsDisplay:YES];
660 }
661
662 @end