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 package com.muwire.gui.chat
import com.muwire.gui.CopyPasteSupport
import com.muwire.gui.UISettings import com.muwire.gui.UISettings
import com.muwire.gui.contacts.POPLabel 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.PersonaOrProfile
import com.muwire.gui.profile.ProfileConstants import com.muwire.gui.profile.ProfileConstants
import sun.swing.UIAction import sun.swing.UIAction
@ -14,6 +18,7 @@ import javax.swing.event.MenuKeyListener
import javax.swing.text.* import javax.swing.text.*
import java.awt.* import java.awt.*
import java.awt.event.ActionEvent import java.awt.event.ActionEvent
import java.awt.event.InputEvent
import java.awt.event.KeyAdapter import java.awt.event.KeyAdapter
import java.awt.event.KeyEvent import java.awt.event.KeyEvent
import java.util.List import java.util.List
@ -90,6 +95,10 @@ class ChatEntryPane extends JTextPane {
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0) KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)
Object enterObject = inputMap.get(enter) Object enterObject = inputMap.get(enter)
actionMap.put(enterObject, noAction) actionMap.put(enterObject, noAction)
Action originalPasteAction = actionMap.get(DefaultEditorKit.pasteAction)
Action linkPasteAction = new LinkPasteAction(originalPasteAction)
actionMap.put(DefaultEditorKit.pasteAction, linkPasteAction)
} }
private String getTextSinceAt(){ private String getTextSinceAt(){
@ -211,9 +220,17 @@ class ChatEntryPane extends JTextPane {
sb.append(c) sb.append(c)
continue continue
} }
POPLabel label = (POPLabel) component if (component instanceof POPLabel) {
sb.append(label.personaOrProfile.getPersona().toBase64()) POPLabel label = (POPLabel) component
sb.append(AT) 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() sb.toString()
} }
@ -256,7 +273,7 @@ class ChatEntryPane extends JTextPane {
position++ position++
} }
} else { } else {
while (position > 0) { while (position >= 0) {
if (!isInComponent(position)) if (!isInComponent(position))
break break
delegate.actionPerformed(e) 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 { private static class NullAction extends UIAction {
NullAction() { NullAction() {
super("nothing") 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()
}