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