diff options
Diffstat (limited to 'platform/platform-api')
33 files changed, 658 insertions, 268 deletions
diff --git a/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java b/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java new file mode 100644 index 000000000000..7d972816769c --- /dev/null +++ b/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java @@ -0,0 +1,127 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.codeInsight.editorActions; + +import com.intellij.openapi.editor.RawText; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class TextBlockTransferable implements Transferable { + private final Collection<TextBlockTransferableData> myExtraData; + private final RawText myRawText; + private final String myText; + private final DataFlavor[] myTransferDataFlavors; + + public TextBlockTransferable(String text, Collection<TextBlockTransferableData> extraData, RawText rawText) { + myText = text; + myExtraData = extraData; + myRawText = rawText; + + List<DataFlavor> dataFlavors = new ArrayList<DataFlavor>(); + Collections.addAll(dataFlavors, DataFlavor.stringFlavor, DataFlavor.plainTextFlavor); + final DataFlavor flavor = RawText.getDataFlavor(); + if (myRawText != null && flavor != null) { + dataFlavors.add(flavor); + } + for(TextBlockTransferableData data: extraData) { + final DataFlavor blockFlavor = data.getFlavor(); + if (blockFlavor != null) { + dataFlavors.add(blockFlavor); + } + } + myTransferDataFlavors = dataFlavors.toArray(new DataFlavor[dataFlavors.size()]); + } + + @Override + public DataFlavor[] getTransferDataFlavors() { + return myTransferDataFlavors; + } + + @Override + public boolean isDataFlavorSupported(DataFlavor flavor) { + DataFlavor[] flavors = getTransferDataFlavors(); + for (DataFlavor flavor1 : flavors) { + if (flavor.equals(flavor1)) { + return true; + } + } + return false; + } + + @Override + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + try { + for(TextBlockTransferableData data: myExtraData) { + if (Comparing.equal(data.getFlavor(), flavor)) { + return data; + } + } + if (myRawText != null && Comparing.equal(RawText.getDataFlavor(), flavor)) { + return myRawText; + } + else if (DataFlavor.stringFlavor.equals(flavor)) { + return myText; + } + else if (DataFlavor.plainTextFlavor.equals(flavor)) { + return new StringReader(myText); + } + } + catch(NoClassDefFoundError e) { + // ignore + } + throw new UnsupportedFlavorException(flavor); + } + + public static String convertLineSeparators(String text, + String newSeparator, + Collection<TextBlockTransferableData> transferableDatas) { + if (transferableDatas.size() > 0){ + int size = 0; + for(TextBlockTransferableData data: transferableDatas) { + size += data.getOffsetCount(); + } + + int[] offsets = new int[size]; + int index = 0; + for(TextBlockTransferableData data: transferableDatas) { + index = data.getOffsets(offsets, index); + } + + text = StringUtil.convertLineSeparators(text, newSeparator, offsets); + + index = 0; + for(TextBlockTransferableData data: transferableDatas) { + index = data.setOffsets(offsets, index); + } + + return text; + } + else{ + return StringUtil.convertLineSeparators(text, newSeparator); + } + } +}
\ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java b/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java new file mode 100644 index 000000000000..bdaf6f2ea546 --- /dev/null +++ b/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.codeInsight.editorActions; + +import java.awt.datatransfer.DataFlavor; + +/** + * @author yole + */ +public interface TextBlockTransferableData { + DataFlavor getFlavor(); + + int getOffsetCount(); + int getOffsets(final int[] offsets, final int index); + int setOffsets(final int[] offsets, final int index); +} diff --git a/platform/platform-api/src/com/intellij/codeStyle/CodeStyleFacade.java b/platform/platform-api/src/com/intellij/codeStyle/CodeStyleFacade.java index 8b424cce0ca4..0bc7ed42febb 100644 --- a/platform/platform-api/src/com/intellij/codeStyle/CodeStyleFacade.java +++ b/platform/platform-api/src/com/intellij/codeStyle/CodeStyleFacade.java @@ -19,6 +19,7 @@ */ package com.intellij.codeStyle; +import com.intellij.lang.Language; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileTypes.FileType; @@ -53,7 +54,7 @@ public abstract class CodeStyleFacade { public abstract boolean isSmartTabs(final FileType fileType); - public abstract int getRightMargin(); + public abstract int getRightMargin(Language language); public abstract boolean isWrapWhenTypingReachesRightMargin(); diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java index d4ac053e994e..1d4fea4c01de 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java @@ -50,6 +50,8 @@ public interface IdeActions { @NonNls String ACTION_EDITOR_COMPLETE_STATEMENT = "EditorCompleteStatement"; @NonNls String ACTION_EDITOR_USE_SOFT_WRAPS = "EditorToggleUseSoftWraps"; @NonNls String ACTION_EDITOR_ADD_OR_REMOVE_CARET= "EditorAddOrRemoveCaret"; + @NonNls String ACTION_EDITOR_CLONE_CARET_BELOW= "EditorCloneCaretBelow"; + @NonNls String ACTION_EDITOR_CLONE_CARET_ABOVE= "EditorCloneCaretAbove"; @NonNls String ACTION_EDITOR_NEXT_TEMPLATE_VARIABLE = "NextTemplateVariable"; @NonNls String ACTION_EDITOR_PREVIOUS_TEMPLATE_VARIABLE = "PreviousTemplateVariable"; @@ -267,6 +269,7 @@ public interface IdeActions { String ACTION_UNDO = "$Undo"; String ACTION_REDO = "$Redo"; String GROUP_REFACTOR = "RefactoringMenu"; + String SELECTED_CHANGES_ROLLBACK = "RollbackLineStatusChanges"; String CHANGES_VIEW_ROLLBACK = "ChangesView.Rollback"; String CONSOLE_CLEAR_ALL = "ConsoleView.ClearAll"; diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java index e72428804ee4..92a1d9c8b42c 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java @@ -47,6 +47,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent private static final Icon DISABLED_ARROW_ICON = IconLoader.getDisabledIcon(ARROW_ICON); private boolean mySmallVariant = true; + private String myPopupTitle; private DataContext myDataContext; protected ComboBoxAction() { @@ -77,6 +78,10 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent mySmallVariant = smallVariant; } + public void setPopupTitle(String popupTitle) { + myPopupTitle = popupTitle; + } + @Override public void update(AnActionEvent e) { super.update(e); @@ -247,7 +252,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent DataContext context = getDataContext(); myDataContext = null; final ListPopup popup = JBPopupFactory.getInstance().createActionGroupPopup( - null, group, context, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false, onDispose, getMaxRows()); + myPopupTitle, group, context, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false, onDispose, getMaxRows()); popup.setMinimumSize(new Dimension(getMinWidth(), getMinHeight())); return popup; } diff --git a/platform/platform-api/src/com/intellij/openapi/editor/CaretStateTransferableData.java b/platform/platform-api/src/com/intellij/openapi/editor/CaretStateTransferableData.java new file mode 100644 index 000000000000..f0d2085cbb6b --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/editor/CaretStateTransferableData.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.editor; + +import com.intellij.codeInsight.editorActions.TextBlockTransferableData; + +import java.awt.datatransfer.DataFlavor; + +public class CaretStateTransferableData implements TextBlockTransferableData { + public static final DataFlavor FLAVOR = new DataFlavor(CaretStateTransferableData.class, "Caret state"); + + public final int[] startOffsets; + public final int[] endOffsets; + + public CaretStateTransferableData(int[] startOffsets, int[] endOffsets) { + this.startOffsets = startOffsets; + this.endOffsets = endOffsets; + } + + @Override + public DataFlavor getFlavor() { + return FLAVOR; + } + + @Override + public int getOffsetCount() { + return startOffsets.length + endOffsets.length; + } + + @Override + public int getOffsets(int[] offsets, int index) { + System.arraycopy(startOffsets, 0, offsets, index, startOffsets.length); + System.arraycopy(endOffsets, 0, offsets, index + startOffsets.length, endOffsets.length); + return index + getOffsetCount(); + } + + @Override + public int setOffsets(int[] offsets, int index) { + System.arraycopy(offsets, index, startOffsets, 0, startOffsets.length); + System.arraycopy(offsets, index + startOffsets.length, endOffsets, 0, endOffsets.length); + return index + getOffsetCount(); + } +} diff --git a/platform/platform-api/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java b/platform/platform-api/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java index afc58b818bce..a3e62412f4a4 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java @@ -15,12 +15,16 @@ */ package com.intellij.openapi.editor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ClipboardTextPerCaretSplitter { - public List<String> split(String input, int caretCount) { + @NotNull + public List<String> split(@NotNull String input, @Nullable CaretStateTransferableData caretData, int caretCount) { if (caretCount <= 0) { throw new IllegalArgumentException("Caret count must be positive"); } @@ -28,9 +32,17 @@ public class ClipboardTextPerCaretSplitter { return Collections.singletonList(input); } List<String> result = new ArrayList<String>(caretCount); - String[] lines = input.split("\n", -1); + int sourceCaretCount = caretData == null ? -1 : caretData.startOffsets.length; + String[] lines = sourceCaretCount == 1 || sourceCaretCount == caretCount ? null : input.split("\n", -1); for (int i = 0; i < caretCount; i++) { - if (lines.length == 0) { + if (sourceCaretCount == 1) { + result.add(input); + } + else if (sourceCaretCount == caretCount) { + //noinspection ConstantConditions + result.add(new String(input.substring(caretData.startOffsets[i], caretData.endOffsets[i]))); + } + else if (lines.length == 0) { result.add(""); } else if (lines.length == 1) { diff --git a/platform/platform-api/src/com/intellij/openapi/editor/CopyPasteSupport.java b/platform/platform-api/src/com/intellij/openapi/editor/CopyPasteSupport.java new file mode 100644 index 000000000000..7095080aa13d --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/editor/CopyPasteSupport.java @@ -0,0 +1,212 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.editor; + +import com.intellij.codeInsight.editorActions.TextBlockTransferable; +import com.intellij.codeInsight.editorActions.TextBlockTransferableData; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.LineTokenizer; +import com.intellij.util.Producer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +public class CopyPasteSupport { + private static final Logger LOG = Logger.getInstance(CopyPasteSupport.class); + + private CopyPasteSupport() { } + + public static void copySelectionToClipboard(@NotNull Editor editor) { + ApplicationManager.getApplication().assertIsDispatchThread(); + List<TextBlockTransferableData> extraData = new ArrayList<TextBlockTransferableData>(); + String s = editor.getCaretModel().supportsMultipleCarets() ? getSelectedTextForClipboard(editor, extraData) + : editor.getSelectionModel().getSelectedText(); + if (s == null) return; + + s = TextBlockTransferable.convertLineSeparators(s, "\n", extraData); + Transferable contents = editor.getCaretModel().supportsMultipleCarets() ? new TextBlockTransferable(s, extraData, null) : new StringSelection(s); + CopyPasteManager.getInstance().setContents(contents); + } + + public static String getSelectedTextForClipboard(@NotNull Editor editor, @NotNull Collection<TextBlockTransferableData> extraDataCollector) { + final StringBuilder buf = new StringBuilder(); + String separator = ""; + List<Caret> carets = editor.getCaretModel().getAllCarets(); + int[] startOffsets = new int[carets.size()]; + int[] endOffsets = new int[carets.size()]; + for (int i = 0; i < carets.size(); i++) { + buf.append(separator); + String caretSelectedText = carets.get(i).getSelectedText(); + startOffsets[i] = buf.length(); + if (caretSelectedText != null) { + buf.append(caretSelectedText); + } + endOffsets[i] = buf.length(); + separator = "\n"; + } + extraDataCollector.add(new CaretStateTransferableData(startOffsets, endOffsets)); + return buf.toString(); + } + + + public static TextRange pasteFromClipboard(Editor editor) { + return pasteTransferable(editor, (Producer<Transferable>)null); + } + + public static TextRange pasteTransferable(Editor editor, final Transferable content) { + return pasteTransferable(editor, new Producer<Transferable>() { + @Nullable + @Override + public Transferable produce() { + return content; + } + }); + } + + @Nullable + public static TextRange pasteTransferable(final Editor editor, @Nullable Producer<Transferable> producer) { + Transferable content = getTransferable(producer); + if (content == null) return null; + String text = getStringContent(content); + if (text == null) return null; + + if (editor.getCaretModel().supportsMultipleCarets()) { + int caretCount = editor.getCaretModel().getCaretCount(); + if (caretCount == 1 && editor.isColumnMode()) { + int pastedLineCount = LineTokenizer.calcLineCount(text, true); + EditorModificationUtil.deleteSelectedText(editor); + Caret caret = editor.getCaretModel().getPrimaryCaret(); + for (int i = 0; i < pastedLineCount - 1; i++) { + caret = caret.clone(false); + if (caret == null) { + break; + } + } + caretCount = editor.getCaretModel().getCaretCount(); + } + CaretStateTransferableData caretData = null; + try { + caretData = content.isDataFlavorSupported(CaretStateTransferableData.FLAVOR) + ? (CaretStateTransferableData)content.getTransferData(CaretStateTransferableData.FLAVOR) : null; + } + catch (Exception e) { + LOG.error(e); + } + final Iterator<String> segments = new ClipboardTextPerCaretSplitter().split(text, caretData, caretCount).iterator(); + editor.getCaretModel().runForEachCaret(new CaretAction() { + @Override + public void perform(Caret caret) { + EditorModificationUtil.insertStringAtCaret(editor, segments.next(), false, true); + } + }); + return null; + } + else { + int caretOffset = editor.getCaretModel().getOffset(); + EditorModificationUtil.insertStringAtCaret(editor, text, false, true); + return new TextRange(caretOffset, caretOffset + text.length()); + } + } + + public static void pasteTransferableAsBlock(Editor editor, @Nullable Producer<Transferable> producer) { + Transferable content = getTransferable(producer); + if (content == null) return; + String text = getStringContent(content); + if (text == null) return; + + int caretLine = editor.getCaretModel().getLogicalPosition().line; + int originalCaretLine = caretLine; + int selectedLinesCount = 0; + + final SelectionModel selectionModel = editor.getSelectionModel(); + if (selectionModel.hasBlockSelection()) { + final LogicalPosition start = selectionModel.getBlockStart(); + final LogicalPosition end = selectionModel.getBlockEnd(); + assert start != null; + assert end != null; + LogicalPosition caret = new LogicalPosition(Math.min(start.line, end.line), Math.min(start.column, end.column)); + selectedLinesCount = Math.abs(end.line - start.line); + caretLine = caret.line; + + EditorModificationUtil.deleteSelectedText(editor); + editor.getCaretModel().moveToLogicalPosition(caret); + } + + LogicalPosition caretToRestore = editor.getCaretModel().getLogicalPosition(); + + String[] lines = LineTokenizer.tokenize(text.toCharArray(), false); + if (lines.length > 1 || selectedLinesCount == 0) { + int longestLineLength = 0; + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + longestLineLength = Math.max(longestLineLength, line.length()); + editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column)); + EditorModificationUtil.insertStringAtCaret(editor, line, false, true); + } + caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + longestLineLength); + } + else { + for (int i = 0; i <= selectedLinesCount; i++) { + editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column)); + EditorModificationUtil.insertStringAtCaret(editor, text, false, true); + } + caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + text.length()); + } + + editor.getCaretModel().moveToLogicalPosition(caretToRestore); + EditorModificationUtil.zeroWidthBlockSelectionAtCaretColumn(editor, caretLine, caretLine + selectedLinesCount); + } + + @Nullable + private static String getStringContent(@NotNull Transferable content) { + RawText raw = RawText.fromTransferable(content); + if (raw != null) return raw.rawText; + + try { + return (String)content.getTransferData(DataFlavor.stringFlavor); + } + catch (UnsupportedFlavorException ignore) { } + catch (IOException ignore) { } + + return null; + } + + private static Transferable getTransferable(Producer<Transferable> producer) { + Transferable content = null; + if (producer != null) { + content = producer.produce(); + } + else { + CopyPasteManager manager = CopyPasteManager.getInstance(); + if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) { + content = manager.getContents(); + } + } + return content; + } +} diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java index 3fddbc344585..ee5527967440 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java @@ -19,20 +19,14 @@ import com.intellij.codeStyle.CodeStyleFacade; import com.intellij.openapi.editor.actionSystem.EditorActionManager; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.event.MockDocumentEvent; -import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.text.LineTokenizer; import com.intellij.psi.PsiDocumentManager; import com.intellij.util.Producer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.UnsupportedFlavorException; -import java.io.IOException; -import java.util.Iterator; import java.util.List; public class EditorModificationUtil { @@ -99,7 +93,7 @@ public class EditorModificationUtil { zeroWidthBlockSelectionAtCaretColumn(editor, startLine, endLine); } - private static void zeroWidthBlockSelectionAtCaretColumn(final Editor editor, final int startLine, final int endLine) { + public static void zeroWidthBlockSelectionAtCaretColumn(final Editor editor, final int startLine, final int endLine) { int caretColumn = editor.getCaretModel().getLogicalPosition().column; editor.getSelectionModel().setBlockSelection(new LogicalPosition(startLine, caretColumn), new LogicalPosition(endLine, caretColumn)); } @@ -181,112 +175,21 @@ public class EditorModificationUtil { return offset; } + /** + * @deprecated Use {@link com.intellij.openapi.editor.CopyPasteSupport#pasteTransferable(Editor, com.intellij.util.Producer)} instead. + * (to remove in IDEA 15) + */ @Nullable public static TextRange pasteTransferable(final Editor editor, @Nullable Producer<Transferable> producer) { - String text = getStringContent(producer); - if (text == null) return null; - - if (editor.getCaretModel().supportsMultipleCarets()) { - int caretCount = editor.getCaretModel().getCaretCount(); - if (caretCount == 1 && editor.isColumnMode()) { - int pastedLineCount = LineTokenizer.calcLineCount(text, true); - deleteSelectedText(editor); - Caret caret = editor.getCaretModel().getPrimaryCaret(); - for (int i = 0; i < pastedLineCount - 1; i++) { - caret = caret.clone(false); - if (caret == null) { - break; - } - } - caretCount = editor.getCaretModel().getCaretCount(); - } - final Iterator<String> segments = new ClipboardTextPerCaretSplitter().split(text, caretCount).iterator(); - editor.getCaretModel().runForEachCaret(new CaretAction() { - @Override - public void perform(Caret caret) { - insertStringAtCaret(editor, segments.next(), false, true); - } - }); - return null; - } - else { - int caretOffset = editor.getCaretModel().getOffset(); - insertStringAtCaret(editor, text, false, true); - return new TextRange(caretOffset, caretOffset + text.length()); - } + return CopyPasteSupport.pasteTransferable(editor, producer); } + /** + * @deprecated Use {@link com.intellij.openapi.editor.CopyPasteSupport#pasteTransferableAsBlock(Editor, com.intellij.util.Producer)} instead. + * (to remove in IDEA 15) + */ public static void pasteTransferableAsBlock(Editor editor, @Nullable Producer<Transferable> producer) { - String text = getStringContent(producer); - if (text == null) return; - - int caretLine = editor.getCaretModel().getLogicalPosition().line; - int originalCaretLine = caretLine; - int selectedLinesCount = 0; - - final SelectionModel selectionModel = editor.getSelectionModel(); - if (selectionModel.hasBlockSelection()) { - final LogicalPosition start = selectionModel.getBlockStart(); - final LogicalPosition end = selectionModel.getBlockEnd(); - assert start != null; - assert end != null; - LogicalPosition caret = new LogicalPosition(Math.min(start.line, end.line), Math.min(start.column, end.column)); - selectedLinesCount = Math.abs(end.line - start.line); - caretLine = caret.line; - - deleteSelectedText(editor); - editor.getCaretModel().moveToLogicalPosition(caret); - } - - LogicalPosition caretToRestore = editor.getCaretModel().getLogicalPosition(); - - String[] lines = LineTokenizer.tokenize(text.toCharArray(), false); - if (lines.length > 1 || selectedLinesCount == 0) { - int longestLineLength = 0; - for (int i = 0; i < lines.length; i++) { - String line = lines[i]; - longestLineLength = Math.max(longestLineLength, line.length()); - editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column)); - insertStringAtCaret(editor, line, false, true); - } - caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + longestLineLength); - } - else { - for (int i = 0; i <= selectedLinesCount; i++) { - editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column)); - insertStringAtCaret(editor, text, false, true); - } - caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + text.length()); - } - - editor.getCaretModel().moveToLogicalPosition(caretToRestore); - zeroWidthBlockSelectionAtCaretColumn(editor, caretLine, caretLine + selectedLinesCount); - } - - @Nullable - private static String getStringContent(@Nullable Producer<Transferable> producer) { - Transferable content = null; - if (producer != null) { - content = producer.produce(); - } - else { - CopyPasteManager manager = CopyPasteManager.getInstance(); - if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) { - content = manager.getContents(); - } - } - if (content == null) return null; - - RawText raw = RawText.fromTransferable(content); - if (raw != null) return raw.rawText; - - try { - return (String)content.getTransferData(DataFlavor.stringFlavor); - } - catch (UnsupportedFlavorException ignore) { } - catch (IOException ignore) { } - - return null; + CopyPasteSupport.pasteTransferableAsBlock(editor, producer); } /** @@ -494,40 +397,4 @@ public class EditorModificationUtil { CaretModel caretModel = editor.getCaretModel(); caretModel.moveToOffset(caretModel.getOffset() + caretShift); } - - /** @deprecated use {@link #pasteTransferable(Editor, Producer)} (to remove in IDEA 14) */ - @SuppressWarnings("UnusedDeclaration") - public static TextRange pasteFromClipboard(Editor editor) { - return pasteTransferable(editor, null); - } - - /** @deprecated use {@link #pasteTransferable(Editor, Producer)} (to remove in IDEA 14) */ - @SuppressWarnings("SpellCheckingInspection,UnusedDeclaration") - public static TextRange pasteFromTransferrable(final Transferable content, Editor editor) { - return pasteTransferable(editor, new Producer<Transferable>() { - @Nullable - @Override - public Transferable produce() { - return content; - } - }); - } - - @SuppressWarnings("UnusedDeclaration") - /** @deprecated use {@link #pasteTransferableAsBlock(Editor, Producer)} (to remove in IDEA 14) */ - public static void pasteFromClipboardAsBlock(Editor editor) { - pasteTransferableAsBlock(editor, (Producer<Transferable>)null); - } - - @SuppressWarnings("UnusedDeclaration") - /** @deprecated use {@link #pasteTransferableAsBlock(Editor, Producer)} (to remove in IDEA 14) */ - public static void pasteTransferableAsBlock(Editor editor, @Nullable final Transferable content) { - pasteTransferableAsBlock(editor, new Producer<Transferable>() { - @Nullable - @Override - public Transferable produce() { - return content; - } - }); - } } diff --git a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java index 13b2c43faa7b..9cd9ab29f4cd 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java @@ -19,6 +19,7 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; @@ -74,8 +75,8 @@ public class FragmentedEditorHighlighter implements EditorHighlighter { if (myMergeByTextAttributes && !myPieces.isEmpty()) { Element element = myPieces.get(myPieces.size() - 1); if (element.getEnd() >= offset + relativeStart && - element.getAttributes().equals(iterator.getTextAttributes()) && - element.getElementType().equals(iterator.getTokenType())) { + Comparing.equal(element.getAttributes(), iterator.getTextAttributes()) && + Comparing.equal(element.getElementType(), iterator.getTokenType())) { merged = true; myPieces.add(new Element(element.getStart(), offset + relativeEnd, diff --git a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java index 07430ddbad8b..11c8bdd90052 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java +++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -90,6 +90,8 @@ public class ConfigurableEP<T extends UnnamedConfigurable> extends AbstractExten @Attribute("id") public String id; + @Attribute("groupId") + public String groupId; /** Marks project level configurables that do not apply to the default project. */ @Attribute("nonDefaultProject") diff --git a/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java b/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java index 634144817fa7..e98bb05aba99 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java +++ b/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java @@ -36,41 +36,49 @@ public interface SearchableConfigurable extends Configurable { boolean hasOwnContent(); boolean isVisible(); - abstract class Abstract implements Parent { private Configurable[] myKids; + @Override public JComponent createComponent() { return null; } + @Override public boolean hasOwnContent() { return false; } + @Override public boolean isModified() { return false; } + @Override public void apply() throws ConfigurationException { } + @Override public void reset() { } + @Override public void disposeUIResources() { myKids = null; } + @Override public Runnable enableSearch(final String option) { return null; } + @Override public boolean isVisible() { return true; } + @Override public final Configurable[] getConfigurables() { if (myKids != null) return myKids; myKids = buildConfigurables(); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java b/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java index 9e6c0aa1b965..5d2ecafb1b7e 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java @@ -76,6 +76,10 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere return value.toString(); } + protected Icon getIconFor(@NotNull T value) { + return null; + } + protected Runnable onChosen(@NotNull final T value) { stopCellEditing(value); @@ -137,6 +141,11 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere return ComboBoxTableRenderer.this.getTextFor(value); } + @Override + public Icon getIconFor(T value) { + return ComboBoxTableRenderer.this.getIconFor(value); + } + public PopupStep onChosen(T selectedValue, boolean finalChoice) { myFinalRunnable = ComboBoxTableRenderer.this.onChosen(selectedValue); return FINAL_CHOICE; @@ -169,6 +178,9 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere protected void customizeComponent(final T value, final JTable table, final boolean isSelected) { setOpaque(true); setText(value == null ? "" : getTextFor(value)); + if (value != null) { + setIcon(getIconFor(value)); + } setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); setForeground(isSelected ? table.getSelectionForeground() : table.getForeground()); } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java index 5bbd3d12da6a..34aaa93d2741 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java @@ -170,11 +170,7 @@ public class DetailsComponent { myContent.setBorder(new EmptyBorder(UIUtil.PANEL_REGULAR_INSETS)); } else { - if (Registry.is("ide.new.project.settings")) { - myContent.setBorder(new EmptyBorder(16, 10, 16, 10)); - } else { - myContent.setBorder(null); - } + myContent.setBorder(null); } } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java b/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java index 6f38d9a96356..101444a9d649 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java @@ -87,7 +87,7 @@ public class FixedSizeButton extends JButton { public Dimension getPreferredSize() { if (myComponent != null) { int size = myComponent.getPreferredSize().height; - if (myComponent instanceof ComboBox && (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderDarcula())) { + if (myComponent instanceof JComboBox && (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderDarcula())) { size -= 2; // decrement to match JTextField's preferred height } return new Dimension(size, size); @@ -120,9 +120,7 @@ public class FixedSizeButton extends JButton { public void setBounds(Rectangle r) { if (r.width != r.height) { int size = Math.min(r.width, r.height); - r = new Rectangle(r); - r.width = size; - r.height = size; + r = new Rectangle(r.x, r.y, size, size); } super.setBounds(r); } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java index 35e81b032ba5..816349ed1c37 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java @@ -135,11 +135,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom mySplitter.setSplitterProportionKey("ProjectStructure.SecondLevelElements"); mySplitter.setHonorComponentsMinimumSize(true); if (Registry.is("ide.new.project.settings")) { - mySplitter.setDividerWidth(1); - mySplitter.setShowDividerIcon(false); - mySplitter.getDivider().setBackground(Gray._153.withAlpha(128)); - mySplitter.setShowDividerControls(false); - mySplitter.setOrientation(mySplitter.getOrientation()); + mySplitter.setOnePixelMode(); } installAutoScroll(); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java index faa26e2415b8..62864d01b91a 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java @@ -26,6 +26,7 @@ import com.intellij.ui.UIBundle; import com.intellij.util.ui.update.Activatable; import com.intellij.util.ui.update.UiNotifyConnector; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -56,9 +57,9 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { private final Divider myFirstDivider; private final Divider myLastDivider; - private JComponent myFirstComponent; - private JComponent myInnerComponent; - private JComponent myLastComponent; + @Nullable private JComponent myFirstComponent; + @Nullable private JComponent myInnerComponent; + @Nullable private JComponent myLastComponent; private int myFirstSize = 10; private int myLastSize = 10; @@ -303,6 +304,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { repaint(); } + @Nullable public JComponent getFirstComponent() { return myFirstComponent; } @@ -312,7 +314,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { * repaint the splitter. If there is already * */ - public void setFirstComponent(JComponent component) { + public void setFirstComponent(@Nullable JComponent component) { if (myFirstComponent != component) { if (myFirstComponent != null) { remove(myFirstComponent); @@ -325,6 +327,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { } } + @Nullable public JComponent getLastComponent() { return myLastComponent; } @@ -335,7 +338,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { * repaint the splitter. * */ - public void setLastComponent(JComponent component) { + public void setLastComponent(@Nullable JComponent component) { if (myLastComponent != component) { if (myLastComponent != null) { remove(myLastComponent); @@ -348,7 +351,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { } } - + @Nullable public JComponent getInnerComponent() { return myInnerComponent; } @@ -359,7 +362,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { * repaint the splitter. * */ - public void setInnerComponent(JComponent component) { + public void setInnerComponent(@Nullable JComponent component) { if (myInnerComponent != component) { if (myInnerComponent != null) { remove(myInnerComponent); diff --git a/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java b/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java index 6584184a1bb2..fc9eec268ece 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.wm; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.popup.util.PopupUtil; import com.intellij.openapi.util.ActionCallback; @@ -22,12 +23,13 @@ import com.intellij.openapi.util.ActiveRunnable; import com.intellij.openapi.util.Expirable; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.util.Arrays; /** @@ -41,6 +43,8 @@ public abstract class FocusCommand extends ActiveRunnable implements Expirable { private boolean myInvalidatesPendingFurtherRequestors = true; private Expirable myExpirable; + public static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.FocusCommand"); + public boolean isForced() { return myForced; } @@ -154,46 +158,51 @@ public abstract class FocusCommand extends ActiveRunnable implements Expirable { public static class ByComponent extends FocusCommand { private Component myToFocus; + private Throwable myAllocation; - public ByComponent(@Nullable Component toFocus) { - this(toFocus, toFocus); + public ByComponent(@Nullable Component toFocus, @NotNull Throwable allocation) { + this(toFocus, toFocus, allocation); } - public ByComponent(@Nullable Component toFocus, @Nullable Component dominationComponent) { + public ByComponent(@Nullable Component toFocus, @Nullable Component dominationComponent, @NotNull Throwable allocation) { super(toFocus, dominationComponent); + myAllocation = allocation; myToFocus = toFocus; } @NotNull public final ActionCallback run() { - if (myToFocus != null) { - if (Registry.is("actionSystem.doNotStealFocus")) { - Window topWindow = SwingUtilities.windowForComponent(myToFocus); - UIUtil.setAutoRequestFocus(topWindow, topWindow.isActive()); - while (topWindow.getOwner() != null) { - topWindow = SwingUtilities.windowForComponent(topWindow); - UIUtil.setAutoRequestFocus(topWindow, topWindow.isActive()); - } - if (topWindow.isActive()) { - if (!myToFocus.requestFocusInWindow()) { - myToFocus.requestFocus(); - } - } else { - myToFocus.requestFocusInWindow(); + boolean shouldLogFocuses = Registry.is("ide.log.focuses"); + + if (shouldLogFocuses) { + myToFocus.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + if (isExpired()) return; + super.focusGained(e); + LOG.info("Focus gained on " + myToFocus.getClass().getName()); + myToFocus.removeFocusListener(this); } + }); + } - } else { - // This change seems reasonable to me. But as far as some implementations - // can ignore the "forced" parameter we can get bad focus behaviour. - // So let's start from mac. - if (!(myToFocus.requestFocusInWindow())) { - if (!SystemInfo.isMac || isForced() ) { - myToFocus.requestFocus(); - } + if (!(myToFocus.requestFocusInWindow())) { + if (shouldLogFocuses) { + LOG.info("We could not request focus in window on " + myToFocus.getClass().getName()); + LOG.info(myAllocation); + } + if (!SystemInfo.isMac || isForced() ) { + myToFocus.requestFocus(); + if (shouldLogFocuses) { + LOG.info("Force request focus on " + myToFocus.getClass().getName()); } } + } else if (shouldLogFocuses) { + LOG.info("We have successfully requested focus in window on " + myToFocus.getClass().getName()); + LOG.info(myAllocation); } + clear(); return new ActionCallback.Done(); } diff --git a/platform/platform-api/src/com/intellij/ui/BooleanTableCellRenderer.java b/platform/platform-api/src/com/intellij/ui/BooleanTableCellRenderer.java index 5c5426dd244a..4a2dc6e8b06c 100644 --- a/platform/platform-api/src/com/intellij/ui/BooleanTableCellRenderer.java +++ b/platform/platform-api/src/com/intellij/ui/BooleanTableCellRenderer.java @@ -30,8 +30,12 @@ public class BooleanTableCellRenderer extends JCheckBox implements TableCellRend private final JPanel myPanel = new JPanel(); public BooleanTableCellRenderer() { + this(CENTER); + } + + public BooleanTableCellRenderer(final int horizontalAlignment) { super(); - setHorizontalAlignment(CENTER); + setHorizontalAlignment(horizontalAlignment); setVerticalAlignment(CENTER); setBorder(null); setOpaque(true); diff --git a/platform/platform-api/src/com/intellij/ui/ColorChooser.java b/platform/platform-api/src/com/intellij/ui/ColorChooser.java index 9c8123ab1a49..6777ed74190f 100644 --- a/platform/platform-api/src/com/intellij/ui/ColorChooser.java +++ b/platform/platform-api/src/com/intellij/ui/ColorChooser.java @@ -18,6 +18,9 @@ package com.intellij.ui; import org.jetbrains.annotations.Nullable; import java.awt.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Utility wrapper around JColorChooser. Helps to avoid memory leak through JColorChooser.ColorChooserDialog.cancelButton. @@ -27,24 +30,38 @@ import java.awt.*; */ public class ColorChooser { @Nullable + @Deprecated + /** + * @deprecated Use {@link #chooseColor(java.awt.Component, String, java.awt.Color, boolean, java.util.List, boolean)} + */ public static Color chooseColor(Component parent, String caption, @Nullable Color preselectedColor, boolean enableOpacity, ColorPickerListener[] listeners, boolean opacityInPercent) { + return chooseColor(parent, caption, preselectedColor, enableOpacity, Arrays.asList(listeners), opacityInPercent); + } + + @Nullable + public static Color chooseColor(Component parent, + String caption, + @Nullable Color preselectedColor, + boolean enableOpacity, + List<ColorPickerListener> listeners, + boolean opacityInPercent) { return ColorChooserService.getInstance().showDialog(parent, caption, preselectedColor, enableOpacity, listeners, opacityInPercent); } @Nullable public static Color chooseColor(Component parent, String caption, @Nullable Color preselectedColor, boolean enableOpacity) { - return chooseColor(parent, caption, preselectedColor, enableOpacity, ColorPickerListener.EMPTY_ARRAY, false); + return chooseColor(parent, caption, preselectedColor, enableOpacity, Collections.<ColorPickerListener>emptyList(), false); } @Nullable public static Color chooseColor(Component parent, String caption, @Nullable Color preselectedColor, boolean enableOpacity, boolean opacityInPercent) { - return chooseColor(parent, caption, preselectedColor, enableOpacity, ColorPickerListener.EMPTY_ARRAY, opacityInPercent); + return chooseColor(parent, caption, preselectedColor, enableOpacity, Collections.<ColorPickerListener>emptyList(), opacityInPercent); } @Nullable diff --git a/platform/platform-api/src/com/intellij/ui/ColorChooserService.java b/platform/platform-api/src/com/intellij/ui/ColorChooserService.java index 6ecad03496ef..6f34e5e7fc05 100644 --- a/platform/platform-api/src/com/intellij/ui/ColorChooserService.java +++ b/platform/platform-api/src/com/intellij/ui/ColorChooserService.java @@ -19,6 +19,7 @@ import com.intellij.openapi.components.ServiceManager; import org.jetbrains.annotations.Nullable; import java.awt.*; +import java.util.List; /** * @author Konstantin Bulenkov @@ -29,10 +30,22 @@ public abstract class ColorChooserService { } @Nullable + @Deprecated + /** + * @deprecated Use {@link #showDialog(java.awt.Component, String, java.awt.Color, boolean, java.util.List, boolean)} + */ public abstract Color showDialog(Component parent, String caption, Color preselectedColor, boolean enableOpacity, ColorPickerListener[] listeners); @Nullable + @Deprecated + /** + * @deprecated Use {@link #showDialog(java.awt.Component, String, java.awt.Color, boolean, java.util.List, boolean)} + */ public abstract Color showDialog(Component parent, String caption, Color preselectedColor, boolean enableOpacity, ColorPickerListener[] listeners, boolean opacityInPercent); + + @Nullable + public abstract Color showDialog(Component parent, String caption, Color preselectedColor, boolean enableOpacity, + List<ColorPickerListener> listeners, boolean opacityInPercent); } diff --git a/platform/platform-api/src/com/intellij/ui/ColorPickerListener.java b/platform/platform-api/src/com/intellij/ui/ColorPickerListener.java index f028dde4bde9..772265f0c1ef 100644 --- a/platform/platform-api/src/com/intellij/ui/ColorPickerListener.java +++ b/platform/platform-api/src/com/intellij/ui/ColorPickerListener.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.Nullable; import java.awt.*; public interface ColorPickerListener { + @Deprecated ColorPickerListener[] EMPTY_ARRAY = new ColorPickerListener[0]; /** diff --git a/platform/platform-api/src/com/intellij/ui/ExpandedItemRendererComponentWrapper.java b/platform/platform-api/src/com/intellij/ui/ExpandedItemRendererComponentWrapper.java index 4e6d1c5c3f41..eea201116350 100644 --- a/platform/platform-api/src/com/intellij/ui/ExpandedItemRendererComponentWrapper.java +++ b/platform/platform-api/src/com/intellij/ui/ExpandedItemRendererComponentWrapper.java @@ -19,6 +19,7 @@ import com.intellij.util.ui.AbstractLayoutManager; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import javax.swing.border.Border; import java.awt.*; public class ExpandedItemRendererComponentWrapper extends JComponent { @@ -40,4 +41,16 @@ public class ExpandedItemRendererComponentWrapper extends JComponent { } }); } + + @Override + public void setBorder(Border border) { + if (getComponentCount() == 1) { + Component component = getComponent(0); + if (component instanceof JComponent) { + ((JComponent)component).setBorder(border); + return; + } + } + super.setBorder(border); + } } diff --git a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java index 3ddbf47028f4..76bacb9cb452 100644 --- a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java +++ b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java @@ -15,9 +15,7 @@ */ package com.intellij.ui; -import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.components.panels.OpaquePanel; -import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.UIUtil; import javax.swing.*; @@ -26,38 +24,14 @@ import javax.swing.border.EmptyBorder; import javax.swing.tree.TreeCellRenderer; import java.awt.*; -import static javax.swing.SwingConstants.CENTER; -import static javax.swing.SwingConstants.LEFT; - public abstract class GroupedElementsRenderer { public static final Color POPUP_SEPARATOR_FOREGROUND = new JBColor(Color.gray.brighter(), Gray._43); public static final Color POPUP_SEPARATOR_TEXT_FOREGROUND = Color.gray; public static final Color SELECTED_FRAME_FOREGROUND = Color.black; - protected SeparatorWithText mySeparatorComponent = new SeparatorWithText() { - @Override - protected void paintComponent(Graphics g) { - if (Registry.is("ide.new.project.settings")) { - g.setColor(POPUP_SEPARATOR_FOREGROUND); - Rectangle viewR = new Rectangle(0, getVgap(), getWidth() - 1, getHeight() - getVgap() - 1); - Rectangle iconR = new Rectangle(); - Rectangle textR = new Rectangle(); - String s = SwingUtilities - .layoutCompoundLabel(g.getFontMetrics(), getCaption(), null, CENTER, - LEFT, - CENTER, - LEFT, - viewR, iconR, textR, 0); - GraphicsUtil.setupAAPainting(g); - g.setColor(Gray._255.withAlpha(80)); - g.drawString(s, textR.x + 10, textR.y + 1 + g.getFontMetrics().getAscent()); - g.setColor(new Color(0x5F6D7B)); - g.drawString(s, textR.x + 10, textR.y + g.getFontMetrics().getAscent()); - } else { - super.paintComponent(g); - } - } - }; + protected SeparatorWithText mySeparatorComponent = createSeparator(); + + protected abstract JComponent createItemComponent(); protected JComponent myComponent; protected MyComponent myRendererComponent; @@ -75,7 +49,9 @@ public abstract class GroupedElementsRenderer { protected abstract void layout(); - protected abstract JComponent createItemComponent(); + protected SeparatorWithText createSeparator() { + return new SeparatorWithText(); + } protected final JComponent configureComponent(String text, String tooltip, Icon icon, Icon disabledIcon, boolean isSelected, boolean hasSeparatorAbove, String separatorTextAbove, int preferredForcedWidth) { mySeparatorComponent.setVisible(hasSeparatorAbove); @@ -127,9 +103,9 @@ public abstract class GroupedElementsRenderer { } - protected final void setDeselected(JComponent aComponent) { + protected final void setDeselected(JComponent aComponent) { aComponent.setBackground(getBackground()); - aComponent.setForeground(Registry.is("ide.new.project.settings") ? Gray._60 : getForeground()); + aComponent.setForeground(getForeground()); } protected abstract Color getSelectionBackground(); @@ -154,7 +130,7 @@ public abstract class GroupedElementsRenderer { public abstract static class List extends GroupedElementsRenderer { @Override - protected final void layout() { + protected void layout() { myRendererComponent.add(mySeparatorComponent, BorderLayout.NORTH); myRendererComponent.add(myComponent, BorderLayout.CENTER); } diff --git a/platform/platform-api/src/com/intellij/ui/JBSplitter.java b/platform/platform-api/src/com/intellij/ui/JBSplitter.java index f25c2aee042c..b4000dbcfae2 100644 --- a/platform/platform-api/src/com/intellij/ui/JBSplitter.java +++ b/platform/platform-api/src/com/intellij/ui/JBSplitter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -94,6 +94,14 @@ public class JBSplitter extends Splitter { saveProportion(); } + public void setOnePixelMode() { + setDividerWidth(1); + setShowDividerIcon(false); + getDivider().setBackground(new JBColor(Gray._153.withAlpha(128), Gray._100.withAlpha(128))); + setShowDividerControls(false); + setOrientation(getOrientation()); + } + protected void loadProportion() { if (! StringUtil.isEmpty(mySplitterProportionKey)) { setProportion(PropertiesComponent.getInstance().getFloat(mySplitterProportionKey, myProportion)); diff --git a/platform/platform-api/src/com/intellij/ui/TextFieldWithHistoryWithBrowseButton.java b/platform/platform-api/src/com/intellij/ui/TextFieldWithHistoryWithBrowseButton.java index 9534bf047de9..e16e421a46a9 100644 --- a/platform/platform-api/src/com/intellij/ui/TextFieldWithHistoryWithBrowseButton.java +++ b/platform/platform-api/src/com/intellij/ui/TextFieldWithHistoryWithBrowseButton.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,4 +50,8 @@ public class TextFieldWithHistoryWithBrowseButton extends ComponentWithBrowseBut super.addBrowseFolderListener(title, description, project, fileChooserDescriptor, accessor, autoRemoveOnHide); FileChooserFactory.getInstance().installFileCompletion(getChildComponent().getTextEditor(), fileChooserDescriptor, false, project); } + + public String getText() { + return getChildComponent().getText(); + } } diff --git a/platform/platform-api/src/com/intellij/ui/dualView/DualView.java b/platform/platform-api/src/com/intellij/ui/dualView/DualView.java index 56fe3200f03b..475220cb6d34 100644 --- a/platform/platform-api/src/com/intellij/ui/dualView/DualView.java +++ b/platform/platform-api/src/com/intellij/ui/dualView/DualView.java @@ -36,6 +36,7 @@ import com.intellij.util.config.Storage; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.ListTableModel; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.Border; @@ -239,8 +240,9 @@ public class DualView extends JPanel { return createWrappedRenderer(super.getCellRenderer(row, column)); } + @NotNull @Override - public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { + public Component prepareRenderer(@NotNull TableCellRenderer renderer, int row, int column) { final Component c = super.prepareRenderer(renderer, row, column); if (c instanceof JComponent && !myFlatView.getCellSelectionEnabled()) { ((JComponent)c).setBorder(null); diff --git a/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearchSupply.java b/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearchSupply.java index de3452d8e61f..736c4db0b677 100644 --- a/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearchSupply.java +++ b/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearchSupply.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,10 @@ import java.beans.PropertyChangeListener; * @author Konstantin Bulenkov */ public abstract class SpeedSearchSupply { + /** + * Client property key to use in jcomponents for passing the actual search query to renderers + */ + public static final String SEARCH_QUERY_KEY = "SEARCH_QUERY"; private static final Key SPEED_SEARCH_COMPONENT_MARKER = new Key("SPEED_SEARCH_COMPONENT_MARKER"); public static final DataKey<String> SPEED_SEARCH_CURRENT_QUERY = DataKey.create("SPEED_SEARCH_CURRENT_QUERY"); diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java index d8736f6fc08e..e7ff935e57f9 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -38,6 +38,8 @@ import java.util.Comparator; import java.util.EventObject; public class JBTable extends JTable implements ComponentWithEmptyText, ComponentWithExpandableItems<TableCell> { + public static final int PREFERRED_SCROLLABLE_VIEWPORT_HEIGHT_IN_ROWS = 7; + private final StatusText myEmptyText; private final ExpandableItemsHandler<TableCell> myExpandableItemsHandler; @@ -84,30 +86,29 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } @Override - public void columnSelectionChanged(ListSelectionEvent e) { + public void columnSelectionChanged(@NotNull ListSelectionEvent e) { } @Override - public void columnAdded(TableColumnModelEvent e) { + public void columnAdded(@NotNull TableColumnModelEvent e) { } @Override - public void columnMoved(TableColumnModelEvent e) { + public void columnMoved(@NotNull TableColumnModelEvent e) { } @Override - public void columnRemoved(TableColumnModelEvent e) { + public void columnRemoved(@NotNull TableColumnModelEvent e) { } }); final TableModelListener modelListener = new TableModelListener() { @Override - public void tableChanged(final TableModelEvent e) { + public void tableChanged(@NotNull final TableModelEvent e) { if (!myRowHeightIsExplicitlySet) { myRowHeight = -1; } - if ((e.getType() == TableModelEvent.DELETE && isEmpty()) - || (e.getType() == TableModelEvent.INSERT && !isEmpty())) { + if (e.getType() == TableModelEvent.DELETE && isEmpty() || e.getType() == TableModelEvent.INSERT && !isEmpty()) { repaintViewport(); } } @@ -116,7 +117,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component if (getModel() != null) getModel().addTableModelListener(modelListener); addPropertyChangeListener("model", new PropertyChangeListener() { @Override - public void propertyChange(PropertyChangeEvent evt) { + public void propertyChange(@NotNull PropertyChangeEvent evt) { repaintViewport(); if (evt.getOldValue() instanceof TableModel) { @@ -197,6 +198,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } } + @NotNull @Override protected JTableHeader createDefaultTableHeader() { return new JBTableHeader(); @@ -237,7 +239,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } @Override - protected void paintComponent(Graphics g) { + protected void paintComponent(@NotNull Graphics g) { if (myEnableAntialiasing) { GraphicsUtil.setupAntialiasing(g); } @@ -320,7 +322,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } @Override - public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { + public int getScrollableUnitIncrement(@NotNull Rectangle visibleRect, int orientation, int direction) { if (orientation == SwingConstants.VERTICAL) { return super.getScrollableUnitIncrement(visibleRect, orientation, direction); } @@ -339,7 +341,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } @Override - public void paint(Graphics g) { + public void paint(@NotNull Graphics g) { if (!isEnabled()) { g = new TableGrayer((Graphics2D)g); } @@ -470,8 +472,9 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component isTypeAhead = false; } + @NotNull @Override - public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { + public Component prepareRenderer(@NotNull TableCellRenderer renderer, int row, int column) { Component result = super.prepareRenderer(renderer, row, column); // Fix GTK background @@ -506,7 +509,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } @Override - public void propertyChange(final PropertyChangeEvent e) { + public void propertyChange(@NotNull final PropertyChangeEvent e) { if (!isEditing()) { return; } @@ -541,7 +544,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component private final class MyMouseListener extends MouseAdapter { @Override - public void mousePressed(final MouseEvent e) { + public void mousePressed(@NotNull final MouseEvent e) { if (SwingUtilities.isRightMouseButton(e)) { final int[] selectedRows = getSelectedRows(); if (selectedRows.length < 2) { @@ -629,6 +632,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component return myModel.getValueAt(row, column); } + @NotNull @Override public String getStringValueAt(int row, int column) { TableStringConverter converter = getStringConverter(); @@ -666,7 +670,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component super(JBTable.this.columnModel); JBTable.this.addPropertyChangeListener(new PropertyChangeListener() { @Override - public void propertyChange(PropertyChangeEvent evt) { + public void propertyChange(@NotNull PropertyChangeEvent evt) { JBTableHeader.this.revalidate(); JBTableHeader.this.repaint(); } @@ -674,7 +678,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } @Override - public void paint(Graphics g) { + public void paint(@NotNull Graphics g) { if (myEnableAntialiasing) { GraphicsUtil.setupAntialiasing(g); } @@ -685,7 +689,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } @Override - public String getToolTipText(final MouseEvent event) { + public String getToolTipText(@NotNull final MouseEvent event) { final TableModel model = getModel(); if (model instanceof SortableColumnModel) { final int i = columnAtPoint(event.getPoint()); @@ -719,6 +723,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component super.setColor(color); } + @NotNull @Override public Graphics create() { return new TableGrayer((Graphics2D)super.create()); diff --git a/platform/platform-api/src/com/intellij/ui/table/TableView.java b/platform/platform-api/src/com/intellij/ui/table/TableView.java index a563c820f815..44b40e938cdb 100644 --- a/platform/platform-api/src/com/intellij/ui/table/TableView.java +++ b/platform/platform-api/src/com/intellij/ui/table/TableView.java @@ -101,10 +101,12 @@ public class TableView<Item> extends BaseTableView implements ItemsProvider, Sel final RowSorter<? extends TableModel> sorter = getRowSorter(); final RowSorter.SortKey sortKey = sorter == null ? null : ContainerUtil.getFirstItem(sorter.getSortKeys()); - ColumnInfo[] columns = getListTableModel().getColumnInfos(); - int[] sizeMode = new int[columns.length]; - int[] headers = new int[columns.length]; - int[] widths = new int[columns.length]; + ColumnInfo[] columnInfos = getListTableModel().getColumnInfos(); + TableColumnModel columnModel = getColumnModel(); + int visibleColumnCount = columnModel.getColumnCount(); + int[] sizeMode = new int[visibleColumnCount]; + int[] headers = new int[visibleColumnCount]; + int[] widths = new int[visibleColumnCount]; int allColumnWidth = 0; int allColumnCurrent = 0; int varCount = 0; @@ -112,9 +114,9 @@ public class TableView<Item> extends BaseTableView implements ItemsProvider, Sel Icon sortIcon = UIManager.getIcon("Table.ascendingSortIcon"); // calculate - for (int i = 0; i < columns.length; i++) { - final ColumnInfo columnInfo = columns[i]; - final TableColumn column = getColumnModel().getColumn(i); + for (int i = 0; i < visibleColumnCount; i++) { + final TableColumn column = columnModel.getColumn(i); + final ColumnInfo columnInfo = columnInfos[column.getModelIndex()]; TableCellRenderer columnHeaderRenderer = column.getHeaderRenderer(); if (columnHeaderRenderer == null) { @@ -162,8 +164,8 @@ public class TableView<Item> extends BaseTableView implements ItemsProvider, Sel allColumnWidth < (1 - gold) * viewWidth ? (1 - gold) * viewWidth : viewWidth) - allColumnWidth) / varCount; - for (int i=0 ; i<columns.length; i ++) { - TableColumn column = getColumnModel().getColumn(i); + for (int i = 0 ; i < visibleColumnCount; i++) { + TableColumn column = columnModel.getColumn(i); int width = widths[i]; if (sizeMode[i] == 1) { column.setMaxWidth(width); diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java index 532c95a52a17..a058badddd41 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java @@ -930,7 +930,7 @@ public class JBTabsImpl extends JComponent if (isShowing()) { - return myFocusManager.requestFocus(new FocusCommand.ByComponent(toFocus), true); + return myFocusManager.requestFocus(new FocusCommand.ByComponent(toFocus, new Exception()), true); } else { final ActionCallback result = new ActionCallback(); @@ -948,7 +948,7 @@ public class JBTabsImpl extends JComponent @Override public void run() { queued.set(true); - requestor.requestFocus(new FocusCommand.ByComponent(toFocus), true).notify(result); + requestor.requestFocus(new FocusCommand.ByComponent(toFocus, new Exception()), true).notify(result); } }; return result; diff --git a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form index 72db5886d23b..5ffe378667d3 100644 --- a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form +++ b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form @@ -117,6 +117,7 @@ </grid> </constraints> <properties> + <lineWrap value="true"/> <toolTipText value=""/> </properties> </component> diff --git a/platform/platform-api/src/com/intellij/util/ui/NSScrollerHelper.java b/platform/platform-api/src/com/intellij/util/ui/NSScrollerHelper.java index db8244255db7..6498ed4e063b 100644 --- a/platform/platform-api/src/com/intellij/util/ui/NSScrollerHelper.java +++ b/platform/platform-api/src/com/intellij/util/ui/NSScrollerHelper.java @@ -75,6 +75,8 @@ class NSScrollerHelper { ID delegateClass = Foundation.allocateObjcClassPair(Foundation.getObjcClass("NSObject"), "NSScrollerChangesObserver"); if (!ID.NIL.equals(delegateClass)) { + // This static initializer might be called more than once (with different class loaders). In that case NSScrollerChangesObserver + // already exists. if (!Foundation.addMethod(delegateClass, Foundation.createSelector("handleScrollerStyleChanged:"), APPEARANCE_CALLBACK, "v@")) { throw new RuntimeException("Cannot add observer method"); } |