1ef90b233c57e12c92058564ced9513c2a5cc8cc
[idea/community.git] / platform / platform-impl / src / com / intellij / util / ContentUtilEx.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.util;
17
18 import com.intellij.ide.util.PropertiesComponent;
19 import com.intellij.openapi.Disposable;
20 import com.intellij.openapi.util.Comparing;
21 import com.intellij.openapi.util.Condition;
22 import com.intellij.openapi.util.Disposer;
23 import com.intellij.openapi.util.Pair;
24 import com.intellij.ui.content.Content;
25 import com.intellij.ui.content.ContentFactory;
26 import com.intellij.ui.content.ContentManager;
27 import com.intellij.ui.content.TabbedContent;
28 import com.intellij.ui.content.impl.TabbedContentImpl;
29 import org.jetbrains.annotations.NotNull;
30 import org.jetbrains.annotations.Nullable;
31
32 import javax.swing.*;
33 import java.util.ArrayList;
34 import java.util.List;
35
36 /**
37  * @author Konstantin Bulenkov
38  */
39 public class ContentUtilEx extends ContentsUtil {
40
41   public static void addTabbedContent(@NotNull ContentManager manager,
42                                       @NotNull JComponent contentComponent,
43                                       @NotNull String groupPrefix,
44                                       @NotNull String tabName,
45                                       boolean select) {
46     addTabbedContent(manager, contentComponent, groupPrefix, tabName, select, null);
47   }
48
49   public static void addTabbedContent(@NotNull ContentManager manager,
50                                       @NotNull JComponent contentComponent,
51                                       @NotNull String groupPrefix,
52                                       @NotNull String tabName,
53                                       boolean select,
54                                       @Nullable Disposable childDisposable) {
55     if (PropertiesComponent.getInstance().getBoolean(TabbedContent.SPLIT_PROPERTY_PREFIX + groupPrefix)) {
56       final Content content = ContentFactory.SERVICE.getInstance().createContent(contentComponent, getFullName(groupPrefix, tabName), true);
57       content.putUserData(Content.TABBED_CONTENT_KEY, Boolean.TRUE);
58       content.putUserData(Content.TAB_GROUP_NAME_KEY, groupPrefix);
59
60       for (Content c : manager.getContents()) {
61         if (c.getComponent() == contentComponent) {
62           if (select) {
63             manager.setSelectedContent(c);
64           }
65           return;
66         }
67       }
68       addContent(manager, content, select);
69
70       registerDisposable(content, childDisposable, contentComponent);
71
72       return;
73     }
74
75     TabbedContent tabbedContent = findTabbedContent(manager, groupPrefix);
76
77     if (tabbedContent == null) {
78       final Disposable disposable = Disposer.newDisposable();
79       tabbedContent = new TabbedContentImpl(contentComponent, tabName, true, groupPrefix);
80       ContentsUtil.addOrReplaceContent(manager, tabbedContent, select);
81       Disposer.register(tabbedContent, disposable);
82     }
83     else {
84       for (Pair<String, JComponent> tab : new ArrayList<>(tabbedContent.getTabs())) {
85         if (Comparing.equal(tab.second, contentComponent)) {
86           tabbedContent.removeContent(tab.second);
87         }
88       }
89       if (select) {
90         manager.setSelectedContent(tabbedContent, true, true);
91       }
92       tabbedContent.addContent(contentComponent, tabName, true);
93     }
94
95     registerDisposable(tabbedContent, childDisposable, contentComponent);
96   }
97
98   private static void registerDisposable(@NotNull Content content,
99                                          @Nullable Disposable childDisposable,
100                                          @NotNull JComponent contentComponent) {
101     if (childDisposable != null) {
102       Disposer.register(content, childDisposable);
103       assert contentComponent.getClientProperty(DISPOSABLE_KEY) == null;
104       contentComponent.putClientProperty(DISPOSABLE_KEY, childDisposable);
105       Disposer.register(childDisposable, () -> contentComponent.putClientProperty(DISPOSABLE_KEY, null));
106     }
107     else {
108       Object disposableByKey = contentComponent.getClientProperty(DISPOSABLE_KEY);
109       if (disposableByKey != null && disposableByKey instanceof Disposable) {
110         Disposer.register(content, (Disposable)disposableByKey);
111       }
112     }
113   }
114
115   @Nullable
116   public static TabbedContent findTabbedContent(@NotNull ContentManager manager, @NotNull String groupPrefix) {
117     TabbedContent tabbedContent = null;
118     for (Content content : manager.getContents()) {
119       if (content instanceof TabbedContent && content.getTabName().startsWith(getFullPrefix(groupPrefix))) {
120         tabbedContent = (TabbedContent)content;
121         break;
122       }
123     }
124     return tabbedContent;
125   }
126
127   public static boolean isContentTab(@NotNull Content content, @NotNull String groupPrefix) {
128     return (content instanceof TabbedContent && content.getTabName().startsWith(getFullPrefix(groupPrefix))) ||
129            groupPrefix.equals(content.getUserData(Content.TAB_GROUP_NAME_KEY));
130   }
131
132   @NotNull
133   public static String getFullName(@NotNull String groupPrefix, @NotNull String tabName) {
134     return getFullPrefix(groupPrefix) + tabName;
135   }
136
137   @NotNull
138   private static String getFullPrefix(@NotNull String groupPrefix) {
139     return groupPrefix + ": ";
140   }
141
142   /**
143    * Searches through all {@link Content simple} and {@link TabbedContent tabbed} contents of the given ContentManager,
144    * and selects the one which holds the specified {@code contentComponent}.
145    *
146    * @return true if the necessary content was found (and thus selected) among content components of the given ContentManager.
147    */
148   public static boolean selectContent(@NotNull ContentManager manager, @NotNull final JComponent contentComponent, boolean requestFocus) {
149     for (Content content : manager.getContents()) {
150       if (content instanceof TabbedContentImpl) {
151         boolean found = ((TabbedContentImpl)content).findAndSelectContent(contentComponent);
152         if (found) {
153           manager.setSelectedContent(content, requestFocus);
154           return true;
155         }
156       }
157       else if (Comparing.equal(content.getComponent(), contentComponent)) {
158         manager.setSelectedContent(content, requestFocus);
159         return true;
160       }
161     }
162     return false;
163   }
164
165   /**
166    * Searches through all {@link Content simple} and {@link TabbedContent tabbed} contents of the given ContentManager,
167    * trying to find the first one which matches the given condition.
168    */
169   @Nullable
170   public static JComponent findContentComponent(@NotNull ContentManager manager, @NotNull Condition<JComponent> condition) {
171     for (Content content : manager.getContents()) {
172       if (content instanceof TabbedContentImpl) {
173         List<Pair<String, JComponent>> tabs = ((TabbedContentImpl)content).getTabs();
174         for (Pair<String, JComponent> tab : tabs) {
175           if (condition.value(tab.second)) {
176             return tab.second;
177           }
178         }
179       }
180       else if (condition.value(content.getComponent())) {
181         return content.getComponent();
182       }
183     }
184     return null;
185   }
186
187   public static int getSelectedTab(@NotNull TabbedContent content) {
188     final JComponent current = content.getComponent();
189     int index = 0;
190     for (Pair<String, JComponent> tab : content.getTabs()) {
191       if (tab.second == current) {
192         return index;
193       }
194       index++;
195     }
196     return -1;
197   }
198
199   @Nullable
200   public static String getTabNameWithoutPrefix(@NotNull TabbedContent content, @NotNull String fullTabName) {
201     int fullPrefixLength = getFullPrefix(content.getTitlePrefix()).length();
202     if (fullTabName.startsWith(content.getTitlePrefix())) {
203       return fullTabName.substring(fullPrefixLength);
204     }
205     return null;
206   }
207 }