📄 sendimwindow.java
字号:
MessageDialog.openError(getShell(), LumaQQ.getString("message.box.common.fail.title"), LumaQQ.getString("message.box.file.open.error"));
return;
}
// 启动sender
sender.start();
// 发送请求发送文件消息包
sender.setSessionSequence(main.getClient().requestSendFile(model.getQQ(), fileName, fileSize, sender.getMyMajorPort(), true));
// 把这个sender加入到哈希表,并设置为当前file session
currentFileSessionId = new Integer(sender.getSessionSequence());
watchers.put(currentFileSessionId, sender);
addFileItem(true, sender.getFileName(), lenStr, currentFileSessionId);
setCurrentFileSession(currentFileSessionId);
// 设置工具条按钮的状态
tiNo.setEnabled(true);
}
}
/**
* 取消文件传输,可能是在协商阶段取消,也可能是在传送过程中取消
*/
protected void cancelFileOperation() {
FileWatcher watcher = removeFileSession(currentFileSessionId);
watcher.abort();
if(watcher instanceof FileSender)
appendHint(LumaQQ.getString("text.cancel.transfer.file", new Object[] { watcher.getFileName() }), hintStyle);
else
appendHint(LumaQQ.getString("text.reject.receive.file"), hintStyle);
}
/**
* 移除一个取消或者完成的文件传输会话
* @param sessionId
*/
public FileWatcher removeFileSession(Integer sessionId) {
tiNo.setEnabled(false);
tiYes.setEnabled(false);
FileWatcher watcher = (FileWatcher)watchers.remove(sessionId);
if(watchers.size() > 0)
setCurrentFileSession((Integer)watchers.keys().nextElement());
else
setCurrentFileSession(null);
return watcher;
}
/**
* 移除一个取消或者完成的文件传输会话
* @param sessionId
*/
public FileWatcher removeFileSession(char sessionId) {
return removeFileSession(new Integer(sessionId));
}
/**
* 设置当前显示的文件传输会话
* @param sessionId
*/
protected void setCurrentFileSession(Integer sessionId) {
if(sessionId == null) {
// null表示没有更多的文件传输存在,隐藏相关控件
tiNo.setEnabled(false);
tiYes.setEnabled(false);
bar.setVisible(false);
lblStatus.setVisible(false);
lblPercent.setVisible(false);
} else {
FileWatcher watcher = (FileWatcher)watchers.get(sessionId);
currentFileSessionId = sessionId;
if(watcher != null) {
// 显示相关控件
boolean send = watcher instanceof FileSender;
tiNo.setEnabled(true);
tiYes.setEnabled(!send && watcher.getFileTransferStatus() == FileWatcher.FT_NEGOTIATING);
tiNo.setToolTipText(LumaQQ.getString(send ? "tooltip.button.cancel.sendfile" : "tooltip.button.reject.sendfile"));
tiYes.setToolTipText(send ? "" : LumaQQ.getString("tooltip.button.accept.sendfile"));
bar.setVisible(true);
lblStatus.setVisible(true);
lblPercent.setVisible(true);
lblPercent.setText("");
// 设定控件的值,如果滑窗为null说明还在连接中
SlideWindow window = watcher.getSlideWindow();
if(window != null) {
bar.setMaximum(watcher.getFragments());
bar.setSelection(window.getMaxPassed());
lblStatus.setText(LumaQQ.getString(send ? "im.label.sending" : "im.label.receiving"));
} else {
bar.setMaximum(100);
bar.setSelection(0);
lblStatus.setText(LumaQQ.getString(send ? "im.label.sending" : "im.label.receiving"));
}
// 设置菜单的选择状态
setFileItemSelection(currentFileSessionId);
}
}
}
/**
* 设置消息发送窗口为聊天模式或者消息模式
*
* @param b
* true表示为聊天模式
*/
public void setTalkMode(boolean b) {
if(b == talkMode) return;
Shell shell = getShell();
if(b) {
talkMode = true;
model.addProperty(IQQNode.TALK_MODE, "true");
btnMode.setText(LumaQQ.getString("im.button.mode.message"));
if(OptionUtil.getInstance().isUseEnterInMessageMode() != OptionUtil.getInstance().isUseEnterInTalkMode())
reinstallSendKey(OptionUtil.getInstance().isUseEnterInTalkMode());
sash.setVisible(true);
outputForm.setLayoutData(new GridData(GridData.FILL_BOTH));
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.heightHint = 100;
inputForm.setLayoutData(gd);
gd = (GridData)sash.getLayoutData();
gd.heightHint = SWT.DEFAULT;
if(talkMode)
getShell().setSize(470, viewer.isVisible() ? 630 : 430);
else
getShell().setSize(440, viewer.isVisible() ? 540 : 340);
inputForm.getParent().layout();
} else {
talkMode = false;
outputBox.clear();
model.addProperty(IQQNode.TALK_MODE, "false");
btnMode.setText(LumaQQ.getString("im.button.mode.talk"));
if(OptionUtil.getInstance().isUseEnterInMessageMode() != OptionUtil.getInstance().isUseEnterInTalkMode())
reinstallSendKey(OptionUtil.getInstance().isUseEnterInMessageMode());
sash.setVisible(false);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.heightHint = outputForm.getTopLeft().getSize().y;
outputForm.setLayoutData(gd);
inputForm.setLayoutData(new GridData(GridData.FILL_BOTH));
gd = (GridData)sash.getLayoutData();
gd.heightHint = 0;
if(talkMode)
getShell().setSize(470, viewer.isVisible() ? 630 : 430);
else
getShell().setSize(440, viewer.isVisible() ? 540 : 340);
inputForm.getParent().layout();
}
}
/**
* 添加一个文件传输项目到菜单中
* @param send
* @param filename
* @param fileSize
* @param sessionId
*/
private void addFileItem(boolean send, String filename, String fileSize, char sessionId) {
addFileItem(send, filename, fileSize, new Integer(sessionId));
}
/**
* 添加一个文件传输项目到菜单中,这个方法必须在watchers的put方法之后调用
* @param send
* @param filename
* @param fileSize
* @param sessionId
*/
private void addFileItem(boolean send, String filename, String fileSize, Integer sessionId) {
boolean b = watchers.size() == 1;
if(b)
fileMenu.getItem(0).dispose();
MenuItem mi = new MenuItem(fileMenu, SWT.RADIO);
if(send)
mi.setText(LumaQQ.getString("menu.file.send", new Object[] { filename, fileSize }));
else
mi.setText(LumaQQ.getString("menu.file.receive", new Object[] { filename, fileSize }));
mi.setData(sessionId);
mi.addSelectionListener(fisl);
mi.setSelection(b);
}
/**
* 删除一个已经完成或者结束的文件传输任务项
* @param sessionId
*/
private void removeFileItem(char sessionId) {
removeFileItem(new Integer(sessionId));
}
/**
* 删除一个已经完成或者取消的文件传输任务项
* @param sessionId
*/
private void removeFileItem(Integer sessionId) {
int count = fileMenu.getItemCount();
for(int i = 0; i < count; i++) {
MenuItem mi = fileMenu.getItem(i);
if(sessionId.equals(mi.getData())) {
mi.dispose();
break;
}
}
// 如果菜单数为0,加一个缺省的菜单
if(fileMenu.getItemCount() == 0) {
MenuItem mi = new MenuItem(fileMenu, SWT.PUSH);
mi.setText(LumaQQ.getString("menu.file.none"));
}
}
/**
* 使和sessionId关联的那个菜单项为选择状态
* @param sessionId
*/
private void setFileItemSelection(Integer sessionId) {
if(watchers.size() == 0) return;
int count = fileMenu.getItemCount();
for(int i = 0; i < count; i++) {
MenuItem mi = fileMenu.getItem(i);
mi.setSelection(sessionId.equals(mi.getData()));
}
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.qq.events.FileListener#fileAborted(edu.tsinghua.lumaqq.qq.events.FileEvent)
*/
public void fileAborted(FileEvent e) {
final FileWatcher watcher = (FileWatcher)e.getSource();
main.getDisplay().syncExec(new Runnable() {
public void run() {
removeFileSession(watcher.getSessionSequence());
removeFileItem(watcher.getSessionSequence());
appendRunnable.hint = LumaQQ.getString("text.cancel.transfer.file", new Object[] { watcher.getFileName() });
appendRunnable.run();
}
});
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.qq.events.FileListener#fileFinished(edu.tsinghua.lumaqq.qq.events.FileEvent)
*/
public void fileFinished(FileEvent e) {
final FileWatcher watcher = (FileWatcher)e.getSource();
if(watcher instanceof FileSender) {
main.getDisplay().syncExec(new Runnable() {
public void run() {
removeFileSession(watcher.getSessionSequence());
removeFileItem(watcher.getSessionSequence());
appendRunnable.hint = LumaQQ.getString("text.send.file.finished", new Object[] { watcher.getFileName() });
appendRunnable.run();
}
});
} else {
main.getDisplay().syncExec(new Runnable() {
public void run() {
removeFileSession(watcher.getSessionSequence());
removeFileItem(watcher.getSessionSequence());
boolean b = Util.checkFileMD5(watcher.getLocalFileName(), watcher.getFileMD5());
appendRunnable.hint = LumaQQ.getString(b ? "text.file.md5.correct" : "text.file.md5.incorrect");
appendRunnable.run();
}
});
}
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.qq.events.FileListener#fileInProgress(edu.tsinghua.lumaqq.qq.events.FileEvent)
*/
public void fileInProgress(FileEvent e) {
final FileWatcher watcher = (FileWatcher)e.getSource();
SlideWindow window = watcher.getSlideWindow();
if(window.isFinished()) {
// 如果接收完毕,则显示一些提示信息,如果这个会话是当前显示的会话,还要更新其进度状态
main.getDisplay().syncExec(new Runnable() {
public void run() {
if(currentFileSessionId.intValue() == watcher.getSessionSequence()) {
lblStatus.setText(LumaQQ.getString("im.label.finished"));
bar.setSelection(bar.getMaximum());
lblPercent.setText("100%");
}
}
});
} else {
// 如果还没有接收完,则只更新进度状态
if(currentFileSessionId.intValue() == watcher.getSessionSequence()) {
refreshRunnable.max = watcher.getFragments();
refreshRunnable.selection = window.getMaxPassed();
int percent = refreshRunnable.selection * 100 / refreshRunnable.max;
refreshRunnable.text = String.valueOf(percent) + '%';
main.getDisplay().syncExec(refreshRunnable);
}
}
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.qq.events.FileListener#fileConnected(edu.tsinghua.lumaqq.qq.events.FileEvent)
*/
public void fileConnected(FileEvent e) {
final FileWatcher watcher = (FileWatcher)e.getSource();
if(watcher.isUseUdp()) {
appendRunnable.hint = LumaQQ.getString("text.udp.connected");
main.getDisplay().syncExec(appendRunnable);
}
}
/**
* 得到一个表示文件大小的字符串形式
* @param len
* @return
*/
protected String getFileSizeString(long len) {
String lenStr = null;
long k = len >> 10;
if(k <= 0)
lenStr = String.valueOf(len) + "Bytes";
else {
long m = k >> 10;
if(m <= 0)
lenStr = String.valueOf(k) + "KB";
else {
long g = m >> 10;
if(g <= 0)
lenStr = String.valueOf(m) + "MB";
else
lenStr = String.valueOf(g) + "GB";
}
}
return lenStr;
}
/**
* 初始化当前文件传输任务菜单
*/
private void initFileMenu() {
fileMenu = new Menu(getShell(), SWT.POP_UP);
// 缺省,无任务进行中
MenuItem mi = new MenuItem(fileMenu, SWT.PUSH);
mi.setText(LumaQQ.getString("menu.file.none"));
}
/**
* 同意接受文件
*/
protected void acceptSendFile() {
// 得到一个文件守望者实例
FileReceiver receiver = (FileReceiver)watchers.get(currentFileSessionId);
if(receiver == null) return;
// 打开一个文件对话框
FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
String fileName = receiver.getFileName();
dialog.setFileName(fileName);
String s = dialog.open();
// 如果用户选择了取消则返回
if(s == null) return;
// 如果用户没有写扩展名,自动加上扩展名,但是如果接收的文件也没有扩展名就作罢
if(s.indexOf('.') == -1) {
int i = fileName.lastIndexOf('.');
if(i != -1)
s += fileName.substring(i);
}
// 如果用户选择了保存,设置watcher的本地文件名变量
receiver.setLocalFileName(s);
// 尝试打开文件准备写操作,如果失败,返回
if(!receiver.openLocalFile()) {
appendHint(L
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -