From 74a90251228a07995ea5ab1bae0fb2428f9cfbc7 Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 11 Nov 2015 00:08:45 +0100 Subject: Fix an issue where changing a table collation could cause an exception (fixes #2320) This issue probably was introduced in f02fb787063caabe246a0ee420394f5676c55a9c The empty item at the top of the collation list will now no longer have a selection mark, though. --- Interfaces/English.lproj/DBView.xib | 9 +++++++ Source/SPPopUpButtonCell.h | 48 +++++++++++++++++++++++++++++++++ Source/SPPopUpButtonCell.m | 51 ++++++++++++++++++++++++++++++++++++ Source/SPTableStructureDelegate.m | 14 +++++----- sequel-pro.xcodeproj/project.pbxproj | 6 +++++ 5 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 Source/SPPopUpButtonCell.h create mode 100644 Source/SPPopUpButtonCell.m diff --git a/Interfaces/English.lproj/DBView.xib b/Interfaces/English.lproj/DBView.xib index 465b72fa..63bbd031 100644 --- a/Interfaces/English.lproj/DBView.xib +++ b/Interfaces/English.lproj/DBView.xib @@ -26580,6 +26580,7 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA com.apple.InterfaceBuilder.CocoaPlugin + SPPopUpButtonCell com.apple.InterfaceBuilder.CocoaPlugin SPIdMenu @@ -30321,6 +30322,14 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA ../Source/SPIndexesController.m + + SPPopUpButtonCell + NSPopUpButtonCell + + IBProjectSource + ../Source/SPPopUpButtonCell.h + + SPProcessListController NSWindowController diff --git a/Source/SPPopUpButtonCell.h b/Source/SPPopUpButtonCell.h new file mode 100644 index 00000000..52c8a074 --- /dev/null +++ b/Source/SPPopUpButtonCell.h @@ -0,0 +1,48 @@ +// +// SPPopUpButtonCell.h +// sequel-pro +// +// Created by Max Lohrmann on 10.11.15. +// Copyright (c) 2015 Max Lohrmann. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// More info at + +#import + +/** + * The only difference here is that objectValue/setObjectValue: + * will use the representedObject of the menu instead of the menu item's index + * + * nil will act the same as @(-1) would with the regular NSPopUpButtonCell. + * + * Note that in theory multiple menu items could have the same representedObject + * and identification is done via isEqual: so this class would only ever + * pick the first one. + */ +@interface SPPopUpButtonCell : NSPopUpButtonCell + +- (id)objectValue; +- (void)setObjectValue:(id)objectValue; + +@end diff --git a/Source/SPPopUpButtonCell.m b/Source/SPPopUpButtonCell.m new file mode 100644 index 00000000..a20a2d92 --- /dev/null +++ b/Source/SPPopUpButtonCell.m @@ -0,0 +1,51 @@ +// +// SPPopUpButtonCell.m +// sequel-pro +// +// Created by Max Lohrmann on 10.11.15. +// Copyright (c) 2015 Max Lohrmann. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// More info at + +#import "SPPopUpButtonCell.h" + +@implementation SPPopUpButtonCell + +- (id)objectValue +{ + NSInteger n = [[super objectValue] integerValue]; + + // this method can be called for invalid selections, which return -1, which fails with itemAtIndex: + if(n < 0 || n >= [self numberOfItems]) return nil; + + return [[self itemAtIndex:n] representedObject]; +} + +- (void)setObjectValue:(id)objectValue +{ + NSInteger n = [self indexOfItemWithRepresentedObject:objectValue]; + [super setObjectValue:@(n)]; +} + +@end diff --git a/Source/SPTableStructureDelegate.m b/Source/SPTableStructureDelegate.m index da173271..a7fa9337 100644 --- a/Source/SPTableStructureDelegate.m +++ b/Source/SPTableStructureDelegate.m @@ -102,7 +102,7 @@ static void _BuildMenuWithPills(NSMenu *menu,struct _cmpMap *map,size_t mapEntri [[collationCell lastItem] setTitle:@""]; //if this is not set the column either has no encoding (numeric etc.) or retrieval failed. Either way we can't provide collations - if(columnEncoding) { + if([columnEncoding length]) { collations = [databaseDataInstance getDatabaseCollationsForEncoding:columnEncoding]; if ([collations count] > 0) { @@ -129,19 +129,18 @@ static void _BuildMenuWithPills(NSMenu *menu,struct _cmpMap *map,size_t mapEntri } } - //look up the right item - NSInteger idx = [collationCell indexOfItemWithRepresentedObject:columnCollation]; - if(idx > 0) return @(idx); + // the popup cell is subclassed to take the representedObject instead of the item index + return columnCollation; } } - return @0; + return nil; } else if ([[tableColumn identifier] isEqualToString:@"encoding"]) { // the encoding menu was already configured during setTableDetails: NSString *columnEncoding = [rowData objectForKey:@"encodingName"]; - if(columnEncoding) { + if([columnEncoding length]) { NSInteger idx = [encodingPopupCell indexOfItemWithRepresentedObject:columnEncoding]; if(idx > 0) return @(idx); } @@ -193,7 +192,8 @@ static void _BuildMenuWithPills(NSMenu *menu,struct _cmpMap *map,size_t mapEntri return; } else if ([[aTableColumn identifier] isEqualToString:@"collation"]) { - NSString *newCollation = [[(NSPopUpButtonCell *)[aTableColumn dataCell] itemAtIndex:[anObject integerValue]] representedObject]; + //the popup button is subclassed to return the representedObject instead of the item index + NSString *newCollation = anObject; if(!newCollation) [currentRow removeObjectForKey:@"collationName"]; diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj index 143aa9dd..7d3dc6a5 100644 --- a/sequel-pro.xcodeproj/project.pbxproj +++ b/sequel-pro.xcodeproj/project.pbxproj @@ -200,6 +200,7 @@ 507FF26A1BC8450100104523 /* SPExportSettingsPersistence.m in Sources */ = {isa = PBXBuildFile; fileRef = 507FF2691BC8450100104523 /* SPExportSettingsPersistence.m */; }; 507FF2A11BCD27A700104523 /* SPFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 507FF1111BBCC57600104523 /* SPFunctions.m */; }; 507FF2A21BCD27AE00104523 /* SPOSInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 50EAB5B71A8FBB08008F627A /* SPOSInfo.m */; }; + 50805B0D1BF2A068005F7A99 /* SPPopUpButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 50805B0C1BF2A068005F7A99 /* SPPopUpButtonCell.m */; }; 5089B0271BE714E300E226CD /* SPIdMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 5089B0261BE714E300E226CD /* SPIdMenu.m */; }; 50A9F8B119EAD4B90053E571 /* SPGotoDatabaseController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50A9F8B019EAD4B90053E571 /* SPGotoDatabaseController.m */; }; 50D3C3491A75B8A800B5429C /* GotoDatabaseDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = 50D3C34B1A75B8A800B5429C /* GotoDatabaseDialog.xib */; }; @@ -923,6 +924,8 @@ 507FF1111BBCC57600104523 /* SPFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPFunctions.m; sourceTree = ""; }; 507FF2681BC8450100104523 /* SPExportSettingsPersistence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPExportSettingsPersistence.h; sourceTree = ""; }; 507FF2691BC8450100104523 /* SPExportSettingsPersistence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPExportSettingsPersistence.m; sourceTree = ""; }; + 50805B0B1BF2A068005F7A99 /* SPPopUpButtonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPPopUpButtonCell.h; sourceTree = ""; }; + 50805B0C1BF2A068005F7A99 /* SPPopUpButtonCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPPopUpButtonCell.m; sourceTree = ""; }; 5089B0251BE714E300E226CD /* SPIdMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPIdMenu.h; sourceTree = ""; }; 5089B0261BE714E300E226CD /* SPIdMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPIdMenu.m; sourceTree = ""; }; 50A9F8AF19EAD4B90053E571 /* SPGotoDatabaseController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPGotoDatabaseController.h; sourceTree = ""; }; @@ -2326,6 +2329,8 @@ 17FDB04B1280778B00DBBBC2 /* SPFontPreviewTextField.m */, 58D2A6A516FBDEFF002EB401 /* SPComboPopupButton.h */, 58D2A6A616FBDEFF002EB401 /* SPComboPopupButton.m */, + 50805B0B1BF2A068005F7A99 /* SPPopUpButtonCell.h */, + 50805B0C1BF2A068005F7A99 /* SPPopUpButtonCell.m */, ); name = Controls; sourceTree = ""; @@ -3286,6 +3291,7 @@ 173C837A11AAD2AE00B8B084 /* SPHTMLExporter.m in Sources */, 173C837B11AAD2AE00B8B084 /* SPPDFExporter.m in Sources */, 173C839011AAD32A00B8B084 /* SPCSVExporterDelegate.m in Sources */, + 50805B0D1BF2A068005F7A99 /* SPPopUpButtonCell.m in Sources */, 173C839111AAD32A00B8B084 /* SPDotExporterDelegate.m in Sources */, 173C839211AAD32A00B8B084 /* SPHTMLExporterDelegate.m in Sources */, 173C839311AAD32A00B8B084 /* SPPDFExporterDelegate.m in Sources */, -- cgit v1.2.3