diff options
author | Max <post@wickenrode.com> | 2016-01-31 19:33:55 +0100 |
---|---|---|
committer | Max <post@wickenrode.com> | 2016-01-31 19:33:55 +0100 |
commit | c196132146dab618005bd88057dd61764f855808 (patch) | |
tree | 72eac5fd7ccd4ff020f4bb0624cde1cec7e05fd6 /Source | |
parent | 6e25cf7799d22e9c1fead1c0db294d45b78be299 (diff) | |
download | sequelpro-c196132146dab618005bd88057dd61764f855808.tar.gz sequelpro-c196132146dab618005bd88057dd61764f855808.tar.bz2 sequelpro-c196132146dab618005bd88057dd61764f855808.zip |
Change CSV field mapper so that the first row is no longer displayed as content row when "First line contains field names" is enabled
Diffstat (limited to 'Source')
-rw-r--r-- | Source/SPFieldMapperController.h | 1 | ||||
-rw-r--r-- | Source/SPFieldMapperController.m | 125 | ||||
-rw-r--r-- | Source/SPFunctions.h | 7 | ||||
-rw-r--r-- | Source/SPFunctions.m | 7 |
4 files changed, 106 insertions, 34 deletions
diff --git a/Source/SPFieldMapperController.h b/Source/SPFieldMapperController.h index 76b65c49..7f03ed10 100644 --- a/Source/SPFieldMapperController.h +++ b/Source/SPFieldMapperController.h @@ -161,6 +161,7 @@ - (NSArray*)fieldMappingGlobalValueArray; - (NSArray*)fieldMappingTableDefaultValues; - (BOOL)importFieldNamesHeader; +- (BOOL)hasContentRows; - (BOOL)insertRemainingRowsAfterUpdate; - (BOOL)globalValuesInUsage; - (BOOL)importIntoNewTable; diff --git a/Source/SPFieldMapperController.m b/Source/SPFieldMapperController.m index 8e662b99..26454f0f 100644 --- a/Source/SPFieldMapperController.m +++ b/Source/SPFieldMapperController.m @@ -37,11 +37,10 @@ #import "SPCategoryAdditions.h" #import "RegexKitLite.h" #import "SPDatabaseData.h" +#import "SPFunctions.h" #import <SPMySQL/SPMySQL.h> -#define SP_NUMBER_OF_RECORDS_STRING NSLocalizedString(@"%ld of %@%lu records", @"Label showing the index of the selected CSV row") - // Constants static NSString *SPTableViewImportValueColumnID = @"import_value"; static NSString *SPTableViewTypeColumnID = @"type"; @@ -204,8 +203,8 @@ static NSUInteger SPSourceColumnTypeInteger = 1; [advancedUpdateView setHidden:YES]; [advancedInsertView setHidden:YES]; - [self changeHasHeaderCheckbox:self]; [self changeTableTarget:self]; + [self changeHasHeaderCheckbox:self]; [[self window] makeFirstResponder:fieldMapperTableView]; if([fieldMappingTableColumnNames count]) [fieldMapperTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO]; @@ -214,7 +213,8 @@ static NSUInteger SPSourceColumnTypeInteger = 1; [insertNULLValueButton setEnabled:([globalValuesTableView numberOfSelectedRows] == 1)]; [self updateFieldNameAlignment]; - + + [self validateImportButton]; } - (void)dealloc @@ -337,7 +337,18 @@ static NSUInteger SPSourceColumnTypeInteger = 1; - (BOOL)importFieldNamesHeader { - return ([importFieldNamesHeaderSwitch state] == NSOnState)?YES:NO; + if(importFieldNamesHeaderSwitch) { + return ([importFieldNamesHeaderSwitch state] == NSOnState); + } + else { + //this is a provisional field for the initial value of the checkbox until the window is actually loaded + return importFieldNamesHeader; + } +} + +- (BOOL)hasContentRows +{ + return (([fieldMappingImportArray count] - ([self importFieldNamesHeader]? 1 : 0)) > 0); } - (BOOL)insertRemainingRowsAfterUpdate @@ -607,9 +618,7 @@ static NSUInteger SPSourceColumnTypeInteger = 1; fieldMappingCurrentRow = 0; if (fieldMappingArray) SPClear(fieldMappingArray); [self setupFieldMappingArray]; - [rowDownButton setEnabled:NO]; - [rowUpButton setEnabled:([fieldMappingImportArray count] > 1)]; - [recordCountLabel setStringValue:[NSString stringWithFormat:SP_NUMBER_OF_RECORDS_STRING, (long)(fieldMappingCurrentRow+1), fieldMappingImportArrayIsPreview?@"first ":@"", (unsigned long)[fieldMappingImportArray count]]]; + [self updateRowNavigation]; [self updateFieldMappingButtonCell]; [self updateFieldMappingOperatorOptions]; @@ -714,7 +723,7 @@ static NSUInteger SPSourceColumnTypeInteger = 1; - (IBAction)changeFieldAlignment:(id)sender { - if(![fieldMappingImportArray count]) return; + if(![self hasContentRows]) return; NSUInteger i; NSInteger j; @@ -767,12 +776,8 @@ static NSUInteger SPSourceColumnTypeInteger = 1; [self updateFieldMappingButtonCell]; [fieldMapperTableView reloadData]; - - [recordCountLabel setStringValue:[NSString stringWithFormat:SP_NUMBER_OF_RECORDS_STRING, (long)(fieldMappingCurrentRow+1), fieldMappingImportArrayIsPreview?@"first ":@"", (unsigned long)[fieldMappingImportArray count]]]; - - // enable/disable buttons - [rowDownButton setEnabled:(fieldMappingCurrentRow != 0)]; - [rowUpButton setEnabled:(fieldMappingCurrentRow != (NSInteger)([fieldMappingImportArray count]-1))]; + + [self updateRowNavigation]; } - (IBAction)changeHasHeaderCheckbox:(id)sender @@ -780,12 +785,12 @@ static NSUInteger SPSourceColumnTypeInteger = 1; NSInteger i; NSArray *headerRow; - [matchingNameMenuItem setEnabled:([importFieldNamesHeaderSwitch state] == NSOnState)?YES:NO]; + [matchingNameMenuItem setEnabled:[self importFieldNamesHeader]]; // In New Table mode reset new field name according to importFieldNamesHeaderSwitch's state if (newTableMode) { [fieldMappingTableColumnNames removeAllObjects]; - if([importFieldNamesHeaderSwitch state] == NSOnState) { + if([self importFieldNamesHeader]) { headerRow = NSArrayObjectAtIndex(fieldMappingImportArray, 0); for (i = 0; i < numberOfImportColumns; i++) { id headerCol = NSArrayObjectAtIndex(headerRow, i); @@ -800,6 +805,13 @@ static NSUInteger SPSourceColumnTypeInteger = 1; } [fieldMapperTableView reloadData]; } + + [self updateFieldMappingButtonCell]; + [fieldMapperTableView reloadData]; + + [self updateRowNavigation]; + + [self validateImportButton]; } - (IBAction)goBackToFileChooserFromPathControl:(id)sender @@ -853,7 +865,7 @@ static NSUInteger SPSourceColumnTypeInteger = 1; } // Step through the currently known data and get the types and values - NSUInteger i = (importFieldNamesHeader ? 1 : 0); + NSUInteger i = ([self importFieldNamesHeader] ? 1 : 0); NSArray *row; id col; for ( ; i < [fieldMappingImportArray count]; i++) { @@ -878,7 +890,7 @@ static NSUInteger SPSourceColumnTypeInteger = 1; [fieldMappingTableTypes removeAllObjects]; BOOL serverGreaterThanVersion4 = ([mySQLConnection serverMajorVersion] >= 5) ? YES : NO; - BOOL importFirstRowAsFieldNames = ([importFieldNamesHeaderSwitch state] == NSOnState); + BOOL importFirstRowAsFieldNames = [self importFieldNamesHeader]; NSArray *headerRow = NSArrayObjectAtIndex(fieldMappingImportArray, 0); for (columnCounter = 0; columnCounter < numberOfImportColumns; columnCounter++) { @@ -919,10 +931,8 @@ static NSUInteger SPSourceColumnTypeInteger = 1; fieldMappingCurrentRow = 0; if (fieldMappingArray) SPClear(fieldMappingArray); [self setupFieldMappingArray]; - [rowDownButton setEnabled:NO]; - [rowUpButton setEnabled:([fieldMappingImportArray count] > 1)]; - [recordCountLabel setStringValue:[NSString stringWithFormat:SP_NUMBER_OF_RECORDS_STRING, (long)(fieldMappingCurrentRow+1), fieldMappingImportArrayIsPreview?@"first ":@"", (unsigned long)[fieldMappingImportArray count]]]; - + [self updateRowNavigation]; + [self updateFieldMappingButtonCell]; [self updateFieldMappingOperatorOptions]; @@ -1105,8 +1115,8 @@ static NSUInteger SPSourceColumnTypeInteger = 1; // Add column placeholder NSInteger i = 0; - if([fieldMappingImportArray count] && [[fieldMappingImportArray objectAtIndex:0] count]) { - for(id item in [fieldMappingImportArray objectAtIndex:0]) { + if([self hasContentRows]) { + for(id item in [fieldMappingImportArray objectAtIndex:([self importFieldNamesHeader]? 1 : 0)]) { i++; if ([item isNSNull]) { [insertPullDownButton addItemWithTitle:[NSString stringWithFormat:@"%li. <%@>", (long)i, [prefs objectForKey:SPNullValue]]]; @@ -1388,7 +1398,7 @@ static NSUInteger SPSourceColumnTypeInteger = 1; - (void)matchHeaderNames { - if(![fieldMappingImportArray count]) return; + if(![self hasContentRows]) return; NSMutableArray *fileHeaderNames = [NSMutableArray array]; [fileHeaderNames setArray:NSArrayObjectAtIndex(fieldMappingImportArray, 0)]; @@ -1502,7 +1512,7 @@ static NSUInteger SPSourceColumnTypeInteger = 1; - (void)updateFieldMappingButtonCell { NSUInteger i; - if([fieldMappingImportArray count] == 0) return; + if(![self hasContentRows]) return; [fieldMappingButtonOptions setArray:[fieldMappingImportArray objectAtIndex:fieldMappingCurrentRow]]; for (i = 0; i < [fieldMappingButtonOptions count]; i++) { if ([[fieldMappingButtonOptions objectAtIndex:i] isNSNull]) @@ -1555,27 +1565,59 @@ static NSUInteger SPSourceColumnTypeInteger = 1; } #endif - // Set matching names only if csv file has an header - if(importFieldNamesHeader && alignment == 2) - [alignByPopup selectItemWithTag:2]; - else if(!importFieldNamesHeader && alignment == 2) - [alignByPopup selectItemWithTag:0]; - else + if(alignment == 2) { + // Set matching names only if csv file has a header + if([self importFieldNamesHeader]) + [alignByPopup selectItemWithTag:2]; + else + [alignByPopup selectItemWithTag:0]; + } + else { [alignByPopup selectItemWithTag:alignment]; + } [self changeFieldAlignment:nil]; } +- (void)updateRowNavigation +{ + int firstRowIsHeader = [self importFieldNamesHeader] ? 1 : 0; + + // if the first row becomes a header row it can no longer be a content row + if(!fieldMappingCurrentRow && firstRowIsHeader && [self hasContentRows]) { + fieldMappingCurrentRow++; + [self updateFieldMappingButtonCell]; + [fieldMapperTableView reloadData]; + } + + NSUInteger countRows = [fieldMappingImportArray count]; + [rowDownButton setEnabled:(fieldMappingCurrentRow > firstRowIsHeader)]; + [rowUpButton setEnabled:(SPIntS2U(fieldMappingCurrentRow) < (countRows - 1))]; + + long displayedCurrentRow = fieldMappingCurrentRow+1-firstRowIsHeader; + unsigned long displayedTotalRows = (countRows? (countRows - firstRowIsHeader) : 0); //avoid negative values on empty array + + NSString *fmt; + if(fieldMappingImportArrayIsPreview) + fmt = NSLocalizedString(@"%ld of first %lu record(s)", @"Label showing the index of the selected CSV row (csv partially loaded)"); + else + fmt = NSLocalizedString(@"%ld of %lu record(s)", @"Label showing the index of the selected CSV row"); + + [recordCountLabel setStringValue:[NSString stringWithFormat:fmt, displayedCurrentRow, displayedTotalRows]]; +} + - (void)validateImportButton { BOOL enableImportButton = YES; - + if (newTableMode) { if (![tablesListInstance isTableNameValid:[newTableNameTextField stringValue] forType:SPTableTypeTable ignoringSelectedTable:NO]) { [importButton setEnabled:NO]; return; } + + BOOL hasImportColumns = NO; for (NSUInteger i = 0; i < [fieldMappingTableColumnNames count]; i++) { NSString *colName = [fieldMappingTableColumnNames objectAtIndex:i]; BOOL shouldImport = [doImportKey isEqualToNumber:[fieldMappingOperatorArray objectAtIndex:i]]; @@ -1583,7 +1625,15 @@ static NSUInteger SPSourceColumnTypeInteger = 1; [importButton setEnabled:NO]; return; } + if(!hasImportColumns && shouldImport) hasImportColumns = YES; + } + + if(!hasImportColumns) { + // new table without any columns is not valid + [importButton setEnabled:NO]; + return; } + for (NSString* fieldType in fieldMappingTableTypes) { if(![fieldType length]) { [importButton setEnabled:NO]; @@ -1591,6 +1641,13 @@ static NSUInteger SPSourceColumnTypeInteger = 1; } } } + else { + // we don't want to create a new table and have no rows to import either => can't import nothing + if(![self hasContentRows]) { + [importButton setEnabled:NO]; + return; + } + } if ([[self selectedImportMethod] isEqualToString:@"UPDATE"]) { enableImportButton = NO; diff --git a/Source/SPFunctions.h b/Source/SPFunctions.h index e462b8cb..0cda7e36 100644 --- a/Source/SPFunctions.h +++ b/Source/SPFunctions.h @@ -42,3 +42,10 @@ void SPMainQSync(void (^block)(void)); * @return 0 on success or -1 if something went wrong, check errno */ int SPBetterRandomBytes(uint8_t *buf, size_t count); + +/** + * Convert a signed integer into an unsigned integer or throw an exception if the values don't fit. + * @param i a signed integer + * @return the same value, casted to unsigned integer + */ +NSUInteger SPIntS2U(NSInteger i); diff --git a/Source/SPFunctions.m b/Source/SPFunctions.m index d1c72555..6f11d236 100644 --- a/Source/SPFunctions.m +++ b/Source/SPFunctions.m @@ -69,3 +69,10 @@ int SPBetterRandomBytes(uint8_t *buf, size_t count) return 0; } + +NSUInteger SPIntS2U(NSInteger i) +{ + if(i < 0) [NSException raise:NSRangeException format:@"NSInteger %ld does not fit in NSUInteger",i]; + + return (NSUInteger)i; +} |