📄 sendimwindow.java
字号:
}
/**
* 发送群消息
* @param string
*/
protected void sendMessage(String s) {
// 检查消息是否为空
if(s.length() == 0) {
MessageDialog.openWarning(getShell(), LumaQQ.getString("message.box.common.warning.title"), LumaQQ.getString("message.box.cannot.send.empty.message"));
return;
}
// 判断用户是否登录
if(main.getClient().getUser().isLoggedIn()) {
message = s;
// 保存到聊天记录中
date.setTime(System.currentTimeMillis());
main.getMessageManager().saveMessage(model.getQQ(), model.getQQ(), main.getMyModel().getQQ(), message, (int)(date.getTime() / 1000));
// 设置输入框暂时不可写
inputBox.setReadonly(true);
inputBox.setBackground(Colors.READONLY_BACKGROUND);
// 计算分片数
totalFragments = message.length() / QQ.MAX_SEND_IM_SIZE + 1;
// 初始化其他变量
currentFragment = -1;
messageId = MessageIDGenerator.getNext();
// 发送下一个分片
sendNextFragment();
// 把发送的消息显示到输出框中
if(talkMode)
appendMessage((String)main.getMyModel().getProperty(INode.NAME), message, date);
// 清空发送框
if(talkMode)
inputBox.clear();
else
getShell().setMinimized(true);
} else {
MessageDialog.openWarning(getShell(), LumaQQ.getString("message.box.common.warning.title"), LumaQQ.getString("message.box.please.login.first"));
}
}
/**
* 发送下一个分片
*
* @return
* true表示发送成功,false表示已经没有更多分片需要发送
*/
private boolean sendNextFragment() {
// 得到下一个要发送的分片
String fragment = getNextFragment();
if(fragment == null)
return false;
// 发送
LineStyle style = main.getDefaultStyle();
main.getClient().sendIM(
model.getQQ(),
fragment,
messageId,
totalFragments,
currentFragment,
style.fontName,
(style.fontStyle & SWT.BOLD) != 0,
(style.fontStyle & SWT.ITALIC) != 0,
false,
style.fontSize,
style.foreground.getRed(),
style.foreground.getGreen(),
style.foreground.getBlue(),
QQ.QQ_IM_NORMAL_REPLY);
return true;
}
/**
* @return
* 下一个要发送的分片,如果为null,表示已经发送完成
*/
private String getNextFragment() {
if(++currentFragment == totalFragments)
return null;
int start = QQ.MAX_SEND_IM_SIZE * currentFragment;
int end = QQ.MAX_SEND_IM_SIZE + start;
if(end > message.length())
end = message.length();
fragment = message.substring(start, end);
return fragment;
}
/**
* 显示记录控件
*/
private void showRecord() {
GridData gd = (GridData)viewer.getLayoutData();
Shell shell = getShell();
if(gd.heightHint == 0) {
gd.heightHint = 200;
viewer.setVisible(true);
viewer.refreshRecord(false);
if(talkMode)
getShell().setSize(470, viewer.isVisible() ? 630 : 430);
else
getShell().setSize(440, viewer.isVisible() ? 540 : 340);
} else {
viewer.setVisible(false);
gd.heightHint = 0;
if(talkMode)
getShell().setSize(470, viewer.isVisible() ? 630 : 430);
else
getShell().setSize(440, viewer.isVisible() ? 540 : 340);
}
viewer.getParent().layout();
shell.layout();
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.qq.events.IQQListener#qqEvent(edu.tsinghua.lumaqq.qq.events.QQEvent)
*/
public void qqEvent(QQEvent e) {
switch(e.type) {
case QQEvent.QQ_SEND_IM_SUCCESS:
processSendIMSuccess(e);
break;
case QQEvent.QQ_ACCEPT_SEND_FILE:
processAcceptSendFile(e);
break;
case QQEvent.QQ_REJECT_SEND_FILE:
processRejectSendFile(e);
break;
case QQEvent.QQ_CANCEL_SEND_FILE:
processCancelSendFile(e);
break;
case QQEvent.QQ_NOTIFY_FILE_TRANSFER_ARGS:
processNotifyFileTransferArgs(e);
break;
case QQEvent.QQ_REQUEST_ME_CONNECT:
processRequestMeConnect(e);
break;
case QQEvent.QQ_OPERATION_TIMEOUT:
if(e.operation == QQ.QQ_CMD_SEND_IM)
processSendIMTimeout(e);
break;
}
}
/**
* 处理0x003F,对方请求我首先连接他,这种情况发生在我处于内网,而对方处于外网时
* @param e
*/
private void processRequestMeConnect(QQEvent e) {
ReceiveIMPacket p = (ReceiveIMPacket)e.getSource();
FileWatcher watcher = (FileWatcher)watchers.get(new Integer(p.normalHeader.sequence));
if(watcher instanceof FileReceiver) {
FileReceiver receiver = (FileReceiver)watcher;
if(receiver.getCondition() == QQ.QQ_I_AM_BEHIND_FIREWALL)
receiver.notifyNATPort();
}
}
/**
* 处理0x003B,好像是通知实际IP的意思
* @param e
*/
private void processNotifyFileTransferArgs(QQEvent e) {
ReceiveIMPacket p = (ReceiveIMPacket)e.getSource();
FileReceiver receiver = (FileReceiver)watchers.get(new Integer(p.normalHeader.sequence));
if(receiver != null) {
receiver.setHisMinorPort(p.fileArgs.minorPort);
receiver.setHisLocalIp(p.fileArgs.localIp);
receiver.startMinorPort();
receiver.start();
receiver.selectPort();
}
}
/**
* 处理文件传输取消事件
* @param e
*/
private void processCancelSendFile(QQEvent e) {
ReceiveIMPacket packet = (ReceiveIMPacket)e.getSource();
if(packet.normalHeader.sender == model.getQQ()) {
final Integer sessionId = new Integer(packet.normalHeader.sequence);
final FileWatcher watcher = (FileWatcher)watchers.get(sessionId);
// 设置watcher状态
if(watcher != null) {
watcher.abort();
// 显示提示信息
main.getDisplay().syncExec(
new Runnable() {
public void run() {
removeFileSession(sessionId);
removeFileItem(sessionId);
appendRunnable.hint = LumaQQ.getString("text.cancel.transfer.file", new Object[] { watcher.getFileName() });
appendRunnable.run();
}
}
);
}
}
}
/**
* 处理拒绝接收文件事件
* @param e
*/
private void processRejectSendFile(QQEvent e) {
ReceiveIMPacket packet = (ReceiveIMPacket)e.getSource();
if(packet.normalHeader.sender == model.getQQ()) {
final Integer sessionId = new Integer(packet.normalHeader.sequence);
final FileWatcher watcher = (FileWatcher)watchers.get(sessionId);
// 设置watcher状态
if(watcher != null) {
watcher.abort();
// 显示提示信息
main.getDisplay().syncExec(new Runnable() {
public void run() {
removeFileSession(sessionId);
removeFileItem(sessionId);
appendRunnable.hint = LumaQQ.getString("text.reject.send.file", new Object[] { watcher.getFileName() });
appendRunnable.run();
}
});
}
}
}
/**
* 处理接受传送文件事件,只处理普通文件接收事件
* @param e
*/
private void processAcceptSendFile(QQEvent e) {
ReceiveIMPacket packet = (ReceiveIMPacket)e.getSource();
if(packet.fileArgs.transferType == QQ.QQ_TRANSFER_FILE && packet.normalHeader.sender == model.getQQ()) {
FileWatcher watcher = (FileWatcher)watchers.get(new Integer(packet.normalHeader.sequence));
// 设置watcher状态
if(watcher != null && watcher instanceof FileSender) {
final FileSender sender = (FileSender)watcher;
// 显示提示信息
appendRunnable.hint = LumaQQ.getString("text.accept.send.file", new Object[] { sender.getFileName() });
main.getDisplay().syncExec(appendRunnable);
// 设置守望者参数
sender.setHisInternetIp(packet.fileArgs.internetIp);
sender.setHisInternetPort(packet.fileArgs.internetPort);
sender.setHisMajorPort(packet.fileArgs.majorPort);
sender.setHisFileSessionKey(packet.normalHeader.fileSessionKey);
// 通知端口信息
main.getClient().notifyFilePort(sender.getHisQQ(), sender.getMyMajorPort(), sender.getMyLocalIp(), sender.getMyMinorPort(), sender.getSessionSequence());
// 发送测试信息
sender.sendInitConnectionToDirect();
}
}
}
/**
* 处理发送消息超时事件
* @param e
*/
private void processSendIMTimeout(QQEvent e) {
SendIMPacket packet = (SendIMPacket)e.getSource();
if(packet.getReceiver() == model.getQQ()) {
main.getDisplay().syncExec(new Runnable() {
public void run() {
inputBox.setReadonly(false);
inputBox.setBackground(Colors.WHITE);
setMinimized(false);
setActive();
MessageDialog.openError(getShell(), LumaQQ.getString("message.box.common.fail.title"), LumaQQ.getString("message.box.send.message.timeout"));
}
});
}
}
/**
* 处理消息发送成功事件,主要是查找出是哪个窗口发送的这个消息,关闭之
* @param e
*/
private void processSendIMSuccess(QQEvent e) {
SendIMPacket packet = (SendIMPacket)e.getSource();
if(packet.getReceiver() == model.getQQ()) {
main.getDisplay().asyncExec(new Runnable() {
public void run() {
if(!inputBox.isReadonly())
return;
if(!sendNextFragment()) {
if(talkMode) {
inputBox.setReadonly(false);
inputBox.setBackground(Colors.WHITE);
} else
closeWindow();
}
}
});
}
}
/**
* 关闭窗口
*/
public void closeWindow() {
Iterator iter = watchers.values().iterator();
while(iter.hasNext()) {
FileWatcher watcher = (FileWatcher)iter.next();
watcher.removeFileListener(this);
watcher.abort();
}
getShell().close();
}
/**
* 取消所有正在进行的文件传输
*/
protected void abortAllFileTransfer() {
Iterator iter = watchers.values().iterator();
while(iter.hasNext()) {
FileWatcher watcher = (FileWatcher)iter.next();
watcher.abort();
}
}
/**
* 请求发送文件
*/
public void requestSendFile() {
// 检查是否是自己,不能给自己发
if(model.getQQ() == main.getMyModel().getQQ()) {
MessageDialog.openWarning(getShell(), LumaQQ.getString("message.box.common.warning.title"), LumaQQ.getString("message.box.cannot.send.file.to.self"));
return;
}
// 要用户选择要发送的文件
FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
String fileName = dialog.open();
if(fileName != null) {
File file = new File(fileName);
fileName = file.getName();
// 计算文件大小
int fileSize = (int)file.length();
// 如果文件长度为0,返回
if(fileSize == 0) {
MessageDialog.openWarning(getShell(), LumaQQ.getString("message.box.common.warning.title"), LumaQQ.getString("message.box.file.length.zero"));
return;
}
// 把数字形式的文件长度转化成humen readable格式
String lenStr = getFileSizeString(fileSize);
// 如果当前不是聊天模式,设置为聊天模式
if(!talkMode)
setTalkMode(true);
// 设置提示文本
appendHint(LumaQQ.getString("text.send.file", new Object[] { model.getName(), fileName, lenStr }), hintStyle);
// 设置守望者参数
FileSender sender = new FileSender(main.getClient());
sender.addFileListener(this);
sender.setHisQQ(model.getQQ());
sender.setFileName(fileName);
sender.setLocalFileName(file.getAbsolutePath());
sender.setFileSize(fileSize);
sender.setMaxFragmentSize(1000);
sender.setFragments(fileSize / 1000);
sender.setFileTransferStatus(FileWatcher.FT_NEGOTIATING);
// 打开要发送的文件,如果打开失败,取消发送
if(!sender.openLocalFile()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -