mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+3
@@ -57,6 +57,7 @@ public class CaptureStorage {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
CapturedStack stack = STORAGE.get(new HardKey(key));
|
||||
Deque<InsertMatch> currentStacks = CURRENT_STACKS.get();
|
||||
if (stack != null) {
|
||||
@@ -131,6 +132,7 @@ public class CaptureStorage {
|
||||
private final CapturedStack myValue;
|
||||
|
||||
public WeakKey(Object key, CapturedStack value, ReferenceQueue q) {
|
||||
//noinspection unchecked
|
||||
super(key, q);
|
||||
myHash = System.identityHashCode(key);
|
||||
myValue = value;
|
||||
@@ -247,6 +249,7 @@ public class CaptureStorage {
|
||||
// to be run from the debugger
|
||||
@SuppressWarnings("unused")
|
||||
public static Object[][] getRelatedStack(Object key, int limit) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
CapturedStack stack = STORAGE.get(new HardKey(key));
|
||||
if (stack == null) {
|
||||
return null;
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.xdebugger.XExpression;
|
||||
import com.intellij.xdebugger.XSourcePosition;
|
||||
@@ -151,7 +152,8 @@ public class JavaDebuggerEvaluator extends XDebuggerEvaluator implements XDebugg
|
||||
}
|
||||
Pair<PsiElement, TextRange> pair = findExpression(elementAtCursor, sideEffectsAllowed);
|
||||
if (pair != null) {
|
||||
return new ExpressionInfo(pair.getSecond(), null, null, pair.getFirst());
|
||||
PsiElement element = pair.getFirst();
|
||||
return new ExpressionInfo(pair.getSecond(), null, null, element instanceof PsiExpression ? element : null);
|
||||
}
|
||||
} catch (IndexNotReadyException ignored) {}
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.lang.jvm.actions
|
||||
|
||||
interface ActionRequest {
|
||||
|
||||
/**
|
||||
* Request may be bound to the PSI-element in call-site language,
|
||||
* which means request will become invalid if element is invalidated.
|
||||
*
|
||||
* @return `true` if it is safe to call other methods of this request, `false` otherwise
|
||||
*/
|
||||
val isValid: Boolean
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.lang.jvm.actions
|
||||
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
import com.intellij.lang.jvm.types.JvmSubstitutor
|
||||
|
||||
interface CreateExecutableRequest {
|
||||
|
||||
val isValid: Boolean
|
||||
interface CreateExecutableRequest : ActionRequest {
|
||||
|
||||
val modifiers: Collection<JvmModifier>
|
||||
|
||||
|
||||
@@ -1,32 +1,10 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.lang.jvm.actions
|
||||
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
import com.intellij.lang.jvm.types.JvmSubstitutor
|
||||
|
||||
interface CreateFieldRequest {
|
||||
|
||||
/**
|
||||
* Request may be bound to the PSI-element in call-site language,
|
||||
* which means request will become invalid if element is invalidated.
|
||||
*
|
||||
* @return `true` if it is safe to call other methods of this object, `false` otherwise
|
||||
*/
|
||||
val isValid: Boolean
|
||||
interface CreateFieldRequest : ActionRequest {
|
||||
|
||||
/**
|
||||
* @return name of the field to be created
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.java.propertyBased;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -23,6 +24,7 @@ import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.testFramework.propertyBased.CompletionPolicy;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -30,6 +32,18 @@ import java.util.Arrays;
|
||||
* @author peter
|
||||
*/
|
||||
class JavaCompletionPolicy extends CompletionPolicy {
|
||||
@Nullable
|
||||
@Override
|
||||
protected String getExpectedVariant(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement leaf, @Nullable PsiReference ref) {
|
||||
if (isBuggyInjection(file)) return null;
|
||||
|
||||
return super.getExpectedVariant(editor, file, leaf, ref);
|
||||
}
|
||||
|
||||
// a language where there are bugs in completion which maintainers of this Java-specific tests can't or don't want to fix
|
||||
private static boolean isBuggyInjection(@NotNull PsiFile file) {
|
||||
return Arrays.asList("XML", "HTML").contains(file.getLanguage().getID());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAfterError(@NotNull PsiFile file, @NotNull PsiElement leaf) {
|
||||
|
||||
@@ -184,6 +184,7 @@ abstract class LineStatusTrackerBase<R : Range> {
|
||||
}
|
||||
|
||||
override fun onUnfreeze(side: Side) {
|
||||
calcInnerRanges()
|
||||
installMissingHighlighters()
|
||||
}
|
||||
|
||||
@@ -194,7 +195,8 @@ abstract class LineStatusTrackerBase<R : Range> {
|
||||
}
|
||||
|
||||
private fun calcInnerRanges() {
|
||||
if (isDetectWhitespaceChangedLines()) {
|
||||
if (isDetectWhitespaceChangedLines() &&
|
||||
!documentTracker.isFrozen()) {
|
||||
for (block in blocks) {
|
||||
if (block.ourData.innerRanges == null) {
|
||||
block.ourData.innerRanges = calcInnerRanges(block)
|
||||
|
||||
+4
-18
@@ -32,19 +32,12 @@
|
||||
<columns value="6"/>
|
||||
</properties>
|
||||
</component>
|
||||
<scrollpane id="80db7" class="com.intellij.ui.components.JBScrollPane">
|
||||
<component id="87e" class="com.intellij.ui.EditorTextField" binding="myDescriptionArea" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="87e" class="com.intellij.ui.EditorTextField" binding="myDescriptionArea" custom-create="true">
|
||||
<constraints/>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
</component>
|
||||
<component id="d6e35" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="2" use-parent-layout="false"/>
|
||||
@@ -53,19 +46,12 @@
|
||||
<text value="Description:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<scrollpane id="c034f" class="com.intellij.ui.components.JBScrollPane">
|
||||
<component id="e20d2" class="com.intellij.ui.EditorTextField" binding="myChangeNotesArea" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="e20d2" class="com.intellij.ui.EditorTextField" binding="myChangeNotesArea" custom-create="true">
|
||||
<constraints/>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
</component>
|
||||
<component id="795b5" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="2" use-parent-layout="false"/>
|
||||
|
||||
+101
-47
@@ -26,6 +26,7 @@ import com.intellij.openapi.actionSystem.impl.MenuItemPresentationFactory;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.ColorKey;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsUtil;
|
||||
@@ -40,6 +41,7 @@ import com.intellij.openapi.options.FontSize;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.DimensionService;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
@@ -63,6 +65,7 @@ import com.intellij.ui.popup.PopupPositionManager;
|
||||
import com.intellij.util.Url;
|
||||
import com.intellij.util.Urls;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.JBDimension;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.accessibility.ScreenReader;
|
||||
@@ -102,6 +105,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
@NonNls private static final String DOCUMENTATION_TOPIC_ID = "reference.toolWindows.Documentation";
|
||||
|
||||
private static final int PREFERRED_HEIGHT_MAX_EM = 10;
|
||||
private static final JBDimension MAX_DEFAULT = new JBDimension(650, 500);
|
||||
private static final JBDimension MIN_DEFAULT = new JBDimension(300, 59);
|
||||
private final ExternalDocAction myExternalDocAction;
|
||||
|
||||
private DocumentationManager myManager;
|
||||
@@ -485,7 +490,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
if (myHint == null && myManager.myToolWindow == null) {
|
||||
int em = myEditorPane.getFont().getSize();
|
||||
int prefHeightMax = PREFERRED_HEIGHT_MAX_EM * em;
|
||||
return new Dimension(size.width, Math.min(prefHeightMax, size.height));
|
||||
return new Dimension(size.width, Math.min(prefHeightMax,
|
||||
size.height + (needsToolbar() ? myControlPanel.getPreferredSize().height : 0)));
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@@ -781,56 +787,104 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
}
|
||||
|
||||
private void showHint() {
|
||||
LookupEx lookup = LookupManager.getActiveLookup(myManager.getEditor());
|
||||
int maxWidth = JBUI.scale(lookup != null ? 435 : 650);
|
||||
Editor editor = myManager.getEditor();
|
||||
LookupEx lookup = LookupManager.getActiveLookup(editor);
|
||||
int maxWidth = lookup != null ? JBUI.scale(435) : MAX_DEFAULT.width;
|
||||
boolean lookupActive = lookup != null && lookup.getCurrentItem() != null && lookup.getComponent().isShowing();
|
||||
if (myHint != null && myHint.getDimensionServiceKey() == null) {
|
||||
Dimension preferredSize = myEditorPane.getPreferredSize();
|
||||
int width = definitionPreferredWidth();
|
||||
width = width < 0 ? preferredSize.width : width;
|
||||
myResizing = true;
|
||||
int height = preferredSize.height + (needsToolbar() ? myControlPanel.getPreferredSize().height : 0);
|
||||
Dimension hintSize = new Dimension(Math.min(maxWidth, Math.max(JBUI.scale(300), width)),
|
||||
Math.min(JBUI.scale(500), Math.max(JBUI.scale(59), height)));
|
||||
if (lookupActive && myHint.getLocationOnScreen().x < lookup.getComponent().getLocationOnScreen().x) {
|
||||
myHint.setLocation(new RelativePoint(lookup.getComponent(), new Point(-hintSize.width - 5, 0)));
|
||||
if (myHint != null) {
|
||||
Dimension hintSize;
|
||||
if (myHint.getDimensionServiceKey() == null) {
|
||||
Dimension preferredSize = myEditorPane.getPreferredSize();
|
||||
int width = definitionPreferredWidth();
|
||||
width = width < 0 ? preferredSize.width : width;
|
||||
myResizing = true;
|
||||
int height = preferredSize.height + (needsToolbar() ? myControlPanel.getPreferredSize().height : 0);
|
||||
hintSize = new Dimension(Math.min(maxWidth, Math.max(JBUI.scale(300), width)),
|
||||
Math.min(MAX_DEFAULT.height, Math.max(MIN_DEFAULT.height, height)));
|
||||
} else {
|
||||
hintSize = DimensionService.getInstance().getSize(DocumentationManager.NEW_JAVADOC_LOCATION_AND_SIZE, myManager.myProject);
|
||||
hintSize = hintSize != null ? hintSize : MIN_DEFAULT;
|
||||
}
|
||||
|
||||
Point location = myHint.getLocationOnScreen();
|
||||
if (lookupActive && location.x < lookup.getComponent().getLocationOnScreen().x) {
|
||||
// pin upper right corner (instead of default upper left)
|
||||
location = new RelativePoint(lookup.getComponent(), new Point(-hintSize.width - 5, 0)).getScreenPoint();
|
||||
myHint.setLocation(location);
|
||||
} else if (editor != null && editor.getComponent().isShowing()) {
|
||||
// pin lower bound (instead of default upper)
|
||||
Point preferredLocation = JBPopupFactory.getInstance().guessBestPopupLocation(editor).getScreenPoint();
|
||||
preferredLocation.y -= editor.getLineHeight();
|
||||
if (location.y < preferredLocation.y) {
|
||||
location = new Point(location.x, preferredLocation.y - hintSize.height);
|
||||
myHint.setLocation(location);
|
||||
}
|
||||
}
|
||||
if (myIsShown) {
|
||||
Rectangle screen = ScreenUtil.getScreenRectangle(myEditorPane);
|
||||
int xOverdraft = location.x + hintSize.width - screen.x - screen.width;
|
||||
if (xOverdraft > 0) {
|
||||
myHint.setLocation(new Point(location.x - xOverdraft, location.y));
|
||||
}
|
||||
int yUnderDraft = screen.y - location.y;
|
||||
if (yUnderDraft > 0) {
|
||||
location.y += yUnderDraft;
|
||||
hintSize.height -= yUnderDraft;
|
||||
}
|
||||
int yOverdraft = location.y + hintSize.height - screen.y - screen.height;
|
||||
if (yOverdraft > 0) {
|
||||
hintSize.height -= yOverdraft;
|
||||
}
|
||||
}
|
||||
myHint.setSize(hintSize);
|
||||
}
|
||||
|
||||
if (!myIsShown && myHint != null && !ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
myResizing = true;
|
||||
Component focusOwner = IdeFocusManager.getInstance(myManager.myProject).getFocusOwner();
|
||||
DataContext dataContext = DataManager.getInstance().getDataContext(focusOwner);
|
||||
if (lookupActive) {
|
||||
Component lookupComponent = lookup.getComponent();
|
||||
Point lookupPosition = lookupComponent.getLocationOnScreen();
|
||||
Rectangle screenRectangle = ScreenUtil.getScreenRectangle(lookupComponent);
|
||||
int lookupWidthAndGap = lookupComponent.getWidth() + 5;
|
||||
int x = lookupPosition.x + lookupWidthAndGap;
|
||||
Dimension hintSize = myHint.getSize();
|
||||
RelativePoint point;
|
||||
if (x + Math.max(hintSize.width, maxWidth) > screenRectangle.width) {
|
||||
point = new RelativePoint(lookupComponent, new Point(-hintSize.width - 5, 0));
|
||||
} else {
|
||||
point = new RelativePoint(lookupComponent, new Point(lookupWidthAndGap, 0));
|
||||
}
|
||||
myHint.show(point);
|
||||
lookup.addLookupListener(new LookupAdapter() {
|
||||
@Override
|
||||
public void lookupCanceled(LookupEvent event) {
|
||||
final AbstractPopup hint = myHint;
|
||||
if (hint != null && hint.canClose() && hint.isVisible()) {
|
||||
hint.cancel();
|
||||
}
|
||||
if (!myIsShown && !ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
myResizing = true;
|
||||
Component focusOwner = IdeFocusManager.getInstance(myManager.myProject).getFocusOwner();
|
||||
DataContext dataContext = DataManager.getInstance().getDataContext(focusOwner);
|
||||
if (lookupActive) {
|
||||
Component lookupComponent = lookup.getComponent();
|
||||
Point lookupPosition = lookupComponent.getLocationOnScreen();
|
||||
Rectangle screenRectangle = ScreenUtil.getScreenRectangle(lookupComponent);
|
||||
int lookupWidthAndGap = lookupComponent.getWidth() + 5;
|
||||
int x = lookupPosition.x + lookupWidthAndGap;
|
||||
RelativePoint point;
|
||||
// if documentation doesn't fit into screen, put it on the left hand side
|
||||
if (x + Math.max(hintSize.width, maxWidth) > screenRectangle.width) {
|
||||
point = new RelativePoint(lookupComponent, new Point(-hintSize.width - 5, 0));
|
||||
} else {
|
||||
point = new RelativePoint(lookupComponent, new Point(lookupWidthAndGap, 0));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
PopupPositionManager.positionPopupInBestPosition(myHint, myManager.getEditor(), dataContext);
|
||||
}
|
||||
myIsShown = true;
|
||||
if (myHint.getDimensionServiceKey() == null) {
|
||||
SwingUtilities.invokeLater(() -> registerSizeTracker());
|
||||
myHint.show(point);
|
||||
lookup.addLookupListener(new LookupAdapter() {
|
||||
@Override
|
||||
public void lookupCanceled(LookupEvent event) {
|
||||
final AbstractPopup hint = myHint;
|
||||
if (hint != null && hint.canClose() && hint.isVisible()) {
|
||||
hint.cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (editor != null && editor.getComponent().isShowing()) {
|
||||
// let's try to fit at least of half of maximum size on the bottom
|
||||
Point preferredLocation = JBPopupFactory.getInstance().guessBestPopupLocation(editor).getScreenPoint();
|
||||
Rectangle preferred = new Rectangle(preferredLocation.x, preferredLocation.y, MAX_DEFAULT.width, MAX_DEFAULT.height / 2);
|
||||
Rectangle adjusted = (Rectangle)preferred.clone();
|
||||
ScreenUtil.fitToScreen(adjusted);
|
||||
// if we fail, show documentation on top
|
||||
if (preferred.y != adjusted.y) {
|
||||
preferredLocation.y -= editor.getLineHeight() + hintSize.height;
|
||||
}
|
||||
|
||||
myHint.show(new RelativePoint(preferredLocation));
|
||||
}
|
||||
else {
|
||||
PopupPositionManager.positionPopupInBestPosition(myHint, editor, dataContext);
|
||||
}
|
||||
myIsShown = true;
|
||||
if (myHint.getDimensionServiceKey() == null) {
|
||||
SwingUtilities.invokeLater(() -> registerSizeTracker());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1075,7 +1129,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
}
|
||||
|
||||
private boolean needsToolbar() {
|
||||
return myHint != null && Registry.is("documentation.show.toolbar");
|
||||
return myManager.myToolWindow == null && Registry.is("documentation.show.toolbar");
|
||||
}
|
||||
|
||||
private static class MyGearActionGroup extends DefaultActionGroup implements HintManagerImpl.ActionToIgnore {
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.find.actions;
|
||||
|
||||
import com.intellij.codeInsight.TargetElementUtil;
|
||||
@@ -1006,25 +1004,17 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
|
||||
myWidth = newWidth;
|
||||
|
||||
int rowsToShow = Math.min(30, data.size());
|
||||
Dimension dimension = new Dimension(newWidth, table.getRowHeight() * rowsToShow);
|
||||
Rectangle rectangle = fitToScreen(dimension, popupPosition, table);
|
||||
if (!data.isEmpty()) {
|
||||
ScrollingUtil.ensureSelectionExists(table);
|
||||
}
|
||||
table.setSize(rectangle.getSize());
|
||||
//table.setPreferredSize(dimension);
|
||||
//table.setMaximumSize(dimension);
|
||||
//table.setPreferredScrollableViewportSize(dimension);
|
||||
|
||||
|
||||
Dimension footerSize = ((AbstractPopup)popup).getFooterPreferredSize();
|
||||
|
||||
int footer = footerSize.height;
|
||||
int footerBorder = footer == 0 ? 0 : 1;
|
||||
Insets insets = ((AbstractPopup)popup).getPopupBorder().getBorderInsets(content);
|
||||
rectangle.height += headerSize.height + footer + footerBorder + insets.top + insets.bottom;
|
||||
ScreenUtil.fitToScreen(rectangle);
|
||||
int minHeight = headerSize.height + footer + footerBorder + insets.top + insets.bottom;
|
||||
|
||||
Rectangle rectangle = getPreferredBounds(table, popupPosition.getScreenPoint(), newWidth, minHeight, data.size());
|
||||
table.setSize(rectangle.width, rectangle.height - minHeight);
|
||||
if (!data.isEmpty()) ScrollingUtil.ensureSelectionExists(table);
|
||||
|
||||
Dimension newDim = rectangle.getSize();
|
||||
window.setBounds(rectangle);
|
||||
window.setMinimumSize(newDim);
|
||||
@@ -1034,16 +1024,19 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
window.repaint();
|
||||
}
|
||||
|
||||
private static Rectangle fitToScreen(@NotNull Dimension newDim, @NotNull RelativePoint popupPosition, JTable table) {
|
||||
Rectangle rectangle = new Rectangle(popupPosition.getScreenPoint(), newDim);
|
||||
ScreenUtil.fitToScreen(rectangle);
|
||||
if (rectangle.getHeight() != newDim.getHeight()) {
|
||||
int newHeight = (int)rectangle.getHeight();
|
||||
int roundedHeight = newHeight - newHeight % table.getRowHeight();
|
||||
rectangle.setSize((int)rectangle.getWidth(), Math.max(roundedHeight, table.getRowHeight()));
|
||||
private static Rectangle getPreferredBounds(@NotNull JTable table, @NotNull Point point, int width, int minHeight, int modelRows) {
|
||||
boolean addExtraSpace = Registry.is("ide.preferred.scrollable.viewport.extra.space");
|
||||
int visibleRows = Math.min(30, modelRows);
|
||||
int rowHeight = table.getRowHeight();
|
||||
int space = addExtraSpace && visibleRows < modelRows ? rowHeight / 2 : 0;
|
||||
int height = visibleRows * rowHeight + minHeight + space;
|
||||
Rectangle bounds = new Rectangle(point.x, point.y, width, height);
|
||||
ScreenUtil.fitToScreen(bounds);
|
||||
if (bounds.height != height) {
|
||||
minHeight += addExtraSpace && space == 0 ? rowHeight / 2 : space;
|
||||
bounds.height = Math.max(1, (bounds.height - minHeight) / rowHeight) * rowHeight + minHeight;
|
||||
}
|
||||
return rectangle;
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
private void appendMoreUsages(Editor editor,
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide.util;
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
@@ -623,9 +609,6 @@ public class FileStructurePopup implements Disposable, TreeActionsOwner {
|
||||
panel.add(topPanel, BorderLayout.NORTH);
|
||||
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTree);
|
||||
scrollPane.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.BOTTOM));
|
||||
Dimension preferredSize = scrollPane.getPreferredSize();
|
||||
preferredSize.width = Math.max(chkPanel.getPreferredSize().width, JBUI.scale(350));
|
||||
scrollPane.setPreferredSize(preferredSize);
|
||||
panel.add(scrollPane, BorderLayout.CENTER);
|
||||
//panel.add(createSouthPanel(), BorderLayout.SOUTH);
|
||||
DataManager.registerDataProvider(panel, new DataProvider() {
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide.util.gotoByName;
|
||||
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
@@ -148,10 +134,6 @@ public class ChooseByNamePopup extends ChooseByNameBase implements ChooseByNameP
|
||||
bounds.y += layeredPane.getHeight();
|
||||
|
||||
final Dimension preferredScrollPaneSize = myListScrollPane.getPreferredSize();
|
||||
int lastVisibleRow = Math.min(myList.getVisibleRowCount(), myList.getModel().getSize()) - 1;
|
||||
Rectangle visibleBounds = lastVisibleRow < 0 ? null : myList.getCellBounds(0, lastVisibleRow);
|
||||
preferredScrollPaneSize.height = visibleBounds != null ? visibleBounds.height : UIManager.getFont("Label.font").getSize();
|
||||
|
||||
preferredScrollPaneSize.width = Math.max(myTextFieldPanel.getWidth(), preferredScrollPaneSize.width);
|
||||
|
||||
// in 'focus follows mouse' mode, to avoid focus escaping to editor, don't reduce popup size when list size is reduced
|
||||
|
||||
@@ -31,6 +31,12 @@ import javax.swing.*;
|
||||
* @see SearchableOptionContributor
|
||||
*/
|
||||
public interface SearchableConfigurable extends Configurable {
|
||||
|
||||
/**
|
||||
* Unique configurable id.
|
||||
* Note this id should be THE SAME as the one specified in XML.
|
||||
* @see ConfigurableEP#id
|
||||
*/
|
||||
@NotNull
|
||||
@NonNls
|
||||
String getId();
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.ui;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
@@ -499,13 +497,6 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
|
||||
|
||||
private void createUIComponents() {
|
||||
myTree = new Tree() {
|
||||
@Override
|
||||
public Dimension getPreferredScrollableViewportSize() {
|
||||
Dimension size = super.getPreferredScrollableViewportSize();
|
||||
size = new Dimension(size.width + 20, size.height);
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NonStaticInitializer")
|
||||
public JToolTip createToolTip() {
|
||||
|
||||
@@ -381,52 +381,4 @@ public class JBList<E> extends JList<E> implements ComponentWithEmptyText, Compo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredScrollableViewportSize() {
|
||||
return getPreferredScrollableViewportSize(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static Dimension getPreferredScrollableViewportSize(@NotNull JList list) {
|
||||
Dimension size = list.getPreferredSize();
|
||||
if (size == null) return new Dimension();
|
||||
if (JList.VERTICAL != list.getLayoutOrientation()) return size;
|
||||
|
||||
int fixedWidth = list.getFixedCellWidth();
|
||||
int fixedHeight = list.getFixedCellHeight();
|
||||
|
||||
ListModel model = list.getModel();
|
||||
int modelRows = model == null ? 0 : model.getSize();
|
||||
if (modelRows <= 0) {
|
||||
if (fixedWidth <= 0) fixedWidth = Registry.intValue("ide.preferred.scrollable.viewport.fixed.width");
|
||||
if (fixedWidth <= 0) fixedWidth = JBUI.scale(256); // scaled value from JDK
|
||||
if (fixedHeight <= 0) fixedHeight = Registry.intValue("ide.preferred.scrollable.viewport.fixed.height");
|
||||
if (fixedHeight <= 0) fixedHeight = JBUI.scale(16); // scaled value from JDK
|
||||
}
|
||||
int visibleRows = list.getVisibleRowCount();
|
||||
if (visibleRows <= 0) visibleRows = Registry.intValue("ide.preferred.scrollable.viewport.visible.rows");
|
||||
|
||||
boolean addExtraSpace = 0 < visibleRows && visibleRows < modelRows && Registry.is("ide.preferred.scrollable.viewport.extra.space");
|
||||
Insets insets = list.getInsets();
|
||||
size.height = insets != null ? insets.top + insets.bottom : 0;
|
||||
if (0 < fixedWidth && 0 < fixedHeight) {
|
||||
size.width = insets != null ? insets.left + insets.right + fixedWidth : fixedWidth;
|
||||
size.height += fixedHeight * visibleRows;
|
||||
if (addExtraSpace) size.height += fixedHeight / 2;
|
||||
}
|
||||
else if (addExtraSpace) {
|
||||
Rectangle bounds = list.getCellBounds(visibleRows, visibleRows);
|
||||
if (bounds != null) size.height = bounds.y + bounds.height / 2;
|
||||
}
|
||||
else if (visibleRows > 0) {
|
||||
int lastRow = Math.min(visibleRows, modelRows) - 1;
|
||||
Rectangle bounds = list.getCellBounds(lastRow, lastRow);
|
||||
if (bounds != null) {
|
||||
size.height = bounds.y + bounds.height;
|
||||
if (insets != null) size.height += insets.bottom;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.components;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -676,116 +662,58 @@ public class JBScrollPane extends JScrollPane {
|
||||
|
||||
@Override
|
||||
public Dimension preferredLayoutSize(Container parent) {
|
||||
/* Sync the (now obsolete) policy fields with the
|
||||
* JScrollPane.
|
||||
*/
|
||||
JScrollPane scrollPane = (JScrollPane)parent;
|
||||
vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
|
||||
hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
|
||||
Dimension result = new Dimension();
|
||||
|
||||
Insets insets = parent.getInsets();
|
||||
int prefWidth = insets.left + insets.right;
|
||||
int prefHeight = insets.top + insets.bottom;
|
||||
JScrollPane pane = (JScrollPane)parent;
|
||||
JBInsets.addTo(result, pane.getInsets());
|
||||
|
||||
/* Note that viewport.getViewSize() is equivalent to
|
||||
* viewport.getView().getPreferredSize() modulo a null
|
||||
* view or a view whose size was explicitly set.
|
||||
*/
|
||||
|
||||
Dimension extentSize = null;
|
||||
Dimension viewSize = null;
|
||||
Component view = null;
|
||||
Border border = pane.getViewportBorder();
|
||||
if (border != null) JBInsets.addTo(result, border.getBorderInsets(parent));
|
||||
|
||||
int vsbPolicy = pane.getVerticalScrollBarPolicy();
|
||||
int hsbPolicy = pane.getHorizontalScrollBarPolicy();
|
||||
if (viewport != null) {
|
||||
extentSize = viewport.getPreferredSize();
|
||||
view = viewport.getView();
|
||||
Component view = viewport.getView();
|
||||
if (view != null) {
|
||||
viewSize = view.getPreferredSize();
|
||||
} else {
|
||||
viewSize = new Dimension(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's a viewport add its preferredSize.
|
||||
*/
|
||||
|
||||
if (extentSize != null) {
|
||||
prefWidth += extentSize.width;
|
||||
prefHeight += extentSize.height;
|
||||
}
|
||||
|
||||
/* If there's a JScrollPane.viewportBorder, add its insets.
|
||||
*/
|
||||
|
||||
Border viewportBorder = scrollPane.getViewportBorder();
|
||||
if (viewportBorder != null) {
|
||||
Insets vpbInsets = viewportBorder.getBorderInsets(parent);
|
||||
prefWidth += vpbInsets.left + vpbInsets.right;
|
||||
prefHeight += vpbInsets.top + vpbInsets.bottom;
|
||||
}
|
||||
|
||||
/* If a header exists and it's visible, factor its
|
||||
* preferred size in.
|
||||
*/
|
||||
|
||||
if ((rowHead != null) && rowHead.isVisible()) {
|
||||
prefWidth += rowHead.getPreferredSize().width;
|
||||
}
|
||||
|
||||
if ((colHead != null) && colHead.isVisible()) {
|
||||
prefHeight += colHead.getPreferredSize().height;
|
||||
}
|
||||
|
||||
/* If a scrollbar is going to appear, factor its preferred size in.
|
||||
* If the scrollbars policy is AS_NEEDED, this can be a little
|
||||
* tricky:
|
||||
*
|
||||
* - If the view is a Scrollable then scrollableTracksViewportWidth
|
||||
* and scrollableTracksViewportHeight can be used to effectively
|
||||
* disable scrolling (if they're true) in their respective dimensions.
|
||||
*
|
||||
* - Assuming that a scrollbar hasn't been disabled by the
|
||||
* previous constraint, we need to decide if the scrollbar is going
|
||||
* to appear to correctly compute the JScrollPanes preferred size.
|
||||
* To do this we compare the preferredSize of the viewport (the
|
||||
* extentSize) to the preferredSize of the view. Although we're
|
||||
* not responsible for laying out the view we'll assume that the
|
||||
* JViewport will always give it its preferredSize.
|
||||
*/
|
||||
|
||||
if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
|
||||
boolean considerVsbWidth = vsb.isOpaque() || isAlwaysOpaque(view);
|
||||
if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
|
||||
if (considerVsbWidth) prefWidth += vsb.getPreferredSize().width;
|
||||
}
|
||||
else if ((viewSize != null) && (extentSize != null)) {
|
||||
boolean canScroll = true;
|
||||
// If the view is tracking the viewports width we don't bother with a horizontal scrollbar.
|
||||
// If the view is tracking the viewports height we don't bother with a vertical scrollbar.
|
||||
boolean viewTracksViewportWidth = false;
|
||||
boolean viewTracksViewportHeight = false;
|
||||
// Don't bother checking the Scrollable methods if there is no room for the viewport,
|
||||
// we aren't going to show any scroll bars in this case anyway.
|
||||
if (view instanceof Scrollable) {
|
||||
canScroll = !((Scrollable)view).getScrollableTracksViewportHeight();
|
||||
Scrollable scrollable = (Scrollable)view;
|
||||
viewTracksViewportWidth = scrollable.getScrollableTracksViewportWidth();
|
||||
viewTracksViewportHeight = scrollable.getScrollableTracksViewportHeight();
|
||||
}
|
||||
if (canScroll && viewSize.height > extentSize.height && considerVsbWidth) {
|
||||
prefWidth += vsb.getPreferredSize().width;
|
||||
Dimension viewportExtentSize = viewport.getPreferredSize();
|
||||
Dimension viewPreferredSize = view.getPreferredSize();
|
||||
if (view instanceof JComponent && !view.isPreferredSizeSet()) {
|
||||
Insets insets = JBViewport.getViewInsets((JComponent)view);
|
||||
JBInsets.removeFrom(viewportExtentSize, insets);
|
||||
JBInsets.removeFrom(viewPreferredSize, insets);
|
||||
}
|
||||
result.width += viewportExtentSize.width;
|
||||
result.height += viewportExtentSize.height;
|
||||
if (!viewTracksViewportHeight && vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED) {
|
||||
if (viewPreferredSize.height > viewportExtentSize.height || 0 != view.getY()) {
|
||||
vsbPolicy = VERTICAL_SCROLLBAR_ALWAYS;
|
||||
}
|
||||
}
|
||||
if (!viewTracksViewportWidth && vsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED) {
|
||||
if (viewPreferredSize.width > viewportExtentSize.width || 0 != view.getX()) {
|
||||
vsbPolicy = HORIZONTAL_SCROLLBAR_ALWAYS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vsb != null && vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) result.width += vsb.getPreferredSize().width;
|
||||
if (hsb != null && hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) result.height += hsb.getPreferredSize().height;
|
||||
|
||||
if ((hsb != null) && (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)) {
|
||||
boolean considerHsbHeight = hsb.isOpaque() || isAlwaysOpaque(view);
|
||||
if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS && considerHsbHeight) {
|
||||
prefHeight += hsb.getPreferredSize().height;
|
||||
}
|
||||
else if ((viewSize != null) && (extentSize != null)) {
|
||||
boolean canScroll = true;
|
||||
if (view instanceof Scrollable) {
|
||||
canScroll = !((Scrollable)view).getScrollableTracksViewportWidth();
|
||||
}
|
||||
if (canScroll && (viewSize.width > extentSize.width) && considerHsbHeight) {
|
||||
prefHeight += hsb.getPreferredSize().height;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rowHead != null && rowHead.isVisible()) result.width += rowHead.getPreferredSize().width;
|
||||
if (colHead != null && colHead.isVisible()) result.height += colHead.getPreferredSize().height;
|
||||
|
||||
return new Dimension(prefWidth, prefHeight);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isAlwaysOpaque(Component view) {
|
||||
|
||||
@@ -6,10 +6,12 @@ import com.intellij.notification.NotificationGroup;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.ui.TypingTarget;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.ui.components.JBScrollPane.Alignment;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.util.MethodInvocator;
|
||||
import com.intellij.util.ui.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -61,8 +63,8 @@ public class JBViewport extends JViewport implements ZoomableViewport {
|
||||
Component view = viewport.getView();
|
||||
if (view instanceof Scrollable) {
|
||||
Scrollable scrollable = (Scrollable)view;
|
||||
if (view instanceof JBList) return scrollable.getPreferredScrollableViewportSize();
|
||||
if (view instanceof JList) return JBList.getPreferredScrollableViewportSize((JList)view);
|
||||
if (view instanceof JList) return getPreferredScrollableViewportSize((JList)view);
|
||||
if (view instanceof JTree) return getPreferredScrollableViewportSize((JTree)view);
|
||||
return scrollable.getPreferredScrollableViewportSize();
|
||||
}
|
||||
if (view != null) {
|
||||
@@ -322,6 +324,7 @@ public class JBViewport extends JViewport implements ZoomableViewport {
|
||||
}
|
||||
|
||||
static Insets getViewInsets(JComponent view) {
|
||||
|
||||
Border border = view.getBorder();
|
||||
if (border instanceof ViewBorder) {
|
||||
ViewBorder vb = (ViewBorder)border;
|
||||
@@ -513,4 +516,100 @@ public class JBViewport extends JViewport implements ZoomableViewport {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> getPreferredScrollableViewportSizeDeclaringClass(@NotNull Scrollable scrollable) {
|
||||
try {
|
||||
return scrollable.getClass().getMethod("getPreferredScrollableViewportSize").getDeclaringClass();
|
||||
}
|
||||
catch (Exception exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Dimension getPreferredScrollableViewportSize(@NotNull JList list) {
|
||||
if (JList.class != getPreferredScrollableViewportSizeDeclaringClass(list)) {
|
||||
return list.getPreferredScrollableViewportSize();
|
||||
}
|
||||
Dimension size = list.getPreferredSize();
|
||||
if (size == null) return new Dimension();
|
||||
if (JList.VERTICAL != list.getLayoutOrientation()) return size;
|
||||
|
||||
int fixedWidth = list.getFixedCellWidth();
|
||||
int fixedHeight = list.getFixedCellHeight();
|
||||
|
||||
ListModel model = list.getModel();
|
||||
int modelRows = model == null ? 0 : model.getSize();
|
||||
if (modelRows <= 0) {
|
||||
if (fixedWidth <= 0) fixedWidth = Registry.intValue("ide.preferred.scrollable.viewport.fixed.width");
|
||||
if (fixedWidth <= 0) fixedWidth = JBUI.scale(256); // scaled value from JDK
|
||||
if (fixedHeight <= 0) fixedHeight = Registry.intValue("ide.preferred.scrollable.viewport.fixed.height");
|
||||
if (fixedHeight <= 0) fixedHeight = JBUI.scale(16); // scaled value from JDK
|
||||
}
|
||||
int visibleRows = list.getVisibleRowCount();
|
||||
if (visibleRows <= 0) visibleRows = Registry.intValue("ide.preferred.scrollable.viewport.visible.rows");
|
||||
|
||||
boolean addExtraSpace = 0 < visibleRows && visibleRows < modelRows && Registry.is("ide.preferred.scrollable.viewport.extra.space");
|
||||
Insets insets = list.getInsets();
|
||||
size.height = insets != null ? insets.top + insets.bottom : 0;
|
||||
if (0 < fixedWidth && 0 < fixedHeight) {
|
||||
size.width = insets != null ? insets.left + insets.right + fixedWidth : fixedWidth;
|
||||
size.height += fixedHeight * visibleRows;
|
||||
if (addExtraSpace) size.height += fixedHeight / 2;
|
||||
}
|
||||
else if (addExtraSpace) {
|
||||
Rectangle bounds = list.getCellBounds(visibleRows, visibleRows);
|
||||
if (bounds != null) size.height = bounds.y + bounds.height / 2;
|
||||
}
|
||||
else if (visibleRows > 0) {
|
||||
int lastRow = Math.min(visibleRows, modelRows) - 1;
|
||||
Rectangle bounds = list.getCellBounds(lastRow, lastRow);
|
||||
if (bounds != null) {
|
||||
size.height = bounds.y + bounds.height;
|
||||
if (insets != null) size.height += insets.bottom;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Dimension getPreferredScrollableViewportSize(@NotNull JTree tree) {
|
||||
if (JTree.class != getPreferredScrollableViewportSizeDeclaringClass(tree)) {
|
||||
return tree.getPreferredScrollableViewportSize();
|
||||
}
|
||||
Dimension size = tree.getPreferredSize();
|
||||
if (size == null) return new Dimension();
|
||||
|
||||
int fixedHeight = tree.getRowHeight();
|
||||
|
||||
int modelRows = tree.getRowCount();
|
||||
if (modelRows <= 0) {
|
||||
if (fixedHeight <= 0) fixedHeight = Registry.intValue("ide.preferred.scrollable.viewport.fixed.height");
|
||||
if (fixedHeight <= 0) fixedHeight = JBUI.scale(16);
|
||||
}
|
||||
int visibleRows = tree.getVisibleRowCount();
|
||||
if (visibleRows <= 0) visibleRows = Registry.intValue("ide.preferred.scrollable.viewport.visible.rows");
|
||||
|
||||
boolean addExtraSpace = Registry.is("ide.preferred.scrollable.viewport.extra.space");
|
||||
Insets insets = tree.getInsets();
|
||||
size.height = insets != null ? insets.top + insets.bottom : 0;
|
||||
if (0 < fixedHeight) {
|
||||
size.height += fixedHeight * visibleRows;
|
||||
if (addExtraSpace) size.height += fixedHeight / 2;
|
||||
}
|
||||
else if (visibleRows > 0) {
|
||||
int lastRow = Math.min(visibleRows, modelRows - 1);
|
||||
Rectangle bounds = tree.getRowBounds(lastRow);
|
||||
if (bounds != null) {
|
||||
size.height = bounds.y + bounds.height * (visibleRows - lastRow);
|
||||
if (addExtraSpace) {
|
||||
size.height += bounds.height / 2;
|
||||
}
|
||||
else if (insets != null) {
|
||||
size.height += insets.bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.treeStructure;
|
||||
|
||||
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
|
||||
@@ -477,10 +463,6 @@ public class SimpleTree extends Tree implements CellEditorListener {
|
||||
return (DefaultTreeModel)getModel();
|
||||
}
|
||||
|
||||
public Dimension getPreferredScrollableViewportSize() {
|
||||
return super.getPreferredSize();
|
||||
}
|
||||
|
||||
public NodeRenderer getRenderer() {
|
||||
return (NodeRenderer)getCellRenderer();
|
||||
}
|
||||
|
||||
@@ -154,8 +154,6 @@ public abstract class RecentProjectsManagerBase extends RecentProjectsManager im
|
||||
private State myState = new State();
|
||||
|
||||
private final Map<String, String> myNameCache = Collections.synchronizedMap(new THashMap<String, String>());
|
||||
private Set<String> myDuplicatesCache = null;
|
||||
private boolean isDuplicatesCacheUpdating = false;
|
||||
private boolean myBatchOpening;
|
||||
|
||||
protected RecentProjectsManagerBase(@NotNull MessageBus messageBus) {
|
||||
@@ -410,26 +408,14 @@ public abstract class RecentProjectsManagerBase extends RecentProjectsManager im
|
||||
}
|
||||
|
||||
private Set<String> getDuplicateProjectNames(Set<String> openedPaths, Set<String> recentPaths) {
|
||||
if (myDuplicatesCache != null) {
|
||||
return myDuplicatesCache;
|
||||
Set<String> names = ContainerUtil.newHashSet();
|
||||
Set<String> duplicates = ContainerUtil.newHashSet();
|
||||
for (String path : ContainerUtil.concat(openedPaths, recentPaths)) {
|
||||
if (!names.add(getProjectName(path))) {
|
||||
duplicates.add(path);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isDuplicatesCacheUpdating) {
|
||||
isDuplicatesCacheUpdating = true; //assuming that this check happens only on EDT. So, no synchronised block or double-checked locking needed
|
||||
Set<String> names = ContainerUtil.newHashSet();
|
||||
final HashSet<String> duplicates = ContainerUtil.newHashSet();
|
||||
ArrayList<String> list = ContainerUtil.newArrayList(ContainerUtil.concat(openedPaths, recentPaths));
|
||||
ApplicationManager.getApplication().executeOnPooledThread(() -> {
|
||||
for (String path : list) {
|
||||
if (!names.add(getProjectName(path))) {
|
||||
duplicates.add(path);
|
||||
}
|
||||
}
|
||||
myDuplicatesCache = duplicates;
|
||||
isDuplicatesCacheUpdating = false;
|
||||
});
|
||||
}
|
||||
return ContainerUtil.newHashSet();
|
||||
return duplicates;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -113,10 +113,10 @@ public class ContextMenuImpl extends JPanel implements Disposable {
|
||||
}
|
||||
|
||||
private void toggleContextToolbar(final boolean show) {
|
||||
myActionToolbar.updateActionsImmediately();
|
||||
if (((Container)myActionToolbar).getComponentCount() == 0) {
|
||||
return;
|
||||
}
|
||||
myActionToolbar.updateActionsImmediately();
|
||||
|
||||
if (myShow != show) {
|
||||
myShow = show;
|
||||
|
||||
@@ -315,30 +315,13 @@ public class MinusculeMatcher implements Matcher {
|
||||
int nameIndex,
|
||||
boolean allowSpecialChars,
|
||||
boolean isAsciiName) {
|
||||
boolean star = isPatternChar(patternIndex - 1, '*');
|
||||
final char p = myPattern[patternIndex];
|
||||
boolean wordStartsOnly = !isPatternChar(patternIndex - 1, '*') && !isWordSeparator[patternIndex];
|
||||
while (true) {
|
||||
int nextOccurrence = star || isWordSeparator[patternIndex] ?
|
||||
indexOfIgnoreCase(name, nameIndex + 1, p, patternIndex, isAsciiName) :
|
||||
indexOfWordStart(name, patternIndex, nameIndex);
|
||||
int nextOccurrence = findNextPatternCharOccurrence(name, nameIndex, patternIndex, isAsciiName, allowSpecialChars, wordStartsOnly);
|
||||
if (nextOccurrence < 0) {
|
||||
return null;
|
||||
}
|
||||
// pattern humps are allowed to match in words separated by " ()", lowercase characters aren't
|
||||
if (!allowSpecialChars && !myHasSeparators && !myHasHumps && StringUtil.containsAnyChar(name, myHardSeparators, nameIndex, nextOccurrence)) {
|
||||
return null;
|
||||
}
|
||||
// if the user has typed a dot, don't skip other dots between humps
|
||||
// but one pattern dot may match several name dots
|
||||
if (!allowSpecialChars && myHasDots && !isPatternChar(patternIndex - 1, '.') && StringUtil.contains(name, nameIndex, nextOccurrence, '.')) {
|
||||
return null;
|
||||
}
|
||||
// uppercase should match either uppercase or a word start
|
||||
if (!isUpperCase[patternIndex] ||
|
||||
Character.isUpperCase(name.charAt(nextOccurrence)) ||
|
||||
NameUtil.isWordStart(name, nextOccurrence) ||
|
||||
// accept uppercase matching lowercase if the whole prefix is uppercase and case sensitivity allows that
|
||||
!myHasHumps && myOptions != NameUtil.MatchingCaseSensitivity.ALL) {
|
||||
if (seemsLikeFragmentStart(name, patternIndex, nextOccurrence)) {
|
||||
FList<TextRange> ranges = matchFragment(name, patternIndex, nextOccurrence, isAsciiName);
|
||||
if (ranges != null) {
|
||||
return ranges;
|
||||
@@ -348,6 +331,37 @@ public class MinusculeMatcher implements Matcher {
|
||||
}
|
||||
}
|
||||
|
||||
private int findNextPatternCharOccurrence(@NotNull String name,
|
||||
int startAt,
|
||||
int patternIndex,
|
||||
boolean isAsciiName,
|
||||
boolean allowSpecialChars, boolean wordStartsOnly) {
|
||||
int next = wordStartsOnly
|
||||
? indexOfWordStart(name, patternIndex, startAt)
|
||||
: indexOfIgnoreCase(name, startAt + 1, myPattern[patternIndex], patternIndex, isAsciiName);
|
||||
|
||||
// pattern humps are allowed to match in words separated by " ()", lowercase characters aren't
|
||||
if (!allowSpecialChars && !myHasSeparators && !myHasHumps && StringUtil.containsAnyChar(name, myHardSeparators, startAt, next)) {
|
||||
return -1;
|
||||
}
|
||||
// if the user has typed a dot, don't skip other dots between humps
|
||||
// but one pattern dot may match several name dots
|
||||
if (!allowSpecialChars && myHasDots && !isPatternChar(patternIndex - 1, '.') && StringUtil.contains(name, startAt, next, '.')) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
private boolean seemsLikeFragmentStart(@NotNull String name, int patternIndex, int nextOccurrence) {
|
||||
// uppercase should match either uppercase or a word start
|
||||
return !isUpperCase[patternIndex] ||
|
||||
Character.isUpperCase(name.charAt(nextOccurrence)) ||
|
||||
NameUtil.isWordStart(name, nextOccurrence) ||
|
||||
// accept uppercase matching lowercase if the whole prefix is uppercase and case sensitivity allows that
|
||||
!myHasHumps && myOptions != NameUtil.MatchingCaseSensitivity.ALL;
|
||||
}
|
||||
|
||||
private boolean charEquals(char patternChar, int patternIndex, char c, boolean isIgnoreCase) {
|
||||
return patternChar == c ||
|
||||
isIgnoreCase && (toLowerCase[patternIndex] == c || toUpperCase[patternIndex] == c);
|
||||
|
||||
+1
-1
@@ -137,7 +137,7 @@ public class MoveChangesToAnotherListAction extends AnAction implements DumbAwar
|
||||
List<VirtualFile> unversionedFiles = ContainerUtil.newArrayList();
|
||||
final List<VirtualFile> changedFiles = ContainerUtil.newArrayList();
|
||||
VirtualFile[] files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY);
|
||||
if (files != null) {
|
||||
if (files != null && changesList.isEmpty()) {
|
||||
changesList.addAll(getChangesForSelectedFiles(project, files, unversionedFiles, changedFiles));
|
||||
}
|
||||
|
||||
|
||||
+23
-10
@@ -24,15 +24,18 @@ import com.intellij.openapi.vcs.changes.ChangeListManager;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import com.intellij.openapi.vcs.changes.actions.MoveChangesToAnotherListAction;
|
||||
import com.intellij.openapi.vcs.changes.ui.ChangeListChooser;
|
||||
import com.intellij.openapi.vcs.ex.PartialLocalLineStatusTracker.LocalRange;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
public class MoveChangesLineStatusAction extends LineStatusActionBase {
|
||||
@Override
|
||||
protected boolean isEnabled(@NotNull LineStatusTrackerBase<?> tracker, @NotNull Editor editor) {
|
||||
@@ -51,36 +54,46 @@ public class MoveChangesLineStatusAction extends LineStatusActionBase {
|
||||
public static void moveToAnotherChangelist(@NotNull PartialLocalLineStatusTracker tracker, @NotNull BitSet selectedLines) {
|
||||
Project project = tracker.getProject();
|
||||
|
||||
List<PartialLocalLineStatusTracker.LocalRange> ranges = tracker.getRangesForLines(selectedLines);
|
||||
List<LocalRange> ranges = tracker.getRangesForLines(selectedLines);
|
||||
if (ranges == null || ranges.isEmpty()) return;
|
||||
|
||||
Set<String> selectedListIds = ContainerUtil.map2Set(ranges, range -> range.getChangelistId());
|
||||
LocalChangeList targetList = askTargetChangelist(project, selectedListIds);
|
||||
LocalChangeList targetList = askTargetChangelist(project, ranges, tracker);
|
||||
if (targetList == null) return;
|
||||
|
||||
tracker.moveToChangelist(selectedLines, targetList);
|
||||
}
|
||||
|
||||
public static void moveToAnotherChangelist(@NotNull PartialLocalLineStatusTracker tracker, @NotNull PartialLocalLineStatusTracker.LocalRange range) {
|
||||
public static void moveToAnotherChangelist(@NotNull PartialLocalLineStatusTracker tracker, @NotNull LocalRange range) {
|
||||
Project project = tracker.getProject();
|
||||
|
||||
Set<String> selectedListIds = Collections.singleton(range.getChangelistId());
|
||||
LocalChangeList targetList = askTargetChangelist(project, selectedListIds);
|
||||
LocalChangeList targetList = askTargetChangelist(project, singletonList(range), tracker);
|
||||
if (targetList == null) return;
|
||||
|
||||
tracker.moveToChangelist(range, targetList);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static LocalChangeList askTargetChangelist(Project project, @NotNull Set<String> selectedListIds) {
|
||||
private static LocalChangeList askTargetChangelist(Project project,
|
||||
@NotNull List<LocalRange> selectedRanges,
|
||||
@NotNull PartialLocalLineStatusTracker tracker) {
|
||||
Set<String> selectedListIds = ContainerUtil.map2Set(selectedRanges, range -> range.getChangelistId());
|
||||
|
||||
Set<String> remainingTrackerListIds = new HashSet<>(tracker.getAffectedChangeListsIds());
|
||||
remainingTrackerListIds.removeAll(selectedListIds);
|
||||
|
||||
ChangeListManager clm = ChangeListManager.getInstance(project);
|
||||
List<LocalChangeList> allChangelists = clm.getChangeListsCopy();
|
||||
|
||||
List<LocalChangeList> nonAffectedLists = ContainerUtil.filter(allChangelists, list -> !selectedListIds.contains(list.getId()));
|
||||
List<LocalChangeList> remainingTrackerLists = ContainerUtil.filter(allChangelists, list -> remainingTrackerListIds.contains(list.getId()));
|
||||
|
||||
List<LocalChangeList> suggestedLists = nonAffectedLists.isEmpty()
|
||||
? Collections.singletonList(clm.getDefaultChangeList())
|
||||
? singletonList(clm.getDefaultChangeList())
|
||||
: nonAffectedLists;
|
||||
ChangeList defaultSelection = MoveChangesToAnotherListAction.guessPreferredList(nonAffectedLists);
|
||||
|
||||
List<LocalChangeList> preferedLists = remainingTrackerLists.isEmpty() ? nonAffectedLists : remainingTrackerLists;
|
||||
ChangeList defaultSelection = MoveChangesToAnotherListAction.guessPreferredList(preferedLists);
|
||||
|
||||
ChangeListChooser chooser = new ChangeListChooser(project,
|
||||
suggestedLists,
|
||||
defaultSelection,
|
||||
|
||||
@@ -277,6 +277,7 @@ abstract class GitImplBase implements Git {
|
||||
"cannot rebase:",
|
||||
"conflict",
|
||||
"unable",
|
||||
"The file will have its original",
|
||||
"runnerw:"
|
||||
};
|
||||
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
*/
|
||||
package git4idea.config;
|
||||
|
||||
import com.intellij.execution.configurations.PathEnvironmentVariableUtil;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -24,7 +26,7 @@ abstract class CachingFileTester<T> {
|
||||
long currentLastModificationDate = 0L;
|
||||
|
||||
try {
|
||||
currentLastModificationDate = Files.getLastModifiedTime(Paths.get(filePath)).toMillis();
|
||||
currentLastModificationDate = Files.getLastModifiedTime(Paths.get(resolveAgainstEnvPath(filePath))).toMillis();
|
||||
if (result == null || result.getFileLastModifiedTimestamp() != currentLastModificationDate) {
|
||||
result = new TestResult(testFile(filePath), currentLastModificationDate);
|
||||
}
|
||||
@@ -40,6 +42,17 @@ abstract class CachingFileTester<T> {
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String resolveAgainstEnvPath(@NotNull String filePath) {
|
||||
if (!filePath.contains(File.separator)) {
|
||||
File exeFile = PathEnvironmentVariableUtil.findInPath(filePath);
|
||||
if (exeFile != null) {
|
||||
return exeFile.getPath();
|
||||
}
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TestResult getCachedResultForFile(@NotNull String filePath) {
|
||||
return myFileTestMap.get(filePath);
|
||||
|
||||
@@ -23,6 +23,8 @@ import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.vcs.log.Hash;
|
||||
import com.intellij.vcs.log.impl.HashImpl;
|
||||
import com.intellij.vcsUtil.VcsFileUtil;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import git4idea.GitUtil;
|
||||
@@ -95,27 +97,27 @@ public class GitIndexUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String write(@NotNull GitRepository repository,
|
||||
@NotNull FilePath filePath,
|
||||
@NotNull byte[] bytes,
|
||||
boolean executable) throws VcsException {
|
||||
public static Hash write(@NotNull GitRepository repository,
|
||||
@NotNull FilePath filePath,
|
||||
@NotNull byte[] bytes,
|
||||
boolean executable) throws VcsException {
|
||||
return write(repository, filePath, new ByteArrayInputStream(bytes), executable);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String write(@NotNull GitRepository repository,
|
||||
@NotNull FilePath filePath,
|
||||
@NotNull InputStream content,
|
||||
boolean executable) throws VcsException {
|
||||
String hash = hashObject(repository, filePath, content);
|
||||
public static Hash write(@NotNull GitRepository repository,
|
||||
@NotNull FilePath filePath,
|
||||
@NotNull InputStream content,
|
||||
boolean executable) throws VcsException {
|
||||
Hash hash = hashObject(repository, filePath, content);
|
||||
updateIndex(repository, filePath, hash, executable);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String hashObject(@NotNull GitRepository repository,
|
||||
@NotNull FilePath filePath,
|
||||
@NotNull InputStream content) throws VcsException {
|
||||
private static Hash hashObject(@NotNull GitRepository repository,
|
||||
@NotNull FilePath filePath,
|
||||
@NotNull InputStream content) throws VcsException {
|
||||
GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.HASH_OBJECT);
|
||||
h.setSilent(true);
|
||||
h.addParameters("-w", "--stdin");
|
||||
@@ -135,19 +137,19 @@ public class GitIndexUtil {
|
||||
notNull(GitVcs.getInstance(repository.getProject())).showErrors(h.errors(), "Applying index modifications");
|
||||
throw h.errors().get(0);
|
||||
}
|
||||
return output.trim();
|
||||
return HashImpl.build(output.trim());
|
||||
}
|
||||
|
||||
private static void updateIndex(@NotNull GitRepository repository,
|
||||
@NotNull FilePath filePath,
|
||||
@NotNull String blobHash,
|
||||
@NotNull Hash blobHash,
|
||||
boolean isExecutable) throws VcsException {
|
||||
String mode = isExecutable ? EXECUTABLE_MODE : DEFAULT_MODE;
|
||||
String path = VcsFileUtil.relativePath(repository.getRoot(), filePath);
|
||||
|
||||
GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.UPDATE_INDEX);
|
||||
h.setSilent(true);
|
||||
h.addParameters("--cacheinfo", mode + "," + blobHash + "," + path);
|
||||
h.addParameters("--cacheinfo", mode + "," + blobHash.asString() + "," + path);
|
||||
h.endOptions();
|
||||
Git.getInstance().runCommandWithoutCollectingOutput(h).getOutputOrThrow();
|
||||
}
|
||||
|
||||
@@ -112,6 +112,7 @@
|
||||
<projectService serviceImplementation="com.intellij.tasks.impl.TaskProjectConfiguration"/>
|
||||
<applicationService serviceImplementation="com.intellij.tasks.config.RecentTaskRepositories"/>
|
||||
<applicationService serviceImplementation="com.intellij.tasks.config.TaskSettings"/>
|
||||
<search.optionContributor implementation="com.intellij.tasks.config.TaskSearchableOptionContributor"/>
|
||||
|
||||
<lang.documentationProvider language="TEXT" implementationClass="com.intellij.tasks.doc.TaskDocumentationProvider"/>
|
||||
|
||||
|
||||
+18
-1
@@ -8,6 +8,7 @@ import com.intellij.openapi.actionSystem.Separator;
|
||||
import com.intellij.openapi.options.BaseConfigurable;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.options.SearchableConfigurable;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ui.configuration.actions.IconWithTextAction;
|
||||
@@ -40,9 +41,11 @@ import java.util.List;
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class TaskRepositoriesConfigurable extends BaseConfigurable implements Configurable.NoScroll {
|
||||
public class TaskRepositoriesConfigurable extends BaseConfigurable implements Configurable.NoScroll, SearchableConfigurable {
|
||||
|
||||
public static final String ID = "tasks.servers";
|
||||
private static final String EMPTY_PANEL = "empty.panel";
|
||||
|
||||
private JPanel myPanel;
|
||||
private JPanel myServersPanel;
|
||||
private final JBList myRepositoriesList;
|
||||
@@ -257,6 +260,20 @@ public class TaskRepositoriesConfigurable extends BaseConfigurable implements Co
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Runnable enableSearch(String option) {
|
||||
TaskRepository matched =
|
||||
myRepositories.stream().filter(repository -> repository.getRepositoryType().getName().contains(option)).findFirst().orElse(null);
|
||||
return matched == null ? null : () -> myRepositoriesList.setSelectedValue(matched, true);
|
||||
}
|
||||
|
||||
private abstract class AddServerAction extends IconWithTextAction implements DumbAware {
|
||||
|
||||
public AddServerAction(TaskRepositorySubtype subtype) {
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.tasks.config;
|
||||
|
||||
import com.intellij.ide.ui.search.SearchableOptionContributor;
|
||||
import com.intellij.ide.ui.search.SearchableOptionProcessor;
|
||||
import com.intellij.tasks.TaskRepositoryType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TaskSearchableOptionContributor extends SearchableOptionContributor {
|
||||
@Override
|
||||
public void processOptions(@NotNull SearchableOptionProcessor processor) {
|
||||
TaskRepositoryType[] types = TaskRepositoryType.getRepositoryTypes();
|
||||
for (TaskRepositoryType type : types) {
|
||||
processor.addOptions(type.getName(), null, null, TaskRepositoriesConfigurable.ID, null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user