fixed: localizer issues

This commit is contained in:
daboe01
2026-06-03 21:19:09 +02:00
parent 750c123d1e
commit e9b9d9702e
5 changed files with 77 additions and 25 deletions
+26 -6
View File
@@ -226,6 +226,9 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
{
[[_slices objectAtIndex:i] _reconfigureSubviews];
}
[self _updatePredicate];
[self _sendRuleAction];
} argument:nil order:0 modes:[CPDefaultRunLoopMode]];
}
}
@@ -574,7 +577,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
if ([self rowTypeForRow:current_index] === CPRuleEditorRowTypeCompound)
{
var candidate = [[self _rowCacheForIndex:current_index] rowObject],
subObjects = [[self _subrowObjectsOfObject:candidate] _representedObject];
subObjects = [self _subrowObjectsOfObject:candidate]; // Standard direct array query
if ([subObjects indexOfObjectIdenticalTo:targetObject] !== CPNotFound)
return current_index;
@@ -641,7 +644,7 @@ TODO: implement
for (var i = rowIndex + 1; i < count; i++)
{
var candidate = [[self _rowCacheForIndex:i] rowObject],
indexInSubrows = [[subobjects _representedObject] indexOfObjectIdenticalTo:candidate];
indexInSubrows = [subobjects indexOfObjectIdenticalTo:candidate]; // Standard direct array query
if (indexInSubrows !== CPNotFound)
{
@@ -810,7 +813,7 @@ TODO: implement
while (current_index !== CPNotFound)
{
var rowObject = [[self _rowCacheForIndex:current_index] rowObject],
relativeChildIndex = [[subrows _representedObject] indexOfObjectIdenticalTo:rowObject];
relativeChildIndex = [subrows indexOfObjectIdenticalTo:rowObject]; // Standard direct array query
if (relativeChildIndex !== CPNotFound)
[childsIndexes addIndex:relativeChildIndex];
@@ -867,7 +870,6 @@ TODO: implement
for (i = 0; i < count; i++)
{
var item = [items objectAtIndex:i],
//var displayValue = [self _queryValueForItem:item inRow:aRow]; Ask the delegate or get cached value ?.
displayValue = [[self displayValuesForRow:aRow] objectAtIndex:i],
predpart = [self _sendDelegateRuleEditorPredicatePartsForCriterion:item withDisplayValue:displayValue inRow:aRow];
@@ -885,6 +887,7 @@ TODO: implement
return nil;
var current_index = [subrowsIndexes firstIndex];
while (current_index !== CPNotFound)
{
var subpredicate = [self predicateForRow:current_index];
@@ -1392,8 +1395,25 @@ TODO: implement
if ([self rowTypeForRow:row] === type && itemIndex < [aCriteria count])
{
var crit = [aCriteria objectAtIndex:itemIndex];
[current_criterions addObject:crit];
// Verify that this row's parent path matches the path currently being built
var pathMatches = true;
for (var p = 0; p < itemIndex; p++)
{
var criterionA = [aCriteria objectAtIndex:p],
criterionB = [items objectAtIndex:p];
if (criterionA !== criterionB && (typeof criterionA.isEqual !== "function" || ![criterionA isEqual:criterionB]))
{
pathMatches = false;
break;
}
}
if (pathMatches)
{
var crit = [aCriteria objectAtIndex:itemIndex];
[current_criterions addObject:crit];
}
}
}
+17 -5
View File
@@ -112,7 +112,7 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
if (!originalTitle)
{
var rep = [selectedItem representedObject];
if (rep && typeof rep === "object" && typeof rep.objectForKey === "function")
if (rep && typeof rep === "object" && [rep respondsToSelector:@selector(objectForKey:)])
{
originalTitle = [rep objectForKey:@"value"];
}
@@ -170,7 +170,7 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
if (!item._originalTitle)
{
var rep = [item representedObject];
if (rep && typeof rep === "object" && typeof rep.objectForKey === "function")
if (rep && typeof rep === "object" && [rep respondsToSelector:@selector(objectForKey:)])
{
item._originalTitle = [rep objectForKey:@"value"];
}
@@ -230,7 +230,9 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
while ((match = regex.exec(localizedPattern)) !== null)
{
var literalText = localizedPattern.substring(lastIndex, match.index);
if (literalText.length > 0)
// Only add a label if there are actual non-whitespace characters (like 'y')
if (literalText.length > 0 && /\S/.test(literalText))
{
var label = [CPTextField labelWithTitle:literalText];
[newViews addObject:label];
@@ -257,9 +259,17 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
[selectedItem setTitle:translatedValue];
}
}
else if (typeof originalView.setStringValue === "function")
else if ([originalView respondsToSelector:@selector(setStringValue:)])
{
[originalView setStringValue:translatedValue];
// Recalculate frame size if it is a static CPTextField to avoid visual clipping
if ([originalView isKindOfClass:[CPTextField class]] && ![originalView isEditable])
{
var font = [originalView font] || [CPFont systemFontOfSize:[CPFont systemFontSize]],
size = [translatedValue sizeWithFont:font];
[originalView setFrameSize:CGSizeMake(size.width + 4, CGRectGetHeight([originalView frame]))];
}
}
}
@@ -272,7 +282,9 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
if (lastIndex < localizedPattern.length)
{
var literalText = localizedPattern.substring(lastIndex);
if (literalText.length > 0)
// Only add a label if there are actual non-whitespace characters
if (literalText.length > 0 && /\S/.test(literalText))
{
var label = [CPTextField labelWithTitle:literalText];
[newViews addObject:label];
@@ -35,6 +35,7 @@
[ruleEditor setAutoresizingMask:CPViewWidthSizable];
[ruleEditor setDelegate:ruleDelegate];
[ruleEditor setEditable:YES];
[ruleEditor setNestingMode:CPRuleEditorNestingModeList];
[ruleEditor setRowHeight:28];
[ruleEditor setTarget:self];
[ruleEditor setAction:@selector(ruleEditorAction:)];
@@ -72,6 +73,12 @@
[addBtn setAction:@selector(addRow:)];
[contentView addSubview:addBtn];
[[CPNotificationCenter defaultCenter] addObserver:self
selector:@selector(ruleEditorRowsDidChange:)
name:CPRuleEditorRowsDidChangeNotification
object:ruleEditor];
[theWindow orderFront:self];
[self ruleEditorAction:nil];
}
@@ -89,4 +96,18 @@
}
}
- (void)ruleEditorRowsDidChange:(CPNotification)note
{
var predicate = [ruleEditor predicate];
if (predicate)
{
[predicateField setStringValue:[predicate predicateFormat]];
}
else
{
[predicateField setStringValue:@"(Incomplete Predicate)"];
}
}
@end
@@ -7,7 +7,8 @@
"%[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";
"Add compound row" = "Añadir grupo de reglas";
@@ -2,6 +2,10 @@
@import <AppKit/CPRuleEditor.j>
@import <AppKit/CPTextField.j>
// Ensure the standard operator constants are explicitly defined
var CPEqualToPredicateOperatorType = 4,
CPContainsPredicateOperatorType = 99;
@implementation RuleDelegate : CPObject
{
}
@@ -11,13 +15,11 @@
{
if (criterion == nil)
{
// Root criteria
return [@[@"firstName", @"lastName", @"age"] objectAtIndex:index];
}
if ([criterion isEqualToString:@"firstName"] || [criterion isEqualToString:@"lastName"])
{
// "is equal to" is placed at index 0 so that the reordered Spanish sentence layout loads automatically on startup
return [@[@"is equal to", @"contains"] objectAtIndex:index];
}
@@ -28,41 +30,39 @@
if ([criterion isEqualToString:@"contains"] || [criterion isEqualToString:@"is equal to"])
{
// The child of an operator is the leaf value node
return @"value";
}
return nil;
}
// 2. Number of children for a given criterion
// 2. Number of children
- (CPInteger)ruleEditor:(CPRuleEditor)editor numberOfChildrenForCriterion:(id)criterion withRowType:(CPRuleEditorRowType)rowType
{
if (criterion == nil)
{
return 3; // firstName, lastName, age
return 3;
}
if ([criterion isEqualToString:@"firstName"] || [criterion isEqualToString:@"lastName"])
{
return 2; // contains, is equal to
return 2;
}
if ([criterion isEqualToString:@"age"])
{
return 1; // is equal to
return 1;
}
if ([criterion isEqualToString:@"contains"] || [criterion isEqualToString:@"is equal to"])
{
// Operators have 1 child representing the value node
return 1;
}
return 0; // Leaf nodes return 0
return 0;
}
// 3. Display values (labels, popup titles, or text input fields)
// 3. Display values
- (id)ruleEditor:(CPRuleEditor)editor displayValueForCriterion:(id)criterion inRow:(CPInteger)row
{
if ([criterion isEqualToString:@"firstName"]) return @"firstName";
@@ -74,7 +74,6 @@
if ([criterion isEqualToString:@"value"])
{
// Return the actual editable text field view for the leaf node
var textField = [[CPTextField alloc] initWithFrame:CGRectMake(0, 0, 120, 24)];
[textField setBezeled:YES];
[textField setBezelStyle:CPTextFieldSquareBezel];
@@ -86,7 +85,7 @@
return nil;
}
// 4. Predicate parts mapping
// 4. Predicate parts
- (CPDictionary)ruleEditor:(CPRuleEditor)editor predicatePartsForCriterion:(id)criterion withDisplayValue:(id)value inRow:(CPInteger)row
{
var parts = @{};
@@ -105,7 +104,6 @@
}
else if ([criterion isEqualToString:@"value"])
{
// Resolve the correct active text field from the slice row on screen
var activeValue = value;
var slices = [editor valueForKey:@"_slices"];