Skip to content

Commit

Permalink
粘贴板功能实现
Browse files Browse the repository at this point in the history
  • Loading branch information
SpringStudent committed Jan 2, 2025
1 parent 9b3015f commit 934aeda
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@
import cn.hutool.core.util.IdUtil;
import io.github.springstudent.dekstop.client.RemoteClient;
import io.github.springstudent.dekstop.client.bean.TransferableFiles;
import io.github.springstudent.dekstop.common.bean.Constants;
import io.github.springstudent.dekstop.common.bean.FileInfo;
import io.github.springstudent.dekstop.common.bean.RemoteClipboard;
import io.github.springstudent.dekstop.common.command.Cmd;
import io.github.springstudent.dekstop.common.command.CmdClipboardText;
import io.github.springstudent.dekstop.common.command.CmdClipboardTransfer;
import io.github.springstudent.dekstop.common.command.CmdType;
import io.github.springstudent.dekstop.common.command.*;
import io.github.springstudent.dekstop.common.log.Log;
import io.github.springstudent.dekstop.common.utils.EmptyUtils;
import io.github.springstudent.dekstop.common.utils.NettyUtils;
Expand All @@ -24,6 +22,8 @@
import java.io.File;
import java.util.List;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;

import static io.github.springstudent.dekstop.common.utils.RemoteUtils.REQUEST_URL_KEY;
import static io.github.springstudent.dekstop.common.utils.RemoteUtils.TMP_PATH_KEY;
Expand Down Expand Up @@ -74,6 +74,7 @@ protected void showMessageDialog(Object msg, int messageType) {
}

protected void sendClipboard() {
AtomicBoolean sendFlag = new AtomicBoolean(false);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) {
String text = null;
Expand All @@ -83,7 +84,9 @@ protected void sendClipboard() {
Log.error("clipboard.getData(DataFlavor.stringFlavor) error", e);
}
if (EmptyUtils.isNotEmpty(text)) {
this.fireCmd(new CmdClipboardText(text));
final String finalText = text;
this.fireCmd(new CmdClipboardText(finalText));
sendFlag.set(true);
}
} else if (clipboard.isDataFlavorAvailable(DataFlavor.imageFlavor)) {
BufferedImage image = null;
Expand All @@ -100,8 +103,9 @@ protected void sendClipboard() {
outputFile = new File(uploadDir + File.separator + IdUtil.fastSimpleUUID() + ".png");
ImageIO.write(clipboardImage, "png", outputFile);
doSendClipboard(Arrays.asList(outputFile));
sendFlag.set(true);
} catch (Exception e) {
Log.error("sendClipboard error", e);
Log.error("send clipboardImage error", e);
} finally {
if (outputFile != null) {
FileUtil.del(outputFile);
Expand All @@ -121,27 +125,32 @@ protected void sendClipboard() {
new Thread(() -> {
try {
doSendClipboard(finalFiles);
sendFlag.set(true);
} catch (Exception e) {
Log.error("sendClipboard error", e);
Log.error("send clipboardFiles error", e);
}
});
}).start();
}
}
//未发送成功,设置粘贴板按钮可点
if (!sendFlag.get()) {
if (getType().equals(Constants.CONTROLLER)) {
RemoteClient.getRemoteClient().getRemoteScreen().transferClipboarButton(true);
} else {
fireCmd(new CmdResRemoteClipboard());
}
}
}

public void doSendClipboard(List<File> files) throws Exception {
private void doSendClipboard(List<File> files) throws Exception {
Map<String, Object> map = new HashMap<>();
map.put(REQUEST_URL_KEY, RemoteClient.getRemoteClient().getClipboardServer());
//clear clipboardInfo
RemoteUtils.clearClipboard(getDeviceCode(), map);
//upload clipboard file and folder
List<RemoteClipboard> remoteClipboards = new ArrayList<>();
for (File file : files) {
processFile(file, null, remoteClipboards);
}
//save clipboard info
RemoteUtils.saveClipboard(remoteClipboards, map);
//notice remote to download clipboard
fireCmd(new CmdClipboardTransfer(getDeviceCode()));
}

Expand Down Expand Up @@ -177,7 +186,7 @@ private void processFile(File file, String filePid, List<RemoteClipboard> remote
}
}

