summaryrefslogtreecommitdiff
path: root/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosPanel.java
blob: 97b3f8720f601b34b54b731ff2f5059c307c0e29 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*
 * Copyright 2000-2012 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * User: anna
 * Date: 27-Jul-2007
 */
package com.intellij.ide.todo;

import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.scopeChooser.IgnoringComboBox;
import com.intellij.openapi.project.Project;
import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.search.scope.NonProjectFilesScope;
import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.psi.search.scope.packageSet.NamedScopeManager;
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.content.Content;
import com.intellij.util.Alarm;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

public class ScopeBasedTodosPanel extends TodoPanel {
  private static final String SELECTED_SCOPE = "TODO_SCOPE";
  private final Alarm myAlarm;
  private JComboBox myScopes;
  private final NamedScopesHolder.ScopeListener myScopeListener;
  private final NamedScopeManager myNamedScopeManager;
  private final DependencyValidationManager myValidationManager;

  public ScopeBasedTodosPanel(final Project project, TodoPanelSettings settings, Content content){
    super(project,settings,false,content);
    myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, project);
    final String scopeName = PropertiesComponent.getInstance(project).getValue(SELECTED_SCOPE);
    rebuildModel(project, scopeName);

    myScopeListener = new NamedScopesHolder.ScopeListener() {
      @Override
      public void scopesChanged() {
        final ScopeWrapper scope = (ScopeWrapper)myScopes.getSelectedItem();
        rebuildModel(project, scope != null ? scope.getName() : null);
      }
    };

    myNamedScopeManager = NamedScopeManager.getInstance(project);
    myNamedScopeManager.addScopeListener(myScopeListener);

    myValidationManager = DependencyValidationManager.getInstance(project);
    myValidationManager.addScopeListener(myScopeListener);

    myScopes.setRenderer(new ListCellRendererWrapper<ScopeWrapper>(){
      @Override
      public void customize(JList list, ScopeWrapper value, int index, boolean selected, boolean hasFocus) {
        setText(value.getName());
        if (value.isSeparator()) {
          setSeparator();
        }
      }
    });
    myScopes.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        rebuildWithAlarm(ScopeBasedTodosPanel.this.myAlarm);
        final ScopeWrapper selectedItem = (ScopeWrapper)myScopes.getSelectedItem();
        if (selectedItem != null) {
          PropertiesComponent.getInstance(myProject).setValue(SELECTED_SCOPE, selectedItem.getName());
        }
      }
    });
    rebuildWithAlarm(myAlarm);
  }

  @Override
  public void dispose() {
    myNamedScopeManager.removeScopeListener(myScopeListener);
    myValidationManager.removeScopeListener(myScopeListener);
    super.dispose();
  }

  private void rebuildModel(Project project, String scopeName) {
    final ArrayList<ScopeWrapper> scopes = new ArrayList<ScopeWrapper>();
    final DependencyValidationManager manager = DependencyValidationManager.getInstance(project);

    scopes.add(new ScopeWrapper("Predefined Scopes"));
    List<NamedScope> predefinedScopesList = manager.getPredefinedScopes();
    NamedScope[] predefinedScopes = predefinedScopesList.toArray(new NamedScope[predefinedScopesList.size()]);
    predefinedScopes = NonProjectFilesScope.removeFromList(predefinedScopes);
    for (NamedScope predefinedScope : predefinedScopes) {
      scopes.add(new ScopeWrapper(predefinedScope));
    }

    collectEditableScopes(scopes, manager, "Custom Project Scopes");
    collectEditableScopes(scopes, NamedScopeManager.getInstance(project), "Custom Local Scopes");

    myScopes.setModel(new DefaultComboBoxModel(scopes.toArray(new ScopeWrapper[scopes.size()])));
    setSelection(scopeName, scopes);
  }

  private void setSelection(@Nullable String scopeName, ArrayList<ScopeWrapper> scopes) {
    boolean hasNonSeparators = false;
    for (ScopeWrapper scope : scopes) {
      if (!scope.isSeparator()) {
        hasNonSeparators = true;
        if (scopeName == null || scopeName.equals(scope.getName())) {
          myScopes.setSelectedItem(scope);
          return;
        }
      }
    }
    assert hasNonSeparators;
    setSelection(null, scopes);
  }

  private static void collectEditableScopes(ArrayList<ScopeWrapper> scopes, NamedScopesHolder manager, String separatorTitle) {
    NamedScope[] editableScopes = manager.getEditableScopes();
    if (editableScopes.length > 0) {
      scopes.add(new ScopeWrapper(separatorTitle));
      for (NamedScope scope : editableScopes) {
        scopes.add(new ScopeWrapper(scope));
      }
    }
  }

  @Override
  protected JComponent createCenterComponent() {
    JPanel panel = new JPanel(new BorderLayout());
    final JComponent component = super.createCenterComponent();
    panel.add(component, BorderLayout.CENTER);
    myScopes = new IgnoringComboBox() {
      @Override
      protected boolean isIgnored(Object item) {
        return item instanceof ScopeWrapper && ((ScopeWrapper)item).isSeparator();
      }
    };

    JPanel chooserPanel = new JPanel(new GridBagLayout());
    final JLabel scopesLabel = new JLabel("Scope:");
    scopesLabel.setDisplayedMnemonic('S');
    scopesLabel.setLabelFor(myScopes);
    final GridBagConstraints gc =
      new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE,
                             new Insets(2, 2, 2, 2), 0, 0);
    chooserPanel.add(scopesLabel, gc);
    chooserPanel.add(myScopes, gc);

    gc.fill = GridBagConstraints.HORIZONTAL;
    gc.weightx = 1;
    chooserPanel.add(Box.createHorizontalBox(), gc);
    panel.add(chooserPanel, BorderLayout.NORTH);
    return panel;
  }

  @Override
  protected TodoTreeBuilder createTreeBuilder(JTree tree, DefaultTreeModel treeModel, Project project) {
    ScopeBasedTodosTreeBuilder builder = new ScopeBasedTodosTreeBuilder(tree, treeModel, project, myScopes);
    builder.init();
    return builder;
  }

  public static class ScopeWrapper {
    private final String myName;
    private final boolean mySeparator;
    private NamedScope myNamedScope;

    private ScopeWrapper(NamedScope namedScope) {
      mySeparator = false;
      myNamedScope = namedScope;
      myName = myNamedScope.getName();
    }
    private ScopeWrapper(String name) {
      mySeparator = true;
      myName = name;
    }

    public String getName() {
      return myName;
    }

    public NamedScope getNamedScope() {
      return myNamedScope;
    }

    public boolean isSeparator() {
      return mySeparator;
    }
  }
}