⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smswindow.java

📁 lumaQQ的源文件
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 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;

import static edu.tsinghua.lumaqq.resource.Messages.*;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import edu.tsinghua.lumaqq.events.FriendSelectionEvent;
import edu.tsinghua.lumaqq.events.IFriendSelectionListener;
import edu.tsinghua.lumaqq.models.Model;
import edu.tsinghua.lumaqq.models.ModelRegistry;
import edu.tsinghua.lumaqq.models.User;
import edu.tsinghua.lumaqq.qq.QQ;
import edu.tsinghua.lumaqq.qq.Util;
import edu.tsinghua.lumaqq.qq.beans.SMSReply;
import edu.tsinghua.lumaqq.qq.events.IQQListener;
import edu.tsinghua.lumaqq.qq.events.QQEvent;
import edu.tsinghua.lumaqq.qq.packets.in.ReceiveIMPacket;
import edu.tsinghua.lumaqq.qq.packets.in.SendSMSReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.out.SendSMSPacket;
import edu.tsinghua.lumaqq.record.IKeyConstants;
import edu.tsinghua.lumaqq.record.RecordEntry;
import edu.tsinghua.lumaqq.resource.Colors;
import edu.tsinghua.lumaqq.resource.DefaultFace;
import edu.tsinghua.lumaqq.resource.Resources;
import edu.tsinghua.lumaqq.ui.helper.DateTool;
import edu.tsinghua.lumaqq.ui.helper.UITool;
import edu.tsinghua.lumaqq.ui.listener.CenterBorderPaintListener;
import edu.tsinghua.lumaqq.widgets.qstyle.Slat;
import edu.tsinghua.lumaqq.widgets.record.RecordViewer;
import edu.tsinghua.lumaqq.widgets.record.SMSFilter;
import edu.tsinghua.lumaqq.widgets.record.SMSRecordProvider;
import edu.tsinghua.lumaqq.widgets.rich.LineStyle;
import edu.tsinghua.lumaqq.widgets.rich.RichBox;

/**
 * 短信发送接收窗口
 * 
 * @author luma
 */
public class SMSWindow extends BaseWindow implements IQQListener, IFriendSelectionListener {
	/**
	 * 闪烁图标
	 * 
	 * @author luma
	 */
	private class Blink implements Runnable {
		private boolean flag;
		private volatile boolean stop;


		public Blink() {
			stop = true;
		}

		public void init() {
			this.flag = true;
			this.stop = false;
		}

		public void run() {
			try {
				if (flag) {
					getShell().setImage(res.getImage(Resources.icoMobile));
					((BorderStyler) getShell().getData(BorderStyler.STYLER)).repaintTitleBar();
				} else {
					getShell().setImage(null);
					((BorderStyler) getShell().getData(BorderStyler.STYLER)).repaintTitleBar();
				}
				flag = !flag;
				if (!stop)
					getShell().getDisplay().timerExec(500, this);
				else {
					getShell().setImage(res.getImage(Resources.icoMobile));
					((BorderStyler) getShell().getData(BorderStyler.STYLER)).repaintTitleBar();
				}
			} catch (SWTException e) {
				// 这个操作可能会抛出SWTException,如果组件已经dispose的话,
				//     所以我们需要捕捉这个异常,不然程序可能崩溃
			}
		}

		public void setStop(boolean stop) {
			this.stop = stop;
		}

		public boolean isStop() {
			return stop;
		}
	}


	private FriendSelectionShell fss;

	private String receiver;
	private RichBox inputBox;
	private Text textSender;
	private RecordViewer viewer;

	// true表示窗口处于一对一发送接收模式,这种模式下不能选择收件人,需要预设,可以发送和接收
	// false表示窗口处于可以多人发送模式,这种模式下可以选择1到多个收件人,只能发送
	private boolean singleMode;

	private boolean isUser;
	private User friend;
	private String mobile;

	// 消息要发送到的手机和好友QQ号列表
	private List<String> mobiles;
	private List<Integer> friends;
	// 短信的分片相关
	private int fragmentCount;
	private int nextFragment;
	private int maxFragmentLength;
	private byte[] fragmentCache;
	// 要发送的消息
	private String textCache;
	// 是否停止发送
	private boolean stop;
	// 当前是否有发送在进行中
	private boolean sending;

	private char expected;

	private Blink blink;

	private static final LineStyle myStyle = new LineStyle(Colors.MY_HINT_COLOR, null, "宋体", SWT.NORMAL, 9);
	private static final LineStyle otherStyle = new LineStyle(Colors.BLUE, null, "宋体", SWT.NORMAL, 9);
	private static final String CRLF = System.getProperty("line.separator");

	private Runnable sendAction = new Runnable() {
		public void run() {
			textCache = inputBox.getText();
			send();
		}
	};
	private Runnable recordAction = new Runnable() {
		public void run() {
			showRecord();
		}
	};
	private RichBox outputBox;
	private Slat btnSend;
	private Text textReceiver;
	private Label lblHint;


	public SMSWindow(MainShell main, String mobile) {
		super(main);
		this.mobile = mobile;
		isUser = false;
		singleMode = true;
	}

	public SMSWindow(MainShell main, User friend) {
		super(main);
		this.friend = friend;
		isUser = true;
		singleMode = true;
	}

	public SMSWindow(MainShell main) {
		super(main);
		singleMode = false;
	}

	@Override
	protected void initializeVariables() {
		super.initializeVariables();
		mobiles = new ArrayList<String>();
		friends = new ArrayList<Integer>();
		maxFragmentLength = QQ.QQ_MAX_SMS_LENGTH - QQ.QQ_MAX_SMS_SENDER_NAME;
		fragmentCount = 1;
		nextFragment = 0;
		stop = true;
		sending = false;
		blink = new Blink();
		receiver = "";
		expected = 0;
	}