public String getDeviceCode() {
private String getDeviceCode() {
if (channel != null) {
String deviceCode = NettyUtils.getDeviceCode(this.channel);
if (EmptyUtils.isEmpty(deviceCode)) {
Expand All @@ -190,24 +199,25 @@ public String getDeviceCode() {
}
}


protected void setClipboard(Cmd cmd) {
try {
if (cmd.getType().equals(CmdType.ClipboardText)) {
StringSelection stringSelection = new StringSelection(((CmdClipboardText) cmd).getPayload());
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, this);
} else if (cmd.getType().equals(CmdType.ClipboardTransfer)) {
String deviceCode = ((CmdClipboardTransfer) cmd).getDeviceCode();
Map<String, Object> map = new HashMap<>();
map.put(REQUEST_URL_KEY, RemoteClient.getRemoteClient().getClipboardServer());
List<RemoteClipboard> remoteClipboards = RemoteUtils.getClipboard(deviceCode, map);
if (EmptyUtils.isNotEmpty(remoteClipboards)) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new TransferableFiles(processClipboard(remoteClipboards)), this);
protected CompletableFuture setClipboard(Cmd cmd) {
return CompletableFuture.runAsync(() -> {
try {
if (cmd.getType().equals(CmdType.ClipboardText)) {
StringSelection stringSelection = new StringSelection(((CmdClipboardText) cmd).getPayload());
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, this);
} else if (cmd.getType().equals(CmdType.ClipboardTransfer)) {
String deviceCode = ((CmdClipboardTransfer) cmd).getDeviceCode();
Map<String, Object> map = new HashMap<>();
map.put(REQUEST_URL_KEY, RemoteClient.getRemoteClient().getClipboardServer());
List<RemoteClipboard> remoteClipboards = RemoteUtils.getClipboard(deviceCode, map);
if (EmptyUtils.isNotEmpty(remoteClipboards)) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new TransferableFiles(processClipboard(remoteClipboards)), this);
}
}
} catch (Exception e) {
Log.error("setClipboard error", e);
}
} catch (Exception e) {
Log.error("setClipboard error", e);
}
});
}

