intercept paste action in chat entry box for mu links

dbus-notify
Zlatin Balevsky 2022-08-04 20:16:01 +01:00
parent 002709457b
commit 5628c39d57
No known key found for this signature in database
GPG Key ID: A72832072D525E41
5 changed files with 186 additions and 5 deletions

View File

@ -1,8 +1,12 @@
package com.muwire.gui.chat
import com.muwire.gui.CopyPasteSupport
import com.muwire.gui.UISettings
import com.muwire.gui.contacts.POPLabel
import com.muwire.gui.mulinks.CollectionMuLink
import com.muwire.gui.mulinks.FileMuLink
import com.muwire.gui.mulinks.InvalidMuLinkException
import com.muwire.gui.mulinks.MuLink
import com.muwire.gui.profile.PersonaOrProfile
import com.muwire.gui.profile.ProfileConstants
import sun.swing.UIAction
@ -14,6 +18,7 @@ import javax.swing.event.MenuKeyListener
import javax.swing.text.*
import java.awt.*
import java.awt.event.ActionEvent
import java.awt.event.InputEvent
import java.awt.event.KeyAdapter
import java.awt.event.KeyEvent
import java.util.List
@ -90,6 +95,10 @@ class ChatEntryPane extends JTextPane {
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)
Object enterObject = inputMap.get(enter)
actionMap.put(enterObject, noAction)
Action originalPasteAction = actionMap.get(DefaultEditorKit.pasteAction)
Action linkPasteAction = new LinkPasteAction(originalPasteAction)
actionMap.put(DefaultEditorKit.pasteAction, linkPasteAction)
}
private String getTextSinceAt(){
@ -211,9 +220,17 @@ class ChatEntryPane extends JTextPane {
sb.append(c)
continue
}
POPLabel label = (POPLabel) component
sb.append(label.personaOrProfile.getPersona().toBase64())
sb.append(AT)
if (component instanceof POPLabel) {
POPLabel label = (POPLabel) component
sb.append(label.personaOrProfile.getPersona().toBase64())
sb.append(AT)
}
if (component instanceof MuLinkLabel) {
MuLinkLabel label = (MuLinkLabel) component
sb.append("<")
sb.append(label.link.toLink())
sb.append(">")
}
}
sb.toString()
}
@ -256,7 +273,7 @@ class ChatEntryPane extends JTextPane {
position++
}
} else {
while (position > 0) {
while (position >= 0) {
if (!isInComponent(position))
break
delegate.actionPerformed(e)
@ -266,6 +283,41 @@ class ChatEntryPane extends JTextPane {
}
}
private class LinkPasteAction extends UIAction {
private final Action delegate
LinkPasteAction(Action delegate) {
super("Paste")
this.delegate = delegate
}
@Override
void actionPerformed(ActionEvent e) {
if(!CopyPasteSupport.canPasteString())
return
String string = CopyPasteSupport.pasteFromClipboard()
try {
MuLink link = MuLink.parse(string)
JLabel label = null
if (link.getLinkType() == MuLink.LinkType.FILE) {
label = new FileLinkLabel((FileMuLink) link, settings, true)
} else if (link.getLinkType() == MuLink.LinkType.COLLECTION) {
label = new CollectionLinkLabel((CollectionMuLink)link, settings, true)
}
final int position = getCaret().getDot()
StyledDocument document = getStyledDocument()
Style style = document.addStyle("newStyle", null)
StyleConstants.setComponent(style, label)
document.insertString(position, " ", style)
} catch (InvalidMuLinkException notALink) {
delegate.actionPerformed(e)
}
}
}
private static class NullAction extends UIAction {
NullAction() {
super("nothing")

View File

@ -0,0 +1,22 @@
package com.muwire.gui.chat
import com.muwire.gui.HTMLSanitizer
import com.muwire.gui.SizeFormatter
import com.muwire.gui.UISettings
import com.muwire.gui.mulinks.CollectionMuLink
class CollectionLinkLabel extends MuLinkLabel {
CollectionLinkLabel(CollectionMuLink link, UISettings settings, boolean border) {
super(link, settings, border)
}
@Override
protected String getVisibleText() {
CollectionMuLink link = (CollectionMuLink) this.link
StringBuffer sb = new StringBuffer()
SizeFormatter.format(link.totalSize, sb)
return HTMLSanitizer.escape(link.name) + " (" + link.numFiles + " files " + sb.toString()+")"
}
}

View File

@ -0,0 +1,22 @@
package com.muwire.gui.chat
import com.muwire.gui.HTMLSanitizer
import com.muwire.gui.SizeFormatter
import com.muwire.gui.UISettings
import com.muwire.gui.mulinks.FileMuLink
class FileLinkLabel extends MuLinkLabel {
FileLinkLabel(FileMuLink link, UISettings settings, boolean border) {
super(link, settings, border)
}
protected String getVisibleText() {
FileMuLink link = (FileMuLink) this.link
StringBuffer sb = new StringBuffer()
SizeFormatter.format(link.fileSize, sb)
HTMLSanitizer.escape(link.name) + " (" + sb.toString() + ")"
}
}

View File

@ -0,0 +1,39 @@
package com.muwire.gui.chat
import com.muwire.gui.UISettings
import com.muwire.gui.mulinks.FileMuLink
import javax.swing.Icon
import javax.swing.ImageIcon
import javax.swing.JButton
import javax.swing.JPanel
import java.awt.BorderLayout
import java.awt.Image
import java.util.function.Consumer
class FileLinkPanel extends JPanel {
private static final Icon DOWN_ICON
static {
DOWN_ICON = new ImageIcon(FileLinkPanel.class.getClassLoader().getResource("down_arrow.png"))
}
private final FileMuLink link
private final UISettings settings
private final Consumer<FileMuLink> linkConsumer
FileLinkPanel(FileMuLink link, UISettings settings, Consumer<FileMuLink> linkConsumer) {
super()
this.linkConsumer = linkConsumer
setLayout(new BorderLayout())
def label = new FileLinkLabel(link, settings, false)
add(label, BorderLayout.CENTER)
JButton button = new JButton()
button.setIcon(DOWN_ICON)
button.addActionListener({linkConsumer.accept(link)})
add(button, BorderLayout.EAST)
}
}

View File

@ -0,0 +1,46 @@
package com.muwire.gui.chat
import com.muwire.gui.UISettings
import com.muwire.gui.mulinks.MuLink
import javax.swing.*
import javax.swing.border.Border
import java.awt.*
abstract class MuLinkLabel extends JLabel {
final MuLink link
private final UISettings settings
MuLinkLabel(MuLink link, UISettings settings, boolean border) {
super()
this.link = link
this.settings = settings
String visibleText = getVisibleText()
setText("<html>$visibleText</html>")
int preferredX = 0, preferredY = 24
FontMetrics fontMetrics = getFontMetrics(getFont())
for (int i = 0; i < visibleText.length(); i++) {
char c = text.charAt(i)
preferredX += fontMetrics.charWidth(c)
}
if (border) {
Border b = BorderFactory.createEtchedBorder()
setBorder(b)
Insets insets = b.getBorderInsets(this)
preferredX += insets.left
preferredX += insets.right
}
setMaximumSize([preferredX, preferredY] as Dimension)
float alignmentY = 0.5f + (settings.fontSize * 1f / preferredY) / 2
setAlignmentY(alignmentY)
}
protected abstract String getVisibleText()
}