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.
17 package com
.intellij
.uiDesigner
.propertyInspector
.properties
;
19 import com
.intellij
.openapi
.application
.ApplicationManager
;
20 import com
.intellij
.openapi
.command
.CommandProcessor
;
21 import com
.intellij
.openapi
.components
.ServiceManager
;
22 import com
.intellij
.openapi
.diagnostic
.Logger
;
23 import com
.intellij
.openapi
.fileEditor
.OpenFileDescriptor
;
24 import com
.intellij
.openapi
.project
.Project
;
25 import com
.intellij
.openapi
.ui
.Messages
;
26 import com
.intellij
.openapi
.util
.Ref
;
27 import com
.intellij
.openapi
.vfs
.ReadonlyStatusHandler
;
28 import com
.intellij
.openapi
.vfs
.VirtualFile
;
29 import com
.intellij
.psi
.*;
30 import com
.intellij
.psi
.codeStyle
.CodeStyleManager
;
31 import com
.intellij
.psi
.util
.PsiTreeUtil
;
32 import com
.intellij
.uiDesigner
.FormEditingUtil
;
33 import com
.intellij
.uiDesigner
.UIDesignerBundle
;
34 import com
.intellij
.uiDesigner
.compiler
.AsmCodeGenerator
;
35 import com
.intellij
.uiDesigner
.compiler
.Utils
;
36 import com
.intellij
.uiDesigner
.lw
.IRootContainer
;
37 import com
.intellij
.uiDesigner
.propertyInspector
.InplaceContext
;
38 import com
.intellij
.uiDesigner
.propertyInspector
.Property
;
39 import com
.intellij
.uiDesigner
.propertyInspector
.PropertyEditor
;
40 import com
.intellij
.uiDesigner
.propertyInspector
.PropertyRenderer
;
41 import com
.intellij
.uiDesigner
.propertyInspector
.editors
.BooleanEditor
;
42 import com
.intellij
.uiDesigner
.propertyInspector
.renderers
.BooleanRenderer
;
43 import com
.intellij
.uiDesigner
.radComponents
.RadComponent
;
44 import com
.intellij
.util
.IncorrectOperationException
;
45 import org
.jetbrains
.annotations
.NotNull
;
48 import java
.util
.List
;
53 public class CustomCreateProperty
extends Property
<RadComponent
, Boolean
> {
54 private static final Logger LOG
= Logger
.getInstance("#com.intellij.uiDesigner.propertyInspector.properties.CustomCreateProperty");
56 public static CustomCreateProperty
getInstance(Project project
) {
57 return ServiceManager
.getService(project
, CustomCreateProperty
.class);
60 private final BooleanRenderer myRenderer
= new BooleanRenderer();
62 private final BooleanEditor myEditor
= new BooleanEditor() {
64 public JComponent
getComponent(final RadComponent component
, final Boolean value
, final InplaceContext inplaceContext
) {
65 JCheckBox result
= (JCheckBox
) super.getComponent(component
, value
, inplaceContext
);
66 final boolean customCreateRequired
= component
.isCustomCreateRequired();
67 if (customCreateRequired
) {
68 result
.setEnabled(false);
69 result
.setSelected(true);
72 result
.setEnabled(true);
78 public CustomCreateProperty() {
79 super(null, "Custom Create");
82 public Boolean
getValue(final RadComponent component
) {
83 return component
.isCustomCreate();
87 public PropertyRenderer
<Boolean
> getRenderer() {
91 public PropertyEditor
<Boolean
> getEditor() {
96 public boolean appliesToSelection(final List
<RadComponent
> selection
) {
97 if (selection
.size() > 1) {
98 // possible "enabled" state may be different
99 for(RadComponent c
: selection
) {
100 if (c
.isCustomCreateRequired()) {
108 protected void setValueImpl(final RadComponent component
, final Boolean value
) throws Exception
{
109 if (value
.booleanValue() && component
.getBinding() == null) {
110 String initialBinding
= BindingProperty
.getDefaultBinding(component
);
111 String binding
= Messages
.showInputDialog(
112 component
.getProject(),
113 UIDesignerBundle
.message("custom.create.field.name.prompt"),
114 UIDesignerBundle
.message("custom.create.title"), Messages
.getQuestionIcon(),
115 initialBinding
, new IdentifierValidator(component
.getProject()));
116 if (binding
== null) {
120 new BindingProperty(component
.getProject()).setValue(component
, binding
);
122 catch (Exception e1
) {
126 component
.setCustomCreate(value
.booleanValue());
127 if (value
.booleanValue()) {
128 final IRootContainer root
= FormEditingUtil
.getRoot(component
);
129 if (root
.getClassToBind() != null && Utils
.getCustomCreateComponentCount(root
) == 1) {
130 final PsiClass aClass
= FormEditingUtil
.findClassToBind(component
.getModule(), root
.getClassToBind());
131 if (aClass
!= null && FormEditingUtil
.findCreateComponentsMethod(aClass
) == null) {
132 generateCreateComponentsMethod(aClass
);
138 public static void generateCreateComponentsMethod(final PsiClass aClass
) {
139 final ReadonlyStatusHandler roHandler
= ReadonlyStatusHandler
.getInstance(aClass
.getProject());
140 final PsiFile psiFile
= aClass
.getContainingFile();
141 if (psiFile
== null) return;
142 final VirtualFile vFile
= psiFile
.getVirtualFile();
143 if (vFile
== null) return;
144 final ReadonlyStatusHandler
.OperationStatus status
= roHandler
.ensureFilesWritable(vFile
);
145 if (status
.hasReadonlyFiles()) return;
147 final Ref
<SmartPsiElementPointer
> refMethod
= new Ref
<SmartPsiElementPointer
>();
148 CommandProcessor
.getInstance().executeCommand(
152 ApplicationManager
.getApplication().runWriteAction(new Runnable() {
154 PsiElementFactory factory
= JavaPsiFacade
.getInstance(aClass
.getProject()).getElementFactory();
157 method
= factory
.createMethodFromText("private void " +
158 AsmCodeGenerator
.CREATE_COMPONENTS_METHOD_NAME
+
159 "() { \n // TODO: place custom component creation code here \n }",
161 final PsiMethod psiMethod
= (PsiMethod
)aClass
.add(method
);
162 refMethod
.set(SmartPointerManager
.getInstance(aClass
.getProject()).createSmartPsiElementPointer(psiMethod
));
163 CodeStyleManager
.getInstance(aClass
.getProject()).reformat(psiMethod
);
165 catch (IncorrectOperationException e
) {
174 if (!refMethod
.isNull()) {
175 SwingUtilities
.invokeLater(new Runnable() {
177 final PsiMethod element
= (PsiMethod
) refMethod
.get().getElement();
178 if (element
!= null) {
179 final PsiCodeBlock body
= element
.getBody();
181 final PsiComment comment
= PsiTreeUtil
.getChildOfType(body
, PsiComment
.class);
182 if (comment
!= null) {
183 new OpenFileDescriptor(comment
.getProject(), vFile
,
184 comment
.getTextOffset()).navigate(true);