[tabs] PanelWithActionsAndCloseButton uses proper close method that disposes individu...
[idea/community.git] / platform / vcs-log / impl / src / com / intellij / vcs / log / impl / VcsLogContentProvider.java
1 /*
2  * Copyright 2000-2015 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.intellij.vcs.log.impl;
17
18 import com.intellij.openapi.application.ApplicationManager;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.util.Condition;
21 import com.intellij.openapi.vcs.ProjectLevelVcsManager;
22 import com.intellij.openapi.vcs.VcsListener;
23 import com.intellij.openapi.vcs.changes.ui.ChangesViewContentProvider;
24 import com.intellij.openapi.wm.ToolWindow;
25 import com.intellij.openapi.wm.ToolWindowId;
26 import com.intellij.openapi.wm.ToolWindowManager;
27 import com.intellij.ui.components.JBPanel;
28 import com.intellij.ui.content.Content;
29 import com.intellij.ui.content.TabbedContent;
30 import com.intellij.ui.content.impl.ContentManagerImpl;
31 import com.intellij.util.ContentUtilEx;
32 import com.intellij.util.ContentsUtil;
33 import com.intellij.util.NotNullFunction;
34 import com.intellij.util.containers.ContainerUtil;
35 import com.intellij.util.messages.MessageBusConnection;
36 import com.intellij.vcs.log.ui.VcsLogUiImpl;
37 import org.jetbrains.annotations.NotNull;
38
39 import javax.swing.*;
40 import java.awt.*;
41 import java.util.Arrays;
42 import java.util.List;
43
44 /**
45  * Provides the Content tab to the ChangesView log toolwindow.
46  * <p/>
47  * Delegates to the VcsLogManager.
48  */
49 public class VcsLogContentProvider implements ChangesViewContentProvider {
50   public static final String TAB_NAME = "Log";
51
52   @NotNull private final Project myProject;
53   @NotNull private final VcsLogManager myLogManager;
54   @NotNull private final JPanel myContainer = new JBPanel(new BorderLayout());
55   private MessageBusConnection myConnection;
56
57   public VcsLogContentProvider(@NotNull Project project, @NotNull VcsLogManager logManager) {
58     myProject = project;
59     myLogManager = logManager;
60     myLogManager.setRecreateMainLogHandler(new Runnable() {
61       @Override
62       public void run() {
63         recreateLog();
64       }
65     });
66   }
67
68   @Override
69   public JComponent initContent() {
70     myConnection = myProject.getMessageBus().connect();
71     myConnection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, new MyVcsListener());
72     initContentInternal();
73     return myContainer;
74   }
75
76   private void initContentInternal() {
77     ApplicationManager.getApplication().assertIsDispatchThread();
78     myContainer.add(myLogManager.initMainLog(TAB_NAME), BorderLayout.CENTER);
79   }
80
81   @Override
82   public void disposeContent() {
83     myConnection.disconnect();
84     myContainer.removeAll();
85     myLogManager.disposeLog();
86   }
87
88   public static void openAnotherLogTab(@NotNull Project project) {
89     VcsLogManager logManager = VcsLogManager.getInstance(project);
90     ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.VCS);
91
92     String shortName = generateShortName(toolWindow);
93     VcsLogUiImpl logUi = logManager.createLog(ContentUtilEx.getFullName(TAB_NAME, shortName));
94     addLogTab(logManager, toolWindow, logUi, shortName);
95   }
96
97   @NotNull
98   private static String generateShortName(@NotNull ToolWindow toolWindow) {
99     TabbedContent tabbedContent = ContentUtilEx.findTabbedContent(toolWindow.getContentManager(), TAB_NAME);
100     if (tabbedContent != null) {
101       return String.valueOf(tabbedContent.getTabs().size() + 1);
102     }
103     else {
104       List<Content> contents = ContainerUtil.filter(toolWindow.getContentManager().getContents(), new Condition<Content>() {
105         @Override
106         public boolean value(Content content) {
107           return TAB_NAME.equals(content.getUserData(Content.TAB_GROUP_NAME_KEY));
108         }
109       });
110       return String.valueOf(contents.size() + 1);
111     }
112   }
113
114   private static void addLogTab(@NotNull VcsLogManager logManager,
115                                 @NotNull ToolWindow toolWindow,
116                                 @NotNull VcsLogUiImpl logUi,
117                                 @NotNull String shortName) {
118     logManager.watchTab(ContentUtilEx.getFullName(TAB_NAME, shortName), logUi);
119     logUi.requestFocus();
120     ContentUtilEx
121       .addTabbedContent(toolWindow.getContentManager(), logUi.getMainFrame().getMainComponent(), TAB_NAME, shortName, true, logUi);
122     toolWindow.activate(null);
123   }
124
125   private void closeLogTabs() {
126     ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.VCS);
127
128     for (Content content: toolWindow.getContentManager().getContents()) {
129       if (ContentUtilEx.isContentTab(content, TAB_NAME)) {
130         ContentsUtil.closeContentTab(toolWindow.getContentManager(), content);
131       }
132     }
133   }
134
135   private void recreateLog() {
136     myContainer.removeAll();
137     closeLogTabs();
138
139     myLogManager.disposeLog();
140
141     initContentInternal();
142   }
143
144   private class MyVcsListener implements VcsListener {
145     @Override
146     public void directoryMappingChanged() {
147       ApplicationManager.getApplication().invokeLater(new Runnable() {
148         @Override
149         public void run() {
150           recreateLog();
151         }
152       });
153     }
154   }
155
156   public static class VcsLogVisibilityPredicate implements NotNullFunction<Project, Boolean> {
157     @NotNull
158     @Override
159     public Boolean fun(Project project) {
160       return !VcsLogManager.findLogProviders(Arrays.asList(ProjectLevelVcsManager.getInstance(project).getAllVcsRoots()), project)
161         .isEmpty();
162     }
163   }
164 }