IDEA-193300 New SE size is too large when no results are found

This commit is contained in:
Mikhail Sokolov
2018-07-25 20:02:10 +03:00
parent ab589e3800
commit 667b7017f0
2 changed files with 110 additions and 25 deletions
@@ -34,6 +34,7 @@ public class SearchEverywhereManagerImpl implements SearchEverywhereManager {
private JBPopup myBalloon;
private SearchEverywhereUI mySearchEverywhereUI;
private Dimension myBalloonFullSize;
private final SearchHistoryList myHistoryList = new SearchHistoryList();
private HistoryIterator myHistoryIterator;
@@ -88,14 +89,12 @@ public class SearchEverywhereManagerImpl implements SearchEverywhereManager {
myBalloon = JBPopupFactory.getInstance().createComponentPopupBuilder(mySearchEverywhereUI, mySearchEverywhereUI.getSearchField())
.setProject(myProject)
.setResizable(false)
.setModalContext(false)
.setCancelOnClickOutside(true)
.setRequestFocus(true)
.setCancelKeyEnabled(false)
.setCancelCallback(() -> {
saveSearchText();
saveLocation();
return true;
})
.addUserData("SIMPLE_WINDOW")
@@ -108,22 +107,51 @@ public class SearchEverywhereManagerImpl implements SearchEverywhereManager {
if (project != null) {
Disposer.register(project, myBalloon);
}
myBalloon.pack(true, true);
Dimension size = mySearchEverywhereUI.getMinimumSize();
myBalloon.setMinimumSize(withInsets(size));
myProject.putUserData(SEARCH_EVERYWHERE_POPUP, myBalloon);
Disposer.register(myBalloon, () -> {
saveSize();
myProject.putUserData(SEARCH_EVERYWHERE_POPUP, null);
mySearchEverywhereUI = null;
myBalloon = null;
myBalloonFullSize = null;
});
if (project != null) {
myBalloon.showCenteredInCurrentWindow(project);
} else {
myBalloon.showInFocusCenter();
calcPositionAndShow(project, myBalloon);
if (mySearchEverywhereUI.getViewType() == SearchEverywhereUI.ViewType.SHORT) {
myBalloonFullSize = DimensionService.getInstance().getSize(LOCATION_SETTINGS_KEY, project);
myBalloon.pack(false, true);
}
}
private void calcPositionAndShow(Project project, JBPopup balloon) {
Point savedLocation = DimensionService.getInstance().getLocation(LOCATION_SETTINGS_KEY, project);
if (project != null) {
balloon.showCenteredInCurrentWindow(project);
} else {
balloon.showInFocusCenter();
}
//for first show and short mode popup should be shifted to the top screen half
if (savedLocation == null && mySearchEverywhereUI.getViewType() == SearchEverywhereUI.ViewType.SHORT) {
Point location = balloon.getLocationOnScreen();
location.y /= 2;
balloon.setLocation(location);
}
}
private Dimension withInsets(Dimension size) {
Insets insets = myBalloon.getContent().getInsets();
return new Dimension(
size.width + insets.left + insets.right,
size.height + insets.top + insets.bottom
);
}
@Override
public boolean isShown() {
return mySearchEverywhereUI != null && myBalloon != null && !myBalloon.isDisposed();
@@ -167,6 +195,22 @@ public class SearchEverywhereManagerImpl implements SearchEverywhereManager {
}
});
view.addViewTypeListener(viewType -> {
if (!isShown()) {
return;
}
if (viewType == SearchEverywhereUI.ViewType.SHORT) {
myBalloonFullSize = myBalloon.getSize();
myBalloon.pack(false, true);
} else {
if (myBalloonFullSize == null) {
myBalloonFullSize = withInsets(mySearchEverywhereUI.getPreferredSize());
}
myBalloon.setSize(myBalloonFullSize);
}
});
DumbAwareAction.create(__ -> showHistoryItem(true))
.registerCustomShortcutSet(SearchTextField.SHOW_HISTORY_SHORTCUT, view);
@@ -194,16 +238,10 @@ public class SearchEverywhereManagerImpl implements SearchEverywhereManager {
}
}
private void saveLocation() {
if (!isShown()) {
return;
private void saveSize() {
if (mySearchEverywhereUI.getViewType() == SearchEverywhereUI.ViewType.SHORT) {
DimensionService.getInstance().setSize(LOCATION_SETTINGS_KEY, myBalloonFullSize, myProject);
}
Dimension size = myBalloon.getSize();
Point location = myBalloon.getLocationOnScreen();
DimensionService service = DimensionService.getInstance();
service.setSize(LOCATION_SETTINGS_KEY, size);
service.setLocation(LOCATION_SETTINGS_KEY, location);
}
private void showHistoryItem(boolean next) {
@@ -55,6 +55,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.DocumentEvent;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
@@ -78,6 +79,7 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
private SETab mySelectedTab;
private final JTextField mySearchField;
private final JPanel suggestionsPanel;
private final JCheckBox myNonProjectCB;
private final List<SETab> myTabs = new ArrayList<>();
@@ -97,13 +99,13 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
private final Alarm emptyListAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, ApplicationManager.getApplication());
private Runnable searchFinishedHandler = () -> {};
private final List<ViewTypeListener> myViewTypeListeners = new ArrayList<>();
private ViewType myViewType = ViewType.SHORT;
public SearchEverywhereUI(Project project,
List<SearchEverywhereContributor> serviceContributors,
List<SearchEverywhereContributor> contributors,
Map<String, SearchEverywhereContributorFilter<?>> filters) {
withMinimumWidth(670);
withPreferredWidth(670);
withBackground(JBUI.CurrentTheme.SearchEverywhere.dialogBackground());
myProject = project;
@@ -118,7 +120,7 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
JPanel contributorsPanel = createTabPanel(contributors);
JPanel settingsPanel = createSettingsPanel();
mySearchField = createSearchField();
JPanel suggestionsPanel = createSuggestionsPanel();
suggestionsPanel = createSuggestionsPanel();
myResultsList.setModel(myListModel);
myResultsList.setFocusable(false);
@@ -154,6 +156,24 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
initSearchActions();
}
@Override
public Dimension getMinimumSize() {
return calcPrefSize(ViewType.SHORT);
}
@Override
public Dimension getPreferredSize() {
return calcPrefSize(myViewType);
}
private Dimension calcPrefSize(ViewType viewType) {
Dimension size = super.getPreferredSize();
if (viewType == ViewType.SHORT) {
size.height -= suggestionsPanel.getPreferredSize().height;
}
return size;
}
private JPanel createSuggestionsPanel() {
JPanel pnl = new JPanel(new BorderLayout());
pnl.setOpaque(false);
@@ -180,6 +200,13 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
return pnl;
}
private void updateViewType(ViewType viewType) {
if (myViewType != viewType) {
myViewType = viewType;
myViewTypeListeners.forEach(listener -> listener.suggestionsShown(viewType));
}
}
public JTextField getSearchField() {
return mySearchField;
}
@@ -469,6 +496,7 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
}
String pattern = getSearchPattern();
updateViewType(pattern.isEmpty() ? ViewType.SHORT : ViewType.FULL);
String matcherString = mySelectedTab.getContributor()
.map(contributor -> contributor.filterControlSymbols(pattern))
.orElse(pattern);
@@ -476,8 +504,6 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
MinusculeMatcher matcher = NameUtil.buildMatcher("*" + matcherString, NameUtil.MatchingCaseSensitivity.NONE);
MatcherHolder.associateMatcher(myResultsList, matcher);
//assert project != null;
//myRenderer.myProject = project;
synchronized (myWorkerRestartRequestLock) { // this lock together with RestartRequestId should be enough to prevent two CalcThreads running at the same time
final int currentRestartRequest = ++myCalcThreadRestartRequestId;
myCurrentWorker.doWhenProcessed(() -> {
@@ -493,8 +519,11 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
}
}
@NotNull
private String getSearchPattern() {
return mySearchField != null ? mySearchField.getText() : "";
return Optional.ofNullable(mySearchField)
.map(JTextComponent::getText)
.orElse("");
}
private void initSearchActions() {
@@ -541,8 +570,7 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
@Override
protected void textChanged(DocumentEvent e) {
String newSearchString = getSearchPattern();
if (nonProjectCheckBoxAutoSet && isUseNonProjectItems()
&& newSearchString != null && !newSearchString.contains(notFoundString)) {
if (nonProjectCheckBoxAutoSet && isUseNonProjectItems() && !newSearchString.contains(notFoundString)) {
doSetUseNonProjectItems(false, true);
}
rebuildList();
@@ -671,7 +699,7 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
private final ActionCallback myDone = new ActionCallback();
private final SearchEverywhereContributor contributorToExpand;
public CalcThread(@NotNull String pattern, @Nullable SearchEverywhereContributor expand) {
private CalcThread(@NotNull String pattern, @Nullable SearchEverywhereContributor expand) {
this.pattern = pattern;
contributorToExpand = expand;
}
@@ -761,6 +789,7 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
.filter(o -> !myListModel.contains(o))
.collect(Collectors.toList());
if (!itemsToAdd.isEmpty()) {
updateViewType(ViewType.FULL);
myListModel.addElements(itemsToAdd, contributor, results.hasMoreItems());
ScrollingUtil.ensureSelectionExists(myResultsList);
}
@@ -1242,6 +1271,24 @@ public class SearchEverywhereUI extends BorderLayoutPanel implements Disposable,
}
}
public ViewType getViewType() {
return myViewType;
}
public enum ViewType {FULL, SHORT}
public interface ViewTypeListener {
void suggestionsShown(ViewType viewType);
}
public void addViewTypeListener(ViewTypeListener listener) {
myViewTypeListeners.add(listener);
}
public void removeViewTypeListener(ViewTypeListener listener) {
myViewTypeListeners.remove(listener);
}
private static JLabel groupInfoLabel(String text) {
JLabel label = new JLabel(text);
label.setForeground(UIUtil.getLabelDisabledForeground());