summaryrefslogtreecommitdiff
path: root/platform/platform-api/src/com/intellij
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-api/src/com/intellij')
-rw-r--r--platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java127
-rw-r--r--platform/platform-api/src/com/intellij/ide/BrowserUtil.java8
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/BrowserFamily.java6
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java36
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/BrowserSpecificSettings.java6
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/chrome/ChromeSettings.java25
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/firefox/FirefoxSettingsConfigurable.java16
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java4
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java11
-rw-r--r--platform/platform-api/src/com/intellij/openapi/diff/DiffRequestFactory.java9
-rw-r--r--platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java14
-rw-r--r--platform/platform-api/src/com/intellij/openapi/diff/MergeRequest.java2
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/CaretStateTransferableData.java56
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java68
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/CopyPasteSupport.java212
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/EditorCopyPasteHelper.java53
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java97
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java263
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/actionSystem/DialogAwareDataContext.java54
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java8
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java46
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java27
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java2
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java15
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/Banner.java20
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java7
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java17
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/FixedComboBoxEditor.java16
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java14
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/NamedConfigurable.java9
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java233
-rw-r--r--platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java2
-rw-r--r--platform/platform-api/src/com/intellij/ui/AnActionButton.java19
-rw-r--r--platform/platform-api/src/com/intellij/ui/CheckboxTreeAdapter.java35
-rw-r--r--platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java266
-rw-r--r--platform/platform-api/src/com/intellij/ui/CheckboxTreeHelper.java234
-rw-r--r--platform/platform-api/src/com/intellij/ui/CheckboxTreeListener.java (renamed from platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java)17
-rw-r--r--platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java5
-rw-r--r--platform/platform-api/src/com/intellij/ui/JBSplitter.java8
-rw-r--r--platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java59
-rw-r--r--platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java11
-rw-r--r--platform/platform-api/src/com/intellij/ui/table/BaseTableView.java8
-rw-r--r--platform/platform-api/src/com/intellij/ui/table/JBTable.java8
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java9
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java2
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java12
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java22
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java13
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java4
-rw-r--r--platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java33
-rw-r--r--platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java4
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java6
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/FormBuilder.java5
53 files changed, 1163 insertions, 1100 deletions
diff --git a/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java b/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java
deleted file mode 100644
index 7d972816769c..000000000000
--- a/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2000-2014 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.codeInsight.editorActions;
-
-import com.intellij.openapi.editor.RawText;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.text.StringUtil;
-
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.Transferable;
-import java.awt.datatransfer.UnsupportedFlavorException;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-public class TextBlockTransferable implements Transferable {
- private final Collection<TextBlockTransferableData> myExtraData;
- private final RawText myRawText;
- private final String myText;
- private final DataFlavor[] myTransferDataFlavors;
-
- public TextBlockTransferable(String text, Collection<TextBlockTransferableData> extraData, RawText rawText) {
- myText = text;
- myExtraData = extraData;
- myRawText = rawText;
-
- List<DataFlavor> dataFlavors = new ArrayList<DataFlavor>();
- Collections.addAll(dataFlavors, DataFlavor.stringFlavor, DataFlavor.plainTextFlavor);
- final DataFlavor flavor = RawText.getDataFlavor();
- if (myRawText != null && flavor != null) {
- dataFlavors.add(flavor);
- }
- for(TextBlockTransferableData data: extraData) {
- final DataFlavor blockFlavor = data.getFlavor();
- if (blockFlavor != null) {
- dataFlavors.add(blockFlavor);
- }
- }
- myTransferDataFlavors = dataFlavors.toArray(new DataFlavor[dataFlavors.size()]);
- }
-
- @Override
- public DataFlavor[] getTransferDataFlavors() {
- return myTransferDataFlavors;
- }
-
- @Override
- public boolean isDataFlavorSupported(DataFlavor flavor) {
- DataFlavor[] flavors = getTransferDataFlavors();
- for (DataFlavor flavor1 : flavors) {
- if (flavor.equals(flavor1)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
- try {
- for(TextBlockTransferableData data: myExtraData) {
- if (Comparing.equal(data.getFlavor(), flavor)) {
- return data;
- }
- }
- if (myRawText != null && Comparing.equal(RawText.getDataFlavor(), flavor)) {
- return myRawText;
- }
- else if (DataFlavor.stringFlavor.equals(flavor)) {
- return myText;
- }
- else if (DataFlavor.plainTextFlavor.equals(flavor)) {
- return new StringReader(myText);
- }
- }
- catch(NoClassDefFoundError e) {
- // ignore
- }
- throw new UnsupportedFlavorException(flavor);
- }
-
- public static String convertLineSeparators(String text,
- String newSeparator,
- Collection<TextBlockTransferableData> transferableDatas) {
- if (transferableDatas.size() > 0){
- int size = 0;
- for(TextBlockTransferableData data: transferableDatas) {
- size += data.getOffsetCount();
- }
-
- int[] offsets = new int[size];
- int index = 0;
- for(TextBlockTransferableData data: transferableDatas) {
- index = data.getOffsets(offsets, index);
- }
-
- text = StringUtil.convertLineSeparators(text, newSeparator, offsets);
-
- index = 0;
- for(TextBlockTransferableData data: transferableDatas) {
- index = data.setOffsets(offsets, index);
- }
-
- return text;
- }
- else{
- return StringUtil.convertLineSeparators(text, newSeparator);
- }
- }
-} \ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java
index 90308f5dbfda..cd1d1b0dba49 100644
--- a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java
+++ b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java
@@ -20,6 +20,7 @@ import com.intellij.execution.util.ExecUtil;
import com.intellij.ide.browsers.BrowserLauncher;
import com.intellij.ide.browsers.BrowserLauncherAppless;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -106,6 +107,10 @@ public class BrowserUtil {
getBrowserLauncher().browse(uri);
}
+ public static void browse(@NotNull String url, @Nullable Project project) {
+ getBrowserLauncher().browse(url, null, project);
+ }
+
@SuppressWarnings("UnusedDeclaration")
@NotNull
@Deprecated
@@ -145,6 +150,9 @@ public class BrowserUtil {
else if (SystemInfo.isMac) {
return "open";
}
+ else if (SystemInfo.isUnix) {
+ return "/usr/bin/firefox";
+ }
else {
return "";
}
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/BrowserFamily.java b/platform/platform-api/src/com/intellij/ide/browsers/BrowserFamily.java
index f6826b528427..f767ec90d49f 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/BrowserFamily.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/BrowserFamily.java
@@ -35,9 +35,9 @@ public enum BrowserFamily implements Iconable {
private final Icon myIcon;
BrowserFamily(@NotNull String name,
- @NotNull final String windowsPath,
- @Nullable final String unixPath,
- @Nullable final String macPath,
+ @NotNull String windowsPath,
+ @Nullable String unixPath,
+ @Nullable String macPath,
@NotNull Icon icon) {
myName = name;
myWindowsPath = windowsPath;
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java b/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
index 0c34152861d1..736dcd8afe22 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
@@ -74,10 +74,10 @@ public class BrowserLauncherAppless extends BrowserLauncher {
Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(action);
}
- public static boolean canStartDefaultBrowser() {
+ public static boolean canUseSystemDefaultBrowserPolicy() {
return isDesktopActionSupported(Desktop.Action.BROWSE) ||
SystemInfo.isMac || SystemInfo.isWindows ||
- SystemInfo.isUnix && SystemInfo.hasXdgOpen();
+ (SystemInfo.isUnix && SystemInfo.hasXdgOpen());
}
private static GeneralSettings getGeneralSettingsInstance() {
@@ -109,7 +109,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
@Override
public void open(@NotNull String url) {
- openOrBrowse(url, false);
+ openOrBrowse(url, false, null);
}
@Override
@@ -119,6 +119,10 @@ public class BrowserLauncherAppless extends BrowserLauncher {
@Override
public void browse(@NotNull URI uri) {
+ browse(uri, null);
+ }
+
+ public void browse(@NotNull URI uri, @Nullable Project project) {
LOG.debug("Launch browser: [" + uri + "]");
GeneralSettings settings = getGeneralSettingsInstance();
@@ -136,15 +140,19 @@ public class BrowserLauncherAppless extends BrowserLauncher {
List<String> command = getDefaultBrowserCommand();
if (command != null) {
- doLaunch(uri.toString(), command, null, null, ArrayUtil.EMPTY_STRING_ARRAY, null);
+ doLaunch(uri.toString(), command, null, project, ArrayUtil.EMPTY_STRING_ARRAY, null);
return;
}
}
- browseUsingPath(uri.toString(), settings.getBrowserPath(), null, null, ArrayUtil.EMPTY_STRING_ARRAY);
+ browseUsingNotSystemDefaultBrowserPolicy(uri, settings, project);
}
- private void openOrBrowse(@NotNull String url, boolean browse) {
+ protected void browseUsingNotSystemDefaultBrowserPolicy(@NotNull URI uri, @NotNull GeneralSettings settings, @Nullable Project project) {
+ browseUsingPath(uri.toString(), settings.getBrowserPath(), null, project, ArrayUtil.EMPTY_STRING_ARRAY);
+ }
+
+ private void openOrBrowse(@NotNull String url, boolean browse, @Nullable Project project) {
url = url.trim();
if (url.startsWith("jar:")) {
@@ -181,7 +189,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
}
if (uri == null) {
- doShowError(IdeBundle.message("error.malformed.url", url), null, null, null, null);
+ doShowError(IdeBundle.message("error.malformed.url", url), null, project, null, null);
}
else {
browse(uri);
@@ -380,7 +388,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
@Override
public void browse(@NotNull String url, @Nullable WebBrowser browser, @Nullable Project project) {
if (browser == null) {
- openOrBrowse(url, true);
+ openOrBrowse(url, true, project);
}
else {
for (UrlOpener urlOpener : UrlOpener.EP_NAME.getExtensions()) {
@@ -436,8 +444,8 @@ public class BrowserLauncherAppless extends BrowserLauncher {
private boolean doLaunch(@Nullable String url,
@NotNull List<String> command,
- @Nullable final WebBrowser browser,
- @Nullable final Project project,
+ @Nullable WebBrowser browser,
+ @Nullable Project project,
@NotNull String[] additionalParameters,
@Nullable Runnable launchTask) {
GeneralCommandLine commandLine = new GeneralCommandLine(command);
@@ -454,7 +462,13 @@ public class BrowserLauncherAppless extends BrowserLauncher {
commandLine.addParameter(url);
}
- addArgs(commandLine, browser == null ? null : browser.getSpecificSettings(), additionalParameters);
+ final BrowserSpecificSettings browserSpecificSettings = browser == null ? null : browser.getSpecificSettings();
+ if (browserSpecificSettings != null) {
+ commandLine.getEnvironment().putAll(browserSpecificSettings.getEnvironmentVariables());
+ }
+
+ addArgs(commandLine, browserSpecificSettings, additionalParameters);
+
try {
Process process = commandLine.createProcess();
checkCreatedProcess(browser, project, commandLine, process, launchTask);
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/BrowserSpecificSettings.java b/platform/platform-api/src/com/intellij/ide/browsers/BrowserSpecificSettings.java
index 826ca80cd21a..b7fd90ef3ade 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/BrowserSpecificSettings.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/BrowserSpecificSettings.java
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
public abstract class BrowserSpecificSettings implements Cloneable {
@NotNull
@@ -30,6 +31,11 @@ public abstract class BrowserSpecificSettings implements Cloneable {
return Collections.emptyList();
}
+ @NotNull
+ public Map<String, String> getEnvironmentVariables() {
+ return Collections.emptyMap();
+ }
+
@Override
public BrowserSpecificSettings clone() {
try {
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/chrome/ChromeSettings.java b/platform/platform-api/src/com/intellij/ide/browsers/chrome/ChromeSettings.java
index b6ca3e7ac44f..555097bb546c 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/chrome/ChromeSettings.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/chrome/ChromeSettings.java
@@ -21,7 +21,9 @@ import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.execution.ParametersListUtil;
+import com.intellij.util.xmlb.annotations.MapAnnotation;
import com.intellij.util.xmlb.annotations.Tag;
+import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,6 +35,7 @@ public final class ChromeSettings extends BrowserSpecificSettings {
private @Nullable String myCommandLineOptions;
private @Nullable String myUserDataDirectoryPath;
private boolean myUseCustomProfile;
+ private @NotNull THashMap<String, String> myEnvironmentVariables = new THashMap<String, String>();
public ChromeSettings() {
}
@@ -85,6 +88,18 @@ public final class ChromeSettings extends BrowserSpecificSettings {
return cliOptions;
}
+ @Override
+ @NotNull
+ @Tag("environment-variables")
+ @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false)
+ public THashMap<String, String> getEnvironmentVariables() {
+ return myEnvironmentVariables;
+ }
+
+ public void setEnvironmentVariables(@NotNull final THashMap<String, String> environmentVariables) {
+ myEnvironmentVariables = environmentVariables;
+ }
+
@NotNull
@Override
public ChromeSettingsConfigurable createConfigurable() {
@@ -92,6 +107,13 @@ public final class ChromeSettings extends BrowserSpecificSettings {
}
@Override
+ public ChromeSettings clone() {
+ ChromeSettings clone = (ChromeSettings)super.clone();
+ clone.myEnvironmentVariables = myEnvironmentVariables.clone();
+ return clone;
+ }
+
+ @Override
public boolean equals(Object o) {
if (this == o) {
return true;
@@ -103,6 +125,7 @@ public final class ChromeSettings extends BrowserSpecificSettings {
ChromeSettings settings = (ChromeSettings)o;
return myUseCustomProfile == settings.myUseCustomProfile &&
Comparing.equal(myCommandLineOptions, settings.myCommandLineOptions) &&
- (!myUseCustomProfile || Comparing.equal(myUserDataDirectoryPath, settings.myUserDataDirectoryPath));
+ (!myUseCustomProfile || Comparing.equal(myUserDataDirectoryPath, settings.myUserDataDirectoryPath)) &&
+ myEnvironmentVariables.equals(settings.myEnvironmentVariables);
}
}
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/firefox/FirefoxSettingsConfigurable.java b/platform/platform-api/src/com/intellij/ide/browsers/firefox/FirefoxSettingsConfigurable.java
index ef95f7cb872e..c28b7e495b41 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/firefox/FirefoxSettingsConfigurable.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/firefox/FirefoxSettingsConfigurable.java
@@ -26,7 +26,6 @@ import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.DocumentAdapter;
-import com.intellij.util.ObjectUtils;
import com.intellij.util.PathUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.Nullable;
@@ -48,7 +47,7 @@ public class FirefoxSettingsConfigurable implements Configurable {
private final FirefoxSettings mySettings;
private String myLastProfilesIniPath;
private String myDefaultProfilesIniPath;
- private String myDefaultProfile;
+ private String defaultProfile;
public FirefoxSettingsConfigurable(FirefoxSettings settings) {
mySettings = settings;
@@ -89,11 +88,8 @@ public class FirefoxSettingsConfigurable implements Configurable {
@Nullable
private String getConfiguredProfileName() {
- final String selected = (String)myProfileCombobox.getSelectedItem();
- if (Comparing.equal(myDefaultProfile, selected)) {
- return null;
- }
- return selected;
+ String selected = (String)myProfileCombobox.getSelectedItem();
+ return Comparing.equal(defaultProfile, selected) ? null : selected;
}
@Override
@@ -110,7 +106,9 @@ public class FirefoxSettingsConfigurable implements Configurable {
String path = mySettings.getProfilesIniPath();
myProfilesIniPathField.setText(path != null ? FileUtilRt.toSystemDependentName(path) : myDefaultProfilesIniPath);
updateProfilesList();
- myProfileCombobox.setSelectedItem(ObjectUtils.notNull(mySettings.getProfile(), myDefaultProfile));
+
+ String profile = mySettings.getProfile();
+ myProfileCombobox.setSelectedItem(profile == null ? defaultProfile : profile);
}
private void updateProfilesList() {
@@ -122,7 +120,7 @@ public class FirefoxSettingsConfigurable implements Configurable {
myProfileCombobox.removeAllItems();
final List<FirefoxProfile> profiles = FirefoxUtil.computeProfiles(new File(profilesIniPath));
final FirefoxProfile defaultProfile = FirefoxUtil.getDefaultProfile(profiles);
- myDefaultProfile = defaultProfile != null ? defaultProfile.getName() : null;
+ this.defaultProfile = defaultProfile != null ? defaultProfile.getName() : null;
for (FirefoxProfile profile : profiles) {
//noinspection unchecked
myProfileCombobox.addItem(profile.getName());
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
index 1d4fea4c01de..049bde52f582 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
@@ -36,6 +36,8 @@ public interface IdeActions {
@NonNls String ACTION_EDITOR_SELECT_WORD_AT_CARET = "EditorSelectWord";
@NonNls String ACTION_EDITOR_UNSELECT_WORD_AT_CARET = "EditorUnSelectWord";
@NonNls String ACTION_EDITOR_BACKSPACE = "EditorBackSpace";
+ @NonNls String ACTION_EDITOR_MOVE_CARET_LEFT_WITH_SELECTION = "EditorLeftWithSelection";
+ @NonNls String ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION = "EditorRightWithSelection";
@NonNls String ACTION_EDITOR_MOVE_CARET_UP = "EditorUp";
@NonNls String ACTION_EDITOR_MOVE_CARET_LEFT = "EditorLeft";
@NonNls String ACTION_EDITOR_MOVE_CARET_DOWN = "EditorDown";
@@ -269,7 +271,7 @@ public interface IdeActions {
String ACTION_UNDO = "$Undo";
String ACTION_REDO = "$Redo";
String GROUP_REFACTOR = "RefactoringMenu";
- String SELECTED_CHANGES_ROLLBACK = "RollbackLineStatusChanges";
+ String SELECTED_CHANGES_ROLLBACK = "Vcs.RollbackChangedLines";
String CHANGES_VIEW_ROLLBACK = "ChangesView.Rollback";
String CONSOLE_CLEAR_ALL = "ConsoleView.ClearAll";
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
index 92a1d9c8b42c..7398bf706c78 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
@@ -110,10 +110,10 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
private boolean myMouseInside = false;
private JBPopup myPopup;
private boolean myForceTransparent = false;
- private Boolean myForceEnabled = null;
public ComboBoxButton(Presentation presentation) {
myPresentation = presentation;
+ setEnabled(myPresentation.isEnabled());
setModel(new MyButtonModel());
setHorizontalAlignment(LEFT);
setFocusable(false);
@@ -207,12 +207,6 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
}
}
- @Override
- public void setEnabled(final boolean enabled) {
- super.setEnabled(enabled);
- myForceEnabled = enabled;
- }
-
public void setForceTransparent(boolean transparent) {
myForceTransparent = transparent;
}
@@ -282,7 +276,6 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
private void initButton() {
setIcon(myPresentation.getIcon());
- setEnabled(myPresentation.isEnabled());
setText(myPresentation.getText());
updateTooltipText(myPresentation.getDescription());
updateButtonSize();
@@ -383,7 +376,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
final Dimension size = getSize();
final boolean isEmpty = getIcon() == null && StringUtil.isEmpty(getText());
- final Color textColor = (myForceEnabled == null ? myPresentation.isEnabled() : myForceEnabled)
+ final Color textColor = isEnabled()
? UIManager.getColor("Panel.foreground")
: UIUtil.getInactiveTextColor();
if (myForceTransparent) {
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/DiffRequestFactory.java b/platform/platform-api/src/com/intellij/openapi/diff/DiffRequestFactory.java
index 78f07a04b4a9..e2c9175ac915 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/DiffRequestFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/diff/DiffRequestFactory.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.diff;
import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -59,4 +60,12 @@ public abstract class DiffRequestFactory {
Project project,
@Nullable ActionButtonPresentation okButtonPresentation,
@Nullable ActionButtonPresentation cancelButtonPresentation);
+
+ public abstract MergeRequest create3WayDiffRequest(String leftText,
+ String rightText,
+ String originalContent,
+ @Nullable FileType type,
+ Project project,
+ @Nullable ActionButtonPresentation okButtonPresentation,
+ @Nullable ActionButtonPresentation cancelButtonPresentation);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java b/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java
index 26537316b4e9..d630bad790df 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java
+++ b/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java
@@ -41,18 +41,28 @@ public class FragmentContent extends DiffContent {
private final FileType myType;
private final MyDocumentsSynchronizer mySynchonizer;
public static final Key<Document> ORIGINAL_DOCUMENT = new Key<Document>("ORIGINAL_DOCUMENT");
+ private final boolean myForceReadOnly;
public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, VirtualFile file) {
- this(original, range, project, file != null ? DiffContentUtil.getContentType(file) : null);
+ this(original, range, project, file, false);
+ }
+
+ public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, VirtualFile file, boolean forceReadOnly) {
+ this(original, range, project, file != null ? DiffContentUtil.getContentType(file) : null, forceReadOnly);
}
public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, FileType fileType) {
+ this(original, range, project, fileType, false);
+ }
+
+ public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, FileType fileType, boolean forceReadOnly) {
RangeMarker rangeMarker = original.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true);
rangeMarker.setGreedyToLeft(true);
rangeMarker.setGreedyToRight(true);
mySynchonizer = new MyDocumentsSynchronizer(project, rangeMarker);
myOriginal = original;
myType = fileType;
+ myForceReadOnly = forceReadOnly;
}
public FragmentContent(DiffContent original, TextRange range, Project project) {
@@ -152,7 +162,7 @@ public class FragmentContent extends DiffContent {
String textInRange =
originalDocument.getCharsSequence().subSequence(myRangeMarker.getStartOffset(), myRangeMarker.getEndOffset()).toString();
final Document result = EditorFactory.getInstance().createDocument(textInRange);
- result.setReadOnly(!originalDocument.isWritable());
+ result.setReadOnly(myForceReadOnly || !originalDocument.isWritable());
result.putUserData(ORIGINAL_DOCUMENT, originalDocument);
return result;
}
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/MergeRequest.java b/platform/platform-api/src/com/intellij/openapi/diff/MergeRequest.java
index 29243f7b9be0..ce8d56044f96 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/MergeRequest.java
+++ b/platform/platform-api/src/com/intellij/openapi/diff/MergeRequest.java
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.Nullable;
* @see DiffRequestFactory#createMergeRequest
*/
public abstract class MergeRequest extends DiffRequest {
- protected MergeRequest(Project project) {
+ protected MergeRequest(@Nullable Project project) {
super(project);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/CaretStateTransferableData.java b/platform/platform-api/src/com/intellij/openapi/editor/CaretStateTransferableData.java
deleted file mode 100644
index f0d2085cbb6b..000000000000
--- a/platform/platform-api/src/com/intellij/openapi/editor/CaretStateTransferableData.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2000-2014 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.openapi.editor;
-
-import com.intellij.codeInsight.editorActions.TextBlockTransferableData;
-
-import java.awt.datatransfer.DataFlavor;
-
-public class CaretStateTransferableData implements TextBlockTransferableData {
- public static final DataFlavor FLAVOR = new DataFlavor(CaretStateTransferableData.class, "Caret state");
-
- public final int[] startOffsets;
- public final int[] endOffsets;
-
- public CaretStateTransferableData(int[] startOffsets, int[] endOffsets) {
- this.startOffsets = startOffsets;
- this.endOffsets = endOffsets;
- }
-
- @Override
- public DataFlavor getFlavor() {
- return FLAVOR;
- }
-
- @Override
- public int getOffsetCount() {
- return startOffsets.length + endOffsets.length;
- }
-
- @Override
- public int getOffsets(int[] offsets, int index) {
- System.arraycopy(startOffsets, 0, offsets, index, startOffsets.length);
- System.arraycopy(endOffsets, 0, offsets, index + startOffsets.length, endOffsets.length);
- return index + getOffsetCount();
- }
-
- @Override
- public int setOffsets(int[] offsets, int index) {
- System.arraycopy(offsets, index, startOffsets, 0, startOffsets.length);
- System.arraycopy(offsets, index + startOffsets.length, endOffsets, 0, endOffsets.length);
- return index + getOffsetCount();
- }
-}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java b/platform/platform-api/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java
deleted file mode 100644
index a3e62412f4a4..000000000000
--- a/platform/platform-api/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2000-2014 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.openapi.editor;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public class ClipboardTextPerCaretSplitter {
- @NotNull
- public List<String> split(@NotNull String input, @Nullable CaretStateTransferableData caretData, int caretCount) {
- if (caretCount <= 0) {
- throw new IllegalArgumentException("Caret count must be positive");
- }
- if (caretCount == 1) {
- return Collections.singletonList(input);
- }
- List<String> result = new ArrayList<String>(caretCount);
- int sourceCaretCount = caretData == null ? -1 : caretData.startOffsets.length;
- String[] lines = sourceCaretCount == 1 || sourceCaretCount == caretCount ? null : input.split("\n", -1);
- for (int i = 0; i < caretCount; i++) {
- if (sourceCaretCount == 1) {
- result.add(input);
- }
- else if (sourceCaretCount == caretCount) {
- //noinspection ConstantConditions
- result.add(new String(input.substring(caretData.startOffsets[i], caretData.endOffsets[i])));
- }
- else if (lines.length == 0) {
- result.add("");
- }
- else if (lines.length == 1) {
- result.add(lines[0]);
- }
- else if (lines.length % caretCount == 0) {
- StringBuilder b = new StringBuilder();
- int linesPerSegment = lines.length / caretCount;
- for (int j = 0; j < linesPerSegment; j++) {
- if (j > 0) {
- b.append('\n');
- }
- b.append(lines[i * linesPerSegment + j]);
- }
- result.add(b.toString());
- }
- else {
- result.add(i < lines.length ? lines[i] : "");
- }
- }
- return result;
- }
-}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/CopyPasteSupport.java b/platform/platform-api/src/com/intellij/openapi/editor/CopyPasteSupport.java
deleted file mode 100644
index 7095080aa13d..000000000000
--- a/platform/platform-api/src/com/intellij/openapi/editor/CopyPasteSupport.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright 2000-2014 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.openapi.editor;
-
-import com.intellij.codeInsight.editorActions.TextBlockTransferable;
-import com.intellij.codeInsight.editorActions.TextBlockTransferableData;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.ide.CopyPasteManager;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.util.text.LineTokenizer;
-import com.intellij.util.Producer;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.StringSelection;
-import java.awt.datatransfer.Transferable;
-import java.awt.datatransfer.UnsupportedFlavorException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-public class CopyPasteSupport {
- private static final Logger LOG = Logger.getInstance(CopyPasteSupport.class);
-
- private CopyPasteSupport() { }
-
- public static void copySelectionToClipboard(@NotNull Editor editor) {
- ApplicationManager.getApplication().assertIsDispatchThread();
- List<TextBlockTransferableData> extraData = new ArrayList<TextBlockTransferableData>();
- String s = editor.getCaretModel().supportsMultipleCarets() ? getSelectedTextForClipboard(editor, extraData)
- : editor.getSelectionModel().getSelectedText();
- if (s == null) return;
-
- s = TextBlockTransferable.convertLineSeparators(s, "\n", extraData);
- Transferable contents = editor.getCaretModel().supportsMultipleCarets() ? new TextBlockTransferable(s, extraData, null) : new StringSelection(s);
- CopyPasteManager.getInstance().setContents(contents);
- }
-
- public static String getSelectedTextForClipboard(@NotNull Editor editor, @NotNull Collection<TextBlockTransferableData> extraDataCollector) {
- final StringBuilder buf = new StringBuilder();
- String separator = "";
- List<Caret> carets = editor.getCaretModel().getAllCarets();
- int[] startOffsets = new int[carets.size()];
- int[] endOffsets = new int[carets.size()];
- for (int i = 0; i < carets.size(); i++) {
- buf.append(separator);
- String caretSelectedText = carets.get(i).getSelectedText();
- startOffsets[i] = buf.length();
- if (caretSelectedText != null) {
- buf.append(caretSelectedText);
- }
- endOffsets[i] = buf.length();
- separator = "\n";
- }
- extraDataCollector.add(new CaretStateTransferableData(startOffsets, endOffsets));
- return buf.toString();
- }
-
-
- public static TextRange pasteFromClipboard(Editor editor) {
- return pasteTransferable(editor, (Producer<Transferable>)null);
- }
-
- public static TextRange pasteTransferable(Editor editor, final Transferable content) {
- return pasteTransferable(editor, new Producer<Transferable>() {
- @Nullable
- @Override
- public Transferable produce() {
- return content;
- }
- });
- }
-
- @Nullable
- public static TextRange pasteTransferable(final Editor editor, @Nullable Producer<Transferable> producer) {
- Transferable content = getTransferable(producer);
- if (content == null) return null;
- String text = getStringContent(content);
- if (text == null) return null;
-
- if (editor.getCaretModel().supportsMultipleCarets()) {
- int caretCount = editor.getCaretModel().getCaretCount();
- if (caretCount == 1 && editor.isColumnMode()) {
- int pastedLineCount = LineTokenizer.calcLineCount(text, true);
- EditorModificationUtil.deleteSelectedText(editor);
- Caret caret = editor.getCaretModel().getPrimaryCaret();
- for (int i = 0; i < pastedLineCount - 1; i++) {
- caret = caret.clone(false);
- if (caret == null) {
- break;
- }
- }
- caretCount = editor.getCaretModel().getCaretCount();
- }
- CaretStateTransferableData caretData = null;
- try {
- caretData = content.isDataFlavorSupported(CaretStateTransferableData.FLAVOR)
- ? (CaretStateTransferableData)content.getTransferData(CaretStateTransferableData.FLAVOR) : null;
- }
- catch (Exception e) {
- LOG.error(e);
- }
- final Iterator<String> segments = new ClipboardTextPerCaretSplitter().split(text, caretData, caretCount).iterator();
- editor.getCaretModel().runForEachCaret(new CaretAction() {
- @Override
- public void perform(Caret caret) {
- EditorModificationUtil.insertStringAtCaret(editor, segments.next(), false, true);
- }
- });
- return null;
- }
- else {
- int caretOffset = editor.getCaretModel().getOffset();
- EditorModificationUtil.insertStringAtCaret(editor, text, false, true);
- return new TextRange(caretOffset, caretOffset + text.length());
- }
- }
-
- public static void pasteTransferableAsBlock(Editor editor, @Nullable Producer<Transferable> producer) {
- Transferable content = getTransferable(producer);
- if (content == null) return;
- String text = getStringContent(content);
- if (text == null) return;
-
- int caretLine = editor.getCaretModel().getLogicalPosition().line;
- int originalCaretLine = caretLine;
- int selectedLinesCount = 0;
-
- final SelectionModel selectionModel = editor.getSelectionModel();
- if (selectionModel.hasBlockSelection()) {
- final LogicalPosition start = selectionModel.getBlockStart();
- final LogicalPosition end = selectionModel.getBlockEnd();
- assert start != null;
- assert end != null;
- LogicalPosition caret = new LogicalPosition(Math.min(start.line, end.line), Math.min(start.column, end.column));
- selectedLinesCount = Math.abs(end.line - start.line);
- caretLine = caret.line;
-
- EditorModificationUtil.deleteSelectedText(editor);
- editor.getCaretModel().moveToLogicalPosition(caret);
- }
-
- LogicalPosition caretToRestore = editor.getCaretModel().getLogicalPosition();
-
- String[] lines = LineTokenizer.tokenize(text.toCharArray(), false);
- if (lines.length > 1 || selectedLinesCount == 0) {
- int longestLineLength = 0;
- for (int i = 0; i < lines.length; i++) {
- String line = lines[i];
- longestLineLength = Math.max(longestLineLength, line.length());
- editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
- EditorModificationUtil.insertStringAtCaret(editor, line, false, true);
- }
- caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + longestLineLength);
- }
- else {
- for (int i = 0; i <= selectedLinesCount; i++) {
- editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
- EditorModificationUtil.insertStringAtCaret(editor, text, false, true);
- }
- caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + text.length());
- }
-
- editor.getCaretModel().moveToLogicalPosition(caretToRestore);
- EditorModificationUtil.zeroWidthBlockSelectionAtCaretColumn(editor, caretLine, caretLine + selectedLinesCount);
- }
-
- @Nullable
- private static String getStringContent(@NotNull Transferable content) {
- RawText raw = RawText.fromTransferable(content);
- if (raw != null) return raw.rawText;
-
- try {
- return (String)content.getTransferData(DataFlavor.stringFlavor);
- }
- catch (UnsupportedFlavorException ignore) { }
- catch (IOException ignore) { }
-
- return null;
- }
-
- private static Transferable getTransferable(Producer<Transferable> producer) {
- Transferable content = null;
- if (producer != null) {
- content = producer.produce();
- }
- else {
- CopyPasteManager manager = CopyPasteManager.getInstance();
- if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) {
- content = manager.getContents();
- }
- }
- return content;
- }
-}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorCopyPasteHelper.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorCopyPasteHelper.java
new file mode 100644
index 000000000000..f698d34efb50
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorCopyPasteHelper.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2014 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.openapi.editor;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.datatransfer.Transferable;
+
+/**
+ * Support for data transfer between editor and clipboard.
+ */
+public abstract class EditorCopyPasteHelper {
+ public static EditorCopyPasteHelper getInstance() {
+ return ServiceManager.getService(EditorCopyPasteHelper.class);
+ }
+
+ /**
+ * Copies text selected in editor to clipboard.
+ */
+ public abstract void copySelectionToClipboard(@NotNull Editor editor);
+
+ /**
+ * Pastes from clipboard into editor at caret(s) position.
+ *
+ * @return ranges of text in the document, corresponding to pasted fragments, if paste succeeds, or <code>null</code> otherwise
+ */
+ @Nullable
+ public abstract TextRange[] pasteFromClipboard(@NotNull Editor editor);
+
+ /**
+ * Pastes given Transferable instance into editor at caret(s) position.
+ *
+ * @return ranges of text in the document, corresponding to pasted fragments, if paste succeeds, or <code>null</code> otherwise
+ */
+ @Nullable
+ public abstract TextRange[] pasteTransferable(@NotNull Editor editor, @NotNull Transferable content);
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
index ee5527967440..6ba31d7edb47 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
@@ -19,14 +19,19 @@ import com.intellij.codeStyle.CodeStyleFacade;
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.MockDocumentEvent;
+import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.LineTokenizer;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.util.Producer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
import java.util.List;
public class EditorModificationUtil {
@@ -176,22 +181,100 @@ public class EditorModificationUtil {
}
/**
- * @deprecated Use {@link com.intellij.openapi.editor.CopyPasteSupport#pasteTransferable(Editor, com.intellij.util.Producer)} instead.
+ * @deprecated Use {@link com.intellij.openapi.editor.EditorCopyPasteHelper} methods instead.
* (to remove in IDEA 15)
*/
@Nullable
public static TextRange pasteTransferable(final Editor editor, @Nullable Producer<Transferable> producer) {
- return CopyPasteSupport.pasteTransferable(editor, producer);
+ EditorCopyPasteHelper helper = EditorCopyPasteHelper.getInstance();
+ if (producer == null) {
+ TextRange[] ranges = helper.pasteFromClipboard(editor);
+ return ranges != null && ranges.length == 1 ? ranges[0] : null;
+ }
+ Transferable transferable = producer.produce();
+ if (transferable == null) {
+ return null;
+ }
+ TextRange[] ranges = helper.pasteTransferable(editor, transferable);
+ return ranges != null && ranges.length == 1 ? ranges[0] : null;
}
- /**
- * @deprecated Use {@link com.intellij.openapi.editor.CopyPasteSupport#pasteTransferableAsBlock(Editor, com.intellij.util.Producer)} instead.
- * (to remove in IDEA 15)
- */
public static void pasteTransferableAsBlock(Editor editor, @Nullable Producer<Transferable> producer) {
- CopyPasteSupport.pasteTransferableAsBlock(editor, producer);
+ Transferable content = getTransferable(producer);
+ if (content == null) return;
+ String text = getStringContent(content);
+ if (text == null) return;
+
+ int caretLine = editor.getCaretModel().getLogicalPosition().line;
+ int originalCaretLine = caretLine;
+ int selectedLinesCount = 0;
+
+ final SelectionModel selectionModel = editor.getSelectionModel();
+ if (selectionModel.hasBlockSelection()) {
+ final LogicalPosition start = selectionModel.getBlockStart();
+ final LogicalPosition end = selectionModel.getBlockEnd();
+ assert start != null;
+ assert end != null;
+ LogicalPosition caret = new LogicalPosition(Math.min(start.line, end.line), Math.min(start.column, end.column));
+ selectedLinesCount = Math.abs(end.line - start.line);
+ caretLine = caret.line;
+
+ deleteSelectedText(editor);
+ editor.getCaretModel().moveToLogicalPosition(caret);
+ }
+
+ LogicalPosition caretToRestore = editor.getCaretModel().getLogicalPosition();
+
+ String[] lines = LineTokenizer.tokenize(text.toCharArray(), false);
+ if (lines.length > 1 || selectedLinesCount == 0) {
+ int longestLineLength = 0;
+ for (int i = 0; i < lines.length; i++) {
+ String line = lines[i];
+ longestLineLength = Math.max(longestLineLength, line.length());
+ editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
+ insertStringAtCaret(editor, line, false, true);
+ }
+ caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + longestLineLength);
+ }
+ else {
+ for (int i = 0; i <= selectedLinesCount; i++) {
+ editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
+ insertStringAtCaret(editor, text, false, true);
+ }
+ caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + text.length());
+ }
+
+ editor.getCaretModel().moveToLogicalPosition(caretToRestore);
+ zeroWidthBlockSelectionAtCaretColumn(editor, caretLine, caretLine + selectedLinesCount);
}
+ @Nullable
+ private static String getStringContent(@NotNull Transferable content) {
+ RawText raw = RawText.fromTransferable(content);
+ if (raw != null) return raw.rawText;
+
+ try {
+ return (String)content.getTransferData(DataFlavor.stringFlavor);
+ }
+ catch (UnsupportedFlavorException ignore) { }
+ catch (IOException ignore) { }
+
+ return null;
+ }
+
+ private static Transferable getTransferable(Producer<Transferable> producer) {
+ Transferable content = null;
+ if (producer != null) {
+ content = producer.produce();
+ }
+ else {
+ CopyPasteManager manager = CopyPasteManager.getInstance();
+ if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) {
+ content = manager.getContents();
+ }
+ }
+ return content;
+ }
/**
* Calculates difference in columns between current editor caret position and end of the logical line fragment displayed
* on a current visual line.
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
index 3780e3a79e0c..942a33aaace8 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
@@ -15,276 +15,19 @@
*/
package com.intellij.openapi.editor;
-import com.intellij.codeStyle.CodeStyleFacade;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.SmartList;
-import com.intellij.util.containers.WeakList;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-
-public class LazyRangeMarkerFactory {
- private final Project myProject;
- private static final Key<WeakList<LazyMarker>> LAZY_MARKERS_KEY = Key.create("LAZY_MARKERS_KEY");
+public abstract class LazyRangeMarkerFactory {
public static LazyRangeMarkerFactory getInstance(Project project) {
return ServiceManager.getService(project, LazyRangeMarkerFactory.class);
}
- public LazyRangeMarkerFactory(@NotNull Project project, @NotNull final FileDocumentManager fileDocumentManager) {
- myProject = project;
-
- EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new DocumentAdapter() {
- @Override
- public void beforeDocumentChange(DocumentEvent e) {
- transformRangeMarkers(e);
- }
-
- @Override
- public void documentChanged(DocumentEvent e) {
- transformRangeMarkers(e);
- }
-
- private void transformRangeMarkers(@NotNull DocumentEvent e) {
- Document document = e.getDocument();
- VirtualFile file = fileDocumentManager.getFile(document);
- if (file == null) {
- return;
- }
-
- WeakList<LazyMarker> lazyMarkers = file.getUserData(LAZY_MARKERS_KEY);
- if (lazyMarkers == null) {
- return;
- }
-
- List<LazyMarker> markers = lazyMarkers.toStrongList();
- List<LazyMarker> markersToRemove = null;
- for (LazyMarker marker : markers) {
- if (file.equals(marker.getFile()) && marker.documentChanged(document) != null) {
- if (markersToRemove == null) {
- markersToRemove = new SmartList<LazyMarker>();
- }
- markersToRemove.add(marker);
- }
- }
- if (markersToRemove != null) {
- lazyMarkers.removeAll(markersToRemove);
- }
- }
- }, project);
- }
-
- private static void addToLazyMarkersList(@NotNull LazyMarker marker, @NotNull VirtualFile file) {
- WeakList<LazyMarker> markers = file.getUserData(LAZY_MARKERS_KEY);
-
- if (markers == null) {
- markers = file.putUserDataIfAbsent(LAZY_MARKERS_KEY, new WeakList<LazyMarker>());
- }
- markers.add(marker);
- }
-
@NotNull
- public RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int offset) {
- return ApplicationManager.getApplication().runReadAction(new Computable<RangeMarker>() {
- @Override
- public RangeMarker compute() {
- // even for already loaded document do not create range marker yet - wait until it really needed when e.g. user clicked to jump to OpenFileDescriptor
- final LazyMarker marker = new OffsetLazyMarker(file, offset);
- addToLazyMarkersList(marker, file);
- return marker;
- }
- });
- }
+ public abstract RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int offset);
@NotNull
- public RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int line, final int column, final boolean persistent) {
- return ApplicationManager.getApplication().runReadAction(new Computable<RangeMarker>() {
- @Override
- public RangeMarker compute() {
- final Document document = FileDocumentManager.getInstance().getCachedDocument(file);
- if (document != null) {
- final int offset = calculateOffset(myProject, file, document, line, column);
- return document.createRangeMarker(offset, offset, persistent);
- }
-
- final LazyMarker marker = new LineColumnLazyMarker(file, line, column);
- addToLazyMarkersList(marker, file);
- return marker;
- }
- });
- }
-
- private abstract static class LazyMarker extends UserDataHolderBase implements RangeMarker {
- private RangeMarker myDelegate;
- private final VirtualFile myFile;
- protected final int myInitialOffset;
-
- private LazyMarker(@NotNull VirtualFile file, int offset) {
- myFile = file;
- myInitialOffset = offset;
- }
-
- @NotNull
- public VirtualFile getFile() {
- return myFile;
- }
-
- @Nullable
- protected final RangeMarker getOrCreateDelegate() {
- if (myDelegate == null) {
- Document document = FileDocumentManager.getInstance().getDocument(myFile);
- if (document == null) {
- return null;
- }
- myDelegate = createDelegate(myFile, document);
- }
- return myDelegate;
- }
-
- @Nullable
- protected final RangeMarker documentChanged(@NotNull Document document) {
- if (myDelegate == null) {
- myDelegate = createDelegate(myFile, document);
- }
- return myDelegate;
- }
-
- @Nullable
- protected abstract RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull Document document);
-
- @Override
- @NotNull
- public Document getDocument() {
- RangeMarker delegate = getOrCreateDelegate();
- if (delegate == null) {
- //noinspection ConstantConditions
- return FileDocumentManager.getInstance().getDocument(myFile);
- }
- return delegate.getDocument();
- }
-
- @Override
- public int getStartOffset() {
- return myDelegate == null ? myInitialOffset : myDelegate.getStartOffset();
- }
-
-
- @Override
- public int getEndOffset() {
- return myDelegate == null ? myInitialOffset : myDelegate.getEndOffset();
- }
-
- @Override
- public boolean isValid() {
- RangeMarker delegate = getOrCreateDelegate();
- return delegate != null && delegate.isValid();
- }
-
- @Override
- public void setGreedyToLeft(boolean greedy) {
- getOrCreateDelegate().setGreedyToLeft(greedy);
- }
-
- @Override
- public void setGreedyToRight(boolean greedy) {
- getOrCreateDelegate().setGreedyToRight(greedy);
- }
-
- @Override
- public boolean isGreedyToRight() {
- return getOrCreateDelegate().isGreedyToRight();
- }
-
- @Override
- public boolean isGreedyToLeft() {
- return getOrCreateDelegate().isGreedyToLeft();
- }
-
- @Override
- public void dispose() {
- RangeMarker delegate = getOrCreateDelegate();
- if (delegate != null) {
- delegate.dispose();
- }
- }
- }
-
- private static class OffsetLazyMarker extends LazyMarker {
- private OffsetLazyMarker(@NotNull VirtualFile file, int offset) {
- super(file, offset);
- }
-
- @Override
- @NotNull
- public RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull final Document document) {
- final int offset = Math.min(myInitialOffset, document.getTextLength());
- return document.createRangeMarker(offset, offset);
- }
- }
-
- private class LineColumnLazyMarker extends LazyMarker {
- private final int myLine;
- private final int myColumn;
-
- private LineColumnLazyMarker(@NotNull VirtualFile file, int line, int column) {
- super(file, -1);
- myLine = line;
- myColumn = column;
- }
-
- @Override
- @Nullable
- public RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull Document document) {
- if (document.getTextLength() == 0 && !(myLine == 0 && myColumn == 0)) {
- return null;
- }
-
- int offset = calculateOffset(myProject, file, document, myLine, myColumn);
- return document.createRangeMarker(offset, offset);
- }
-
- @Override
- public int getStartOffset() {
- getOrCreateDelegate();
- return super.getStartOffset();
- }
-
- @Override
- public int getEndOffset() {
- getOrCreateDelegate();
- return super.getEndOffset();
- }
- }
-
- private static int calculateOffset(@NotNull Project project, @NotNull VirtualFile file, @NotNull Document document, final int line, final int column) {
- int offset;
- if (line < document.getLineCount()) {
- final int lineStart = document.getLineStartOffset(line);
- final int lineEnd = document.getLineEndOffset(line);
- final CharSequence docText = document.getCharsSequence();
- final int tabSize = CodeStyleFacade.getInstance(project).getTabSize(file.getFileType());
-
- offset = lineStart;
- int col = 0;
- while (offset < lineEnd && col < column) {
- col += docText.charAt(offset) == '\t' ? tabSize : 1;
- offset++;
- }
- }
- else {
- offset = document.getTextLength();
- }
- return offset;
- }
-
+ public abstract RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int line, final int column, final boolean persistent);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/DialogAwareDataContext.java b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/DialogAwareDataContext.java
new file mode 100644
index 000000000000..c49645254ebd
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/DialogAwareDataContext.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2014 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.openapi.editor.actionSystem;
+
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.DataKey;
+import com.intellij.openapi.editor.Editor;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.intellij.openapi.actionSystem.CommonDataKeys.*;
+import static com.intellij.openapi.actionSystem.PlatformDataKeys.PROJECT_FILE_DIRECTORY;
+
+/**
+* @author Konstantin Bulenkov
+*/
+final class DialogAwareDataContext implements DataContext {
+ private static final DataKey[] keys = {PROJECT, PROJECT_FILE_DIRECTORY, EDITOR, VIRTUAL_FILE, PSI_FILE};
+ private final Map<String, Object> values = new HashMap<String, Object>();
+
+ DialogAwareDataContext(DataContext context) {
+ for (DataKey key : keys) {
+ values.put(key.getName(), key.getData(context));
+ }
+ }
+
+ @Override
+ public Object getData(@NonNls String dataId) {
+ if (values.keySet().contains(dataId)) {
+ return values.get(dataId);
+ }
+ final Editor editor = (Editor)values.get(EDITOR.getName());
+ if (editor != null) {
+ return DataManager.getInstance().getDataContext(editor.getContentComponent()).getData(dataId);
+ }
+ return null;
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java
index 217ff70c3fb5..945c52022984 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java
@@ -26,6 +26,8 @@ import org.jetbrains.annotations.Nullable;
import java.awt.event.KeyEvent;
+import static com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT;
+
public abstract class EditorAction extends AnAction implements DumbAware {
private EditorActionHandler myHandler;
private boolean myHandlersLoaded;
@@ -126,14 +128,14 @@ public abstract class EditorAction extends AnAction implements DumbAware {
}
private static DataContext getProjectAwareDataContext(final Editor editor, @NotNull final DataContext original) {
- if (CommonDataKeys.PROJECT.getData(original) == editor.getProject()) {
- return original;
+ if (PROJECT.getData(original) == editor.getProject()) {
+ return new DialogAwareDataContext(original);
}
return new DataContext() {
@Override
public Object getData(String dataId) {
- if (CommonDataKeys.PROJECT.is(dataId)) {
+ if (PROJECT.is(dataId)) {
return editor.getProject();
}
return original.getData(dataId);
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java
index 9cd9ab29f4cd..db138237af81 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java
@@ -71,31 +71,17 @@ public class FragmentedEditorHighlighter implements EditorHighlighter {
if (range.getEndOffset() >= iterator.getStart()) {
int relativeStart = Math.max(iterator.getStart() - range.getStartOffset(), 0);
int relativeEnd = Math.min(iterator.getEnd() - range.getStartOffset(), range.getLength() + 1);
- boolean merged = false;
- if (myMergeByTextAttributes && !myPieces.isEmpty()) {
- Element element = myPieces.get(myPieces.size() - 1);
- if (element.getEnd() >= offset + relativeStart &&
- Comparing.equal(element.getAttributes(), iterator.getTextAttributes()) &&
- Comparing.equal(element.getElementType(), iterator.getTokenType())) {
- merged = true;
- myPieces.add(new Element(element.getStart(),
- offset + relativeEnd,
- iterator.getTokenType(),
- iterator.getTextAttributes()));
- }
- }
- if (!merged) {
- myPieces.add(new Element(offset + relativeStart,
- offset + relativeEnd,
- iterator.getTokenType(),
- iterator.getTextAttributes()));
- }
+
+ addElement(new Element(offset + relativeStart,
+ offset + relativeEnd,
+ iterator.getTokenType(),
+ iterator.getTextAttributes()));
}
if (range.getEndOffset() < iterator.getEnd()) {
offset += range.getLength() + 1 + myAdditionalOffset; // myAdditionalOffset because of extra line - for shoene separators
int lastEnd = myPieces.isEmpty() ? -1 : myPieces.get(myPieces.size() - 1).getEnd();
- myPieces.add(new Element(Math.max(offset - 1 - myAdditionalOffset, lastEnd), offset, null, TextAttributes.ERASE_MARKER));
+ addElement(new Element(Math.max(offset - 1 - myAdditionalOffset, lastEnd), offset, null, TextAttributes.ERASE_MARKER));
index++;
continue;
}
@@ -104,6 +90,26 @@ public class FragmentedEditorHighlighter implements EditorHighlighter {
}
}
+ private void addElement(@NotNull Element element) {
+ boolean merged = false;
+ if (myMergeByTextAttributes && !myPieces.isEmpty()) {
+ Element oldElement = myPieces.get(myPieces.size() - 1);
+ if (oldElement.getEnd() >= element.getStart() &&
+ Comparing.equal(oldElement.getAttributes(), element.getAttributes()) &&
+ Comparing.equal(oldElement.getElementType(), element.getElementType())) {
+ merged = true;
+ myPieces.remove(myPieces.size() - 1);
+ myPieces.add(new Element(oldElement.getStart(),
+ element.getEnd(),
+ element.getElementType(),
+ element.getAttributes()));
+ }
+ }
+ if (!merged) {
+ myPieces.add(element);
+ }
+ }
+
@NotNull
@Override
public HighlighterIterator createIterator(int startOffset) {
diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java
index 1e43287a1d94..c958dbca878e 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java
@@ -19,9 +19,11 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.UIBundle;
+import org.jetbrains.annotations.NotNull;
public class FileChooserDescriptorFactory {
- private FileChooserDescriptorFactory() { }
+ private FileChooserDescriptorFactory() {
+ }
public static FileChooserDescriptor createAllButJarContentsDescriptor() {
return new FileChooserDescriptor(true, true, true, true, false, true);
@@ -83,7 +85,18 @@ public class FileChooserDescriptorFactory {
}
public static FileChooserDescriptor createSingleFileDescriptor(final FileType fileType) {
- return new FileChooserDescriptor(true, false, false, false, false, false) {
+ return createSingleFileDescriptor(fileType, false);
+ }
+
+ /**
+ * Creates file descriptor with certain type and (possible) folders.
+ * @param fileType supported type
+ * @param supportDirectories support directories or not
+ * @return descriptor
+ */
+ @NotNull
+ public static FileChooserDescriptor createSingleFileDescriptor(final FileType fileType, final boolean supportDirectories) {
+ return new FileChooserDescriptor(true, supportDirectories, false, false, false, false) {
@Override
public boolean isFileVisible(final VirtualFile file, final boolean showHiddenFiles) {
return file.isDirectory() || file.getFileType() == fileType;
@@ -91,18 +104,22 @@ public class FileChooserDescriptorFactory {
@Override
public boolean isFileSelectable(final VirtualFile file) {
- return super.isFileSelectable(file) && file.getFileType() == fileType;
+ return super.isFileSelectable(file) && (file.getFileType() == fileType || ((file.isDirectory() && supportDirectories)));
}
};
}
- /** @deprecated use {@link #createSingleFileNoJarsDescriptor()} (to be removed in IDEA 15) */
+ /**
+ * @deprecated use {@link #createSingleFileNoJarsDescriptor()} (to be removed in IDEA 15)
+ */
@SuppressWarnings({"UnusedDeclaration", "deprecation"})
public static FileChooserDescriptorBuilder onlyFiles() {
return FileChooserDescriptorBuilder.onlyFiles();
}
- /** @deprecated use {@link #createSingleFileOrFolderDescriptor()} ()} (to be removed in IDEA 15) */
+ /**
+ * @deprecated use {@link #createSingleFileOrFolderDescriptor()} ()} (to be removed in IDEA 15)
+ */
@SuppressWarnings({"UnusedDeclaration", "deprecation"})
public static FileChooserDescriptorBuilder filesAndFolders() {
return FileChooserDescriptorBuilder.filesAndFolders();
diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java
index 366f69db9cc6..b9589574059d 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java
@@ -30,7 +30,7 @@ public abstract class FileEditorManager {
public static final Key<Boolean> USE_CURRENT_WINDOW = Key.create("OpenFile.searchForOpen");
- public static FileEditorManager getInstance(Project project) {
+ public static FileEditorManager getInstance(@NotNull Project project) {
return project.getComponent(FileEditorManager.class);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
index 9ec804def43d..fdf32b9adcba 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
@@ -55,34 +55,31 @@ public class OpenFileDescriptor implements Navigatable {
private boolean myUseCurrentWindow = false;
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int offset) {
- this(project, file, -1, -1, offset, null, false);
+ this(project, file, -1, -1, offset, false);
}
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int logicalLine, int logicalColumn) {
- this(project, file, logicalLine, logicalColumn, -1, null, false);
+ this(project, file, logicalLine, logicalColumn, -1, false);
}
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file,
int logicalLine, int logicalColumn, boolean persistent) {
- this(project, file, logicalLine, logicalColumn, -1, null, persistent);
+ this(project, file, logicalLine, logicalColumn, -1, persistent);
}
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file) {
- this(project, file, -1, -1, -1, null, false);
+ this(project, file, -1, -1, -1, false);
}
private OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file,
- int logicalLine, int logicalColumn, int offset, @Nullable RangeMarker rangeMarker, boolean persistent) {
+ int logicalLine, int logicalColumn, int offset, boolean persistent) {
myProject = project;
myFile = file;
myLogicalLine = logicalLine;
myLogicalColumn = logicalColumn;
myOffset = offset;
- if (rangeMarker != null) {
- myRangeMarker = rangeMarker;
- }
- else if (offset >= 0) {
+ if (offset >= 0) {
myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, offset);
}
else if (logicalLine >= 0 ){
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/Banner.java b/platform/platform-api/src/com/intellij/openapi/ui/Banner.java
index 3f4a92aec5ff..8dbe02228bae 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/Banner.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/Banner.java
@@ -16,6 +16,8 @@
package com.intellij.openapi.ui;
import com.intellij.icons.AllIcons;
+import com.intellij.openapi.options.OptionsBundle;
+import com.intellij.openapi.project.Project;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.ui.components.panels.NonOpaquePanel;
@@ -35,7 +37,7 @@ import java.util.Set;
class Banner extends NonOpaquePanel implements PropertyChangeListener{
private int myBannerMinHeight;
private final JComponent myText = new MyText();
-
+ private final JLabel myProjectIcon = new JLabel(AllIcons.General.ProjectConfigurableBanner, SwingConstants.LEFT);
private final NonOpaquePanel myActionsPanel = new NonOpaquePanel(new FlowLayout(FlowLayout.RIGHT, 2, 2));
private final Map<Action, LinkLabel> myActions = new HashMap<Action, LinkLabel>();
@@ -45,7 +47,10 @@ class Banner extends NonOpaquePanel implements PropertyChangeListener{
setBorder(new EmptyBorder(2, 6, 2, 4));
- add(myText, BorderLayout.CENTER);
+ myProjectIcon.setVisible(false);
+ myProjectIcon.setBorder(new EmptyBorder(0, 12, 0, 4));
+ add(myText, BorderLayout.WEST);
+ add(myProjectIcon, BorderLayout.CENTER);
add(myActionsPanel, BorderLayout.EAST);
}
@@ -112,6 +117,17 @@ class Banner extends NonOpaquePanel implements PropertyChangeListener{
repaint();
}
+ public void forProject(Project project) {
+ if (project != null) {
+ myProjectIcon.setVisible(true);
+ myProjectIcon.setText(OptionsBundle.message(project.isDefault()
+ ? "configurable.default.project.tooltip"
+ : "configurable.current.project.tooltip"));
+ } else {
+ myProjectIcon.setVisible(false);
+ }
+ }
+
public void setText(@NotNull final String... text) {
myText.removeAll();
for (int i = 0; i < text.length; i++) {
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java b/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java
index 5d2ecafb1b7e..c02f27af5d4b 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java
@@ -46,6 +46,7 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
private WeakReference<ListPopup> myPopupRef;
private ChangeEvent myChangeEvent = null;
private T myValue;
+ private boolean myPaintArrow = true;
protected EventListenerList myListenerList = new EventListenerList();
@@ -80,6 +81,10 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
return null;
}
+ public void setPaintArrow(final boolean paintArrow) {
+ myPaintArrow = paintArrow;
+ }
+
protected Runnable onChosen(@NotNull final T value) {
stopCellEditing(value);
@@ -94,7 +99,7 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
protected void paintComponent(Graphics g) {
super.paintComponent(g);
- if (!StringUtil.isEmpty(getText())) {
+ if (!StringUtil.isEmpty(getText()) && myPaintArrow) {
final Rectangle r = getBounds();
final Insets i = getInsets();
final int x = r.width - i.right - AllIcons.General.ArrowDown.getIconWidth();
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
index 34aaa93d2741..463d950ae900 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
@@ -16,7 +16,7 @@
package com.intellij.openapi.ui;
-import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.project.Project;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.util.ArrayUtil;
@@ -45,15 +45,21 @@ public class DetailsComponent {
private final NonOpaquePanel myBanner;
private String[] myBannerText;
- private boolean myDetailsEnabled = !Registry.is("ide.new.project.settings");
+ private boolean myDetailsEnabled;
private String[] myPrefix;
private String[] myText;
private final Wrapper myContentGutter = new Wrapper();
- private boolean myPaintBorder = !Registry.is("ide.new.project.settings");
+ private boolean myPaintBorder;
public DetailsComponent() {
+ this(true, true);
+ }
+
+ public DetailsComponent(boolean detailsEnabled, boolean paintBorder) {
+ myDetailsEnabled = detailsEnabled;
+ myPaintBorder = paintBorder;
myComponent = new JPanel(new BorderLayout()) {
@Override
protected void paintComponent(final Graphics g) {
@@ -110,7 +116,7 @@ public class DetailsComponent {
myBanner = new NonOpaquePanel(new BorderLayout());
myBannerLabel = new Banner();
- if (!Registry.is("ide.new.project.settings")) {
+ if (myDetailsEnabled) {
myBanner.add(myBannerLabel, BorderLayout.CENTER);
}
@@ -174,6 +180,9 @@ public class DetailsComponent {
}
}
+ public void forProject(Project project) {
+ myBannerLabel.forProject(project);
+ }
public void setPrefix(@Nullable String... prefix) {
myPrefix = prefix;
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/FixedComboBoxEditor.java b/platform/platform-api/src/com/intellij/openapi/ui/FixedComboBoxEditor.java
index 25c52c75b077..6ef25dddb5bc 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/FixedComboBoxEditor.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/FixedComboBoxEditor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,6 +17,7 @@ package com.intellij.openapi.ui;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.Gray;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.ui.MacUIUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
@@ -34,7 +35,6 @@ import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
@@ -118,17 +118,7 @@ public class FixedComboBoxEditor implements ComboBoxEditor {
final ComboBoxUI ui = comboBox.getUI();
ComboPopup popup = null;
if (ui instanceof BasicComboBoxUI) {
- try {
- final Field popupField = BasicComboBoxUI.class.getDeclaredField("popup");
- popupField.setAccessible(true);
- popup = (ComboPopup)popupField.get(ui);
- }
- catch (NoSuchFieldException e1) {
- popup = null;
- }
- catch (IllegalAccessException e1) {
- popup = null;
- }
+ popup = ReflectionUtil.getField(BasicComboBoxUI.class, ui, ComboPopup.class, "popup");
}
return popup;
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
index 816349ed1c37..6c13964d5789 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
@@ -111,7 +111,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
protected MyNode myRoot = new MyRootNode();
protected Tree myTree = new Tree();
- private final DetailsComponent myDetails = new DetailsComponent();
+ private final DetailsComponent myDetails = new DetailsComponent(!Registry.is("ide.new.project.settings"), !Registry.is("ide.new.project.settings"));
protected JPanel myWholePanel;
public JPanel myNorthPanel = new JPanel(new BorderLayout());
@@ -131,12 +131,9 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
protected MasterDetailsComponent(MasterDetailsState state) {
myState = state;
- mySplitter = new JBSplitter(false, .2f);
+ mySplitter = Registry.is("ide.new.project.settings") ? new OnePixelSplitter(false, .2f) : new JBSplitter(false, .2f);
mySplitter.setSplitterProportionKey("ProjectStructure.SecondLevelElements");
mySplitter.setHonorComponentsMinimumSize(true);
- if (Registry.is("ide.new.project.settings")) {
- mySplitter.setOnePixelMode();
- }
installAutoScroll();
reInitWholePanelIfNeeded();
@@ -300,6 +297,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
@NotNull
public JComponent createComponent() {
+ myTree.updateUI();
reInitWholePanelIfNeeded();
updateSelectionFromTree();
@@ -962,7 +960,11 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
myPreselection != null ? myPreselection.getDefaultIndex() : 0, true);
final ListPopup listPopup = popupFactory.createListPopup(step);
listPopup.setHandleAutoSelectionBeforeShow(true);
- listPopup.showUnderneathOf(myNorthPanel);
+ if (e instanceof AnActionButton.AnActionEventWrapper) {
+ ((AnActionButton.AnActionEventWrapper)e).showPopup(listPopup);
+ } else {
+ listPopup.showUnderneathOf(myNorthPanel);
+ }
}
}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/NamedConfigurable.java b/platform/platform-api/src/com/intellij/openapi/ui/NamedConfigurable.java
index 12b84f8db465..e619473197e7 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/NamedConfigurable.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/NamedConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -18,10 +18,12 @@ package com.intellij.openapi.ui;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.DocumentAdapter;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import java.awt.*;
@@ -55,6 +57,11 @@ public abstract class NamedConfigurable<T> implements Configurable {
}
});
}
+ if (Registry.is("ide.new.project.settings")) {
+ myNamePanel.setBorder(new EmptyBorder(10, 10, 6, 10));
+ } else {
+ myNamePanel.setBorder(new EmptyBorder(0,0,0,0));
+ }
}
public boolean isNameEditable() {
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java b/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java
new file mode 100644
index 000000000000..2b0097005dc1
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2000-2014 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.openapi.ui;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.Weighted;
+import com.intellij.openapi.wm.IdeGlassPane;
+import com.intellij.openapi.wm.IdeGlassPaneUtil;
+import com.intellij.ui.Gray;
+import com.intellij.ui.JBColor;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class OnePixelDivider extends Divider {
+ private boolean myVertical;
+ private Splitter mySplitter;
+ private boolean myResizeEnabled;
+ private boolean mySwitchOrientationEnabled;
+ protected Point myPoint;
+ private IdeGlassPane myGlassPane;
+ private final MouseAdapter myListener = new MyMouseAdapter();
+ private Disposable myDisposable;
+
+ public OnePixelDivider(boolean vertical, Splitter splitter) {
+ super(new GridBagLayout());
+ mySplitter = splitter;
+ myResizeEnabled = true;
+ mySwitchOrientationEnabled = false;
+ setFocusable(false);
+ enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
+ //setOpaque(false);
+ setOrientation(vertical);
+ setBackground(new JBColor(Gray._153.withAlpha(128), Gray._100.withAlpha(128)));
+ }
+
+ @Override
+ public void addNotify() {
+ super.addNotify();
+ init();
+ }
+
+ @Override
+ public void removeNotify() {
+ super.removeNotify();
+ if (myDisposable != null && !Disposer.isDisposed(myDisposable)) {
+ Disposer.dispose(myDisposable);
+ }
+ }
+
+ private boolean dragging = false;
+ private class MyMouseAdapter extends MouseAdapter implements Weighted {
+ @Override
+ public void mousePressed(MouseEvent e) {
+ dragging = isInDragZone(e);
+ _processMouseEvent(e);
+ }
+
+ boolean isInDragZone(MouseEvent e) {
+ final MouseEvent event = getTargetEvent(e);
+ final Point p = event.getPoint();
+ final int r = Math.abs(isVertical() ? p.y : p.x);
+ return r < 6;
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ _processMouseEvent(e);
+ dragging = false;
+ }
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ final OnePixelDivider divider = OnePixelDivider.this;
+ if (isInDragZone(e)) {
+ myGlassPane.setCursor(divider.getCursor(), divider);
+ } else {
+ myGlassPane.setCursor(null, divider);
+ }
+ _processMouseMotionEvent(e);
+ }
+
+ @Override
+ public void mouseDragged(MouseEvent e) {
+ _processMouseMotionEvent(e);
+ }
+ @Override
+ public double getWeight() {
+ return 1;
+ }
+ private void _processMouseMotionEvent(MouseEvent e) {
+ MouseEvent event = getTargetEvent(e);
+ if (event == null) {
+ myGlassPane.setCursor(null, myListener);
+ return;
+ }
+
+ processMouseMotionEvent(event);
+ if (event.isConsumed()) {
+ e.consume();
+ }
+ }
+
+ private void _processMouseEvent(MouseEvent e) {
+ MouseEvent event = getTargetEvent(e);
+ if (event == null) {
+ myGlassPane.setCursor(null, myListener);
+ return;
+ }
+
+ processMouseEvent(event);
+ if (event.isConsumed()) {
+ e.consume();
+ }
+ }
+ }
+
+ private MouseEvent getTargetEvent(MouseEvent e) {
+ return SwingUtilities.convertMouseEvent(e.getComponent(), e, this);
+ }
+
+ private void init() {
+ myGlassPane = IdeGlassPaneUtil.find(this);
+ myDisposable = Disposer.newDisposable();
+ myGlassPane.addMouseMotionPreprocessor(myListener, myDisposable);
+ myGlassPane.addMousePreprocessor(myListener, myDisposable);
+ }
+
+ public void setOrientation(boolean vertical) {
+ removeAll();
+ myVertical = vertical;
+ final int cursorType = isVertical() ? Cursor.N_RESIZE_CURSOR : Cursor.W_RESIZE_CURSOR;
+ setCursor(Cursor.getPredefinedCursor(cursorType));
+ }
+
+ @Override
+ protected void processMouseMotionEvent(MouseEvent e) {
+ super.processMouseMotionEvent(e);
+ if (!myResizeEnabled) return;
+ if (MouseEvent.MOUSE_DRAGGED == e.getID() && dragging) {
+ myPoint = SwingUtilities.convertPoint(this, e.getPoint(), mySplitter);
+ float proportion;
+ final float firstMinProportion = getMinProportion(mySplitter.getFirstComponent());
+ final float secondMinProportion = getMinProportion(mySplitter.getSecondComponent());
+ if (isVertical()) {
+ if (getHeight() > 0) {
+ proportion = Math.min(1.0f, Math
+ .max(.0f, Math.min(Math.max(firstMinProportion, (float)myPoint.y / (float)mySplitter.getHeight()), 1 - secondMinProportion)));
+ mySplitter.setProportion(proportion);
+ }
+ }
+ else {
+ if (getWidth() > 0) {
+ proportion = Math.min(1.0f, Math.max(.0f, Math.min(
+ Math.max(firstMinProportion, (float)myPoint.x / (float)mySplitter.getWidth()), 1 - secondMinProportion)));
+ mySplitter.setProportion(proportion);
+ }
+ }
+ }
+ }
+
+ private float getMinProportion(JComponent component) {
+ if (component != null &&
+ mySplitter.getFirstComponent() != null &&
+ mySplitter.getFirstComponent().isVisible() &&
+ mySplitter.getSecondComponent() != null &&
+ mySplitter.getSecondComponent().isVisible()) {
+ if (isVertical()) {
+ return (float)component.getMinimumSize().height / (float)(mySplitter.getHeight() - 1);
+ } else {
+ return (float)component.getMinimumSize().width / (float)(mySplitter.getWidth() - 1);
+ }
+ }
+
+ return 0.0f;
+ }
+
+ @Override
+ protected void processMouseEvent(MouseEvent e) {
+ super.processMouseEvent(e);
+ if (e.getID() == MouseEvent.MOUSE_CLICKED) {
+ if (mySwitchOrientationEnabled
+ && e.getClickCount() == 1
+ && SwingUtilities.isLeftMouseButton(e) && (SystemInfo.isMac ? e.isMetaDown() : e.isControlDown())) {
+ mySplitter.setOrientation(!mySplitter.getOrientation());
+ }
+ if (myResizeEnabled && e.getClickCount() == 2) {
+ mySplitter.setProportion(.5f);
+ }
+ }
+ }
+
+ public void setResizeEnabled(boolean resizeEnabled) {
+ myResizeEnabled = resizeEnabled;
+ if (!myResizeEnabled) {
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ else {
+ setCursor(isVertical() ?
+ Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR) :
+ Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
+ }
+ }
+
+ public void setSwitchOrientationEnabled(boolean switchOrientationEnabled) {
+ mySwitchOrientationEnabled = switchOrientationEnabled;
+ }
+
+
+ public boolean isVertical() {
+ return myVertical;
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java b/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java
index fc9eec268ece..6c40a04f5831 100644
--- a/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java
+++ b/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java
@@ -43,7 +43,7 @@ public abstract class FocusCommand extends ActiveRunnable implements Expirable {
private boolean myInvalidatesPendingFurtherRequestors = true;
private Expirable myExpirable;
- public static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.FocusCommand");
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.FocusCommand");
public boolean isForced() {
return myForced;
diff --git a/platform/platform-api/src/com/intellij/ui/AnActionButton.java b/platform/platform-api/src/com/intellij/ui/AnActionButton.java
index 7c539b1bb2a4..d1c19df6e3ad 100644
--- a/platform/platform-api/src/com/intellij/ui/AnActionButton.java
+++ b/platform/platform-api/src/com/intellij/ui/AnActionButton.java
@@ -17,6 +17,7 @@ package com.intellij.ui;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.containers.SmartHashSet;
import com.intellij.util.ui.UIUtil;
@@ -187,7 +188,7 @@ public abstract class AnActionButton extends AnAction implements ShortcutProvide
@Override
public void actionPerformed(AnActionEvent e) {
- myAction.actionPerformed(e);
+ myAction.actionPerformed(new AnActionEventWrapper(e, this));
}
@Override
@@ -205,4 +206,20 @@ public abstract class AnActionButton extends AnAction implements ShortcutProvide
return myAction.isDumbAware();
}
}
+
+ public static class AnActionEventWrapper extends AnActionEvent {
+ private final AnActionButton myPeer;
+
+ private AnActionEventWrapper(AnActionEvent e, AnActionButton peer) {
+ super(e.getInputEvent(), e.getDataContext(), e.getPlace(), e.getPresentation(), e.getActionManager(), e.getModifiers());
+ myPeer = peer;
+ }
+
+ public void showPopup(JBPopup popup) {
+ popup.show(myPeer.getPreferredPopupPoint());
+ }
+
+
+
+ }
}
diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeAdapter.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeAdapter.java
new file mode 100644
index 000000000000..186904a4a843
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeAdapter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class CheckboxTreeAdapter implements CheckboxTreeListener {
+ @Override
+ public void mouseDoubleClicked(@NotNull CheckedTreeNode node) {
+ }
+
+ @Override
+ public void nodeStateChanged(@NotNull CheckedTreeNode node) {
+ }
+
+ @Override
+ public void beforeNodeStateChanged(@NotNull CheckedTreeNode node) {
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
index d9755f342a3f..88f433f7c62a 100644
--- a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
+++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
@@ -16,67 +16,49 @@
package com.intellij.ui;
import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.EventDispatcher;
import com.intellij.util.ui.UIUtil;
-import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.tree.*;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeCellRenderer;
+import javax.swing.tree.TreeNode;
import java.awt.*;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Enumeration;
public class CheckboxTreeBase extends Tree {
- private final CheckPolicy myCheckPolicy;
- private static final CheckPolicy DEFAULT_POLICY = new CheckPolicy(true, true, false, true);
+ private final CheckboxTreeHelper myHelper;
+ private final EventDispatcher<CheckboxTreeListener> myEventDispatcher;
public CheckboxTreeBase() {
this(new CheckboxTreeCellRendererBase(), null);
}
public CheckboxTreeBase(final CheckboxTreeCellRendererBase cellRenderer, CheckedTreeNode root) {
- this(cellRenderer, root, DEFAULT_POLICY);
+ this(cellRenderer, root, CheckboxTreeHelper.DEFAULT_POLICY);
}
public CheckboxTreeBase(CheckboxTreeCellRendererBase cellRenderer, @Nullable CheckedTreeNode root, CheckPolicy checkPolicy) {
- myCheckPolicy = checkPolicy;
-
- setRootVisible(false);
- setShowsRootHandles(true);
- setLineStyleAngled();
- TreeUtil.installActions(this);
-
- installRenderer(cellRenderer);
-
- addKeyListener(new KeyAdapter() {
- public void keyPressed(KeyEvent e) {
- if (isToggleEvent(e)) {
- TreePath treePath = getLeadSelectionPath();
- if (treePath == null) return;
- final Object o = treePath.getLastPathComponent();
- if (!(o instanceof CheckedTreeNode)) return;
- CheckedTreeNode firstNode = (CheckedTreeNode)o;
- boolean checked = toggleNode(firstNode);
-
- TreePath[] selectionPaths = getSelectionPaths();
- for (int i = 0; selectionPaths != null && i < selectionPaths.length; i++) {
- final TreePath selectionPath = selectionPaths[i];
- final Object o1 = selectionPath.getLastPathComponent();
- if (!(o1 instanceof CheckedTreeNode)) continue;
- CheckedTreeNode node = (CheckedTreeNode)o1;
- checkNode(node, checked);
- ((DefaultTreeModel)getModel()).nodeChanged(node);
- }
-
- e.consume();
- }
+ myEventDispatcher = EventDispatcher.create(CheckboxTreeListener.class);
+ myEventDispatcher.addListener(new CheckboxTreeListener() {
+ @Override
+ public void mouseDoubleClicked(@NotNull CheckedTreeNode node) {
+ onDoubleClick(node);
+ }
+
+ @Override
+ public void nodeStateChanged(@NotNull CheckedTreeNode node) {
+ CheckboxTreeBase.this.onNodeStateChanged(node);
+ }
+
+ @Override
+ public void beforeNodeStateChanged(@NotNull CheckedTreeNode node) {
+ CheckboxTreeBase.this.nodeStateWillChange(node);
}
});
+ myHelper = new CheckboxTreeHelper(checkPolicy, myEventDispatcher);
+ myHelper.initTree(this, this, cellRenderer);
setSelectionRow(0);
if (root != null) {
@@ -84,55 +66,37 @@ public class CheckboxTreeBase extends Tree {
}
}
+ @Deprecated
public void installRenderer(final CheckboxTreeCellRendererBase cellRenderer) {
setCellRenderer(cellRenderer);
- new ClickListener() {
- @Override
- public boolean onClick(@NotNull MouseEvent e, int clickCount) {
- int row = getRowForLocation(e.getX(), e.getY());
- if (row < 0) return false;
- final Object o = getPathForRow(row).getLastPathComponent();
- if (!(o instanceof CheckedTreeNode)) return false;
- Rectangle rowBounds = getRowBounds(row);
- cellRenderer.setBounds(rowBounds);
- Rectangle checkBounds = cellRenderer.myCheckbox.getBounds();
- checkBounds.setLocation(rowBounds.getLocation());
-
- if (checkBounds.height == 0) checkBounds.height = checkBounds.width = rowBounds.height;
-
- final CheckedTreeNode node = (CheckedTreeNode)o;
- if (checkBounds.contains(e.getPoint())) {
- if (node.isEnabled()) {
- toggleNode(node);
- setSelectionRow(row);
- return true;
- }
- }
- else if (clickCount > 1) {
- onDoubleClick(node);
- return true;
- }
- return false;
- }
- }.installOn(this);
}
- protected void onDoubleClick(final CheckedTreeNode node) {
+ /**
+ * @deprecated use {@link #setNodeState} to change node state or subscribe to {@link #addCheckboxTreeListener} to get notifications about state changes
+ */
+ @Deprecated
+ protected boolean toggleNode(CheckedTreeNode node) {
+ setNodeState(node, !node.isChecked());
+ return node.isChecked();
}
- protected boolean isToggleEvent(KeyEvent e) {
- return e.getKeyCode() == KeyEvent.VK_SPACE;
+ /**
+ * @deprecated use {@link #setNodeState} to change node state or subscribe to {@link #addCheckboxTreeListener} to get notifications about state changes
+ */
+ @Deprecated
+ protected void checkNode(CheckedTreeNode node, boolean checked) {
+ setNodeState(node, checked);
}
- protected boolean toggleNode(CheckedTreeNode node) {
- boolean checked = !node.isChecked();
- checkNode(node, checked);
+ public void setNodeState(@NotNull CheckedTreeNode node, boolean checked) {
+ myHelper.setNodeState(this, node, checked);
+ }
- // notify model listeners about model change
- final TreeModel model = getModel();
- model.valueForPathChanged(new TreePath(node.getPath()), node.getUserObject());
+ public void addCheckboxTreeListener(@NotNull CheckboxTreeListener listener) {
+ myEventDispatcher.addListener(listener);
+ }
- return checked;
+ protected void onDoubleClick(final CheckedTreeNode node) {
}
/**
@@ -144,38 +108,8 @@ public class CheckboxTreeBase extends Tree {
* @param <T> the type of the node
* @return an array of collected nodes
*/
- @SuppressWarnings("unchecked")
public <T> T[] getCheckedNodes(final Class<T> nodeType, @Nullable final NodeFilter<T> filter) {
- final ArrayList<T> nodes = new ArrayList<T>();
- final Object root = getModel().getRoot();
- if (!(root instanceof CheckedTreeNode)) {
- throw new IllegalStateException(
- "The root must be instance of the " + CheckedTreeNode.class.getName() + ": " + root.getClass().getName());
- }
- new Object() {
- @SuppressWarnings("unchecked")
- public void collect(CheckedTreeNode node) {
- if (node.isLeaf()) {
- Object userObject = node.getUserObject();
- if (node.isChecked() && userObject != null && nodeType.isAssignableFrom(userObject.getClass())) {
- final T value = (T)userObject;
- if (filter != null && !filter.accept(value)) return;
- nodes.add(value);
- }
- }
- else {
- for (int i = 0; i < node.getChildCount(); i++) {
- final TreeNode child = node.getChildAt(i);
- if (child instanceof CheckedTreeNode) {
- collect((CheckedTreeNode)child);
- }
- }
- }
- }
- }.collect((CheckedTreeNode)root);
- T[] result = (T[])Array.newInstance(nodeType, nodes.size());
- nodes.toArray(result);
- return result;
+ return CheckboxTreeHelper.getCheckedNodes(nodeType, filter, getModel());
}
@@ -184,118 +118,14 @@ public class CheckboxTreeBase extends Tree {
return -1;
}
- protected void checkNode(CheckedTreeNode node, boolean checked) {
- adjustParentsAndChildren(node, checked);
- repaint();
- }
-
protected void onNodeStateChanged(CheckedTreeNode node) {
-
}
protected void nodeStateWillChange(CheckedTreeNode node) {
-
- }
-
- protected void adjustParentsAndChildren(final CheckedTreeNode node, final boolean checked) {
- changeNodeState(node, checked);
- if (!checked) {
- if (myCheckPolicy.uncheckParentWithUncheckedChild) {
- TreeNode parent = node.getParent();
- while (parent != null) {
- if (parent instanceof CheckedTreeNode) {
- changeNodeState((CheckedTreeNode)parent, false);
- }
- parent = parent.getParent();
- }
- }
- if (myCheckPolicy.uncheckChildrenWithUncheckedParent) {
- uncheckChildren(node);
- }
-
- }
- else {
- if (myCheckPolicy.checkChildrenWithCheckedParent) {
- checkChildren(node);
- }
-
- if (myCheckPolicy.checkParentWithCheckedChild) {
- TreeNode parent = node.getParent();
- while (parent != null) {
- if (parent instanceof CheckedTreeNode) {
- changeNodeState((CheckedTreeNode)parent, true);
- }
- parent = parent.getParent();
- }
- }
-
- }
- repaint();
- }
-
- private void changeNodeState(final CheckedTreeNode node, final boolean checked) {
- if (node.isChecked() != checked) {
- nodeStateWillChange(node);
- node.setChecked(checked);
- onNodeStateChanged(node);
- }
- }
-
- private void uncheckChildren(final CheckedTreeNode node) {
- final Enumeration children = node.children();
- while (children.hasMoreElements()) {
- final Object o = children.nextElement();
- if (!(o instanceof CheckedTreeNode)) continue;
- CheckedTreeNode child = (CheckedTreeNode)o;
- changeNodeState(child, false);
- uncheckChildren(child);
- }
- }
-
- private void checkChildren(final CheckedTreeNode node) {
- final Enumeration children = node.children();
- while (children.hasMoreElements()) {
- final Object o = children.nextElement();
- if (!(o instanceof CheckedTreeNode)) continue;
- CheckedTreeNode child = (CheckedTreeNode)o;
- changeNodeState(child, true);
- checkChildren(child);
- }
}
+ @Deprecated
protected void adjustParents(final CheckedTreeNode node, final boolean checked) {
- TreeNode parentNode = node.getParent();
- if (!(parentNode instanceof CheckedTreeNode)) return;
- CheckedTreeNode parent = (CheckedTreeNode)parentNode;
-
- if (!checked && isAllChildrenUnchecked(parent)) {
- changeNodeState(parent, false);
- adjustParents(parent, false);
- }
- else if (checked && isAllChildrenChecked(parent)) {
- changeNodeState(parent, true);
- adjustParents(parent, true);
- }
- }
-
- private static boolean isAllChildrenUnchecked(final CheckedTreeNode node) {
- for (int i = 0; i < node.getChildCount(); i++) {
- final TreeNode o = node.getChildAt(i);
- if ((o instanceof CheckedTreeNode) && ((CheckedTreeNode)o).isChecked()) {
- return false;
- }
- }
- return true;
- }
-
- private static boolean isAllChildrenChecked(final CheckedTreeNode node) {
- for (int i = 0; i < node.getChildCount(); i++) {
- final TreeNode o = node.getChildAt(i);
- if ((o instanceof CheckedTreeNode) && !((CheckedTreeNode)o).isChecked()) {
- return false;
- }
- }
- return true;
}
public static class CheckboxTreeCellRendererBase extends JPanel implements TreeCellRenderer {
@@ -395,8 +225,8 @@ public class CheckboxTreeBase extends Tree {
}
/**
- * @deprecated
* @see CheckboxTreeCellRendererBase#customizeRenderer(javax.swing.JTree, Object, boolean, boolean, boolean, int, boolean)
+ * @deprecated
*/
@Deprecated
public void customizeCellRenderer(JTree tree,
diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeHelper.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeHelper.java
new file mode 100644
index 000000000000..3048d131caa7
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeHelper.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import com.intellij.ui.speedSearch.SpeedSearchSupply;
+import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.EventDispatcher;
+import com.intellij.util.ui.tree.TreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+import java.awt.*;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+/**
+ * @author nik
+ */
+class CheckboxTreeHelper {
+ static final CheckboxTreeBase.CheckPolicy DEFAULT_POLICY = new CheckboxTreeBase.CheckPolicy(true, true, false, true);
+ private final CheckboxTreeBase.CheckPolicy myCheckPolicy;
+ private final EventDispatcher<CheckboxTreeListener> myEventDispatcher;
+
+ CheckboxTreeHelper(CheckboxTreeBase.CheckPolicy checkPolicy, EventDispatcher<CheckboxTreeListener> dispatcher) {
+ myCheckPolicy = checkPolicy;
+ myEventDispatcher = dispatcher;
+ }
+
+ public void initTree(@NotNull final Tree tree, JComponent mainComponent, CheckboxTreeBase.CheckboxTreeCellRendererBase cellRenderer) {
+ tree.setCellRenderer(cellRenderer);
+ tree.setRootVisible(false);
+ tree.setShowsRootHandles(true);
+ tree.setLineStyleAngled();
+ TreeUtil.installActions(tree);
+
+ setupKeyListener(tree, mainComponent);
+ setupMouseListener(tree, mainComponent, cellRenderer);
+ }
+
+ public void setNodeState(Tree tree, CheckedTreeNode node, boolean checked) {
+ changeNodeState(node, checked);
+ adjustParentsAndChildren(node, checked);
+ tree.repaint();
+
+ // notify model listeners about model change
+ final TreeModel model = tree.getModel();
+ model.valueForPathChanged(new TreePath(node.getPath()), node.getUserObject());
+ }
+
+ private void toggleNode(Tree tree, CheckedTreeNode node) {
+ setNodeState(tree, node, !node.isChecked());
+ }
+
+ private void adjustParentsAndChildren(final CheckedTreeNode node, final boolean checked) {
+ if (!checked) {
+ if (myCheckPolicy.uncheckParentWithUncheckedChild) {
+ TreeNode parent = node.getParent();
+ while (parent != null) {
+ if (parent instanceof CheckedTreeNode) {
+ changeNodeState((CheckedTreeNode)parent, false);
+ }
+ parent = parent.getParent();
+ }
+ }
+ if (myCheckPolicy.uncheckChildrenWithUncheckedParent) {
+ uncheckChildren(node);
+ }
+ }
+ else {
+ if (myCheckPolicy.checkChildrenWithCheckedParent) {
+ checkChildren(node);
+ }
+
+ if (myCheckPolicy.checkParentWithCheckedChild) {
+ TreeNode parent = node.getParent();
+ while (parent != null) {
+ if (parent instanceof CheckedTreeNode) {
+ changeNodeState((CheckedTreeNode)parent, true);
+ }
+ parent = parent.getParent();
+ }
+ }
+ }
+ }
+
+ private void changeNodeState(final CheckedTreeNode node, final boolean checked) {
+ if (node.isChecked() != checked) {
+ myEventDispatcher.getMulticaster().beforeNodeStateChanged(node);
+ node.setChecked(checked);
+ myEventDispatcher.getMulticaster().nodeStateChanged(node);
+ }
+ }
+
+ private void uncheckChildren(final CheckedTreeNode node) {
+ final Enumeration children = node.children();
+ while (children.hasMoreElements()) {
+ final Object o = children.nextElement();
+ if (!(o instanceof CheckedTreeNode)) continue;
+ CheckedTreeNode child = (CheckedTreeNode)o;
+ changeNodeState(child, false);
+ uncheckChildren(child);
+ }
+ }
+
+ private void checkChildren(final CheckedTreeNode node) {
+ final Enumeration children = node.children();
+ while (children.hasMoreElements()) {
+ final Object o = children.nextElement();
+ if (!(o instanceof CheckedTreeNode)) continue;
+ CheckedTreeNode child = (CheckedTreeNode)o;
+ changeNodeState(child, true);
+ checkChildren(child);
+ }
+ }
+
+ private void setupKeyListener(final Tree tree, final JComponent mainComponent) {
+ mainComponent.addKeyListener(new KeyAdapter() {
+ public void keyPressed(@NotNull KeyEvent e) {
+ if (isToggleEvent(e, mainComponent)) {
+ TreePath treePath = tree.getLeadSelectionPath();
+ if (treePath == null) return;
+ final Object o = treePath.getLastPathComponent();
+ if (!(o instanceof CheckedTreeNode)) return;
+ CheckedTreeNode firstNode = (CheckedTreeNode)o;
+ toggleNode(tree, firstNode);
+ boolean checked = firstNode.isChecked();
+
+ TreePath[] selectionPaths = tree.getSelectionPaths();
+ for (int i = 0; selectionPaths != null && i < selectionPaths.length; i++) {
+ final TreePath selectionPath = selectionPaths[i];
+ final Object o1 = selectionPath.getLastPathComponent();
+ if (!(o1 instanceof CheckedTreeNode)) continue;
+ CheckedTreeNode node = (CheckedTreeNode)o1;
+ setNodeState(tree, node, checked);
+ }
+
+ e.consume();
+ }
+ }
+ });
+ }
+
+ private static boolean isToggleEvent(KeyEvent e, JComponent mainComponent) {
+ return e.getKeyCode() == KeyEvent.VK_SPACE && SpeedSearchSupply.getSupply(mainComponent) == null;
+ }
+
+ private void setupMouseListener(final Tree tree, JComponent mainComponent, final CheckboxTreeBase.CheckboxTreeCellRendererBase cellRenderer) {
+ new ClickListener() {
+ @Override
+ public boolean onClick(@NotNull MouseEvent e, int clickCount) {
+ int row = tree.getRowForLocation(e.getX(), e.getY());
+ if (row < 0) return false;
+ final Object o = tree.getPathForRow(row).getLastPathComponent();
+ if (!(o instanceof CheckedTreeNode)) return false;
+ Rectangle rowBounds = tree.getRowBounds(row);
+ cellRenderer.setBounds(rowBounds);
+ Rectangle checkBounds = cellRenderer.myCheckbox.getBounds();
+ checkBounds.setLocation(rowBounds.getLocation());
+
+ if (checkBounds.height == 0) checkBounds.height = checkBounds.width = rowBounds.height;
+
+ final CheckedTreeNode node = (CheckedTreeNode)o;
+ if (checkBounds.contains(e.getPoint())) {
+ if (node.isEnabled()) {
+ toggleNode(tree, node);
+ tree.setSelectionRow(row);
+ return true;
+ }
+ }
+ else if (clickCount > 1) {
+ myEventDispatcher.getMulticaster().mouseDoubleClicked(node);
+ return true;
+ }
+
+ return false;
+ }
+ }.installOn(mainComponent);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T[] getCheckedNodes(final Class<T> nodeType, @Nullable final Tree.NodeFilter<T> filter, final TreeModel model) {
+ final ArrayList<T> nodes = new ArrayList<T>();
+ final Object root = model.getRoot();
+ if (!(root instanceof CheckedTreeNode)) {
+ throw new IllegalStateException(
+ "The root must be instance of the " + CheckedTreeNode.class.getName() + ": " + root.getClass().getName());
+ }
+ new Object() {
+ @SuppressWarnings("unchecked")
+ public void collect(CheckedTreeNode node) {
+ if (node.isLeaf()) {
+ Object userObject = node.getUserObject();
+ if (node.isChecked() && userObject != null && nodeType.isAssignableFrom(userObject.getClass())) {
+ final T value = (T)userObject;
+ if (filter != null && !filter.accept(value)) return;
+ nodes.add(value);
+ }
+ }
+ else {
+ for (int i = 0; i < node.getChildCount(); i++) {
+ final TreeNode child = node.getChildAt(i);
+ if (child instanceof CheckedTreeNode) {
+ collect((CheckedTreeNode)child);
+ }
+ }
+ }
+ }
+ }.collect((CheckedTreeNode)root);
+ T[] result = (T[])Array.newInstance(nodeType, nodes.size());
+ nodes.toArray(result);
+ return result;
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeListener.java
index bdaf6f2ea546..792c4589c85d 100644
--- a/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java
+++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeListener.java
@@ -13,18 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package com.intellij.ui;
-package com.intellij.codeInsight.editorActions;
+import org.jetbrains.annotations.NotNull;
-import java.awt.datatransfer.DataFlavor;
+import java.util.EventListener;
/**
- * @author yole
+ * @author nik
*/
-public interface TextBlockTransferableData {
- DataFlavor getFlavor();
+public interface CheckboxTreeListener extends EventListener {
+ void mouseDoubleClicked(@NotNull CheckedTreeNode node);
- int getOffsetCount();
- int getOffsets(final int[] offsets, final int index);
- int setOffsets(final int[] offsets, final int index);
+ void nodeStateChanged(@NotNull CheckedTreeNode node);
+
+ void beforeNodeStateChanged(@NotNull CheckedTreeNode node);
}
diff --git a/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java b/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java
index 846378cc1633..2d4213da3954 100644
--- a/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java
+++ b/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -165,6 +165,9 @@ public class CommonActionsPanel extends JPanel {
@Override
public void addNotify() {
+ if (getBackground() != null && !getBackground().equals(UIUtil.getPanelBackground())) {
+ SwingUtilities.updateComponentTreeUI(this.getParent());
+ }
final JRootPane pane = getRootPane();
for (AnActionButton button : myActions) {
final ShortcutSet shortcut = button.getShortcut();
diff --git a/platform/platform-api/src/com/intellij/ui/JBSplitter.java b/platform/platform-api/src/com/intellij/ui/JBSplitter.java
index b4000dbcfae2..5f01602d92c5 100644
--- a/platform/platform-api/src/com/intellij/ui/JBSplitter.java
+++ b/platform/platform-api/src/com/intellij/ui/JBSplitter.java
@@ -94,14 +94,6 @@ public class JBSplitter extends Splitter {
saveProportion();
}
- public void setOnePixelMode() {
- setDividerWidth(1);
- setShowDividerIcon(false);
- getDivider().setBackground(new JBColor(Gray._153.withAlpha(128), Gray._100.withAlpha(128)));
- setShowDividerControls(false);
- setOrientation(getOrientation());
- }
-
protected void loadProportion() {
if (! StringUtil.isEmpty(mySplitterProportionKey)) {
setProportion(PropertiesComponent.getInstance().getFloat(mySplitterProportionKey, myProportion));
diff --git a/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java b/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java
new file mode 100644
index 000000000000..15dd5fdc2abb
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2014 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.ui;
+
+import com.intellij.openapi.ui.Divider;
+import com.intellij.openapi.ui.OnePixelDivider;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class OnePixelSplitter extends JBSplitter {
+
+ public OnePixelSplitter() {
+ super();
+ init();
+ }
+
+ public OnePixelSplitter(boolean vertical) {
+ super(vertical);
+ init();
+ }
+
+ public OnePixelSplitter(boolean vertical, float proportion) {
+ super(vertical, proportion);
+ init();
+ }
+
+ public OnePixelSplitter(float proportion) {
+ super(proportion);
+ init();
+ }
+
+ public OnePixelSplitter(boolean vertical, float proportion, float minProp, float maxProp) {
+ super(vertical, proportion, minProp, maxProp);
+ init();
+ }
+
+ protected void init() {
+ setDividerWidth(1);
+ }
+
+ @Override
+ protected Divider createDivider() {
+ return new OnePixelDivider(isVertical(), this);
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java b/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java
index ee68a3f94ae8..2f5bf0343ed6 100644
--- a/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java
+++ b/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,6 +17,7 @@ package com.intellij.ui.border;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.border.Border;
import java.awt.*;
@@ -28,17 +29,17 @@ public class CustomLineBorder implements Border {
private final Color myColor;
private final Insets myInsets;
- public CustomLineBorder(@NotNull Color color, @NotNull Insets insets) {
+ public CustomLineBorder(@Nullable Color color, @NotNull Insets insets) {
myColor = color;
myInsets = insets;
}
- public CustomLineBorder(@NotNull Color color, int top, int left, int bottom, int right) {
+ public CustomLineBorder(@Nullable Color color, int top, int left, int bottom, int right) {
this(color, new Insets(top, left, bottom, right));
}
public CustomLineBorder(@NotNull Insets insets) {
- this(UIUtil.getBorderColor(), insets);
+ this(null, insets);
}
public CustomLineBorder(int top, int left, int bottom, int right) {
@@ -59,7 +60,7 @@ public class CustomLineBorder implements Border {
}
protected Color getColor() {
- return myColor;
+ return myColor == null ? UIUtil.getBorderColor() : myColor;
}
@Override
diff --git a/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java b/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java
index a79349b5f6aa..46bce6b3834d 100644
--- a/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java
+++ b/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java
@@ -17,12 +17,12 @@ package com.intellij.ui.table;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.config.Storage;
-import com.intellij.util.ui.ListTableModel;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
+import javax.swing.table.TableModel;
import java.util.ArrayList;
import java.util.Arrays;
@@ -33,10 +33,14 @@ import java.util.Arrays;
public class BaseTableView extends JBTable {
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.table.BaseTableView");
- public BaseTableView(final ListTableModel model) {
+ public BaseTableView(final TableModel model) {
super(model);
}
+ public BaseTableView(TableModel model, TableColumnModel columnModel) {
+ super(model, columnModel);
+ }
+
@NonNls
private static String orderPropertyName(final int index) {
return "Order"+index;
diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
index e7ff935e57f9..435c4358959f 100644
--- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java
+++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
@@ -62,8 +62,12 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
this(new DefaultTableModel());
}
- public JBTable(final TableModel model) {
- super(model);
+ public JBTable(TableModel model) {
+ this(model, null);
+ }
+
+ public JBTable(final TableModel model, final TableColumnModel columnModel) {
+ super(model, columnModel);
myEmptyText = new StatusText(this) {
@Override
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java b/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java
index d1dfa976e479..c8c944c86e4a 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java
@@ -92,6 +92,7 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
* out of its container. (IDEA-61536)
*/
private WeakReference<TabInfo> myPreviousSelection = new WeakReference<TabInfo>(null);
+ private boolean myTitleShortened;
public TabInfo(final JComponent component) {
myComponent = component;
@@ -392,6 +393,14 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
return myPreviousSelection.get();
}
+ public boolean isTitleShortened() {
+ return myTitleShortened;
+ }
+
+ public void setTitleIsShortened(boolean titleIsShortened) {
+ myTitleShortened = titleIsShortened;
+ }
+
public interface DragOutDelegate {
void dragOutStarted(MouseEvent mouseEvent, TabInfo info);
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java
index 655854ac933c..b0df0917dfe0 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java
@@ -240,7 +240,7 @@ class DragHelper extends MouseDragHelper {
final JBTabsPosition position = myTabs.getTabsPosition();
- if (!willDragOutStart && JBEditorTabs.isAlphabeticalMode() && position != JBTabsPosition.top && position != JBTabsPosition.bottom) {
+ if (!willDragOutStart && myTabs.isAlphabeticalMode() && position != JBTabsPosition.top && position != JBTabsPosition.bottom) {
Point p = new Point(event.getPoint());
p = SwingUtilities.convertPoint(event.getComponent(), p, myTabs);
if (myTabs.getVisibleRect().contains(p) && myPressedOnScreenPoint.distance(new RelativePoint(event).getScreenPoint()) > 15) {
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java
index 761d3ea0d341..a842f623ac45 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java
@@ -43,7 +43,8 @@ import java.util.List;
* @author pegov
*/
public class JBEditorTabs extends JBTabsImpl {
- private static final String TABS_ALPHABETICAL_KEY = "tabs.alphabetical";
+ public static final String TABS_ALPHABETICAL_KEY = "tabs.alphabetical";
+ static final String TABS_SHORTEN_TITLE_IF_NEED = "tabs.shorten.title.if.need";
private JBEditorTabsPainter myDarkPainter = new DarculaEditorTabsPainter();
private JBEditorTabsPainter myDefaultPainter = new DefaultEditorTabsPainter();
@@ -61,6 +62,13 @@ public class JBEditorTabs extends JBTabsImpl {
}
@Override
+ protected TabLabel createTabLabel(TabInfo info) {
+ TabLabel label = super.createTabLabel(info);
+ label.putClientProperty(TABS_SHORTEN_TITLE_IF_NEED, Boolean.TRUE);
+ return label;
+ }
+
+ @Override
public boolean isEditorTabs() {
return true;
}
@@ -130,7 +138,7 @@ public class JBEditorTabs extends JBTabsImpl {
return UIUtil.isUnderDarcula() ? myDarkPainter : myDefaultPainter;
}
- public static boolean isAlphabeticalMode() {
+ public boolean isAlphabeticalMode() {
return Registry.is(TABS_ALPHABETICAL_KEY);
}
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
index a058badddd41..60898a6e9bd8 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
@@ -1262,6 +1262,10 @@ public class JBTabsImpl extends JComponent
return null;
}
+ public boolean isAlphabeticalMode() {
+ return false;
+ }
+
@Nullable
private TabInfo findEnabledBackward(int from, boolean cycle) {
if (from < 0) return null;
@@ -1653,19 +1657,13 @@ public class JBTabsImpl extends JComponent
config.setAntialiasing(false);
- if (isSideComponentVertical()) {
- Toolbar toolbarComp = myInfo2Toolbar.get(mySelectedInfo);
- if (toolbarComp != null && !toolbarComp.isEmpty()) {
- Rectangle toolBounds = toolbarComp.getBounds();
- g2d.setColor(CaptionPanel.CNT_ACTIVE_BORDER_COLOR);
+ Toolbar toolbarComp = myInfo2Toolbar.get(mySelectedInfo);
+ if (toolbarComp != null && !toolbarComp.isEmpty()) {
+ Rectangle toolBounds = toolbarComp.getBounds();
+ g2d.setColor(CaptionPanel.CNT_ACTIVE_BORDER_COLOR);
+ if (isSideComponentVertical()) {
g2d.drawLine((int)toolBounds.getMaxX(), toolBounds.y, (int)toolBounds.getMaxX(), (int)toolBounds.getMaxY() - 1);
- }
- }
- else if (!isSideComponentOnTabs()) {
- Toolbar toolbarComp = myInfo2Toolbar.get(mySelectedInfo);
- if (toolbarComp != null && !toolbarComp.isEmpty()) {
- Rectangle toolBounds = toolbarComp.getBounds();
- g2d.setColor(CaptionPanel.CNT_ACTIVE_BORDER_COLOR);
+ } else if (!isSideComponentOnTabs()) {
g2d.drawLine(toolBounds.x, (int)toolBounds.getMaxY(), (int)toolBounds.getMaxX() - 1, (int)toolBounds.getMaxY());
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
index 21c36d5dd66a..a360c4e9294f 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -22,6 +22,7 @@ import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.util.Pass;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.*;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.ui.tabs.JBTabsPosition;
@@ -317,6 +318,16 @@ public class TabLabel extends JPanel {
public void setText(final SimpleColoredText text) {
+ myInfo.setTitleIsShortened(false);
+ if (text != null && text.getTexts().size() == 1 && Boolean.TRUE == getClientProperty(JBEditorTabs.TABS_SHORTEN_TITLE_IF_NEED)) {
+ String title = text.getTexts().get(0);
+ if (title.length() > UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT) {
+ SimpleTextAttributes attributes = text.getAttributes().get(0);
+ text.clear();
+ text.append(StringUtil.getShortened(title, UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT), attributes);
+ myInfo.setTitleIsShortened(true);
+ }
+ }
myLabel.change(new Runnable() {
public void run() {
myLabel.clear();
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java
index 653420ae261f..4e5925d2a2ee 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -147,7 +147,7 @@ public class SingleRowLayout extends TabLayout {
}
public LayoutPassInfo layoutSingleRow(List<TabInfo> visibleInfos) {
- if (JBEditorTabs.isAlphabeticalMode()) {
+ if (myTabs.isAlphabeticalMode()) {
Collections.sort(visibleInfos, new Comparator<TabInfo>() {
@Override
public int compare(TabInfo o1, TabInfo o2) {
diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java
index 169b5d57479b..0975876055b2 100644
--- a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java
+++ b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -828,4 +828,35 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith
public void setHorizontalAutoScrollingEnabled(boolean enabled) {
myHorizontalAutoScrolling = enabled;
}
+
+ /**
+ * Returns the deepest visible component
+ * that will be rendered at the specified location.
+ *
+ * @param x horizontal location in the tree
+ * @param y vertical location in the tree
+ * @return the deepest visible component of the renderer
+ */
+ @Nullable
+ protected Component getDeepestRendererComponentAt(int x, int y) {
+ int row = getRowForLocation(x, y);
+ if (row >= 0) {
+ TreeCellRenderer renderer = getCellRenderer();
+ if (renderer != null) {
+ TreePath path = getPathForRow(row);
+ Object node = path.getLastPathComponent();
+ Component component = renderer.getTreeCellRendererComponent(this, node,
+ isRowSelected(row),
+ isExpanded(row),
+ getModel().isLeaf(node),
+ row, true);
+ Rectangle bounds = getPathBounds(path);
+ if (bounds != null) {
+ component.setBounds(bounds); // initialize size to layout complex renderer
+ return SwingUtilities.getDeepestComponentAt(component, x - bounds.x, y - bounds.y);
+ }
+ }
+ }
+ return null;
+ }
} \ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java
index dac3354a24fb..b574926a7eb8 100644
--- a/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java
+++ b/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java
@@ -98,7 +98,9 @@ public class TreeTableTree extends Tree {
public void setVisibleRow(int row) {
myVisibleRow = row;
- setPreferredSize(new Dimension(getRowBounds(myVisibleRow).width, getPreferredSize().height));
+ final Rectangle rowBounds = getRowBounds(myVisibleRow);
+ final int indent = rowBounds.x - getVisibleRect().x;
+ setPreferredSize(new Dimension(getRowBounds(myVisibleRow).width + indent, getPreferredSize().height));
}
public void _processKeyEvent(KeyEvent e){
diff --git a/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java b/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java
index 94eaa4db1ccb..0bcb416c7334 100644
--- a/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java
+++ b/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.util.SystemProperties;
import com.intellij.util.WaitForProgressToShow;
import com.intellij.util.proxy.CommonProxy;
import com.intellij.util.proxy.JavaProxyProperty;
@@ -64,6 +65,7 @@ import java.util.*;
)
public class HttpConfigurable implements PersistentStateComponent<HttpConfigurable>, ApplicationComponent,
ExportableApplicationComponent {
+ public static final int CONNECTION_TIMEOUT = SystemProperties.getIntProperty("connection.timeout", 10000);
private static final Logger LOG = Logger.getInstance("#com.intellij.util.net.HttpConfigurable");
public boolean PROXY_TYPE_IS_SOCKS = false;
public boolean USE_HTTP_PROXY = false;
@@ -348,8 +350,8 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
final URLConnection connection = openConnection(url);
try {
- connection.setConnectTimeout(3 * 1000);
- connection.setReadTimeout(3 * 1000);
+ connection.setConnectTimeout(CONNECTION_TIMEOUT);
+ connection.setReadTimeout(CONNECTION_TIMEOUT);
connection.connect();
connection.getInputStream();
}
diff --git a/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java b/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java
index c2d3d829440d..89d5a238c188 100644
--- a/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java
+++ b/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java
@@ -108,6 +108,11 @@ public class FormBuilder {
}
public FormBuilder addVerticalGap(final int height) {
+ if (height == -1) {
+ myPanel.add(new JLabel(), new GridBagConstraints(0, myLineCount++, 2, 1, 0, 1, CENTER, NONE, new Insets(0, 0, 0, 0), 0, 0));
+ return this;
+ }
+
return addLabeledComponent((JLabel)null,
new Box.Filler(new Dimension(0, height), new Dimension(0, height), new Dimension(Short.MAX_VALUE, height)));
}