diff --git a/java/execution/impl/src/com/intellij/execution/ui/ConfigurationArgumentsHelpArea.java b/java/execution/impl/src/com/intellij/execution/ui/ConfigurationArgumentsHelpArea.java index dbec76e5438a..aa7e95aa644e 100644 --- a/java/execution/impl/src/com/intellij/execution/ui/ConfigurationArgumentsHelpArea.java +++ b/java/execution/impl/src/com/intellij/execution/ui/ConfigurationArgumentsHelpArea.java @@ -18,13 +18,10 @@ package com.intellij.execution.ui; import com.intellij.execution.ExecutionBundle; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.ide.CopyPasteManager; -import com.intellij.openapi.project.Project; import com.intellij.ui.PopupHandler; -import com.intellij.util.ui.EmptyClipboardOwner; import javax.swing.*; import java.awt.*; -import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; public class ConfigurationArgumentsHelpArea extends JPanel { @@ -68,17 +65,8 @@ public class ConfigurationArgumentsHelpArea extends JPanel { } public void actionPerformed(final AnActionEvent e) { - try { - final StringSelection contents = new StringSelection(myHelpArea.getText().trim()); - final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); - if (project == null) { - final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - clipboard.setContents(contents, EmptyClipboardOwner.INSTANCE); - } else { - CopyPasteManager.getInstance().setContents(contents); - } - } catch(Exception ex) { - } + final StringSelection contents = new StringSelection(myHelpArea.getText().trim()); + CopyPasteManager.getInstance().setContents(contents); } } diff --git a/platform/lang-impl/src/com/intellij/ui/debugger/extensions/DisposerDebugger.java b/platform/lang-impl/src/com/intellij/ui/debugger/extensions/DisposerDebugger.java index 87b2d994847e..d368803099ad 100644 --- a/platform/lang-impl/src/com/intellij/ui/debugger/extensions/DisposerDebugger.java +++ b/platform/lang-impl/src/com/intellij/ui/debugger/extensions/DisposerDebugger.java @@ -25,6 +25,7 @@ import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; @@ -204,8 +205,7 @@ public class DisposerDebugger implements UiDebuggerExtension, Disposable { public void actionPerformed(AnActionEvent e) { try { - Toolkit.getDefaultToolkit().getSystemClipboard() - .setContents(new TextTransferrable(myAllocation.getText(), myAllocation.getText()), null); + CopyPasteManager.getInstance().setContents(new TextTransferrable(myAllocation.getText(), myAllocation.getText())); } catch (HeadlessException e1) { LOG.error(e1); diff --git a/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java b/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java index 6bd6c5712f35..1f77a3107745 100644 --- a/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java +++ b/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java @@ -22,7 +22,6 @@ import com.intellij.execution.executors.DefaultRunExecutor; import com.intellij.execution.filters.Filter; import com.intellij.execution.filters.TextConsoleBuilder; import com.intellij.execution.filters.TextConsoleBuilderFactory; -import com.intellij.execution.impl.ConsoleViewImpl; import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.ExecutionConsole; @@ -67,7 +66,7 @@ public class AnalyzeStacktraceUtil { @Nullable public static String getTextInClipboard() { - final Transferable contents = CopyPasteManagerEx.getInstanceEx().getSystemClipboardContents(false); + final Transferable contents = CopyPasteManagerEx.getInstanceEx().getSystemClipboardContents(); if (contents != null) { try { return (String)contents.getTransferData(DataFlavor.stringFlavor); 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 92505fe844d9..9f4acb282a6b 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java @@ -26,7 +26,6 @@ import com.intellij.openapi.util.text.LineTokenizer; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.Nullable; -import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; @@ -166,16 +165,7 @@ public class EditorModificationUtil { } private static Transferable getClipboardContent(Editor editor) { - Transferable content; - Project project = editor.getProject(); - - if (project != null) { - content = CopyPasteManager.getInstance().getContents(); - } else { - Clipboard clipboard = editor.getComponent().getToolkit().getSystemClipboard(); - content = clipboard.getContents(editor.getComponent()); - } - return content; + return CopyPasteManager.getInstance().getContents(); } public static void pasteFromClipboardAsBlock(Editor editor) { diff --git a/platform/platform-impl/src/com/intellij/ide/ClipboardSynchronizer.java b/platform/platform-impl/src/com/intellij/ide/ClipboardSynchronizer.java new file mode 100644 index 000000000000..d2733c0af190 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ClipboardSynchronizer.java @@ -0,0 +1,195 @@ +/* + * Copyright 2000-2011 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.ide; + +import com.intellij.Patches; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * This class is used to workaround the problem with getting clipboard contents (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4818143). + * Although this bug is marked as fixed actually Sun just set 10 seconds timeout for {@link java.awt.datatransfer.Clipboard#getContents(Object)} + * method. So we perform synchronization with system clipboard on a separate thread and schedule it when IDEA frame is activated or Copy/Cut + * action in Swing component is invoked + * + * @author nik + */ +public class ClipboardSynchronizer implements ApplicationComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.ClipboardSynchronizer"); + @NonNls private static final String DATA_TRANSFER_TIMEOUT_PROPERTY = "sun.awt.datatransfer.timeout"; + private AtomicBoolean mySynchronizationInProgress = new AtomicBoolean(false); + private Transferable myCurrentContent; + private final Object myLock = new Object(); + + public static ClipboardSynchronizer getInstance() { + return ApplicationManager.getApplication().getComponent(ClipboardSynchronizer.class); + } + + @Override + public void initComponent() { + if (!Patches.SLOW_GETTING_CLIPBOARD_CONTENTS) return; + + if (System.getProperty(DATA_TRANSFER_TIMEOUT_PROPERTY) == null) { + System.setProperty(DATA_TRANSFER_TIMEOUT_PROPERTY, "2000"); + } + + FrameStateManager.getInstance().addListener(new FrameStateListener() { + @Override + public void onFrameDeactivated() { + } + + @Override + public void onFrameActivated() { + scheduleSynchronization(); + } + }); + } + + public void replaceDefaultCopyPasteActions(UIDefaults defaults) { + if (!Patches.SLOW_GETTING_CLIPBOARD_CONTENTS) return; + + //ensure that '.actionMap' properties are initialized + new JTextField(); + new JPasswordField(); + new JTextArea(); + //noinspection UndesirableClassUsage + new JTable(); + + String[] textComponents = {"TextField", "PasswordField", "TextArea", "Table"}; + for (String name : textComponents) { + final String key = name + ".actionMap"; + final ActionMap actionMap = (ActionMap)defaults.get(key); + if (actionMap != null) { + replaceAction(actionMap, TransferHandler.getCopyAction()); + replaceAction(actionMap, TransferHandler.getCutAction()); + } + else { + LOG.warn(key + " property not initialized"); + } + } + } + + private void replaceAction(ActionMap actionMap, final Action action) { + final String actionName = (String)action.getValue(Action.NAME); + actionMap.put(actionName, new AbstractAction(actionName) { + @Override + public void actionPerformed(ActionEvent e) { + action.actionPerformed(e); + scheduleSynchronization(); + } + }); + } + + public Transferable getContents() { + if (Patches.SLOW_GETTING_CLIPBOARD_CONTENTS) { + synchronized (myLock) { + return myCurrentContent; + } + } + return doGetContents(); + } + + public boolean isDataFlavorAvailable(DataFlavor dataFlavor) { + if (Patches.SLOW_GETTING_CLIPBOARD_CONTENTS) { + final Transferable contents = getContents(); + return contents != null && contents.isDataFlavorSupported(dataFlavor); + } + return Toolkit.getDefaultToolkit().getSystemClipboard().isDataFlavorAvailable(dataFlavor); + } + + private void scheduleSynchronization() { + final boolean inProgress = mySynchronizationInProgress.getAndSet(true); + if (inProgress) return; + + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + try { + final Transferable content = doGetContents(); + synchronized (myLock) { + myCurrentContent = content; + } + } + catch (Throwable e) { + LOG.info(e); + } + finally { + mySynchronizationInProgress.set(false); + } + } + }); + } + + @Override + public void disposeComponent() { + } + + private Transferable doGetContents() { + IllegalStateException last = null; + for (int i = 0; i < 3; i++) { + try { + return Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this); + } + catch (IllegalStateException e) { + try { + //noinspection BusyWait + Thread.sleep(50); + } + catch (InterruptedException ignored) { + } + last = e; + } + } + throw last; + } + + @NotNull + @Override + public String getComponentName() { + return "ClipboardSynchronizer"; + } + + public void setContent(Transferable content, ClipboardOwner owner) { + synchronized (myLock) { + myCurrentContent = content; + } + for (int i = 0; i < 3; i++) { + try { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(content, owner); + } + catch (IllegalStateException e) { + try { + Thread.sleep(50); + } + catch (InterruptedException ignored) { + } + continue; + } + break; + } + } +} diff --git a/platform/platform-impl/src/com/intellij/ide/CopyPasteManagerEx.java b/platform/platform-impl/src/com/intellij/ide/CopyPasteManagerEx.java index b4506630d269..3c5d422ce0fd 100644 --- a/platform/platform-impl/src/com/intellij/ide/CopyPasteManagerEx.java +++ b/platform/platform-impl/src/com/intellij/ide/CopyPasteManagerEx.java @@ -15,132 +15,36 @@ */ package com.intellij.ide; -import com.intellij.Patches; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.ide.CutElementMarker; -import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; import com.intellij.util.EventDispatcher; -import java.awt.*; import java.awt.datatransfer.*; import java.io.IOException; import java.util.ArrayList; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; public class CopyPasteManagerEx extends CopyPasteManager implements ClipboardOwner { - private static final Logger LOG = Logger.getInstance("#com.intellij.ide.CopyPasteManagerEx"); - private final ArrayList myDatas; - -// private static long ourWastedMemory = 0; -// private static long ourLastPrintedMemory = 0; -// private static long ourLastPrintTime = 0; -// private static long ourInvokationCounter = 0; - private final EventDispatcher myDispatcher = EventDispatcher.create(ContentChangedListener.class); - private static final int DELAY_UNTIL_ABORT_CLIPBOARD_ACCESS = 2000; - private boolean myIsWarningShown = false; + private final ClipboardSynchronizer myClipboardSynchronizer; public static CopyPasteManagerEx getInstanceEx() { return (CopyPasteManagerEx)getInstance(); } - public CopyPasteManagerEx() { + public CopyPasteManagerEx(ClipboardSynchronizer clipboardSynchronizer) { + myClipboardSynchronizer = clipboardSynchronizer; myDatas = new ArrayList(); } public Transferable getSystemClipboardContents() { - return getSystemClipboardContents(true); + return myClipboardSynchronizer.getContents(); } - public Transferable getSystemClipboardContents(boolean showMessage) { - final Transferable[] contents = new Transferable[] {null}; - final boolean[] success = new boolean[] {false}; - Runnable accessor = new Runnable() { - public void run() { - try { - for (int i = 0; i < 3; i++) { - try { - contents[0] = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(CopyPasteManagerEx.this); - } - catch (IllegalStateException e) { - try { - Thread.sleep(50); - } - catch (InterruptedException e1) { - } - continue; - } - break; - } - - success[0] = true; - } - catch (Throwable e) { - LOG.info(e); - // No luck - } - finally { - Thread.interrupted(); // reset interrupted status - } - } - }; - - if (Patches.SUN_BUG_ID_4818143) { - final Future accessorFuture = ApplicationManager.getApplication().executeOnPooledThread(accessor); - - try { - accessorFuture.get(DELAY_UNTIL_ABORT_CLIPBOARD_ACCESS, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) { - // {no luck} - } - catch (TimeoutException e) { - // {no luck} - } - catch (ExecutionException e) { - LOG.error(e); - } - - if (success[0]) return contents[0]; - accessorFuture.cancel(true); - if (showMessage) { - showWorkaroundMessage(); - } else { - LOG.warn("Can't access to SystemClipboard"); - } - - return null; - } - else { - accessor.run(); - return contents[0]; - } - } - - private void showWorkaroundMessage() { - if (myIsWarningShown) return; - final String productName = ApplicationNamesInfo.getInstance().getProductName(); - Messages.showErrorDialog(IdeBundle.message("error.paste.bug.workaround", productName, productName), IdeBundle.message("title.system.error")); - myIsWarningShown = true; - } - -// private long getUsedMemory() { -// Runtime runtime = Runtime.getRuntime(); -// long usedMemory = runtime.totalMemory() - runtime.freeMemory(); -// return usedMemory; -// } -// public void lostOwnership(Clipboard clipboard, Transferable contents) { fireContentChanged(null); } @@ -170,6 +74,10 @@ public class CopyPasteManagerEx extends CopyPasteManager implements ClipboardOwn fireContentChanged(old); } + public boolean isDataFlavorAvailable(DataFlavor dataFlavor) { + return myClipboardSynchronizer.isDataFlavorAvailable(dataFlavor); + } + public boolean isCutElement(final Object element) { for(CutElementMarker marker: Extensions.getExtensions(CutElementMarker.EP_NAME)) { if (marker.isCutElement(element)) return true; @@ -178,48 +86,7 @@ public class CopyPasteManagerEx extends CopyPasteManager implements ClipboardOwn } void setSystemClipboardContent(final Transferable content) { - final boolean[] success = new boolean[]{false}; - final Runnable accessor = new Runnable() { - public void run() { - try { - for (int i = 0; i < 3; i++) { - try { - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(content, CopyPasteManagerEx.this); - } - catch (IllegalStateException e) { - try { - Thread.sleep(50); - } - catch (InterruptedException e1) { - } - continue; - } - break; - } - success[0] = true; - } - finally { - Thread.interrupted(); // reset interrupted status - } - } - }; - - if (Patches.SUN_BUG_ID_4818143) { - Future accessorFuture = ApplicationManager.getApplication().executeOnPooledThread(accessor); - - try { - accessorFuture.get(DELAY_UNTIL_ABORT_CLIPBOARD_ACCESS, TimeUnit.MILLISECONDS); - } - catch (Exception e) { /* no luck */ } - - if (!success[0]) { - showWorkaroundMessage(); - accessorFuture.cancel(true); - } - } - else { - accessor.run(); - } + myClipboardSynchronizer.setContent(content, this); } private void addNewContentToStack(Transferable content) { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java index 0f759e40252a..d1140782b60f 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java @@ -16,6 +16,7 @@ package com.intellij.ide.ui; import com.intellij.CommonBundle; +import com.intellij.ide.ClipboardSynchronizer; import com.intellij.ide.IdeBundle; import com.intellij.idea.StartupUtil; import com.intellij.notification.Notification; @@ -489,6 +490,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo public void updateUI() { UIDefaults lookAndFeelDefaults=UIManager.getLookAndFeelDefaults(); initInputMapDefaults(lookAndFeelDefaults); + initActionMapDefaults(lookAndFeelDefaults); patchFileChooserStrings(lookAndFeelDefaults); if (shouldPatchLAFFonts()) { storeOriginalFontDefaults(lookAndFeelDefaults); @@ -630,6 +632,10 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo } } + private static void initActionMapDefaults(UIDefaults defaults) { + ClipboardSynchronizer.getInstance().replaceDefaultCopyPasteActions(defaults); + } + @SuppressWarnings({"HardCodedStringLiteral"}) private void initFontDefaults(UIDefaults defaults) { defaults.put("Tree.ancestorInputMap", null); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutLineEndAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutLineEndAction.java index 154423330c7c..96a96401710e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutLineEndAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutLineEndAction.java @@ -25,17 +25,13 @@ package com.intellij.openapi.editor.actions; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; import com.intellij.openapi.ide.CopyPasteManager; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.ui.EmptyClipboardOwner; -import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; public class CutLineEndAction extends EditorAction { @@ -63,7 +59,7 @@ public class CutLineEndAction extends EditorAction { } if (myCopyToClipboard) { - copyToClipboard(doc, caretOffset, lineEndOffset, dataContext, editor); + copyToClipboard(doc, caretOffset, lineEndOffset); } final int lineStartOffset = doc.getLineStartOffset(lineNumber); @@ -75,24 +71,12 @@ public class CutLineEndAction extends EditorAction { } } - private static void copyToClipboard(final Document doc, - int caretOffset, - int lineEndOffset, - DataContext dataContext, - Editor editor) { + private static void copyToClipboard(final Document doc, int caretOffset, int lineEndOffset) { String s = doc.getCharsSequence().subSequence(caretOffset, lineEndOffset).toString(); s = StringUtil.convertLineSeparators(s); StringSelection contents = new StringSelection(s); - - Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null) { - Clipboard clipboard = editor.getComponent().getToolkit().getSystemClipboard(); - clipboard.setContents(contents, EmptyClipboardOwner.INSTANCE); - } - else { - CopyPasteManager.getInstance().setContents(contents); - } + CopyPasteManager.getInstance().setContents(contents); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 917e8d449be9..699c7ff1eb09 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -55,6 +55,7 @@ import com.intellij.openapi.editor.impl.softwrap.SoftWrapHelper; import com.intellij.openapi.editor.markup.*; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.options.FontSize; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; @@ -76,7 +77,6 @@ import com.intellij.util.containers.HashMap; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.text.CharArrayUtil; import com.intellij.util.ui.ButtonlessScrollBarUI; -import com.intellij.util.ui.EmptyClipboardOwner; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.update.UiNotifyConnector; import gnu.trove.TIntArrayList; @@ -95,7 +95,6 @@ import javax.swing.border.EmptyBorder; import javax.swing.plaf.ScrollBarUI; import javax.swing.plaf.basic.BasicScrollBarUI; import java.awt.*; -import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; @@ -5164,12 +5163,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (editor.getDocument().getRangeGuard(offset, offset) != null) return; EditorActionHandler pasteHandler = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_PASTE); - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + final CopyPasteManager copyPasteManager = CopyPasteManager.getInstance(); Transferable backup = null; try { - backup = clipboard.getContents(this); - clipboard.setContents(t, EmptyClipboardOwner.INSTANCE); + backup = copyPasteManager.getContents(); + copyPasteManager.setContents(t); } catch (Exception e) { LOG.info("Error communicating with system clipboard", e); @@ -5179,7 +5178,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi pasteHandler.execute(editor, editor.getDataContext()); try { if (backup != null) { - clipboard.setContents(backup, EmptyClipboardOwner.INSTANCE); + copyPasteManager.setContents(backup); } } catch (IllegalStateException e) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java index 8a5da8c145b2..1a5c6c8f5178 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java @@ -24,9 +24,7 @@ */ package com.intellij.openapi.editor.impl; -import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.IdeActions; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.*; @@ -44,7 +42,6 @@ import com.intellij.openapi.editor.ex.PrioritizedDocumentListener; import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.ide.CopyPasteManager; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; @@ -728,15 +725,7 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi s = StringUtil.convertLineSeparators(s); StringSelection contents = new StringSelection(s); - - Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(myEditor.getContentComponent())); - if (project == null) { - Clipboard clipboard = myEditor.getComponent().getToolkit().getSystemClipboard(); - clipboard.setContents(contents, EmptyClipboardOwner.INSTANCE); - } - else { - CopyPasteManager.getInstance().setContents(contents); - } + CopyPasteManager.getInstance().setContents(contents); } public TextAttributes getTextAttributes() { diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 7ded1a7c5fc4..61305fb25489 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -10,7 +10,6 @@ button.finish=&Finish button.ok=&OK button.wizard.previous=< &Previous button.wizard.next=&Next > -error.paste.bug.workaround=You''re seeing this message because of the workaround to JRE issue: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4818143\n{0} would hang otherwise. The system clipboard might be not working correctly. It is recommended to restart {1}. title.system.error=System Error title.select.path.to.browser=Select Path to Browser title.general=General diff --git a/platform/platform-resources/src/componentSets/Platform.xml b/platform/platform-resources/src/componentSets/Platform.xml index fa0f63758036..9605bc3a9c51 100644 --- a/platform/platform-resources/src/componentSets/Platform.xml +++ b/platform/platform-resources/src/componentSets/Platform.xml @@ -123,6 +123,11 @@ com.intellij.internal.statistic.persistence.ApplicationStatisticsPersistenceComponent + + com.intellij.ide.ClipboardSynchronizer + com.intellij.ide.ClipboardSynchronizer + + com.intellij.openapi.util.FoundationLoader diff --git a/platform/util/src/com/intellij/Patches.java b/platform/util/src/com/intellij/Patches.java index c20edf165fed..eb1ac45bd11a 100644 --- a/platform/util/src/com/intellij/Patches.java +++ b/platform/util/src/com/intellij/Patches.java @@ -124,10 +124,10 @@ public class Patches { public static final boolean MAC_HIDE_QUIT_HACK = false; /** - * Causes calling thread to lock up acquiring content of the system clipboard on linux. Being called from the swing thread an - * application stops responding. + * The corresponding bug (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4818143) is marked as fixed but it isn't really fixed. + * {@link java.awt.datatransfer.Clipboard#getContents(Object)} call may took 10 seconds if clipboard owner is not responding. */ - public static final boolean SUN_BUG_ID_4818143 = SystemInfo.isLinux || SystemInfo.isFreeBSD || SystemInfo.isMac; + public static final boolean SLOW_GETTING_CLIPBOARD_CONTENTS = SystemInfo.isLinux || SystemInfo.isFreeBSD || SystemInfo.isMac; /** * Java does not recognize the optional BOM which can begin a UTF-8 stream. diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/CutCopyPasteSupport.java b/plugins/ui-designer/src/com/intellij/uiDesigner/CutCopyPasteSupport.java index 3ab7787d2e63..e4f0463a55c4 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/CutCopyPasteSupport.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/CutCopyPasteSupport.java @@ -15,19 +15,20 @@ */ package com.intellij.uiDesigner; +import com.intellij.ide.CopyPasteManagerEx; import com.intellij.ide.CopyProvider; import com.intellij.ide.CutProvider; import com.intellij.ide.PasteProvider; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.module.Module; import com.intellij.uiDesigner.compiler.Utils; import com.intellij.uiDesigner.designSurface.GuiEditor; import com.intellij.uiDesigner.lw.LwComponent; import com.intellij.uiDesigner.lw.LwContainer; import com.intellij.uiDesigner.radComponents.RadComponent; -import com.intellij.util.ui.EmptyClipboardOwner; import gnu.trove.TIntArrayList; import org.jdom.Document; import org.jdom.Element; @@ -37,7 +38,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; @@ -81,13 +81,11 @@ public final class CutCopyPasteSupport implements CopyProvider, CutProvider, Pas final SerializedComponentData data = new SerializedComponentData(serializeForCopy(myEditor, selectedComponents)); final SimpleTransferable transferable = new SimpleTransferable(data, SerializedComponentData.class, ourDataFlavor); try { - final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - clipboard.setContents(transferable, EmptyClipboardOwner.INSTANCE); + CopyPasteManager.getInstance().setContents(transferable); return true; - } catch (Exception e) { - if (LOG.isDebugEnabled()) { - LOG.debug(e); - } + } + catch (Exception e) { + LOG.debug(e); return false; } } @@ -207,13 +205,13 @@ public final class CutCopyPasteSupport implements CopyProvider, CutProvider, Pas } @Nullable - private String getSerializedComponents() { + private static String getSerializedComponents() { try { - final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - if (!clipboard.isDataFlavorAvailable(ourDataFlavor)) { + final CopyPasteManagerEx copyPasteManager = CopyPasteManagerEx.getInstanceEx(); + if (!copyPasteManager.isDataFlavorAvailable(ourDataFlavor)) { return null; } - final Transferable content = clipboard.getContents(this); + final Transferable content = copyPasteManager.getContents(); final Object transferData; try { transferData = content.getTransferData(ourDataFlavor); diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/ShowXPathAction.java b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/ShowXPathAction.java index 593a280fd4dc..d6d1f4fcd836 100644 --- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/ShowXPathAction.java +++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/ShowXPathAction.java @@ -24,6 +24,7 @@ import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.psi.PsiDocumentManager; @@ -36,20 +37,14 @@ import com.intellij.ui.HintHint; import com.intellij.ui.InplaceButton; import com.intellij.ui.LightweightHint; import com.intellij.ui.components.panels.NonOpaquePanel; -import com.intellij.util.ui.BaseButtonBehavior; -import com.intellij.util.ui.EmptyClipboardOwner; import org.intellij.plugins.xpathView.support.XPathSupport; import org.intellij.plugins.xpathView.util.HighlighterUtil; import javax.swing.*; -import javax.swing.border.BevelBorder; -import javax.swing.border.LineBorder; import java.awt.*; -import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; public class ShowXPathAction extends XPathAction { public void update(AnActionEvent event) { @@ -124,7 +119,7 @@ public class ShowXPathAction extends XPathAction { InplaceButton copy = new InplaceButton(ActionsBundle.message("action.EditorCopy.text"), IconLoader.getIcon("/actions/copy.png"), new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(path), EmptyClipboardOwner.INSTANCE); + CopyPasteManager.getInstance().setContents(new StringSelection(path)); } });