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
;
39 public class FormMergerTreeStructureProvider
implements TreeStructureProvider
{
40 private final Project myProject
;
42 public FormMergerTreeStructureProvider(Project 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
) {
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;
72 forms
= FormClassIndex
.findFormsBoundToClass(myProject
, qName
);
74 catch (ProcessCanceledException e
) {
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
);
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();
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());
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
);
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()]);