diff --git a/AppKit/CPRuleEditor/CPRuleEditor.j b/AppKit/CPRuleEditor/CPRuleEditor.j index cbc08326f..9e5a2cbdd 100644 --- a/AppKit/CPRuleEditor/CPRuleEditor.j +++ b/AppKit/CPRuleEditor/CPRuleEditor.j @@ -214,6 +214,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType", object:nil]; } + - (void)_ruleEditorLocalizerDidLoad:(CPNotification)aNotification { if ([aNotification object] === [self standardLocalizer]) @@ -224,7 +225,9 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType", var count = [_slices count]; for (var i = 0; i < count; i++) { - [[_slices objectAtIndex:i] _reconfigureSubviews]; + var slice = [_slices objectAtIndex:i]; + [slice _reconfigureSubviews]; + [slice _updateButtonVisibilities]; // Force updates on row button tooltips } [self _updatePredicate]; diff --git a/AppKit/CPRuleEditor/_CPRuleEditorLocalizer.j b/AppKit/CPRuleEditor/_CPRuleEditorLocalizer.j index 467445242..14404e0ed 100644 --- a/AppKit/CPRuleEditor/_CPRuleEditorLocalizer.j +++ b/AppKit/CPRuleEditor/_CPRuleEditorLocalizer.j @@ -202,6 +202,10 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+) } } } + else + { + [item setTitle:item._originalTitle]; + } } if (selectedItem) @@ -219,6 +223,32 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+) if (localizedPattern === key) { + var count = [views count]; + + for (var i = 0; i < count; i++) + { + var originalView = [views objectAtIndex:i]; + if ([originalView isKindOfClass:[CPPopUpButton class]]) + { + var selectedItem = [originalView selectedItem]; + if (selectedItem && selectedItem._originalTitle) + { + [selectedItem setTitle:selectedItem._originalTitle]; + } + } + else if ([originalView respondsToSelector:@selector(setStringValue:)] && originalView._originalText) + { + [originalView setStringValue:originalView._originalText]; + + if ([originalView isKindOfClass:[CPTextField class]] && ![originalView isEditable]) + { + var font = [originalView font] || [CPFont systemFontOfSize:[CPFont systemFontSize]], + size = [originalView._originalText sizeWithFont:font]; + [originalView setFrameSize:CGSizeMake(size.width + 4, CGRectGetHeight([originalView frame]))]; + } + } + } + return views; } diff --git a/AppKit/CPRuleEditor/_CPRuleEditorViewSliceRow.j b/AppKit/CPRuleEditor/_CPRuleEditorViewSliceRow.j index a32764fbe..ee21be432 100644 --- a/AppKit/CPRuleEditor/_CPRuleEditorViewSliceRow.j +++ b/AppKit/CPRuleEditor/_CPRuleEditorViewSliceRow.j @@ -440,6 +440,9 @@ { [_addButton setHidden:[_ruleEditor _shouldHideAddButtonForSlice:self]]; [_subtractButton setHidden:[_ruleEditor _shouldHideSubtractButtonForSlice:self]]; + + [_addButton setToolTip:[_ruleEditor _toolTipForAddSimpleRowButton]]; + [_subtractButton setToolTip:[_ruleEditor _toolTipForDeleteRowButton]]; } - (void)_configurePlusButtonByRowType:(CPRuleEditorRowType)type diff --git a/Tests/Manual/CPRuleEditorTestSpanish/AppController.j b/Tests/Manual/CPRuleEditorTestSpanish/AppController.j index d39cbf981..20c22eeea 100644 --- a/Tests/Manual/CPRuleEditorTestSpanish/AppController.j +++ b/Tests/Manual/CPRuleEditorTestSpanish/AppController.j @@ -3,31 +3,53 @@ @import @import @import +@import @import "RuleDelegate.j" @implementation AppController : CPObject { - CPWindow theWindow; - CPRuleEditor ruleEditor; - CPTextField predicateField; - RuleDelegate ruleDelegate; + CPWindow theWindow; + CPRuleEditor ruleEditor; + CPTextField predicateField; + RuleDelegate ruleDelegate; + CPPopUpButton langPopUp; + + CPDictionary englishDict; + CPDictionary spanishDict; + CPDictionary germanDict; } - (void)applicationDidFinishLaunching:(CPNotification)aNotification { - theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(50, 50, 800, 500) + theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(50, 50, 800, 520) styleMask:CPTitledWindowMask | CPClosableWindowMask | CPResizableWindowMask]; - [theWindow setTitle:@"Spanish CPRuleEditor Whole-Sentence Localization Test"]; + [theWindow setTitle:@"CPRuleEditor Multi-Language Localization Demo"]; [theWindow setFullPlatformWindow:YES]; var contentView = [theWindow contentView]; [contentView setBackgroundColor:[CPColor colorWithHexString:@"f3f4f5"]]; var label = [CPTextField labelWithTitle:@"CPRuleEditor Sentence Localization & Positional Reordering:"]; - [label setFrame:CGRectMake(20, 20, 760, 24)]; + [label setFrame:CGRectMake(20, 20, 500, 24)]; [label setFont:[CPFont boldSystemFontOfSize:14]]; [contentView addSubview:label]; + // Language Selector Label + var langLabel = [CPTextField labelWithTitle:@"Language:"]; + [langLabel setFrame:CGRectMake(530, 20, 80, 24)]; + [langLabel setFont:[CPFont boldSystemFontOfSize:12]]; + [langLabel setAlignment:CPRightTextAlignment]; + [contentView addSubview:langLabel]; + + // Language Selector PopUpButton + langPopUp = [[CPPopUpButton alloc] initWithFrame:CGRectMake(620, 16, 160, 24)]; + [langPopUp addItemWithTitle:@"Spanish"]; + [langPopUp addItemWithTitle:@"German"]; + [langPopUp addItemWithTitle:@"English"]; + [langPopUp setTarget:self]; + [langPopUp setAction:@selector(changeLanguage:)]; + [contentView addSubview:langPopUp]; + ruleDelegate = [[RuleDelegate alloc] init]; // Create Rule Editor @@ -40,20 +62,45 @@ [ruleEditor setTarget:self]; [ruleEditor setAction:@selector(ruleEditorAction:)]; - // Populate Spanish translations programmatically - var path = [[CPBundle mainBundle] pathForResource:@"Spanish.strings"]; - if (path) - { - [[ruleEditor standardLocalizer] loadContentOfURL:[CPURL URLWithString:path]]; - } + // Programmatic dictionaries setup + englishDict = [CPDictionary dictionary]; // Identity fallback + + spanishDict = [CPDictionary dictionaryWithDictionary:@{ + @"%[firstName]@ %[is equal to]@ %@" : @"%1$[Nombre]@ y %3$@ %2$[son iguales]@", + @"%[firstName]@ %[contains]@ %@" : @"%1$[Nombre]@ %2$[contiene]@ %3$@", + @"%[lastName]@ %[is equal to]@ %@" : @"%1$[Apellido]@ y %3$@ %2$[son iguales]@", + @"%[lastName]@ %[contains]@ %@" : @"%1$[Apellido]@ %2$[contiene]@ %3$@", + @"%[age]@ %[is equal to]@ %@" : @"%1$[Edad]@ y %3$@ %2$[son iguales]@", + @"%[age]@ is equal to %@" : @"%1$[Edad]@ y %3$@ %2$[son iguales]@", + @"Add row" : @"Añadir regla", + @"Delete row" : @"Eliminar regla", + @"Add compound row" : @"Añadir grupo de reglas" + }]; + + germanDict = [CPDictionary dictionaryWithDictionary:@{ + @"%[firstName]@ %[is equal to]@ %@" : @"%1$[Vorname]@ und %3$@ %2$[sind gleich]@", + @"%[firstName]@ %[contains]@ %@" : @"%1$[Vorname]@ %2$[enthält]@ %3$@", + @"%[lastName]@ %[is equal to]@ %@" : @"%1$[Nachname]@ und %3$@ %2$[sind gleich]@", + @"%[lastName]@ %[contains]@ %@" : @"%1$[Nachname]@ %2$[enthält]@ %3$@", + @"%[age]@ %[is equal to]@ %@" : @"%1$[Alter]@ und %3$@ %2$[sind gleich]@", + @"%[age]@ is equal to %@" : @"%1$[Alter]@ und %3$@ %2$[sind gleich]@", + @"Add row" : @"Regel hinzufügen", + @"Delete row" : @"Regel löschen", + @"Add compound row" : @"Regelgruppe hinzufügen" + }]; + + // Initialize with Spanish by default + [[ruleEditor standardLocalizer] setDictionary:spanishDict]; [contentView addSubview:ruleEditor]; - // Populate default row + // Populate initial rows + [ruleEditor addRow:self]; + [ruleEditor addRow:self]; [ruleEditor addRow:self]; // Display Output Label - var predLabel = [CPTextField labelWithTitle:@"CPRuleEditor Sentence Localization & Positional Reordering:"]; + var predLabel = [CPTextField labelWithTitle:@"Evaluated Predicate:"]; [predLabel setFrame:CGRectMake(20, 320, 760, 20)]; [predLabel setFont:[CPFont boldSystemFontOfSize:12]]; [contentView addSubview:predLabel]; @@ -67,13 +114,6 @@ [predicateField setFont:[CPFont systemFontOfSize:13]]; [contentView addSubview:predicateField]; - var addBtn = [CPButton buttonWithTitle:@"Añadir regla"]; - [addBtn setFrame:CGRectMake(20, 400, 120, 24)]; - [addBtn setTarget:ruleEditor]; - [addBtn setAction:@selector(addRow:)]; - [contentView addSubview:addBtn]; - - [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(ruleEditorRowsDidChange:) name:CPRuleEditorRowsDidChangeNotification @@ -83,6 +123,26 @@ [self ruleEditorAction:nil]; } +- (void)changeLanguage:(id)sender +{ + var selectedTitle = [sender titleOfSelectedItem], + targetDict = englishDict; + + if ([selectedTitle isEqualToString:@"Spanish"]) + { + targetDict = spanishDict; + } + else if ([selectedTitle isEqualToString:@"German"]) + { + targetDict = germanDict; + } + + [[ruleEditor standardLocalizer] setDictionary:targetDict]; + + // Post notification to trigger localized redraw across editor slices + [[CPNotificationCenter defaultCenter] postNotificationName:@"_CPRuleEditorLocalizerDidLoadNotification" object:[ruleEditor standardLocalizer]]; +} + - (void)ruleEditorAction:(id)sender { var predicate = [ruleEditor predicate]; diff --git a/Tests/Manual/CPRuleEditorTestSpanish/Resources/Spanish.strings b/Tests/Manual/CPRuleEditorTestSpanish/Resources/Spanish.strings deleted file mode 100644 index 75dd5e735..000000000 --- a/Tests/Manual/CPRuleEditorTestSpanish/Resources/Spanish.strings +++ /dev/null @@ -1,14 +0,0 @@ -/* Spanish formatting patterns for CPRuleEditor */ - -"%[firstName]@ %[is equal to]@ %@" = "%1$[Nombre]@ y %3$@ %2$[son iguales]@"; -"%[firstName]@ %[contains]@ %@" = "%1$[Nombre]@ %2$[contiene]@ %3$@"; - -"%[lastName]@ %[is equal to]@ %@" = "%1$[Apellido]@ y %3$@ %2$[son iguales]@"; -"%[lastName]@ %[contains]@ %@" = "%1$[Apellido]@ %2$[contiene]@ %3$@"; - -"%[age]@ %[is equal to]@ %@" = "%1$[Edad]@ y %3$@ %2$[son iguales]@"; -"%[age]@ is equal to %@" = "%1$[Edad]@ y %3$@ %2$[son iguales]@"; - -"Add row" = "Añadir regla"; -"Delete row" = "Eliminar regla"; -"Add compound row" = "Añadir grupo de reglas";