	/**
	 * 开始闪烁系统消息图标
	 */
	public void startBlink() {
		if (!blink.isStop())
			return;
		blink.init();
		getShell().getDisplay().timerExec(0, blink);
	}

	/**
	 * 停止系统消息按钮上的闪烁效果
	 */
	public void stopBlink() {
		blink.setStop(true);
	}

	@Override
	protected String getTitle() {
		User me = main.getMyModel();
		if (me.isMobile())
			return NLS.bind(sms_title_mobile_qq, String.valueOf(me.qq));
		else if (me.isBind())
			return NLS.bind(sms_title_bind_user, String.valueOf(me.qq));
		else
			return NLS.bind(sms_title_no_bind, String.valueOf(me.qq));
	}

	@Override
	protected Image getImage() {
		return res.getImage(Resources.icoMobile);
	}

	@Override
	protected IQQListener getQQListener() {
		return this;
	}

	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		initializeFriendSelectionShell(newShell);
	}

	private void initializeFriendSelectionShell(Shell newShell) {
		fss = new FriendSelectionShell(newShell, false);
		fss.addFriendSelectionListener(this);
		fss.setModel(main.getBlindHelper().getSMSReceivableGroupList());
	}

	@Override
	protected Point getInitialSize() {
		return new Point(500, 450);
	}

	@Override
	protected Control createContents(Composite parent) {
		Composite control = getContentContainer();

		Composite container = new Composite(control, SWT.NONE);
		container.setBackground(Colors.WHITE);
		container.setLayoutData(new GridData(GridData.FILL_BOTH));
		container.setLayout(new GridLayout());
		container.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				Composite c = (Composite) e.getSource();
				Rectangle rect = c.getClientArea();
				rect.width--;
				rect.height--;
				e.gc.setForeground(Colors.MAINSHELL_BORDER_OUTMOST);
				e.gc.drawRectangle(rect);
			}
		});

		UITool.setDefaultBackground(Colors.WHITE);

		GridLayout layout = new GridLayout(2, false);
		layout.marginHeight = 1;
		Composite top = UITool.createContainer(container, new GridData(GridData.FILL_HORIZONTAL), layout);
		top.addPaintListener(new CenterBorderPaintListener(new Class[] { Text.class }, 16, Colors.PAGE_CONTROL_BORDER));

		// 收件人
		Slat btnReceiver = new Slat(top);
		btnReceiver.setText(sms_to);
		btnReceiver.setLayoutData(new GridData());
		btnReceiver.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				if (fss.isVisible())
					fss.setVisible(false);
				else {
					if (fss == null || fss.isDisposed())
						initializeFriendSelectionShell(getShell());
					fss.setVisible(true);
				}
			}
		});
		btnReceiver.setEnabled(!singleMode);

		textReceiver = new Text(top, SWT.SINGLE | (singleMode ? SWT.READ_ONLY : SWT.NONE));
		textReceiver.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		layout = new GridLayout();
		layout.marginHeight = layout.marginWidth = 3;
		layout.verticalSpacing = 0;
		Composite center = UITool.createContainer(container, new GridData(GridData.FILL_BOTH), layout);
		center.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				Composite c = (Composite) e.getSource();
				Rectangle rect = c.getClientArea();
				rect.width--;
				rect.height--;
				e.gc.setForeground(Colors.MAINSHELL_BORDER_OUTMOST);
				e.gc.drawRectangle(rect);
			}
		});

		outputBox = new RichBox(center);
		outputBox.setLayoutData(new GridData(GridData.FILL_BOTH));
		outputBox.setReadonly(true);
		outputBox.setBackground(Colors.WHITE);
		outputBox.setDefaultStyle(myStyle);

		// sash
		Sash sash = new Sash(center, SWT.HORIZONTAL);
		sash.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		sash.setBackground(Colors.READONLY_BACKGROUND);
		sash.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				GridData data = (GridData) inputBox.getLayoutData();
				data.heightHint = inputBox.getParent().getClientArea().height - e.y - 23;
				inputBox.getParent().layout();
			}
		});

		// 提示条
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.heightHint = 20;
		Composite hintContainer = UITool.createContainer(center, gd, new GridLayout());
		hintContainer.setBackground(Colors.VIEWFORM_BANNER_BACKGROUND);

		lblHint = UITool.createLabel(hintContainer, NLS.bind(sms_will_send, String.valueOf(1)), new GridData(GridData.FILL_HORIZONTAL
				| GridData.VERTICAL_ALIGN_CENTER));
		lblHint.setBackground(lblHint.getParent().getBackground());

		inputBox = new RichBox(center);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.heightHint = 100;
		inputBox.setLayoutData(gd);
		inputBox.setBackground(Colors.WHITE);
		inputBox.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				calculateFragmentCount();
				refreshHint();
			}
		});

		layout = new GridLayout(4, false);
		layout.marginHeight = layout.marginWidth = 1;
		Composite bottom = UITool.createContainer(container, new GridData(GridData.FILL_HORIZONTAL), layout);
		bottom.addPaintListener(new CenterBorderPaintListener(new Class[] { Text.class }, 16, Colors.PAGE_CONTROL_BORDER));

		// 聊天记录
		gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		gd.grabExcessHorizontalSpace = true;
		Slat btnRecord = UITool.createSlat(bottom, button_record_accel, gd);
		btnRecord.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				Slat temp = (Slat) e.getSource();
				if (e.x > temp.getSize().x || e.y > temp.getSize().y || e.x < 0 || e.y < 0) {
					return;
				}
				showRecord();
			}
		});
		// 签名        
		UITool.createLabel(bottom, sms_sender, new GridData(GridData.HORIZONTAL_ALIGN_END));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -