blob: a9043c649291128334f5f2bfae33ff305880a08a [file] [log] [blame]
/*
* Copyright 2000-2010 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.
*/
package com.intellij.ide.util.gotoByName;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.ElementsChooser;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* This class contains UI related to filtering functionality.
*/
public abstract class ChooseByNameFilter<T> {
/**
* a parent popup
*/
private final ChooseByNamePopup myParentPopup;
/**
* action toolbar
*/
private final ActionToolbar myToolbar;
/**
* a file type chooser, only one instance is used
*/
private final ElementsChooser<T> myChooser;
/**
* A panel that contains chooser
*/
private final JPanel myChooserPanel;
/**
* a file type popup, the value is non-null if popup is active
*/
private JBPopup myPopup;
/**
* a project to use. The project is used for dimension service.
*/
private final Project myProject;
/**
* A constructor
*
* @param popup a parent popup
* @param model a model for popup
* @param filterConfiguration storage for selected filter values
* @param project a context project
*/
public ChooseByNameFilter(@NotNull ChooseByNamePopup popup,
@NotNull FilteringGotoByModel<T> model,
@NotNull ChooseByNameFilterConfiguration<T> filterConfiguration,
@NotNull Project project) {
myParentPopup = popup;
DefaultActionGroup actionGroup = new DefaultActionGroup("go.to.file.filter", false);
ToggleAction action = new ToggleAction("Filter", "Filter files by type", AllIcons.General.Filter) {
@Override
public boolean isSelected(final AnActionEvent e) {
return myPopup != null;
}
@Override
public void setSelected(final AnActionEvent e, final boolean state) {
if (state) {
createPopup();
}
else {
close();
}
}
};
actionGroup.add(action);
myToolbar = ActionManager.getInstance().createActionToolbar("gotfile.filter", actionGroup, true);
myToolbar.setLayoutPolicy(ActionToolbar.NOWRAP_LAYOUT_POLICY);
myToolbar.updateActionsImmediately();
myToolbar.getComponent().setFocusable(false);
myToolbar.getComponent().setBorder(null);
myProject = project;
myChooser = createChooser(model, filterConfiguration);
myChooserPanel = createChooserPanel();
popup.setToolArea(myToolbar.getComponent());
}
/**
* @return a panel with chooser and buttons
*/
private JPanel createChooserPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(myChooser);
JPanel buttons = new JPanel();
JButton all = new JButton("All");
all.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
myChooser.setAllElementsMarked(true);
}
});
buttons.add(all);
JButton none = new JButton("None");
none.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
myChooser.setAllElementsMarked(false);
}
});
buttons.add(none);
JButton invert = new JButton("Invert");
invert.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
myChooser.invertSelection();
}
});
buttons.add(invert);
panel.add(buttons);
return panel;
}
/**
* Create a file type chooser
*
*
* @param model a model to update
* @param filterConfiguration
* @return a created file chooser
*/
@NotNull
protected ElementsChooser<T> createChooser(@NotNull final FilteringGotoByModel<T> model,
@NotNull final ChooseByNameFilterConfiguration<T> filterConfiguration) {
List<T> elements = new ArrayList<T>(getAllFilterValues());
final ElementsChooser<T> chooser = new ElementsChooser<T>(elements, true) {
@Override
protected String getItemText(@NotNull final T value) {
return textForFilterValue(value);
}
@Override
protected Icon getItemIcon(@NotNull final T value) {
return iconForFilterValue(value);
}
};
chooser.setFocusable(false);
final int count = chooser.getElementCount();
for (int i = 0; i < count; i++) {
T type = chooser.getElementAt(i);
if (!DumbService.getInstance(myProject).isDumb() && !filterConfiguration.isFileTypeVisible(type)) {
chooser.setElementMarked(type, false);
}
}
updateModel(model, chooser, true);
chooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener<T>() {
@Override
public void elementMarkChanged(final T element, final boolean isMarked) {
filterConfiguration.setVisible(element, isMarked);
updateModel(model, chooser, false);
}
});
return chooser;
}
protected abstract String textForFilterValue(@NotNull T value);
@Nullable
protected abstract Icon iconForFilterValue(@NotNull T value);
@NotNull
protected abstract Collection<T> getAllFilterValues();
/**
* Update model basing on the chooser state
*
* @param gotoFileModel a model
* @param chooser a file type chooser
*/
protected void updateModel(@NotNull FilteringGotoByModel<T> gotoFileModel, @NotNull ElementsChooser<T> chooser, boolean initial) {
final List<T> markedElements = chooser.getMarkedElements();
gotoFileModel.setFilterItems(markedElements);
myParentPopup.rebuildList(initial);
}
/**
* Create and show popup
*/
private void createPopup() {
if (myPopup != null) {
return;
}
myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(myChooserPanel, myChooser).setModalContext(false).setFocusable(false)
.setResizable(true).setCancelOnClickOutside(false).setMinSize(new Dimension(200, 200))
.setDimensionServiceKey(myProject, "GotoFile_FileTypePopup", false).createPopup();
myPopup.addListener(new JBPopupListener.Adapter() {
@Override
public void onClosed(LightweightWindowEvent event) {
myPopup = null;
}
});
myPopup.showUnderneathOf(myToolbar.getComponent());
}
/**
* close the file type filter
*/
public void close() {
if (myPopup != null) {
Disposer.dispose(myPopup);
}
}
}