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 org
.jetbrains
.idea
.maven
.navigator
;
18 import com
.intellij
.openapi
.components
.PersistentStateComponent
;
19 import com
.intellij
.openapi
.components
.State
;
20 import com
.intellij
.openapi
.components
.Storage
;
21 import com
.intellij
.openapi
.project
.DumbAwareRunnable
;
22 import com
.intellij
.openapi
.project
.Project
;
23 import com
.intellij
.openapi
.wm
.ToolWindow
;
24 import com
.intellij
.openapi
.wm
.ToolWindowAnchor
;
25 import com
.intellij
.openapi
.wm
.ToolWindowManager
;
26 import com
.intellij
.openapi
.util
.Pair
;
27 import com
.intellij
.ui
.treeStructure
.SimpleTree
;
28 import com
.intellij
.util
.containers
.ContainerUtil
;
29 import org
.jetbrains
.annotations
.TestOnly
;
30 import org
.jetbrains
.idea
.maven
.project
.*;
31 import org
.jetbrains
.idea
.maven
.project
.MavenProject
;
32 import org
.jetbrains
.idea
.maven
.tasks
.MavenShortcutsManager
;
33 import org
.jetbrains
.idea
.maven
.tasks
.MavenTasksManager
;
34 import org
.jetbrains
.idea
.maven
.utils
.MavenIcons
;
35 import org
.jetbrains
.idea
.maven
.utils
.MavenUtil
;
36 import org
.jetbrains
.idea
.maven
.utils
.SimpleProjectComponent
;
39 import javax
.swing
.tree
.TreeSelectionModel
;
42 import java
.util
.Collections
;
43 import java
.util
.List
;
44 import java
.util
.concurrent
.atomic
.AtomicBoolean
;
46 @State(name
= "MavenProjectNavigator", storages
= {@Storage(id
= "default", file
= "$WORKSPACE_FILE$")})
47 public class MavenProjectsNavigator
extends SimpleProjectComponent
implements PersistentStateComponent
<MavenProjectsNavigatorState
> {
48 public static final String TOOL_WINDOW_ID
= "Maven Projects";
50 private static final URL ADD_ICON_URL
= MavenProjectsNavigator
.class.getResource("/general/add.png");
51 private static final URL SYNC_ICON_URL
= MavenProjectsNavigator
.class.getResource("/actions/sync.png");
53 private final AtomicBoolean myInitialized
= new AtomicBoolean(false);
55 private MavenProjectsNavigatorState myState
= new MavenProjectsNavigatorState();
57 private final MavenProjectsManager myProjectsManager
;
58 private final MavenTasksManager myTasksManager
;
59 private final MavenShortcutsManager myShortcutsManager
;
61 private SimpleTree myTree
;
62 private MavenProjectsStructure myStructure
;
64 public static MavenProjectsNavigator
getInstance(Project project
) {
65 return project
.getComponent(MavenProjectsNavigator
.class);
68 public MavenProjectsNavigator(Project project
,
69 MavenProjectsManager projectsManager
,
70 MavenTasksManager tasksManager
,
71 MavenShortcutsManager shortcutsManager
) {
73 myProjectsManager
= projectsManager
;
74 myTasksManager
= tasksManager
;
75 myShortcutsManager
= shortcutsManager
;
78 public MavenProjectsNavigatorState
getState() {
82 public void loadState(MavenProjectsNavigatorState state
) {
87 public boolean getGroupModules() {
88 return myState
.groupStructurally
;
91 public void setGroupModules(boolean value
) {
92 if (myState
.groupStructurally
!= value
) {
93 myState
.groupStructurally
= value
;
98 public boolean getShowIgnored() {
99 return myState
.showIgnored
;
102 public void setShowIgnored(boolean value
) {
103 if (myState
.showIgnored
!= value
) {
104 myState
.showIgnored
= value
;
109 public boolean getShowBasicPhasesOnly() {
110 return myState
.showBasicPhasesOnly
;
113 public void setShowBasicPhasesOnly(boolean value
) {
114 if (myState
.showBasicPhasesOnly
!= value
) {
115 myState
.showBasicPhasesOnly
= value
;
121 public void initComponent() {
122 if (!isNormalProject()) return;
127 public void initForTests() {
131 private void doInit() {
132 if (myInitialized
.getAndSet(true)) return;
135 listenForActivation();
137 if (isUnitTestMode()) return;
139 MavenUtil
.runWhenInitialized(myProject
, new DumbAwareRunnable() {
147 public void disposeComponent() {
148 myInitialized
.set(false);
151 private boolean isInitialized() {
152 return myInitialized
.get();
155 private void initTree() {
156 myTree
= new SimpleTree() {
157 private final JLabel myLabel
= new JLabel(ProjectBundle
.message("maven.navigator.nothing.to.display",
158 MavenUtil
.formatHtmlImage(ADD_ICON_URL
),
159 MavenUtil
.formatHtmlImage(SYNC_ICON_URL
)));
162 protected void paintComponent(Graphics g
) {
163 super.paintComponent(g
);
164 if (myProjectsManager
.hasProjects()) return;
166 myLabel
.setFont(getFont());
167 myLabel
.setBackground(getBackground());
168 myLabel
.setForeground(getForeground());
169 Rectangle bounds
= getBounds();
170 Dimension size
= myLabel
.getPreferredSize();
171 myLabel
.setBounds(0, 0, size
.width
, size
.height
);
173 int x
= (bounds
.width
- size
.width
) / 2;
174 Graphics g2
= g
.create(bounds
.x
+ x
, bounds
.y
+ 20, bounds
.width
, bounds
.height
);
184 myTree
.getSelectionModel().setSelectionMode(TreeSelectionModel
.DISCONTIGUOUS_TREE_SELECTION
);
185 myStructure
= new MavenProjectsStructure(myProject
, myProjectsManager
, myTasksManager
, myShortcutsManager
, this, myTree
);
188 private void listenForActivation() {
189 myProjectsManager
.addManagerListener(new MavenProjectsManager
.Listener() {
190 public void activated() {
191 scheduleStructureUpdate(new Runnable() {
193 myStructure
.buildTree();
196 listenForProjectsChanges();
199 public void scheduledImportsChanged() {
204 private void listenForProjectsChanges() {
205 myProjectsManager
.addProjectsTreeListener(new MyProjectsListener());
207 myShortcutsManager
.addListener(new MavenShortcutsManager
.Listener() {
208 public void shortcutsUpdated() {
209 scheduleStructureUpdate(new Runnable() {
211 myStructure
.updateGoals();
217 myTasksManager
.addListener(new MavenTasksManager
.Listener() {
218 public void compileTasksChanged() {
219 scheduleStructureUpdate(new Runnable() {
221 myStructure
.updateGoals();
228 private void initToolWindow() {
229 JPanel panel
= new MavenProjectsNavigatorPanel(myProject
, myTree
);
231 ToolWindowManager manager
= ToolWindowManager
.getInstance(myProject
);
232 ToolWindow toolWindow
= manager
.registerToolWindow(TOOL_WINDOW_ID
, panel
, ToolWindowAnchor
.RIGHT
, myProject
, true);
233 toolWindow
.setIcon(MavenIcons
.MAVEN_ICON
);
236 private void update(boolean restructure
) {
237 if (!isInitialized()) return;
238 myStructure
.update(restructure
);
241 public void selectInTree(MavenProject project
) {
242 if (!isInitialized()) return;
243 myStructure
.select(project
);
247 public MavenProjectsStructure
getStructureForTests() {
251 private void scheduleStructureUpdate(Runnable r
) {
252 MavenUtil
.invokeLater(myProject
, r
);
255 private class MyProjectsListener
extends MavenProjectsTree
.ListenerAdapter
{
257 public void projectsIgnoredStateChanged(final List
<MavenProject
> ignored
, final List
<MavenProject
> unignored
, Object message
) {
258 scheduleStructureUpdate(new Runnable() {
260 myStructure
.updateIgnored(ContainerUtil
.concat(ignored
, unignored
));
266 public void profilesChanged(final List
<String
> profiles
) {
267 scheduleStructureUpdate(new Runnable() {
269 myStructure
.setActiveProfiles(profiles
);
275 public void projectsUpdated(final List
<Pair
<MavenProject
, MavenProjectChanges
>> updated
,
276 final List
<MavenProject
> deleted
,
278 scheduleStructureUpdate(new Runnable() {
280 myStructure
.updateProjects(MavenUtil
.collectFirsts(updated
), deleted
);
285 public void projectResolved(Pair
<MavenProject
, MavenProjectChanges
> projectWithChanges
,
286 org
.apache
.maven
.project
.MavenProject nativeMavenProject
,
288 updateProject(projectWithChanges
.first
);
291 public void pluginsResolved(MavenProject project
) {
292 updateProject(project
);
295 private void updateProject(final MavenProject project
) {
296 scheduleStructureUpdate(new Runnable() {
298 myStructure
.updateProjects(Collections
.singletonList(project
), Collections
.EMPTY_LIST
);