public List<File> processClipboard(List<RemoteClipboard> remoteClipboards) throws Exception {
Expand Down Expand Up @@ -246,6 +256,7 @@ private void downloadClipboardFile(String tmpDir, RemoteClipboard remoteClipboar

public abstract void handleCmd(Cmd cmd);

public abstract String getType();

public void start() {
}
Expand All @@ -255,6 +266,6 @@ public void stop() {

@Override
public void lostOwnership(Clipboard clipboard, Transferable contents) {

Log.info("lostOwnership ....");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.github.springstudent.dekstop.client.compress.CompressorEngine;
import io.github.springstudent.dekstop.client.compress.CompressorEngineListener;
import io.github.springstudent.dekstop.common.bean.CompressionMethod;
import io.github.springstudent.dekstop.common.bean.Constants;
import io.github.springstudent.dekstop.common.bean.MemByteBuffer;
import io.github.springstudent.dekstop.common.command.*;
import io.github.springstudent.dekstop.common.configuration.CaptureEngineConfiguration;
Expand Down Expand Up @@ -91,10 +92,17 @@ public void handleCmd(Cmd cmd) {
} else if (cmd.getType().equals(CmdType.ReqRemoteClipboard)) {
super.sendClipboard();
} else if (cmd.getType().equals(CmdType.ClipboardText) || cmd.getType().equals(CmdType.ClipboardTransfer)) {
super.setClipboard(cmd);
super.setClipboard(cmd).whenComplete((o, o2) -> {
fireCmd(new CmdResRemoteClipboard());
});
}
}

@Override
public String getType() {
return Constants.CONTROLLED;
}

@Override
public void onCompressed(int captureId, CompressionMethod compressionMethod, CompressorEngineConfiguration compressionConfiguration, MemByteBuffer compressed) {
fireCmd(new CmdCapture(captureId, compressionMethod, compressionConfiguration, compressed));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,17 @@ public void handleCmd(Cmd cmd) {
deCompressorEngine.handleCapture((CmdCapture) cmd);
countReceivedBit(cmd);
} else if (cmd.getType().equals(CmdType.ClipboardText) || cmd.getType().equals(CmdType.ClipboardTransfer)) {
super.setClipboard(cmd);
super.setClipboard(cmd).whenComplete((o, o2) -> RemoteClient.getRemoteClient().getRemoteScreen().transferClipboarButton(true));
} else if (cmd.getType().equals(CmdType.ResCapture)) {
RemoteClient.getRemoteClient().getRemoteScreen().transferClipboarButton(true);
}
}

@Override
public String getType() {
return Constants.CONTROLLED;
}

private void countReceivedBit(Cmd cmd) {
receivedBitCounter.add(8d * cmd.getWireSize());
}
Expand Down Expand Up @@ -444,16 +451,17 @@ public void actionPerformed(ActionEvent ev) {
}

private void requireRemoteClipboard() {
RemoteClient.getRemoteClient().getRemoteScreen().transferClipboarButton(false);
new Thread(() -> fireCmd(new CmdReqRemoteClipboard()));
}

public Action createSendLoacalClibboardAction() {
final Action setRemoteClipboard = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ev) {
RemoteClient.getRemoteClient().getRemoteScreen().transferClipboarButton(false);
RemoteController.this.sendClipboard();
}

};
setRemoteClipboard.putValue(Action.SHORT_DESCRIPTION, "发送本机粘贴板");
setRemoteClipboard.putValue(Action.SMALL_ICON, ImageUtilities.getOrCreateIcon("up.png"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public class RemoteScreen extends JFrame {

private Timer sessionTimer;

private JButton reqClipboardButton;

private JButton sendClipboardButton;

private final AtomicBoolean fitToScreenActivated = new AtomicBoolean(false);

private final AtomicBoolean keepAspectRatioActivated = new AtomicBoolean(false);
Expand Down Expand Up @@ -126,16 +130,21 @@ public void actionPerformed(ActionEvent ev) {
if (EmptyUtils.isNotEmpty(RemoteClient.getRemoteClient().getClipboardServer())) {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
JButton getClipboardButton = createButton(RemoteClient.getRemoteClient().getController().createRequireRemoteClipboardAction());
JButton sendClipboardButton = createButton(RemoteClient.getRemoteClient().getController().createSendLoacalClibboardAction());
buttonPanel.add(getClipboardButton);
this.reqClipboardButton = createButton(RemoteClient.getRemoteClient().getController().createRequireRemoteClipboardAction());
this.sendClipboardButton = createButton(RemoteClient.getRemoteClient().getController().createSendLoacalClibboardAction());
buttonPanel.add(reqClipboardButton);
buttonPanel.add(Box.createHorizontalStrut(10));
buttonPanel.add(sendClipboardButton);
menuBar.add(buttonPanel);
}
this.setJMenuBar(menuBar);
}

public final void transferClipboarButton(boolean enabled) {
this.sendClipboardButton.setEnabled(enabled);
this.sendClipboardButton.setEnabled(enabled);
}

private JButton createButton(Action action) {
final JButton button = new JButton();
button.setMargin(new Insets(1, 1, 1, 1));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.github.springstudent.dekstop.common.command;

import io.netty.buffer.ByteBuf;

import java.io.IOException;

/**
* @author ZhouNing
* @date 2025/1/2 16:25
**/
public class CmdResRemoteClipboard extends Cmd {

@Override
public CmdType getType() {
return CmdType.ResRemoteClipboard;
}

@Override
public int getWireSize() {
return 0;
}

@Override
public String toString() {
return CmdResRemoteClipboard.class.getSimpleName();
}

@Override
public void encode(ByteBuf out) throws IOException {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public enum CmdType {
ResCliInfo,
ResCapture,
ResPong,

ResRemoteClipboard,
Capture,
CompressorConfig,
CaptureConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteB
case ClipboardTransfer:
list.add(CmdClipboardTransfer.decode(byteBuf));
break;
case ResRemoteClipboard:
list.add(new CmdResRemoteClipboard());
break;
default:
throw new IllegalArgumentException(format("unknown cmdType=%s", cmdType));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,10 @@ public static List<RemoteClipboard> getClipboard(String deviceCode, Map<String,
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("deviceCode", deviceCode);
JSONObject result = parseObj(HttpRequest.get(reqUrl + GET_CLIPBOARD).form(paramMap).timeout(reqTimeout).execute().body());
return buildTree(JSONUtil.toList(result.getStr("result"), RemoteClipboard.class));
return buildClipboard(JSONUtil.toList(result.getStr("result"), RemoteClipboard.class));
}

public static List<RemoteClipboard> buildTree(List<RemoteClipboard> clipboards) {
public static List<RemoteClipboard> buildClipboard(List<RemoteClipboard> clipboards) {
Map<String, RemoteClipboard> clipboardMap = clipboards.stream()
.collect(Collectors.toMap(RemoteClipboard::getId, clipboard -> clipboard));
List<RemoteClipboard> roots = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ protected void channelRead0(ChannelHandlerContext ctx, Cmd cmd) throws Exception
} else {
ctx.channel().writeAndFlush(new CmdResCapture(CmdResCapture.STOP_));
}
} else if (cmd.getType().equals(CmdType.CaptureConfig) || cmd.getType().equals(CmdType.CompressorConfig) || cmd.getType().equals(CmdType.KeyControl) || cmd.getType().equals(CmdType.MouseControl) || cmd.getType().equals(CmdType.ReqRemoteClipboard)) {
} else if (cmd.getType().equals(CmdType.CaptureConfig) || cmd.getType().equals(CmdType.CompressorConfig) || cmd.getType().equals(CmdType.KeyControl) || cmd.getType().equals(CmdType.MouseControl) || cmd.getType().equals(CmdType.ReqRemoteClipboard) || cmd.getType().equals(CmdType.ResRemoteClipboard)) {
if (StrUtil.isNotEmpty(NettyUtils.getControllFlag(ctx.channel()))) {
Channel controlledChannel = NettyChannelManager.getControlledChannel(ctx.channel());
if (controlledChannel != null) {
Expand Down

0 comments on commit 934aeda

Please sign in to comment.