Unverified Commit baef0cdc authored by Evan W. Patton's avatar Evan W. Patton Committed by Jeffrey I. Schiller

Implement per-component tooltips on collison

Change-Id: I5778d0ddad1a34c1019645478fb6061d88acea10
parent 468b72a6
...@@ -569,7 +569,7 @@ ...@@ -569,7 +569,7 @@
<pathelement location="${gwt.sdk}/validation-api-1.0.0.GA-sources.jar" /> <pathelement location="${gwt.sdk}/validation-api-1.0.0.GA-sources.jar" />
</classpath> </classpath>
<jvmarg value="-Xss2M"/> <!-- increase if you see a StackOverflowError --> <jvmarg value="-Xss2M"/> <!-- increase if you see a StackOverflowError -->
<jvmarg value="-Xmx1G"/> <jvmarg value="-Xmx2G"/>
<jvmarg line="${XstartOnFirstThread}"/> <jvmarg line="${XstartOnFirstThread}"/>
<jvmarg value="-Dfile.encoding=UTF-8" /> <jvmarg value="-Dfile.encoding=UTF-8" />
<arg line="-war"/> <arg line="-war"/>
......
...@@ -283,10 +283,11 @@ Blockly.Blocks.component_event = { ...@@ -283,10 +283,11 @@ Blockly.Blocks.component_event = {
this.setParameterOrientation(horizParams); this.setParameterOrientation(horizParams);
var tooltipDescription; var tooltipDescription;
if (eventType) { if (eventType) {
tooltipDescription = componentDb.getInternationalizedEventDescription(eventType.name, eventType.description); tooltipDescription = componentDb.getInternationalizedEventDescription(this.getTypeName(), eventType.name,
eventType.description);
} }
else { else {
tooltipDescription = componentDb.getInternationalizedEventDescription(this.eventName); tooltipDescription = componentDb.getInternationalizedEventDescription(this.getTypeName(), this.eventName);
} }
this.setTooltip(tooltipDescription); this.setTooltip(tooltipDescription);
this.setPreviousStatement(false, null); this.setPreviousStatement(false, null);
...@@ -309,6 +310,10 @@ Blockly.Blocks.component_event = { ...@@ -309,6 +310,10 @@ Blockly.Blocks.component_event = {
this.rendered = oldRendered; this.rendered = oldRendered;
}, },
getTypeName: function() {
return this.typeName === 'Form' ? 'Screen' : this.typeName;
},
// [lyn, 10/24/13] Allow switching between horizontal and vertical display of arguments // [lyn, 10/24/13] Allow switching between horizontal and vertical display of arguments
// Also must create flydown params and DO input if they don't exist. // Also must create flydown params and DO input if they don't exist.
...@@ -418,11 +423,10 @@ Blockly.Blocks.component_event = { ...@@ -418,11 +423,10 @@ Blockly.Blocks.component_event = {
} }
}, },
helpUrl : function() { helpUrl : function() {
var mode = this.typeName === "Form" ? "Screen" : this.typeName; var url = Blockly.ComponentBlock.EVENTS_HELPURLS[this.getTypeName()];
var url = Blockly.ComponentBlock.EVENTS_HELPURLS[mode];
if (url && url[0] == '/') { if (url && url[0] == '/') {
var parts = url.split('#'); var parts = url.split('#');
parts[1] = this.typeName + '.' + this.eventName; parts[1] = this.getTypeName() + '.' + this.eventName;
url = parts.join('#'); url = parts.join('#');
} }
return url; return url;
...@@ -599,18 +603,14 @@ Blockly.Blocks.component_event = { ...@@ -599,18 +603,14 @@ Blockly.Blocks.component_event = {
Blockly.Blocks.component_method = { Blockly.Blocks.component_method = {
category : 'Component', category : 'Component',
helpUrl : function() { helpUrl : function() {
var mode = this.typeName === "Form" ? "Screen" : this.typeName; var url = Blockly.ComponentBlock.METHODS_HELPURLS[this.getTypeName()];
var url = Blockly.ComponentBlock.METHODS_HELPURLS[mode];
if (url && url[0] == '/') { if (url && url[0] == '/') {
var parts = url.split('#'); var parts = url.split('#');
parts[1] = this.typeName + '.' + this.methodName; parts[1] = this.getTypeName() + '.' + this.methodName;
url = parts.join('#'); url = parts.join('#');
} }
return url; return url;
}, },
init: function() {
this.genericComponentInput = Blockly.Msg.LANG_COMPONENT_BLOCK_GENERIC_METHOD_TITLE_FOR_COMPONENT;
},
mutationToDom : function() { mutationToDom : function() {
...@@ -728,9 +728,10 @@ Blockly.Blocks.component_method = { ...@@ -728,9 +728,10 @@ Blockly.Blocks.component_method = {
var tooltipDescription; var tooltipDescription;
if (methodTypeObject) { if (methodTypeObject) {
tooltipDescription = componentDb.getInternationalizedMethodDescription(methodTypeObject.name, methodTypeObject.description); tooltipDescription = componentDb.getInternationalizedMethodDescription(this.getTypeName(), methodTypeObject.name,
methodTypeObject.description);
} else { } else {
tooltipDescription = componentDb.getInternationalizedMethodDescription(this.typeName); tooltipDescription = componentDb.getInternationalizedMethodDescription(this.getTypeName(), this.methodName);
} }
this.setTooltip(tooltipDescription); this.setTooltip(tooltipDescription);
...@@ -780,6 +781,10 @@ Blockly.Blocks.component_method = { ...@@ -780,6 +781,10 @@ Blockly.Blocks.component_method = {
this.rendered = oldRendered; this.rendered = oldRendered;
}, },
getTypeName: function() {
return this.typeName === 'Form' ? 'Screen' : this.typeName;
},
// Rename the block's instanceName, type, and reset its title // Rename the block's instanceName, type, and reset its title
rename : function(oldname, newname) { rename : function(oldname, newname) {
if (this.instanceName == oldname) { if (this.instanceName == oldname) {
...@@ -957,11 +962,10 @@ Blockly.Blocks.component_set_get = { ...@@ -957,11 +962,10 @@ Blockly.Blocks.component_set_get = {
category : 'Component', category : 'Component',
//this.blockType = 'getter', //this.blockType = 'getter',
helpUrl : function() { helpUrl : function() {
var mode = this.typeName === "Form" ? "Screen" : this.typeName; var url = Blockly.ComponentBlock.PROPERTIES_HELPURLS[this.getTypeName()];
var url = Blockly.ComponentBlock.PROPERTIES_HELPURLS[mode];
if (url && url[0] == '/') { if (url && url[0] == '/') {
var parts = url.split('#'); var parts = url.split('#');
parts[1] = this.typeName + '.' + this.propertyName; parts[1] = this.getTypeName() + '.' + this.propertyName;
url = parts.join('#'); url = parts.join('#');
} }
return url; return url;
...@@ -1026,7 +1030,8 @@ Blockly.Blocks.component_set_get = { ...@@ -1026,7 +1030,8 @@ Blockly.Blocks.component_set_get = {
} }
var tooltipDescription; var tooltipDescription;
if (this.propertyName) { if (this.propertyName) {
tooltipDescription = componentDb.getInternationalizedPropertyDescription(this.propertyName, this.propertyObject.description); tooltipDescription = componentDb.getInternationalizedPropertyDescription(this.getTypeName(), this.propertyName,
this.propertyObject.description);
} else { } else {
tooltipDescription = Blockly.Msg.UNDEFINED_BLOCK_TOOLTIP; tooltipDescription = Blockly.Msg.UNDEFINED_BLOCK_TOOLTIP;
} }
...@@ -1042,7 +1047,8 @@ Blockly.Blocks.component_set_get = { ...@@ -1042,7 +1047,8 @@ Blockly.Blocks.component_set_get = {
thisBlock.propertyObject = thisBlock.getPropertyObject(selection); thisBlock.propertyObject = thisBlock.getPropertyObject(selection);
thisBlock.setTypeCheck(); thisBlock.setTypeCheck();
if (thisBlock.propertyName) { if (thisBlock.propertyName) {
thisBlock.setTooltip(componentDb.getInternationalizedPropertyDescription(thisBlock.propertyName, thisBlock.propertyObject.description)); thisBlock.setTooltip(componentDb.getInternationalizedPropertyDescription(thisBlock.getTabCatcherElement(),
thisBlock.propertyName, thisBlock.propertyObject.description));
} else { } else {
thisBlock.setTooltip(Blockly.Msg.UNDEFINED_BLOCK_TOOLTIP); thisBlock.setTooltip(Blockly.Msg.UNDEFINED_BLOCK_TOOLTIP);
} }
...@@ -1135,6 +1141,10 @@ Blockly.Blocks.component_set_get = { ...@@ -1135,6 +1141,10 @@ Blockly.Blocks.component_set_get = {
this.rendered = oldRendered; this.rendered = oldRendered;
}, },
getTypeName: function() {
return this.typeName === 'Form' ? 'Screen' : this.typeName;
},
setTypeCheck : function() { setTypeCheck : function() {
var inputOrOutput = Blockly.Blocks.Utilities.OUTPUT; var inputOrOutput = Blockly.Blocks.Utilities.OUTPUT;
...@@ -1304,8 +1314,7 @@ Blockly.Blocks.component_component_block = { ...@@ -1304,8 +1314,7 @@ Blockly.Blocks.component_component_block = {
category : 'Component', category : 'Component',
helpUrl : function() { helpUrl : function() {
var mode = this.typeName === "Form" ? "Screen" : this.typeName; return Blockly.ComponentBlock.HELPURLS[this.getTypeName()];
return Blockly.ComponentBlock.HELPURLS[mode];
}, // TODO: fix }, // TODO: fix
mutationToDom : function() { mutationToDom : function() {
...@@ -1329,6 +1338,11 @@ Blockly.Blocks.component_component_block = { ...@@ -1329,6 +1338,11 @@ Blockly.Blocks.component_component_block = {
this.setOutput(true, [this.typeName,"COMPONENT"]); this.setOutput(true, [this.typeName,"COMPONENT"]);
this.errors = [{name:"checkIfUndefinedBlock"},{name:"checkComponentNotExistsError"}]; this.errors = [{name:"checkIfUndefinedBlock"},{name:"checkComponentNotExistsError"}];
}, },
getTypeName: function() {
return this.typeName === 'Form' ? 'Screen' : this.typeName;
},
// Renames the block's instanceName, type, and reset its title // Renames the block's instanceName, type, and reset its title
rename : function(oldname, newname) { rename : function(oldname, newname) {
if (this.instanceName == oldname) { if (this.instanceName == oldname) {
......
...@@ -360,30 +360,38 @@ Blockly.ComponentDatabase.prototype.populateTypes = function(componentInfos) { ...@@ -360,30 +360,38 @@ Blockly.ComponentDatabase.prototype.populateTypes = function(componentInfos) {
} }
}; };
Blockly.ComponentDatabase.PROPDESC = /PropertyDescriptions$/;
Blockly.ComponentDatabase.METHODDESC = /MethodDescrptions$/;
Blockly.ComponentDatabase.EVENTDESC = /EventDescriptions$/;
/** /**
* Populate the tranlsations for components. * Populate the tranlsations for components.
* @param translations * @param translations
*/ */
Blockly.ComponentDatabase.prototype.populateTranslations = function(translations) { Blockly.ComponentDatabase.prototype.populateTranslations = function(translations) {
var newkey;
for (var key in translations) { for (var key in translations) {
if (translations.hasOwnProperty(key)) { if (translations.hasOwnProperty(key)) {
var parts = key.split('-', 2); var parts = key.split('-', 2);
if (parts[0] == 'COMPONENT') { if (parts[0] === 'COMPONENT') {
this.i18nComponentTypes_[parts[1]] = translations[key]; this.i18nComponentTypes_[parts[1]] = translations[key];
} else if (parts[0] == 'PROPERTY') { } else if (parts[0] === 'PROPERTY') {
this.i18nPropertyNames_[parts[1]] = translations[key]; this.i18nPropertyNames_[parts[1]] = translations[key];
} else if (parts[0] == 'EVENT') { } else if (parts[0] === 'EVENT') {
this.i18nEventNames_[parts[1]] = translations[key]; this.i18nEventNames_[parts[1]] = translations[key];
} else if (parts[0] == 'METHOD') { } else if (parts[0] === 'METHOD') {
this.i18nMethodNames_[parts[1]] = translations[key]; this.i18nMethodNames_[parts[1]] = translations[key];
} else if (parts[0] == 'PARAM') { } else if (parts[0] === 'PARAM') {
this.i18nParamNames_[parts[1]] = translations[key]; this.i18nParamNames_[parts[1]] = translations[key];
} else if (parts[0] == 'EVENTDESC') { } else if (parts[0] === 'EVENTDESC') {
newkey = parts[1].replace(Blockly.ComponentDatabase.EVENTDESC, '');
this.i18nEventDescriptions_[parts[1]] = translations[key]; this.i18nEventDescriptions_[parts[1]] = translations[key];
} else if (parts[0] == 'METHDESC') { } else if (parts[0] === 'METHODDESC') {
this.i18nMethodDescriptions_[parts[1]] = translations[key]; newkey = parts[1].replace(Blockly.ComponentDatabase.METHODDESC, '');
} else if (parts[0] == 'PROPDESC') { this.i18nMethodDescriptions_[newkey] = translations[key];
this.i18nPropertyDescriptions_[parts[1]] = translations[key]; } else if (parts[0] === 'PROPDESC') {
newkey = parts[1].replace(Blockly.ComponentDatabase.PROPDESC, '');
this.i18nPropertyDescriptions_[newkey] = translations[key];
} }
} }
} }
...@@ -521,8 +529,8 @@ Blockly.ComponentDatabase.prototype.getInternationalizedEventName = function(nam ...@@ -521,8 +529,8 @@ Blockly.ComponentDatabase.prototype.getInternationalizedEventName = function(nam
* @param {?string=name} opt_default Optional default value (default: name parameter) * @param {?string=name} opt_default Optional default value (default: name parameter)
* @returns {string} The localized string if available, otherwise the unlocalized name. * @returns {string} The localized string if available, otherwise the unlocalized name.
*/ */
Blockly.ComponentDatabase.prototype.getInternationalizedEventDescription = function(name, opt_default) { Blockly.ComponentDatabase.prototype.getInternationalizedEventDescription = function(component, name, opt_default) {
return this.i18nEventDescriptions_[name] || opt_default || name; return this.i18nEventDescriptions_[component + '.' + name] || this.i18nEventDescriptions_[name] || opt_default || name;
}; };
/** /**
...@@ -541,8 +549,8 @@ Blockly.ComponentDatabase.prototype.getInternationalizedMethodName = function(na ...@@ -541,8 +549,8 @@ Blockly.ComponentDatabase.prototype.getInternationalizedMethodName = function(na
* @param {?string=name} opt_default Optional default value (default: name parameter) * @param {?string=name} opt_default Optional default value (default: name parameter)
* @returns {string} The localized string if available, otherwise the unlocalized name. * @returns {string} The localized string if available, otherwise the unlocalized name.
*/ */
Blockly.ComponentDatabase.prototype.getInternationalizedMethodDescription = function(name, opt_default) { Blockly.ComponentDatabase.prototype.getInternationalizedMethodDescription = function(component, name, opt_default) {
return this.i18nMethodDescriptions_[name] || opt_default || name; return this.i18nMethodDescriptions_[component + '.' + name] || this.i18nMethodDescriptions_[name] || opt_default || name;
}; };
/** /**
...@@ -571,6 +579,6 @@ Blockly.ComponentDatabase.prototype.getInternationalizedPropertyName = function( ...@@ -571,6 +579,6 @@ Blockly.ComponentDatabase.prototype.getInternationalizedPropertyName = function(
* @param {?string=name} opt_default Optional default value (default: name parameter) * @param {?string=name} opt_default Optional default value (default: name parameter)
* @returns {string} The localized string if available, otherwise the unlocalized name. * @returns {string} The localized string if available, otherwise the unlocalized name.
*/ */
Blockly.ComponentDatabase.prototype.getInternationalizedPropertyDescription = function(name, opt_default) { Blockly.ComponentDatabase.prototype.getInternationalizedPropertyDescription = function(component, name, opt_default) {
return this.i18nPropertyDescriptions_[name] || opt_default || name; return this.i18nPropertyDescriptions_[component + '.' + name] || this.i18nPropertyDescriptions_[name] || opt_default || name;
}; };
...@@ -61,7 +61,7 @@ page.open('src/demos/yail/yail_testing_index.html', function(status) { ...@@ -61,7 +61,7 @@ page.open('src/demos/yail/yail_testing_index.html', function(status) {
'METHOD-TranslatedMethod': 'SuccessfulMethod', 'METHOD-TranslatedMethod': 'SuccessfulMethod',
'PROPERTY-TranslatedProperty': 'SuccessfulProperty', 'PROPERTY-TranslatedProperty': 'SuccessfulProperty',
'EVENTDESC-TranslatedEvent': 'Successfully translated event test.', 'EVENTDESC-TranslatedEvent': 'Successfully translated event test.',
'METHDESC-TranslatedMethod': 'Successfully translated method test.', 'METHODDESC-TranslatedMethod': 'Successfully translated method test.',
'PROPDESC-TranslatedProperty': 'Successfully translated property test.' 'PROPDESC-TranslatedProperty': 'Successfully translated property test.'
}); });
......
...@@ -841,6 +841,14 @@ public abstract class ComponentProcessor extends AbstractProcessor { ...@@ -841,6 +841,14 @@ public abstract class ComponentProcessor extends AbstractProcessor {
return "Form".equals(componentTypeName) ? "Screen" : componentTypeName; return "Form".equals(componentTypeName) ? "Screen" : componentTypeName;
} }
protected String getName() {
if (name.equals("Form")) {
return "Screen";
} else {
return name;
}
}
} }
/** /**
......
...@@ -7,6 +7,7 @@ package com.google.appinventor.components.scripts; ...@@ -7,6 +7,7 @@ package com.google.appinventor.components.scripts;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.HashSet;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
...@@ -22,18 +23,22 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -22,18 +23,22 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
private static final String OUTPUT_FILE_NAME = "ComponentsTranslation.java"; private static final String OUTPUT_FILE_NAME = "ComponentsTranslation.java";
private static final String AUTOGEN_OUTPUT_FILE_NAME = "AutogeneratedOdeMessages.java"; private static final String AUTOGEN_OUTPUT_FILE_NAME = "AutogeneratedOdeMessages.java";
private Map<String, String> tooltips = new TreeMap<>();
private Map<String, Set<String>> tooltipComponent = new TreeMap<>();
private Set<String> collisionKeys = new HashSet<>();
private void outputComponent(ComponentInfo component, Set<String> outProperties, private void outputComponent(ComponentInfo component, Set<String> outProperties,
Set<String> outMethods, Set<String> outEvents, StringBuilder sb) { Set<String> outMethods, Set<String> outEvents, StringBuilder sb) {
if (component.getExternal()) { // Avoid adding entries for external components if (component.getExternal()) { // Avoid adding entries for external components
return; return;
} }
Map<String, Parameter> parameters = new LinkedHashMap<String, Parameter>(); Map<String, Parameter> parameters = new LinkedHashMap<String, Parameter>();
sb.append("\n\n/* Component: " + component.name + " */\n\n"); sb.append("\n\n/* Component: " + component.getName() + " */\n\n");
sb.append(" map.put(\"COMPONENT-" + component.name + "\", MESSAGES." + sb.append(" map.put(\"COMPONENT-" + component.getName() + "\", MESSAGES."
Character.toLowerCase(component.name.charAt(0)) + component.name.substring(1) + + Character.toLowerCase(component.getName().charAt(0)) + component.getName().substring(1)
"ComponentPallette());\n\n"); + "ComponentPallette());\n\n");
sb.append(" map.put(\"" + component.name + "-helpString\", MESSAGES." + sb.append(" map.put(\"" + component.getName() + "-helpString\", MESSAGES."
component.name + "HelpStringComponentPallette());\n\n"); + component.getName() + "HelpStringComponentPallette());\n\n");
sb.append("\n\n/* Properties */\n\n"); sb.append("\n\n/* Properties */\n\n");
for (Property prop : component.properties.values()) { for (Property prop : component.properties.values()) {
String propertyName = prop.name; String propertyName = prop.name;
...@@ -85,30 +90,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -85,30 +90,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
} }
} }
private void outputPropertyDescription(String property, StringBuilder sb) {
sb.append(" map.put(\"PROPDESC-");
sb.append(property);
sb.append("\", MESSAGES.");
sb.append(property);
sb.append("PropertyDescriptions());\n");
}
private void outputEventDescription(String event, StringBuilder sb) {
sb.append(" map.put(\"EVENTDESC-");
sb.append(event);
sb.append("\", MESSAGES.");
sb.append(event);
sb.append("EventDescriptions());\n");
}
private void outputMethodDescription(String method, StringBuilder sb) {
sb.append(" map.put(\"METHDESC-");
sb.append(method);
sb.append("\", MESSAGES.");
sb.append(method);
sb.append("MethodDescriptions());\n");
}
private void outputCategory(String category, StringBuilder sb) { private void outputCategory(String category, StringBuilder sb) {
// santize the category name // santize the category name
String[] parts = category.split(" "); String[] parts = category.split(" ");
...@@ -133,19 +114,19 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -133,19 +114,19 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
Map<String, Property> outProperties, Map<String, Method> outMethods, Map<String, Property> outProperties, Map<String, Method> outMethods,
Map<String, Event> outEvents, StringBuilder sb) { Map<String, Event> outEvents, StringBuilder sb) {
sb.append(" @DefaultMessage(\""); sb.append(" @DefaultMessage(\"");
sb.append(component.name); sb.append(component.getName());
sb.append("\")\n"); sb.append("\")\n");
sb.append(" @Description(\"\")\n"); sb.append(" @Description(\"\")\n");
sb.append(" String "); sb.append(" String ");
sb.append(Character.toLowerCase(component.name.charAt(0))); sb.append(Character.toLowerCase(component.getName().charAt(0)));
sb.append(component.name.substring(1)); sb.append(component.getName().substring(1));
sb.append("ComponentPallette();\n\n"); sb.append("ComponentPallette();\n\n");
sb.append(" @DefaultMessage(\""); sb.append(" @DefaultMessage(\"");
sb.append(sanitize(component.description)); sb.append(sanitize(component.description));
sb.append("\")\n"); sb.append("\")\n");
sb.append(" @Description(\"\")\n"); sb.append(" @Description(\"\")\n");
sb.append(" String "); sb.append(" String ");
sb.append(component.name); sb.append(component.getName());
sb.append("HelpStringComponentPallette();\n\n"); sb.append("HelpStringComponentPallette();\n\n");
for (Property property : component.properties.values()) { for (Property property : component.properties.values()) {
if (property.isUserVisible() || component.designerProperties.containsKey(property.name) || if (property.isUserVisible() || component.designerProperties.containsKey(property.name) ||
...@@ -173,13 +154,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -173,13 +154,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
sb.append(" String "); sb.append(" String ");
sb.append(property.name); sb.append(property.name);
sb.append("Properties();\n\n"); sb.append("Properties();\n\n");
sb.append(" @DefaultMessage(\"");
sb.append(sanitize(property.getDescription()));
sb.append("\")\n");
sb.append(" @Description(\"\")\n");
sb.append(" String ");
sb.append(property.name);
sb.append("PropertyDescriptions();\n\n");
} }
private void outputMethodAutogen(Method method, Map<String, Parameter> outParameters, StringBuilder sb) { private void outputMethodAutogen(Method method, Map<String, Parameter> outParameters, StringBuilder sb) {
...@@ -190,13 +164,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -190,13 +164,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
sb.append(" String "); sb.append(" String ");
sb.append(method.name); sb.append(method.name);
sb.append("Methods();\n\n"); sb.append("Methods();\n\n");
sb.append(" @DefaultMessage(\"");
sb.append(sanitize(method.description));
sb.append("\")\n");
sb.append(" @Description(\"\")\n");
sb.append(" String ");
sb.append(method.name);
sb.append("MethodDescriptions();\n\n");
for (Parameter param : method.parameters) { for (Parameter param : method.parameters) {
outParameters.put(param.name, param); outParameters.put(param.name, param);
} }
...@@ -210,13 +177,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -210,13 +177,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
sb.append(" String "); sb.append(" String ");
sb.append(event.name); sb.append(event.name);
sb.append("Events();\n\n"); sb.append("Events();\n\n");
sb.append(" @DefaultMessage(\"");
sb.append(sanitize(event.description));
sb.append("\")\n");
sb.append(" @Description(\"\")\n");
sb.append(" String ");
sb.append(event.name);
sb.append("EventDescriptions();\n\n");
for (Parameter param : event.parameters) { for (Parameter param : event.parameters) {
outParameters.put(param.name, param); outParameters.put(param.name, param);
} }
...@@ -263,6 +223,47 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -263,6 +223,47 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
.replaceAll("\"", "\\\\\"").replaceAll("'", "''").replaceAll("[ \t]+", " ").trim(); .replaceAll("\"", "\\\\\"").replaceAll("'", "''").replaceAll("[ \t]+", " ").trim();
} }
private void storeTooltip(ComponentInfo component, String name, String suffix,
String description) {
String key = name + suffix;
String value = tooltips.get(key);
if (collisionKeys.contains(key)) {
// Already detected a collision
key = component.getName() + "__" + key;
tooltips.put(key, description);
} else if (value == null) {
// This is the first observation of this key
tooltips.put(key, description);
Set<String> components = new HashSet<>();
components.add(component.getName());
tooltipComponent.put(key, components);
} else if (!value.equals(description)) {
// Descriptions don't match == collision!
collisionKeys.add(key);
for (String componentName : tooltipComponent.get(key)) {
tooltips.put(componentName + "__" + key, value);
}
key = component.getName() + "__" + key;
tooltips.put(key, description);
} else {
// Two (or more) components have the exact same description. Technically not a collision, but
// we need to do some bookkeeping in case a collision is detected with another component.
tooltipComponent.get(key).add(component.getName());
}
}
private void computeTooltipMap(ComponentInfo component) {
for (Property property : component.properties.values()) {
storeTooltip(component, property.name, "PropertyDescriptions", property.getDescription());
}
for (Method method : component.methods.values()) {
storeTooltip(component, method.name, "MethodDescriptions", method.description);
}
for (Event event : component.events.values()) {
storeTooltip(component, event.name, "EventDescriptions", event.description);
}
}
protected void outputAutogenOdeMessages() throws IOException { protected void outputAutogenOdeMessages() throws IOException {
Set<String> categories = new TreeSet<>(); Set<String> categories = new TreeSet<>();
Map<String, Property> properties = new TreeMap<>(); Map<String, Property> properties = new TreeMap<>();
...@@ -279,8 +280,12 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -279,8 +280,12 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
for (Map.Entry<String, ComponentInfo> entry : components.entrySet()) { for (Map.Entry<String, ComponentInfo> entry : components.entrySet()) {
ComponentInfo component = entry.getValue(); ComponentInfo component = entry.getValue();
outputComponentAutogen(component, properties, methods, events, sb); outputComponentAutogen(component, properties, methods, events, sb);
computeTooltipMap(component);
categories.add(component.getCategory()); categories.add(component.getCategory());
} }
for (String key : collisionKeys) {
tooltips.remove(key);
}
sb.append("\n /* Properties */\n"); sb.append("\n /* Properties */\n");
for (Map.Entry<String, Property> entry : properties.entrySet()) { for (Map.Entry<String, Property> entry : properties.entrySet()) {
outputPropertyAutogen(entry.getValue(), sb); outputPropertyAutogen(entry.getValue(), sb);
...@@ -293,6 +298,15 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -293,6 +298,15 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
for (Map.Entry<String, Event> entry : events.entrySet()) { for (Map.Entry<String, Event> entry : events.entrySet()) {
outputEventAutogen(entry.getValue(), parameters, sb); outputEventAutogen(entry.getValue(), parameters, sb);
} }
for (Map.Entry<String, String> entry : tooltips.entrySet()) {
sb.append(" @DefaultMessage(\"");
sb.append(sanitize(entry.getValue()));
sb.append("\")\n");
sb.append(" @Description(\"\")\n");
sb.append(" String ");
sb.append(entry.getKey());
sb.append("();\n\n");
}
sb.append("\n /* Parameters */\n"); sb.append("\n /* Parameters */\n");
for (Map.Entry<String, Parameter> entry : parameters.entrySet()) { for (Map.Entry<String, Parameter> entry : parameters.entrySet()) {
outputParameterAutogen(entry.getValue(), sb); outputParameterAutogen(entry.getValue(), sb);
...@@ -316,14 +330,15 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -316,14 +330,15 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
@Override @Override
protected void outputResults() throws IOException { protected void outputResults() throws IOException {
outputAutogenOdeMessages();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("package com.google.appinventor.client;\n"); sb.append("package com.google.appinventor.client;\n");
sb.append(""); sb.append("\n");
sb.append("import java.util.HashMap;\n"); sb.append("import java.util.HashMap;\n");
sb.append("import java.util.Map;\n"); sb.append("import java.util.Map;\n");
sb.append(""); sb.append("\n");
sb.append("import static com.google.appinventor.client.Ode.MESSAGES;\n"); sb.append("import static com.google.appinventor.client.Ode.MESSAGES;\n");
sb.append(""); sb.append("\n");
sb.append("public class ComponentsTranslation {\n"); sb.append("public class ComponentsTranslation {\n");
sb.append(" public static Map<String, String> myMap = map();\n\n"); sb.append(" public static Map<String, String> myMap = map();\n\n");
sb.append(" private static String getName(String key) {\n"); sb.append(" private static String getName(String key) {\n");
...@@ -377,7 +392,7 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -377,7 +392,7 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
sb.append(" HashMap<String, String> map = new HashMap<String, String>();\n"); sb.append(" HashMap<String, String> map = new HashMap<String, String>();\n");
// Components are already sorted. // Components are already sorted.
Set<String> categories = new TreeSet<String>(); Set<String> categories = new TreeSet<>();
Set<String> properties = new TreeSet<>(); Set<String> properties = new TreeSet<>();
Set<String> methods = new TreeSet<>(); Set<String> methods = new TreeSet<>();
Set<String> events = new TreeSet<>(); Set<String> events = new TreeSet<>();
...@@ -387,14 +402,26 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -387,14 +402,26 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
categories.add(component.getCategory()); categories.add(component.getCategory());
} }
sb.append("\n\n /* Descriptions */\n\n"); sb.append("\n\n /* Descriptions */\n\n");
for (String property : properties) { for (String key : tooltips.keySet()) {
outputPropertyDescription(property, sb); if (key.endsWith("PropertyDescriptions")) {
} sb.append(" map.put(\"PROPDESC-");
for (String event : events) { sb.append(key.replaceAll("__", "."));
outputEventDescription(event, sb); sb.append("\", MESSAGES.");
} sb.append(key);
for (String method : methods) { sb.append("());\n");
outputMethodDescription(method, sb); } else if (key.endsWith("MethodDescriptions")) {
sb.append(" map.put(\"METHODDESC-");
sb.append(key.replaceAll("__", "."));
sb.append("\", MESSAGES.");
sb.append(key);
sb.append("());\n");
} else if (key.endsWith("EventDescriptions")) {
sb.append(" map.put(\"EVENTDESC-");
sb.append(key.replaceAll("__", "."));
sb.append("\", MESSAGES.");
sb.append(key);
sb.append("());\n");
}
} }
sb.append("\n\n /* Categories */\n\n"); sb.append("\n\n /* Categories */\n\n");
for (String category : categories) { for (String category : categories) {
...@@ -409,7 +436,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor { ...@@ -409,7 +436,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
writer.flush(); writer.flush();
writer.close(); writer.close();
messager.printMessage(Diagnostic.Kind.NOTE, "Wrote file " + src.toUri()); messager.printMessage(Diagnostic.Kind.NOTE, "Wrote file " + src.toUri());
outputAutogenOdeMessages();
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment