mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 04:57:03 +00:00
Fixed: CPRuleEditor word-by-word translation issue (#1834)
This commit is contained in:
@@ -94,4 +94,174 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
|
||||
return aString;
|
||||
}
|
||||
|
||||
#pragma mark - Whole Sentence Formatting & Reordering Helpers
|
||||
|
||||
// Constructs the English-matching format representation of a single view
|
||||
- (CPString)_englishRepresentationForView:(id)aView
|
||||
{
|
||||
if ([aView isKindOfClass:[CPPopUpButton class]])
|
||||
{
|
||||
var selectedItem = [aView selectedItem];
|
||||
if (selectedItem)
|
||||
{
|
||||
var originalTitle = [selectedItem representedObject] || selectedItem._originalTitle || [selectedItem title];
|
||||
return "%[" + originalTitle + "]@";
|
||||
}
|
||||
return "%[]@";
|
||||
}
|
||||
else if ([aView isKindOfClass:[CPTextField class]] && ![aView isEditable])
|
||||
{
|
||||
return [aView stringValue];
|
||||
}
|
||||
else
|
||||
{
|
||||
return "%@";
|
||||
}
|
||||
}
|
||||
|
||||
// Builds the current formatting lookup key (e.g. "%[property]@ %[is]@ %@")
|
||||
- (CPString)formattingKeyForViews:(NSArray *)views
|
||||
{
|
||||
var keyParts = [];
|
||||
var count = [views count];
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var view = [views objectAtIndex:i];
|
||||
[keyParts addObject:[self _englishRepresentationForView:view]];
|
||||
}
|
||||
return [keyParts componentsJoinedByString:@" "];
|
||||
}
|
||||
|
||||
// Localizes all popup menu options within the row under their proper context
|
||||
- (void)localizeMenuItemsForViews:(NSArray *)views
|
||||
{
|
||||
var count = [views count];
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var view = [views objectAtIndex:i];
|
||||
if ([view isKindOfClass:[CPPopUpButton class]])
|
||||
{
|
||||
var menuItems = [view itemArray];
|
||||
var menuItemsCount = [menuItems count];
|
||||
var selectedItem = [view selectedItem];
|
||||
|
||||
for (var j = 0; j < menuItemsCount; j++)
|
||||
{
|
||||
var item = [menuItems objectAtIndex:j];
|
||||
|
||||
if (!item._originalTitle)
|
||||
{
|
||||
item._originalTitle = [item title];
|
||||
}
|
||||
|
||||
// Temporarily select item to formulate the unique localization key
|
||||
[view selectItem:item];
|
||||
|
||||
var tempKey = [self formattingKeyForViews:views];
|
||||
var tempPattern = [self localizedStringForString:tempKey];
|
||||
|
||||
if (tempPattern !== tempKey)
|
||||
{
|
||||
// Search for this view position's translation inside the pattern (e.g. %2$[son iguales]@)
|
||||
var regex = /%(\d+)\$(?:\[([^\]]+)\])?@/g;
|
||||
var match;
|
||||
while ((match = regex.exec(tempPattern)) !== null)
|
||||
{
|
||||
var position = parseInt(match[1], 10) - 1;
|
||||
var translatedValue = match[2];
|
||||
|
||||
if (position === i && translatedValue)
|
||||
{
|
||||
[item setTitle:translatedValue];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restore initial selection
|
||||
if (selectedItem)
|
||||
{
|
||||
[view selectItem:selectedItem];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Translates labels and reorders the active subviews based on positional formatting string
|
||||
- (NSArray *)localizeAndReorderViews:(NSArray *)views
|
||||
{
|
||||
var key = [self formattingKeyForViews:views];
|
||||
var localizedPattern = [self localizedStringForString:key];
|
||||
|
||||
if (localizedPattern === key)
|
||||
{
|
||||
return views;
|
||||
}
|
||||
|
||||
var newViews = [CPMutableArray array];
|
||||
|
||||
// Pattern to extract index and translation: %1$[translation]@ or %1$@
|
||||
var regex = /%(\d+)\$(?:\[([^\]]+)\])?@/g;
|
||||
var lastIndex = 0;
|
||||
var match;
|
||||
|
||||
while ((match = regex.exec(localizedPattern)) !== null)
|
||||
{
|
||||
// 1. Insert any leading static text (e.g. " y ")
|
||||
var literalText = localizedPattern.substring(lastIndex, match.index);
|
||||
if (literalText.length > 0)
|
||||
{
|
||||
var label = [CPTextField labelWithString:literalText];
|
||||
[newViews addObject:label];
|
||||
}
|
||||
|
||||
// 2. Identify the original view corresponding to the positional index
|
||||
var position = parseInt(match[1], 10) - 1;
|
||||
var translatedValue = match[2];
|
||||
|
||||
if (position >= 0 && position < [views count])
|
||||
{
|
||||
var originalView = [views objectAtIndex:position];
|
||||
|
||||
if (translatedValue !== undefined && translatedValue !== null)
|
||||
{
|
||||
if ([originalView isKindOfClass:[CPPopUpButton class]])
|
||||
{
|
||||
var selectedItem = [originalView selectedItem];
|
||||
if (selectedItem)
|
||||
{
|
||||
if (!selectedItem._originalTitle)
|
||||
{
|
||||
selectedItem._originalTitle = [selectedItem title];
|
||||
}
|
||||
[selectedItem setTitle:translatedValue];
|
||||
}
|
||||
}
|
||||
else if (typeof originalView.setStringValue === "function")
|
||||
{
|
||||
[originalView setStringValue:translatedValue];
|
||||
}
|
||||
}
|
||||
|
||||
[newViews addObject:originalView];
|
||||
}
|
||||
|
||||
lastIndex = regex.lastIndex;
|
||||
}
|
||||
|
||||
// 3. Append trailing static text
|
||||
if (lastIndex < localizedPattern.length)
|
||||
{
|
||||
var literalText = localizedPattern.substring(lastIndex);
|
||||
if (literalText.length > 0)
|
||||
{
|
||||
var label = [CPTextField labelWithString:literalText];
|
||||
[newViews addObject:label];
|
||||
}
|
||||
}
|
||||
|
||||
return newViews;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user