allow dumb mode
[idea/community.git] / python / ide / src / com / jetbrains / python / configuration / PyContentEntriesModuleConfigurable.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
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 com.jetbrains.python.configuration;
17
18 import com.intellij.facet.impl.DefaultFacetsProvider;
19 import com.intellij.openapi.application.ApplicationManager;
20 import com.intellij.openapi.module.Module;
21 import com.intellij.openapi.module.impl.ModuleConfigurationStateImpl;
22 import com.intellij.openapi.options.Configurable;
23 import com.intellij.openapi.options.ConfigurationException;
24 import com.intellij.openapi.options.SearchableConfigurable;
25 import com.intellij.openapi.project.DumbService;
26 import com.intellij.openapi.roots.ModifiableRootModel;
27 import com.intellij.openapi.roots.ModuleRootManager;
28 import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
29 import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
30 import com.intellij.openapi.util.Computable;
31 import com.jetbrains.python.module.PyContentEntriesEditor;
32 import org.jetbrains.annotations.NotNull;
33 import org.jetbrains.jps.model.java.JavaSourceRootType;
34
35 import javax.swing.*;
36 import java.awt.*;
37
38 import static com.intellij.openapi.project.DumbModePermission.MAY_START_BACKGROUND;
39
40 public class PyContentEntriesModuleConfigurable extends SearchableConfigurable.Parent.Abstract {
41   private final Module myModule;
42   private final JPanel myTopPanel = new JPanel(new BorderLayout());
43   protected ModifiableRootModel myModifiableModel;
44   protected PyContentEntriesEditor myEditor;
45
46   public PyContentEntriesModuleConfigurable(final Module module) {
47     myModule = module;
48   }
49
50   @Override
51   public String getDisplayName() {
52     return "Project Structure";
53   }
54
55   @Override
56   public String getHelpTopic() {
57     return "reference.settingsdialog.project.structure";
58   }
59
60   @Override
61   public JComponent createComponent() {
62     createEditor();
63     return myTopPanel;
64   }
65
66   private void createEditor() {
67     if (myModule == null) return;
68     myModifiableModel = ApplicationManager.getApplication().runReadAction(new Computable<ModifiableRootModel>() {
69       @Override
70       public ModifiableRootModel compute() {
71         return ModuleRootManager.getInstance(myModule).getModifiableModel();
72       }
73     });
74
75     final ModuleConfigurationStateImpl moduleConfigurationState =
76       new ModuleConfigurationStateImpl(myModule.getProject(), new DefaultModulesProvider(myModule.getProject())) {
77         @Override
78         public ModifiableRootModel getRootModel() {
79           return myModifiableModel;
80         }
81
82         @Override
83         public FacetsProvider getFacetsProvider() {
84           return DefaultFacetsProvider.INSTANCE;
85         }
86       };
87     myEditor = createEditor(myModule, moduleConfigurationState);
88
89     JComponent component = ApplicationManager.getApplication().runReadAction(new Computable<JComponent>() {
90       @Override
91       public JComponent compute() {
92         return myEditor.createComponent();
93       }
94     });
95     myTopPanel.add(component, BorderLayout.CENTER);
96   }
97
98   protected PyContentEntriesEditor createEditor(@NotNull Module module, @NotNull ModuleConfigurationStateImpl state) {
99     return new PyContentEntriesEditor(module, state, JavaSourceRootType.SOURCE);
100   }
101
102   @Override
103   public boolean isModified() {
104     return myEditor != null && myEditor.isModified();
105   }
106
107   @Override
108   public void apply() throws ConfigurationException {
109     if (myEditor == null) return;
110     final boolean editorWasModified = myEditor.isModified();
111     myEditor.apply();
112     if (editorWasModified) {
113       DumbService.getInstance(myModifiableModel.getProject()).allowStartingDumbModeInside(MAY_START_BACKGROUND, new Runnable() {
114         @Override
115         public void run() {
116           ApplicationManager.getApplication().runWriteAction(new Runnable() {
117             @Override
118             public void run() {
119               myModifiableModel.commit();
120             }
121           });
122         }
123       });
124       resetEditor();
125     }
126   }
127
128   @Override
129   public void reset() {
130     if (myEditor == null) return;
131     if (myModifiableModel != null) {
132       myModifiableModel.dispose();
133     }
134     resetEditor();
135   }
136
137   private void resetEditor() {
138     myEditor.disposeUIResources();
139     myTopPanel.remove(myEditor.getComponent());
140     createEditor();
141   }
142
143   @Override
144   public void disposeUIResources() {
145     if (myEditor != null) {
146       myEditor.disposeUIResources();
147       myTopPanel.remove(myEditor.getComponent());
148       myEditor = null;
149     }
150     if (myModifiableModel != null) {
151       myModifiableModel.dispose();
152       myModifiableModel = null;
153     }
154   }
155
156   @Override
157   protected Configurable[] buildConfigurables() {
158     return new Configurable[0];
159   }
160
161   @Override
162   @NotNull
163   public String getId() {
164     return "python.project.structure";
165   }
166
167 }