Commit 2609901e authored by David Fuhrmann's avatar David Fuhrmann

macosx: TextfieldPanel: change result handling from delegate to block

The former delegate approach had some drawbacks as one class could
be only delegate for one panel. This commit replaces it with a
completion handler block which moves the result handling code
closer to the actual creation of the dialog.

Also fixes crash for eq panels.
parent b5acac3b
......@@ -366,10 +366,50 @@
[_textfieldPanel setSubTitle: _NS("Enter a name for the new profile:")];
[_textfieldPanel setCancelButtonLabel: _NS("Cancel")];
[_textfieldPanel setOKButtonLabel: _NS("Save")];
[_textfieldPanel setTarget:self];
b_genericAudioProfileInInteraction = YES;
[_textfieldPanel runModalForWindow:self.window];
__weak typeof(self) _self = self;
[_textfieldPanel runModalForWindow:self.window completionHandler:^(NSInteger returnCode, NSString *resultingText) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (returnCode != NSOKButton) {
[_profilePopup selectItemAtIndex:[defaults integerForKey:@"AudioEffectSelectedProfile"]];
return;
}
NSArray *profileNames = [defaults objectForKey:@"AudioEffectProfileNames"];
// duplicate names are not allowed in the popup control
if ([resultingText length] == 0 || [profileNames containsObject:resultingText]) {
[_profilePopup selectItemAtIndex:[defaults integerForKey:@"AudioEffectSelectedProfile"]];
NSAlert *alert = [[NSAlert alloc] init];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert setMessageText:_NS("Please enter a unique name for the new profile.")];
[alert setInformativeText:_NS("Multiple profiles with the same name are not allowed.")];
[alert beginSheetModalForWindow:_self.window
modalDelegate:nil
didEndSelector:nil
contextInfo:nil];
return;
}
NSString *newProfile = [_self generateProfileString];
/* add string to user defaults as well as a label */
NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"AudioEffectProfiles"]];
[workArray addObject:newProfile];
[defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"AudioEffectProfiles"];
[defaults setInteger:[workArray count] - 1 forKey:@"AudioEffectSelectedProfile"];
workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"AudioEffectProfileNames"]];
[workArray addObject:resultingText];
[defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"AudioEffectProfileNames"];
/* save defaults */
[defaults synchronize];
[_self resetProfileSelector];
}];
}
- (void)removeAudioEffectsProfile:(id)sender
......@@ -601,93 +641,45 @@ static bool GetEqualizerStatus(intf_thread_t *p_custom_intf,
- (IBAction)addPresetAction:(id)sender
{
/* show panel */
VLCTextfieldPanelController *panel = [[VLCTextfieldPanelController alloc] init];
[panel setTitle: _NS("Save current selection as new preset")];
[panel setSubTitle: _NS("Enter a name for the new preset:")];
[panel setCancelButtonLabel: _NS("Cancel")];
[panel setOKButtonLabel: _NS("Save")];
[panel setTarget:self];
b_genericAudioProfileInInteraction = NO;
[panel runModalForWindow:self.window];
}
- (void)panel:(VLCTextfieldPanelController *)panel returnValue:(NSUInteger)value text:(NSString *)text
{
[_textfieldPanel setTitle: _NS("Save current selection as new preset")];
[_textfieldPanel setSubTitle: _NS("Enter a name for the new preset:")];
[_textfieldPanel setCancelButtonLabel: _NS("Cancel")];
[_textfieldPanel setOKButtonLabel: _NS("Save")];
__weak typeof(self) _self = self;
[_textfieldPanel runModalForWindow:self.window completionHandler:^(NSInteger returnCode, NSString *resultingText) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// EQ settings
if (!b_genericAudioProfileInInteraction) {
if (value == NSOKButton && [text length] > 0) {
if (returnCode != NSOKButton || [resultingText length] == 0)
return;
NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"EQValues"]];
[workArray addObject:[self generatePresetString]];
[defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"EQValues"];
workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"EQTitles"]];
[workArray addObject:text];
[workArray addObject:resultingText];
[defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"EQTitles"];
workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"EQPreampValues"]];
[workArray addObject:[NSString stringWithFormat:@"%.1f", [_equalizerPreampSlider floatValue]]];
[defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"EQPreampValues"];
workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"EQNames"]];
[workArray addObject:[text decomposedStringWithCanonicalMapping]];
[workArray addObject:[resultingText decomposedStringWithCanonicalMapping]];
[defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"EQNames"];
[defaults synchronize];
/* update VLC internals */
audio_output_t *p_aout = getAout();
if (p_aout) {
var_SetString(p_aout, "equalizer-preset", [[text decomposedStringWithCanonicalMapping] UTF8String]);
var_SetString(p_aout, "equalizer-preset", [[resultingText decomposedStringWithCanonicalMapping] UTF8String]);
vlc_object_release(p_aout);
}
config_PutPsz(VLCIntf, "equalizer-preset", [[text decomposedStringWithCanonicalMapping] UTF8String]);
config_PutPsz(VLCIntf, "equalizer-preset", [[resultingText decomposedStringWithCanonicalMapping] UTF8String]);
/* update UI */
[self updatePresetSelector];
}
// profile settings
} else {
if (value != NSOKButton) {
[_profilePopup selectItemAtIndex:[defaults integerForKey:@"AudioEffectSelectedProfile"]];
return;
}
NSArray *profileNames = [defaults objectForKey:@"AudioEffectProfileNames"];
// duplicate names are not allowed in the popup control
if ([text length] == 0 || [profileNames containsObject:text]) {
[_profilePopup selectItemAtIndex:[defaults integerForKey:@"AudioEffectSelectedProfile"]];
NSAlert *alert = [[NSAlert alloc] init];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert setMessageText:_NS("Please enter a unique name for the new profile.")];
[alert setInformativeText:_NS("Multiple profiles with the same name are not allowed.")];
[alert beginSheetModalForWindow:self.window
modalDelegate:nil
didEndSelector:nil
contextInfo:nil];
return;
}
NSString *newProfile = [self generateProfileString];
/* add string to user defaults as well as a label */
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"AudioEffectProfiles"]];
[workArray addObject:newProfile];
[defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"AudioEffectProfiles"];
[defaults setInteger:[workArray count] - 1 forKey:@"AudioEffectSelectedProfile"];
workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"AudioEffectProfileNames"]];
[workArray addObject:text];
[defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"AudioEffectProfileNames"];
/* save defaults */
[defaults synchronize];
[self resetProfileSelector];
}
[_self updatePresetSelector];
}];
}
- (IBAction)deletePresetAction:(id)sender
......
......@@ -166,7 +166,6 @@
- (IBAction)streamAnnouncementToggle:(id)sender;
- (IBAction)sdpFileLocationSelector:(id)sender;
- (void)panel:(VLCTextfieldPanelController *)panel returnValue:(NSUInteger)value text:(NSString *)text;
- (void)panel:(VLCPopupPanelController *)panel returnValue:(NSUInteger)value item:(NSUInteger)item;
@end
......@@ -452,9 +452,32 @@
[_textfieldPanel setSubTitle: _NS("Enter a name for the new profile:")];
[_textfieldPanel setCancelButtonLabel: _NS("Cancel")];
[_textfieldPanel setOKButtonLabel: _NS("Save")];
[_textfieldPanel setTarget:self];
[_textfieldPanel runModalForWindow:_customizePanel];
__weak typeof(self) _self = self;
[_textfieldPanel runModalForWindow:_customizePanel completionHandler:^(NSInteger returnCode, NSString *resultingText) {
if (returnCode != NSOKButton || [resultingText length] == 0)
return;
/* prepare current data */
[_self updateCurrentProfile];
/* add profile to arrays */
NSMutableArray * workArray = [[NSMutableArray alloc] initWithArray:self.profileNames];
[workArray addObject:resultingText];
[_self setProfileNames:[[NSArray alloc] initWithArray:workArray]];
workArray = [[NSMutableArray alloc] initWithArray:self.profileValueList];
[workArray addObject:[self.currentProfile componentsJoinedByString:@";"]];
[_self setProfileValueList:[[NSArray alloc] initWithArray:workArray]];
/* update UI */
[_self recreateProfilePopup];
[_profilePopup selectItemWithTitle:resultingText];
/* update internals */
[_self switchProfile:self];
[_self storeProfilesOnDisk];
}];
}
#pragma mark -
......@@ -605,33 +628,6 @@
return NO;
}
- (void)panel:(VLCTextfieldPanelController *)panel returnValue:(NSUInteger)value text:(NSString *)text
{
if (value == NSOKButton) {
if ([text length] > 0) {
/* prepare current data */
[self updateCurrentProfile];
/* add profile to arrays */
NSMutableArray * workArray = [[NSMutableArray alloc] initWithArray:self.profileNames];
[workArray addObject:text];
[self setProfileNames:[[NSArray alloc] initWithArray:workArray]];
workArray = [[NSMutableArray alloc] initWithArray:self.profileValueList];
[workArray addObject:[self.currentProfile componentsJoinedByString:@";"]];
[self setProfileValueList:[[NSArray alloc] initWithArray:workArray]];
/* update UI */
[self recreateProfilePopup];
[_profilePopup selectItemWithTitle:text];
/* update internals */
[self switchProfile:self];
[self storeProfilesOnDisk];
}
}
}
- (void)panel:(VLCPopupPanelController *)panel returnValue:(NSUInteger)value item:(NSUInteger)item
{
if (value == NSOKButton) {
......
......@@ -35,19 +35,25 @@
@property (readwrite, assign) NSString *subTitle;
@property (readwrite, assign) NSString *OKButtonLabel;
@property (readwrite, assign) NSString *CancelButtonLabel;
@property (readwrite, assign) id target;
@property (readonly) NSString *enteredText;
- (void)runModalForWindow:(NSWindow *)window;
/**
* Completion handler for textfield panel
* \param returnCode Result from panel. Can be NSOKButton or NSCancelButton.
* \param resultingText Resulting text string entered in panel.
*/
typedef void(^TextfieldPanelCompletionBlock)(NSInteger returnCode, NSString *resultingText);
/**
* Shows the panel as a modal dialog with window as its owner.
* \param window Parent window for the dialog.
* \param handler Completion block.
*/
- (void)runModalForWindow:(NSWindow *)window completionHandler:(TextfieldPanelCompletionBlock)handler;
- (IBAction)windowElementAction:(id)sender;
@end
@protocol VLCTextfieldPanelController <NSObject>
@optional
- (void)panel:(VLCTextfieldPanelController *)view returnValue:(NSUInteger)value text:(NSString *)text;
@end
@interface VLCPopupPanelController : NSWindowController
......
......@@ -23,6 +23,13 @@
#import "SharedDialogs.h"
@interface VLCTextfieldPanelController()
{
TextfieldPanelCompletionBlock _completionBlock;
}
@end
@implementation VLCTextfieldPanelController
......@@ -38,17 +45,11 @@
[self.window orderOut:sender];
[NSApp endSheet: self.window];
if (self.target) {
if ([self.target respondsToSelector:@selector(panel:returnValue:text:)]) {
if (sender == _cancelButton)
[self.target panel:self returnValue:NSCancelButton text:NULL];
else
[self.target panel:self returnValue:NSOKButton text:self.enteredText];
}
}
if (_completionBlock)
_completionBlock(sender == _okButton ? NSOKButton : NSCancelButton, [_textField stringValue]);
}
- (void)runModalForWindow:(NSWindow *)window
- (void)runModalForWindow:(NSWindow *)window completionHandler:(TextfieldPanelCompletionBlock)handler;
{
[self window];
......@@ -58,12 +59,9 @@
[_okButton setTitle:self.OKButtonLabel];
[_textField setStringValue:@""];
[NSApp beginSheet:self.window modalForWindow:window modalDelegate:self didEndSelector:NULL contextInfo:nil];
}
_completionBlock = [handler copy];
- (NSString *)enteredText
{
return [_textField stringValue];
[NSApp beginSheet:self.window modalForWindow:window modalDelegate:self didEndSelector:NULL contextInfo:nil];
}
@end
......
......@@ -673,16 +673,13 @@
[_textfieldPanel setSubTitle: _NS("Enter a name for the new profile:")];
[_textfieldPanel setCancelButtonLabel: _NS("Cancel")];
[_textfieldPanel setOKButtonLabel: _NS("Save")];
[_textfieldPanel setTarget:self];
[_textfieldPanel runModalForWindow:self.window];
}
__weak typeof(self) _self = self;
[_textfieldPanel runModalForWindow:self.window completionHandler:^(NSInteger returnCode, NSString *resultingText) {
- (void)panel:(VLCTextfieldPanelController *)panel returnValue:(NSUInteger)value text:(NSString *)text
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (value != NSOKButton) {
if (returnCode != NSOKButton) {
[_profilePopup selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
return;
}
......@@ -690,7 +687,7 @@
NSArray *profileNames = [defaults objectForKey:@"VideoEffectProfileNames"];
// duplicate names are not allowed in the popup control
if ([text length] == 0 || [profileNames containsObject:text]) {
if ([resultingText length] == 0 || [profileNames containsObject:resultingText]) {
[_profilePopup selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
NSAlert *alert = [[NSAlert alloc] init];
......@@ -698,7 +695,7 @@
[alert setMessageText:_NS("Please enter a unique name for the new profile.")];
[alert setInformativeText:_NS("Multiple profiles with the same name are not allowed.")];
[alert beginSheetModalForWindow:self.window
[alert beginSheetModalForWindow:_self.window
modalDelegate:nil
didEndSelector:nil
contextInfo:nil];
......@@ -706,7 +703,7 @@
}
/* fetch all the current settings in a uniform string */
NSString *newProfile = [self generateProfileString];
NSString *newProfile = [_self generateProfileString];
/* add string to user defaults as well as a label */
......@@ -716,14 +713,15 @@
[defaults setInteger:[workArray count] - 1 forKey:@"VideoEffectSelectedProfile"];
workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfileNames"]];
[workArray addObject:text];
[workArray addObject:resultingText];
[defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfileNames"];
/* save defaults */
[defaults synchronize];
/* refresh UI */
[self resetProfileSelector];
[_self resetProfileSelector];
}];
}
- (void)removeProfile:(id)sender
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment