update copyright
[fedora-idea.git] / plugins / ui-designer / src / com / intellij / uiDesigner / projectView / FormMergerTreeStructureProvider.java
blobe410cf08563302a9f8c362b5d80368181e7616ae
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.uiDesigner.projectView;
18 import com.intellij.ide.DeleteProvider;
19 import com.intellij.ide.projectView.ProjectViewNode;
20 import com.intellij.ide.projectView.TreeStructureProvider;
21 import com.intellij.ide.projectView.ViewSettings;
22 import com.intellij.ide.projectView.impl.nodes.BasePsiNode;
23 import com.intellij.ide.util.DeleteHandler;
24 import com.intellij.ide.util.treeView.AbstractTreeNode;
25 import com.intellij.openapi.actionSystem.DataConstants;
26 import com.intellij.openapi.actionSystem.DataContext;
27 import com.intellij.openapi.actionSystem.PlatformDataKeys;
28 import com.intellij.openapi.fileTypes.StdFileTypes;
29 import com.intellij.openapi.progress.ProcessCanceledException;
30 import com.intellij.openapi.project.Project;
31 import com.intellij.psi.PsiClass;
32 import com.intellij.psi.PsiElement;
33 import com.intellij.psi.PsiFile;
34 import com.intellij.refactoring.actions.MoveAction;
35 import com.intellij.uiDesigner.binding.FormClassIndex;
37 import java.util.*;
39 public class FormMergerTreeStructureProvider implements TreeStructureProvider {
40 private final Project myProject;
42 public FormMergerTreeStructureProvider(Project project) {
43 myProject = project;
46 public Collection<AbstractTreeNode> modify(AbstractTreeNode parent, Collection<AbstractTreeNode> children, ViewSettings settings) {
47 if (parent.getValue() instanceof Form) return children;
49 // Optimization. Check if there are any forms at all.
50 boolean formsFound = false;
51 for (AbstractTreeNode node : children) {
52 if (node.getValue() instanceof PsiFile) {
53 PsiFile file = (PsiFile)node.getValue();
54 if (file.getFileType() == StdFileTypes.GUI_DESIGNER_FORM) {
55 formsFound = true;
56 break;
61 if (!formsFound) return children;
63 Collection<AbstractTreeNode> result = new LinkedHashSet<AbstractTreeNode>(children);
64 ProjectViewNode[] copy = children.toArray(new ProjectViewNode[children.size()]);
65 for (ProjectViewNode element : copy) {
66 if (element.getValue() instanceof PsiClass) {
67 PsiClass aClass = (PsiClass)element.getValue();
68 final String qName = aClass.getQualifiedName();
69 if (qName == null) continue;
70 List<PsiFile> forms;
71 try {
72 forms = FormClassIndex.findFormsBoundToClass(myProject, qName);
74 catch (ProcessCanceledException e) {
75 continue;
77 Collection<BasePsiNode<? extends PsiElement>> formNodes = findFormsIn(children, forms);
78 if (!formNodes.isEmpty()) {
79 Collection<PsiFile> formFiles = convertToFiles(formNodes);
80 Collection<BasePsiNode<? extends PsiElement>> subNodes = new ArrayList<BasePsiNode<? extends PsiElement>>();
81 //noinspection unchecked
82 subNodes.add((BasePsiNode<? extends PsiElement>) element);
83 subNodes.addAll(formNodes);
84 result.add(new FormNode(myProject, new Form(aClass, formFiles), settings, subNodes));
85 result.remove(element);
86 result.removeAll(formNodes);
90 return result;
93 public Object getData(Collection<AbstractTreeNode> selected, String dataId) {
94 if (selected != null) {
95 if (dataId.equals(Form.DATA_KEY.getName())) {
96 List<Form> result = new ArrayList<Form>();
97 for(AbstractTreeNode node: selected) {
98 if (node.getValue() instanceof Form) {
99 result.add((Form) node.getValue());
102 if (!result.isEmpty()) {
103 return result.toArray(new Form[result.size()]);
106 else if (dataId.equals(DataConstants.DELETE_ELEMENT_PROVIDER)) {
107 for(AbstractTreeNode node: selected) {
108 if (node.getValue() instanceof Form) {
109 return new MyDeleteProvider(selected);
113 else if (dataId.equals(MoveAction.MOVE_PROVIDER)) {
114 for(AbstractTreeNode node: selected) {
115 if (node.getValue() instanceof Form) {
116 return new FormMoveProvider();
121 return null;
124 private static Collection<PsiFile> convertToFiles(Collection<BasePsiNode<? extends PsiElement>> formNodes) {
125 ArrayList<PsiFile> psiFiles = new ArrayList<PsiFile>();
126 for (AbstractTreeNode treeNode : formNodes) {
127 psiFiles.add((PsiFile)treeNode.getValue());
129 return psiFiles;
132 private static Collection<BasePsiNode<? extends PsiElement>> findFormsIn(Collection<AbstractTreeNode> children, List<PsiFile> forms) {
133 if (children.isEmpty() || forms.isEmpty()) return Collections.emptyList();
134 ArrayList<BasePsiNode<? extends PsiElement>> result = new ArrayList<BasePsiNode<? extends PsiElement>>();
135 HashSet<PsiFile> psiFiles = new HashSet<PsiFile>(forms);
136 for (final AbstractTreeNode child : children) {
137 if (child instanceof BasePsiNode) {
138 //noinspection unchecked
139 BasePsiNode<? extends PsiElement> treeNode = (BasePsiNode<? extends PsiElement>)child;
140 //noinspection SuspiciousMethodCalls
141 if (psiFiles.contains(treeNode.getValue())) result.add(treeNode);
144 return result;
147 private static class MyDeleteProvider implements DeleteProvider {
148 private final PsiElement[] myElements;
150 public MyDeleteProvider(final Collection<AbstractTreeNode> selected) {
151 myElements = collectFormPsiElements(selected);
154 public void deleteElement(DataContext dataContext) {
155 Project project = PlatformDataKeys.PROJECT.getData(dataContext);
156 DeleteHandler.deletePsiElement(myElements, project);
159 public boolean canDeleteElement(DataContext dataContext) {
160 return DeleteHandler.shouldEnableDeleteAction(myElements);
163 private static PsiElement[] collectFormPsiElements(Collection<AbstractTreeNode> selected) {
164 Set<PsiElement> result = new HashSet<PsiElement>();
165 for(AbstractTreeNode node: selected) {
166 if (node.getValue() instanceof Form) {
167 Form form = (Form) node.getValue();
168 result.add(form.getClassToBind());
169 result.addAll(Arrays.asList(form.getFormFiles()));
171 else if (node.getValue() instanceof PsiElement) {
172 result.add((PsiElement) node.getValue());
175 return result.toArray(new PsiElement[result.size()]);