📄 downloadgroupjob.java
字号:
/*
* LumaQQ - Java QQ Client
*
* Copyright (C) 2004 luma <stubma@163.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package edu.tsinghua.lumaqq.ui.jobs;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import edu.tsinghua.lumaqq.IconHolder;
import edu.tsinghua.lumaqq.LumaQQ;
import edu.tsinghua.lumaqq.models.ClusterModel;
import edu.tsinghua.lumaqq.models.FriendModel;
import edu.tsinghua.lumaqq.models.GroupModel;
import edu.tsinghua.lumaqq.models.IQQNode;
import edu.tsinghua.lumaqq.qq.QQ;
import edu.tsinghua.lumaqq.qq.beans.ClusterInfo;
import edu.tsinghua.lumaqq.qq.beans.DownloadFriendEntry;
import edu.tsinghua.lumaqq.qq.events.IQQListener;
import edu.tsinghua.lumaqq.qq.events.QQEvent;
import edu.tsinghua.lumaqq.qq.packets.in.DownloadGroupFriendReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.GroupDataOpReplyPacket;
import edu.tsinghua.lumaqq.ui.MainShell;
import edu.tsinghua.lumaqq.utils.OptionUtil;
import edu.tsinghua.swt.models.DefaultShutterModel;
import edu.tsinghua.swt.models.INode;
/**
* 下载好友分组的任务
*
* @author luma
*/
public class DownloadGroupJob extends AbstractJob implements IQQListener {
private IconHolder icons;
private IProgressMonitor monitor;
// 组名list和组内好友的hash,用在下载分组信息的时候,因为下载分组信息是
// 分两部分进行的,一部分得到组名称一部分得到组的好友,光完成一部分还不
// 行,所以需要暂时保存一下结果
private List groupNames;
private List friends;
// 分组好友是否已经下载完毕
private boolean downloadGroupFriendFinished;
private boolean finished;
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.ui.jobs.IJob#prepare(edu.tsinghua.lumaqq.ui.MainShell)
*/
public void prepare(MainShell main) {
super.prepare(main);
icons = IconHolder.getInstance();
downloadGroupFriendFinished = false;
finished = false;
main.getClient().addQQListener(this);
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.ui.jobs.IJob#clear()
*/
public void clear() {
main.getClient().removeQQListener(this);
}
/* (non-Javadoc)
* @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
*/
public void run(IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException {
this.monitor = monitor;
monitor.beginTask("", 100);
monitor.subTask(LumaQQ.getString("job.download.group.1"));
main.getClient().downloadGroup();
main.getClient().downloadFriend(0);
monitor.worked(10);
synchronized(this) {
while(!finished) {
try {
this.wait(2000);
} catch (InterruptedException e) {
}
}
}
}
/* (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_DOWNLOAD_GROUP_NAME_SUCCESS:
processDownloadGroupNameSuccess(e);
break;
case QQEvent.QQ_DOWNLOAD_GROUP_FRIEND_SUCCESS:
processDownloadGroupFriendSuccess(e);
break;
case QQEvent.QQ_DOWNLOAD_GROUP_FRIEND_FAIL:
processDownloadGroupFriendFail(e);
break;
case QQEvent.QQ_OPERATION_TIMEOUT:
switch(e.operation) {
case QQ.QQ_CMD_DOWNLOAD_GROUP_FRIEND:
case QQ.QQ_CMD_GROUP_DATA_OP:
processDownloadGroupFriendFail(e);
break;
}
break;
}
}
/**
* 处理下载分组好友列表失败事件
*
* @param e
* QQEvent
*/
private void processDownloadGroupFriendFail(QQEvent e) {
groupNames = null;
friends = null;
errorMessage = LumaQQ.getString("job.download.group.error");
wake();
}
/**
* 处理下载分组好友列表成功事件
*
* @param e
* QQEvent
*/
private void processDownloadGroupFriendSuccess(QQEvent e) {
if(friends == null)
friends = new ArrayList();
DownloadGroupFriendReplyPacket packet = (DownloadGroupFriendReplyPacket)e.getSource();
friends.addAll(packet.friends);
if(packet.beginFrom == 0) {
downloadGroupFriendFinished = true;
if(groupNames != null)
resetModel();
} else {
downloadGroupFriendFinished = false;
main.getClient().downloadFriend(packet.beginFrom);
monitor.worked(10);
}
}
/**
* 处理下载分组名称成功事件
*
* @param e
* QQEvent
*/
private void processDownloadGroupNameSuccess(QQEvent e) {
GroupDataOpReplyPacket packet = (GroupDataOpReplyPacket)e.getSource();
groupNames = packet.groupNames;
if(downloadGroupFriendFinished && friends != null)
resetModel();
}
/**
* 重新设置shutter的model
*/
private void resetModel() {
monitor.subTask(LumaQQ.getString("job.download.group.2"));
downloadGroupFriendFinished = false;
main.setFriendListFinished(false);
final DefaultShutterModel model = new DefaultShutterModel();
// 用来保存需要得到信息的好友或者群
List needInfos = new ArrayList();
// 加入我的好友组model
GroupModel gModel = new GroupModel(LumaQQ.getString("group.default.friend"));
model.addTab(gModel);
// 加入下载到的组
Iterator iter = groupNames.iterator();
while(iter.hasNext()) {
gModel = new GroupModel((String)iter.next());
model.addTab(gModel);
}
// 添加群组
gModel = new GroupModel(LumaQQ.getString("group.default.cluster"));
gModel.addProperty(IQQNode.CLUSTER, "true");
gModel.addProperty(IQQNode.UPLOAD, "false");
model.addTab(gModel);
int clusterIndex = 0;
int[] cluster = main.getMVCHelper().listClusterGroup();
if(cluster != null && cluster.length > 0) {
// 得到群的索引,当前显然是最后一个tab
clusterIndex = model.getTabCount() - 1;
// 得到旧model中的群个数
int size = main.getModel().getItemCount(cluster[0]);
// 逐个添加这些ClusterModel
for(int i = 0; i < size; i++) {
ClusterModel c = (ClusterModel)main.getModel().getItem(cluster[0], i);
model.addItem(clusterIndex, c);
}
}
// 添加陌生人组
gModel = new GroupModel(LumaQQ.getString("group.default.stranger"));
gModel.addProperty(IQQNode.FRIENDLY, "false");
gModel.addProperty(IQQNode.UPLOAD, "false");
model.addTab(gModel);
// 添加陌生人组中的人
int[] stranger = main.getMVCHelper().listStrangerGroup();
if(stranger != null && stranger.length > 0) {
int sIndex = model.getTabCount() - 1;
int size = main.getModel().getItemCount(stranger[0]);
for(int i = 0; i < size; i++)
model.addItem(sIndex, main.getModel().getItem(stranger[0], i));
}
// 添加黑名单组
gModel = new GroupModel(LumaQQ.getString("group.default.blacklist"));
gModel.addProperty(IQQNode.FRIENDLY, "false");
gModel.addProperty(IQQNode.BLACKLIST, "true");
gModel.addProperty(IQQNode.UPLOAD, "false");
model.addTab(gModel);
// 设置黑名单的可见状态
GroupModel bModel = null;
final int[] blacklist = main.getMVCHelper().listBlacklistGroup();
if(blacklist != null && blacklist.length > 0) {
bModel = (GroupModel)main.getModel().getTab(blacklist[0]);
gModel.addProperty(IQQNode.VISIBLE, bModel.getProperty(IQQNode.VISIBLE));
// 添加黑名单中的人
int bIndex = model.getTabCount() - 1;
int size = main.getModel().getItemCount(blacklist[0]);
for(int i = 0; i < size; i++)
model.addItem(bIndex, main.getModel().getItem(blacklist[0], i));
}
final boolean blacklistVisible = (bModel != null && "false".equals(bModel.getProperty(IQQNode.VISIBLE))) ? false : true;
// 添加最近联系人组
if(OptionUtil.getInstance().isEnableLatest()) {
gModel = new GroupModel(LumaQQ.getString("group.default.latest"));
gModel.addProperty(IQQNode.FRIENDLY, "false");
gModel.addProperty(IQQNode.UPLOAD, "false");
model.addTab(gModel);
final int[] latest = main.getMVCHelper().listLatestGroup();
int lIndex = model.getTabCount() - 1;
if(latest != null && latest.length > 0) {
GroupModel oldGroup = (GroupModel)main.getModel().getTab(latest[0]);
int size = main.getModel().getItemCount(latest[0]);
for(int i = 0; i < size; i++)
model.addItem(lIndex, main.getModel().getItem(latest[0], i));
}
}
monitor.worked(20);
// 得到组总数
int tabCount = groupNames.size() + 1;
// 添加分组中的好友
int size = friends.size();
for(int i = 0; i < size; i++) {
// 得到下载项
DownloadFriendEntry dfe = (DownloadFriendEntry)friends.get(i);
if(dfe.isCluster()) {
ClusterModel c = main.getMVCHelper().getClusterModel(dfe.qqNum);
// 如果等于null,则添加。不等于null不做什么,因为前面已经添加过了
if(c == null) {
needInfos.add(dfe);
c = new ClusterModel(dfe.qqNum);
ClusterInfo info = new ClusterInfo();
info.clusterId = dfe.qqNum;
c.addProperty(IQQNode.INFO, info);
c.addProperty(INode.IMAGE, icons.getClusterHead(1));
c.addProperty(IQQNode.HEAD, new Integer(1));
model.addItem(clusterIndex, c);
}
} else {
// 如果group不正确,置0
if(dfe.group >= tabCount)
dfe.group = 0;
// 搜索目前的model,得到这个好友的model,如果没有找到这个好友,创建一个新model
// 并把这个model保存到一个list中,因为需要得到这些好友的info。另外,还要
// 把有消息的好友保存起来,因为在设置新model完成后,要恢复图标的跳动和闪烁
FriendModel old = main.getMVCHelper().getFriendModel(dfe.qqNum);
if(old != null) {
FriendModel f = old.cloneProperties();
f.addProperty(IQQNode.STATUS, IQQNode.VALUE_OFFLINE);
model.addItem(dfe.group, f);
} else {
needInfos.add(dfe);
FriendModel f = new FriendModel(String.valueOf(dfe.qqNum), icons.getHead(0));
f.addProperty(IQQNode.QQ_NUMBER, new Integer(dfe.qqNum));
f.addProperty(IQQNode.STATUS, IQQNode.VALUE_OFFLINE);
f.addProperty(IQQNode.HEAD, new Integer(0));
f.addProperty(IQQNode.MEMBER, "false");
model.addItem(dfe.group, f);
}
}
}
// 新model已经完全构造好了,现在把旧model替换成新model
main.getDisplay().syncExec(new Runnable() {
public void run() {
main.setModel(model);
main.getMVCHelper().setModel(model);
// 判断黑名单当前是否是隐藏的,如果是,隐藏黑名单
if(!blacklistVisible) {
main.getShutter().hideTab(blacklist[0], true);
}
}
});
monitor.worked(20);
// 对于那些没有在旧model中出现的好友或者群,请求得到他们的info
iter = needInfos.iterator();
while(iter.hasNext()) {
DownloadFriendEntry dfe = (DownloadFriendEntry)iter.next();
if(dfe.isCluster() && dfe.qqNum != 0)
main.getClient().getClusterInfo(dfe.qqNum);
else
main.getClient().getUserInfo(dfe.qqNum);
}
// 恢复图标的跳动和闪烁,然后关闭提示框
main.getDisplay().syncExec(new Runnable() {
public void run() {
main.getUIHelper().resetAllImageEffect();
}
});
main.setFriendListFinished(true);
friends = null;
groupNames = null;
main.getDisplay().syncExec(new Runnable() {
public void run() {
// 得到在线好友, 设置firstTime为true是为了防止不必要的上线提示
main.getTipHelper().setFirstTime(true);
main.getClient().getFriendOnline();
// 处理延迟消息
main.getMessageHelper().processPostponedIM();
}
});
monitor.done();
wake();
}
/**
* 唤醒任务线程,使其返回
*/
private void wake() {
synchronized(this) {
finished = true;
this.notify();
}
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.ui.jobs.IJob#isSuccess()
*/
public boolean isSuccess() {
return errorMessage != null;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -