├── .idea
├── .name
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── libraries
│ └── libs.xml
├── misc.xml
├── modules.xml
├── uiDesigner.xml
├── vcs.xml
└── workspace.xml
├── AndroidSuperPlugin.iml
├── GsonFormat
├── ConvertBridge.java
├── EditDialog.form
├── EditDialog.java
├── ErrorDialog.form
├── ErrorDialog.java
├── FieldsDialog.form
├── FieldsDialog.java
├── JsonUtilsDialog.form
├── JsonUtilsDialog.java
├── MainAction.java
├── SettingDialog.form
├── SettingDialog.java
├── WriterUtil.java
├── config
│ ├── Config.java
│ └── Strings.java
├── entity
│ ├── FieldEntity.java
│ └── InnerClassEntity.java
├── org
│ └── json
│ │ ├── JSONArray.java
│ │ ├── JSONException.java
│ │ ├── JSONObject.java
│ │ ├── JSONString.java
│ │ └── JSONTokener.java
├── res
│ └── icon.png
├── src
│ ├── cn
│ │ └── vearn
│ │ │ └── checktreetable
│ │ │ └── FiledTreeTableModel.java
│ └── org
│ │ └── jdesktop
│ │ └── swingx
│ │ └── ux
│ │ ├── CheckTreeCellProvider.java
│ │ ├── CheckTreeSelectionModel.java
│ │ ├── CheckTreeTableManager.java
│ │ └── TristateCheckBox.java
└── utils
│ ├── CheckUtil.java
│ ├── PsiClassUtil.java
│ └── Toast.java
├── README.md
├── android_code_generator
└── com
│ └── morcinek
│ └── android
│ └── codegenerator
│ └── plugin
│ ├── actions
│ ├── ActivityAction.java
│ ├── AdapterAction.java
│ ├── FragmentAction.java
│ ├── LayoutAction.java
│ ├── MenuAction.java
│ ├── butterknife
│ │ ├── BActivityAction.java
│ │ ├── BAdapterAction.java
│ │ └── BFragmentAction.java
│ └── visibility
│ │ └── ActionVisibilityHelper.java
│ ├── codegenerator
│ ├── CodeGeneratorController.java
│ └── CodeGeneratorFactory.java
│ ├── error
│ └── ErrorHandler.java
│ ├── groups
│ └── GenerateAndroidCodeGroup.java
│ ├── persistence
│ └── Settings.java
│ ├── preferences
│ ├── configurables
│ │ ├── MainConfigurable.java
│ │ └── templates
│ │ │ └── TemplateConfigurable.java
│ └── persistence
│ │ └── TemplateSettings.java
│ ├── ui
│ ├── CodeDialogBuilder.java
│ ├── DialogsFactory.java
│ └── StringResources.java
│ └── utils
│ ├── ClipboardHelper.java
│ ├── PackageHelper.java
│ ├── PathHelper.java
│ └── ProjectHelper.java
├── android_parcelable_intellij_plugin
└── pl
│ └── charmas
│ └── parcelablegenerator
│ ├── CodeGenerator.java
│ ├── GenerateDialog.java
│ ├── ParcelableAction.java
│ ├── typeserializers
│ ├── BundleSerializerFactory.java
│ ├── ChainSerializerFactory.java
│ ├── DateSerializerFactory.java
│ ├── EnumerationSerializerFactory.java
│ ├── ListSerializerFactory.java
│ ├── ParcelableSerializerFactory.java
│ ├── PrimitiveArraySerializerFactory.java
│ ├── PrimitiveTypeSerializerFactory.java
│ ├── SerializableSerializerFactory.java
│ ├── TypeSerializer.java
│ ├── TypeSerializerFactory.java
│ └── serializers
│ │ ├── BooleanPrimitiveSerializer.java
│ │ ├── BooleanSparseArraySerializer.java
│ │ ├── BundleSerializer.java
│ │ ├── CharPrimitiveSerializer.java
│ │ ├── DateSerializer.java
│ │ ├── EnumerationSerializer.java
│ │ ├── GenericListSerializer.java
│ │ ├── NullablePrimitivesSerializer.java
│ │ ├── ParcelableArraySerializer.java
│ │ ├── ParcelableListSerializer.java
│ │ ├── ParcelableObjectSerializer.java
│ │ ├── PrimitiveArraySerializer.java
│ │ ├── PrimitiveTypeSerializer.java
│ │ ├── SerializableObjectSerializer.java
│ │ └── UnknownTypeSerializer.java
│ └── util
│ └── PsiUtils.java
├── android_selector_chapek
├── Constants.java
├── SelectorChapekAction.java
├── SelectorDetector.java
├── SelectorGenerator.java
└── utils
│ ├── Log.java
│ └── RunnableHelper.java
├── folding_plugin
└── com
│ └── dd
│ ├── ComposeAction.java
│ ├── DirectoryNode.java
│ ├── FoldingNode.java
│ ├── ProjectStructureProvider.java
│ ├── SettingConfigurable.form
│ ├── SettingConfigurable.java
│ ├── Settings.java
│ ├── SettingsManager.java
│ └── Utils.java
├── libs
├── android-codegenerator-library-1.0.5.jar
├── commons-io-2.4-sources.jar
├── commons-io-2.4.jar
├── commons-lang3-3.3.2.jar
├── commons-math3-3.4.1-src.zip
├── commons-math3-3.4.1.jar
├── gson-2.3.1.jar
├── guava-18.0.jar
├── imgscalr-lib-4.2-sources.jar
├── imgscalr-lib-4.2.jar
├── thumbnailator-0.4.8-sources.jar
├── thumbnailator-0.4.8.jar
└── xom-1.2.10.jar
├── lifecycle_sorter
├── Action
│ ├── SortAction.java
│ ├── SortEndAction.java
│ └── SortStartAction.java
├── Lifecycle
│ ├── ActivityLifecycle.java
│ ├── FragmentLifecycle.java
│ ├── Lifecycle.java
│ └── LifecycleFactory.java
├── Sort
│ └── Sorter.java
└── Util
│ └── LifecycleUtils.java
├── resources
└── META-INF
│ └── plugin.xml
└── src
└── de
└── espend
└── idea
└── android
├── AndroidView.java
├── RelatedPopupGotoLineMarker.java
├── action
├── ExtractStringAction.java
├── generator
│ ├── AbstractActivityViewAction.java
│ ├── AbstractInflateViewAction.java
│ ├── ActivityViewFieldVariable.java
│ ├── ActivityViewMethodVariable.java
│ ├── FieldViewInflateViewAction.java
│ └── LocalViewAction.java
└── write
│ ├── InflateLocalVariableAction.java
│ ├── InflateThisExpressionAction.java
│ └── ReformatAndOptimizeImportsProcessor.java
├── annotator
├── InflateCastAnnotator.java
└── InflateViewAnnotator.java
├── linemarker
├── FragmentRelatedFileLineMarker.java
├── InflateLayoutLineMarkerProvider.java
└── ViewInflateLineMarker.java
├── symbol
└── AndroidSymbolContributor.java
└── utils
├── AndroidUtils.java
├── AndroidViewUtil.java
└── JavaPsiUtil.java
/.idea/.name:
--------------------------------------------------------------------------------
1 | AndroidSuperPlugin
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/libraries/libs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/AndroidSuperPlugin.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/GsonFormat/EditDialog.java:
--------------------------------------------------------------------------------
1 | import config.Config;
2 | import config.Strings;
3 |
4 | import javax.swing.*;
5 | import java.awt.event.*;
6 |
7 | public class EditDialog extends JFrame {
8 | private JPanel contentPane;
9 | private JButton okButton;
10 | private JButton cancelButton;
11 | private JTextPane editTP;
12 | private JButton resetButton;
13 | private JLabel titleLB;
14 |
15 | private String titleName;
16 |
17 | private String editStr;
18 |
19 | private Type type;
20 |
21 |
22 | public EditDialog(Type type ) {
23 | this.type=type;
24 | setContentPane(contentPane);
25 | // setModal(true);
26 | this.setAlwaysOnTop(true);
27 | getRootPane().setDefaultButton(okButton);
28 |
29 | okButton.addActionListener(new ActionListener() {
30 | public void actionPerformed(ActionEvent e) {
31 | onOK();
32 | }
33 | });
34 |
35 | cancelButton.addActionListener(new ActionListener() {
36 | public void actionPerformed(ActionEvent e) {
37 | onCancel();
38 | }
39 | });
40 | setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
41 |
42 | addWindowListener(new WindowAdapter() {
43 | public void windowClosing(WindowEvent e) {
44 | onCancel();
45 | }
46 | });
47 |
48 | contentPane.registerKeyboardAction(new ActionListener() {
49 | public void actionPerformed(ActionEvent e) {
50 | onCancel();
51 | }
52 | }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
53 |
54 |
55 | setTitle("Convert method");
56 | switch (type){
57 | case OBJECT_FROM_DATA:
58 | titleName="objectFromData(Object data)";
59 | editStr=Config.getInstant().getObjectFromDataStr();
60 | break;
61 | case OBJECT_FROM_DATA1:
62 | titleName="objectFromData(Object data,String key)";
63 | editStr=Config.getInstant().getObjectFromDataStr1();
64 | break;
65 | case ARRAY_FROM_DATA:
66 | titleName="arrayFromData(Object data)";
67 | editStr=Config.getInstant().getArrayFromDataStr();
68 | break;
69 | case ARRAY_FROM_DATA1:
70 | titleName="arrayFromData(Object data,String key)";
71 | editStr=Config.getInstant().getArrayFromData1Str();
72 | break;
73 | }
74 | titleLB.setText(titleName);
75 |
76 | editTP.setText(editStr);
77 | resetButton.addActionListener(new ActionListener() {
78 | @Override
79 | public void actionPerformed(ActionEvent actionEvent) {
80 |
81 | resetAction();
82 |
83 | }
84 | });
85 |
86 |
87 | }
88 |
89 | private void resetAction() {
90 |
91 | switch (type){
92 | case OBJECT_FROM_DATA:
93 | editTP.setText(Strings.objectFromObject);
94 | break;
95 | case OBJECT_FROM_DATA1:
96 |
97 | System.out.println(Strings.objectFromObject1);
98 | editTP.setText(Strings.objectFromObject1);
99 | break;
100 | case ARRAY_FROM_DATA:
101 | editTP.setText(Strings.arrayFromData);
102 | break;
103 | case ARRAY_FROM_DATA1:
104 | editTP.setText(Strings.arrayFromData1);
105 | break;
106 | }
107 | }
108 |
109 | private void onOK() {
110 | switch (type){
111 | case OBJECT_FROM_DATA:
112 | Config.getInstant().saveObjectFromDataStr(editTP.getText());
113 | break;
114 | case OBJECT_FROM_DATA1:
115 | Config.getInstant().saveObjectFromDataStr1(editTP.getText());
116 | break;
117 | case ARRAY_FROM_DATA:
118 | Config.getInstant().saveArrayFromDataStr(editTP.getText());
119 | break;
120 | case ARRAY_FROM_DATA1:
121 | Config.getInstant().saveArrayFromData1Str(editTP.getText());
122 | break;
123 | }
124 | dispose();
125 | }
126 |
127 | private void onCancel() {
128 | dispose();
129 | }
130 |
131 |
132 |
133 |
134 | public enum Type{
135 | OBJECT_FROM_DATA,OBJECT_FROM_DATA1,ARRAY_FROM_DATA,ARRAY_FROM_DATA1;
136 |
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/GsonFormat/ErrorDialog.form:
--------------------------------------------------------------------------------
1 |
2 |
70 |
--------------------------------------------------------------------------------
/GsonFormat/ErrorDialog.java:
--------------------------------------------------------------------------------
1 | import javax.swing.*;
2 | import java.awt.event.ActionEvent;
3 | import java.awt.event.ActionListener;
4 |
5 | public class ErrorDialog extends JFrame {
6 | private JPanel contentPane;
7 | private JTextPane editTP;
8 | private JButton okButton;
9 | private JScrollPane scrollPane;
10 |
11 | public ErrorDialog(String errorInfo) {
12 | setContentPane(contentPane);
13 | setTitle("error info");
14 | getRootPane().setDefaultButton(okButton);
15 | this.setAlwaysOnTop(true);
16 | editTP.setText(errorInfo);
17 |
18 |
19 | okButton.addActionListener(new ActionListener() {
20 | public void actionPerformed(ActionEvent e) {
21 | dispose();
22 | }
23 | });
24 | editTP.setCaretPosition(0);
25 |
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/GsonFormat/MainAction.java:
--------------------------------------------------------------------------------
1 | import com.intellij.codeInsight.CodeInsightActionHandler;
2 | import com.intellij.codeInsight.generation.actions.BaseGenerateAction;
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import com.intellij.openapi.actionSystem.PlatformDataKeys;
5 | import com.intellij.openapi.editor.Editor;
6 | import com.intellij.openapi.project.Project;
7 | import com.intellij.psi.*;
8 | import com.intellij.psi.util.PsiUtilBase;
9 |
10 | /**
11 | * Created with IntelliJ IDEA.
12 | * User: zzz40500
13 | * Date: 14-7-4
14 | * Time: 下午1:44
15 | *
16 | */
17 | public class MainAction extends BaseGenerateAction {
18 | protected PsiClass mClass;
19 | private PsiElementFactory mFactory;
20 | private Project project;
21 |
22 | @SuppressWarnings("unused")
23 | public MainAction() {
24 | super(null);
25 | }
26 |
27 | @SuppressWarnings("unused")
28 | public MainAction(CodeInsightActionHandler handler) {
29 | super(handler);
30 | }
31 |
32 | @Override
33 | protected boolean isValidForClass(final PsiClass targetClass) {
34 | return super.isValidForClass(targetClass) ;
35 | }
36 |
37 | @Override
38 | public boolean isValidForFile(Project project, Editor editor, PsiFile file) {
39 |
40 | return super.isValidForFile(project, editor, file);
41 | }
42 |
43 |
44 | public void actionPerformed(AnActionEvent event) {
45 |
46 | project = event.getData(PlatformDataKeys.PROJECT);
47 | Editor editor = event.getData(PlatformDataKeys.EDITOR);
48 | PsiFile mFile = PsiUtilBase.getPsiFileInEditor(editor, project);
49 | mClass=getTargetClass(editor,mFile);
50 | JsonUtilsDialog jsonD=new JsonUtilsDialog(mClass,mFactory,mFile,project);
51 | jsonD.setmClass(mClass);
52 | jsonD.setmFactory(mFactory);
53 | jsonD.setmFile(mFile);
54 | jsonD.setmProject(project);
55 | jsonD.setSize(600, 400);
56 | jsonD.setLocationRelativeTo(null);
57 | jsonD.setVisible(true);
58 |
59 | }
60 |
61 |
62 |
63 |
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/GsonFormat/WriterUtil.java:
--------------------------------------------------------------------------------
1 | import com.intellij.openapi.command.WriteCommandAction;
2 | import com.intellij.openapi.project.Project;
3 | import com.intellij.psi.*;
4 | import com.intellij.psi.codeStyle.JavaCodeStyleManager;
5 | import entity.InnerClassEntity;
6 |
7 | import javax.swing.*;
8 |
9 | /**
10 | * Created with IntelliJ IDEA.
11 | * User: zzz40500
12 | * Date: 14-7-4
13 | * Time: 下午3:58
14 | * To change this template use File | Settings | File Templates.
15 | */
16 | public class WriterUtil extends WriteCommandAction.Simple {
17 |
18 | protected PsiClass mClass;
19 | private PsiElementFactory mFactory;
20 | private Project project;
21 | private PsiFile mFile;
22 |
23 | public InnerClassEntity mInnerClassEntity;
24 |
25 | public WriterUtil(JsonUtilsDialog mJsonUtilsDialog, JLabel jLabel,
26 | PsiFile mFile, Project project, PsiClass mClass, PsiFile... files) {
27 | super(project, files);
28 | mFactory = JavaPsiFacade.getElementFactory(project);
29 | this.mFile = mFile;
30 | this.project = project;
31 | this.mClass = mClass;
32 |
33 | }
34 |
35 | @Override
36 | protected void run() {
37 |
38 | mInnerClassEntity.generateFiled(mFactory, mClass);
39 | JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project);
40 | styleManager.optimizeImports(mFile);
41 | styleManager.shortenClassReferences(mClass);
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/GsonFormat/config/Strings.java:
--------------------------------------------------------------------------------
1 | package config;
2 |
3 | /**
4 | * Created by zzz40500 on 15/5/31.
5 | */
6 | public class Strings {
7 |
8 |
9 | public static final String privateStr=" private String name;\n" +
10 | "\n" +
11 | " public void setName(String name){\n" +
12 | " this.name=name;\n" +
13 | " }\n" +
14 | "\n" +
15 | " public String getName(){\n" +
16 | " return name;\n" +
17 | " }";
18 | public static final String publicStr=" public String name;";
19 | public static final String privateUseSerializedNameStr=" @SerializedName(\"name\")\n" +
20 | " private String name;\n" +
21 | "\n" +
22 | " public void setName(String name){\n" +
23 | " this.name=name;\n" +
24 | " }\n" +
25 | "\n" +
26 | " public String getName(){\n" +
27 | " return name;\n" +
28 | " }";
29 | public static final String publicUseSerializedNameStr=" @SerializedName(\"name\")\n" +
30 | " public String name;";
31 |
32 |
33 |
34 | public static final String objectFromObject=" public static $ClassName$ objectFromData(String str){\n" +
35 | "\n" +
36 | " return new com.google.gson.Gson().fromJson(str,$ClassName$.class);\n" +
37 | " }";
38 | public static final String objectFromObject1=" public static $ClassName$ objectFromData(String str, String key){\n" +
39 | "\n" +
40 | " try {\n" +
41 | " org.json.JSONObject jsonObject=new org.json.JSONObject(str);\n" +
42 | "\n" +
43 | " return new com.google.gson.Gson().fromJson(jsonObject.getString(str),$ClassName$.class);\n" +
44 | " } catch (org.json.JSONException e) {\n" +
45 | " e.printStackTrace();\n" +
46 | " }\n" +
47 | "\n" +
48 | " return null;\n" +
49 | " }";
50 | public static final String arrayFromData=" public static java.util.List<$ClassName$> array$ClassName$FromData(String str){\n" +
51 | "\n" +
52 | " java.lang.reflect.Type listType=new com.google.gson.reflect.TypeToken>(){}.getType();\n" +
53 | "\n" +
54 | " return new com.google.gson.Gson().fromJson(str,listType);\n" +
55 | " }";
56 | public static final String arrayFromData1=" public static java.util.List<$ClassName$> array$ClassName$FromData(String str,String key){\n" +
57 | "\n" +
58 | " try {\n" +
59 | " org.json.JSONObject jsonObject=new org.json.JSONObject(str);\n" +
60 | " java.lang.reflect.Type listType=new com.google.gson.reflect.TypeToken>(){}.getType();\n" +
61 | "\n" +
62 | " return new com.google.gson.Gson().fromJson(jsonObject.getString(str),listType);\n" +
63 | "\n" +
64 | " } catch (org.json.JSONException e) {\n" +
65 | " e.printStackTrace();\n" +
66 | " }\n" +
67 | "\n" +
68 | " return new java.util.ArrayList();\n" +
69 | "\n" +
70 | "\n" +
71 | " }";
72 |
73 | public static final String gsonAnnotation="@com.google.gson.annotations.SerializedName\\s*\\(\\s*\"{filed}\"\\s*\\)";
74 | public static final String gsonFullNameAnnotation="@com.google.gson.annotations.SerializedName(\"{filed}\")";
75 | public static final String fastFullNameAnnotation="@com.alibaba.fastjson.annotation.JSONField(name=\"{filed}\")";
76 | public static final String fastAnnotation="@com.alibaba.fastjson.annotation.JSONField\\s*\\(\\s*name\\s*=\\s*\"{filed}\"\\s*\\)";
77 | public static final String jackAnnotation="@com.fasterxml.jackson.annotation.JsonProperty\\s*\\(\\s*\"{filed}\"\\s*\\)";
78 | public static final String jackFullNameAnnotation="@com.fasterxml.jackson.annotation.JsonProperty(\"{filed}\")";
79 | }
80 |
--------------------------------------------------------------------------------
/GsonFormat/org/json/JSONException.java:
--------------------------------------------------------------------------------
1 | package org.json;
2 |
3 | /**
4 | * The JSONException is thrown by the JSON.org classes when things are amiss.
5 | *
6 | * @author JSON.org
7 | * @version 2014-05-03
8 | */
9 | public class JSONException extends RuntimeException {
10 | private static final long serialVersionUID = 0;
11 | private Throwable cause;
12 |
13 | /**
14 | * Constructs a JSONException with an explanatory message.
15 | *
16 | * @param message
17 | * Detail about the reason for the exception.
18 | */
19 | public JSONException(String message) {
20 | super(message);
21 | }
22 |
23 | /**
24 | * Constructs a new JSONException with the specified cause.
25 | * @param cause The cause.
26 | */
27 | public JSONException(Throwable cause) {
28 | super(cause.getMessage());
29 | this.cause = cause;
30 | }
31 |
32 | /**
33 | * Returns the cause of this exception or null if the cause is nonexistent
34 | * or unknown.
35 | *
36 | * @return the cause of this exception or null if the cause is nonexistent
37 | * or unknown.
38 | */
39 | @Override
40 | public Throwable getCause() {
41 | return this.cause;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/GsonFormat/org/json/JSONString.java:
--------------------------------------------------------------------------------
1 | package org.json;
2 | /**
3 | * The JSONString
interface allows a toJSONString()
4 | * method so that a class can change the behavior of
5 | * JSONObject.toString()
, JSONArray.toString()
,
6 | * and JSONWriter.value(
Object)
. The
7 | * toJSONString
method will be used instead of the default behavior
8 | * of using the Object's toString()
method and quoting the result.
9 | */
10 | public interface JSONString {
11 | /**
12 | * The toJSONString
method allows a class to produce its own JSON
13 | * serialization.
14 | *
15 | * @return A strictly syntactically correct JSON text.
16 | */
17 | public String toJSONString();
18 | }
19 |
--------------------------------------------------------------------------------
/GsonFormat/res/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/GsonFormat/res/icon.png
--------------------------------------------------------------------------------
/GsonFormat/src/cn/vearn/checktreetable/FiledTreeTableModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 | package src.cn.vearn.checktreetable;
6 |
7 | import entity.FieldEntity;
8 | import org.jdesktop.swingx.treetable.DefaultMutableTreeTableNode;
9 | import org.jdesktop.swingx.treetable.DefaultTreeTableModel;
10 | import org.jdesktop.swingx.treetable.TreeTableNode;
11 |
12 | /**
13 | *
14 | * @author vearn
15 | */
16 | public class FiledTreeTableModel extends DefaultTreeTableModel {
17 |
18 | private String[] _names = {" Key ", "Value", "Data Types"," FiledName "};
19 | private Class[] _types = {Object.class,Object.class, Object.class, Object.class};
20 |
21 |
22 | public FiledTreeTableModel(TreeTableNode node) {
23 | super(node);
24 | }
25 |
26 | /**
27 | * 列的类型
28 | */
29 | @Override
30 | public Class getColumnClass(int col) {
31 | return _types[col];
32 | }
33 |
34 | /**
35 | * 列的数量
36 | */
37 | @Override
38 | public int getColumnCount() {
39 | return _names.length;
40 | }
41 |
42 | /**
43 | * 表头显示的内容
44 | */
45 | @Override
46 | public String getColumnName(int column) {
47 | return _names[column];
48 | }
49 |
50 | /**
51 | * 返回在单元格中显示的Object
52 | */
53 | @Override
54 | public Object getValueAt(Object node, int column) {
55 | Object value = null;
56 | if (node instanceof DefaultMutableTreeTableNode) {
57 | DefaultMutableTreeTableNode mutableNode = (DefaultMutableTreeTableNode) node;
58 | Object o = mutableNode.getUserObject();
59 | if (o != null && o instanceof FieldEntity) {
60 | FieldEntity bean = (FieldEntity) o;
61 | switch (column) {
62 | case 0:
63 | value = bean.getKey();
64 | break;
65 | case 1:
66 | value = bean.getValue();
67 | break;
68 | case 2:
69 | value = bean.getRealType();
70 | break;
71 | case 3:
72 | value = bean.getFieldName();
73 | break;
74 | }
75 | }
76 | }
77 | return value;
78 | }
79 |
80 | @Override
81 | public void setValueAt(Object value, Object node, int column) {
82 | super.setValueAt(value, node, column);
83 |
84 | if (node instanceof DefaultMutableTreeTableNode) {
85 | DefaultMutableTreeTableNode mutableNode = (DefaultMutableTreeTableNode) node;
86 | Object o = mutableNode.getUserObject();
87 | if (o != null && o instanceof FieldEntity) {
88 | FieldEntity bean = (FieldEntity) o;
89 | switch (column) {
90 | case 2:
91 | bean.checkAndSetType(value.toString());
92 | break;
93 | case 3:
94 | bean.setFieldName(value.toString());
95 | break;
96 | }
97 | }
98 | }
99 | }
100 |
101 |
102 | @Override
103 | public boolean isCellEditable(Object node, int column) {
104 |
105 |
106 |
107 | if(column == 2){
108 | return true;
109 | }
110 |
111 | if(column == 3){
112 | return true;
113 | }
114 | return false;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/GsonFormat/src/org/jdesktop/swingx/ux/CheckTreeCellProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 | package src.org.jdesktop.swingx.ux;
6 |
7 | import java.awt.BorderLayout;
8 | import javax.swing.JLabel;
9 | import javax.swing.JPanel;
10 | import javax.swing.JTree;
11 | import javax.swing.tree.TreePath;
12 |
13 | import entity.FieldEntity;
14 | import org.jdesktop.swingx.renderer.CellContext;
15 | import org.jdesktop.swingx.renderer.ComponentProvider;
16 | import org.jdesktop.swingx.treetable.DefaultMutableTreeTableNode;
17 |
18 | /**
19 | *
20 | * @author vearn
21 | */
22 | public class CheckTreeCellProvider extends ComponentProvider {
23 |
24 | private CheckTreeSelectionModel selectionModel;
25 | private TristateCheckBox _checkBox = null;
26 | private JLabel _label = null;
27 |
28 | public CheckTreeCellProvider(CheckTreeSelectionModel selectionModel) {
29 | this.selectionModel = selectionModel;
30 | _checkBox = new TristateCheckBox(); // 创建一个TristateCheckBox实例
31 | _checkBox.setOpaque(false); // 设置TristateCheckBox不绘制背景
32 | _label = new JLabel(); // 创建一个JLabel实例
33 | }
34 |
35 | @Override
36 | protected void format(CellContext arg0) {
37 | // 从CellContext获取tree中的文字和图标
38 | JTree tree = (JTree) arg0.getComponent();
39 | DefaultMutableTreeTableNode node = (DefaultMutableTreeTableNode) arg0.getValue();
40 | Object obj = node.getUserObject();
41 | if(obj instanceof FieldEntity){
42 | _label.setText(((FieldEntity) obj).getKey());
43 | _checkBox.setFieldEntity((FieldEntity) obj);
44 | }
45 |
46 | // _label.setIcon(arg0.getIcon());
47 |
48 | // 根据selectionModel中的状态来绘制TristateCheckBox的外观
49 | TreePath path = tree.getPathForRow(arg0.getRow());
50 | if (path != null) {
51 | if (selectionModel.isPathSelected(path, true)) {
52 | _checkBox.setState(Boolean.TRUE);
53 | } else if (selectionModel.isPartiallySelected(path)) {
54 | _checkBox.setState(null); // 注意“部分选中”状态的API
55 | } else {
56 | _checkBox.setState(Boolean.FALSE);
57 | }
58 | }
59 |
60 | // 使用BorderLayout布局,依次放置TristateCheckBox和JLabel
61 | rendererComponent.setLayout(new BorderLayout());
62 | rendererComponent.add(_checkBox);
63 | rendererComponent.add(_label, BorderLayout.LINE_END);
64 | }
65 |
66 | @Override
67 | protected void configureState(CellContext arg0) {
68 | }
69 |
70 | /**
71 | * 初始化一个JPanel来放置TristateCheckBox和JLabel
72 | */
73 | @Override
74 | protected JPanel createRendererComponent() {
75 | JPanel panel = new JPanel();
76 | return panel;
77 | }
78 | }
--------------------------------------------------------------------------------
/GsonFormat/src/org/jdesktop/swingx/ux/CheckTreeTableManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 | package src.org.jdesktop.swingx.ux;
6 |
7 | import java.awt.event.MouseAdapter;
8 | import java.awt.event.MouseEvent;
9 | import javax.swing.JCheckBox;
10 | import javax.swing.JTree;
11 | import javax.swing.event.TreeSelectionEvent;
12 | import javax.swing.event.TreeSelectionListener;
13 | import javax.swing.tree.TreePath;
14 | import org.jdesktop.swingx.JXTreeTable;
15 | import org.jdesktop.swingx.renderer.DefaultTreeRenderer;
16 |
17 | /**
18 | *
19 | * @author Santhosh Kumr T - santhosh@in.fiorano.com
20 | */
21 | public class CheckTreeTableManager extends MouseAdapter implements TreeSelectionListener {
22 |
23 | private CheckTreeSelectionModel selectionModel;
24 | private JXTreeTable treetable;
25 | private JTree tree;
26 | int hotspot = new JCheckBox().getPreferredSize().width;
27 |
28 | public CheckTreeTableManager(JXTreeTable treeTable) {
29 | this.treetable = treeTable;
30 | this.tree = (JTree) treeTable.getCellRenderer(0, 0);
31 | selectionModel = new CheckTreeSelectionModel(tree.getModel());
32 | tree.setCellRenderer(new DefaultTreeRenderer(new CheckTreeCellProvider(selectionModel)));
33 | treeTable.addMouseListener(this);
34 |
35 | selectionModel.addTreeSelectionListener(this);
36 | }
37 |
38 | @Override
39 | public void mouseClicked(MouseEvent me) {
40 | TreePath path = tree.getPathForLocation(me.getX(), me.getY());
41 | if (path == null) {
42 | return;
43 | }
44 | if (me.getX() > tree.getPathBounds(path).x + hotspot) {
45 | return;
46 | }
47 |
48 | boolean selected = selectionModel.isPathSelected(path, true);
49 | selectionModel.removeTreeSelectionListener(this);
50 |
51 | try {
52 | if (selected) {
53 | selectionModel.removeSelectionPath(path);
54 | } else {
55 | selectionModel.addSelectionPath(path);
56 | }
57 | } finally {
58 | selectionModel.addTreeSelectionListener(this);
59 | treetable.repaint();
60 | }
61 | }
62 |
63 | public CheckTreeSelectionModel getSelectionModel() {
64 | return selectionModel;
65 | }
66 |
67 | public void valueChanged(TreeSelectionEvent e) {
68 | }
69 | }
--------------------------------------------------------------------------------
/GsonFormat/utils/CheckUtil.java:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by qingwei on 2015/8/21.
8 | */
9 | public class CheckUtil {
10 |
11 | private static CheckUtil mCheckUtil;
12 | private List mKeyWordList=new ArrayList();
13 |
14 | private CheckUtil(){
15 | mKeyWordList.add("abstract");
16 | mKeyWordList.add("assert");
17 | mKeyWordList.add("boolean");
18 | mKeyWordList.add("break");
19 | mKeyWordList.add("byte");
20 | mKeyWordList.add("case");
21 | mKeyWordList.add("catch");
22 | mKeyWordList.add("char");
23 | mKeyWordList.add("class");
24 | mKeyWordList.add("const");
25 | mKeyWordList.add("continue");
26 | mKeyWordList.add("default");
27 | mKeyWordList.add("do");
28 | mKeyWordList.add("double");
29 | mKeyWordList.add("else");
30 | mKeyWordList.add("enum");
31 | mKeyWordList.add("extends");
32 | mKeyWordList.add("final");
33 | mKeyWordList.add("finally");
34 | mKeyWordList.add("float");
35 | mKeyWordList.add("for");
36 | mKeyWordList.add("goto");
37 | mKeyWordList.add("if");
38 | mKeyWordList.add("implements");
39 | mKeyWordList.add("import");
40 | mKeyWordList.add("instanceof");
41 | mKeyWordList.add("int");
42 | mKeyWordList.add("interface");
43 | mKeyWordList.add("long");
44 | mKeyWordList.add("native");
45 | mKeyWordList.add("new");
46 | mKeyWordList.add("package");
47 | mKeyWordList.add("private");
48 | mKeyWordList.add("protected");
49 | mKeyWordList.add("public");
50 | mKeyWordList.add("return");
51 | mKeyWordList.add("strictfp");
52 | mKeyWordList.add("short");
53 | mKeyWordList.add("static");
54 | mKeyWordList.add("super");
55 | mKeyWordList.add("switch");
56 | mKeyWordList.add("synchronized");
57 | mKeyWordList.add("this");
58 | mKeyWordList.add("throw");
59 | mKeyWordList.add("throws");
60 | mKeyWordList.add("transient");
61 | mKeyWordList.add("abstract");
62 | mKeyWordList.add("void");
63 | mKeyWordList.add("volatile");
64 | mKeyWordList.add("while");
65 |
66 | }
67 |
68 | public static CheckUtil getInstant(){
69 | if(mCheckUtil == null){
70 | mCheckUtil =new CheckUtil();
71 | }
72 | return mCheckUtil;
73 | }
74 |
75 |
76 | public boolean checkKeyWord(String key) {
77 |
78 | return mKeyWordList.contains(key);
79 | }
80 |
81 |
82 |
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/GsonFormat/utils/Toast.java:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.openapi.ui.MessageType;
5 | import com.intellij.openapi.ui.popup.Balloon;
6 | import com.intellij.openapi.ui.popup.JBPopupFactory;
7 | import com.intellij.openapi.wm.StatusBar;
8 | import com.intellij.openapi.wm.WindowManager;
9 | import com.intellij.ui.awt.RelativePoint;
10 |
11 | import javax.swing.*;
12 |
13 | /**
14 | * Created by zzz40500 on 15/8/24.
15 | */
16 | public class Toast {
17 |
18 | /**
19 | * Display simple notification of given type
20 | *
21 | * @param project
22 | * @param type
23 | * @param text
24 | */
25 | public static void make(Project project,JComponent jComponent, MessageType type, String text) {
26 |
27 | StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
28 |
29 | JBPopupFactory.getInstance()
30 | .createHtmlTextBalloonBuilder(text, type, null)
31 | .setFadeoutTime(7500)
32 | .createBalloon()
33 | .show(RelativePoint.getCenterOf(jComponent), Balloon.Position.above);
34 | } /**
35 | * Display simple notification of given type
36 | *
37 | * @param project
38 | * @param type
39 | * @param text
40 | */
41 | public static void make(Project project, MessageType type, String text) {
42 |
43 | StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
44 |
45 | JBPopupFactory.getInstance()
46 | .createHtmlTextBalloonBuilder(text, type, null)
47 | .setFadeoutTime(7500)
48 | .createBalloon()
49 | .show(RelativePoint.getCenterOf(statusBar.getComponent()), Balloon.Position.atRight);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AndroidStudioSuperPlugin
2 |
3 |
4 | This project aims at integrating existing good-to-use android studio plugin so that we can use just one plugin and don't have to download plugins everywhere
5 |
6 |
7 | Version1.0.0 integrated following plugins:
8 | * Android Studio Prettify(https://github.com/Haehnchen/idea-android-studio-plugin)
9 | * GsonFormat(https://github.com/zzz40500/GsonFormat")
10 | * Android Code Generator(https://github.com/tmorcinek/android-codegenerator-plugin-intellij)
11 | * SelectorChapek(https://github.com/inmite/android-selector-chapek)
12 | * IntelliJ/Android Studio Plugin for Android Parcelable boilerplate code generation(https://github.com/mcharmas/android-parcelable-intellij-plugin)
13 | * folding-plugin(https://github.com/dmytrodanylyk/folding-plugin)
14 | * Lifecycle-Sorter(https://github.com/armandAkop/Lifecycle-Sorter)
15 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/actions/ActivityAction.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.actions;
2 |
3 | import com.morcinek.android.codegenerator.codegeneration.providers.ResourceProvidersFactory;
4 | import com.morcinek.android.codegenerator.codegeneration.providers.factories.ActivityResourceProvidersFactory;
5 |
6 | /**
7 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
8 | */
9 | public class ActivityAction extends LayoutAction {
10 |
11 | @Override
12 | protected String getResourceName() {
13 | return "Activity";
14 | }
15 |
16 | @Override
17 | protected String getTemplateName() {
18 | return "Activity_template";
19 | }
20 |
21 | @Override
22 | protected ResourceProvidersFactory getResourceProvidersFactory() {
23 | return new ActivityResourceProvidersFactory();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/actions/AdapterAction.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.actions;
2 |
3 | import com.morcinek.android.codegenerator.codegeneration.providers.ResourceProvidersFactory;
4 | import com.morcinek.android.codegenerator.codegeneration.providers.factories.AdapterResourceProvidersFactory;
5 |
6 | /**
7 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
8 | */
9 | public class AdapterAction extends LayoutAction {
10 |
11 | @Override
12 | protected String getResourceName() {
13 | return "Adapter";
14 | }
15 |
16 | @Override
17 | protected String getTemplateName() {
18 | return "Adapter_template";
19 | }
20 |
21 | @Override
22 | protected ResourceProvidersFactory getResourceProvidersFactory() {
23 | return new AdapterResourceProvidersFactory();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/actions/FragmentAction.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.actions;
2 |
3 | import com.morcinek.android.codegenerator.codegeneration.providers.ResourceProvidersFactory;
4 | import com.morcinek.android.codegenerator.codegeneration.providers.factories.FragmentResourceProvidersFactory;
5 |
6 | /**
7 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
8 | */
9 | public class FragmentAction extends LayoutAction {
10 |
11 | @Override
12 | protected String getResourceName() {
13 | return "Fragment";
14 | }
15 |
16 | @Override
17 | protected String getTemplateName() {
18 | return "Fragment_template";
19 | }
20 |
21 | @Override
22 | protected ResourceProvidersFactory getResourceProvidersFactory() {
23 | return new FragmentResourceProvidersFactory();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/actions/MenuAction.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.actions;
2 |
3 | import com.intellij.openapi.actionSystem.AnAction;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.actionSystem.PlatformDataKeys;
6 | import com.intellij.openapi.project.Project;
7 | import com.intellij.openapi.vfs.VirtualFile;
8 | import com.morcinek.android.codegenerator.codegeneration.providers.factories.MenuResourceProvidersFactory;
9 | import com.morcinek.android.codegenerator.plugin.actions.visibility.ActionVisibilityHelper;
10 | import com.morcinek.android.codegenerator.plugin.codegenerator.CodeGeneratorController;
11 | import com.morcinek.android.codegenerator.plugin.error.ErrorHandler;
12 | import com.morcinek.android.codegenerator.plugin.ui.CodeDialogBuilder;
13 | import com.morcinek.android.codegenerator.plugin.ui.StringResources;
14 | import com.morcinek.android.codegenerator.plugin.utils.ClipboardHelper;
15 |
16 | /**
17 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
18 | */
19 | public class MenuAction extends AnAction {
20 |
21 | private final ActionVisibilityHelper actionVisibilityHelper = new ActionVisibilityHelper("menu", "xml");
22 |
23 | private final ErrorHandler errorHandler = new ErrorHandler();
24 |
25 | @Override
26 | public void actionPerformed(AnActionEvent event) {
27 | final Project project = event.getData(PlatformDataKeys.PROJECT);
28 | final VirtualFile selectedFile = event.getData(PlatformDataKeys.VIRTUAL_FILE);
29 | try {
30 | CodeGeneratorController codeGeneratorController = new CodeGeneratorController("Menu_template", new MenuResourceProvidersFactory());
31 | String generatedCode = codeGeneratorController.generateCode(project, selectedFile, event.getData(PlatformDataKeys.EDITOR));
32 | final CodeDialogBuilder codeDialogBuilder = new CodeDialogBuilder(project,
33 | String.format(StringResources.TITLE_FORMAT_TEXT, selectedFile.getName()), generatedCode);
34 | codeDialogBuilder.addAction(StringResources.COPY_ACTION_LABEL, new Runnable() {
35 | @Override
36 | public void run() {
37 | ClipboardHelper.copy(codeDialogBuilder.getModifiedCode());
38 | codeDialogBuilder.closeDialog();
39 | }
40 | });
41 | codeDialogBuilder.showDialog();
42 | } catch (Exception exception) {
43 | errorHandler.handleError(project, exception);
44 | }
45 | }
46 |
47 | @Override
48 | public void update(AnActionEvent event) {
49 | event.getPresentation().setVisible(actionVisibilityHelper.isVisible(event.getDataContext()));
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/actions/butterknife/BActivityAction.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.actions.butterknife;
2 |
3 | import com.morcinek.android.codegenerator.codegeneration.providers.ResourceProvidersFactory;
4 | import com.morcinek.android.codegenerator.codegeneration.providers.factories.BActivityResourceProvidersFactory;
5 | import com.morcinek.android.codegenerator.plugin.actions.LayoutAction;
6 |
7 | /**
8 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
9 | */
10 | public class BActivityAction extends LayoutAction {
11 |
12 | @Override
13 | protected String getResourceName() {
14 | return "Activity";
15 | }
16 |
17 | @Override
18 | protected String getTemplateName() {
19 | return "BActivity_template";
20 | }
21 |
22 | @Override
23 | protected ResourceProvidersFactory getResourceProvidersFactory() {
24 | return new BActivityResourceProvidersFactory();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/actions/butterknife/BAdapterAction.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.actions.butterknife;
2 |
3 | import com.morcinek.android.codegenerator.codegeneration.providers.ResourceProvidersFactory;
4 | import com.morcinek.android.codegenerator.codegeneration.providers.factories.BAdapterResourceProvidersFactory;
5 | import com.morcinek.android.codegenerator.plugin.actions.LayoutAction;
6 |
7 | /**
8 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
9 | */
10 | public class BAdapterAction extends LayoutAction {
11 |
12 | @Override
13 | protected String getResourceName() {
14 | return "Adapter";
15 | }
16 |
17 | @Override
18 | protected String getTemplateName() {
19 | return "BAdapter_template";
20 | }
21 |
22 | @Override
23 | protected ResourceProvidersFactory getResourceProvidersFactory() {
24 | return new BAdapterResourceProvidersFactory();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/actions/butterknife/BFragmentAction.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.actions.butterknife;
2 |
3 | import com.morcinek.android.codegenerator.codegeneration.providers.ResourceProvidersFactory;
4 | import com.morcinek.android.codegenerator.codegeneration.providers.factories.BActivityResourceProvidersFactory;
5 | import com.morcinek.android.codegenerator.codegeneration.providers.factories.FragmentResourceProvidersFactory;
6 | import com.morcinek.android.codegenerator.plugin.actions.LayoutAction;
7 |
8 | /**
9 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
10 | */
11 | public class BFragmentAction extends LayoutAction {
12 |
13 | @Override
14 | protected String getResourceName() {
15 | return "Fragment";
16 | }
17 |
18 | @Override
19 | protected String getTemplateName() {
20 | return "BFragment_template";
21 | }
22 |
23 | @Override
24 | protected ResourceProvidersFactory getResourceProvidersFactory() {
25 | return new BActivityResourceProvidersFactory();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/actions/visibility/ActionVisibilityHelper.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.actions.visibility;
2 |
3 | import com.intellij.openapi.actionSystem.CommonDataKeys;
4 | import com.intellij.openapi.actionSystem.DataContext;
5 | import com.intellij.openapi.vfs.VirtualFile;
6 |
7 | /**
8 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
9 | */
10 | public class ActionVisibilityHelper {
11 |
12 | private String folder;
13 |
14 | private String extension;
15 |
16 | public ActionVisibilityHelper(String folder, String extension) {
17 | this.folder = folder;
18 | this.extension = extension;
19 | }
20 |
21 | public boolean isVisible(DataContext dataContext) {
22 | VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
23 | if (files != null && files.length == 1) {
24 | VirtualFile file = files[0];
25 | return !file.isDirectory() && hasCorrectExtension(file) && hasCorrectFolder(file);
26 | } else {
27 | return false;
28 | }
29 | }
30 |
31 | private boolean hasCorrectExtension(VirtualFile data) {
32 | return data.getExtension() != null && data.getExtension().equals(extension);
33 | }
34 |
35 | private boolean hasCorrectFolder(VirtualFile data) {
36 | return data.getParent().getName().equals(folder);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/codegenerator/CodeGeneratorController.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.codegenerator;
2 |
3 | import com.intellij.openapi.editor.Editor;
4 | import com.intellij.openapi.fileEditor.FileEditor;
5 | import com.intellij.openapi.fileEditor.FileEditorManager;
6 | import com.intellij.openapi.fileEditor.TextEditor;
7 | import com.intellij.openapi.project.Project;
8 | import com.intellij.openapi.vfs.VirtualFile;
9 | import com.morcinek.android.codegenerator.CodeGenerator;
10 | import com.morcinek.android.codegenerator.codegeneration.providers.ResourceProvidersFactory;
11 | import org.xml.sax.SAXException;
12 |
13 | import javax.xml.parsers.ParserConfigurationException;
14 | import javax.xml.xpath.XPathExpressionException;
15 | import java.io.ByteArrayInputStream;
16 | import java.io.IOException;
17 | import java.io.InputStream;
18 |
19 | /**
20 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
21 | */
22 | public class CodeGeneratorController {
23 |
24 | private CodeGenerator codeGenerator;
25 |
26 | public CodeGeneratorController(String templateName, ResourceProvidersFactory resourceProvidersFactory) {
27 | codeGenerator = CodeGeneratorFactory.createCodeGenerator(templateName, resourceProvidersFactory);
28 | }
29 |
30 | public String generateCode(Project project, VirtualFile file, Editor editor) throws ParserConfigurationException, SAXException, XPathExpressionException, IOException {
31 | return codeGenerator.produceCode(getContents(project, editor, file), file.getName());
32 | }
33 |
34 | private InputStream getContents(Project project, Editor editor, VirtualFile file) throws IOException {
35 | editor = getEditor(project, editor, file);
36 | if (editor != null) {
37 | return new ByteArrayInputStream(getText(editor).getBytes());
38 | } else {
39 | return file.getInputStream();
40 | }
41 | }
42 |
43 | private Editor getEditor(Project project, Editor editor, VirtualFile file) {
44 | if (editor == null) {
45 | TextEditor textEditor = getTextEditor(project, file);
46 | if (textEditor != null) {
47 | return textEditor.getEditor();
48 | }
49 | }
50 | return editor;
51 | }
52 |
53 | private TextEditor getTextEditor(Project project, VirtualFile file) {
54 | FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(file);
55 | if (fileEditor instanceof TextEditor) {
56 | return (TextEditor) fileEditor;
57 | }
58 | return null;
59 | }
60 |
61 | private String getText(Editor editor) {
62 | return editor.getDocument().getText();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/codegenerator/CodeGeneratorFactory.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.codegenerator;
2 |
3 | import com.google.common.io.Resources;
4 | import com.morcinek.android.codegenerator.CodeGenerator;
5 | import com.morcinek.android.codegenerator.codegeneration.TemplateCodeGenerator;
6 | import com.morcinek.android.codegenerator.codegeneration.providers.ResourceProvidersFactory;
7 | import com.morcinek.android.codegenerator.codegeneration.templates.TemplatesProvider;
8 | import com.morcinek.android.codegenerator.extractor.XMLResourceExtractor;
9 | import com.morcinek.android.codegenerator.extractor.string.FileNameExtractor;
10 | import com.morcinek.android.codegenerator.plugin.preferences.persistence.TemplateSettings;
11 |
12 | import java.io.IOException;
13 | import java.net.URL;
14 | import java.nio.charset.Charset;
15 |
16 | /**
17 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
18 | */
19 | public class CodeGeneratorFactory {
20 |
21 | public static CodeGenerator createCodeGenerator(String templateName, ResourceProvidersFactory resourceProvidersFactory) {
22 | return new CodeGenerator(XMLResourceExtractor.createResourceExtractor(),
23 | new FileNameExtractor(),
24 | //FIXME change ResourceTemplateProvider for PreferencesTemplateProvider
25 | new TemplateCodeGenerator(templateName, resourceProvidersFactory, TemplateSettings.getInstance()));
26 | }
27 |
28 | public static class ResourceTemplateProvider implements TemplatesProvider {
29 |
30 | @Override
31 | public String provideTemplateForName(String templateName) {
32 | URL url = getClass().getClassLoader().getResource(templateName);
33 | try {
34 | return Resources.toString(url, Charset.defaultCharset());
35 | } catch (IOException e) {
36 | e.printStackTrace();
37 | }
38 | return null;
39 | }
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/error/ErrorHandler.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.error;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.openapi.ui.Messages;
5 |
6 | /**
7 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
8 | */
9 | public class ErrorHandler {
10 |
11 | public void handleError(Project project, Exception exception) {
12 | exception.printStackTrace();
13 | showErrorMessage(project, exception);
14 | }
15 |
16 | private void showErrorMessage(Project project, Exception e) {
17 | showErrorMessage(project, e.getMessage());
18 | }
19 |
20 | private void showErrorMessage(Project project, String message) {
21 | Messages.showErrorDialog(project, message, "Eclipse Maven Plugin");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/groups/GenerateAndroidCodeGroup.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.groups;
2 |
3 | import com.intellij.openapi.actionSystem.DefaultActionGroup;
4 |
5 | /**
6 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
7 | */
8 | public class GenerateAndroidCodeGroup extends DefaultActionGroup {
9 |
10 | @Override
11 | public boolean hideIfNoVisibleChildren() {
12 | return true;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/persistence/Settings.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.persistence;
2 |
3 | import com.intellij.openapi.components.*;
4 | import com.intellij.openapi.project.Project;
5 | import com.intellij.util.xmlb.XmlSerializerUtil;
6 | import org.jetbrains.annotations.Nullable;
7 |
8 | /**
9 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
10 | */
11 | @State(
12 | name = "CodeGeneratorSettings",
13 | storages = {
14 | @Storage(file = StoragePathMacros.PROJECT_FILE),
15 | @Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/code_generator_settings.xml", scheme = StorageScheme.DIRECTORY_BASED)
16 | }
17 | )
18 | public class Settings implements PersistentStateComponent {
19 |
20 | private String sourcePath;
21 |
22 | public String getSourcePath() {
23 | return sourcePath;
24 | }
25 |
26 | public void setSourcePath(String sourcePath) {
27 | this.sourcePath = sourcePath;
28 | }
29 |
30 | public static Settings getInstance(Project project) {
31 | return ServiceManager.getService(project, Settings.class);
32 | }
33 |
34 | @Nullable
35 | @Override
36 | public Settings getState() {
37 | return this;
38 | }
39 |
40 | @Override
41 | public void loadState(Settings settings) {
42 | XmlSerializerUtil.copyBean(settings, this);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/preferences/configurables/MainConfigurable.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.preferences.configurables;
2 |
3 | import com.intellij.openapi.options.Configurable;
4 | import com.intellij.openapi.options.ConfigurationException;
5 | import com.morcinek.android.codegenerator.plugin.preferences.configurables.templates.TemplateConfigurable;
6 | import org.jetbrains.annotations.Nls;
7 | import org.jetbrains.annotations.NonNls;
8 | import org.jetbrains.annotations.Nullable;
9 |
10 | import javax.swing.*;
11 | import java.awt.*;
12 |
13 | /**
14 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
15 | */
16 | public class MainConfigurable implements Configurable.Composite, Configurable.NoScroll, Configurable {
17 |
18 | private Configurable[] configurables;
19 |
20 | public MainConfigurable() {
21 | super();
22 | }
23 |
24 | @Nls
25 | @Override
26 | public String getDisplayName() {
27 | return "Android Code Generator";
28 | }
29 |
30 | @Nullable
31 | @NonNls
32 | @Override
33 | public String getHelpTopic() {
34 | return null;
35 | }
36 |
37 | @Override
38 | public JComponent createComponent() {
39 | JPanel panel = new JPanel(new BorderLayout());
40 | JLabel label = new JLabel("Here you can edit 'Android Code Generator' settings. In children pages you can edit template for each code generation method.");
41 | label.setVerticalAlignment(SwingConstants.TOP);
42 | panel.add(label, BorderLayout.PAGE_START);
43 | return panel;
44 | }
45 |
46 | public void disposeUIResources() {
47 | }
48 |
49 | @Override
50 | public boolean isModified() {
51 | return false;
52 | }
53 |
54 | @Override
55 | public void apply() throws ConfigurationException {
56 | }
57 |
58 | @Override
59 | public void reset() {
60 | }
61 |
62 | public Configurable[] getConfigurables() {
63 | if (configurables == null) {
64 | configurables = new Configurable[]{
65 | new TemplateConfigurable("Activity Template", "Setup Template for Activity code generation:", "Activity_template"),
66 | new TemplateConfigurable("Adapter Template", "Setup Template for Adapter code generation:", "Adapter_template"),
67 | new TemplateConfigurable("Fragment Template", "Setup Template for Fragment code generation:", "Fragment_template"),
68 | new TemplateConfigurable("Menu Template", "Setup Template for Menu code generation:", "Menu_template")
69 | };
70 | }
71 | return configurables;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/preferences/persistence/TemplateSettings.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.preferences.persistence;
2 |
3 | import com.google.common.collect.Maps;
4 | import com.intellij.openapi.components.*;
5 | import com.intellij.util.xmlb.XmlSerializerUtil;
6 | import com.morcinek.android.codegenerator.codegeneration.templates.TemplatesProvider;
7 | import com.morcinek.android.codegenerator.plugin.codegenerator.CodeGeneratorFactory;
8 | import org.jetbrains.annotations.Nullable;
9 |
10 | import java.util.Map;
11 |
12 | /**
13 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
14 | */
15 | @State(
16 | name = "CodeGeneratorTemplateSettings",
17 | storages = {
18 | @Storage(file = StoragePathMacros.APP_CONFIG + "/code_generator_template_settings.xml")
19 | }
20 | )
21 | public class TemplateSettings implements PersistentStateComponent, TemplatesProvider {
22 |
23 | private Map templateValues = Maps.newHashMap();
24 |
25 | private TemplatesProvider templatesProvider = new CodeGeneratorFactory.ResourceTemplateProvider();
26 |
27 | public static TemplateSettings getInstance() {
28 | return ServiceManager.getService(TemplateSettings.class);
29 | }
30 |
31 | public Map getTemplateValues() {
32 | return templateValues;
33 | }
34 |
35 | public void setTemplateValues(Map templateValues) {
36 | this.templateValues = templateValues;
37 | }
38 |
39 | @Nullable
40 | @Override
41 | public TemplateSettings getState() {
42 | return this;
43 | }
44 |
45 | @Override
46 | public void loadState(TemplateSettings templateSettings) {
47 | XmlSerializerUtil.copyBean(templateSettings, this);
48 | }
49 |
50 | @Override
51 | public String provideTemplateForName(String templateName) {
52 | if (isUsingCustomTemplateForName(templateName)) {
53 | return templateValues.get(templateName);
54 | }
55 | return templatesProvider.provideTemplateForName(templateName);
56 | }
57 |
58 | public void removeTemplateForName(String templateName) {
59 | templateValues.remove(templateName);
60 | }
61 |
62 | public boolean isUsingCustomTemplateForName(String templateName) {
63 | return templateValues.containsKey(templateName);
64 | }
65 |
66 | public void setTemplateForName(String templateName, String template) {
67 | templateValues.put(templateName, template);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/ui/CodeDialogBuilder.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.ui;
2 |
3 | import com.google.common.collect.Maps;
4 | import com.intellij.openapi.application.ApplicationManager;
5 | import com.intellij.openapi.project.Project;
6 | import com.intellij.openapi.ui.ComboBox;
7 | import com.intellij.openapi.ui.DialogBuilder;
8 | import com.intellij.openapi.ui.DialogWrapper;
9 | import com.intellij.ui.CollectionComboBoxModel;
10 | import com.intellij.ui.JBColor;
11 | import com.intellij.ui.components.JBScrollPane;
12 | import com.intellij.ui.components.JBTextField;
13 |
14 | import javax.swing.*;
15 | import javax.swing.border.LineBorder;
16 | import java.awt.*;
17 | import java.awt.event.ActionEvent;
18 | import java.util.Map;
19 |
20 | /**
21 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
22 | */
23 | public class CodeDialogBuilder {
24 |
25 | private final DialogBuilder dialogBuilder;
26 |
27 | private final JPanel topPanel;
28 |
29 | private final JTextArea codeArea;
30 | private JBTextField packageText;
31 | private JComboBox sourcePathComboBox;
32 |
33 | public CodeDialogBuilder(Project project, String title, String producedCode) {
34 | dialogBuilder = new DialogBuilder(project);
35 | dialogBuilder.setTitle(title);
36 |
37 | JPanel centerPanel = new JPanel(new BorderLayout());
38 |
39 | codeArea = prepareCodeArea(producedCode);
40 | centerPanel.add(new JBScrollPane(codeArea), BorderLayout.CENTER);
41 | dialogBuilder.setCenterPanel(centerPanel);
42 |
43 | topPanel = new JPanel(new GridLayout(0, 2));
44 | centerPanel.add(topPanel, BorderLayout.PAGE_START);
45 |
46 | dialogBuilder.removeAllActions();
47 | }
48 |
49 | public void addAction(String title, final Runnable action) {
50 | addAction(title, action, false);
51 | }
52 |
53 | public void addAction(String title, final Runnable action, final boolean runWriteAction) {
54 | dialogBuilder.addAction(new AbstractAction(title) {
55 | @Override
56 | public void actionPerformed(ActionEvent e) {
57 | if (runWriteAction) {
58 | ApplicationManager.getApplication().runWriteAction(action);
59 | } else {
60 | action.run();
61 | }
62 | }
63 | });
64 | }
65 |
66 | public void addPackageSection(String defaultText) {
67 | topPanel.add(new JLabel(StringResources.PACKAGE_LABEL));
68 | packageText = new JBTextField(defaultText);
69 | topPanel.add(packageText);
70 | }
71 |
72 | public String getPackage() {
73 | return packageText.getText();
74 | }
75 |
76 | public void addSourcePathSection(java.util.List string, String defaultValue) {
77 | topPanel.add(new JLabel(StringResources.SOURCE_PATH_LABEL));
78 | sourcePathComboBox = new ComboBox(new CollectionComboBoxModel(string));
79 | sourcePathComboBox.setSelectedItem(defaultValue);
80 | topPanel.add(sourcePathComboBox);
81 | }
82 |
83 | public String getSourcePath() {
84 | return (String) sourcePathComboBox.getSelectedItem();
85 | }
86 |
87 | public int showDialog() {
88 | return dialogBuilder.show();
89 | }
90 |
91 | public void closeDialog(){
92 | dialogBuilder.getDialogWrapper().close(DialogWrapper.OK_EXIT_CODE);
93 | }
94 |
95 | public String getModifiedCode() {
96 | return codeArea.getText();
97 | }
98 |
99 | private JTextArea prepareCodeArea(String producedCode) {
100 | JTextArea codeArea = new JTextArea(producedCode);
101 | codeArea.setBorder(new LineBorder(JBColor.gray));
102 | return codeArea;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/ui/DialogsFactory.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.ui;
2 |
3 | import com.intellij.ide.IdeBundle;
4 | import com.intellij.openapi.project.Project;
5 | import com.intellij.openapi.ui.Messages;
6 | import com.intellij.util.ui.UIUtil;
7 |
8 | /**
9 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
10 | */
11 | public class DialogsFactory {
12 |
13 | public static boolean openOverrideFileDialog(Project project, String folderPath, String fileName) {
14 | return Messages.showYesNoDialog(
15 | project,
16 | String.format(StringResources.OVERRIDE_DIALOG_MESSAGE, folderPath, fileName),
17 | StringResources.OVERRIDE_DIALOG_TITLE,
18 | StringResources.OVERRIDE_DIALOG_YES_TEXT,
19 | StringResources.OVERRIDE_DIALOG_NO_TEXT,
20 | UIUtil.getWarningIcon()
21 | ) == Messages.OK;
22 | }
23 |
24 | public static void showMissingSourcePathDialog(Project project) {
25 | Messages.showErrorDialog(
26 | project,
27 | StringResources.MISSING_SOURCE_PATH_DIALOG_MESSAGE,
28 | StringResources.MISSING_SOURCE_PATH_DIALOG_TITLE
29 | );
30 | }
31 |
32 | public static boolean openResetTemplateDialog() {
33 | return Messages.showOkCancelDialog(IdeBundle.message("prompt.reset.to.original.template"),
34 | IdeBundle.message("title.reset.template"), Messages.getQuestionIcon()) ==
35 | Messages.OK;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/ui/StringResources.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.ui;
2 |
3 | /**
4 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
5 | */
6 | public interface StringResources {
7 |
8 | String PACKAGE_LABEL = "Package";
9 | String SOURCE_PATH_LABEL = "Source Path";
10 | String TITLE_FORMAT_TEXT = "Code generated from: '%s'";
11 | String COPY_ACTION_LABEL = "Copy Code To Clipboard";
12 | String CREATE_ACTION_LABEL = "Create File";
13 |
14 | String OVERRIDE_DIALOG_TITLE = "File Already Exists";
15 | String OVERRIDE_DIALOG_MESSAGE = "File '%s/%s' already exists.\nDo you want to override file content with generated code.";
16 | String OVERRIDE_DIALOG_YES_TEXT = "Override";
17 | String OVERRIDE_DIALOG_NO_TEXT = "Cancel";
18 |
19 | String MISSING_SOURCE_PATH_DIALOG_MESSAGE = "You need to select 'Source Path' in which the file will be created.\nSelect one from the project's source roots.";
20 | String MISSING_SOURCE_PATH_DIALOG_TITLE = "Missing Source Path";
21 |
22 | String RESET_TO_DEFAULT_ACTION_DESCRIPTION = "Reset templates to Defaults";
23 | String RESET_TO_DEFAULT_ACTION_TITLE = "Reset to Defaults";
24 | }
25 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/utils/ClipboardHelper.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.utils;
2 |
3 | import com.intellij.openapi.ide.CopyPasteManager;
4 |
5 | import java.awt.datatransfer.StringSelection;
6 |
7 | /**
8 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
9 | */
10 | public class ClipboardHelper {
11 |
12 | public static void copy(String generatedCode) {
13 | CopyPasteManager.getInstance().setContents(new StringSelection(generatedCode));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/utils/PackageHelper.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.utils;
2 |
3 | import com.google.common.collect.Lists;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.project.Project;
6 | import com.intellij.openapi.vfs.VirtualFile;
7 | import com.morcinek.android.codegenerator.extractor.PackageExtractor;
8 | import com.morcinek.android.codegenerator.extractor.XMLPackageExtractor;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | /**
14 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
15 | */
16 | public class PackageHelper {
17 |
18 | private final PackageExtractor packageExtractor = new XMLPackageExtractor();
19 |
20 | private final ProjectHelper projectHelper = new ProjectHelper();
21 |
22 | public String getPackageName(Project project, AnActionEvent event) {
23 | try {
24 | for (String path : possibleManifestPaths()) {
25 | VirtualFile file = getManifestFileFromPath(project, path);
26 | if (file != null && file.exists()) {
27 | return packageExtractor.extractPackageFromManifestStream(file.getInputStream());
28 | }
29 | }
30 | for (String path : sourceRootPaths(project, event)) {
31 | VirtualFile file = getManifestFileFromPath(project, path);
32 | if (file != null && file.exists()) {
33 | return packageExtractor.extractPackageFromManifestStream(file.getInputStream());
34 | }
35 | }
36 | } catch (Exception ignored) {
37 | }
38 | return "";
39 | }
40 |
41 | private ArrayList possibleManifestPaths() {
42 | return Lists.newArrayList("", "app/", "app/src/main/", "src/main/", "res/");
43 | }
44 |
45 | private List sourceRootPaths(Project project, AnActionEvent event) {
46 | return projectHelper.getSourceRootPathList(project, event);
47 | }
48 |
49 | private VirtualFile getManifestFileFromPath(Project project, String path) {
50 | VirtualFile folder = project.getBaseDir().findFileByRelativePath(path);
51 | if (folder != null) {
52 | return folder.findChild("AndroidManifest.xml");
53 | }
54 | return null;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/utils/PathHelper.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.utils;
2 |
3 | import com.morcinek.android.codegenerator.codegeneration.builders.file.ClassNameBuilder;
4 | import com.morcinek.android.codegenerator.codegeneration.builders.file.PackageBuilder;
5 | import com.morcinek.android.codegenerator.extractor.string.FileNameExtractor;
6 | import org.apache.velocity.util.StringUtils;
7 |
8 | /**
9 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
10 | */
11 | public class PathHelper {
12 |
13 | public String getMergedCodeWithPackage(String packageName, String generateCode) {
14 | if (!packageName.isEmpty()) {
15 | return new PackageBuilder(packageName).builtString() + generateCode;
16 | }
17 | return generateCode;
18 | }
19 |
20 | public String getFileName(String filePath, String resourceName) {
21 | String fileName = new FileNameExtractor().extractFromString(filePath);
22 | return new ClassNameBuilder(fileName).builtString() + resourceName + ".java";
23 | }
24 |
25 | public String getFolderPath(String sourcePath, String packageName) {
26 | String normalizePath = StringUtils.normalizePath(sourcePath + "/" + StringUtils.getPackageAsPath(packageName));
27 | return org.apache.commons.lang3.StringUtils.strip(normalizePath, "/");
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/android_code_generator/com/morcinek/android/codegenerator/plugin/utils/ProjectHelper.java:
--------------------------------------------------------------------------------
1 | package com.morcinek.android.codegenerator.plugin.utils;
2 |
3 | import com.google.common.collect.Lists;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.actionSystem.LangDataKeys;
6 | import com.intellij.openapi.fileEditor.FileEditorManager;
7 | import com.intellij.openapi.project.Project;
8 | import com.intellij.openapi.roots.ModuleRootManager;
9 | import com.intellij.openapi.vfs.VirtualFile;
10 | import org.apache.velocity.util.StringUtils;
11 |
12 | import java.io.IOException;
13 | import java.util.List;
14 |
15 | /**
16 | * Copyright 2014 Tomasz Morcinek. All rights reserved.
17 | */
18 | public class ProjectHelper {
19 |
20 | public boolean fileExists(Project project, String fileName, String folderPath) throws IOException {
21 | try {
22 | return project.getBaseDir().findFileByRelativePath(folderPath).findFileByRelativePath(fileName).exists();
23 | } catch (NullPointerException e) {
24 | return false;
25 | }
26 | }
27 |
28 | public VirtualFile createOrFindFile(Project project, String fileName, String folderPath) throws IOException {
29 | VirtualFile folder = createFolderIfNotExist(project, folderPath);
30 | return folder.findOrCreateChildData(project, fileName);
31 | }
32 |
33 | public VirtualFile setFileContent(Project project, VirtualFile createdFile, String code) throws IOException {
34 | createdFile.setBinaryContent(code.getBytes());
35 | openFileInEditor(project, createdFile);
36 | return createdFile;
37 | }
38 |
39 | private void openFileInEditor(Project project, VirtualFile fileWithGeneratedCode) {
40 | FileEditorManager.getInstance(project).openFile(fileWithGeneratedCode, true);
41 | }
42 |
43 | private VirtualFile createFolderIfNotExist(Project project, String folder) throws IOException {
44 | VirtualFile directory = project.getBaseDir();
45 | String[] folders = folder.split("/");
46 | for (String childFolder : folders) {
47 | VirtualFile childDirectory = directory.findChild(childFolder);
48 | if (childDirectory != null && childDirectory.isDirectory()) {
49 | directory = childDirectory;
50 | } else {
51 | directory = directory.createChildDirectory(project, childFolder);
52 | }
53 | }
54 | return directory;
55 | }
56 |
57 | public List getSourceRootPathList(Project project, AnActionEvent event) {
58 | List sourceRoots = Lists.newArrayList();
59 | String projectPath = StringUtils.normalizePath(project.getBasePath());
60 | for (VirtualFile virtualFile : getModuleRootManager(event).getSourceRoots(false)) {
61 | sourceRoots.add(StringUtils.normalizePath(virtualFile.getPath()).replace(projectPath, ""));
62 | }
63 | return sourceRoots;
64 | }
65 |
66 | private ModuleRootManager getModuleRootManager(AnActionEvent event) {
67 | return ModuleRootManager.getInstance(event.getData(LangDataKeys.MODULE));
68 | }
69 | }
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/GenerateDialog.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator;
17 |
18 | import com.intellij.ide.util.DefaultPsiElementCellRenderer;
19 | import com.intellij.openapi.ui.DialogWrapper;
20 | import com.intellij.openapi.ui.LabeledComponent;
21 | import com.intellij.psi.PsiClass;
22 | import com.intellij.psi.PsiField;
23 | import com.intellij.psi.PsiModifier;
24 | import com.intellij.psi.search.SearchScope;
25 | import com.intellij.ui.CollectionListModel;
26 | import com.intellij.ui.ToolbarDecorator;
27 | import com.intellij.ui.components.JBList;
28 | import org.jetbrains.annotations.Nullable;
29 |
30 | import javax.lang.model.element.Modifier;
31 | import javax.swing.*;
32 | import java.util.Arrays;
33 | import java.util.List;
34 |
35 | public class GenerateDialog extends DialogWrapper {
36 |
37 | private final LabeledComponent myComponent;
38 | private CollectionListModel myFields;
39 |
40 | protected GenerateDialog(PsiClass psiClass) {
41 | super(psiClass.getProject());
42 | setTitle("Select Fields for Parcelable Generation");
43 |
44 | PsiField[] allFields = psiClass.getFields();
45 | PsiField[] fields = new PsiField[allFields.length];
46 |
47 | int i = 0;
48 |
49 | for (PsiField field : allFields) {
50 | // Exclude static fields
51 | if (!field.hasModifierProperty(PsiModifier.STATIC)) {
52 | fields[i++] = field;
53 | }
54 | }
55 |
56 | // i is post-incremented, so no need to add 1 for the count
57 | fields = Arrays.copyOfRange(fields, 0, i);
58 |
59 | myFields = new CollectionListModel(fields);
60 |
61 | JBList fieldList = new JBList(myFields);
62 | fieldList.setCellRenderer(new DefaultPsiElementCellRenderer());
63 | ToolbarDecorator decorator = ToolbarDecorator.createDecorator(fieldList);
64 | decorator.disableAddAction();
65 | JPanel panel = decorator.createPanel();
66 |
67 | myComponent = LabeledComponent.create(panel, "Fields to include in Parcelable");
68 |
69 | init();
70 | }
71 |
72 | @Nullable
73 | @Override
74 | protected JComponent createCenterPanel() {
75 | return myComponent;
76 | }
77 |
78 | public List getSelectedFields() {
79 | return myFields.getItems();
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/ParcelableAction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator;
17 |
18 | import com.intellij.openapi.actionSystem.AnAction;
19 | import com.intellij.openapi.actionSystem.AnActionEvent;
20 | import com.intellij.openapi.actionSystem.LangDataKeys;
21 | import com.intellij.openapi.actionSystem.PlatformDataKeys;
22 | import com.intellij.openapi.command.WriteCommandAction;
23 | import com.intellij.openapi.editor.Editor;
24 | import com.intellij.psi.PsiClass;
25 | import com.intellij.psi.PsiElement;
26 | import com.intellij.psi.PsiField;
27 | import com.intellij.psi.PsiFile;
28 | import com.intellij.psi.util.PsiTreeUtil;
29 |
30 | import java.util.List;
31 |
32 | public class ParcelableAction extends AnAction {
33 |
34 | @Override
35 | public void actionPerformed(AnActionEvent e) {
36 | PsiClass psiClass = getPsiClassFromContext(e);
37 |
38 | GenerateDialog dlg = new GenerateDialog(psiClass);
39 | dlg.show();
40 |
41 | if (dlg.isOK()) {
42 | generateParcelable(psiClass, dlg.getSelectedFields());
43 | }
44 | }
45 |
46 | private void generateParcelable(final PsiClass psiClass, final List fields) {
47 | new WriteCommandAction.Simple(psiClass.getProject(), psiClass.getContainingFile()) {
48 | @Override
49 | protected void run() throws Throwable {
50 | new CodeGenerator(psiClass, fields).generate();
51 | }
52 | }.execute();
53 | }
54 |
55 |
56 | @Override
57 | public void update(AnActionEvent e) {
58 | PsiClass psiClass = getPsiClassFromContext(e);
59 | e.getPresentation().setEnabled(psiClass != null && !psiClass.isEnum() && !psiClass.isInterface());
60 | }
61 |
62 | private PsiClass getPsiClassFromContext(AnActionEvent e) {
63 | PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);
64 | Editor editor = e.getData(PlatformDataKeys.EDITOR);
65 |
66 | if (psiFile == null || editor == null) {
67 | return null;
68 | }
69 |
70 | int offset = editor.getCaretModel().getOffset();
71 | PsiElement element = psiFile.findElementAt(offset);
72 |
73 | return PsiTreeUtil.getParentOfType(element, PsiClass.class);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/BundleSerializerFactory.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.typeserializers;
2 |
3 | import com.intellij.psi.PsiType;
4 | import pl.charmas.parcelablegenerator.typeserializers.serializers.BundleSerializer;
5 |
6 | /**
7 | * Custom serializer factory for Date objects
8 | *
9 | * @author Dallas Gutauckis [dallas@gutauckis.com]
10 | */
11 | public class BundleSerializerFactory implements TypeSerializerFactory {
12 | private final BundleSerializer mSerializer;
13 |
14 | public BundleSerializerFactory() {
15 | mSerializer = new BundleSerializer();
16 | }
17 |
18 | @Override
19 | public TypeSerializer getSerializer(PsiType psiType) {
20 | if ("android.os.Bundle".equals(psiType.getCanonicalText())) {
21 | return mSerializer;
22 | }
23 |
24 | return null;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/ChainSerializerFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers;
17 |
18 | import com.intellij.psi.PsiType;
19 | import pl.charmas.parcelablegenerator.typeserializers.serializers.UnknownTypeSerializer;
20 |
21 | import java.util.Arrays;
22 | import java.util.List;
23 |
24 | public class ChainSerializerFactory implements TypeSerializerFactory {
25 |
26 | private final List factories;
27 |
28 | public ChainSerializerFactory(TypeSerializerFactory... factories) {
29 | this.factories = Arrays.asList(factories);
30 | }
31 |
32 | @Override
33 | public TypeSerializer getSerializer(PsiType psiType) {
34 | for (TypeSerializerFactory factory : factories) {
35 | TypeSerializer serializer = factory.getSerializer(psiType);
36 | if (serializer != null) {
37 | return serializer;
38 | }
39 | }
40 | return new UnknownTypeSerializer(psiType.getCanonicalText());
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/DateSerializerFactory.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.typeserializers;
2 |
3 | import com.intellij.psi.PsiType;
4 | import pl.charmas.parcelablegenerator.typeserializers.serializers.DateSerializer;
5 |
6 | /**
7 | * Custom serializer factory for Date objects
8 | *
9 | * @author Dallas Gutauckis [dallas@gutauckis.com]
10 | */
11 | public class DateSerializerFactory implements TypeSerializerFactory {
12 | private final DateSerializer mSerializer;
13 |
14 | public DateSerializerFactory() {
15 | mSerializer = new DateSerializer();
16 | }
17 |
18 | @Override
19 | public TypeSerializer getSerializer(PsiType psiType) {
20 | if ("java.util.Date".equals(psiType.getCanonicalText())) {
21 | return mSerializer;
22 | }
23 |
24 | return null;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/EnumerationSerializerFactory.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.typeserializers;
2 |
3 | import com.intellij.psi.PsiClassType;
4 | import com.intellij.psi.PsiEnumConstant;
5 | import com.intellij.psi.PsiField;
6 | import com.intellij.psi.PsiType;
7 | import com.intellij.psi.impl.source.PsiClassReferenceType;
8 | import com.intellij.psi.impl.source.PsiEnumConstantImpl;
9 | import pl.charmas.parcelablegenerator.typeserializers.serializers.EnumerationSerializer;
10 | import pl.charmas.parcelablegenerator.util.PsiUtils;
11 |
12 | /**
13 | * Modified by Dallas Gutauckis [dallas@gutauckis.com]
14 | */
15 | public class EnumerationSerializerFactory implements TypeSerializerFactory {
16 | private TypeSerializer mSerializer = new EnumerationSerializer();
17 |
18 | @Override
19 | public TypeSerializer getSerializer(PsiType psiType) {
20 | if (psiType instanceof PsiClassReferenceType && ((PsiClassReferenceType) psiType).resolve().isEnum()) {
21 | return mSerializer;
22 | }
23 |
24 | return null;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/ListSerializerFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers;
17 |
18 | import com.intellij.psi.PsiType;
19 | import pl.charmas.parcelablegenerator.typeserializers.serializers.GenericListSerializer;
20 | import pl.charmas.parcelablegenerator.util.PsiUtils;
21 |
22 | public class ListSerializerFactory implements TypeSerializerFactory {
23 | private TypeSerializer mSerializer = new GenericListSerializer();
24 |
25 | @Override
26 | public TypeSerializer getSerializer(PsiType psiType) {
27 | if (PsiUtils.isOfType(psiType, "java.util.List")) {
28 | return mSerializer;
29 | }
30 |
31 | return null;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/ParcelableSerializerFactory.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.typeserializers;
2 |
3 | import com.intellij.psi.PsiType;
4 | import pl.charmas.parcelablegenerator.typeserializers.serializers.ParcelableArraySerializer;
5 | import pl.charmas.parcelablegenerator.typeserializers.serializers.ParcelableListSerializer;
6 | import pl.charmas.parcelablegenerator.typeserializers.serializers.ParcelableObjectSerializer;
7 | import pl.charmas.parcelablegenerator.util.PsiUtils;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * Serializer factory for Parcelable objects
13 | *
14 | * @author Dallas Gutauckis [dallas@gutauckis.com]
15 | * @author Michał Charmas [micha@charmas.pl]
16 | */
17 | public class ParcelableSerializerFactory implements TypeSerializerFactory {
18 | private TypeSerializer mSerializer = new ParcelableObjectSerializer();
19 | private TypeSerializer listSerializer = new ParcelableListSerializer();
20 | private TypeSerializer arraySerializer = new ParcelableArraySerializer();
21 |
22 | @Override
23 | public TypeSerializer getSerializer(PsiType psiType) {
24 | if (PsiUtils.isOfType(psiType, "android.os.Parcelable[]")) {
25 | return arraySerializer;
26 | }
27 |
28 | if (PsiUtils.isOfType(psiType, "android.os.Parcelable")) {
29 | return mSerializer;
30 | }
31 |
32 | if (PsiUtils.isOfType(psiType, "java.util.List")) {
33 | List resolvedGenerics = PsiUtils.getResolvedGenerics(psiType);
34 | for (PsiType resolvedGeneric : resolvedGenerics) {
35 | if (PsiUtils.isOfType(resolvedGeneric, "android.os.Parcelable")) {
36 | return listSerializer;
37 | }
38 | }
39 | }
40 |
41 | return null;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/PrimitiveArraySerializerFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers;
17 |
18 | import com.intellij.psi.PsiType;
19 | import pl.charmas.parcelablegenerator.typeserializers.serializers.BooleanSparseArraySerializer;
20 | import pl.charmas.parcelablegenerator.typeserializers.serializers.PrimitiveArraySerializer;
21 |
22 | import java.util.HashMap;
23 |
24 | public class PrimitiveArraySerializerFactory implements TypeSerializerFactory {
25 | private final HashMap handledTypes;
26 |
27 | public PrimitiveArraySerializerFactory() {
28 | handledTypes = new HashMap();
29 | handledTypes.put("boolean[]", new PrimitiveArraySerializer("Boolean"));
30 | handledTypes.put("byte[]", new PrimitiveArraySerializer("Byte"));
31 | handledTypes.put("char[]", new PrimitiveArraySerializer("Char"));
32 | handledTypes.put("double[]", new PrimitiveArraySerializer("Double"));
33 | handledTypes.put("float[]", new PrimitiveArraySerializer("Float"));
34 | handledTypes.put("int[]", new PrimitiveArraySerializer("Int"));
35 | handledTypes.put("long[]", new PrimitiveArraySerializer("Long"));
36 | handledTypes.put("java.lang.String[]", new PrimitiveArraySerializer("String"));
37 | handledTypes.put("android.util.SparseBooleanArray", new BooleanSparseArraySerializer());
38 | }
39 |
40 | @Override
41 | public TypeSerializer getSerializer(PsiType psiType) {
42 | return handledTypes.get(psiType.getCanonicalText());
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/PrimitiveTypeSerializerFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers;
17 |
18 | import com.intellij.psi.PsiType;
19 | import pl.charmas.parcelablegenerator.typeserializers.serializers.BooleanPrimitiveSerializer;
20 | import pl.charmas.parcelablegenerator.typeserializers.serializers.CharPrimitiveSerializer;
21 | import pl.charmas.parcelablegenerator.typeserializers.serializers.NullablePrimitivesSerializer;
22 | import pl.charmas.parcelablegenerator.typeserializers.serializers.PrimitiveTypeSerializer;
23 |
24 | import java.util.HashMap;
25 | import java.util.Map;
26 |
27 | public class PrimitiveTypeSerializerFactory implements TypeSerializerFactory {
28 |
29 | private final Map writeMethodsForTypes = new HashMap();
30 |
31 | public PrimitiveTypeSerializerFactory() {
32 | initPrimitives();
33 | initNullablePrimitives();
34 | }
35 |
36 | private void initNullablePrimitives() {
37 | writeMethodsForTypes.put("byte", new PrimitiveTypeSerializer("Byte"));
38 | writeMethodsForTypes.put("double", new PrimitiveTypeSerializer("Double"));
39 | writeMethodsForTypes.put("float", new PrimitiveTypeSerializer("Float"));
40 | writeMethodsForTypes.put("int", new PrimitiveTypeSerializer("Int"));
41 | writeMethodsForTypes.put("long", new PrimitiveTypeSerializer("Long"));
42 | writeMethodsForTypes.put("java.lang.String", new PrimitiveTypeSerializer("String"));
43 | writeMethodsForTypes.put("boolean", new BooleanPrimitiveSerializer());
44 | writeMethodsForTypes.put("char", new CharPrimitiveSerializer());
45 | }
46 |
47 | private void initPrimitives() {
48 | writeMethodsForTypes.put("java.lang.Byte", new NullablePrimitivesSerializer("java.lang.Byte"));
49 | writeMethodsForTypes.put("java.lang.Double", new NullablePrimitivesSerializer("java.lang.Double"));
50 | writeMethodsForTypes.put("java.lang.Float", new NullablePrimitivesSerializer("java.lang.Float"));
51 | writeMethodsForTypes.put("java.lang.Integer", new NullablePrimitivesSerializer("java.lang.Integer"));
52 | writeMethodsForTypes.put("java.lang.Long", new NullablePrimitivesSerializer("java.lang.Long"));
53 | writeMethodsForTypes.put("java.lang.Boolean", new NullablePrimitivesSerializer("java.lang.Boolean"));
54 | writeMethodsForTypes.put("java.lang.Char", new NullablePrimitivesSerializer("java.lang.Char"));
55 | }
56 |
57 | @Override
58 | public TypeSerializer getSerializer(PsiType psiType) {
59 | return writeMethodsForTypes.get(psiType.getCanonicalText());
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/SerializableSerializerFactory.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.typeserializers;
2 |
3 | import com.intellij.psi.PsiType;
4 | import pl.charmas.parcelablegenerator.typeserializers.serializers.SerializableObjectSerializer;
5 |
6 | /**
7 | * Modified by Dallas Gutauckis [dallas@gutauckis.com]
8 | */
9 | public class SerializableSerializerFactory implements TypeSerializerFactory {
10 | private TypeSerializer mSerializer;
11 |
12 | public SerializableSerializerFactory() {
13 | mSerializer = new SerializableObjectSerializer();
14 | }
15 |
16 | @Override
17 | public TypeSerializer getSerializer(PsiType psiType) {
18 | PsiType[] superTypes = psiType.getSuperTypes();
19 |
20 | for (PsiType superType : superTypes) {
21 | String canonicalText = superType.getCanonicalText();
22 |
23 | if ("java.io.Serializable".equals(canonicalText)) {
24 | return mSerializer;
25 | }
26 | }
27 |
28 | return null;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/TypeSerializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers;
17 |
18 | import com.intellij.psi.PsiField;
19 |
20 | public interface TypeSerializer {
21 |
22 | String writeValue(PsiField field, String parcel, String flags);
23 |
24 | String readValue(PsiField field, String parcel);
25 | }
26 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/TypeSerializerFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers;
17 |
18 | import com.intellij.psi.PsiType;
19 |
20 | public interface TypeSerializerFactory {
21 | public TypeSerializer getSerializer(PsiType psiType);
22 | }
23 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/BooleanPrimitiveSerializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
17 |
18 | import com.intellij.psi.PsiField;
19 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
20 |
21 | public class BooleanPrimitiveSerializer implements TypeSerializer {
22 |
23 | @Override
24 | public String writeValue(PsiField field, String parcel, String flags) {
25 | return parcel + ".writeByte(" + field.getName() + " ? (byte) 1 : (byte) 0);";
26 | }
27 |
28 | @Override
29 | public String readValue(PsiField field, String parcel) {
30 | return "this." + field.getName() + " = " + parcel + ".readByte() != 0;";
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/BooleanSparseArraySerializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
17 |
18 | import com.intellij.psi.PsiField;
19 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
20 |
21 | public class BooleanSparseArraySerializer implements TypeSerializer {
22 |
23 | @Override
24 | public String writeValue(PsiField field, String parcel, String flags) {
25 | return parcel + ".writeSparseBooleanArray(this." + field.getName() + ");";
26 | }
27 |
28 | @Override
29 | public String readValue(PsiField field, String parcel) {
30 | return "this." + field.getName() + " = " + parcel + ".readSparseBooleanArray();";
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/BundleSerializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
17 |
18 | import com.intellij.psi.PsiField;
19 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
20 |
21 | /**
22 | * Custom serializer for Date objects to simplify parceling
23 | *
24 | * @author Dallas Gutauckis [dallas@gutauckis.com]
25 | */
26 | public class BundleSerializer implements TypeSerializer {
27 |
28 | private static final String NULL_VALUE = "-1";
29 |
30 | @Override
31 | public String writeValue(PsiField field, String parcel, String flags) {
32 | return parcel + ".writeBundle(" + field.getName() + ");";
33 | }
34 |
35 | @Override
36 | public String readValue(PsiField field, String parcel) {
37 | return field.getName() + " = " + parcel + ".readBundle();";
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/CharPrimitiveSerializer.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
2 |
3 | import com.intellij.psi.PsiField;
4 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
5 |
6 | public class CharPrimitiveSerializer implements TypeSerializer {
7 | @Override
8 | public String writeValue(PsiField field, String parcel, String flags) {
9 | return parcel + ".writeInt(" + field.getName() + ");";
10 | }
11 |
12 | @Override
13 | public String readValue(PsiField field, String parcel) {
14 | return "this." + field.getName() + " = (char) " + parcel + ".readInt();";
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/DateSerializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
17 |
18 | import com.intellij.psi.PsiField;
19 | import org.apache.xmlbeans.impl.common.NameUtil;
20 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
21 |
22 | /**
23 | * Custom serializer for Date objects to simplify parceling
24 | *
25 | * @author Dallas Gutauckis [dallas@gutauckis.com]
26 | */
27 | public class DateSerializer implements TypeSerializer {
28 |
29 | private static final String NULL_VALUE = "-1";
30 |
31 | @Override
32 | public String writeValue(PsiField field, String parcel, String flags) {
33 | String fieldName = field.getName();
34 | return String.format("%s.writeLong(%s != null ? %s.getTime() : %s);", parcel, fieldName, fieldName, NULL_VALUE);
35 | }
36 |
37 | @Override
38 | public String readValue(PsiField field, String parcel) {
39 | String fieldName = field.getName();
40 | String tmpFieldName = NameUtil.upperCaseFirstLetter(fieldName);
41 | String formatted = String.format("long tmp%s = %s.readLong(); " +
42 | "this.%s = tmp%s == %s ? null : new java.util.Date(tmp%s);", tmpFieldName, parcel, fieldName, tmpFieldName, NULL_VALUE, tmpFieldName);
43 | return formatted;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/EnumerationSerializer.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
2 |
3 | import com.intellij.psi.PsiField;
4 | import org.apache.xmlbeans.impl.common.NameUtil;
5 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
6 |
7 | /**
8 | * Modified by Dallas Gutauckis [dallas@gutauckis.com]
9 | */
10 | public class EnumerationSerializer implements TypeSerializer {
11 | @Override
12 | public String writeValue(PsiField field, String parcel, String flags) {
13 | String fieldName = field.getName();
14 | return String.format("%s.writeInt(this.%s == null ? -1 : this.%s.ordinal());", parcel, fieldName, fieldName);
15 | }
16 |
17 | @Override
18 | public String readValue(PsiField field, String parcel) {
19 | String fieldName = field.getName();
20 | String tmpFieldName = NameUtil.upperCaseFirstLetter(fieldName);
21 | String format = "int tmp%s = %s.readInt();"
22 | + "this.%s = tmp%s == -1 ? null : %s.values()[tmp%s];";
23 | return String.format(format, tmpFieldName, parcel, fieldName, tmpFieldName, field.getType().getCanonicalText(), tmpFieldName);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/GenericListSerializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
17 |
18 | import com.intellij.psi.PsiField;
19 | import com.intellij.psi.PsiType;
20 | import com.intellij.psi.impl.source.PsiClassReferenceType;
21 | import org.jetbrains.annotations.NotNull;
22 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
23 |
24 | public class GenericListSerializer implements TypeSerializer {
25 |
26 | public static final String STRING_TYPE_NAME = "java.lang.String";
27 |
28 | @Override
29 | public String writeValue(PsiField field, String parcel, String flags) {
30 | String method = "writeList";
31 | if (getGenericType(field).equals(STRING_TYPE_NAME)) {
32 | method = "writeStringList";
33 | }
34 | return parcel + "." + method + "(this." + field.getName() + ");";
35 | }
36 |
37 | @Override
38 | public String readValue(PsiField field, String parcel) {
39 | String genericType = getGenericType(field);
40 |
41 | StringBuilder statement = new StringBuilder();
42 | if (genericType.equals(STRING_TYPE_NAME)) {
43 | statement.append("this.").append(field.getName()).append("=").append(parcel).append(".createStringArrayList();");
44 | } else {
45 | String listConstructor = !genericType.isEmpty()
46 | ? "new java.util.ArrayList<" + genericType + ">();"
47 | : "new java.util.ArrayList();";
48 |
49 | statement.append("this.").append(field.getName()).append(" = ").append(listConstructor);
50 | statement.append(parcel).append(".readList(this.").append(field.getName()).append(", List.class.getClassLoader());");
51 | }
52 |
53 | return statement.toString();
54 | }
55 |
56 | @NotNull
57 | private String getGenericType(PsiField field) {
58 | String genericType = "";
59 | try {
60 | PsiType[] parameters = ((PsiClassReferenceType) field.getType()).getParameters();
61 | if (parameters.length > 0) {
62 | genericType = parameters[0].getCanonicalText();
63 | }
64 | } catch (Exception ignored) {
65 | }
66 | return genericType;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/NullablePrimitivesSerializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
17 |
18 | import com.intellij.psi.PsiField;
19 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
20 |
21 | public class NullablePrimitivesSerializer implements TypeSerializer {
22 |
23 | private final String typeName;
24 |
25 | public NullablePrimitivesSerializer(String typeName) {
26 | this.typeName = typeName;
27 | }
28 |
29 | @Override
30 | public String writeValue(PsiField field, String parcel, String flags) {
31 | return parcel + ".writeValue(this." + field.getName() + ");";
32 | }
33 |
34 | @Override
35 | public String readValue(PsiField field, String parcel) {
36 | return "this." + field.getName() + " = (" + typeName + ")" + parcel + ".readValue(" + typeName + ".class.getClassLoader());";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/ParcelableArraySerializer.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
2 |
3 | import com.intellij.psi.PsiField;
4 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
5 |
6 | public class ParcelableArraySerializer implements TypeSerializer {
7 | @Override
8 | public String writeValue(PsiField field, String parcel, String flags) {
9 | return parcel + ".writeParcelableArray(this." + field.getName() + ", 0);";
10 | }
11 |
12 | @Override
13 | public String readValue(PsiField field, String parcel) {
14 | return "this." + field.getName() + " = (" + field.getType().getCanonicalText() + ")" + parcel + ".readParcelableArray(" + field.getType().getDeepComponentType().getCanonicalText() + ".class.getClassLoader());";
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/ParcelableListSerializer.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
2 |
3 | import com.intellij.psi.PsiField;
4 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
5 | import pl.charmas.parcelablegenerator.util.PsiUtils;
6 |
7 | /**
8 | * @author Dallas Gutauckis [dallas@gutauckis.com]
9 | * @author Michał Charmas [michal@charmas.pl]
10 | */
11 | public class ParcelableListSerializer implements TypeSerializer {
12 | @Override
13 | public String writeValue(PsiField field, String parcel, String flags) {
14 | return String.format("%s.writeTypedList(%s);", parcel, field.getName());
15 | }
16 |
17 | @Override
18 | public String readValue(PsiField field, String parcel) {
19 | String paramType = PsiUtils.getResolvedGenerics(field.getType()).get(0).getCanonicalText();
20 | return String.format("this.%s = %s.createTypedArrayList(%s.CREATOR);", field.getName(), parcel, paramType);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/ParcelableObjectSerializer.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
2 |
3 | import com.intellij.psi.PsiField;
4 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
5 |
6 | /**
7 | * Serializer for types implementing Parcelable
8 | *
9 | * @author Dallas Gutauckis [dallas@gutauckis.com]
10 | */
11 | public class ParcelableObjectSerializer implements TypeSerializer {
12 | @Override
13 | public String writeValue(PsiField field, String parcel, String flags) {
14 | return parcel + ".writeParcelable(this." + field.getName() + ", 0);";
15 | }
16 |
17 | @Override
18 | public String readValue(PsiField field, String parcel) {
19 | return "this." + field.getName() + " = " + parcel + ".readParcelable(" + field.getType().getCanonicalText() + ".class.getClassLoader());";
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/PrimitiveArraySerializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
17 |
18 | import com.intellij.psi.PsiField;
19 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
20 |
21 | public class PrimitiveArraySerializer implements TypeSerializer {
22 |
23 | private final String type;
24 |
25 | public PrimitiveArraySerializer(String type) {
26 | this.type = type;
27 | }
28 |
29 | @Override
30 | public String writeValue(PsiField field, String parcel, String flags) {
31 | return parcel + ".write" + type + "Array(this." + field.getName() + ");";
32 | }
33 |
34 | @Override
35 | public String readValue(PsiField field, String parcel) {
36 | return "this." + field.getName() + " = " + parcel + ".create" + type + "Array();";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/PrimitiveTypeSerializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
17 |
18 | import com.intellij.psi.PsiField;
19 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
20 |
21 | public class PrimitiveTypeSerializer implements TypeSerializer {
22 |
23 | private final String typeName;
24 |
25 | public PrimitiveTypeSerializer(String typeName) {
26 | this.typeName = typeName;
27 | }
28 |
29 | @Override
30 | public String writeValue(PsiField field, String parcel, String flags) {
31 | return parcel + ".write" + typeName + "(this." + field.getName() + ");";
32 | }
33 |
34 | @Override
35 | public String readValue(PsiField field, String parcel) {
36 | return "this." + field.getName() + " = " + parcel + ".read" + typeName + "();";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/SerializableObjectSerializer.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
2 |
3 | import com.intellij.psi.PsiField;
4 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
5 |
6 | /**
7 | * Modified by Dallas Gutauckis [dallas@gutauckis.com]
8 | */
9 | public class SerializableObjectSerializer implements TypeSerializer {
10 | @Override
11 | public String writeValue(PsiField field, String parcel, String flags) {
12 | return parcel + ".writeSerializable(this." + field.getName() + ");";
13 | }
14 |
15 | @Override
16 | public String readValue(PsiField field, String parcel) {
17 | return "this." + field.getName() + " = (" + field.getType().getCanonicalText() + ") " + parcel + ".readSerializable();";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/typeserializers/serializers/UnknownTypeSerializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pl.charmas.parcelablegenerator.typeserializers.serializers;
17 |
18 | import com.intellij.psi.PsiField;
19 | import pl.charmas.parcelablegenerator.typeserializers.TypeSerializer;
20 |
21 | public class UnknownTypeSerializer implements TypeSerializer {
22 |
23 | private final String typeName;
24 |
25 | public UnknownTypeSerializer(String typeName) {
26 | this.typeName = typeName;
27 | }
28 |
29 | @Override
30 | public String writeValue(PsiField field, String parcel, String flags) {
31 | return parcel + ".writeParcelable(this." + field.getName() + ", " + flags + ");";
32 | }
33 |
34 | @Override
35 | public String readValue(PsiField field, String parcel) {
36 | return "this." + field.getName() + " = " + parcel + ".readParcelable(" + this.typeName + ".class.getClassLoader());";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/android_parcelable_intellij_plugin/pl/charmas/parcelablegenerator/util/PsiUtils.java:
--------------------------------------------------------------------------------
1 | package pl.charmas.parcelablegenerator.util;
2 |
3 | import com.intellij.psi.PsiClass;
4 | import com.intellij.psi.PsiClassType;
5 | import com.intellij.psi.PsiType;
6 | import com.intellij.psi.util.PsiTypesUtil;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | /**
12 | * Utils for introspecting Psi* stuff
13 | *
14 | * @author Dallas Gutauckis [dallas@gutauckis.com]
15 | */
16 | final public class PsiUtils {
17 | private PsiUtils() {
18 | }
19 |
20 | /**
21 | * Resolves generics on the given type and returns them (if any) or null if there are none
22 | *
23 | * @param type
24 | * @return
25 | */
26 | public static List getResolvedGenerics(PsiType type) {
27 | List psiTypes = null;
28 |
29 | if (type instanceof PsiClassType) {
30 | PsiClassType pct = (PsiClassType) type;
31 | psiTypes = new ArrayList(pct.resolveGenerics().getSubstitutor().getSubstitutionMap().values());
32 | }
33 |
34 | return psiTypes;
35 | }
36 |
37 | public static boolean isOfType(PsiType type, String canonicalName) {
38 | if (type.getCanonicalText().equals(canonicalName)) {
39 | return true;
40 | }
41 |
42 | if (getNonGenericType(type).equals(canonicalName)) {
43 | return true;
44 | }
45 |
46 | for (PsiType iterType : type.getSuperTypes()) {
47 | if (isOfType(iterType, canonicalName)) {
48 | return true;
49 | }
50 | }
51 |
52 | return false;
53 | }
54 |
55 | public static String getNonGenericType(PsiType type) {
56 | if (type instanceof PsiClassType) {
57 | PsiClassType pct = (PsiClassType) type;
58 | return pct.resolve().getQualifiedName();
59 | }
60 |
61 | return type.getCanonicalText();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/android_selector_chapek/Constants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Inmite s.r.o. (www.inmite.eu).
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import java.util.HashMap;
18 | import java.util.regex.Pattern;
19 |
20 | /**
21 | * Constants for various stuff used in whole plugin.
22 | * @author David Vávra (david@inmite.eu)
23 | */
24 | public class Constants {
25 | public static final String NORMAL = "_normal";
26 | public static final String FOCUSED = "_focused";
27 | public static final String PRESSED = "_pressed";
28 | public static final String SELECTED = "_selected";
29 | public static final String CHECKED = "_checked";
30 | public static final String DISABLED = "_disabled";
31 | public static final String HOVERED = "_hovered";
32 | public static final String CHECKABLE = "_checkable";
33 | public static final String ACTIVATED = "_activated";
34 | public static final String WINDOW_FOCUSED = "_windowfocused";
35 | public static String[] SUFFIXES = new String[]{NORMAL, PRESSED, FOCUSED, SELECTED, CHECKED, DISABLED, HOVERED, CHECKABLE, ACTIVATED, WINDOW_FOCUSED};
36 | public static Pattern VALID_FOLDER_PATTERN = Pattern.compile("^drawable(-[a-zA-Z0-9]+)*$");
37 | public static String EXPORT_FOLDER = "drawable";
38 | public static HashMap sMapping;
39 |
40 | static {
41 | // mapping from file suffixes into android attributes and their default values
42 | sMapping = new HashMap();
43 | sMapping.put(FOCUSED, new State("state_focused", false));
44 | sMapping.put(PRESSED, new State("state_pressed", false));
45 | sMapping.put(SELECTED, new State("state_selected", false));
46 | sMapping.put(CHECKED, new State("state_checked", false));
47 | sMapping.put(DISABLED, new State("state_enabled", true));
48 | sMapping.put(HOVERED, new State("state_hovered", false));
49 | sMapping.put(CHECKABLE, new State("state_checkable", false));
50 | sMapping.put(ACTIVATED, new State("state_activated", false));
51 | sMapping.put(WINDOW_FOCUSED, new State("state_window_focused", false));
52 | }
53 |
54 | static class State {
55 | public String attributeName;
56 | public boolean defaultValue;
57 |
58 | State(String attributeName, boolean defaultValue) {
59 | this.attributeName = attributeName;
60 | this.defaultValue = defaultValue;
61 | }
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/android_selector_chapek/SelectorChapekAction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Inmite s.r.o. (www.inmite.eu).
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import com.intellij.openapi.actionSystem.AnAction;
18 | import com.intellij.openapi.actionSystem.AnActionEvent;
19 | import com.intellij.openapi.actionSystem.DataKeys;
20 | import com.intellij.openapi.ui.MessageType;
21 | import com.intellij.openapi.ui.popup.Balloon;
22 | import com.intellij.openapi.ui.popup.JBPopupFactory;
23 | import com.intellij.openapi.vfs.VirtualFile;
24 | import com.intellij.openapi.wm.StatusBar;
25 | import com.intellij.openapi.wm.WindowManager;
26 | import com.intellij.ui.awt.RelativePoint;
27 | import utils.Log;
28 |
29 | import java.util.regex.Matcher;
30 |
31 | /**
32 | * Action which is launched when user clicks the menu item. It handles related UI-stuff.
33 | *
34 | * @author David Vávra (david@inmite.eu)
35 | */
36 | public class SelectorChapekAction extends AnAction {
37 |
38 | @Override
39 | public void actionPerformed(AnActionEvent e) {
40 | Log.d("---- Start - menu item clicked ----");
41 | VirtualFile selectedFile = DataKeys.VIRTUAL_FILE.getData(e.getDataContext());
42 | if (isCorrectFolderSelected(selectedFile)) {
43 | new SelectorDetector(e.getProject()).detectAndCreateSelectors(selectedFile);
44 | showInfoDialog("Selectors were generated into 'drawable' folder", e);
45 | } else {
46 | if (selectedFile != null) {
47 | showErrorDialog("You need to select folder with image resources, for example 'drawables-xhdpi' " +
48 | "" + selectedFile.getName(), e);
49 | }
50 | }
51 | }
52 |
53 | @Override
54 | public void update(AnActionEvent e) {
55 | VirtualFile selectedFile = DataKeys.VIRTUAL_FILE.getData(e.getDataContext());
56 | e.getPresentation().setEnabled(isCorrectFolderSelected(selectedFile));
57 | }
58 |
59 | private boolean isCorrectFolderSelected(VirtualFile selectedFile) {
60 | if (selectedFile != null && selectedFile.isDirectory()) {
61 | Matcher matcher = Constants.VALID_FOLDER_PATTERN.matcher(selectedFile.getName());
62 | if (matcher.matches()) {
63 | return true;
64 | }
65 | }
66 | return false;
67 | }
68 |
69 | private void showInfoDialog(String text, AnActionEvent e) {
70 | StatusBar statusBar = WindowManager.getInstance().getStatusBar(DataKeys.PROJECT.getData(e.getDataContext()));
71 |
72 | if (statusBar != null) {
73 | JBPopupFactory.getInstance()
74 | .createHtmlTextBalloonBuilder(text, MessageType.INFO, null)
75 | .setFadeoutTime(10000)
76 | .createBalloon()
77 | .show(RelativePoint.getCenterOf(statusBar.getComponent()),
78 | Balloon.Position.atRight);
79 | }
80 | }
81 |
82 | private void showErrorDialog(String text, AnActionEvent e) {
83 | StatusBar statusBar = WindowManager.getInstance().getStatusBar(DataKeys.PROJECT.getData(e.getDataContext()
84 | ));
85 |
86 | if (statusBar != null) {
87 | JBPopupFactory.getInstance()
88 | .createHtmlTextBalloonBuilder(text, MessageType.ERROR, null)
89 | .setFadeoutTime(10000)
90 | .createBalloon()
91 | .show(RelativePoint.getCenterOf(statusBar.getComponent()),
92 | Balloon.Position.atRight);
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/android_selector_chapek/SelectorGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Inmite s.r.o. (www.inmite.eu).
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import com.intellij.openapi.vfs.VirtualFile;
18 | import nu.xom.Attribute;
19 | import nu.xom.Document;
20 | import nu.xom.Element;
21 | import nu.xom.Serializer;
22 | import utils.Log;
23 |
24 | import java.io.IOException;
25 | import java.io.OutputStream;
26 | import java.util.ArrayList;
27 | import java.util.List;
28 |
29 | /**
30 | * Generates selectors into XML.
31 | *
32 | * @author David Vávra (david@inmite.eu)
33 | */
34 | public class SelectorGenerator {
35 |
36 | private static final String SCHEMA = "http://schemas.android.com/apk/res/android";
37 | private static final String NS = "android";
38 |
39 | public static void generate(VirtualFile newFile, List detectorResults) {
40 | Log.d("generating XML:");
41 | Element root = new Element("selector");
42 | root.addNamespaceDeclaration(NS, SCHEMA);
43 | List allStatesWithoutNormal = new ArrayList();
44 | for (SelectorDetector.Result result : detectorResults) {
45 | for (String state : result.states) {
46 | if (!state.equals(Constants.NORMAL) && !allStatesWithoutNormal.contains(state)) {
47 | allStatesWithoutNormal.add(state);
48 | }
49 | }
50 | }
51 | for (SelectorDetector.Result result : detectorResults) {
52 | Log.d("fileName=" + result.drawableName + ", states:" + result.states);
53 | Element item = new Element("item");
54 | Attribute attribute = new Attribute("drawable", "@drawable/" + result.drawableName);
55 | attribute.setNamespace(NS, SCHEMA);
56 | item.addAttribute(attribute);
57 | for (String state : allStatesWithoutNormal) {
58 | boolean defaultValue = Constants.sMapping.get(state).defaultValue;
59 | addState(item, Constants.sMapping.get(state).attributeName, result.states.contains(state)
60 | ? (!defaultValue) : defaultValue);
61 | }
62 | Log.d("row=" + item.toXML());
63 | root.appendChild(item);
64 | }
65 | Document doc = new Document(root);
66 | OutputStream os = null;
67 | try {
68 | os = newFile.getOutputStream(null);
69 | Serializer serializer = new Serializer(os);
70 | serializer.setIndent(4);
71 | serializer.write(doc);
72 | } catch (IOException e) {
73 | Log.e(e);
74 | } finally {
75 | if (os != null) {
76 | try {
77 | os.close();
78 | } catch (IOException e) {
79 | Log.e(e);
80 | }
81 | }
82 | }
83 |
84 | }
85 |
86 | private static void addState(Element item, String state, boolean value) {
87 | Attribute attribute = new Attribute(state, String.valueOf(value));
88 | attribute.setNamespace(NS, SCHEMA);
89 | item.addAttribute(attribute);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/android_selector_chapek/utils/Log.java:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | /**
4 | * Copyright (c) 2013, Inmite s.r.o. (www.inmite.eu). All rights reserved.
5 | *
6 | * This source code can be used only for purposes specified by the given license contract
7 | * signed by the rightful deputy of Inmite s.r.o. This source code can be used only
8 | * by the owner of the license.
9 | *
10 | * Any disputes arising in respect of this agreement (license) shall be brought
11 | * before the Municipal Court of Prague.
12 | */
13 | public class Log {
14 | public static final boolean DEBUG = false;
15 |
16 | public static void d(String output) {
17 | if (DEBUG) {
18 | System.out.println(output);
19 | }
20 | }
21 |
22 | public static void e(Exception e) {
23 | e.printStackTrace();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/android_selector_chapek/utils/RunnableHelper.java:
--------------------------------------------------------------------------------
1 | package utils;/*
2 | * Copyright 2013 Inmite s.r.o. (www.inmite.eu).
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of 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,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import com.intellij.openapi.application.ApplicationManager;
17 | import com.intellij.openapi.command.CommandProcessor;
18 | import com.intellij.openapi.project.Project;
19 |
20 | /**
21 | * Helper class for launching filesystem write operations on background.
22 | * @author David Vávra (david@inmite.eu)
23 | */
24 | public class RunnableHelper
25 | {
26 | public static void runReadCommand(Project project, Runnable cmd)
27 | {
28 | CommandProcessor.getInstance().executeCommand(project, new ReadAction(cmd), "Foo", "Bar");
29 | }
30 |
31 | public static void runWriteCommand(Project project, Runnable cmd)
32 | {
33 | CommandProcessor.getInstance().executeCommand(project, new WriteAction(cmd), "Foo", "Bar");
34 | }
35 |
36 | static class ReadAction implements Runnable
37 | {
38 | ReadAction(Runnable cmd)
39 | {
40 | this.cmd = cmd;
41 | }
42 |
43 | public void run()
44 | {
45 | ApplicationManager.getApplication().runReadAction(cmd);
46 | }
47 |
48 | Runnable cmd;
49 | }
50 |
51 | static class WriteAction implements Runnable
52 | {
53 | WriteAction(Runnable cmd)
54 | {
55 | this.cmd = cmd;
56 | }
57 |
58 | public void run()
59 | {
60 | ApplicationManager.getApplication().runWriteAction(cmd);
61 | }
62 |
63 | Runnable cmd;
64 | }
65 |
66 | private RunnableHelper() {}
67 | }
68 |
--------------------------------------------------------------------------------
/folding_plugin/com/dd/ComposeAction.java:
--------------------------------------------------------------------------------
1 | package com.dd;
2 |
3 | import com.intellij.ide.projectView.ProjectView;
4 | import com.intellij.openapi.actionSystem.AnAction;
5 | import com.intellij.openapi.actionSystem.AnActionEvent;
6 | import com.intellij.openapi.actionSystem.CommonDataKeys;
7 | import com.intellij.openapi.project.Project;
8 | import com.intellij.psi.PsiDirectory;
9 |
10 | public class ComposeAction extends AnAction {
11 |
12 | private static final String DECOMPOSE = "Ungroup";
13 | private static final String COMPOSE = "Group";
14 |
15 | @Override
16 | public void actionPerformed(AnActionEvent actionEvent) {
17 | Object nav = actionEvent.getData(CommonDataKeys.NAVIGATABLE);
18 | if (nav instanceof PsiDirectory) {
19 | PsiDirectory directory = (PsiDirectory) nav;
20 |
21 | String path = directory.getVirtualFile().getPath();
22 |
23 | if (SettingsManager.isComposed(path)) {
24 | SettingsManager.removeComposedFolder(path);
25 | } else {
26 | SettingsManager.addComposedFolder(path);
27 | }
28 |
29 | Project project = actionEvent.getData(CommonDataKeys.PROJECT);
30 | if (project != null) {
31 | ProjectView.getInstance(project).refresh();
32 | }
33 | }
34 | }
35 |
36 | @Override
37 | public void update(AnActionEvent actionEvent) {
38 | boolean enabledAndVisible = false;
39 | Project project = actionEvent.getData(CommonDataKeys.PROJECT);
40 | if (project != null) {
41 | Object nav = actionEvent.getData(CommonDataKeys.NAVIGATABLE);
42 |
43 | if (nav instanceof PsiDirectory) {
44 | PsiDirectory directory = (PsiDirectory) nav;
45 |
46 | String path = directory.getVirtualFile().getPath();
47 |
48 | if (SettingsManager.isComposed(path)) {
49 | actionEvent.getPresentation().setText(DECOMPOSE);
50 | } else {
51 | actionEvent.getPresentation().setText(COMPOSE);
52 | }
53 |
54 | enabledAndVisible = true;
55 | }
56 | }
57 | actionEvent.getPresentation().setEnabledAndVisible(enabledAndVisible);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/folding_plugin/com/dd/DirectoryNode.java:
--------------------------------------------------------------------------------
1 | package com.dd;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.ide.projectView.PresentationData;
5 | import com.intellij.ide.projectView.ProjectViewNode;
6 | import com.intellij.ide.projectView.ViewSettings;
7 | import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
8 | import com.intellij.ide.util.PropertiesComponent;
9 | import com.intellij.ide.util.treeView.AbstractTreeNode;
10 | import com.intellij.openapi.project.Project;
11 | import com.intellij.openapi.vfs.VirtualFile;
12 | import com.intellij.psi.PsiFile;
13 | import org.jetbrains.annotations.NotNull;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | public class DirectoryNode extends ProjectViewNode {
19 |
20 | private final String mName;
21 | private List mChildNodeList;
22 |
23 | protected DirectoryNode(Project project, ViewSettings viewSettings, PsiFile directory, String name) {
24 | super(project, directory, viewSettings);
25 | mName = name;
26 | mChildNodeList = new ArrayList();
27 | }
28 |
29 | @Override
30 | public boolean contains(@NotNull VirtualFile file) {
31 | for (final AbstractTreeNode childNode : mChildNodeList) {
32 | ProjectViewNode treeNode = (ProjectViewNode) childNode;
33 | if (treeNode.contains(file)) {
34 | return true;
35 | }
36 | }
37 | return false;
38 | }
39 |
40 | public void addChildren(AbstractTreeNode treeNode) {
41 | mChildNodeList.add(treeNode);
42 | }
43 |
44 | public void addAllChildren(List treeNodeList) {
45 | mChildNodeList.addAll(treeNodeList);
46 | }
47 |
48 | @NotNull
49 | @Override
50 | public List getChildren() {
51 | if (PropertiesComponent.getInstance().getBoolean(SettingConfigurable.PREFIX_HIDE, false)) {
52 | final ArrayList abstractTreeNodes = new ArrayList<>();
53 | for (AbstractTreeNode fileNode : mChildNodeList) {
54 | PsiFile psiFile = (PsiFile) fileNode.getValue();
55 | final ViewSettings settings = ((PsiFileNode) fileNode).getSettings();
56 | String shortName = psiFile.getName().substring(mName.length());
57 | final int beginIndex = shortName.indexOf(ProjectStructureProvider.COMPOSE_BY_CHAR);
58 | if (beginIndex != -1) {
59 | shortName = shortName.substring(beginIndex + 1);
60 | }
61 | abstractTreeNodes.add(new FoldingNode(fileNode.getProject(), psiFile, settings, shortName));
62 | }
63 | return abstractTreeNodes;
64 | } else {
65 | return mChildNodeList;
66 | }
67 | }
68 |
69 |
70 | @Override
71 | protected void update(PresentationData presentation) {
72 | presentation.setPresentableText(mName);
73 | presentation.setIcon(AllIcons.Nodes.Folder);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/folding_plugin/com/dd/FoldingNode.java:
--------------------------------------------------------------------------------
1 | package com.dd;
2 |
3 | import com.intellij.ide.projectView.PresentationData;
4 | import com.intellij.ide.projectView.ViewSettings;
5 | import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
6 | import com.intellij.openapi.project.Project;
7 | import com.intellij.psi.PsiFile;
8 |
9 | class FoldingNode extends PsiFileNode {
10 | private String mName;
11 |
12 | public FoldingNode(Project project, PsiFile value, ViewSettings viewSettings, String shortName) {
13 | super(project, value, viewSettings);
14 | mName = shortName;
15 | }
16 |
17 | @Override
18 | protected void updateImpl(PresentationData presentationData) {
19 | super.updateImpl(presentationData);
20 |
21 | presentationData.setPresentableText(mName);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/folding_plugin/com/dd/SettingConfigurable.form:
--------------------------------------------------------------------------------
1 |
2 |
49 |
--------------------------------------------------------------------------------
/folding_plugin/com/dd/SettingConfigurable.java:
--------------------------------------------------------------------------------
1 | package com.dd;
2 |
3 | import com.intellij.ide.projectView.ProjectView;
4 | import com.intellij.ide.util.PropertiesComponent;
5 | import com.intellij.openapi.options.Configurable;
6 | import com.intellij.openapi.options.ConfigurationException;
7 | import com.intellij.openapi.project.Project;
8 | import org.jetbrains.annotations.Nls;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | import javax.swing.*;
12 | import javax.swing.event.DocumentEvent;
13 | import javax.swing.event.DocumentListener;
14 | import java.awt.event.ActionEvent;
15 | import java.awt.event.ActionListener;
16 |
17 | /**
18 | *
19 | * Created by skyrylyuk on 10/15/15.
20 | */
21 | public class SettingConfigurable implements Configurable {
22 | public static final String PREFIX_PATTERN = "folding_plugin_prefix_pattern";
23 | public static final String PREFIX_CUSTOM_USE = "folding_plugin_prefix_custom_use";
24 | public static final String PREFIX_HIDE = "folding_plugin_prefix_hide";
25 |
26 | public static final String DEFAULT_PATTERN = "[^_]{1,}(?=_)";
27 | public static final String DEFAULT_PATTERN_DOUBLE = "[^_]{1,}_[^_]{1,}(?=_)";
28 |
29 | private JPanel mPanel;
30 | private JCheckBox useCustomPatternCheckBox;
31 | private JTextField customPattern;
32 | private JCheckBox hideFoldingPrefix;
33 | private boolean isModified = false;
34 |
35 | @Nls
36 | @Override
37 | public String getDisplayName() {
38 | return "Android Folding";
39 | }
40 |
41 | @Nullable
42 | @Override
43 | public String getHelpTopic() {
44 | return "null:";
45 | }
46 |
47 | @Nullable
48 | @Override
49 | public JComponent createComponent() {
50 |
51 | useCustomPatternCheckBox.addActionListener(new ActionListener() {
52 | public void actionPerformed(ActionEvent actionEvent) {
53 | boolean selected = getCheckBoxStatus(actionEvent);
54 |
55 | customPattern.setEnabled(selected);
56 | isModified = true;
57 | }
58 | });
59 |
60 | customPattern.getDocument().addDocumentListener(new DocumentListener() {
61 | @Override
62 | public void insertUpdate(DocumentEvent e) {
63 | isModified = true;
64 | }
65 |
66 | @Override
67 | public void removeUpdate(DocumentEvent e) {
68 | isModified = true;
69 | }
70 |
71 | @Override
72 | public void changedUpdate(DocumentEvent e) {
73 | isModified = true;
74 | }
75 | });
76 |
77 | hideFoldingPrefix.addActionListener(new ActionListener() {
78 | public void actionPerformed(ActionEvent actionEvent) {
79 | isModified = true;
80 | }
81 | });
82 |
83 | reset();
84 |
85 | return mPanel;
86 | }
87 |
88 | private boolean getCheckBoxStatus(ActionEvent actionEvent) {
89 | AbstractButton abstractButton = (AbstractButton) actionEvent.getSource();
90 | return abstractButton.getModel().isSelected();
91 | }
92 |
93 |
94 | @Override
95 | public boolean isModified() {
96 |
97 | return isModified;
98 | }
99 |
100 | @Override
101 | public void apply() throws ConfigurationException {
102 | PropertiesComponent.getInstance().setValue(PREFIX_CUSTOM_USE, Boolean.valueOf(useCustomPatternCheckBox.isSelected()).toString());
103 | PropertiesComponent.getInstance().setValue(PREFIX_PATTERN, customPattern.getText());
104 | PropertiesComponent.getInstance().setValue(PREFIX_HIDE, Boolean.valueOf(hideFoldingPrefix.isSelected()).toString());
105 |
106 | if (isModified) {
107 | Project currentProject = Utils.getCurrentProject();
108 |
109 | if (currentProject != null) {
110 | ProjectView.getInstance(currentProject).refresh();
111 | }
112 | }
113 |
114 | isModified = false;
115 | }
116 |
117 | @Override
118 | public void reset() {
119 | final boolean customPrefix = PropertiesComponent.getInstance().getBoolean(PREFIX_CUSTOM_USE, false);
120 | useCustomPatternCheckBox.setSelected(customPrefix);
121 | customPattern.setEnabled(customPrefix);
122 | customPattern.setText(PropertiesComponent.getInstance().getValue(PREFIX_PATTERN, DEFAULT_PATTERN_DOUBLE));
123 | hideFoldingPrefix.getModel().setSelected(PropertiesComponent.getInstance().getBoolean(PREFIX_HIDE, false));
124 | }
125 |
126 | @Override
127 | public void disposeUIResources() {
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/folding_plugin/com/dd/Settings.java:
--------------------------------------------------------------------------------
1 | package com.dd;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | public class Settings {
10 |
11 | @SerializedName("DecomposedFolders")
12 | private List mComposedFolders;
13 |
14 | @NotNull
15 | public List getComposedFolders() {
16 | if(mComposedFolders == null) {
17 | mComposedFolders = new ArrayList();
18 | }
19 |
20 | return mComposedFolders;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/folding_plugin/com/dd/SettingsManager.java:
--------------------------------------------------------------------------------
1 | package com.dd;
2 |
3 | import com.google.gson.Gson;
4 | import com.intellij.ide.util.PropertiesComponent;
5 | import com.intellij.openapi.project.Project;
6 | import org.jetbrains.annotations.NotNull;
7 |
8 | public class SettingsManager {
9 |
10 | private static final String KEY_SETTINGS = "KEY_COMPOSED_FOLDERS";
11 |
12 | public static boolean isComposed(@NotNull String folder) {
13 | boolean isFoldingOn = false;
14 | Project currentProject = Utils.getCurrentProject();
15 | if (currentProject != null) {
16 | Settings settings = getSettings(currentProject);
17 | isFoldingOn = settings.getComposedFolders().contains(folder);
18 |
19 | }
20 |
21 | return isFoldingOn;
22 | }
23 |
24 | public static void addComposedFolder(@NotNull String folder) {
25 | Project currentProject = Utils.getCurrentProject();
26 | if (currentProject != null) {
27 | Gson gson = new Gson();
28 | Settings settings = getSettings(currentProject);
29 | settings.getComposedFolders().add(folder);
30 |
31 | PropertiesComponent.getInstance(currentProject).setValue(KEY_SETTINGS, gson.toJson(settings));
32 | }
33 |
34 | }
35 |
36 | public static void removeComposedFolder(@NotNull String folder) {
37 | Project currentProject = Utils.getCurrentProject();
38 | if (currentProject != null) {
39 | Gson gson = new Gson();
40 | Settings settings = getSettings(currentProject);
41 | settings.getComposedFolders().remove(folder);
42 |
43 | PropertiesComponent.getInstance(currentProject).setValue(KEY_SETTINGS, gson.toJson(settings));
44 | }
45 | }
46 |
47 | @NotNull
48 | private static Settings getSettings(@NotNull Project currentProject) {
49 | Gson gson = new Gson();
50 | String json = PropertiesComponent.getInstance(currentProject).getValue(KEY_SETTINGS);
51 | Settings settings;
52 | if (json == null) {
53 | settings = new Settings();
54 | } else {
55 | settings = gson.fromJson(json, Settings.class);
56 | }
57 |
58 | return settings;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/folding_plugin/com/dd/Utils.java:
--------------------------------------------------------------------------------
1 | package com.dd;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.openapi.project.ProjectManager;
5 | import org.jetbrains.annotations.Nullable;
6 |
7 | public final class Utils {
8 |
9 | @Nullable
10 | public static Project getCurrentProject() {
11 | Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
12 | return openProjects.length > 0 ? openProjects[0] : null;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/libs/android-codegenerator-library-1.0.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/android-codegenerator-library-1.0.5.jar
--------------------------------------------------------------------------------
/libs/commons-io-2.4-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/commons-io-2.4-sources.jar
--------------------------------------------------------------------------------
/libs/commons-io-2.4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/commons-io-2.4.jar
--------------------------------------------------------------------------------
/libs/commons-lang3-3.3.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/commons-lang3-3.3.2.jar
--------------------------------------------------------------------------------
/libs/commons-math3-3.4.1-src.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/commons-math3-3.4.1-src.zip
--------------------------------------------------------------------------------
/libs/commons-math3-3.4.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/commons-math3-3.4.1.jar
--------------------------------------------------------------------------------
/libs/gson-2.3.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/gson-2.3.1.jar
--------------------------------------------------------------------------------
/libs/guava-18.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/guava-18.0.jar
--------------------------------------------------------------------------------
/libs/imgscalr-lib-4.2-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/imgscalr-lib-4.2-sources.jar
--------------------------------------------------------------------------------
/libs/imgscalr-lib-4.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/imgscalr-lib-4.2.jar
--------------------------------------------------------------------------------
/libs/thumbnailator-0.4.8-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/thumbnailator-0.4.8-sources.jar
--------------------------------------------------------------------------------
/libs/thumbnailator-0.4.8.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/thumbnailator-0.4.8.jar
--------------------------------------------------------------------------------
/libs/xom-1.2.10.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/b2b2244424/AndroidStudioSuperPlugin/68ed824ad99b22deb7b0133b7e6702329109585f/libs/xom-1.2.10.jar
--------------------------------------------------------------------------------
/lifecycle_sorter/Action/SortAction.java:
--------------------------------------------------------------------------------
1 | package Action;
2 |
3 | import com.intellij.openapi.actionSystem.*;
4 | import com.intellij.openapi.command.WriteCommandAction;
5 | import com.intellij.openapi.editor.Editor;
6 | import com.intellij.psi.*;
7 | import com.intellij.psi.util.PsiTreeUtil;
8 | import Sort.Sorter;
9 | /**
10 | * Created by armand on 3/1/15.
11 | */
12 | public class SortAction extends AnAction {
13 |
14 | protected Sorter.SortPosition mSortPosition;
15 |
16 | @Override
17 | public void actionPerformed(AnActionEvent e) {
18 |
19 | PsiClass psiClass = getPsiClassFromContext(e);
20 |
21 | if (psiClass != null) {
22 | sortLifecycleMethods(psiClass);
23 | }
24 |
25 | }
26 |
27 | private void sortLifecycleMethods(final PsiClass psiClass) {
28 | new WriteCommandAction.Simple(psiClass.getProject(), psiClass.getContainingFile()) {
29 | @Override
30 | protected void run() throws Throwable {
31 | new Sorter(psiClass, mSortPosition).sort();
32 | }
33 | }.execute();
34 |
35 |
36 | }
37 |
38 |
39 | /**
40 | * @param e the action event that occurred
41 | * @return The PSIClass object based on which class your mouse cursor was in
42 | */
43 | protected PsiClass getPsiClassFromContext(AnActionEvent e) {
44 | PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);
45 | Editor editor = e.getData(PlatformDataKeys.EDITOR);
46 |
47 | if (psiFile == null || editor == null) {
48 | return null;
49 | }
50 |
51 | int offSet = editor.getCaretModel().getOffset();
52 | PsiElement elementAt = psiFile.findElementAt(offSet);
53 | PsiClass psiClass = PsiTreeUtil.getParentOfType(elementAt, PsiClass.class);
54 |
55 | return psiClass;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/lifecycle_sorter/Action/SortEndAction.java:
--------------------------------------------------------------------------------
1 | package Action;
2 |
3 | import Sort.Sorter;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 |
6 | /**
7 | * Created by akopian on 5/24/15.
8 | */
9 | public class SortEndAction extends SortAction {
10 |
11 | @Override
12 | public void actionPerformed(AnActionEvent e) {
13 | mSortPosition = Sorter.SortPosition.END;
14 | super.actionPerformed(e);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lifecycle_sorter/Action/SortStartAction.java:
--------------------------------------------------------------------------------
1 | package Action;
2 |
3 | import Sort.Sorter;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 |
6 | /**
7 | * Created by akopian on 5/24/15.
8 | */
9 | public class SortStartAction extends SortAction {
10 |
11 | @Override
12 | public void actionPerformed(AnActionEvent e) {
13 | mSortPosition = Sorter.SortPosition.START;
14 | super.actionPerformed(e);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lifecycle_sorter/Lifecycle/ActivityLifecycle.java:
--------------------------------------------------------------------------------
1 | package Lifecycle;
2 |
3 | import com.intellij.psi.PsiMethod;
4 |
5 | import java.util.*;
6 |
7 | /**
8 | * Created by armand on 3/1/15.
9 | */
10 | public class ActivityLifecycle extends Lifecycle {
11 |
12 | /**
13 | * Activity Lifecycle method names
14 | */
15 | private static final String ON_CREATE = "onCreate";
16 | private static final String ON_RESTART = "onRestart";
17 | private static final String ON_START = "onStart";
18 | private static final String ON_RESUME = "onResume";
19 | private static final String ON_PAUSE = "onPause";
20 | private static final String ON_STOP = "onStop";
21 | private static final String ON_DESTROY = "onDestroy";
22 |
23 |
24 | /**
25 | * The ordering of the Activity Lifecycle methods
26 | */
27 | private static final List ACTIVITY_LIFECYCLE_METHODS = new ArrayList();
28 |
29 | static {
30 | ACTIVITY_LIFECYCLE_METHODS.add(ON_CREATE);
31 | ACTIVITY_LIFECYCLE_METHODS.add(ON_RESTART);
32 | ACTIVITY_LIFECYCLE_METHODS.add(ON_START);
33 | ACTIVITY_LIFECYCLE_METHODS.add(ON_RESUME);
34 | ACTIVITY_LIFECYCLE_METHODS.add(ON_PAUSE);
35 | ACTIVITY_LIFECYCLE_METHODS.add(ON_STOP);
36 | ACTIVITY_LIFECYCLE_METHODS.add(ON_DESTROY);
37 | }
38 |
39 |
40 | public ActivityLifecycle(Map methods) {
41 | super(methods);
42 | mLifecycleOrdering = ACTIVITY_LIFECYCLE_METHODS;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/lifecycle_sorter/Lifecycle/FragmentLifecycle.java:
--------------------------------------------------------------------------------
1 | package Lifecycle;
2 |
3 | import com.intellij.psi.PsiMethod;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | /**
10 | * Created by armand on 3/29/15.
11 | */
12 | public class FragmentLifecycle extends Lifecycle {
13 |
14 | /**
15 | * Fragment Lifecycle method names
16 | */
17 | private static final String ON_ATTACH = "onAttach";
18 | private static final String ON_CREATE = "onCreate";
19 | private static final String ON_CREATE_VIEW = "onCreateView";
20 | private static final String ON_VIEW_CREATED = "onViewCreated";
21 | private static final String ON_ACTIVITY_CREATED = "onActivityCreated";
22 | private static final String ON_VIEW_STATE_RESTORED = "onViewStateRestored";
23 | private static final String ON_START = "onStart";
24 | private static final String ON_RESUME = "onResume";
25 | private static final String ON_PAUSE = "onPause";
26 | private static final String ON_STOP = "onStop";
27 | private static final String ON_DESTROY_VIEW = "onDestroyView";
28 | private static final String ON_DESTROY = "onDestroy";
29 | private static final String ON_DETACH = "onDetach";
30 |
31 |
32 | /**
33 | * The ordering of the Fragment Lifecycle methods
34 | */
35 | private static final List FRAGMENT_LIFECYCLE_METHODS = new ArrayList();
36 |
37 | static {
38 | FRAGMENT_LIFECYCLE_METHODS.add(ON_ATTACH);
39 | FRAGMENT_LIFECYCLE_METHODS.add(ON_CREATE);
40 | FRAGMENT_LIFECYCLE_METHODS.add(ON_CREATE_VIEW);
41 | FRAGMENT_LIFECYCLE_METHODS.add(ON_VIEW_CREATED);
42 | FRAGMENT_LIFECYCLE_METHODS.add(ON_ACTIVITY_CREATED);
43 | FRAGMENT_LIFECYCLE_METHODS.add(ON_VIEW_STATE_RESTORED);
44 | FRAGMENT_LIFECYCLE_METHODS.add(ON_START);
45 | FRAGMENT_LIFECYCLE_METHODS.add(ON_RESUME);
46 | FRAGMENT_LIFECYCLE_METHODS.add(ON_PAUSE);
47 | FRAGMENT_LIFECYCLE_METHODS.add(ON_STOP);
48 | FRAGMENT_LIFECYCLE_METHODS.add(ON_DESTROY_VIEW);
49 | FRAGMENT_LIFECYCLE_METHODS.add(ON_DESTROY);
50 | FRAGMENT_LIFECYCLE_METHODS.add(ON_DETACH);
51 | }
52 |
53 | public FragmentLifecycle(Map methods) {
54 | super(methods);
55 | mLifecycleOrdering = FRAGMENT_LIFECYCLE_METHODS;
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/lifecycle_sorter/Lifecycle/Lifecycle.java:
--------------------------------------------------------------------------------
1 | package Lifecycle;
2 |
3 | import com.intellij.psi.PsiMethod;
4 |
5 | import java.util.LinkedHashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | /**
10 | * Created by armand on 3/15/15.
11 | *
12 | * Abstract class that represents a Lifecycle (could be an Activity/Fragment/etc).
13 | */
14 | public abstract class Lifecycle {
15 |
16 | /**
17 | * A Map representing all methods in a PsiClass. This Map will be filtered down to create
18 | * a new Map with the lifecycle methods of an Activity or Fragment in the proper ordering.
19 | * The key is the method name, and the value is the entire method represented as a String,
20 | * such as any Annotations, signature, accessors, method body, etc.
21 | */
22 | private Map mAllMethods;
23 |
24 | /**
25 | * A List containing the proper ordering of the lifecycle methods, whether it's
26 | * the activity lifecycle or fragment lifecycle
27 | */
28 | protected List mLifecycleOrdering;
29 |
30 |
31 | public Lifecycle(Map methods) {
32 | this.mAllMethods = methods;
33 | }
34 |
35 |
36 | /**
37 | * Sorts the lifecycle methods provided
38 | * @return A Map of the method names and entire method definitions, respecting the
39 | * sort order of mLifecycleOrdering
40 | */
41 | public Map sort() {
42 |
43 | // LinkedHashMap because we must respect the ordering in which we insert
44 | Map sortedMethods = new LinkedHashMap();
45 |
46 | for (int i = 0; i < mLifecycleOrdering.size(); i++) {
47 | String methodName = mLifecycleOrdering.get(i);
48 | PsiMethod method = mAllMethods.get(methodName);
49 |
50 | if (method != null) {
51 | sortedMethods.put(methodName, method);
52 | }
53 | }
54 |
55 | return sortedMethods;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/lifecycle_sorter/Lifecycle/LifecycleFactory.java:
--------------------------------------------------------------------------------
1 | package Lifecycle;
2 |
3 | import Util.LifecycleUtils;
4 | import com.intellij.psi.PsiClass;
5 | import com.intellij.psi.PsiMethod;
6 |
7 | import java.util.Map;
8 |
9 | /**
10 | * Created by armand on 4/4/15.
11 | */
12 | public class LifecycleFactory {
13 |
14 | public Lifecycle createLifecycle(PsiClass psiClass, Map methods) {
15 | switch (LifecycleUtils.getLifeCycleType(psiClass)) {
16 |
17 | case LifecycleUtils.ACTIVITY:
18 | return new ActivityLifecycle(methods);
19 |
20 | case LifecycleUtils.FRAGMENT:
21 | return new FragmentLifecycle(methods);
22 |
23 | default: return null;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lifecycle_sorter/Sort/Sorter.java:
--------------------------------------------------------------------------------
1 | package Sort;
2 |
3 | import Lifecycle.Lifecycle;
4 | import Lifecycle.LifecycleFactory;
5 | import com.intellij.psi.*;
6 | import org.jetbrains.annotations.NotNull;
7 |
8 | import java.util.Collection;
9 | import java.util.LinkedHashMap;
10 | import java.util.Map;
11 |
12 | /**
13 | * Created by armand on 3/1/15.
14 | */
15 |
16 | /**
17 | * This class determines if the current class is an Activity or a Fragment
18 | * and sorts the lifecycle methods based off that criteria.
19 | */
20 | public class Sorter {
21 |
22 | private PsiClass mPsiClass;
23 |
24 | /**
25 | * Enum for specifying the offset in the file where the lifecycle methods will be placed.
26 | * START - Places the methods at the start of the class, after the variable declarations.
27 | * END - Places the methods at the end of the class
28 | */
29 | public enum SortPosition {
30 | START, END
31 | }
32 |
33 | private SortPosition mSortPosition;
34 |
35 | /**
36 | * @param psiClass The class whose methods to sort
37 | * @param sortPosition The offset position in the class in which to place the sorted methods
38 | */
39 | public Sorter(PsiClass psiClass, SortPosition sortPosition) {
40 | mPsiClass = psiClass;
41 | mSortPosition = sortPosition;
42 | }
43 |
44 | /**
45 | * Formats the activity/fragment lifecycle methods
46 | */
47 | public void sort() {
48 | Map methods = getMethodsMap();
49 |
50 | Map sortedMethods = null;
51 |
52 | LifecycleFactory lifecycleFactory = new LifecycleFactory();
53 | Lifecycle lifecycle = lifecycleFactory.createLifecycle(mPsiClass, methods);
54 |
55 | if (lifecycle != null && !methods.isEmpty()) {
56 | sortedMethods = lifecycle.sort();
57 | appendSortedMethods(sortedMethods);
58 |
59 | // After obtaining and appending the new sorted list of PsiMethods,
60 | // we must remove the old, unsorted list
61 | deleteUnsortedLifecycleMethods(sortedMethods.values());
62 | }
63 |
64 | }
65 |
66 | /**
67 | * Generates a Map of all the methods in the current class
68 | * @return a Map of all the methods in the current class
69 | */
70 | @NotNull
71 | private Map getMethodsMap() {
72 | PsiMethod[] psiClassMethods = mPsiClass.getMethods();
73 |
74 | Map methods = new LinkedHashMap();
75 |
76 | for (PsiMethod method : psiClassMethods) {
77 | if (method != null) {
78 | methods.put(method.getName(), method);
79 | }
80 | }
81 | return methods;
82 | }
83 |
84 |
85 | /**
86 | * Removes the collection of PsiMethods from the PsiClass
87 | *
88 | * @param methods the methods to remove from the PsiClass
89 | */
90 | private void deleteUnsortedLifecycleMethods(Collection methods) {
91 | for (PsiMethod method : methods) method.delete();
92 | }
93 |
94 |
95 | /**
96 | * Appends the sorted methods to the file
97 | *
98 | * @param sortedMethods The sorted methods to append
99 | */
100 | private void appendSortedMethods(Map sortedMethods) {
101 |
102 | switch (mSortPosition) {
103 | case START:
104 | appendToStart(sortedMethods); break;
105 | case END:
106 | appendToEnd(sortedMethods); break;
107 | default:
108 | appendToStart(sortedMethods); break;
109 | }
110 |
111 | }
112 |
113 | /**
114 | * Appends the sorted lifecycle methods to the end of the class.
115 | * @param sortedMethods The sorted lifecycle methods
116 | */
117 | private void appendToEnd(Map sortedMethods) {
118 | for (PsiMethod method : sortedMethods.values()) {
119 | mPsiClass.add(method);
120 | }
121 | }
122 |
123 | /**
124 | * Appends the sorted lifecycle methods to the start of the class.
125 | * @param sortedMethods The sorted lifecycle methods
126 | */
127 | private void appendToStart(Map sortedMethods) {
128 | // We want the lifecycle methods to be the first methods in the class
129 | // so we grab the current first method and append the lifecycle
130 | // methods before it.
131 | PsiElement anchorToAddBefore = mPsiClass.getMethods()[0];
132 |
133 | for (PsiMethod method : sortedMethods.values()) {
134 | mPsiClass.addBefore(method, anchorToAddBefore);
135 | }
136 | }
137 |
138 | }
139 |
--------------------------------------------------------------------------------
/lifecycle_sorter/Util/LifecycleUtils.java:
--------------------------------------------------------------------------------
1 | package Util;
2 |
3 | import com.intellij.psi.PsiClass;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | /**
9 | * Created by armand on 3/22/15.
10 | */
11 | public class LifecycleUtils {
12 |
13 | public static final int ACTIVITY = 1;
14 | public static final int FRAGMENT = 2;
15 |
16 |
17 | private static final List ACTIVITY_PACKAGE_NAMES = new ArrayList();
18 |
19 | static {
20 | ACTIVITY_PACKAGE_NAMES.add("android.app.Activity");
21 | }
22 |
23 |
24 | /**
25 | * The fragment package names and the support libraries that come with it.
26 | */
27 | private static final List FRAGMENT_PACKAGE_NAMES = new ArrayList();
28 |
29 | static {
30 | FRAGMENT_PACKAGE_NAMES.add("android.app.Fragment");
31 | FRAGMENT_PACKAGE_NAMES.add("android.support.v4.app.Fragment");
32 | }
33 |
34 | /**
35 | * To Prevent instantiation
36 | */
37 | private LifecycleUtils() {
38 | }
39 |
40 |
41 | /**
42 | * Checks a list of superclasses of a PsiClass against the Activity/Fragment classes and support classes.
43 | * @param psiClass
44 | * @return true if a match is found, false otherwise
45 | */
46 | public static int getLifeCycleType(PsiClass psiClass) {
47 | List packages = buildSuperClassList(psiClass, new ArrayList());
48 | return resolvePackageToCompare(packages);
49 |
50 | }
51 |
52 | /**
53 | * Cross checks the list of package names we've built up against the list of
54 | * Activity package names and list of Fragment package names.
55 | * @param superClassList The hierarchy of classes found from the current PsiClass
56 | * @return {@value #ACTIVITY} if the superClassList contains the appropriate package
57 | * name identifying that Activity has been inherited, {@value #FRAGMENT} if the superClassList
58 | * contains the appropriate package name identifying that Fragment has been inherited.
59 | * -1 if no inheritance matches are found.
60 | */
61 | private static int resolvePackageToCompare(List superClassList) {
62 | for (int i = 0; i < ACTIVITY_PACKAGE_NAMES.size(); i++) {
63 | if (superClassList.contains(ACTIVITY_PACKAGE_NAMES.get(i))) return ACTIVITY;
64 | }
65 |
66 | for (int i = 0; i < FRAGMENT_PACKAGE_NAMES.size(); i++) {
67 | if (superClassList.contains(FRAGMENT_PACKAGE_NAMES.get(i))) return FRAGMENT;
68 | }
69 |
70 | return -1;
71 | }
72 |
73 |
74 | /**
75 | * Recurses up the superclass chain of the PsiClass provided to determine
76 | * if the chain contains Activity or Fragment as one of the base classes.
77 | * This will then be used to determine which lifecycle methods to sort by.
78 | *
79 | * @param psiClass the psiClass used to traverse up the superclass chain
80 | * @param packages the list of packages that will be built up from traversal
81 | * @return the list of packages collected after traversal
82 | */
83 | private static List buildSuperClassList(PsiClass psiClass, List packages) {
84 |
85 | // After traversing up the hierarchy, either the JDK is not
86 | // configured or they're simply not using the Android SDK
87 | // which would obviously contain the required packages
88 | if (psiClass == null || psiClass.getQualifiedName().equals("java.lang.Object")) {
89 | return packages;
90 | } else {
91 | packages.add(psiClass.getQualifiedName());
92 | return buildSuperClassList(psiClass.getSuperClass(), packages);
93 | }
94 | }
95 |
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/AndroidView.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android;
2 |
3 | import com.intellij.psi.PsiElement;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | public class AndroidView {
7 |
8 | private String id;
9 | private String name;
10 | private PsiElement xmlTarget;
11 |
12 | public AndroidView(@NotNull String id, @NotNull String className, PsiElement xmlTarget) {
13 | this.xmlTarget = xmlTarget;
14 |
15 | if (id.startsWith("@+id/")) {
16 | this.id = ("R.id." + id.split("@\\+id/")[1]);
17 | } else if (id.contains(":")) {
18 | String[] s = id.split(":id/");
19 | String packageStr = s[0].substring(1, s[0].length());
20 | this.id = (packageStr + ".R.id." + s[1]);
21 | }
22 | if (className.contains("."))
23 | this.name = className;
24 | else if ((className.equals("View")) || (className.equals("ViewGroup")))
25 | this.name = String.format("android.view.%s", className);
26 | else
27 | this.name = String.format("android.widget.%s", className);
28 | }
29 |
30 | public PsiElement getXmlTarget() {
31 | return xmlTarget;
32 | }
33 |
34 | public String getId() {
35 | return this.id;
36 | }
37 |
38 | public String getName() {
39 | return this.name;
40 | }
41 |
42 | public String getFieldName() {
43 | String[] words = getId().split("_");
44 | StringBuilder fieldName = new StringBuilder();
45 | for (String word : words) {
46 | String[] idTokens = word.split("\\.");
47 | char[] chars = idTokens[(idTokens.length - 1)].toCharArray();
48 | fieldName.append(chars);
49 | }
50 | return fieldName.toString();
51 | }
52 | }
--------------------------------------------------------------------------------
/src/de/espend/idea/android/RelatedPopupGotoLineMarker.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android;
2 |
3 | import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
4 | import com.intellij.ide.actions.GotoRelatedFileAction;
5 | import com.intellij.navigation.GotoRelatedItem;
6 | import com.intellij.psi.PsiElement;
7 | import com.intellij.ui.awt.RelativePoint;
8 | import org.jetbrains.annotations.NotNull;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | import javax.swing.*;
12 | import java.awt.event.MouseEvent;
13 | import java.util.List;
14 |
15 | public class RelatedPopupGotoLineMarker {
16 |
17 | public static class NavigationHandler implements GutterIconNavigationHandler {
18 |
19 | private List items;
20 |
21 | public NavigationHandler(List items){
22 | this.items = items;
23 | }
24 |
25 | public void navigate(MouseEvent e, PsiElement elt) {
26 | List items = this.items;
27 | if (items.size() == 1) {
28 | items.get(0).navigate();
29 | } else {
30 | GotoRelatedFileAction.createPopup(items, "Go to Related Files").show(new RelativePoint(e));
31 | }
32 |
33 | }
34 |
35 | }
36 |
37 | public static class PopupGotoRelatedItem extends GotoRelatedItem {
38 |
39 | private String customName;
40 | private Icon icon;
41 | private Icon smallIcon;
42 |
43 | public PopupGotoRelatedItem(@NotNull PsiElement element) {
44 | super(element);
45 | }
46 |
47 | public PopupGotoRelatedItem(@NotNull PsiElement element, String customName) {
48 | super(element);
49 | this.customName = customName;
50 | }
51 |
52 | @Nullable
53 | @Override
54 | public String getCustomName() {
55 | return customName;
56 | }
57 |
58 | @Nullable
59 | @Override
60 | public Icon getCustomIcon() {
61 | if(this.icon != null) {
62 | return this.icon;
63 | }
64 |
65 | return super.getCustomIcon();
66 | }
67 |
68 | public PopupGotoRelatedItem withIcon(Icon icon, Icon smallIcon) {
69 | this.icon = icon;
70 | this.smallIcon = smallIcon;
71 | return this;
72 | }
73 |
74 | public Icon getSmallIcon() {
75 | return smallIcon;
76 | }
77 |
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/action/ExtractStringAction.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.action;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import com.intellij.openapi.actionSystem.PlatformDataKeys;
5 | import com.intellij.openapi.application.ApplicationManager;
6 | import com.intellij.openapi.command.CommandProcessor;
7 | import com.intellij.openapi.editor.Editor;
8 | import com.intellij.openapi.project.DumbAwareAction;
9 | import com.intellij.openapi.project.Project;
10 | import com.intellij.psi.PsiElement;
11 | import com.intellij.psi.PsiFile;
12 | import com.intellij.psi.PsiLiteralExpression;
13 | import icons.AndroidIcons;
14 | import org.jetbrains.android.intentions.AndroidAddStringResourceAction;
15 | import org.jetbrains.annotations.Nullable;
16 |
17 | public class ExtractStringAction extends DumbAwareAction {
18 |
19 | public ExtractStringAction() {
20 | super("Extract String resource", "Extract string resource (string.xml)", AndroidIcons.Android);
21 | }
22 |
23 | @Override
24 | public void update(AnActionEvent event) {
25 | PsiElement psiElement = getPsiElement(event.getData(PlatformDataKeys.PSI_FILE), event.getData(PlatformDataKeys.EDITOR));
26 | event.getPresentation().setVisible(psiElement instanceof PsiLiteralExpression);
27 | }
28 |
29 | @Override
30 | public void actionPerformed(AnActionEvent event) {
31 |
32 | final PsiFile psiFile = event.getData(PlatformDataKeys.PSI_FILE);
33 | final Editor editor = event.getData(PlatformDataKeys.EDITOR);
34 | final Project project = event.getData(PlatformDataKeys.PROJECT);
35 |
36 | if(project == null) {
37 | return;
38 | }
39 |
40 | CommandProcessor.getInstance().executeCommand(project, new Runnable() {
41 | @Override
42 | public void run() {
43 | ApplicationManager.getApplication().runWriteAction(new Runnable() {
44 | @Override
45 | public void run() {
46 | new AndroidAddStringResourceAction().invoke(project, editor, psiFile);
47 | }
48 | });
49 |
50 | }
51 | }, "Extract string resource", "Android Studio Plugin");
52 |
53 | }
54 |
55 | @Nullable
56 | protected static PsiElement getPsiElement(@Nullable PsiFile file, @Nullable Editor editor) {
57 |
58 | if(file == null || editor == null) {
59 | return null;
60 | }
61 |
62 | int offset = editor.getCaretModel().getOffset();
63 | PsiElement element = file.findElementAt(offset);
64 | return element != null ? element.getParent() : null;
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/action/generator/AbstractActivityViewAction.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.action.generator;
2 |
3 | import com.intellij.codeInsight.generation.actions.BaseGenerateAction;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.editor.Editor;
6 | import com.intellij.openapi.project.Project;
7 | import com.intellij.patterns.PlatformPatterns;
8 | import com.intellij.psi.*;
9 | import com.intellij.psi.impl.source.PsiClassReferenceType;
10 | import com.intellij.psi.util.PsiTreeUtil;
11 | import com.intellij.psi.util.PsiUtilBase;
12 | import de.espend.idea.android.annotator.InflateViewAnnotator;
13 | import de.espend.idea.android.utils.AndroidUtils;
14 | import icons.AndroidIcons;
15 | import org.jetbrains.annotations.NotNull;
16 | import org.jetbrains.annotations.Nullable;
17 |
18 | abstract public class AbstractActivityViewAction extends BaseGenerateAction {
19 |
20 | public AbstractActivityViewAction() {
21 | super(null);
22 | }
23 |
24 | @Override
25 | protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
26 | int offset = editor.getCaretModel().getOffset();
27 | PsiElement psiElement = file.findElementAt(offset);
28 |
29 | if(!PlatformPatterns.psiElement().inside(PsiMethodCallExpression.class).accepts(psiElement)) {
30 | return false;
31 | }
32 |
33 | PsiMethodCallExpression psiMethodCallExpression = PsiTreeUtil.getParentOfType(psiElement, PsiMethodCallExpression.class);
34 | if(psiMethodCallExpression == null) {
35 | return false;
36 | }
37 |
38 | PsiMethod psiMethod = psiMethodCallExpression.resolveMethod();
39 | if(psiMethod == null) {
40 | return false;
41 | }
42 |
43 | return "setContentView".equals(psiMethod.getName());
44 | }
45 |
46 | @Override
47 | public void actionPerformedImpl(@NotNull final Project project, final Editor editor) {
48 | PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, project);
49 | if(file == null) {
50 | return;
51 | }
52 |
53 | int offset = editor.getCaretModel().getOffset();
54 | PsiElement psiElement = file.findElementAt(offset);
55 | if(psiElement == null) {
56 | return;
57 | }
58 |
59 | PsiMethodCallExpression psiMethodCallExpression = PsiTreeUtil.getParentOfType(psiElement, PsiMethodCallExpression.class);
60 | if(psiMethodCallExpression == null) {
61 | return;
62 | }
63 |
64 | PsiFile xmlFile = matchInflate(psiMethodCallExpression);
65 | generate(psiMethodCallExpression, xmlFile, editor, file);
66 | }
67 |
68 | @Nullable
69 | public static PsiFile matchInflate(PsiMethodCallExpression psiMethodCallExpression) {
70 |
71 | PsiExpression[] psiExpressions = psiMethodCallExpression.getArgumentList().getExpressions();
72 | if(psiExpressions.length == 0) {
73 | return null;
74 | }
75 |
76 | return AndroidUtils.findXmlResource((PsiReferenceExpression) psiExpressions[0]);
77 | }
78 |
79 | @Override
80 | public void update(AnActionEvent event) {
81 | super.update(event);
82 | event.getPresentation().setIcon(AndroidIcons.AndroidToolWindow);
83 | }
84 |
85 | abstract public void generate(PsiMethodCallExpression psiMethodCallExpression, PsiFile xmlFile, Editor editor, @NotNull PsiFile file);
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/action/generator/AbstractInflateViewAction.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.action.generator;
2 |
3 | import com.intellij.codeInsight.generation.actions.BaseGenerateAction;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.editor.Editor;
6 | import com.intellij.openapi.project.Project;
7 | import com.intellij.patterns.PlatformPatterns;
8 | import com.intellij.psi.PsiElement;
9 | import com.intellij.psi.PsiFile;
10 | import com.intellij.psi.PsiLocalVariable;
11 | import com.intellij.psi.util.PsiTreeUtil;
12 | import com.intellij.psi.util.PsiUtilBase;
13 | import de.espend.idea.android.annotator.InflateViewAnnotator;
14 | import icons.AndroidIcons;
15 | import org.jetbrains.annotations.NotNull;
16 |
17 | abstract public class AbstractInflateViewAction extends BaseGenerateAction {
18 |
19 | public AbstractInflateViewAction() {
20 | super(null);
21 | }
22 |
23 | @Override
24 | protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
25 | int offset = editor.getCaretModel().getOffset();
26 | PsiElement psiElement = file.findElementAt(offset);
27 |
28 | if(!PlatformPatterns.psiElement().inside(PsiLocalVariable.class).accepts(psiElement)) {
29 | return false;
30 | }
31 |
32 | PsiLocalVariable psiLocalVariable = PsiTreeUtil.getParentOfType(psiElement, PsiLocalVariable.class);
33 | return InflateViewAnnotator.matchInflate(psiLocalVariable) != null;
34 | }
35 |
36 | @Override
37 | public void actionPerformedImpl(@NotNull final Project project, final Editor editor) {
38 | PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, project);
39 | if(file == null) {
40 | return;
41 | }
42 |
43 | int offset = editor.getCaretModel().getOffset();
44 | PsiElement psiElement = file.findElementAt(offset);
45 | if(psiElement == null) {
46 | return;
47 | }
48 |
49 | PsiLocalVariable psiLocalVariable = PsiTreeUtil.getParentOfType(psiElement, PsiLocalVariable.class);
50 | InflateViewAnnotator.InflateContainer inflateContainer = InflateViewAnnotator.matchInflate(psiLocalVariable);
51 | if(inflateContainer == null) {
52 | return;
53 | }
54 |
55 | generate(inflateContainer, editor, file);
56 | }
57 |
58 | @Override
59 | public void update(AnActionEvent event) {
60 | super.update(event);
61 | event.getPresentation().setIcon(AndroidIcons.AndroidToolWindow);
62 | }
63 |
64 | abstract public void generate(InflateViewAnnotator.InflateContainer inflateContainer, Editor editor, @NotNull PsiFile file);
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/action/generator/ActivityViewFieldVariable.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.action.generator;
2 |
3 | import com.intellij.openapi.editor.Editor;
4 | import com.intellij.psi.PsiFile;
5 | import com.intellij.psi.PsiMethodCallExpression;
6 | import de.espend.idea.android.action.write.InflateLocalVariableAction;
7 | import de.espend.idea.android.action.write.InflateThisExpressionAction;
8 | import org.jetbrains.annotations.NotNull;
9 |
10 | public class ActivityViewFieldVariable extends AbstractActivityViewAction {
11 |
12 | @Override
13 | public void generate(PsiMethodCallExpression psiMethodCallExpression, PsiFile xmlFile, Editor editor, @NotNull PsiFile file) {
14 | new InflateThisExpressionAction(psiMethodCallExpression, xmlFile).invoke(file.getProject(), editor, file);
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/action/generator/ActivityViewMethodVariable.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.action.generator;
2 |
3 | import com.intellij.openapi.editor.Editor;
4 | import com.intellij.psi.PsiFile;
5 | import com.intellij.psi.PsiMethodCallExpression;
6 | import de.espend.idea.android.action.write.InflateLocalVariableAction;
7 | import org.jetbrains.annotations.NotNull;
8 |
9 | public class ActivityViewMethodVariable extends AbstractActivityViewAction {
10 |
11 | @Override
12 | public void generate(PsiMethodCallExpression psiMethodCallExpression, PsiFile xmlFile, Editor editor, @NotNull PsiFile file) {
13 | new InflateLocalVariableAction(psiMethodCallExpression, xmlFile).invoke(file.getProject(), editor, file);
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/action/generator/FieldViewInflateViewAction.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.action.generator;
2 |
3 | import com.intellij.openapi.editor.Editor;
4 | import com.intellij.psi.PsiFile;
5 | import de.espend.idea.android.action.write.InflateThisExpressionAction;
6 | import de.espend.idea.android.annotator.InflateViewAnnotator;
7 | import org.jetbrains.annotations.NotNull;
8 |
9 | public class FieldViewInflateViewAction extends AbstractInflateViewAction {
10 |
11 | @Override
12 | public void generate(InflateViewAnnotator.InflateContainer inflateContainer, Editor editor, @NotNull PsiFile file) {
13 | new InflateThisExpressionAction(inflateContainer.getPsiLocalVariable(), inflateContainer.getXmlFile()).invoke(file.getProject(), editor, file);
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/action/generator/LocalViewAction.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.action.generator;
2 |
3 | import com.intellij.openapi.editor.Editor;
4 | import com.intellij.psi.PsiFile;
5 | import de.espend.idea.android.action.write.InflateLocalVariableAction;
6 | import de.espend.idea.android.annotator.InflateViewAnnotator;
7 | import org.jetbrains.annotations.NotNull;
8 |
9 | public class LocalViewAction extends AbstractInflateViewAction {
10 |
11 | @Override
12 | public void generate(InflateViewAnnotator.InflateContainer inflateContainer, Editor editor, @NotNull PsiFile file) {
13 | new InflateLocalVariableAction(inflateContainer.getPsiLocalVariable(), inflateContainer.getXmlFile()).invoke(file.getProject(), editor, file);
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/action/write/InflateLocalVariableAction.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.action.write;
2 |
3 | import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
4 | import com.intellij.openapi.application.ApplicationManager;
5 | import com.intellij.openapi.editor.Editor;
6 | import com.intellij.openapi.project.Project;
7 | import com.intellij.psi.*;
8 | import com.intellij.psi.codeStyle.JavaCodeStyleManager;
9 | import com.intellij.psi.util.PsiElementFilter;
10 | import com.intellij.psi.util.PsiTreeUtil;
11 | import com.intellij.util.DocumentUtil;
12 | import com.intellij.util.IncorrectOperationException;
13 | import de.espend.idea.android.AndroidView;
14 | import de.espend.idea.android.utils.AndroidUtils;
15 | import org.jetbrains.annotations.NotNull;
16 | import org.jetbrains.annotations.Nullable;
17 |
18 | import java.util.HashSet;
19 | import java.util.List;
20 | import java.util.Set;
21 |
22 | public class InflateLocalVariableAction extends BaseIntentionAction {
23 |
24 | final private PsiFile xmlFile;
25 | final private PsiElement psiElement;
26 |
27 | @Nullable
28 | private String variableName = null;
29 |
30 | public InflateLocalVariableAction(PsiLocalVariable psiLocalVariable, PsiFile xmlFile) {
31 | this.xmlFile = xmlFile;
32 | this.psiElement = psiLocalVariable;
33 | this.variableName = psiLocalVariable.getName();
34 | }
35 |
36 | public InflateLocalVariableAction(PsiElement psiElement, PsiFile xmlFile) {
37 | this.xmlFile = xmlFile;
38 | this.psiElement = psiElement;
39 | }
40 |
41 | @NotNull
42 | @Override
43 | public String getFamilyName() {
44 | return "Android Studio Prettify";
45 | }
46 |
47 | @Override
48 | public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile psiFile) {
49 | return true;
50 | }
51 |
52 | @Override
53 | public void invoke(@NotNull Project project, Editor editor, PsiFile psiFile) throws IncorrectOperationException {
54 | DocumentUtil.writeInRunUndoTransparentAction(new Runnable() {
55 | @Override
56 | public void run() {
57 | List androidViews = AndroidUtils.getIDsFromXML(xmlFile);
58 |
59 | PsiStatement psiStatement = PsiTreeUtil.getParentOfType(psiElement, PsiStatement.class);
60 | if (psiStatement == null) {
61 | return;
62 | }
63 |
64 | PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiStatement.getProject());
65 |
66 | PsiElement[] localVariables = PsiTreeUtil.collectElements(psiStatement.getParent(), new PsiElementFilter() {
67 | @Override
68 | public boolean isAccepted(PsiElement element) {
69 | return element instanceof PsiLocalVariable;
70 | }
71 | });
72 |
73 | Set variables = new HashSet();
74 | for (PsiElement localVariable : localVariables) {
75 | variables.add(((PsiLocalVariable) localVariable).getName());
76 | }
77 |
78 | for (AndroidView v : androidViews) {
79 | if (!variables.contains(v.getFieldName())) {
80 | String sb1;
81 |
82 | if (variableName != null) {
83 | sb1 = String.format("%s %s = (%s) %s.findViewById(%s);", v.getName(), v.getFieldName(), v.getName(), variableName, v.getId());
84 | } else {
85 | sb1 = String.format("%s %s = (%s) findViewById(%s);", v.getName(), v.getFieldName(), v.getName(), v.getId());
86 | }
87 |
88 | PsiStatement statementFromText = elementFactory.createStatementFromText(sb1, null);
89 | psiStatement.getParent().addAfter(statementFromText, psiStatement);
90 | }
91 | }
92 |
93 | JavaCodeStyleManager.getInstance(psiStatement.getProject()).shortenClassReferences(psiStatement.getParent());
94 | new ReformatAndOptimizeImportsProcessor(psiStatement.getProject(), psiStatement.getContainingFile(), true).run();
95 |
96 | }
97 | });
98 |
99 | }
100 |
101 | @NotNull
102 | @Override
103 | public String getText() {
104 | return "Local View Variables";
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/action/write/ReformatAndOptimizeImportsProcessor.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.action.write;
2 |
3 | import com.intellij.codeInsight.CodeInsightBundle;
4 | import com.intellij.codeInsight.actions.AbstractLayoutCodeProcessor;
5 | import com.intellij.codeInsight.actions.OptimizeImportsProcessor;
6 | import com.intellij.codeInsight.actions.ReformatCodeProcessor;
7 | import com.intellij.openapi.module.Module;
8 | import com.intellij.openapi.project.Project;
9 | import com.intellij.psi.PsiDirectory;
10 | import com.intellij.psi.PsiFile;
11 | import com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl;
12 | import com.intellij.util.IncorrectOperationException;
13 | import org.jetbrains.annotations.NotNull;
14 |
15 | import java.util.concurrent.Callable;
16 | import java.util.concurrent.FutureTask;
17 |
18 | /**
19 | * @author max
20 | */
21 | public class ReformatAndOptimizeImportsProcessor extends AbstractLayoutCodeProcessor {
22 | public static final String COMMAND_NAME = CodeInsightBundle.message("progress.reformat.and.optimize.common.command.text");
23 | private static final String PROGRESS_TEXT = CodeInsightBundle.message("reformat.and.optimize.progress.common.text");
24 |
25 | private final OptimizeImportsProcessor myOptimizeImportsProcessor;
26 | private final ReformatCodeProcessor myReformatCodeProcessor;
27 |
28 | public ReformatAndOptimizeImportsProcessor(Project project, PsiFile file, boolean processChangedTextOnly) {
29 | super(project, file, PROGRESS_TEXT, COMMAND_NAME, processChangedTextOnly);
30 | myOptimizeImportsProcessor = new OptimizeImportsProcessor(project, file);
31 | myReformatCodeProcessor = new ReformatCodeProcessor(project, file, null, processChangedTextOnly);
32 | }
33 |
34 | @NotNull
35 | @Override
36 | protected FutureTask prepareTask(@NotNull PsiFile psiFile, boolean b) throws IncorrectOperationException {
37 | return new FutureTask(new Callable() {
38 | @Override
39 | public Boolean call() throws Exception {
40 | return true;
41 | }
42 | });
43 | }
44 |
45 | @Override
46 | @NotNull
47 | public FutureTask preprocessFile(@NotNull PsiFile file, boolean processChangedTextOnly) throws IncorrectOperationException {
48 | final FutureTask reformatTask = myReformatCodeProcessor.preprocessFile(file, processChangedTextOnly);
49 | final FutureTask optimizeImportsTask = myOptimizeImportsProcessor.preprocessFile(file, false);
50 | return new FutureTask(new Callable() {
51 | @Override
52 | public Boolean call() throws Exception {
53 | reformatTask.run();
54 | if (!reformatTask.get() || reformatTask.isCancelled()) {
55 | return false;
56 | }
57 |
58 | CodeStyleManagerImpl.setSequentialProcessingAllowed(false);
59 | try {
60 | optimizeImportsTask.run();
61 | return optimizeImportsTask.get() && !optimizeImportsTask.isCancelled();
62 | }
63 | finally {
64 | CodeStyleManagerImpl.setSequentialProcessingAllowed(true);
65 | }
66 | }
67 | });
68 | }
69 | }
--------------------------------------------------------------------------------
/src/de/espend/idea/android/annotator/InflateViewAnnotator.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.annotator;
2 |
3 | import com.intellij.lang.annotation.Annotation;
4 | import com.intellij.lang.annotation.AnnotationHolder;
5 | import com.intellij.lang.annotation.Annotator;
6 | import com.intellij.psi.*;
7 | import com.intellij.psi.impl.source.PsiClassReferenceType;
8 | import com.intellij.psi.impl.source.tree.java.PsiIdentifierImpl;
9 | import com.intellij.psi.util.PsiTreeUtil;
10 | import de.espend.idea.android.action.write.InflateLocalVariableAction;
11 | import de.espend.idea.android.action.write.InflateThisExpressionAction;
12 | import de.espend.idea.android.utils.AndroidUtils;
13 | import de.espend.idea.android.utils.JavaPsiUtil;
14 | import org.jetbrains.annotations.NotNull;
15 | import org.jetbrains.annotations.Nullable;
16 |
17 | public class InflateViewAnnotator implements Annotator {
18 |
19 | @Override
20 | public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) {
21 |
22 | InflateContainer inflateContainer = matchInflate(psiElement);
23 | if(inflateContainer == null) {
24 | return;
25 | }
26 |
27 | Annotation inflateLocal = annotationHolder.createWeakWarningAnnotation(psiElement, null);
28 | inflateLocal.setHighlightType(null);
29 | inflateLocal.registerFix(new InflateLocalVariableAction(inflateContainer.getPsiLocalVariable(), inflateContainer.getXmlFile()));
30 |
31 | Annotation inflateThis = annotationHolder.createWeakWarningAnnotation(psiElement, null);
32 | inflateThis.setHighlightType(null);
33 | inflateThis.registerFix(new InflateThisExpressionAction(inflateContainer.getPsiLocalVariable(), inflateContainer.getXmlFile()));
34 |
35 | }
36 |
37 | @Nullable
38 | public static InflateContainer matchInflate(@Nullable PsiElement psiElement) {
39 | if(!(psiElement instanceof PsiIdentifierImpl)) {
40 | return null;
41 | }
42 |
43 | // View "rootView" = inflater.inflate(R.layout.fragment_main, container, false);
44 | PsiElement psiLocalVariable = psiElement.getParent();
45 | if(psiLocalVariable instanceof PsiLocalVariable) {
46 | return matchInflate((PsiLocalVariable) psiLocalVariable);
47 | }
48 |
49 | return null;
50 |
51 | }
52 |
53 | @Nullable
54 | public static InflateContainer matchInflate(PsiLocalVariable psiLocalVariable) {
55 | PsiType psiType = psiLocalVariable.getType();
56 | if(psiType instanceof PsiClassReferenceType) {
57 | PsiMethodCallExpression psiMethodCallExpression = PsiTreeUtil.findChildOfType(psiLocalVariable, PsiMethodCallExpression.class);
58 | if(psiMethodCallExpression != null) {
59 | PsiMethod psiMethod = psiMethodCallExpression.resolveMethod();
60 |
61 | // @TODO: replace "inflate"; resolve method and check nethod calls
62 | if(psiMethod != null && psiMethod.getName().equals("inflate")) {
63 | PsiExpression[] expressions = psiMethodCallExpression.getArgumentList().getExpressions();
64 | if(expressions.length > 0 && expressions[0] instanceof PsiReferenceExpression) {
65 | PsiFile xmlFile = AndroidUtils.findXmlResource((PsiReferenceExpression) expressions[0]);
66 | if(xmlFile != null) {
67 | return new InflateContainer(xmlFile, ((PsiLocalVariable) psiLocalVariable));
68 | }
69 | }
70 | }
71 | }
72 | }
73 |
74 | return null;
75 | }
76 |
77 | public static class InflateContainer {
78 |
79 | final private PsiFile xmlFile;
80 | final private PsiLocalVariable psiLocalVariable;
81 |
82 | public InflateContainer(PsiFile xmlFile, PsiLocalVariable psiLocalVariable) {
83 | this.xmlFile = xmlFile;
84 | this.psiLocalVariable = psiLocalVariable;
85 | }
86 |
87 | public PsiLocalVariable getPsiLocalVariable() {
88 | return psiLocalVariable;
89 | }
90 |
91 | public PsiFile getXmlFile() {
92 | return xmlFile;
93 | }
94 |
95 | }
96 |
97 |
98 |
99 |
100 | }
101 |
102 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/linemarker/FragmentRelatedFileLineMarker.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.linemarker;
2 |
3 | import com.intellij.codeInsight.daemon.LineMarkerInfo;
4 | import com.intellij.codeInsight.daemon.LineMarkerProvider;
5 | import com.intellij.navigation.GotoRelatedItem;
6 | import com.intellij.psi.*;
7 | import com.intellij.psi.util.PsiTreeUtil;
8 | import com.intellij.util.ConstantFunction;
9 | import de.espend.idea.android.RelatedPopupGotoLineMarker;
10 | import de.espend.idea.android.utils.AndroidUtils;
11 | import icons.AndroidIcons;
12 | import org.jetbrains.android.AndroidLineMarkerProvider;
13 | import org.jetbrains.annotations.NotNull;
14 | import org.jetbrains.annotations.Nullable;
15 |
16 | import java.util.ArrayList;
17 | import java.util.Collection;
18 | import java.util.List;
19 |
20 | public class FragmentRelatedFileLineMarker implements LineMarkerProvider {
21 |
22 | @Nullable
23 | @Override
24 | public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
25 | return null;
26 | }
27 |
28 | @Override
29 | public void collectSlowLineMarkers(@NotNull List elements, @NotNull Collection result) {
30 |
31 | for(PsiElement psiElement : elements) {
32 |
33 | List gotoRelatedItems = new ArrayList();
34 | List psiFiles = new ArrayList();
35 |
36 | // android studio provide line marker with xml targets only on root classes not on class inside classes like fragments
37 | // we support all of them :)
38 | if(psiElement instanceof PsiIdentifier && psiElement.getParent() instanceof PsiClass && !(psiElement.getParent().getParent() instanceof PsiFile)) {
39 |
40 | // simple hack activity provide this on core
41 | if(isFragmentClass((PsiClass) psiElement.getParent())) {
42 | Collection PsiMethodCallExpressions = PsiTreeUtil.collectElementsOfType(psiElement.getParent(), PsiMethodCallExpression.class);
43 | for(PsiMethodCallExpression methodCallExpression: PsiMethodCallExpressions) {
44 | PsiMethod psiMethod = methodCallExpression.resolveMethod();
45 | if(psiMethod != null && psiMethod.getName().equals("inflate")) {
46 | PsiExpression[] expressions = methodCallExpression.getArgumentList().getExpressions();
47 | if(expressions.length > 0 && expressions[0] instanceof PsiReferenceExpression) {
48 | PsiFile xmlFile = AndroidUtils.findXmlResource((PsiReferenceExpression) expressions[0]);
49 | if(xmlFile != null && !psiFiles.contains(xmlFile)) {
50 | psiFiles.add(xmlFile);
51 | gotoRelatedItems.add(new GotoRelatedItem(xmlFile));
52 | }
53 | }
54 | }
55 | }
56 | }
57 |
58 | }
59 |
60 | if(gotoRelatedItems.size() > 0) {
61 | result.add(new LineMarkerInfo(psiElement, psiElement.getTextOffset(), AndroidIcons.AndroidToolWindow, 6, new ConstantFunction("Related Files"), new RelatedPopupGotoLineMarker.NavigationHandler(gotoRelatedItems)));
62 | }
63 |
64 | }
65 |
66 | }
67 |
68 | private boolean isFragmentClass(PsiClass psiClass) {
69 |
70 | PsiReferenceList extendsList = psiClass.getExtendsList();
71 | if(extendsList == null) {
72 | return false;
73 | }
74 |
75 | // @TODO: replace this one with instance check
76 | PsiClassType[] tests = extendsList.getReferencedTypes();
77 | for(PsiClassType psiClassType: tests) {
78 | if(psiClassType.getClassName().contains("Activity")) {
79 | return false;
80 | }
81 | if(psiClassType.getClassName().contains("Fragment")) {
82 | return true;
83 | }
84 | }
85 |
86 | return false;
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/linemarker/InflateLayoutLineMarkerProvider.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.linemarker;
2 |
3 | import com.intellij.codeInsight.daemon.LineMarkerInfo;
4 | import com.intellij.codeInsight.daemon.LineMarkerProvider;
5 | import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
6 | import com.intellij.psi.*;
7 | import de.espend.idea.android.utils.AndroidUtils;
8 | import icons.AndroidIcons;
9 | import org.jetbrains.annotations.NotNull;
10 | import org.jetbrains.annotations.Nullable;
11 |
12 | import java.util.Collection;
13 | import java.util.List;
14 |
15 | public class InflateLayoutLineMarkerProvider implements LineMarkerProvider {
16 |
17 | @Nullable
18 | @Override
19 | public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
20 | return null;
21 | }
22 |
23 | @Override
24 | public void collectSlowLineMarkers(@NotNull List elements, @NotNull Collection result) {
25 | for(PsiElement psiElement : elements) {
26 |
27 | if(psiElement instanceof PsiMethodCallExpression) {
28 | PsiMethod psiMethod = ((PsiCallExpression) psiElement).resolveMethod();
29 | if(psiMethod != null && ("inflate".equals(psiMethod.getName()) || "setContentView".equals(psiMethod.getName()))) {
30 | PsiExpressionList psiExpressionList = ((PsiCallExpression) psiElement).getArgumentList();
31 | if(psiExpressionList != null) {
32 | PsiExpression[] psiExpressions = psiExpressionList.getExpressions();
33 | if(psiExpressions.length > 0 && psiExpressions[0].getText().startsWith("R.layout")) {
34 | String layoutText = psiExpressions[0].getText();
35 |
36 | PsiFile xmlFile = AndroidUtils.findXmlResource(psiElement.getProject(), layoutText);
37 | if(xmlFile != null) {
38 |
39 | NavigationGutterIconBuilder builder = NavigationGutterIconBuilder.create(AndroidIcons.Views.Fragment).
40 | setTooltipText(xmlFile.getName()).
41 | setTargets(xmlFile);
42 |
43 | result.add(builder.createLineMarkerInfo(psiElement));
44 | }
45 |
46 | }
47 | }
48 | }
49 | }
50 |
51 | }
52 | }
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/linemarker/ViewInflateLineMarker.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.linemarker;
2 |
3 | import com.intellij.codeInsight.daemon.LineMarkerInfo;
4 | import com.intellij.codeInsight.daemon.LineMarkerProvider;
5 | import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
6 | import com.intellij.psi.*;
7 | import com.intellij.psi.search.GlobalSearchScope;
8 | import com.intellij.psi.util.PsiTreeUtil;
9 | import de.espend.idea.android.AndroidView;
10 | import de.espend.idea.android.utils.AndroidUtils;
11 | import de.espend.idea.android.utils.AndroidViewUtil;
12 | import icons.AndroidIcons;
13 | import org.jetbrains.annotations.NotNull;
14 | import org.jetbrains.annotations.Nullable;
15 |
16 | import javax.swing.*;
17 | import java.util.Collection;
18 | import java.util.List;
19 |
20 | public class ViewInflateLineMarker implements LineMarkerProvider {
21 |
22 | @Nullable
23 | @Override
24 | public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
25 | return null;
26 | }
27 |
28 | @Override
29 | public void collectSlowLineMarkers(@NotNull List elements, @NotNull Collection result) {
30 |
31 | for(PsiElement psiElement : elements) {
32 | if(psiElement instanceof PsiMethodCallExpression) {
33 | attachFindViewByIdInflate((PsiMethodCallExpression) psiElement, result);
34 | attachFindViewByIdSetContentViews((PsiMethodCallExpression) psiElement, result);
35 | }
36 | }
37 |
38 | }
39 | private void attachFindViewByIdInflate(PsiMethodCallExpression psiMethodCallExpression, @NotNull Collection result) {
40 | AndroidView androidView = AndroidViewUtil.getAndroidView(psiMethodCallExpression);
41 | if(androidView != null) {
42 | attachLineIcon(androidView, psiMethodCallExpression, result);
43 | }
44 | }
45 |
46 | private void attachFindViewByIdSetContentViews(PsiMethodCallExpression psiMethodCallExpression, @NotNull Collection result) {
47 |
48 | PsiExpression[] psiExpressions = psiMethodCallExpression.getArgumentList().getExpressions();
49 | if(psiExpressions.length == 0) {
50 | return;
51 | }
52 |
53 | PsiMethod psiMethodResolved = psiMethodCallExpression.resolveMethod();
54 | if(psiMethodResolved == null) {
55 | return;
56 | }
57 |
58 | if("findViewById".equals(psiMethodResolved.getName())) {
59 | String viewId = psiExpressions[0].getText();
60 |
61 | PsiMethod psiMethod = PsiTreeUtil.getParentOfType(psiMethodCallExpression, PsiMethod.class);
62 | if(psiMethod != null) {
63 | for(PsiFile psiFile : AndroidViewUtil.findLayoutFilesInsideMethod(psiMethod)) {
64 | AndroidView androidView = AndroidUtils.getViewType(psiFile, viewId);
65 | if(androidView != null) {
66 | attachLineIcon(androidView, psiMethodCallExpression, result);
67 | }
68 | }
69 | }
70 | }
71 |
72 | }
73 |
74 | private void attachLineIcon(@NotNull AndroidView view, @NotNull PsiElement psiElement, @NotNull Collection result) {
75 |
76 | JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(psiElement.getProject());
77 | PsiClass psiClass = psiFacade.findClass(view.getName(), GlobalSearchScope.allScope(psiElement.getProject()));
78 | if(psiClass == null) {
79 | return;
80 | }
81 |
82 | Icon icon = AndroidViewUtil.getCoreIconWithExtends(view, psiClass);
83 | if(icon == null) {
84 | icon = AndroidIcons.Views.View;
85 | }
86 |
87 | NavigationGutterIconBuilder builder = NavigationGutterIconBuilder.create(icon).
88 | setTooltipText(view.getName()).
89 | setTargets(view.getXmlTarget());
90 |
91 | result.add(builder.createLineMarkerInfo(psiElement));
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/utils/AndroidUtils.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.utils;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.openapi.vfs.VfsUtil;
5 | import com.intellij.openapi.vfs.VirtualFile;
6 | import com.intellij.psi.*;
7 | import com.intellij.psi.search.FilenameIndex;
8 | import com.intellij.psi.search.GlobalSearchScope;
9 | import com.intellij.psi.xml.XmlAttribute;
10 | import com.intellij.psi.xml.XmlTag;
11 | import de.espend.idea.android.AndroidView;
12 | import org.jetbrains.annotations.NotNull;
13 | import org.jetbrains.annotations.Nullable;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 |
19 | public class AndroidUtils {
20 |
21 | @Nullable
22 | public static PsiFile findXmlResource(@Nullable PsiReferenceExpression referenceExpression) {
23 | if (referenceExpression == null) return null;
24 |
25 | PsiElement firstChild = referenceExpression.getFirstChild();
26 | if (firstChild == null || !"R.layout".equals(firstChild.getText())) {
27 | return null;
28 | }
29 |
30 | PsiElement lastChild = referenceExpression.getLastChild();
31 | if(lastChild == null) {
32 | return null;
33 | }
34 |
35 | String name = String.format("%s.xml", lastChild.getText());
36 | PsiFile[] foundFiles = FilenameIndex.getFilesByName(referenceExpression.getProject(), name, GlobalSearchScope.allScope(referenceExpression.getProject()));
37 | if (foundFiles.length <= 0) {
38 | return null;
39 | }
40 |
41 | return foundFiles[0];
42 | }
43 |
44 | public static List getProjectViews(Project project) {
45 |
46 | List androidViews = new ArrayList();
47 | for(PsiFile psiFile: getLayoutFiles(project)) {
48 | androidViews.addAll(getIDsFromXML(psiFile));
49 | }
50 |
51 | return androidViews;
52 | }
53 |
54 | public static List getLayoutFiles(Project project) {
55 |
56 | List psiFileList = new ArrayList();
57 |
58 | for (VirtualFile virtualFile : FilenameIndex.getAllFilesByExt(project, "xml")) {
59 | VirtualFile parent = virtualFile.getParent();
60 | if (parent != null && "layout".equals(parent.getName())) {
61 | String relative = VfsUtil.getRelativePath(virtualFile, project.getBaseDir(), '/');
62 | if (relative != null) {
63 | PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
64 | if (psiFile != null) {
65 | psiFileList.add(psiFile);
66 | }
67 | }
68 | }
69 | }
70 |
71 | return psiFileList;
72 | }
73 |
74 | @Nullable
75 | public static PsiFile findXmlResource(Project project, String layoutName) {
76 |
77 | if (!layoutName.startsWith("R.layout.")) {
78 | return null;
79 | }
80 |
81 | layoutName = layoutName.substring("R.layout.".length());
82 |
83 | String name = String.format("%s.xml", layoutName);
84 | PsiFile[] foundFiles = FilenameIndex.getFilesByName(project, name, GlobalSearchScope.allScope(project));
85 | if (foundFiles.length <= 0) {
86 | return null;
87 | }
88 |
89 | return foundFiles[0];
90 | }
91 |
92 | @NotNull
93 | public static List getIDsFromXML(@NotNull PsiFile f) {
94 | final ArrayList ret = new ArrayList();
95 | f.accept(new XmlRecursiveElementVisitor() {
96 | @Override
97 | public void visitElement(final PsiElement element) {
98 | super.visitElement(element);
99 | if (element instanceof XmlTag) {
100 | XmlTag t = (XmlTag) element;
101 | XmlAttribute id = t.getAttribute("android:id", null);
102 | if (id == null) {
103 | return;
104 | }
105 | final String val = id.getValue();
106 | if (val == null) {
107 | return;
108 | }
109 | ret.add(new AndroidView(val, t.getName(), id));
110 |
111 | }
112 |
113 | }
114 | });
115 |
116 | return ret;
117 | }
118 |
119 | @Nullable
120 | public static AndroidView getViewType(@NotNull PsiFile f, String findId) {
121 |
122 | // @TODO: replace dup for
123 | List views = getIDsFromXML(f);
124 |
125 | for(AndroidView view: views) {
126 | if(findId.equals(view.getId())) {
127 | return view;
128 | }
129 | }
130 |
131 | return null;
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/src/de/espend/idea/android/utils/JavaPsiUtil.java:
--------------------------------------------------------------------------------
1 | package de.espend.idea.android.utils;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.psi.JavaPsiFacade;
5 | import com.intellij.psi.PsiClass;
6 | import com.intellij.psi.PsiClassType;
7 | import com.intellij.psi.impl.PsiClassImplUtil;
8 | import com.intellij.psi.search.GlobalSearchScope;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | public class JavaPsiUtil {
12 |
13 | @Nullable
14 | public static PsiClass getClass(Project project, String qualifiedClassName) {
15 | JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
16 | return psiFacade.findClass(qualifiedClassName, GlobalSearchScope.allScope(project));
17 | }
18 |
19 | public static boolean isInstanceOf(PsiClass instance, PsiClass interfaceExtendsClass) {
20 |
21 | String className = interfaceExtendsClass.getQualifiedName();
22 | if(className == null) {
23 | return true;
24 | }
25 |
26 | if(className.equals(instance.getQualifiedName())) {
27 | return true;
28 | }
29 |
30 | for(PsiClassType psiClassType: PsiClassImplUtil.getExtendsListTypes(instance)) {
31 | PsiClass resolve = psiClassType.resolve();
32 | if(resolve != null) {
33 | if(className.equals(resolve.getQualifiedName())) {
34 | return true;
35 | }
36 | }
37 | }
38 |
39 | for(PsiClass psiInterface: PsiClassImplUtil.getInterfaces(instance)) {
40 | if(className.equals(psiInterface.getQualifiedName())) {
41 | return true;
42 | }
43 | }
44 |
45 | return false;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------