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 com
.intellij
.openapi
.vcs
.changes
.committed
;
18 import com
.intellij
.ide
.util
.treeView
.TreeState
;
19 import com
.intellij
.openapi
.project
.Project
;
20 import com
.intellij
.openapi
.vcs
.FilePath
;
21 import com
.intellij
.openapi
.vcs
.VcsBundle
;
22 import com
.intellij
.openapi
.vcs
.changes
.Change
;
23 import com
.intellij
.openapi
.vcs
.changes
.ChangesUtil
;
24 import com
.intellij
.openapi
.vcs
.changes
.ui
.ChangesBrowserNode
;
25 import com
.intellij
.openapi
.vcs
.changes
.ui
.ChangesBrowserNodeRenderer
;
26 import com
.intellij
.openapi
.vcs
.changes
.ui
.TreeModelBuilder
;
27 import com
.intellij
.openapi
.vcs
.versionBrowser
.CommittedChangeList
;
28 import com
.intellij
.ui
.treeStructure
.Tree
;
29 import com
.intellij
.util
.containers
.ContainerUtil
;
30 import org
.jetbrains
.annotations
.NotNull
;
31 import org
.jetbrains
.annotations
.Nullable
;
34 import javax
.swing
.event
.ChangeEvent
;
35 import javax
.swing
.event
.ChangeListener
;
36 import javax
.swing
.event
.TreeSelectionEvent
;
37 import javax
.swing
.event
.TreeSelectionListener
;
38 import javax
.swing
.tree
.DefaultMutableTreeNode
;
39 import javax
.swing
.tree
.DefaultTreeModel
;
42 import java
.util
.List
;
43 import java
.util
.concurrent
.CopyOnWriteArrayList
;
48 public class StructureFilteringStrategy
implements ChangeListFilteringStrategy
{
49 private final CopyOnWriteArrayList
<ChangeListener
> myListeners
= ContainerUtil
.createEmptyCOWList();
51 private final Project myProject
;
52 private final List
<FilePath
> mySelection
= new ArrayList
<FilePath
>();
54 public StructureFilteringStrategy(final Project project
) {
58 public String
toString() {
59 return VcsBundle
.message("filter.structure.name");
63 public JComponent
getFilterUI() {
70 public void setFilterBase(List
<CommittedChangeList
> changeLists
) {
75 myUI
.append(changeLists
);
78 public void addChangeListener(ChangeListener listener
) {
79 myListeners
.add(listener
);
82 public void removeChangeListener(ChangeListener listener
) {
83 myListeners
.remove(listener
);
86 public void resetFilterBase() {
90 public void appendFilterBase(List
<CommittedChangeList
> changeLists
) {
91 myUI
.append(changeLists
);
95 public List
<CommittedChangeList
> filterChangeLists(List
<CommittedChangeList
> changeLists
) {
96 if (mySelection
.size() == 0) {
99 final ArrayList
<CommittedChangeList
> result
= new ArrayList
<CommittedChangeList
>();
100 for(CommittedChangeList list
: changeLists
) {
101 if (listMatchesSelection(list
)) {
108 private boolean listMatchesSelection(final CommittedChangeList list
) {
109 for(Change change
: list
.getChanges()) {
110 FilePath path
= ChangesUtil
.getFilePath(change
);
111 for(FilePath selPath
: mySelection
) {
112 if (path
.isUnder(selPath
, false)) {
120 private class MyUI
extends JPanel
{
121 private final Tree myStructureTree
;
122 private boolean myRendererInitialized
;
123 private final TreeModelBuilder myBuilder
;
124 private TreeState myState
;
127 setLayout(new BorderLayout());
128 myStructureTree
= new Tree();
129 myStructureTree
.setRootVisible(false);
130 myStructureTree
.setShowsRootHandles(true);
131 myStructureTree
.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
132 public void valueChanged(final TreeSelectionEvent e
) {
134 ChangesBrowserNode node
= (ChangesBrowserNode
) e
.getPath().getLastPathComponent();
135 Collections
.addAll(mySelection
, node
.getFilePathsUnder());
137 for(ChangeListener listener
: myListeners
) {
138 listener
.stateChanged(new ChangeEvent(this));
142 add(new JScrollPane(myStructureTree
), BorderLayout
.CENTER
);
143 myBuilder
= new TreeModelBuilder(myProject
, false);
146 public void initRenderer() {
147 if (!myRendererInitialized
) {
148 myRendererInitialized
= true;
149 myStructureTree
.setCellRenderer(new ChangesBrowserNodeRenderer(myProject
, false, false));
153 public void reset() {
154 myState
= TreeState
.createOn(myStructureTree
, (DefaultMutableTreeNode
) myStructureTree
.getModel().getRoot());
155 myStructureTree
.setModel(myBuilder
.clearAndGetModel());
158 public void append(final List
<CommittedChangeList
> changeLists
) {
159 final TreeState localState
= (myState
!= null) && myBuilder
.isEmpty() ? myState
: TreeState
.createOn(myStructureTree
, (DefaultMutableTreeNode
) myStructureTree
.getModel().getRoot());
161 final Set
<FilePath
> filePaths
= new HashSet
<FilePath
>();
162 for(CommittedChangeList changeList
: changeLists
) {
163 for(Change change
: changeList
.getChanges()) {
164 final FilePath path
= ChangesUtil
.getFilePath(change
);
165 if (path
.getParentPath() != null) {
166 filePaths
.add(path
.getParentPath());
171 final DefaultTreeModel model
= myBuilder
.buildModelFromFilePaths(filePaths
);
172 myStructureTree
.setModel(model
);
173 localState
.applyTo(myStructureTree
, (DefaultMutableTreeNode
) myStructureTree
.getModel().getRoot());
174 myStructureTree
.revalidate();
175 myStructureTree
.repaint();