Skip to content

Commit cf40043

Browse files
committed
Support for options items
1 parent d897f2e commit cf40043

File tree

11 files changed

+351
-2
lines changed

11 files changed

+351
-2
lines changed

AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/AndroidAnnotationProcessor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import com.googlecode.androidannotations.annotations.ItemLongClick;
4545
import com.googlecode.androidannotations.annotations.ItemSelect;
4646
import com.googlecode.androidannotations.annotations.LongClick;
47+
import com.googlecode.androidannotations.annotations.OptionsItem;
4748
import com.googlecode.androidannotations.annotations.OptionsMenu;
4849
import com.googlecode.androidannotations.annotations.RoboGuice;
4950
import com.googlecode.androidannotations.annotations.SystemService;
@@ -101,6 +102,7 @@
101102
import com.googlecode.androidannotations.processing.ItemSelectedProcessor;
102103
import com.googlecode.androidannotations.processing.LongClickProcessor;
103104
import com.googlecode.androidannotations.processing.ModelProcessor;
105+
import com.googlecode.androidannotations.processing.OptionsItemProcessor;
104106
import com.googlecode.androidannotations.processing.OptionsMenuProcessor;
105107
import com.googlecode.androidannotations.processing.PrefProcessor;
106108
import com.googlecode.androidannotations.processing.ResProcessor;
@@ -132,6 +134,7 @@
132134
import com.googlecode.androidannotations.validation.ItemSelectedValidator;
133135
import com.googlecode.androidannotations.validation.LongClickValidator;
134136
import com.googlecode.androidannotations.validation.ModelValidator;
137+
import com.googlecode.androidannotations.validation.OptionsItemValidator;
135138
import com.googlecode.androidannotations.validation.OptionsMenuValidator;
136139
import com.googlecode.androidannotations.validation.PrefValidator;
137140
import com.googlecode.androidannotations.validation.ResValidator;
@@ -196,6 +199,7 @@
196199
Put.class,
197200
FromHtml.class, //
198201
OptionsMenu.class, //
202+
OptionsItem.class, //
199203
HtmlRes.class})
200204
@SupportedSourceVersion(SourceVersion.RELEASE_6)
201205
public class AndroidAnnotationProcessor extends AnnotatedAbstractProcessor {
@@ -354,6 +358,7 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices
354358
modelValidator.register(new PutValidator(processingEnv));
355359
modelValidator.register(new AppValidator(processingEnv, androidManifest));
356360
modelValidator.register(new OptionsMenuValidator(processingEnv, rClass));
361+
modelValidator.register(new OptionsItemValidator(processingEnv, rClass));
357362
return modelValidator;
358363
}
359364

@@ -396,6 +401,7 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices
396401
modelProcessor.register(new GetProcessor(processingEnv, restImplementationHolder));
397402
modelProcessor.register(new AppProcessor());
398403
modelProcessor.register(new OptionsMenuProcessor(rClass));
404+
modelProcessor.register(new OptionsItemProcessor(rClass));
399405
return modelProcessor;
400406
}
401407

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Copyright (C) 2010-2011 eBusiness Information, Excilys Group
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed To in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package com.googlecode.androidannotations.annotations;
17+
18+
import java.lang.annotation.ElementType;
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
import java.lang.annotation.Target;
22+
23+
/**
24+
* Should be used on option items listener methods in activity classes
25+
*
26+
* The method may have zero or one parameter, that MUST be of type
27+
* android.view.MenuItem .
28+
*
29+
* The annotation value should be one of R.id.* fields. If not set, the method
30+
* name will be used as the R.id.* field name.
31+
*
32+
*/
33+
@Retention(RetentionPolicy.SOURCE)
34+
@Target(ElementType.METHOD)
35+
public @interface OptionsItem {
36+
37+
int [] value() default Id.DEFAULT_VALUE;
38+
39+
}

AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/ValidatorHelper.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
public class ValidatorHelper {
6161

6262
private static final String ANDROID_VIEW_QUALIFIED_NAME = "android.view.View";
63+
private static final String ANDROID_MENU_ITEM_QUALIFIED_NAME = "android.view.MenuItem";
6364
private static final String ANDROID_TEXT_VIEW_QUALIFIED_NAME = "android.widget.TextView";
6465
private static final String ANDROID_VIEWGROUP_QUALIFIED_NAME = "android.view.ViewGroup";
6566
private static final String ANDROID_APPLICATION_QUALIFIED_NAME = "android.app.Application";
@@ -378,6 +379,11 @@ public void zeroOrOneViewParameters(ExecutableElement executableElement, IsValid
378379
zeroOrOneSpecificParameter(executableElement, ANDROID_VIEW_QUALIFIED_NAME, valid);
379380
}
380381

382+
public void zeroOrOneMenuItemParameters(ExecutableElement executableElement, IsValid valid) {
383+
zeroOrOneSpecificParameter(executableElement, ANDROID_MENU_ITEM_QUALIFIED_NAME, valid);
384+
}
385+
386+
381387
public void zeroOrOneSpecificParameter(ExecutableElement executableElement, String parameterTypeQualifiedName, IsValid valid) {
382388

383389
zeroOrOneParameter(executableElement, valid);

AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/ClickProcessor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
/**
3939
* @author Mathieu Boniface
40+
* @author Pierre-Yves
4041
*/
4142
public class ClickProcessor extends MultipleResIdsBasedProcessor implements ElementProcessor {
4243

AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/EBeanHolder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.sun.codemodel.JDefinedClass;
2424
import com.sun.codemodel.JFieldVar;
2525
import com.sun.codemodel.JMethod;
26+
import com.sun.codemodel.JSwitch;
2627
import com.sun.codemodel.JVar;
2728

2829
public class EBeanHolder {
@@ -40,6 +41,9 @@ public class EBeanHolder {
4041

4142
private Map<String, JClass> loadedClasses = new HashMap<String, JClass>();
4243
public JFieldVar handler;
44+
45+
public JSwitch onOptionsItemSelectedSwitch;
46+
public JVar onOptionsItemSelectedItem;
4347

4448
public JClass refClass(String fullyQualifiedClassName) {
4549

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/**
2+
* Copyright (C) 2010-2011 eBusiness Information, Excilys Group
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed To in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package com.googlecode.androidannotations.processing;
17+
18+
import static com.sun.codemodel.JExpr.FALSE;
19+
import static com.sun.codemodel.JExpr.TRUE;
20+
import static com.sun.codemodel.JExpr._super;
21+
import static com.sun.codemodel.JExpr.invoke;
22+
23+
import java.lang.annotation.Annotation;
24+
import java.util.List;
25+
26+
import javax.lang.model.element.Element;
27+
import javax.lang.model.element.ExecutableElement;
28+
import javax.lang.model.element.VariableElement;
29+
import javax.lang.model.type.TypeKind;
30+
import javax.lang.model.type.TypeMirror;
31+
32+
import com.googlecode.androidannotations.annotations.OptionsItem;
33+
import com.googlecode.androidannotations.rclass.IRClass;
34+
import com.sun.codemodel.JBlock;
35+
import com.sun.codemodel.JCase;
36+
import com.sun.codemodel.JCodeModel;
37+
import com.sun.codemodel.JExpr;
38+
import com.sun.codemodel.JFieldRef;
39+
import com.sun.codemodel.JInvocation;
40+
import com.sun.codemodel.JMethod;
41+
import com.sun.codemodel.JMod;
42+
import com.sun.codemodel.JVar;
43+
44+
/**
45+
* @author Pierre-Yves Ricau
46+
*/
47+
public class OptionsItemProcessor extends MultipleResIdsBasedProcessor implements ElementProcessor {
48+
49+
public OptionsItemProcessor(IRClass rClass) {
50+
super(rClass);
51+
}
52+
53+
@Override
54+
public Class<? extends Annotation> getTarget() {
55+
return OptionsItem.class;
56+
}
57+
58+
@Override
59+
public void process(Element element, JCodeModel codeModel, EBeansHolder activitiesHolder) {
60+
EBeanHolder holder = activitiesHolder.getEnclosingActivityHolder(element);
61+
62+
String methodName = element.getSimpleName().toString();
63+
64+
ExecutableElement executableElement = (ExecutableElement) element;
65+
List<? extends VariableElement> parameters = executableElement.getParameters();
66+
TypeMirror returnType = executableElement.getReturnType();
67+
boolean returnMethodResult = returnType.getKind() != TypeKind.VOID;
68+
69+
boolean hasItemParameter = parameters.size() == 1;
70+
71+
OptionsItem annotation = element.getAnnotation(OptionsItem.class);
72+
List<JFieldRef> idsRefs = extractQualifiedIds(element, annotation.value(), "Selected", holder);
73+
74+
if (holder.onOptionsItemSelectedSwitch == null) {
75+
JMethod method = holder.eBean.method(JMod.PUBLIC, codeModel.BOOLEAN, "onOptionsItemSelected");
76+
method.annotate(Override.class);
77+
holder.onOptionsItemSelectedItem = method.param(holder.refClass("android.view.MenuItem"), "item");
78+
79+
JBlock body = method.body();
80+
JVar handled = body.decl(codeModel.BOOLEAN, "handled", invoke(_super(), method).arg(holder.onOptionsItemSelectedItem));
81+
82+
body._if(handled)._then()._return(TRUE);
83+
84+
holder.onOptionsItemSelectedSwitch = body._switch(holder.onOptionsItemSelectedItem.invoke("getItemId"));
85+
86+
JBlock defaultBody = holder.onOptionsItemSelectedSwitch._default().body();
87+
defaultBody._return(FALSE);
88+
}
89+
90+
JCase itemCase = null;
91+
for (JFieldRef idRef : idsRefs) {
92+
itemCase = holder.onOptionsItemSelectedSwitch._case(idRef);
93+
}
94+
95+
JBlock itemCaseBody = itemCase.body();
96+
JInvocation methodCall = invoke(methodName);
97+
98+
if (returnMethodResult) {
99+
itemCaseBody._return(methodCall);
100+
} else {
101+
itemCaseBody.add(methodCall);
102+
itemCaseBody._return(TRUE);
103+
}
104+
105+
if (hasItemParameter) {
106+
methodCall.arg(holder.onOptionsItemSelectedItem);
107+
}
108+
109+
110+
}
111+
112+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* Copyright (C) 2010-2011 eBusiness Information, Excilys Group
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed To in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package com.googlecode.androidannotations.validation;
17+
18+
import java.lang.annotation.Annotation;
19+
20+
import javax.annotation.processing.ProcessingEnvironment;
21+
import javax.lang.model.element.Element;
22+
import javax.lang.model.element.ExecutableElement;
23+
24+
import com.googlecode.androidannotations.annotations.OptionsItem;
25+
import com.googlecode.androidannotations.helper.IdAnnotationHelper;
26+
import com.googlecode.androidannotations.helper.IdValidatorHelper;
27+
import com.googlecode.androidannotations.model.AnnotationElements;
28+
import com.googlecode.androidannotations.rclass.IRClass;
29+
30+
/**
31+
* @author Pierre-Yves Ricau
32+
*/
33+
public class OptionsItemValidator implements ElementValidator {
34+
35+
private IdValidatorHelper validatorHelper;
36+
37+
public OptionsItemValidator(ProcessingEnvironment processingEnv, IRClass rClass) {
38+
IdAnnotationHelper annotationHelper = new IdAnnotationHelper(processingEnv, getTarget(), rClass) {
39+
public String actionName() {
40+
return "Selected";
41+
};
42+
};
43+
validatorHelper = new IdValidatorHelper(annotationHelper);
44+
}
45+
46+
@Override
47+
public Class<? extends Annotation> getTarget() {
48+
return OptionsItem.class;
49+
}
50+
51+
@Override
52+
public boolean validate(Element element, AnnotationElements validatedElements) {
53+
54+
IsValid valid = new IsValid();
55+
56+
validatorHelper.idListenerMethod(element, validatedElements, valid);
57+
58+
ExecutableElement executableElement = (ExecutableElement) element;
59+
60+
validatorHelper.voidOrBooleanReturnType(executableElement, valid);
61+
62+
validatorHelper.zeroOrOneMenuItemParameters(executableElement, valid);
63+
64+
return valid.isValid();
65+
}
66+
}

AndroidAnnotations/functional-test-1-5/res/menu/main.xml renamed to AndroidAnnotations/functional-test-1-5/res/menu/my_menu.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,9 @@
2828
<item android:id="@+id/menu_share"
2929
android:title="Share"
3030
/>
31+
32+
<item android:id="@+id/menu_add"
33+
android:title="Add"
34+
/>
35+
3136
</menu>

AndroidAnnotations/functional-test-1-5/src/main/java/com/googlecode/androidannotations/test15/ClicksHandledActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void conventionButton() {
4242
public void snakeCaseButton() {
4343
snakeCaseButtonClicked = true;
4444
}
45-
45+
4646
@Click
4747
public void extendedConventionButtonClicked() {
4848
extendedConventionButtonClicked = true;

AndroidAnnotations/functional-test-1-5/src/main/java/com/googlecode/androidannotations/test15/menu/OptionsMenuActivity.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,35 @@
1616
package com.googlecode.androidannotations.test15.menu;
1717

1818
import android.app.Activity;
19+
import android.view.MenuItem;
1920

2021
import com.googlecode.androidannotations.annotations.EActivity;
22+
import com.googlecode.androidannotations.annotations.OptionsItem;
2123
import com.googlecode.androidannotations.annotations.OptionsMenu;
2224
import com.googlecode.androidannotations.test15.R;
2325

2426
@EActivity
25-
@OptionsMenu(R.menu.main)
27+
@OptionsMenu(R.menu.my_menu)
2628
public class OptionsMenuActivity extends Activity {
2729

30+
boolean menuRefreshSelected;
31+
boolean multipleMenuItems;
32+
boolean menu_add;
33+
34+
@OptionsItem
35+
void menuRefreshSelected() {
36+
menuRefreshSelected = true;
37+
}
38+
39+
@OptionsItem({ R.id.menu_search, R.id.menu_share })
40+
boolean multipleMenuItems() {
41+
multipleMenuItems = true;
42+
return false;
43+
}
44+
45+
@OptionsItem
46+
void menu_add(MenuItem item) {
47+
menu_add = true;
48+
}
2849

2950
}

0 commit comments

Comments
 (0)