Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
appinventor-sources
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
appinventor-sources
Commits
baef0cdc
Unverified
Commit
baef0cdc
authored
Nov 16, 2019
by
Evan W. Patton
Committed by
Jeffrey I. Schiller
Dec 17, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement per-component tooltips on collison
Change-Id: I5778d0ddad1a34c1019645478fb6061d88acea10
parent
468b72a6
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
162 additions
and
106 deletions
+162
-106
appinventor/appengine/build.xml
appinventor/appengine/build.xml
+1
-1
appinventor/blocklyeditor/src/blocks/components.js
appinventor/blocklyeditor/src/blocks/components.js
+34
-20
appinventor/blocklyeditor/src/component_database.js
appinventor/blocklyeditor/src/component_database.js
+24
-16
appinventor/blocklyeditor/tests/com/google/appinventor/blocklyeditor/component_database_tests.js
...gle/appinventor/blocklyeditor/component_database_tests.js
+1
-1
appinventor/components/src/com/google/appinventor/components/scripts/ComponentProcessor.java
...le/appinventor/components/scripts/ComponentProcessor.java
+8
-0
appinventor/components/src/com/google/appinventor/components/scripts/ComponentTranslationGenerator.java
...tor/components/scripts/ComponentTranslationGenerator.java
+94
-68
No files found.
appinventor/appengine/build.xml
View file @
baef0cdc
...
...
@@ -569,7 +569,7 @@
<pathelement
location=
"${gwt.sdk}/validation-api-1.0.0.GA-sources.jar"
/>
</classpath>
<jvmarg
value=
"-Xss2M"
/>
<!-- increase if you see a StackOverflowError -->
<jvmarg
value=
"-Xmx
1
G"
/>
<jvmarg
value=
"-Xmx
2
G"
/>
<jvmarg
line=
"${XstartOnFirstThread}"
/>
<jvmarg
value=
"-Dfile.encoding=UTF-8"
/>
<arg
line=
"-war"
/>
...
...
appinventor/blocklyeditor/src/blocks/components.js
View file @
baef0cdc
...
...
@@ -283,10 +283,11 @@ Blockly.Blocks.component_event = {
this
.
setParameterOrientation
(
horizParams
);
var
tooltipDescription
;
if
(
eventType
)
{
tooltipDescription
=
componentDb
.
getInternationalizedEventDescription
(
eventType
.
name
,
eventType
.
description
);
tooltipDescription
=
componentDb
.
getInternationalizedEventDescription
(
this
.
getTypeName
(),
eventType
.
name
,
eventType
.
description
);
}
else
{
tooltipDescription
=
componentDb
.
getInternationalizedEventDescription
(
this
.
eventName
);
tooltipDescription
=
componentDb
.
getInternationalizedEventDescription
(
this
.
getTypeName
(),
this
.
eventName
);
}
this
.
setTooltip
(
tooltipDescription
);
this
.
setPreviousStatement
(
false
,
null
);
...
...
@@ -309,6 +310,10 @@ Blockly.Blocks.component_event = {
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
// Also must create flydown params and DO input if they don't exist.
...
...
@@ -418,11 +423,10 @@ Blockly.Blocks.component_event = {
}
},
helpUrl
:
function
()
{
var
mode
=
this
.
typeName
===
"
Form
"
?
"
Screen
"
:
this
.
typeName
;
var
url
=
Blockly
.
ComponentBlock
.
EVENTS_HELPURLS
[
mode
];
var
url
=
Blockly
.
ComponentBlock
.
EVENTS_HELPURLS
[
this
.
getTypeName
()];
if
(
url
&&
url
[
0
]
==
'
/
'
)
{
var
parts
=
url
.
split
(
'
#
'
);
parts
[
1
]
=
this
.
typeName
+
'
.
'
+
this
.
eventName
;
parts
[
1
]
=
this
.
getTypeName
()
+
'
.
'
+
this
.
eventName
;
url
=
parts
.
join
(
'
#
'
);
}
return
url
;
...
...
@@ -599,18 +603,14 @@ Blockly.Blocks.component_event = {
Blockly
.
Blocks
.
component_method
=
{
category
:
'
Component
'
,
helpUrl
:
function
()
{
var
mode
=
this
.
typeName
===
"
Form
"
?
"
Screen
"
:
this
.
typeName
;
var
url
=
Blockly
.
ComponentBlock
.
METHODS_HELPURLS
[
mode
];
var
url
=
Blockly
.
ComponentBlock
.
METHODS_HELPURLS
[
this
.
getTypeName
()];
if
(
url
&&
url
[
0
]
==
'
/
'
)
{
var
parts
=
url
.
split
(
'
#
'
);
parts
[
1
]
=
this
.
typeName
+
'
.
'
+
this
.
methodName
;
parts
[
1
]
=
this
.
getTypeName
()
+
'
.
'
+
this
.
methodName
;
url
=
parts
.
join
(
'
#
'
);
}
return
url
;
},
init
:
function
()
{
this
.
genericComponentInput
=
Blockly
.
Msg
.
LANG_COMPONENT_BLOCK_GENERIC_METHOD_TITLE_FOR_COMPONENT
;
},
mutationToDom
:
function
()
{
...
...
@@ -728,9 +728,10 @@ Blockly.Blocks.component_method = {
var
tooltipDescription
;
if
(
methodTypeObject
)
{
tooltipDescription
=
componentDb
.
getInternationalizedMethodDescription
(
methodTypeObject
.
name
,
methodTypeObject
.
description
);
tooltipDescription
=
componentDb
.
getInternationalizedMethodDescription
(
this
.
getTypeName
(),
methodTypeObject
.
name
,
methodTypeObject
.
description
);
}
else
{
tooltipDescription
=
componentDb
.
getInternationalizedMethodDescription
(
this
.
type
Name
);
tooltipDescription
=
componentDb
.
getInternationalizedMethodDescription
(
this
.
getTypeName
(),
this
.
method
Name
);
}
this
.
setTooltip
(
tooltipDescription
);
...
...
@@ -780,6 +781,10 @@ Blockly.Blocks.component_method = {
this
.
rendered
=
oldRendered
;
},
getTypeName
:
function
()
{
return
this
.
typeName
===
'
Form
'
?
'
Screen
'
:
this
.
typeName
;
},
// Rename the block's instanceName, type, and reset its title
rename
:
function
(
oldname
,
newname
)
{
if
(
this
.
instanceName
==
oldname
)
{
...
...
@@ -957,11 +962,10 @@ Blockly.Blocks.component_set_get = {
category
:
'
Component
'
,
//this.blockType = 'getter',
helpUrl
:
function
()
{
var
mode
=
this
.
typeName
===
"
Form
"
?
"
Screen
"
:
this
.
typeName
;
var
url
=
Blockly
.
ComponentBlock
.
PROPERTIES_HELPURLS
[
mode
];
var
url
=
Blockly
.
ComponentBlock
.
PROPERTIES_HELPURLS
[
this
.
getTypeName
()];
if
(
url
&&
url
[
0
]
==
'
/
'
)
{
var
parts
=
url
.
split
(
'
#
'
);
parts
[
1
]
=
this
.
typeName
+
'
.
'
+
this
.
propertyName
;
parts
[
1
]
=
this
.
getTypeName
()
+
'
.
'
+
this
.
propertyName
;
url
=
parts
.
join
(
'
#
'
);
}
return
url
;
...
...
@@ -1026,7 +1030,8 @@ Blockly.Blocks.component_set_get = {
}
var
tooltipDescription
;
if
(
this
.
propertyName
)
{
tooltipDescription
=
componentDb
.
getInternationalizedPropertyDescription
(
this
.
propertyName
,
this
.
propertyObject
.
description
);
tooltipDescription
=
componentDb
.
getInternationalizedPropertyDescription
(
this
.
getTypeName
(),
this
.
propertyName
,
this
.
propertyObject
.
description
);
}
else
{
tooltipDescription
=
Blockly
.
Msg
.
UNDEFINED_BLOCK_TOOLTIP
;
}
...
...
@@ -1042,7 +1047,8 @@ Blockly.Blocks.component_set_get = {
thisBlock
.
propertyObject
=
thisBlock
.
getPropertyObject
(
selection
);
thisBlock
.
setTypeCheck
();
if
(
thisBlock
.
propertyName
)
{
thisBlock
.
setTooltip
(
componentDb
.
getInternationalizedPropertyDescription
(
thisBlock
.
propertyName
,
thisBlock
.
propertyObject
.
description
));
thisBlock
.
setTooltip
(
componentDb
.
getInternationalizedPropertyDescription
(
thisBlock
.
getTabCatcherElement
(),
thisBlock
.
propertyName
,
thisBlock
.
propertyObject
.
description
));
}
else
{
thisBlock
.
setTooltip
(
Blockly
.
Msg
.
UNDEFINED_BLOCK_TOOLTIP
);
}
...
...
@@ -1135,6 +1141,10 @@ Blockly.Blocks.component_set_get = {
this
.
rendered
=
oldRendered
;
},
getTypeName
:
function
()
{
return
this
.
typeName
===
'
Form
'
?
'
Screen
'
:
this
.
typeName
;
},
setTypeCheck
:
function
()
{
var
inputOrOutput
=
Blockly
.
Blocks
.
Utilities
.
OUTPUT
;
...
...
@@ -1304,8 +1314,7 @@ Blockly.Blocks.component_component_block = {
category
:
'
Component
'
,
helpUrl
:
function
()
{
var
mode
=
this
.
typeName
===
"
Form
"
?
"
Screen
"
:
this
.
typeName
;
return
Blockly
.
ComponentBlock
.
HELPURLS
[
mode
];
return
Blockly
.
ComponentBlock
.
HELPURLS
[
this
.
getTypeName
()];
},
// TODO: fix
mutationToDom
:
function
()
{
...
...
@@ -1329,6 +1338,11 @@ Blockly.Blocks.component_component_block = {
this
.
setOutput
(
true
,
[
this
.
typeName
,
"
COMPONENT
"
]);
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
rename
:
function
(
oldname
,
newname
)
{
if
(
this
.
instanceName
==
oldname
)
{
...
...
appinventor/blocklyeditor/src/component_database.js
View file @
baef0cdc
...
...
@@ -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.
* @param translations
*/
Blockly
.
ComponentDatabase
.
prototype
.
populateTranslations
=
function
(
translations
)
{
var
newkey
;
for
(
var
key
in
translations
)
{
if
(
translations
.
hasOwnProperty
(
key
))
{
var
parts
=
key
.
split
(
'
-
'
,
2
);
if
(
parts
[
0
]
==
'
COMPONENT
'
)
{
if
(
parts
[
0
]
==
=
'
COMPONENT
'
)
{
this
.
i18nComponentTypes_
[
parts
[
1
]]
=
translations
[
key
];
}
else
if
(
parts
[
0
]
==
'
PROPERTY
'
)
{
}
else
if
(
parts
[
0
]
==
=
'
PROPERTY
'
)
{
this
.
i18nPropertyNames_
[
parts
[
1
]]
=
translations
[
key
];
}
else
if
(
parts
[
0
]
==
'
EVENT
'
)
{
}
else
if
(
parts
[
0
]
==
=
'
EVENT
'
)
{
this
.
i18nEventNames_
[
parts
[
1
]]
=
translations
[
key
];
}
else
if
(
parts
[
0
]
==
'
METHOD
'
)
{
}
else
if
(
parts
[
0
]
==
=
'
METHOD
'
)
{
this
.
i18nMethodNames_
[
parts
[
1
]]
=
translations
[
key
];
}
else
if
(
parts
[
0
]
==
'
PARAM
'
)
{
}
else
if
(
parts
[
0
]
==
=
'
PARAM
'
)
{
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
];
}
else
if
(
parts
[
0
]
==
'
METHDESC
'
)
{
this
.
i18nMethodDescriptions_
[
parts
[
1
]]
=
translations
[
key
];
}
else
if
(
parts
[
0
]
==
'
PROPDESC
'
)
{
this
.
i18nPropertyDescriptions_
[
parts
[
1
]]
=
translations
[
key
];
}
else
if
(
parts
[
0
]
===
'
METHODDESC
'
)
{
newkey
=
parts
[
1
].
replace
(
Blockly
.
ComponentDatabase
.
METHODDESC
,
''
);
this
.
i18nMethodDescriptions_
[
newkey
]
=
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
* @param {?string=name} opt_default Optional default value (default: name parameter)
* @returns {string} The localized string if available, otherwise the unlocalized name.
*/
Blockly
.
ComponentDatabase
.
prototype
.
getInternationalizedEventDescription
=
function
(
name
,
opt_default
)
{
return
this
.
i18nEventDescriptions_
[
name
]
||
opt_default
||
name
;
Blockly
.
ComponentDatabase
.
prototype
.
getInternationalizedEventDescription
=
function
(
component
,
name
,
opt_default
)
{
return
this
.
i18nEventDescriptions_
[
component
+
'
.
'
+
name
]
||
this
.
i18nEventDescriptions_
[
name
]
||
opt_default
||
name
;
};
/**
...
...
@@ -541,8 +549,8 @@ Blockly.ComponentDatabase.prototype.getInternationalizedMethodName = function(na
* @param {?string=name} opt_default Optional default value (default: name parameter)
* @returns {string} The localized string if available, otherwise the unlocalized name.
*/
Blockly
.
ComponentDatabase
.
prototype
.
getInternationalizedMethodDescription
=
function
(
name
,
opt_default
)
{
return
this
.
i18nMethodDescriptions_
[
name
]
||
opt_default
||
name
;
Blockly
.
ComponentDatabase
.
prototype
.
getInternationalizedMethodDescription
=
function
(
component
,
name
,
opt_default
)
{
return
this
.
i18nMethodDescriptions_
[
component
+
'
.
'
+
name
]
||
this
.
i18nMethodDescriptions_
[
name
]
||
opt_default
||
name
;
};
/**
...
...
@@ -571,6 +579,6 @@ Blockly.ComponentDatabase.prototype.getInternationalizedPropertyName = function(
* @param {?string=name} opt_default Optional default value (default: name parameter)
* @returns {string} The localized string if available, otherwise the unlocalized name.
*/
Blockly
.
ComponentDatabase
.
prototype
.
getInternationalizedPropertyDescription
=
function
(
name
,
opt_default
)
{
return
this
.
i18nPropertyDescriptions_
[
name
]
||
opt_default
||
name
;
Blockly
.
ComponentDatabase
.
prototype
.
getInternationalizedPropertyDescription
=
function
(
component
,
name
,
opt_default
)
{
return
this
.
i18nPropertyDescriptions_
[
component
+
'
.
'
+
name
]
||
this
.
i18nPropertyDescriptions_
[
name
]
||
opt_default
||
name
;
};
appinventor/blocklyeditor/tests/com/google/appinventor/blocklyeditor/component_database_tests.js
View file @
baef0cdc
...
...
@@ -61,7 +61,7 @@ page.open('src/demos/yail/yail_testing_index.html', function(status) {
'
METHOD-TranslatedMethod
'
:
'
SuccessfulMethod
'
,
'
PROPERTY-TranslatedProperty
'
:
'
SuccessfulProperty
'
,
'
EVENTDESC-TranslatedEvent
'
:
'
Successfully translated event test.
'
,
'
METHDESC-TranslatedMethod
'
:
'
Successfully translated method test.
'
,
'
METH
OD
DESC-TranslatedMethod
'
:
'
Successfully translated method test.
'
,
'
PROPDESC-TranslatedProperty
'
:
'
Successfully translated property test.
'
});
...
...
appinventor/components/src/com/google/appinventor/components/scripts/ComponentProcessor.java
View file @
baef0cdc
...
...
@@ -841,6 +841,14 @@ public abstract class ComponentProcessor extends AbstractProcessor {
return
"Form"
.
equals
(
componentTypeName
)
?
"Screen"
:
componentTypeName
;
}
protected
String
getName
()
{
if
(
name
.
equals
(
"Form"
))
{
return
"Screen"
;
}
else
{
return
name
;
}
}
}
/**
...
...
appinventor/components/src/com/google/appinventor/components/scripts/ComponentTranslationGenerator.java
View file @
baef0cdc
...
...
@@ -7,6 +7,7 @@ package com.google.appinventor.components.scripts;
import
java.io.IOException
;
import
java.io.Writer
;
import
java.util.HashSet
;
import
java.util.TreeMap
;
import
java.util.TreeSet
;
import
java.util.LinkedHashMap
;
...
...
@@ -22,18 +23,22 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
private
static
final
String
OUTPUT_FILE_NAME
=
"ComponentsTranslation.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
,
Set
<
String
>
outMethods
,
Set
<
String
>
outEvents
,
StringBuilder
sb
)
{
if
(
component
.
getExternal
())
{
// Avoid adding entries for external components
return
;
}
Map
<
String
,
Parameter
>
parameters
=
new
LinkedHashMap
<
String
,
Parameter
>();
sb
.
append
(
"\n\n/* Component: "
+
component
.
name
+
" */\n\n"
);
sb
.
append
(
" map.put(\"COMPONENT-"
+
component
.
name
+
"\", MESSAGES."
+
Character
.
toLowerCase
(
component
.
name
.
charAt
(
0
))
+
component
.
name
.
substring
(
1
)
+
"ComponentPallette());\n\n"
);
sb
.
append
(
" map.put(\""
+
component
.
name
+
"-helpString\", MESSAGES."
+
component
.
name
+
"HelpStringComponentPallette());\n\n"
);
sb
.
append
(
"\n\n/* Component: "
+
component
.
getName
()
+
" */\n\n"
);
sb
.
append
(
" map.put(\"COMPONENT-"
+
component
.
getName
()
+
"\", MESSAGES."
+
Character
.
toLowerCase
(
component
.
getName
().
charAt
(
0
))
+
component
.
getName
().
substring
(
1
)
+
"ComponentPallette());\n\n"
);
sb
.
append
(
" map.put(\""
+
component
.
getName
()
+
"-helpString\", MESSAGES."
+
component
.
getName
()
+
"HelpStringComponentPallette());\n\n"
);
sb
.
append
(
"\n\n/* Properties */\n\n"
);
for
(
Property
prop
:
component
.
properties
.
values
())
{
String
propertyName
=
prop
.
name
;
...
...
@@ -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
)
{
// santize the category name
String
[]
parts
=
category
.
split
(
" "
);
...
...
@@ -133,19 +114,19 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
Map
<
String
,
Property
>
outProperties
,
Map
<
String
,
Method
>
outMethods
,
Map
<
String
,
Event
>
outEvents
,
StringBuilder
sb
)
{
sb
.
append
(
" @DefaultMessage(\""
);
sb
.
append
(
component
.
name
);
sb
.
append
(
component
.
getName
()
);
sb
.
append
(
"\")\n"
);
sb
.
append
(
" @Description(\"\")\n"
);
sb
.
append
(
" String "
);
sb
.
append
(
Character
.
toLowerCase
(
component
.
name
.
charAt
(
0
)));
sb
.
append
(
component
.
name
.
substring
(
1
));
sb
.
append
(
Character
.
toLowerCase
(
component
.
getName
()
.
charAt
(
0
)));
sb
.
append
(
component
.
getName
()
.
substring
(
1
));
sb
.
append
(
"ComponentPallette();\n\n"
);
sb
.
append
(
" @DefaultMessage(\""
);
sb
.
append
(
sanitize
(
component
.
description
));
sb
.
append
(
"\")\n"
);
sb
.
append
(
" @Description(\"\")\n"
);
sb
.
append
(
" String "
);
sb
.
append
(
component
.
name
);
sb
.
append
(
component
.
getName
()
);
sb
.
append
(
"HelpStringComponentPallette();\n\n"
);
for
(
Property
property
:
component
.
properties
.
values
())
{
if
(
property
.
isUserVisible
()
||
component
.
designerProperties
.
containsKey
(
property
.
name
)
||
...
...
@@ -173,13 +154,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
sb
.
append
(
" String "
);
sb
.
append
(
property
.
name
);
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
)
{
...
...
@@ -190,13 +164,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
sb
.
append
(
" String "
);
sb
.
append
(
method
.
name
);
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
)
{
outParameters
.
put
(
param
.
name
,
param
);
}
...
...
@@ -210,13 +177,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
sb
.
append
(
" String "
);
sb
.
append
(
event
.
name
);
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
)
{
outParameters
.
put
(
param
.
name
,
param
);
}
...
...
@@ -263,6 +223,47 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
.
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
{
Set
<
String
>
categories
=
new
TreeSet
<>();
Map
<
String
,
Property
>
properties
=
new
TreeMap
<>();
...
...
@@ -279,8 +280,12 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
for
(
Map
.
Entry
<
String
,
ComponentInfo
>
entry
:
components
.
entrySet
())
{
ComponentInfo
component
=
entry
.
getValue
();
outputComponentAutogen
(
component
,
properties
,
methods
,
events
,
sb
);
computeTooltipMap
(
component
);
categories
.
add
(
component
.
getCategory
());
}
for
(
String
key
:
collisionKeys
)
{
tooltips
.
remove
(
key
);
}
sb
.
append
(
"\n /* Properties */\n"
);
for
(
Map
.
Entry
<
String
,
Property
>
entry
:
properties
.
entrySet
())
{
outputPropertyAutogen
(
entry
.
getValue
(),
sb
);
...
...
@@ -293,6 +298,15 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
for
(
Map
.
Entry
<
String
,
Event
>
entry
:
events
.
entrySet
())
{
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"
);
for
(
Map
.
Entry
<
String
,
Parameter
>
entry
:
parameters
.
entrySet
())
{
outputParameterAutogen
(
entry
.
getValue
(),
sb
);
...
...
@@ -316,14 +330,15 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
@Override
protected
void
outputResults
()
throws
IOException
{
outputAutogenOdeMessages
();
StringBuilder
sb
=
new
StringBuilder
();
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.Map;\n"
);
sb
.
append
(
""
);
sb
.
append
(
"
\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 static Map<String, String> myMap = map();\n\n"
);
sb
.
append
(
" private static String getName(String key) {\n"
);
...
...
@@ -377,7 +392,7 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
sb
.
append
(
" HashMap<String, String> map = new HashMap<String, String>();\n"
);
// Components are already sorted.
Set
<
String
>
categories
=
new
TreeSet
<
String
>();
Set
<
String
>
categories
=
new
TreeSet
<>();
Set
<
String
>
properties
=
new
TreeSet
<>();
Set
<
String
>
methods
=
new
TreeSet
<>();
Set
<
String
>
events
=
new
TreeSet
<>();
...
...
@@ -387,14 +402,26 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
categories
.
add
(
component
.
getCategory
());
}
sb
.
append
(
"\n\n /* Descriptions */\n\n"
);
for
(
String
property
:
properties
)
{
outputPropertyDescription
(
property
,
sb
);
}
for
(
String
event
:
events
)
{
outputEventDescription
(
event
,
sb
);
for
(
String
key
:
tooltips
.
keySet
())
{
if
(
key
.
endsWith
(
"PropertyDescriptions"
))
{
sb
.
append
(
" map.put(\"PROPDESC-"
);
sb
.
append
(
key
.
replaceAll
(
"__"
,
"."
));
sb
.
append
(
"\", MESSAGES."
);
sb
.
append
(
key
);
sb
.
append
(
"());\n"
);
}
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"
);
}
for
(
String
method
:
methods
)
{
outputMethodDescription
(
method
,
sb
);
}
sb
.
append
(
"\n\n /* Categories */\n\n"
);
for
(
String
category
:
categories
)
{
...
...
@@ -409,7 +436,6 @@ public final class ComponentTranslationGenerator extends ComponentProcessor {
writer
.
flush
();
writer
.
close
();
messager
.
printMessage
(
Diagnostic
.
Kind
.
NOTE
,
"Wrote file "
+
src
.
toUri
());
outputAutogenOdeMessages
();
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment