IJ-CR-3109: Modifies PasteHandler to allow any data flavour to pass through and delegate calls to [PasteProvider]s.

GitOrigin-RevId: 6f2f22af81438695b59b3dc969f02f360dfb7967
This commit is contained in:
Razmik Seysyan
2020-09-24 19:27:43 +02:00
committed by intellij-monorepo-bot
parent 34ad8e628f
commit 5c2dd84e8e
5 changed files with 52 additions and 73 deletions

View File

@@ -26,8 +26,7 @@
<fileLookupInfoProvider implementation="org.intellij.images.completion.ImageLookupInfoProvider"/>
<documentationProvider implementation="org.intellij.images.fileTypes.ImageDocumentationProvider"/>
<customPasteProvider implementation="org.intellij.images.project.ImagePasteProvider"/>
<filePasteProvider implementation="org.intellij.images.project.ImagePasteProvider" order="last"/>
<filePasteProvider implementation="org.intellij.images.ide.ImagePasteProvider" order="last"/>
<projectService serviceImplementation="org.intellij.images.search.ImageTagManager"/>
<registryKey key="ide.images.wheel.zooming" defaultValue="true" description="Enable zoom in/out by mouse wheel"/>

View File

@@ -1,45 +0,0 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.intellij.images.codeInsight
import com.intellij.codeInsight.editorActions.PasteHandler
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.Caret
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.actionSystem.EditorActionHandler
import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.ide.CopyPasteManager
import com.intellij.util.Producer
import java.awt.datatransfer.DataFlavor
import java.awt.datatransfer.Transferable
abstract class ImagePasteHandler(originalAction: EditorActionHandler) : PasteHandler(originalAction) {
abstract val supportedFileType: FileType
// prevents to be overridden in descendants
final override fun isEnabledForCaret(editor: Editor, caret: Caret, dataContext: DataContext?): Boolean =
super.isEnabledForCaret(editor, caret, dataContext) //
final override fun doExecute(editor: Editor, caret: Caret?, dataContext: DataContext?) =
when (dataContext?.getData(CommonDataKeys.VIRTUAL_FILE)?.fileType) {
supportedFileType -> {
assert(caret == null) { "Invocation of 'paste' operation for specific caret is not supported" }
// Provides special producer that extracts image from clipboard
execute(editor, dataContext, Producer<Transferable> {
CopyPasteManager.getInstance().let { manager ->
if (manager.areDataFlavorsAvailable(DataFlavor.imageFlavor))
manager.contents
else
null
}
})
executedOnSupportedFile(editor, dataContext)
}
else -> super.doExecute(editor, caret, dataContext)
}
open fun executedOnSupportedFile(editor: Editor, dataContext: DataContext?) = Unit
}

View File

@@ -0,0 +1,27 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.intellij.images.ide
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.vfs.VirtualFile
/**
* Represents a paste provider that allows to paste screenshots (from clipboard) as PNG files and insert links to currently edited document.
*
* NOTE: If registered as `customPasteProvider` handles paste operations in editor.
*/
abstract class EditorImagePasteProvider : ImagePasteProvider() {
abstract val supportedFileType: FileType
final override fun isEnabledForDataContext(dataContext: DataContext): Boolean =
dataContext.getData(CommonDataKeys.EDITOR) != null &&
dataContext.getData(CommonDataKeys.VIRTUAL_FILE)?.fileType == supportedFileType
final override fun imageFilePasted(dataContext: DataContext, imageFile: VirtualFile) {
dataContext.getData(CommonDataKeys.EDITOR)?.imageFilePasted(imageFile)
}
abstract fun Editor.imageFilePasted(imageFile: VirtualFile)
}

View File

@@ -1,7 +1,6 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.intellij.images.project
package org.intellij.images.ide
import com.intellij.codeInsight.editorActions.PasteHandler
import com.intellij.ide.PasteProvider
import com.intellij.lang.LangBundle
import com.intellij.openapi.actionSystem.CommonDataKeys
@@ -10,10 +9,9 @@ import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.ide.CopyPasteManager
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import java.awt.Image
import java.awt.datatransfer.DataFlavor
import java.awt.datatransfer.DataFlavor.imageFlavor
import java.awt.image.BufferedImage
import java.awt.image.MultiResolutionImage
@@ -22,20 +20,20 @@ import javax.imageio.ImageIO
/**
* Allows to paste screenshots as PNG files.
* Represents a basic paste provider that allows to paste screenshots (from clipboard) as PNG files.
*
* NOTE: Text editors allows only [DataFlavor.stringFlavor] content to be pasted.
* [ImagePasteProvider] is called when pasting to an editor (not to the project view) only if there is a [PasteHandler] that extracts data with [DataFlavor.imageFlavor].
* @see [ImagePasteHandler.doExecute]
* NOTE: If registered as `filePasteProvider` handles paste operations in project view.
*/
class ImagePasteProvider : PasteProvider {
override fun isPasteEnabled(dataContext: DataContext): Boolean =
dataContext.getData(CommonDataKeys.VIRTUAL_FILE) != null
&& CopyPasteManager.getInstance().areDataFlavorsAvailable(imageFlavor)
open class ImagePasteProvider : PasteProvider {
final override fun isPastePossible(dataContext: DataContext): Boolean = true
final override fun isPasteEnabled(dataContext: DataContext): Boolean =
CopyPasteManager.getInstance().areDataFlavorsAvailable(imageFlavor)
&& dataContext.getData(CommonDataKeys.VIRTUAL_FILE) != null
&& isEnabledForDataContext(dataContext)
override fun isPastePossible(dataContext: DataContext): Boolean = true
open fun isEnabledForDataContext(dataContext: DataContext): Boolean = true
override fun performPaste(dataContext: DataContext) {
final override fun performPaste(dataContext: DataContext) {
val project = dataContext.getData(CommonDataKeys.PROJECT) ?: return
val currentFile = dataContext.getData(CommonDataKeys.VIRTUAL_FILE) ?: return
val pasteContents = CopyPasteManager.getInstance().contents ?: return
@@ -100,14 +98,11 @@ class ImagePasteProvider : PasteProvider {
return@runWriteAction
}
dataContext.getData(CommonDataKeys.EDITOR)?.putUserData(PASTED_FILE_NAME, imageFile.name)
imageFilePasted(dataContext, imageFile)
}
}
companion object {
@JvmStatic
val PASTED_FILE_NAME = Key.create<String>("pasteFileName")
}
open fun imageFilePasted(dataContext: DataContext, imageFile: VirtualFile) = Unit
}
private fun Image.toBufferedImage() = let { img ->
@@ -126,5 +121,3 @@ private fun Image.toBufferedImage() = let { img ->
}
}
}

View File

@@ -58,13 +58,18 @@ public class PasteHandler extends EditorActionHandler implements EditorTextInser
execute(editor, dataContext, null);
}
private static Transferable getContentsToPasteToEditor(@Nullable Producer<Transferable> producer) {
if (producer == null) {
return CopyPasteManager.getInstance().getContents();
}
else {
return producer.produce();
}
}
@Override
public void execute(Editor editor, DataContext dataContext, @Nullable Producer<Transferable> producer) {
final Transferable transferable = EditorModificationUtil.getContentsToPasteToEditor(producer);
if (transferable == null) {
myOriginalHandler.execute(editor, null, dataContext);
return;
}
final Transferable transferable = getContentsToPasteToEditor(producer);
if (!EditorModificationUtil.checkModificationAllowed(editor)) return;