[
  {
    "path": "META-INF/plugin.xml",
    "content": "<idea-plugin version=\"2\">\n    <id>importre.intellij.android.selector</id>\n    <name>Android Selector</name>\n    <version>0.2.0</version>\n    <vendor email=\"jaeweheo@gmail.com\" url=\"http://import.re\">\n        importre\n    </vendor>\n\n    <description><![CDATA[\n      <h1>Generate selectors for background drawable</h1>\n      <br/>\n      You can use `colorButtonNormal` simply,\n      <br/>\n      but make easily touch feedback of normal `View`s as well as `Button`s with this plugin.\n      <br/><br/>\n\n      1. Set your colors(in `res/values/colors.xml`).\n      <br/>\n      2. Select `New -> Android Selector(or Ctrl/Cmd + N)` on your `res` directory.\n      <br/>\n      3. Select filename, color, pressed and pressed-v21 respectively.\n      <br/><br/>\n\n      - ripple drawable is generated in drawable-v21 directory.<br/>\n      - normal drawable is generated in drawable directory.<br/><br/>\n\n      <h2>Dependency</h2>\n      <br/>\n      - com.android.support:appcompat-v7:22.+\n    ]]></description>\n\n    <change-notes><![CDATA[\n      - Implementation of color selection based on `res/values/colors.xml`\n      <br/>\n      - Changing icon\n    ]]>\n    </change-notes>\n\n    <!-- please see https://confluence.jetbrains.com/display/IDEADEV/Build+Number+Ranges for description -->\n    <idea-version since-build=\"141\"/>\n\n    <!-- please see https://confluence.jetbrains.com/display/IDEADEV/Plugin+Compatibility+with+IntelliJ+Platform+Products\n         on how to target different products -->\n\n    <depends>com.intellij.modules.lang</depends>\n\n    <extensions defaultExtensionNs=\"com.intellij\">\n        <!-- Add your extensions here -->\n    </extensions>\n\n    <application-components>\n        <!-- Add your application components here -->\n    </application-components>\n\n    <project-components>\n        <!-- Add your project components here -->\n    </project-components>\n\n    <actions>\n        <!-- Add your actions here -->\n        <action id=\"importre.intellij.android.selector.AndroidSelector\"\n                class=\"importre.intellij.android.selector.action.AndroidSelector\"\n                text=\"Android Selector\"\n                icon=\"/icons/icon.png\"\n                description=\"Generate android selector xml files\">\n            <add-to-group group-id=\"NewGroup\" anchor=\"after\"\n                          relative-to-action=\"NewAndroidAssetImage\"/>\n        </action>\n    </actions>\n\n</idea-plugin>\n"
  },
  {
    "path": "license",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Jaewe Heo\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "readme.md",
    "content": "[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-android--selector--intellij--plugin-green.svg?style=flat)](https://android-arsenal.com/details/1/2342)\n\n\n# android-selector-intellij-plugin ![icon](src/icons/icon@2x.png)\n:art: Generate selectors for background drawable.\n\nYou can use `colorButtonNormal` simply,  \nbut make easily touch feedback of normal `View`s as well as `Button`s with this plugin.\n\n\n## Installation\n\n1. open Android Studio(or IntelliJ)\n2. Preferences :arrow_right: Plugins :arrow_right: Browse Repositories\n3. Search \"Android Selector\"\n4. Click \"Install Plugin\" button\n\n\n## Usage\n- Set your colors(in `res/values/colors.xml`).\n```xml\n<color name=\"colorPrimary\">#519FE5</color>\n<color name=\"colorPrimaryDark\">#388AC6</color>\n<color name=\"colorAccent\">#FFFFFF</color>\n```\n\n- Select `New -> Android Selector(or Ctrl/Cmd + N)` on your `res` directory.  \n\n![screenshot1](images/screenshot1.png)\n\n- Select filename, color, pressed and pressed-v21 respectively.\n\n![screenshot2](images/screenshot2.png)\n\n> ripple drawable is generated in drawable-v21 directory.  \n> normal drawable is generated in drawable directory.\n\n- Use the drawable.\n```xml\n    <android.support.v7.widget.AppCompatButton\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"16dp\"\n        android:background=\"@drawable/<GENERATED_DRAWABLE>\"\n        android:gravity=\"center\"\n        android:minWidth=\"100dp\"\n        android:text=\"pressed\" />\n```\n\n\n## Demo\n\n| Lollipop &gt; | Lollipop &lt;= |\n|---------------|----------------|\n| ![demo1][d1]  | ![demo2][d2]   |\n\n\n## Dependency\n- com.android.support:appcompat-v7:22.+\n\n\n## License\nMIT © [Jaewe Heo][importre]\n\n\n\n\n\n\n\n\n\n\n\n\n[importre]: http://import.re\n[d1]: images/demo1.png\n[d2]: images/demo2.png\n"
  },
  {
    "path": "src/importre/intellij/android/selector/action/AndroidSelector.java",
    "content": "package importre.intellij.android.selector.action;\n\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi.actionSystem.AnActionEvent;\nimport com.intellij.openapi.actionSystem.LangDataKeys;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport importre.intellij.android.selector.form.AndroidSelectorDialog;\n\npublic class AndroidSelector extends AnAction {\n\n    @Override\n    public void update(AnActionEvent e) {\n        super.update(e);\n\n        VirtualFile dir = e.getData(LangDataKeys.VIRTUAL_FILE);\n        if (dir != null && dir.isDirectory()) {\n            String text = dir.getName();\n            e.getPresentation().setVisible(\"res\".equals(text));\n        }\n    }\n\n    @Override\n    public void actionPerformed(AnActionEvent e) {\n        final VirtualFile dir = e.getData(LangDataKeys.VIRTUAL_FILE);\n        if (dir == null) {\n            return;\n        }\n\n        Project project = e.getProject();\n        AndroidSelectorDialog dialog = new AndroidSelectorDialog(project, dir);\n        dialog.show();\n    }\n}\n"
  },
  {
    "path": "src/importre/intellij/android/selector/color/ColorIcon.java",
    "content": "package importre.intellij.android.selector.color;\n\nimport com.intellij.ui.JBColor;\nimport org.jetbrains.annotations.Nullable;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.geom.Rectangle2D;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class ColorIcon implements Icon {\n\n    private final String color;\n\n    public ColorIcon(String color) {\n        if (color == null) {\n            this.color = null;\n        } else {\n            this.color = color.startsWith(\"#\") ? color.substring(1) : null;\n        }\n    }\n\n    public int getIconHeight() {\n        return 16;\n    }\n\n    public int getIconWidth() {\n        return 16;\n    }\n\n    public void paintIcon(Component c, Graphics g, int x, int y) {\n        JBColor color = getColor();\n        if (color == null) {\n            g.setColor(JBColor.WHITE);\n            g.fillRect(1, 1, getIconWidth(), getIconHeight());\n            g.setColor(JBColor.DARK_GRAY);\n\n            if (g instanceof Graphics2D) {\n                RenderingHints.Key key = RenderingHints.KEY_TEXT_ANTIALIASING;\n                Object value = RenderingHints.VALUE_TEXT_ANTIALIAS_ON;\n                ((Graphics2D) g).setRenderingHint(key, value);\n            }\n\n            String q = \"?\";\n            FontMetrics fm = g.getFontMetrics();\n            Rectangle2D r = fm.getStringBounds(q, g);\n            x = (int) ((getIconWidth() - (int) r.getWidth()) * 0.7f);\n            y = (getIconHeight() - (int) r.getHeight()) / 2 + fm.getAscent();\n            g.drawString(q, x, y);\n        } else {\n            g.setColor(color);\n            g.fillRect(1, 1, getIconWidth(), getIconHeight());\n        }\n        g.setColor(JBColor.DARK_GRAY);\n        g.drawRect(1, 1, getIconWidth(), getIconHeight());\n    }\n\n    @Nullable\n    private JBColor getColor() {\n        String regex = \"((?:[0-9a-fA-F]{2})?)\" +\n                \"([0-9a-fA-F]{2})\" +\n                \"([0-9a-fA-F]{2})\" +\n                \"([0-9a-fA-F]{2})\";\n        Pattern p = Pattern.compile(regex);\n        try {\n            if (color == null) {\n                return null;\n            }\n\n            Matcher m = p.matcher(color);\n            if (m.find()) {\n                int r = Integer.parseInt(m.group(2), 16);\n                int g = Integer.parseInt(m.group(3), 16);\n                int b = Integer.parseInt(m.group(4), 16);\n                if (m.group(1).isEmpty()) {\n                    return new JBColor(\n                            new Color(r, g, b),\n                            new Color(r, g, b));\n                } else {\n                    int a = Integer.parseInt(m.group(1), 16);\n                    return new JBColor(\n                            new Color(r, g, b, a),\n                            new Color(r, g, b, a));\n                }\n            }\n        } catch (Exception ignore) {\n        }\n        return null;\n    }\n}\n\n"
  },
  {
    "path": "src/importre/intellij/android/selector/color/ColorItemRenderer.java",
    "content": "package importre.intellij.android.selector.color;\n\nimport javax.swing.*;\nimport java.awt.*;\n\npublic class ColorItemRenderer implements ListCellRenderer {\n    DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();\n\n    @Override\n    public Component getListCellRendererComponent(\n            JList list, Object value,\n            int index, boolean isSelected, boolean cellHasFocus) {\n        Icon icon;\n        String name;\n\n        JLabel renderer = (JLabel) defaultRenderer\n                .getListCellRendererComponent(\n                        list, value, index, isSelected, cellHasFocus);\n\n        String values[] = (String[]) value;\n        name = values[1];\n        icon = new ColorIcon(values[0]);\n\n        renderer.setIcon(icon);\n        renderer.setText(name);\n        return renderer;\n    }\n}\n"
  },
  {
    "path": "src/importre/intellij/android/selector/form/AndroidSelectorDialog.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class=\"importre.intellij.android.selector.form.AndroidSelectorDialog\">\n  <grid id=\"cbd77\" binding=\"contentPane\" layout-manager=\"GridLayoutManager\" row-count=\"1\" column-count=\"1\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n    <margin top=\"10\" left=\"10\" bottom=\"10\" right=\"10\"/>\n    <constraints>\n      <xy x=\"48\" y=\"54\" width=\"541\" height=\"297\"/>\n    </constraints>\n    <properties>\n      <minimumSize width=\"400\" height=\"150\"/>\n    </properties>\n    <border type=\"none\"/>\n    <children>\n      <grid id=\"e3588\" layout-manager=\"GridLayoutManager\" row-count=\"4\" column-count=\"2\" same-size-horizontally=\"false\" same-size-vertically=\"false\" hgap=\"-1\" vgap=\"-1\">\n        <margin top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>\n        <constraints>\n          <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"3\" hsize-policy=\"3\" anchor=\"0\" fill=\"3\" indent=\"0\" use-parent-layout=\"false\"/>\n        </constraints>\n        <properties/>\n        <border type=\"none\"/>\n        <children>\n          <component id=\"d712\" class=\"javax.swing.JLabel\">\n            <constraints>\n              <grid row=\"1\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"color\"/>\n            </properties>\n          </component>\n          <component id=\"6d3ec\" class=\"javax.swing.JLabel\">\n            <constraints>\n              <grid row=\"2\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"pressed\"/>\n            </properties>\n          </component>\n          <component id=\"f2b95\" class=\"javax.swing.JLabel\">\n            <constraints>\n              <grid row=\"3\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"pressed-v21\"/>\n            </properties>\n          </component>\n          <component id=\"13295\" class=\"javax.swing.JLabel\">\n            <constraints>\n              <grid row=\"0\" column=\"0\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"0\" anchor=\"8\" fill=\"0\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <text value=\"filename\"/>\n            </properties>\n          </component>\n          <component id=\"9546b\" class=\"javax.swing.JTextField\" binding=\"filenameText\">\n            <constraints>\n              <grid row=\"0\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"6\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\">\n                <preferred-size width=\"150\" height=\"-1\"/>\n              </grid>\n            </constraints>\n            <properties>\n              <text value=\"selectable_background\"/>\n              <toolTipText value=\"filename of drawable xml\"/>\n            </properties>\n          </component>\n          <component id=\"6223d\" class=\"javax.swing.JComboBox\" binding=\"colorCombo\">\n            <constraints>\n              <grid row=\"1\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"2\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties>\n              <model/>\n            </properties>\n          </component>\n          <component id=\"67df7\" class=\"javax.swing.JComboBox\" binding=\"pressedCombo\">\n            <constraints>\n              <grid row=\"2\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"2\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties/>\n          </component>\n          <component id=\"acac4\" class=\"javax.swing.JComboBox\" binding=\"pressedV21Combo\">\n            <constraints>\n              <grid row=\"3\" column=\"1\" row-span=\"1\" col-span=\"1\" vsize-policy=\"0\" hsize-policy=\"2\" anchor=\"8\" fill=\"1\" indent=\"0\" use-parent-layout=\"false\"/>\n            </constraints>\n            <properties/>\n          </component>\n        </children>\n      </grid>\n    </children>\n  </grid>\n</form>\n"
  },
  {
    "path": "src/importre/intellij/android/selector/form/AndroidSelectorDialog.java",
    "content": "package importre.intellij.android.selector.form;\n\nimport com.intellij.openapi.application.Application;\nimport com.intellij.openapi.application.ApplicationManager;\nimport com.intellij.openapi.project.Project;\nimport com.intellij.openapi.ui.DialogWrapper;\nimport com.intellij.openapi.ui.Messages;\nimport com.intellij.openapi.vfs.VirtualFile;\nimport importre.intellij.android.selector.color.ColorItemRenderer;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NodeList;\n\nimport javax.swing.*;\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.transform.OutputKeys;\nimport javax.xml.transform.Transformer;\nimport javax.xml.transform.TransformerFactory;\nimport javax.xml.transform.dom.DOMSource;\nimport javax.xml.transform.stream.StreamResult;\nimport javax.xml.xpath.XPath;\nimport javax.xml.xpath.XPathConstants;\nimport javax.xml.xpath.XPathExpression;\nimport javax.xml.xpath.XPathFactory;\nimport java.io.*;\nimport java.util.*;\n\npublic class AndroidSelectorDialog extends DialogWrapper {\n\n    private static final String INDENT_SPACE = \"{http://xml.apache.org/xslt}indent-amount\";\n\n    private static final String drawableDir = \"drawable\";\n    private static final String drawableV21Dir = \"drawable-v21\";\n    private static final String valuesColorsXml = \"values/colors.xml\";\n    private static final String localProps = \"local.properties\";\n    private static final String platformsRes = \"%s/platforms/%s/data/res/values\";\n    private static final String nsUri = \"http://www.w3.org/2000/xmlns/\";\n    private static final String androidUri = \"http://schemas.android.com/apk/res/android\";\n\n    private final VirtualFile dir;\n    private final Project project;\n\n    private JPanel contentPane;\n    private JTextField filenameText;\n    private JComboBox colorCombo;\n    private JComboBox pressedCombo;\n    private JComboBox pressedV21Combo;\n\n    public AndroidSelectorDialog(@Nullable Project project, VirtualFile dir) {\n        super(project);\n\n        this.project = project;\n        this.dir = dir;\n        setTitle(\"Android Selector\");\n        setResizable(false);\n        init();\n    }\n\n    @Override\n    public void show() {\n        try {\n            if (initColors(dir)) {\n                super.show();\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    private boolean initColors(VirtualFile dir) {\n        VirtualFile colorsXml = dir.findFileByRelativePath(valuesColorsXml);\n        if (colorsXml != null && colorsXml.exists()) {\n            HashMap<String, String> cmap = parseColorsXml(colorsXml);\n            HashMap<String, String> andCmap = parseAndroidColorsXml();\n\n            if (cmap.isEmpty()) {\n                String title = \"Error\";\n                String msg = \"Cannot find colors in colors.xml\";\n                showMessageDialog(title, msg);\n                return false;\n            }\n\n            String regex = \"^@(android:)?color/(.+$)\";\n            ArrayList<String[]> elements = new ArrayList<String[]>();\n            for (String name : cmap.keySet()) {\n                String color = cmap.get(name);\n                while (color != null && color.matches(regex)) {\n                    if (color.startsWith(\"@color/\")) {\n                        String key = color.replace(\"@color/\", \"\");\n                        color = cmap.get(key);\n                    } else if (color.startsWith(\"@android:color/\")) {\n                        String key = color.replace(\"@android:color/\", \"\");\n                        color = andCmap.get(key);\n                    } else {\n                        // not reachable...\n                    }\n                }\n\n                if (color != null) {\n                    elements.add(new String[]{color, name});\n                }\n            }\n\n            ColorItemRenderer renderer = new ColorItemRenderer();\n            colorCombo.setRenderer(renderer);\n            pressedCombo.setRenderer(renderer);\n            pressedV21Combo.setRenderer(renderer);\n            for (Object element : elements) {\n                colorCombo.addItem(element);\n                pressedCombo.addItem(element);\n                pressedV21Combo.addItem(element);\n            }\n            return !elements.isEmpty();\n        }\n\n        String title = \"Error\";\n        String msg = String.format(\"Cannot find %s\", valuesColorsXml);\n        showMessageDialog(title, msg);\n        return false;\n    }\n\n    @NotNull\n    private HashMap<String, String> parseColorsXml(VirtualFile colorsXml) {\n        HashMap<String, String> map = new LinkedHashMap<String, String>();\n        try {\n            NodeList colors = getColorNodes(colorsXml.getInputStream());\n            makeColorMap(colors, map);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return map;\n    }\n\n    private void makeColorMap(NodeList colors, HashMap<String, String> map) {\n        for (int i = 0; i < colors.getLength(); i++) {\n            Element node = (Element) colors.item(i);\n            String nodeName = node.getNodeName();\n            if (\"color\".equals(nodeName) || \"item\".equals(nodeName)) {\n                String name = node.getAttribute(\"name\");\n                String color = node.getTextContent();\n                if (name != null && color != null && !map.containsKey(name)) {\n                    map.put(name, color);\n                }\n            }\n        }\n    }\n\n    private NodeList getColorNodes(InputStream stream) throws Exception {\n        XPath xPath = XPathFactory.newInstance().newXPath();\n        String expression = \"//item[@type=\\\"color\\\"]|//color\";\n        XPathExpression compile = xPath.compile(expression);\n        DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();\n        DocumentBuilder builder = f.newDocumentBuilder();\n        Document doc = builder.parse(stream);\n        return (NodeList) compile.evaluate(doc, XPathConstants.NODESET);\n    }\n\n    @NotNull\n    private HashMap<String, String> parseAndroidColorsXml() {\n        HashMap<String, String> map = new HashMap<String, String>();\n        if (project == null) return map;\n        VirtualFile baseDir = project.getBaseDir();\n        VirtualFile prop = baseDir.findFileByRelativePath(localProps);\n        if (prop == null) return map;\n\n        Properties properties = new Properties();\n        try {\n            properties.load(prop.getInputStream());\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        String sdkDir = properties.getProperty(\"sdk.dir\");\n        File file = new File(sdkDir + File.separator + \"platforms\");\n        if (!file.isDirectory()) return map;\n\n        ArrayList<String> platforms = new ArrayList<String>();\n        Collections.addAll(platforms, file.list());\n        Collections.reverse(platforms);\n        for (int i = 0, size = platforms.size(); i < size; i++) {\n            String platform = platforms.get(i);\n            if (platform.matches(\"^android-\\\\d+$\")) continue;\n            if (i > 3) break;\n\n            String path = String.format(platformsRes, sdkDir, platform);\n            File[] files = new File(path).listFiles();\n            if (files == null) continue;\n            for (File f : files) {\n                if (f.getName().matches(\"colors.*\\\\.xml\")) {\n                    try {\n                        FileInputStream stream = new FileInputStream(f);\n                        NodeList colors = getColorNodes(stream);\n                        makeColorMap(colors, map);\n                    } catch (Exception e) {\n                        e.printStackTrace();\n                    }\n                }\n            }\n        }\n        return map;\n    }\n\n    @Nullable\n    @Override\n    protected JComponent createCenterPanel() {\n        return contentPane;\n    }\n\n    private String getColorName(JComboBox combo) {\n        Object colorItem = combo.getSelectedItem();\n        try {\n            if (colorItem instanceof Object[]) {\n                return \"@color/\" + ((Object[]) (colorItem))[1];\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return \"\";\n    }\n\n    @Override\n    protected void doOKAction() {\n        String f = filenameText.getText();\n        final String filename = (f.endsWith(\".xml\") ? f : f + \".xml\").trim();\n        final String color = getColorName(colorCombo);\n        final String pressed = getColorName(pressedCombo);\n        final String pressedV21 = getColorName(pressedV21Combo);\n\n        if (!valid(filename, color, pressed, pressedV21)) {\n            String title = \"Invalidation\";\n            String msg = \"color, pressed, pressedV21 must start with `@color/`\";\n            showMessageDialog(title, msg);\n            return;\n        }\n\n        if (exists(filename)) {\n            String title = \"Cannot create files\";\n            String msg = String.format(Locale.US,\n                    \"`%s` already exists\", filename);\n            showMessageDialog(title, msg);\n            return;\n        }\n\n        Application app = ApplicationManager.getApplication();\n        app.runWriteAction(new Runnable() {\n            @Override\n            public void run() {\n                try {\n                    createDrawable(filename, color, pressed);\n                    createDrawableV21(filename, color, pressedV21);\n                } catch (Exception e) {\n                    e.printStackTrace();\n                }\n            }\n        });\n        super.doOKAction();\n    }\n\n    private boolean valid(String filename, String color,\n                          String pressed, String pressedV21) {\n        if (filename.isEmpty() || \".xml\".equals(filename))\n            return false;\n\n        String regex = \"^@color/.+\";\n        return color.matches(regex) ||\n                pressed.matches(regex) ||\n                pressedV21.matches(regex);\n    }\n\n    private boolean exists(String filename) {\n        String[] dirs = new String[]{drawableDir, drawableV21Dir};\n        for (String d : dirs) {\n            VirtualFile f = dir.findChild(d);\n            if (f != null && f.isDirectory()) {\n                VirtualFile dest = f.findChild(filename);\n                if (dest != null && dest.exists()) {\n                    return true;\n                }\n            }\n        }\n\n        return false;\n    }\n\n    private void createDrawable(String filename,\n                                String color,\n                                String pressed) throws Exception {\n        VirtualFile child = dir.findChild(drawableDir);\n        if (child == null) {\n            child = dir.createChildDirectory(null, drawableDir);\n        }\n\n        VirtualFile newXmlFile = child.findChild(filename);\n        if (newXmlFile != null && newXmlFile.exists()) {\n            newXmlFile.delete(null);\n        }\n        newXmlFile = child.createChildData(null, filename);\n\n        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\n        DocumentBuilder builder = factory.newDocumentBuilder();\n\n        Document doc = builder.newDocument();\n        Element root = doc.createElement(\"selector\");\n        root.setAttributeNS(nsUri, \"xmlns:android\", androidUri);\n        doc.appendChild(root);\n\n        Element item = doc.createElement(\"item\");\n        item.setAttribute(\"android:drawable\",\n                \"@drawable/abc_list_selector_disabled_holo_light\");\n        item.setAttribute(\"android:state_enabled\", \"false\");\n        item.setAttribute(\"android:state_focused\", \"true\");\n        item.setAttribute(\"android:state_pressed\", \"true\");\n        root.appendChild(item);\n\n        item = doc.createElement(\"item\");\n        item.setAttribute(\"android:drawable\",\n                \"@drawable/abc_list_selector_disabled_holo_light\");\n        item.setAttribute(\"android:state_enabled\", \"false\");\n        item.setAttribute(\"android:state_focused\", \"true\");\n        root.appendChild(item);\n\n        item = doc.createElement(\"item\");\n        item.setAttribute(\"android:drawable\", pressed);\n        item.setAttribute(\"android:state_focused\", \"true\");\n        item.setAttribute(\"android:state_pressed\", \"true\");\n        root.appendChild(item);\n\n        item = doc.createElement(\"item\");\n        item.setAttribute(\"android:drawable\", pressed);\n        item.setAttribute(\"android:state_focused\", \"false\");\n        item.setAttribute(\"android:state_pressed\", \"true\");\n        root.appendChild(item);\n\n        item = doc.createElement(\"item\");\n        item.setAttribute(\"android:drawable\", color);\n        root.appendChild(item);\n\n        OutputStream os = newXmlFile.getOutputStream(null);\n        PrintWriter out = new PrintWriter(os);\n\n        StringWriter writer = new StringWriter();\n        TransformerFactory tf = TransformerFactory.newInstance();\n        Transformer transformer = tf.newTransformer();\n        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, \"no\");\n        transformer.setOutputProperty(OutputKeys.INDENT, \"yes\");\n        transformer.setOutputProperty(INDENT_SPACE, \"4\");\n        transformer.transform(new DOMSource(doc), new StreamResult(writer));\n\n        out.println(writer.getBuffer().toString());\n        out.close();\n    }\n\n    private void createDrawableV21(String filename,\n                                   String color,\n                                   String pressed) throws Exception {\n        VirtualFile child = dir.findChild(drawableV21Dir);\n        if (child == null) {\n            child = dir.createChildDirectory(null, drawableV21Dir);\n        }\n\n        VirtualFile newXmlFile = child.findChild(filename);\n        if (newXmlFile != null && newXmlFile.exists()) {\n            newXmlFile.delete(null);\n        }\n        newXmlFile = child.createChildData(null, filename);\n\n        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\n        DocumentBuilder builder = factory.newDocumentBuilder();\n\n        Document doc = builder.newDocument();\n        Element root = doc.createElement(\"ripple\");\n        root.setAttributeNS(nsUri, \"xmlns:android\", androidUri);\n        root.setAttribute(\"android:color\", pressed);\n        doc.appendChild(root);\n\n        Element item = doc.createElement(\"item\");\n        item.setAttribute(\"android:drawable\", color);\n        root.appendChild(item);\n\n        OutputStream os = newXmlFile.getOutputStream(null);\n        PrintWriter out = new PrintWriter(os);\n\n        StringWriter writer = new StringWriter();\n        TransformerFactory tf = TransformerFactory.newInstance();\n        Transformer transformer = tf.newTransformer();\n        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, \"no\");\n        transformer.setOutputProperty(OutputKeys.INDENT, \"yes\");\n        transformer.setOutputProperty(INDENT_SPACE, \"4\");\n        transformer.transform(new DOMSource(doc), new StreamResult(writer));\n\n        out.println(writer.getBuffer().toString());\n        out.close();\n    }\n\n    private void showMessageDialog(String title, String message) {\n        Messages.showMessageDialog(\n                project, message, title, Messages.getErrorIcon());\n    }\n}\n"
  }
]