Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2014-08-03 19:01:38 +02:00
71 changed files with 1067 additions and 529 deletions
+1
View File
@@ -214,6 +214,7 @@ libraryLicense(name: "maven-core", version: "3.0.5", libraryNames: ["maven-core-
libraryLicense(name: "plexus-component-annotations", version: "1.5.5", libraryNames: ["plexus-component-annotations-1.5.5.jar"], license: "Apache 2.0", url: "http://maven.apache.org/", licenseUrl: "http://maven.apache.org/license.html")
libraryLicense(name: "Maven3", libraryNames: ["Maven3", "maven-dependency-tree-1.2.jar", "archetype-catalog-2.2.jar", "archetype-common-2.2.jar"], version: "3.0.5", license: "Apache 2.0", url: "http://maven.apache.org/", licenseUrl: "http://maven.apache.org/license.html")
libraryLicense(name: "Gradle", version: "1.12", license: "Apache 2.0", url: "http://gradle.org/", licenseUrl: "http://gradle.org/license")
libraryLicense(name: "gradle-tooling-api-2.0.jar", version: "2.0", license: "Apache 2.0", url: "http://gradle.org/", licenseUrl: "http://gradle.org/license")
libraryLicense(name: "GradleJnaPosix", version: "1.0.3", license: "LGPL 2.1", url: "http://www.jruby.org/", licenseUrl: "http://www.gnu.org/licenses/lgpl-2.1.txt")
libraryLicense(name: "Slf4j", version: "1.7.2", license: "MIT License", url: "http://slf4j.org/", licenseUrl: "http://slf4j.org/license.html")
libraryLicense(name: "GradleGuava", version: "14.0.1", license: "Apache 2.0", url: "http://code.google.com/p/guava-libraries/", licenseUrl: "http://apache.org/licenses/LICENSE-2.0")
@@ -111,13 +111,13 @@ public class JavaDebuggerSupport extends DebuggerSupport {
@Override
@NotNull
public DebuggerActionHandler getRunToCursorHandler() {
return myRunToCursorActionHandler;
return DISABLED;
}
@Override
@NotNull
public DebuggerActionHandler getForceRunToCursorHandler() {
return myForceRunToCursorActionHandler;
return DISABLED;
}
@Override
@@ -44,6 +44,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.ui.JBSplitter;
import com.intellij.ui.OnePixelSplitter;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.ui.navigation.BackAction;
import com.intellij.ui.navigation.ForwardAction;
@@ -174,12 +175,9 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se
public JComponent createComponent() {
myComponent = new MyPanel();
mySplitter = new JBSplitter(false, .15f);
mySplitter = Registry.is("ide.new.project.settings") ? new OnePixelSplitter(false, .15f) : new JBSplitter(false, .15f);
mySplitter.setSplitterProportionKey("ProjectStructure.TopLevelElements");
mySplitter.setHonorComponentsMinimumSize(true);
if (Registry.is("ide.new.project.settings")) {
mySplitter.setOnePixelMode();
}
initSidePanel();
@@ -206,7 +206,7 @@ public class ArtifactEditorImpl implements ArtifactEditorEx {
myErrorPanelPlace.add(myValidationManager.getMainErrorPanel(), BorderLayout.CENTER);
JBSplitter splitter = new JBSplitter(false);
final JBSplitter splitter = Registry.is("ide.new.project.settings") ? new OnePixelSplitter(false) : new JBSplitter(false);
final JPanel leftPanel = new JPanel(new BorderLayout());
JPanel treePanel = myLayoutTreeComponent.getTreePanel();
if (UIUtil.isUnderDarcula()) {
@@ -262,7 +262,6 @@ public class ArtifactEditorImpl implements ArtifactEditorEx {
}
splitter.setSecondComponent(rightPanel);
if (Registry.is("ide.new.project.settings")) {
splitter.setOnePixelMode();
splitter.getDivider().setBackground(UIUtil.getPanelBackground());
treePanel.setBorder(new EmptyBorder(0, 0, 0, 0));
rightPanel.setBorder(new EmptyBorder(0, 0, 0, 0));
@@ -72,6 +72,7 @@ public class UISettings implements PersistentStateComponent<UISettings>, Exporta
public int RECENT_FILES_LIMIT = 50;
public int CONSOLE_COMMAND_HISTORY_LIMIT = 300;
public int EDITOR_TAB_LIMIT = 10;
public int EDITOR_TAB_TITLE_LIMIT = 100;
public boolean ANIMATE_WINDOWS = true;
public int ANIMATION_SPEED = 2000; // Pixels per second
public boolean SHOW_TOOL_WINDOW_NUMBERS = true;
@@ -3,7 +3,7 @@
<grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="527"/>
<xy x="20" y="20" width="500" height="585"/>
</constraints>
<properties/>
<border type="none"/>
@@ -108,7 +108,7 @@
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="eb8d0" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="10">
<grid id="eb8d0" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="10">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -119,7 +119,7 @@
</clientProperties>
<border type="none" title-resource-bundle="messages/ApplicationBundle" title-key="group.tab.closing.policy"/>
<children>
<grid id="5a5a7" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="5a5a7" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -129,7 +129,9 @@
<children>
<component id="527a6" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
<preferred-size width="60" height="27"/>
</grid>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="editbox.tab.limit"/>
@@ -138,19 +140,38 @@
<component id="16477" class="javax.swing.JTextField" binding="myEditorTabLimitField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="0" indent="0" use-parent-layout="false">
<preferred-size width="30" height="-1"/>
<preferred-size width="30" height="27"/>
</grid>
</constraints>
<properties>
<text value="15"/>
</properties>
</component>
<component id="2479d" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="editbox.tab.title.limit"/>
</properties>
</component>
<component id="3499c" class="javax.swing.JTextField" binding="myTabTitleLimitField">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="0" indent="0" use-parent-layout="false">
<preferred-size width="30" height="27"/>
</grid>
</constraints>
<properties>
<columns value="2"/>
<text value="30"/>
</properties>
</component>
</children>
</grid>
<grid id="9b723" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="2">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -184,7 +205,7 @@
<grid id="611cc" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="2">
<margin top="10" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -45,6 +45,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
private JCheckBox myShowCloseButtonOnCheckBox;
private JCheckBox myShowDirectoryInTabCheckBox;
private JRadioButton myActivateRightNeighbouringTabRadioButton;
private JTextField myTabTitleLimitField;
public EditorTabsConfigurable() {
myEditorTabPlacement.setModel(new DefaultComboBoxModel(new Object[]{
@@ -119,6 +120,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
myHideKnownExtensions.setSelected(uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS);
myShowDirectoryInTabCheckBox.setSelected(uiSettings.SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES);
myEditorTabLimitField.setText(Integer.toString(uiSettings.EDITOR_TAB_LIMIT));
myTabTitleLimitField.setText(Integer.toString(uiSettings.EDITOR_TAB_TITLE_LIMIT));
myShowCloseButtonOnCheckBox.setSelected(uiSettings.SHOW_CLOSE_BUTTON);
if (uiSettings.CLOSE_NON_MODIFIED_FILES_FIRST) {
@@ -171,14 +173,29 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
uiSettings.ACTIVATE_RIGHT_EDITOR_ON_CLOSE = myActivateRightNeighbouringTabRadioButton.isSelected();
String temp = myEditorTabLimitField.getText();
if(temp.trim().length() > 0){
if (temp.trim().length() > 0) {
try {
int newEditorTabLimit = Integer.parseInt(temp);
if(newEditorTabLimit>0&&newEditorTabLimit!=uiSettings.EDITOR_TAB_LIMIT){
uiSettings.EDITOR_TAB_LIMIT=newEditorTabLimit;
if (newEditorTabLimit > 0 && newEditorTabLimit != uiSettings.EDITOR_TAB_LIMIT) {
uiSettings.EDITOR_TAB_LIMIT = newEditorTabLimit;
uiSettingsChanged = true;
}
}catch (NumberFormatException ignored){}
}
catch (NumberFormatException ignored) {
}
}
temp = myTabTitleLimitField.getText();
if (temp.trim().length() > 0) {
try {
int newTabTitleLimit = Integer.parseInt(temp);
newTabTitleLimit = Math.max(10, Math.min(100, newTabTitleLimit));
if (newTabTitleLimit != uiSettings.EDITOR_TAB_TITLE_LIMIT){
uiSettings.EDITOR_TAB_TITLE_LIMIT = newTabTitleLimit;
uiSettingsChanged = true;
}
}
catch (NumberFormatException ignored) {
}
}
if(uiSettingsChanged){
uiSettings.fireUISettingsChanged();
@@ -191,6 +208,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
boolean isModified = isModified(myCbModifiedTabsMarkedWithAsterisk, uiSettings.MARK_MODIFIED_TABS_WITH_ASTERISK);
isModified |= isModified(myShowTabsTooltipsCheckBox, uiSettings.SHOW_TABS_TOOLTIPS);
isModified |= isModified(myEditorTabLimitField, uiSettings.EDITOR_TAB_LIMIT);
isModified |= isModified(myTabTitleLimitField, uiSettings.EDITOR_TAB_TITLE_LIMIT);
int tabPlacement = ((Integer)myEditorTabPlacement.getSelectedItem()).intValue();
isModified |= tabPlacement != uiSettings.EDITOR_TAB_PLACEMENT;
isModified |= myHideKnownExtensions.isSelected() != uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS;
@@ -26,11 +26,13 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.*;
import com.intellij.ui.treeStructure.treetable.TreeColumnInfo;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ComboBoxCellEditor;
import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -38,12 +40,11 @@ import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.*;
import java.util.List;
import java.util.Map;
/**
* This dialog allows selecting paths inside selected archives or directories.
@@ -108,17 +109,17 @@ public class DetectedRootsChooserDialog extends DialogWrapper {
private JScrollPane myPane;
private String myDescription;
public DetectedRootsChooserDialog(Component component, List<SuggestedChildRootInfo> suggestedRoots) {
public DetectedRootsChooserDialog(Component component, Collection<SuggestedChildRootInfo> suggestedRoots) {
super(component, true);
init(suggestedRoots);
}
public DetectedRootsChooserDialog(Project project, List<SuggestedChildRootInfo> suggestedRoots) {
public DetectedRootsChooserDialog(Project project, Collection<SuggestedChildRootInfo> suggestedRoots) {
super(project, true);
init(suggestedRoots);
}
private void init(List<SuggestedChildRootInfo> suggestedRoots) {
private void init(Collection<SuggestedChildRootInfo> suggestedRoots) {
myDescription = XmlStringUtil.wrapInHtml(ApplicationNamesInfo.getInstance().getFullProductName() +
" just scanned files and detected the following " + StringUtil.pluralize("root", suggestedRoots.size()) + ".<br>" +
"Select items in the tree below or press Cancel to cancel operation.");
@@ -128,7 +129,7 @@ public class DetectedRootsChooserDialog extends DialogWrapper {
init();
}
private static CheckboxTreeTable createTreeTable(List<SuggestedChildRootInfo> suggestedRoots) {
private static CheckboxTreeTable createTreeTable(Collection<SuggestedChildRootInfo> suggestedRoots) {
final CheckedTreeNode root = createRoot(suggestedRoots);
CheckboxTreeTable treeTable = new CheckboxTreeTable(root, new CheckboxTree.CheckboxTreeCellRenderer(true) {
@Override
@@ -189,14 +190,30 @@ public class DetectedRootsChooserDialog extends DialogWrapper {
column.setPreferredWidth(width);
column.setMaxWidth(width);
treeTable.setRootVisible(false);
new TreeTableSpeedSearch(treeTable, new Convertor<TreePath, String>() {
@Override
public String convert(TreePath o) {
Object node = o.getLastPathComponent();
if (!(node instanceof VirtualFileCheckedTreeNode)) return "";
return ((VirtualFileCheckedTreeNode)node).getFile().getPresentableUrl();
}
});
TreeUtil.expandAll(treeTable.getTree());
return treeTable;
}
private static CheckedTreeNode createRoot(List<SuggestedChildRootInfo> suggestedRoots) {
private static CheckedTreeNode createRoot(Collection<SuggestedChildRootInfo> suggestedRoots) {
SuggestedChildRootInfo[] sortedRoots = suggestedRoots.toArray(new SuggestedChildRootInfo[suggestedRoots.size()]);
Arrays.sort(sortedRoots, new Comparator<SuggestedChildRootInfo>() {
@Override
public int compare(@NotNull SuggestedChildRootInfo o1, @NotNull SuggestedChildRootInfo o2) {
return o1.getDetectedRoot().getFile().getPresentableUrl().compareTo(o2.getDetectedRoot().getFile().getPresentableUrl());
}
});
CheckedTreeNode root = new CheckedTreeNode(null);
Map<VirtualFile, CheckedTreeNode> rootCandidateNodes = new HashMap<VirtualFile, CheckedTreeNode>();
for (SuggestedChildRootInfo rootInfo : suggestedRoots) {
for (SuggestedChildRootInfo rootInfo : sortedRoots) {
final VirtualFile rootCandidate = rootInfo.getRootCandidate();
CheckedTreeNode parent = rootCandidateNodes.get(rootCandidate);
if (parent == null) {
@@ -230,6 +247,12 @@ public class DetectedRootsChooserDialog extends DialogWrapper {
return "DetectedRootsChooserDialog";
}
@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
return myTreeTable;
}
private static class VirtualFileCheckedTreeNode extends CheckedTreeNode {
private final VirtualFile myFile;
@@ -19,6 +19,7 @@ import com.intellij.openapi.roots.libraries.LibraryRootType;
import com.intellij.openapi.roots.libraries.ui.DetectedLibraryRoot;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Map;
@@ -32,17 +33,19 @@ class SuggestedChildRootInfo {
private final Map<LibraryRootType, String> myRootTypeNames;
private LibraryRootType mySelectedRootType;
SuggestedChildRootInfo(VirtualFile rootCandidate, DetectedLibraryRoot detectedRoot, Map<LibraryRootType, String> rootTypeNames) {
SuggestedChildRootInfo(@NotNull VirtualFile rootCandidate, @NotNull DetectedLibraryRoot detectedRoot, @NotNull Map<LibraryRootType, String> rootTypeNames) {
myRootCandidate = rootCandidate;
myDetectedRoot = detectedRoot;
myRootTypeNames = rootTypeNames;
mySelectedRootType = detectedRoot.getTypes().get(0);
}
@NotNull
public VirtualFile getRootCandidate() {
return myRootCandidate;
}
@NotNull
public DetectedLibraryRoot getDetectedRoot() {
return myDetectedRoot;
}
@@ -51,6 +54,7 @@ class SuggestedChildRootInfo {
return myRootTypeNames.get(type);
}
@NotNull
public LibraryRootType getSelectedRootType() {
return mySelectedRootType;
}
@@ -64,6 +68,7 @@ class SuggestedChildRootInfo {
}
}
@NotNull
public String[] getRootTypeNames() {
final String[] types = ArrayUtil.toStringArray(myRootTypeNames.values());
Arrays.sort(types, String.CASE_INSENSITIVE_ORDER);
@@ -39,6 +39,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.ex.VirtualFileManagerAdapter;
import com.intellij.ui.JBSplitter;
import com.intellij.ui.OnePixelSplitter;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.border.CustomLineBorder;
import com.intellij.ui.roots.ToolbarPanel;
@@ -171,10 +172,7 @@ public class CommonContentEntriesEditor extends ModuleElementsEditor {
}
entriesPanel.add(toolbarPanel, BorderLayout.CENTER);
final JBSplitter splitter = new JBSplitter(false);
if (Registry.is("ide.new.project.settings")) {
splitter.setOnePixelMode();
}
final JBSplitter splitter = Registry.is("ide.new.project.settings") ? new OnePixelSplitter(false) : new JBSplitter(false);
splitter.setProportion(0.6f);
splitter.setHonorComponentsMinimumSize(true);
@@ -367,7 +367,7 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
"Unexpected difference in indexing of %s by index %s, file type %s, charset %s\ndiff %s\nprevious indexed info %s",
fileContent.getFile(),
myIndexId,
fileContent.getFileType(),
fileContent.getFileType().getName(),
((FileContentImpl)fileContent).getCharset(),
buildDiff(data, contentData),
myIndexingTrace.get(hashId)
@@ -396,7 +396,7 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
FileContent fileContent = (FileContent)content;
try {
myIndexingTrace.put(hashId, ((FileContentImpl)fileContent).getCharset() + "," + fileContent.getFileType()+"," + fileContent.getFile().getPath() + "," +
myIndexingTrace.put(hashId, ((FileContentImpl)fileContent).getCharset() + "," + fileContent.getFileType().getName()+"," + fileContent.getFile().getPath() + "," +
ExceptionUtil.getThrowableText(new Throwable()));
} catch (IOException ex) {
LOG.error(ex);
@@ -1,3 +1,18 @@
/*
* 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.webcore.packaging;
import com.intellij.icons.AllIcons;
@@ -93,6 +108,7 @@ public class ManagePackagesDialog extends DialogWrapper {
public void run() {
try {
myController.reloadAllPackages();
initModel();
myPackages.setPaintBusy(false);
}
catch (final IOException e) {
@@ -310,6 +326,7 @@ public class ManagePackagesDialog extends DialogWrapper {
@Override
public void run() {
myPackages.setModel(myPackagesModel);
((MyPackageFilter)myFilter).filter();
doSelectPackage(mySelectedPackageName);
setDownloadStatus(false);
}
@@ -473,6 +490,7 @@ public class ManagePackagesDialog extends DialogWrapper {
final Object pyPackage = myPackages.getSelectedValue();
if (pyPackage instanceof RepoPackage) {
final String packageName = ((RepoPackage)pyPackage).getName();
mySelectedPackageName = packageName;
myVersionComboBox.removeAllItems();
if (myVersionCheckBox.isEnabled()) {
myController.fetchPackageVersions(packageName, new CatchingConsumer<List<String>, Exception>() {
@@ -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;
}
@@ -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();
@@ -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;
}
}
@@ -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) {
}
}
@@ -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;
myEventDispatcher = EventDispatcher.create(CheckboxTreeListener.class);
myEventDispatcher.addListener(new CheckboxTreeListener() {
@Override
public void mouseDoubleClicked(@NotNull CheckedTreeNode node) {
onDoubleClick(node);
}
setRootVisible(false);
setShowsRootHandles(true);
setLineStyleAngled();
TreeUtil.installActions(this);
@Override
public void nodeStateChanged(@NotNull CheckedTreeNode node) {
CheckboxTreeBase.this.onNodeStateChanged(node);
}
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();
}
@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,57 +66,39 @@ 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;
/**
* @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();
}
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);
/**
* @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);
}
public void setNodeState(@NotNull CheckedTreeNode node, boolean checked) {
myHelper.setNodeState(this, node, checked);
}
public void addCheckboxTreeListener(@NotNull CheckboxTreeListener listener) {
myEventDispatcher.addListener(listener);
}
protected void onDoubleClick(final CheckedTreeNode node) {
}
protected boolean isToggleEvent(KeyEvent e) {
return e.getKeyCode() == KeyEvent.VK_SPACE;
}
protected boolean toggleNode(CheckedTreeNode node) {
boolean checked = !node.isChecked();
checkNode(node, checked);
// notify model listeners about model change
final TreeModel model = getModel();
model.valueForPathChanged(new TreePath(node.getPath()), node.getUserObject());
return checked;
}
/**
* Collect checked leaf nodes of the type {@code nodeType} and that are accepted by
* {@code filter}
@@ -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,
@@ -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.
@@ -13,19 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.roots.libraries.ui.impl;
package com.intellij.ui;
import com.intellij.ui.CheckboxTree;
import com.intellij.ui.CheckedTreeNode;
import com.intellij.ui.ClickListener;
import com.intellij.ui.dualView.TreeTableView;
import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
import com.intellij.ui.treeStructure.treetable.TreeTableTree;
import com.intellij.util.ui.ColumnInfo;
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.tree.DefaultTreeModel;
import javax.swing.*;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
@@ -40,21 +37,135 @@ import java.util.Enumeration;
/**
* @author nik
*/
public class CheckboxTreeTable extends TreeTableView {
public CheckboxTreeTable(CheckedTreeNode root, CheckboxTree.CheckboxTreeCellRenderer renderer, final ColumnInfo[] columns) {
super(new ListTreeTableModelOnColumns(root, columns));
initTree(getTree(), renderer);
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;
}
//todo[nik] I hate to copy-paste but have to copy the code below from CheckboxTreeBase to support CheckboxTree inside TreeTable in IDEA 11.1.x branch
//todo[nik] I solemnly swear to get rid of this code in IDEA 12 branch
private void initTree(final TreeTableTree tree, final CheckboxTree.CheckboxTreeCellRenderer cellRenderer) {
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) {
@@ -67,122 +178,33 @@ public class CheckboxTreeTable extends TreeTableView {
Rectangle checkBounds = cellRenderer.myCheckbox.getBounds();
checkBounds.setLocation(rowBounds.getLocation());
if (checkBounds.height == 0) checkBounds.height = rowBounds.height;
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);
toggleNode(tree, node);
tree.setSelectionRow(row);
return true;
}
}
else if (clickCount > 1) {
myEventDispatcher.getMulticaster().mouseDoubleClicked(node);
return true;
}
return false;
}
}.installOn(this);
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (isToggleEvent(e)) {
TreePath treePath = tree.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 = 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;
checkNode(node, checked);
((DefaultTreeModel)tree.getModel()).nodeChanged(node);
}
e.consume();
}
}
});
tree.setSelectionRow(0);
}
private static boolean isToggleEvent(KeyEvent e) {
return e.getKeyCode() == KeyEvent.VK_SPACE;
}
protected boolean toggleNode(CheckedTreeNode node) {
boolean checked = !node.isChecked();
checkNode(node, checked);
// notify model listeners about model change
final TreeModel model = getTree().getModel();
model.valueForPathChanged(new TreePath(node.getPath()), node.getUserObject());
return checked;
}
private void checkNode(CheckedTreeNode node, boolean checked) {
adjustParentsAndChildren(node, checked);
repaint();
}
private void adjustParentsAndChildren(final CheckedTreeNode node, final boolean checked) {
changeNodeState(node, checked);
if (!checked) {
TreeNode parent = node.getParent();
while (parent != null) {
if (parent instanceof CheckedTreeNode) {
changeNodeState((CheckedTreeNode)parent, false);
}
parent = parent.getParent();
}
uncheckChildren(node);
}
else {
checkChildren(node);
}
repaint();
}
private static void changeNodeState(final CheckedTreeNode node, final boolean checked) {
if (node.isChecked() != checked) {
node.setChecked(checked);
}
}
private static 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 static 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);
}
}.installOn(mainComponent);
}
@SuppressWarnings("unchecked")
public <T> T[] getCheckedNodes(final Class<T> nodeType) {
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 = getTree().getModel().getRoot();
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());
throw new IllegalStateException(
"The root must be instance of the " + CheckedTreeNode.class.getName() + ": " + root.getClass().getName());
}
new Object() {
@SuppressWarnings("unchecked")
@@ -191,6 +213,7 @@ public class CheckboxTreeTable extends TreeTableView {
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);
}
}
@@ -0,0 +1,31 @@
/*
* 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;
import java.util.EventListener;
/**
* @author nik
*/
public interface CheckboxTreeListener extends EventListener {
void mouseDoubleClicked(@NotNull CheckedTreeNode node);
void nodeStateChanged(@NotNull CheckedTreeNode node);
void beforeNodeStateChanged(@NotNull CheckedTreeNode node);
}
@@ -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));
@@ -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);
}
}
@@ -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);
@@ -44,6 +44,7 @@ import java.util.List;
*/
public class JBEditorTabs extends JBTabsImpl {
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();
@@ -60,6 +61,13 @@ public class JBEditorTabs extends JBTabsImpl {
return super.createSingleRowLayout();
}
@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;
@@ -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();
@@ -73,8 +73,9 @@ public class CompareClipboardWithSelection extends BaseDiffAction {
SelectionModel selectionModel = myEditor.getSelectionModel();
if (selectionModel.hasSelection()) {
TextRange range = new TextRange(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
boolean forceReadOnly = myEditor.isViewer();
myContents[1] = new FragmentContent(DiffContent.fromDocument(getProject(), getDocument()),
range, getProject(), getDocumentFile(getDocument()));
range, getProject(), getDocumentFile(getDocument()), forceReadOnly);
}
else {
myContents [1] = DiffContent.fromDocument(getProject(), getDocument());
@@ -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.
@@ -19,6 +19,7 @@ import com.intellij.openapi.diff.impl.highlighting.DiffPanelState;
import com.intellij.openapi.diff.impl.splitter.DiffDividerPaint;
import com.intellij.openapi.editor.event.VisibleAreaEvent;
import com.intellij.openapi.editor.event.VisibleAreaListener;
import com.intellij.openapi.ui.Divider;
import com.intellij.openapi.ui.Splitter;
import javax.swing.*;
@@ -43,8 +44,8 @@ class DiffSplitter extends Splitter implements DiffSplitterI {
setHonorComponentsMinimumSize(false);
}
protected Splitter.Divider createDivider() {
return new Divider(){
protected Divider createDivider() {
return new DividerImpl(){
public void paint(Graphics g) {
super.paint(g);
myPaint.paint(g, this);
@@ -277,6 +277,8 @@ public final class EditorTabbedContainer implements Disposable, CloseAction.Clos
myTabs.getTabAt(index).setTooltipText(text);
}
public boolean isTitleShortened(int index) { return myTabs.getTabAt(index).isTitleShortened(); }
public void setBackgroundColorAt(final int index, final Color color) {
myTabs.getTabAt(index).setTabColor(color);
}
@@ -464,6 +464,10 @@ public class EditorWindow {
}
}
private boolean isTitleShortenedAt(int index) {
return myTabbedPane != null && myTabbedPane.isTitleShortened(index);
}
private void setBackgroundColorAt(final int index, final Color color) {
if (myTabbedPane != null) {
myTabbedPane.setBackgroundColorAt(index, color);
@@ -908,7 +912,9 @@ public class EditorWindow {
final int index = findEditorIndex(findFileComposite(file));
if (index != -1) {
setTitleAt(index, EditorTabbedContainer.calcTabTitle(getManager().getProject(), file));
setToolTipTextAt(index, UISettings.getInstance().SHOW_TABS_TOOLTIPS ? getManager().getFileTooltipText(file) : null);
setToolTipTextAt(index, UISettings.getInstance().SHOW_TABS_TOOLTIPS || isTitleShortenedAt(index)
? getManager().getFileTooltipText(file)
: null);
}
}
@@ -278,19 +278,22 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
}
protected void setStateImpl(final Project project, final Editor editor, final TextEditorState state){
if (editor.getCaretModel().supportsMultipleCarets()) {
CaretModel caretModel = editor.getCaretModel();
List<CaretState> states = new ArrayList<CaretState>(state.CARETS.length);
for (TextEditorState.CaretState caretState : state.CARETS) {
states.add(new CaretState(new LogicalPosition(caretState.LINE, caretState.COLUMN),
new LogicalPosition(caretState.SELECTION_START_LINE, caretState.SELECTION_START_COLUMN),
new LogicalPosition(caretState.SELECTION_END_LINE, caretState.SELECTION_END_COLUMN)));
if (state.CARETS != null) {
if (editor.getCaretModel().supportsMultipleCarets()) {
CaretModel caretModel = editor.getCaretModel();
List<CaretState> states = new ArrayList<CaretState>(state.CARETS.length);
for (TextEditorState.CaretState caretState : state.CARETS) {
states.add(new CaretState(new LogicalPosition(caretState.LINE, caretState.COLUMN),
new LogicalPosition(caretState.SELECTION_START_LINE, caretState.SELECTION_START_COLUMN),
new LogicalPosition(caretState.SELECTION_END_LINE, caretState.SELECTION_END_COLUMN)));
}
caretModel.setCaretsAndSelections(states);
}
else {
LogicalPosition pos = new LogicalPosition(state.CARETS[0].LINE, state.CARETS[0].COLUMN);
editor.getCaretModel().moveToLogicalPosition(pos);
editor.getSelectionModel().removeSelection();
}
caretModel.setCaretsAndSelections(states);
} else {
LogicalPosition pos = new LogicalPosition(state.CARETS[0].LINE, state.CARETS[0].COLUMN);
editor.getCaretModel().moveToLogicalPosition(pos);
editor.getSelectionModel().removeSelection();
}
EditorEx editorEx = editor instanceof EditorEx ? (EditorEx)editor : null;
boolean preciselyScrollVertically =
@@ -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.
@@ -21,8 +21,8 @@ import com.intellij.ide.dnd.DnDAware;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.Divider;
import com.intellij.openapi.ui.Painter;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.ui.impl.GlassPaneDialogWrapperPeer;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
@@ -381,7 +381,7 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent
private boolean canProcessCursorFor(Component target) {
if (target instanceof JMenu ||
target instanceof JMenuItem ||
target instanceof Splitter.Divider ||
target instanceof Divider ||
target instanceof JSeparator ||
(target instanceof JEditorPane && ((JEditorPane)target).getEditorKit() instanceof HTMLEditorKit)) {
return false;
@@ -15,8 +15,6 @@
*/
package com.intellij.ui;
import java.awt.event.KeyEvent;
/**
* User: lex
* Date: Sep 18, 2003
@@ -56,11 +54,4 @@ public class CheckboxTree extends CheckboxTreeBase {
protected void installSpeedSearch() {
new TreeSpeedSearch(this);
}
protected boolean isToggleEvent(KeyEvent e) {
return super.isToggleEvent(e) && !SpeedSearchBase.hasActiveSpeedSearch(this);
}
}
@@ -0,0 +1,47 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ui;
import com.intellij.ui.dualView.TreeTableView;
import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
import com.intellij.ui.treeStructure.treetable.TreeTableTree;
import com.intellij.util.EventDispatcher;
import com.intellij.util.ui.ColumnInfo;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class CheckboxTreeTable extends TreeTableView {
private final EventDispatcher<CheckboxTreeListener> myEventDispatcher;
public CheckboxTreeTable(CheckedTreeNode root, CheckboxTree.CheckboxTreeCellRenderer renderer, final ColumnInfo[] columns) {
super(new ListTreeTableModelOnColumns(root, columns));
final TreeTableTree tree = getTree();
myEventDispatcher = EventDispatcher.create(CheckboxTreeListener.class);
CheckboxTreeHelper helper = new CheckboxTreeHelper(CheckboxTreeHelper.DEFAULT_POLICY, myEventDispatcher);
helper.initTree(tree, this, renderer);
tree.setSelectionRow(0);
}
public void addCheckboxTreeListener(@NotNull CheckboxTreeListener listener) {
myEventDispatcher.addListener(listener);
}
public <T> T[] getCheckedNodes(final Class<T> nodeType) {
return CheckboxTreeHelper.getCheckedNodes(nodeType, null, getTree().getModel());
}
}
@@ -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.
@@ -16,6 +16,7 @@
package com.intellij.ui;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.ui.Divider;
import com.intellij.openapi.ui.PseudoSplitter;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.vcs.changes.RefreshablePanel;
@@ -41,7 +42,7 @@ public abstract class SplitterWithSecondHideable {
private final boolean myVertical;
private final OnOffListener<Integer> myListener;
private final JPanel myFictivePanel;
private Splitter.Divider mySuperDivider;
private Splitter.DividerImpl mySuperDivider;
private float myPreviousProportion;
public SplitterWithSecondHideable(final boolean vertical,
@@ -185,7 +186,7 @@ public abstract class SplitterWithSecondHideable {
return vertical ? myTitledSeparator.getHeight() : myTitledSeparator.getWidth();
}
class MyDivider extends Divider {
class MyDivider extends DividerImpl {
@Override
public void processMouseMotionEvent(MouseEvent e) {
super.processMouseMotionEvent(e);
@@ -360,6 +360,7 @@ label.collapse.by.default=Collapse by default:
checkbox.show.code.folding.outline=Show code folding outline
group.tab.appearance=Tab Appearance
editbox.tab.limit=Tab limit:
editbox.tab.title.limit=Tab title limit:
combobox.editor.tab.placement=Placement:
checkbox.editor.tabs.in.single.row=Show tabs in single row
checkbox.editor.tabs.show.close.button=Show "close" button on editor tabs
@@ -312,6 +312,10 @@
<keyboard-shortcut first-keystroke="meta 3"/>
</action>
<action id="Vcs.RollbackChangedLines">
<keyboard-shortcut first-keystroke="control shift alt Z"/>
</action>
<action id="ActivateProjectToolWindow"/>
<action id="ActivateFavoritesToolWindow"/>
<action id="ActivateFindToolWindow">
@@ -82,7 +82,7 @@ public abstract class CompiledPattern {
public boolean isRealTypedVar(PsiElement element) {
if (element!=null && element.getTextLength()>0) {
String str = getTypedVarString(element);
if (str.length()==0) {
if (str == null || str.length()==0) {
return false;
}
return isTypedVar( str );
@@ -204,7 +204,7 @@ public class ChunkExtractor {
highlighter.restart(chars);
myDocumentStamp = myDocument.getModificationStamp();
} else if(lexer.getTokenStart() > start) {
highlighter.resetPosition(0);
highlighter.resetPosition(0); // todo restart from nearest position with initial state
}
boolean isBeginning = true;
@@ -40,10 +40,7 @@ import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewBundle;
import com.intellij.usages.impl.rules.UsageType;
import com.intellij.usages.rules.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.NotNullFunction;
import com.intellij.util.Processor;
import com.intellij.util.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -80,7 +77,8 @@ public class UsageInfo2UsageAdapter implements UsageInModule,
private final int myLineNumber;
private final int myOffset;
protected Icon myIcon;
private Reference<TextChunk[]> myTextChunks; // allow to be gced and recreated on-demand because it requires a lot of memory
private volatile Reference<TextChunk[]> myTextChunks; // allow to be gced and recreated on-demand because it requires a lot of memory
private volatile UsageType myUsageType;
public UsageInfo2UsageAdapter(@NotNull final UsageInfo usageInfo) {
myUsageInfo = usageInfo;
@@ -337,7 +335,7 @@ public class UsageInfo2UsageAdapter implements UsageInModule,
UsageInfo[] merged = ArrayUtil.mergeArrays(getMergedInfos(), u2.getMergedInfos());
myMergedUsageInfos = merged.length == 1 ? merged[0] : merged;
Arrays.sort(getMergedInfos(), BY_NAVIGATION_OFFSET);
initChunks();
myTextChunks = null; // chunks will be rebuilt lazily (IDEA-126048)
return true;
}
@@ -496,13 +494,42 @@ public class UsageInfo2UsageAdapter implements UsageInModule,
}
public @Nullable UsageType getUsageType() {
TextChunk[] chunks = getText();
for(TextChunk chunk:chunks) {
UsageType type = chunk.getType();
if (type != null) {
return type;
UsageType usageType = myUsageType;
if (usageType == null) {
usageType = UsageType.UNCLASSIFIED;
PsiFile file = getPsiFile();
if (file != null) {
ChunkExtractor extractor = ChunkExtractor.getExtractor(file);
Segment segment = getFirstSegment();
if (segment != null) {
Document document = PsiDocumentManager.getInstance(getProject()).getDocument(file);
if (document != null) {
SmartList<TextChunk> chunks = new SmartList<TextChunk>();
extractor.createTextChunks(
this,
document.getCharsSequence(),
segment.getStartOffset(),
segment.getEndOffset(),
false,
chunks
);
for(TextChunk chunk:chunks) {
UsageType chunkUsageType = chunk.getType();
if (chunkUsageType != null) {
usageType = chunkUsageType;
break;
}
}
}
}
}
myUsageType = usageType;
}
return null;
return usageType;
}
}
@@ -388,7 +388,7 @@ console.too.much.text.buffer.ratio.description=Used for disabling of console pro
when there is too much of text to process.\n\
The ratio is used against the console cycle buffer size (idea.cycle.buffer.size/theRatio=maxTextLength).
ide.file.settings.order.new=false
ide.new.project.settings=false
ide.new.project.settings=true
ide.new.project.settings.description=Temporary key for new project settings dialog UI
commonjs.complete.required.filename.with.extension=false
@@ -0,0 +1,34 @@
/*
* 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 javax.swing.*;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public abstract class Divider extends JPanel {
public Divider(LayoutManager layout) {
super(layout);
}
public abstract void setResizeEnabled(boolean resizeEnabled);
public abstract void setSwitchOrientationEnabled(boolean switchOrientationEnabled);
public abstract void setOrientation(boolean vertical);
}
@@ -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.
@@ -177,7 +177,7 @@ public class Splitter extends JPanel {
}
protected Divider createDivider() {
return new Divider();
return new DividerImpl();
}
@Override
@@ -481,12 +481,12 @@ public class Splitter extends JPanel {
return myDivider;
}
public class Divider extends JPanel {
public class DividerImpl extends Divider {
private boolean myResizeEnabled;
private boolean mySwitchOrientationEnabled;
protected Point myPoint;
public Divider() {
public DividerImpl() {
super(new GridBagLayout());
myResizeEnabled = true;
mySwitchOrientationEnabled = false;
@@ -496,7 +496,7 @@ public class Splitter extends JPanel {
setOrientation(myVerticalSplit);
}
private void setOrientation(boolean isVerticalSplit) {
public void setOrientation(boolean isVerticalSplit) {
removeAll();
setCursor(isVertical() ?
@@ -2658,6 +2658,56 @@ public class StringUtil extends StringUtilRt {
return s.startsWith(smallPart.toLowerCase()) && bigPart.toLowerCase().startsWith(s);
}
public static String getShortened(String s, int maxWidth) {
int length = s.length();
if (isEmpty(s) || length <= maxWidth) return s;
ArrayList<String> words = new ArrayList<String>();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < length; i++) {
char ch = s.charAt(i);
if (i == length - 1) {
builder.append(ch);
words.add(builder.toString());
builder.delete(0, builder.length());
continue;
}
if (i > 0 && (ch == '/' || ch == '.' || Character.isUpperCase(ch))) {
words.add(builder.toString());
builder.delete(0, builder.length());
}
builder.append(ch);
}
int removedLength = 0;
String toPaste = "...";
int index;
while (true) {
index = Math.max(0, words.size() / 2 - 1);
String aWord = words.get(index);
words.remove(index);
if (words.size() < 2) {
int toCut = length - removedLength - maxWidth + 3;
int pos = (aWord.length() - toCut) / 2;
toPaste = aWord.substring(0, pos) + "..." + aWord.substring(pos+toCut);
break;
}
removedLength += aWord.length();
if (length - removedLength <= maxWidth - 3) {
break;
}
}
for (int i = 0; i < words.size(); i++) {
String word = words.get(i);
if (i == index || words.size() == 1) builder.append(toPaste);
builder.append(word);
}
return builder.toString().replaceAll("\\.{4,}", "...");
}
/**
* Expirable CharSequence. Very useful to control external library execution time,
* i.e. when java.util.regex.Pattern match goes out of control.
@@ -195,4 +195,15 @@ public class StringUtilTest extends TestCase {
assertEquals(Arrays.asList("\n", "\r\n", "\n", "\r\n", "\r", "\r", "aa\r", "bb\r\n", "cc\n", "\r", "dd\n", "\n", "\r\n", "\r"),
Arrays.asList(StringUtil.splitByLinesKeepSeparators("\n\r\n\n\r\n\r\raa\rbb\r\ncc\n\rdd\n\n\r\n\r")));
}
public void testShortened() {
String[] names = {"AVeryVeeryLongClassName.java", "com.test.SomeJAVAClassName.java", "strangelowercaseclassname.java"};
for (String name : names) {
for (int i = name.length() + 1; i > 15; i--) {
String shortened = StringUtil.getShortened(name, i);
assertTrue(shortened.length() <= i);
assertTrue(!shortened.contains("...."));
}
}
}
}
@@ -272,7 +272,7 @@ public abstract class ProjectLevelVcsManager {
public abstract VcsHistoryCache getVcsHistoryCache();
public abstract ContentRevisionCache getContentRevisionCache();
public abstract boolean isFileInContent(final VirtualFile vf);
public abstract boolean isIgnoredByVcs(VirtualFile vf);
public abstract boolean isIgnored(VirtualFile vf);
public abstract boolean dvcsUsedInProject();
@@ -173,7 +173,7 @@ public class LocalChangeListImpl extends LocalChangeList {
return false;
}
VirtualFile vFile = revision.getFile().getVirtualFile();
return vFile != null && ProjectLevelVcsManager.getInstance(project).isIgnoredByVcs(vFile);
return vFile != null && ProjectLevelVcsManager.getInstance(project).isIgnored(vFile);
}
});
}
@@ -121,7 +121,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder {
@Override
public Boolean compute() {
checkIfDisposed();
return myVcsManager.isIgnoredByVcs(file);
return myVcsManager.isIgnored(file);
}
});
}
@@ -73,7 +73,7 @@ public class VcsGuess {
final boolean inContent = myVcsManager.isFileInContent(validParent);
if (inContent) return true;
if (filePath != null) {
return isFileInBaseDir(filePath, myProject.getBaseDir()) && !myVcsManager.isIgnoredByVcs(validParent);
return isFileInBaseDir(filePath, myProject.getBaseDir()) && !myVcsManager.isIgnored(validParent);
}
return false;
}
@@ -845,13 +845,13 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme
return vf != null && (myExcludedIndex.isInContent(vf) || isFileInBaseDir(vf) || vf.equals(myProject.getBaseDir()) ||
hasExplicitMapping(vf) || isInDirectoryBasedRoot(vf)
|| !Registry.is("ide.hide.excluded.files") && myExcludedIndex.isExcludedFile(vf))
&& !isIgnoredByVcs(vf);
&& !isIgnored(vf);
}
});
}
@Override
public boolean isIgnoredByVcs(VirtualFile vf) {
public boolean isIgnored(VirtualFile vf) {
if (Registry.is("ide.hide.excluded.files")) {
return myExcludedIndex.isExcludedFile(vf);
}
@@ -67,7 +67,7 @@ public class VcsRootIterator {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
return !project.isDisposed() && vcsManager.isIgnoredByVcs(file);
return !project.isDisposed() && vcsManager.isIgnored(file);
}
});
}
@@ -234,7 +234,7 @@ public class NewMappings {
@Nullable
public VcsDirectoryMapping getMappingFor(final VirtualFile file, final Object parentModule) {
// if parentModule is not null it means that file belongs to the module so it isn't excluded
if (parentModule == null && myVcsManager.isIgnoredByVcs(file)) {
if (parentModule == null && myVcsManager.isIgnored(file)) {
return null;
}
@@ -91,7 +91,7 @@ public class XDebugSessionImpl implements XDebugSession {
private XDebugProcess myDebugProcess;
private final Map<XBreakpoint<?>, CustomizedBreakpointPresentation> myRegisteredBreakpoints =
new THashMap<XBreakpoint<?>, CustomizedBreakpointPresentation>();
private final Set<XBreakpoint<?>> myInactiveSlaveBreakpoints = new SmartHashSet<XBreakpoint<?>>();
private final Set<XBreakpoint<?>> myInactiveSlaveBreakpoints = Collections.synchronizedSet(new SmartHashSet<XBreakpoint<?>>());
private boolean myBreakpointsDisabled;
private final XDebuggerManagerImpl myDebuggerManager;
private MyBreakpointListener myBreakpointListener;
@@ -295,12 +295,15 @@ public class XDebugSessionImpl implements XDebugSession {
XBreakpointManagerImpl breakpointManager = myDebuggerManager.getBreakpointManager();
XDependentBreakpointManager dependentBreakpointManager = breakpointManager.getDependentBreakpointManager();
disableSlaveBreakpoints(dependentBreakpointManager);
processAllBreakpoints(true, false);
// listeners have to be applied before processing all existing breakpoints,
// otherwise we may not process breakpoints added during the processing
myBreakpointListener = new MyBreakpointListener();
breakpointManager.addBreakpointListener(myBreakpointListener);
myDependentBreakpointListener = new MyDependentBreakpointListener();
dependentBreakpointManager.addListener(myDependentBreakpointListener);
processAllBreakpoints(true, false);
}
@Override
@@ -15,6 +15,7 @@
*/
package com.intellij.xdebugger.impl.actions.handlers;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.impl.actions.XDebuggerSuspendedActionHandler;
import com.intellij.xdebugger.impl.XDebuggerUtilImpl;
import com.intellij.xdebugger.XDebugSession;
@@ -33,7 +34,9 @@ public class XDebuggerRunToCursorActionHandler extends XDebuggerSuspendedActionH
}
protected boolean isEnabled(final @NotNull XDebugSession session, final DataContext dataContext) {
return super.isEnabled(session, dataContext) && XDebuggerUtilImpl.getCaretPosition(session.getProject(), dataContext) != null;
if (!super.isEnabled(session, dataContext)) return false;
XSourcePosition position = XDebuggerUtilImpl.getCaretPosition(session.getProject(), dataContext);
return position != null && XDebuggerUtil.getInstance().canPutBreakpointAt(session.getProject(), position.getFile(), position.getLine());
}
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
@@ -240,14 +240,15 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
@NotNull
public <B extends XBreakpoint<?>> Collection<? extends B> getBreakpoints(@NotNull final XBreakpointType<B,?> type) {
ApplicationManager.getApplication().assertReadAccessAllowed();
Collection<? extends XBreakpointBase<?,?,?>> breakpoints = myBreakpoints.get(type);
Collection<? extends B> regular = breakpoints != null ? Collections.unmodifiableCollection((Collection<? extends B>)breakpoints) : Collections.<B>emptyList();
final XBreakpointBase<?, ?, ?> defaultBreakpoint = myDefaultBreakpoints.get(type);
if (defaultBreakpoint == null) return regular;
List<B> result = new ArrayList<B>();
result.add((B)defaultBreakpoint);
result.addAll(regular);
B defaultBreakpoint = getDefaultBreakpoint(type);
if (defaultBreakpoint != null) {
result.add(defaultBreakpoint);
}
Collection<XBreakpointBase<?, ?, ?>> breakpoints = myBreakpoints.get(type);
if (breakpoints != null) {
result.addAll((Collection<? extends B>)breakpoints);
}
return result;
}
@@ -247,17 +247,17 @@ public class InjectorUtils {
// make sure comment is close enough and ...
int off1 = r0.getEndOffset();
int off2 = e2.getTextRange().getStartOffset();
if (off2 - off1 > 120) return null;
if (off2 - off1 > 2) {
// ... there's nothing in between on the top level and ...
for (PsiElement e = e1; e != e2; e = e.getNextSibling()) {
if (!isWhitespaceCommentOrBlank(e)) return null;
}
// ... there's no non-empty host in the left (comment) subtree
Producer<PsiElement> producer = prevWalker(PsiTreeUtil.getDeepestLast(e1), e1);
if (off2 - off1 > 120) {
return null;
}
else if (off2 - off1 > 2) {
// ... there's no non-empty valid host in between comment and e2
Producer<PsiElement> producer = prevWalker(e2, commonParent);
PsiElement e;
while ( (e = producer.produce()) != null && e != psiComment) {
if (e instanceof PsiLanguageInjectionHost && !StringUtil.isEmptyOrSpaces(e.getText())) {
if (e instanceof PsiLanguageInjectionHost &&
((PsiLanguageInjectionHost)e).isValidHost() &&
!StringUtil.isEmptyOrSpaces(e.getText())) {
return null;
}
}
@@ -268,11 +268,6 @@ public class InjectorUtils {
return new BaseInjection(supportId).copyFrom(entry.getValue());
}
protected static boolean isWhitespaceCommentOrBlank(PsiElement e) {
return e instanceof PsiWhiteSpace || e instanceof PsiComment ||
e instanceof PsiLanguageInjectionHost && StringUtil.isEmptyOrSpaces(e.getText());
}
@Nullable
private static TreeMap<TextRange, BaseInjection> getInjectionMap(@Nullable final PsiFile file) {
if (file == null) return null; // e.g. null for synthetic groovy variables
@@ -295,8 +290,6 @@ public class InjectorUtils {
CharSequence contents = file.getViewProvider().getContents();
final char[] contentsArray = CharArrayUtil.fromSequenceWithoutCopying(contents);
//long time = System.currentTimeMillis();
int s0 = 0, s1 = contents.length();
for (int idx = searcher.scan(contents, contentsArray, s0, s1);
idx != -1;
@@ -311,30 +304,6 @@ public class InjectorUtils {
}
}
}
//VirtualFile virtualFile = file.getVirtualFile();
//Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
//EditorHighlighter highlighter = EditorHighlighterCache.getEditorHighlighterForCachesBuilding(document);
//
//ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(file.getLanguage());
//TokenSet commentTokens = definition.getCommentTokens();
//HighlighterIterator it = highlighter != null && PlatformIdTableBuilding.checkCanUseCachedEditorHighlighter(contents, highlighter) ?
// highlighter.createIterator(0) : null;
//
//do {
// if (it != null) {
// while (!it.atEnd() && !commentTokens.contains(it.getTokenType())) it.advance();
// if (it.atEnd()) break;
// }
// int s0 = it == null ? 0 : it.getStart();
// int s1 = it == null ? contents.length() : it.getEnd();
//
// for () { .. }
//
// if (it != null && !it.atEnd()) it.advance();
//} while (it != null && !it.atEnd());
//System.out.println(Thread.currentThread().getName() + ": " + file.getName() + "@" + file.hashCode() + " indexed: " + (System.currentTimeMillis() - time));
return injectionMap;
}
@@ -375,18 +344,11 @@ public class InjectorUtils {
if (e == null || e == scope) return null;
PsiElement prev = e.getPrevSibling();
if (prev != null) {
e = prev;
while (true) {
PsiElement lastChild = e.getLastChild();
if (lastChild == null) break;
e = lastChild;
}
return e;
return e = PsiTreeUtil.getDeepestLast(prev);
}
else {
PsiElement parent = e.getParent();
e = parent == scope || parent instanceof PsiFile ? null : parent;
return e;
return e = parent == scope || parent instanceof PsiFile ? null : parent;
}
}
};
@@ -164,7 +164,7 @@ public class CvsChangeProvider implements ChangeProvider {
for (VirtualFile file : children) {
progress.checkCanceled();
if (file.isDirectory()) {
final boolean isIgnored = myVcsManager.isIgnoredByVcs(file);
final boolean isIgnored = myVcsManager.isIgnored(file);
if (!isIgnored) {
processEntriesIn(file, scope, builder, true, progress);
}
@@ -256,6 +256,6 @@ public class ImportTree extends NodeRenderer {
}
private boolean isIgnoredByVcs(VirtualFile vFile) {
return myProject != null && ProjectLevelVcsManager.getInstance(myProject).isIgnoredByVcs(vFile);
return myProject != null && ProjectLevelVcsManager.getInstance(myProject).isIgnored(vFile);
}
}
@@ -164,6 +164,7 @@ public class PrepareToDeployAction extends AnAction {
else {
FileUtil.copy(jarFile, dstFile);
}
LocalFileSystem.getInstance().refreshIoFiles(Collections.singleton(dstFile), true, false, null);
successMessages.add(DevKitBundle.message("saved.message", isZip ? 1 : 2, pluginName, dstPath));
}
catch (final IOException e) {
@@ -354,7 +354,7 @@ public class GithubShareAction extends DumbAwareAction {
return ContainerUtil.filter(files, new Condition<VirtualFile>() {
@Override
public boolean value(VirtualFile file) {
return !changeListManager.isIgnoredFile(file) && !vcsManager.isIgnoredByVcs(file);
return !changeListManager.isIgnoredFile(file) && !vcsManager.isIgnored(file);
}
});
}
@@ -79,7 +79,7 @@ public class StatusWalkerPartner {
@Override
public Boolean compute() {
if (myVcs.getProject().isDisposed()) throw new ProcessCanceledException();
return myVcsManager.isIgnoredByVcs(vFile);
return myVcsManager.isIgnored(vFile);
}
});
}
@@ -70,7 +70,7 @@ public class SvnExcludingIgnoredOperation {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
return myVcsManager.isIgnoredByVcs(file);
return myVcsManager.isIgnored(file);
}
});
}
+6 -2
View File
@@ -141,7 +141,11 @@ class _BehaveRunner(_bdd_utils.BddRunner):
elif element.status == 'passed':
self._test_passed(element.name, element.duration)
elif element.status == 'failed':
self._test_failed(element.name, element.error_message, traceback.format_exc())
try:
trace = traceback.format_exc()
except Exception:
trace = "".join(traceback.format_tb(element.exc_traceback))
self._test_failed(element.name, element.error_message, trace)
elif element.status == 'undefined':
self._test_undefined(element.name, element.location)
else:
@@ -231,7 +235,7 @@ if __name__ == "__main__":
if not my_config.paths: # No path provided, trying to load dit manually
if os.path.isfile(what_to_run): # File is provided, load it
my_config.paths = [what_to_run]
else: # Dir is provided, find subdirs ro run
else: # Dir is provided, find subdirs ro run
my_config.paths = _get_dirs_to_run(base_dir)
_BehaveRunner(my_config, base_dir).run()
@@ -0,0 +1,55 @@
package com.jetbrains.python;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.codeInsight.imports.AddImportHelper;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.PyElementGenerator;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyImportStatementBase;
import org.jetbrains.annotations.NotNull;
/**
* Quick fix that adds import to file
*
* @author Ilya.Kazakevich
*/
public class PyAddImportFix implements LocalQuickFix {
@NotNull
private final String myImportToAdd;
@NotNull
private final PyFile myFile;
/**
* @param importToAdd string representing what to add (i.e. "from foo import bar")
* @param file where to add
*/
public PyAddImportFix(@NotNull final String importToAdd, @NotNull final PyFile file) {
myImportToAdd = importToAdd;
myFile = file;
}
@NotNull
@Override
public String getName() {
return PyBundle.message("QFIX.add.import", myImportToAdd);
}
@NotNull
@Override
public String getFamilyName() {
return getName();
}
@Override
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
final PyElementGenerator generator = PyElementGenerator.getInstance(project);
final PyImportStatementBase statement =
generator.createFromText(LanguageLevel.forElement(myFile), PyImportStatementBase.class, myImportToAdd);
final PsiElement recommendedPosition = AddImportHelper.getFileInsertPosition(myFile);
myFile.addAfter(statement, recommendedPosition);
}
}
@@ -32,6 +32,8 @@ QFIX.create.property=Create property
QFIX.add.encoding=Add encoding declaration
QFIX.add.import=Add "''{0}''"
QFIX.NAME.parameters=Parameters of functions and methods
QFIX.rename.parameter.to.$0=Rename to ''{0}''
@@ -1645,6 +1645,11 @@ public class PyUtil {
return Collections2.filter(pyMemberInfos, new ObjectPredicate(false));
}
public static boolean isStarImportableFrom(@NotNull String name, @NotNull PyFile file) {
final List<String> dunderAll = file.getDunderAll();
return dunderAll != null ? dunderAll.contains(name) : !name.startsWith("_");
}
/**
* Filters only pyclass object (new class)
*/
@@ -477,8 +477,9 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
if (starImportSource != null) {
starImportSource = PyUtil.turnDirIntoInit(starImportSource);
if (starImportSource instanceof PyFile) {
final PsiElement result = ((PyFile)starImportSource).getElementNamed(name);
if (result != null) {
final PyFile file = (PyFile)starImportSource;
final PsiElement result = file.getElementNamed(name);
if (result != null && PyUtil.isStarImportableFrom(name, file)) {
return result;
}
}
@@ -52,11 +52,8 @@ public class PyStarImportElementImpl extends PyElementImpl implements PyStarImpo
for (PsiElement importedFile : new HashSet<PsiElement>(importedFiles)) { // resolver gives lots of duplicates
final PsiElement source = PyUtil.turnDirIntoInit(importedFile);
if (source instanceof PyFile) {
Iterable<PyElement> declaredNames = ((PyFile)source).iterateNames();
if (((PyFile)source).getDunderAll() == null) {
declaredNames = excludeUnderscoredNames(declaredNames);
}
chain.add(declaredNames);
final PyFile sourceFile = (PyFile)source;
chain.add(filterStarImportableNames(sourceFile.iterateNames(), sourceFile));
}
}
return chain;
@@ -64,15 +61,13 @@ public class PyStarImportElementImpl extends PyElementImpl implements PyStarImpo
return Collections.emptyList();
}
private static Iterable<PyElement> excludeUnderscoredNames(Iterable<PyElement> declaredNames) {
@NotNull
private static Iterable<PyElement> filterStarImportableNames(@NotNull Iterable<PyElement> declaredNames, @NotNull final PyFile file) {
return Iterables.filter(declaredNames, new Predicate<PyElement>() {
@Override
public boolean apply(@Nullable PyElement input) {
final String name = input != null ? input.getName() : null;
if (name != null && name.startsWith("_")) {
return false;
}
return true;
return name != null && PyUtil.isStarImportableFrom(name, file);
}
});
}
@@ -93,11 +88,7 @@ public class PyStarImportElementImpl extends PyElementImpl implements PyStarImpo
final List<? extends RatedResolveResult> results = moduleType.resolveMember(name, null, AccessDirection.READ,
PyResolveContext.defaultContext());
final PsiElement result = results != null && !results.isEmpty() ? results.get(0).getElement() : null;
if (result != null) {
final List<String> all = sourceFile.getDunderAll();
if (all != null ? !all.contains(name) : name.startsWith("_")) {
continue;
}
if (result != null && PyUtil.isStarImportableFrom(name, sourceFile) ) {
return result;
}
}
@@ -0,0 +1,3 @@
import b
<warning descr="Unused import statement">from p1 import *</warning>
print(b)
@@ -376,6 +376,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase {
doMultiFileTest();
}
// PY-13585
public void testUnusedImportBeforeStarDunderAll() {
doMultiFileTest();
}
@NotNull
@Override
protected Class<? extends PyInspection> getInspectionClass() {