6bf55c7eda7bdff8b8c14389709621ba8a940a24
[fedora-idea.git] / platform / vcs-impl / src / com / intellij / openapi / vcs / changes / committed / CommittedChangesPanel.java
blob6bf55c7eda7bdff8b8c14389709621ba8a940a24
1 /*
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.
18 * Created by IntelliJ IDEA.
19 * User: yole
20 * Date: 05.12.2006
21 * Time: 19:39:22
23 package com.intellij.openapi.vcs.changes.committed;
25 import com.intellij.openapi.Disposable;
26 import com.intellij.openapi.actionSystem.*;
27 import com.intellij.openapi.diagnostic.Logger;
28 import com.intellij.openapi.progress.ProgressManager;
29 import com.intellij.openapi.project.Project;
30 import com.intellij.openapi.ui.Messages;
31 import com.intellij.openapi.util.Ref;
32 import com.intellij.openapi.util.text.StringUtil;
33 import com.intellij.openapi.vcs.*;
34 import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
35 import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
36 import com.intellij.openapi.vfs.VirtualFile;
37 import com.intellij.ui.FilterComponent;
38 import com.intellij.util.Consumer;
39 import org.jetbrains.annotations.NotNull;
40 import org.jetbrains.annotations.Nullable;
42 import javax.swing.*;
43 import java.awt.*;
44 import java.util.ArrayList;
45 import java.util.Collections;
46 import java.util.List;
48 public class CommittedChangesPanel extends JPanel implements TypeSafeDataProvider, Disposable {
49 private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.committed.CommittedChangesPanel");
51 private final CommittedChangesTreeBrowser myBrowser;
52 private final Project myProject;
53 private CommittedChangesProvider myProvider;
54 private ChangeBrowserSettings mySettings;
55 private final RepositoryLocation myLocation;
56 private int myMaxCount = 0;
57 private final FilterComponent myFilterComponent = new MyFilterComponent();
58 private List<CommittedChangeList> myChangesFromProvider;
59 private final JLabel myErrorLabel = new JLabel();
60 private final List<Runnable> myShouldBeCalledOnDispose;
62 public CommittedChangesPanel(Project project, final CommittedChangesProvider provider, final ChangeBrowserSettings settings,
63 @Nullable final RepositoryLocation location, @Nullable ActionGroup extraActions) {
64 super(new BorderLayout());
65 mySettings = settings;
66 myProject = project;
67 myProvider = provider;
68 myLocation = location;
69 myShouldBeCalledOnDispose = new ArrayList<Runnable>();
70 myBrowser = new CommittedChangesTreeBrowser(project, new ArrayList<CommittedChangeList>());
71 add(myBrowser, BorderLayout.CENTER);
73 myErrorLabel.setForeground(Color.red);
74 add(myErrorLabel, BorderLayout.SOUTH);
76 final VcsCommittedViewAuxiliary auxiliary = provider.createActions(myBrowser, location);
78 JPanel toolbarPanel = new JPanel(new BorderLayout());
79 ActionGroup group = (ActionGroup) ActionManager.getInstance().getAction("CommittedChangesToolbar");
81 ActionToolbar toolBar = myBrowser.createGroupFilterToolbar(project, group, extraActions,
82 auxiliary != null ? auxiliary.getToolbarActions() : Collections.<AnAction>emptyList());
83 toolbarPanel.add(toolBar.getComponent(), BorderLayout.WEST);
85 toolbarPanel.add(myFilterComponent, BorderLayout.EAST);
86 myBrowser.addToolBar(toolbarPanel);
88 if (auxiliary != null) {
89 myShouldBeCalledOnDispose.add(auxiliary.getCalledOnViewDispose());
90 myBrowser.setTableContextMenu(group, (auxiliary.getPopupActions() == null) ? Collections.<AnAction>emptyList() : auxiliary.getPopupActions());
91 } else {
92 myBrowser.setTableContextMenu(group, Collections.<AnAction>emptyList());
95 final AnAction anAction = ActionManager.getInstance().getAction("CommittedChanges.Refresh");
96 anAction.registerCustomShortcutSet(CommonShortcuts.getRerun(), this);
99 public RepositoryLocation getRepositoryLocation() {
100 return myLocation;
103 public void setMaxCount(final int maxCount) {
104 myMaxCount = maxCount;
107 public void setProvider(final CommittedChangesProvider provider) {
108 if (myProvider != provider) {
109 myProvider = provider;
110 mySettings = provider.createDefaultSettings();
114 public void refreshChanges(final boolean cacheOnly) {
115 if (myLocation != null) {
116 refreshChangesFromLocation();
118 else {
119 refreshChangesFromCache(cacheOnly);
123 private void refreshChangesFromLocation() {
124 final Ref<VcsException> refEx = new Ref<VcsException>();
125 final Ref<List<CommittedChangeList>> changes = new Ref<List<CommittedChangeList>>();
126 boolean completed = ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
127 public void run() {
128 try {
129 changes.set(myProvider.getCommittedChanges(mySettings, myLocation, myMaxCount));
131 catch (VcsException ex) {
132 refEx.set(ex);
135 }, "Loading changes", true, myProject);
136 if (!refEx.isNull()) {
137 LOG.info(refEx.get());
138 Messages.showErrorDialog(myProject, "Error refreshing view: " + StringUtil.join(refEx.get().getMessages(), "\n"), "Committed Changes");
140 else if (completed) {
141 myChangesFromProvider = changes.get();
142 updateFilteredModel(false);
146 private void refreshChangesFromCache(final boolean cacheOnly) {
147 final CommittedChangesCache cache = CommittedChangesCache.getInstance(myProject);
148 if (!cache.hasCachesForAnyRoot()) {
149 if (cacheOnly) {
150 myBrowser.setEmptyText(VcsBundle.message("committed.changes.not.loaded.message"));
151 return;
153 if (!CacheSettingsDialog.showSettingsDialog(myProject)) return;
155 cache.getProjectChangesAsync(mySettings, myMaxCount, cacheOnly,
156 new Consumer<List<CommittedChangeList>>() {
157 public void consume(final List<CommittedChangeList> committedChangeLists) {
158 myChangesFromProvider = committedChangeLists;
159 updateFilteredModel(false);
162 new Consumer<List<VcsException>>() {
163 public void consume(final List<VcsException> vcsExceptions) {
164 AbstractVcsHelper.getInstance(myProject).showErrors(vcsExceptions, "Error refreshing VCS history");
169 private void updateFilteredModel(final boolean keepFilter) {
170 if (myChangesFromProvider == null) {
171 return;
173 myBrowser.setEmptyText(VcsBundle.message("committed.changes.empty.message"));
174 if (StringUtil.isEmpty(myFilterComponent.getFilter())) {
175 myBrowser.setItems(myChangesFromProvider, keepFilter, CommittedChangesBrowserUseCase.COMMITTED);
177 else {
178 final String[] strings = myFilterComponent.getFilter().split(" ");
179 for(int i=0; i<strings.length; i++) {
180 strings [i] = strings [i].toLowerCase();
182 List<CommittedChangeList> filteredChanges = new ArrayList<CommittedChangeList>();
183 for(CommittedChangeList changeList: myChangesFromProvider) {
184 if (changeListMatches(changeList, strings)) {
185 filteredChanges.add(changeList);
188 myBrowser.setItems(filteredChanges, keepFilter, CommittedChangesBrowserUseCase.COMMITTED);
192 private static boolean changeListMatches(@NotNull final CommittedChangeList changeList, final String[] filterWords) {
193 for(String word: filterWords) {
194 final String comment = changeList.getComment();
195 final String committer = changeList.getCommitterName();
196 if ((comment != null && comment.toLowerCase().indexOf(word) >= 0) ||
197 (committer != null && committer.toLowerCase().indexOf(word) >= 0) ||
198 Long.toString(changeList.getNumber()).indexOf(word) >= 0) {
199 return true;
202 return false;
205 public void setChangesFilter() {
206 CommittedChangesFilterDialog filterDialog = new CommittedChangesFilterDialog(myProject, myProvider.createFilterUI(true), mySettings);
207 filterDialog.show();
208 if (filterDialog.isOK()) {
209 mySettings = filterDialog.getSettings();
210 refreshChanges(false);
214 public void calcData(DataKey key, DataSink sink) {
215 if (key.equals(VcsDataKeys.CHANGES) || key.equals(VcsDataKeys.CHANGE_LISTS)) {
216 myBrowser.calcData(key, sink);
220 public void dispose() {
221 myBrowser.dispose();
222 for (Runnable runnable : myShouldBeCalledOnDispose) {
223 runnable.run();
227 public void setErrorText(String text) {
228 myErrorLabel.setText(text);
231 private class MyFilterComponent extends FilterComponent {
232 public MyFilterComponent() {
233 super("COMMITTED_CHANGES_FILTER_HISTORY", 20);
236 public void filter() {
237 updateFilteredModel(true);
241 public void passCachedListsToListener(final VcsConfigurationChangeListener.DetailedNotification notification,
242 final Project project, final VirtualFile root) {
243 if ((myChangesFromProvider != null) && (! myChangesFromProvider.isEmpty())) {
244 notification.execute(project, root, myChangesFromProvider);