/* * Copyright 2000-2017 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.find.impl; import com.intellij.find.FindBundle; import com.intellij.find.FindInProjectSettings; import com.intellij.find.FindModel; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.actionSystem.ToggleAction; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.FixedSizeButton; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.util.ui.JBUI; 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.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.util.List; public class FindPopupDirectoryChooser extends JPanel { @NotNull private final FindUIHelper myHelper; @NotNull private final Project myProject; @NotNull private final FindPopupPanel myFindPopupPanel; @NotNull private final ComboBox<String> myDirectoryComboBox; public FindPopupDirectoryChooser(@NotNull FindPopupPanel panel) { super(new BorderLayout()); myHelper = panel.getHelper(); myProject = panel.getProject(); myFindPopupPanel = panel; myDirectoryComboBox = new ComboBox<>(200); Component editorComponent = myDirectoryComboBox.getEditor().getEditorComponent(); if (editorComponent instanceof JTextField) { JTextField field = (JTextField)editorComponent; field.setColumns(40); } myDirectoryComboBox.setEditable(true); myDirectoryComboBox.setMaximumRowCount(8); ActionListener restartSearchListener = e -> myFindPopupPanel.scheduleResultsUpdate(); myDirectoryComboBox.addActionListener(restartSearchListener); FixedSizeButton mySelectDirectoryButton = new FixedSizeButton(myDirectoryComboBox); TextFieldWithBrowseButton.MyDoClickAction.addTo(mySelectDirectoryButton, myDirectoryComboBox); mySelectDirectoryButton.setMargin(JBUI.emptyInsets()); mySelectDirectoryButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor(); descriptor.setForcedToUseIdeaFileChooser(true); myFindPopupPanel.getCanClose().set(false); FileChooser.chooseFiles(descriptor, myProject, myFindPopupPanel, null, new FileChooser.FileChooserConsumer() { @Override public void consume(List<VirtualFile> files) { ApplicationManager.getApplication().invokeLater(() -> { myFindPopupPanel.getCanClose().set(true); IdeFocusManager.getInstance(myProject).requestFocus(myDirectoryComboBox.getEditor().getEditorComponent(), true); myHelper.getModel().setDirectoryName(files.get(0).getPresentableUrl()); myDirectoryComboBox.getEditor().setItem(files.get(0).getPresentableUrl()); }); } @Override public void cancelled() { ApplicationManager.getApplication().invokeLater(() -> { myFindPopupPanel.getCanClose().set(true); IdeFocusManager.getInstance(myProject).requestFocus(myDirectoryComboBox.getEditor().getEditorComponent(), true); }); } }); } }); MyRecursiveDirectoryAction recursiveDirectoryAction = new MyRecursiveDirectoryAction(); int mnemonicModifiers = SystemInfo.isMac ? InputEvent.ALT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK : InputEvent.ALT_DOWN_MASK; recursiveDirectoryAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_Y, mnemonicModifiers)), myFindPopupPanel); add(myDirectoryComboBox, BorderLayout.CENTER); JPanel buttonsPanel = new JPanel(new GridLayout(1, 2)); buttonsPanel.add(mySelectDirectoryButton); buttonsPanel.add(FindPopupPanel.createToolbar(recursiveDirectoryAction).getComponent()); //check if toolbar updates the button with no delays add(buttonsPanel, BorderLayout.EAST); } public void initByModel(@NotNull FindModel findModel) { final String directoryName = findModel.getDirectoryName(); java.util.List<String> strings = FindInProjectSettings.getInstance(myProject).getRecentDirectories(); if (myDirectoryComboBox.getItemCount() > 0) { myDirectoryComboBox.removeAllItems(); } if (directoryName != null && !directoryName.isEmpty()) { if (strings.contains(directoryName)) { strings.remove(directoryName); } myDirectoryComboBox.addItem(directoryName); } for (int i = strings.size() - 1; i >= 0; i--) { myDirectoryComboBox.addItem(strings.get(i)); } if (myDirectoryComboBox.getItemCount() == 0) { myDirectoryComboBox.addItem(""); } } @NotNull public ComboBox getComboBox() { return myDirectoryComboBox; } @NotNull public String getDirectory() { return (String)myDirectoryComboBox.getSelectedItem(); } @Nullable public ValidationInfo validate(@NotNull FindModel model) { VirtualFile directory = FindInProjectUtil.getDirectory(model); if (directory == null) { return new ValidationInfo(FindBundle.message("find.directory.not.found.error", getDirectory()), myDirectoryComboBox); } return null; } private class MyRecursiveDirectoryAction extends ToggleAction { MyRecursiveDirectoryAction() { super(FindBundle.message("find.scope.directory.recursive.checkbox"), "Recursively", AllIcons.General.Recursive); } @Override public boolean isSelected(AnActionEvent e) { return myHelper.getModel().isWithSubdirectories(); } @Override public void setSelected(AnActionEvent e, boolean state) { myHelper.getModel().setWithSubdirectories(state); myFindPopupPanel.scheduleResultsUpdate(); } } }