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

📄 recordviewer.java

📁 用java实现的
💻 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.widgets;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MenuAdapter;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

import edu.tsinghua.lumaqq.IMessage;
import edu.tsinghua.lumaqq.IconHolder;
import edu.tsinghua.lumaqq.LumaQQ;
import edu.tsinghua.lumaqq.MessageEntry;
import edu.tsinghua.lumaqq.qq.Utils;

/**
 * 聊天记录查看器控件,做成控件比较方便维护
 * 
 * @author 马若劼
 */
public class RecordViewer extends Composite implements DisposeListener {
    // 在表的大小改变时,修改表头的宽度
    private class ResizeListener extends ControlAdapter {
        // 保存宽度的数值,-1表示占据所有未用部分
        private int[] width;
        // 表示宽度的数值是否是个相对量
        private boolean[] relative;
        
        // 构造函数
        public ResizeListener(String[] w) {
            setWidth(w);
        }
        
        public void controlResized(ControlEvent e) {
            // 得到表的客户区大小
            Table table = (Table)e.getSource();
            int caWidth = table.getClientArea().width;
            // 已分配的宽度
            int allocWidth = 0;
            // 临时变量
            int w;
            // 先设置width不等于-1的行
            for(int i = 0; i < width.length; i++) {
                if(width[i] != -1) {
                    TableColumn tc = table.getColumn(i);
                    w = relative[i] ? (caWidth * width[i] / 100) : width[i];
                    allocWidth += w;
                    tc.setWidth(w);
                }
            }
            // 再设置宽度为-1,也就是占据剩余空间的行,如果有多个-1的行,则只有第一个可以显示,其他的
            //     都会被置为0
            for(int i = 0; i < width.length; i++) {
                if(width[i] == -1) {
                    TableColumn tc = table.getColumn(i);
                    w = caWidth - allocWidth;
                    allocWidth += w;
                    tc.setWidth(w);
                }
            }
        }
        
        /**
         * 根据输入的字符串形式的宽度描述,转换成内部描述,这样是为了避免每次都解析字符串
         * @param w
         */
        public void setWidth(String[] w) {
            width = new int[w.length];
            relative = new boolean[w.length];
            for(int i = 0; i < w.length; i++) {
                relative[i] = w[i].endsWith("%");
                if(w[i].equals("*"))
                    width[i] = -1;
                else 
                    width[i] = Utils.getInt(w[i].substring(0, 
                        relative[i] ? (w[i].length() - 1) : w[i].length()), 10);
            }
        }
    }
    
    // Log对象
    private static Log log = LogFactory.getLog(RecordViewer.class);
	// 界面控件
	private Label lblYear, lblMonth, lblDay;
	private Button chkDisplayAll;
	private Table recordTable;
	private Menu recordMenu;
	// 年月日
	private int year, month, day;
	// 消息管理器
	private IMessage mm;
	// TableItem字符串格式化器
	private IRecordFormatter formatter;
	private IRecordExporter exporter;
	// TableItem选择事件监听器
	private List listeners;
	// IconHolder实例
	private IconHolder icons;
	// 剪贴板实例
	private Clipboard clipboard;
	// QQ号,表示这个RecordViewer用于查看与哪个好友的聊天记录,10000表示系统消息
	private int qqNum;
	// 表resiz事件处理器
	private ResizeListener rl;
	
	/**
	 * @param parent
	 * @param style
	 */
	public RecordViewer(Composite parent, int style) {
		super(parent, style);
		
		// 初始化变量
		listeners = new ArrayList();
		clipboard = new Clipboard(getDisplay());
		icons = IconHolder.getInstance();
		Calendar c = Calendar.getInstance();
		year = c.get(Calendar.YEAR);
		month = c.get(Calendar.MONTH) + 1;
		day = c.get(Calendar.DAY_OF_MONTH);
		// 初始化窗口布局
		initLayout();
		// 初始化弹出菜单
		initPopupMenu();
		// 添加事件监听器
		addDisposeListener(this);
	}

	/**
	 * 初始化弹出菜单
	 */
	private void initPopupMenu() {
		recordMenu = new Menu(this);
		// 拷贝消息到剪贴板
		MenuItem mi = new MenuItem(recordMenu, SWT.PUSH);
		mi.setText(LumaQQ.getResourceString("record.viewer.menu.copy"));
		mi.setImage(icons.getResource(IconHolder.icoCopy));
		mi.addSelectionListener(
			new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					int index = recordTable.getSelectionIndex();
					if(index != -1) {			
						MessageEntry me = (MessageEntry)recordTable.getItem(index).getData();
						String copyString = formatter.copy(me);
						if(copyString != null)
							clipboard.setContents(new Object[] { copyString }, new Transfer[] { TextTransfer.getInstance() });
					}
				}
			}
		);
		// 导出表中所有信息
		mi = new MenuItem(recordMenu, SWT.PUSH);
		mi.setText(LumaQQ.getResourceString("record.viewer.menu.export"));
		mi.setImage(icons.getResource(IconHolder.icoTxtFile));
		mi.addSelectionListener(
			new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					// 创建文件对话框,设置参数,打开
					FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
					dialog.setFilterExtensions(new String[] { "*.txt", "*.*" } );
					dialog.setFileName(String.valueOf(qqNum) + ".txt");
					String filename = dialog.open();
					// 如果filename不等于null则导出
					if(filename != null) {
						BufferedWriter writer = null;
						try {
							// 创建文本文件
							File file = new File(filename);
							if(!file.exists())
								file.createNewFile();
							// 创建流
							writer = new BufferedWriter(new FileWriter(file));
							// 导出头部
							writer.write(exporter.exportHeader());
							// 得到TableItem总数,然后得到TableItem,交给exporter处理
							int size = recordTable.getItemCount();
							for(int i = 0; i < size; i++) {
								writer.write(exporter.exportString((MessageEntry)recordTable.getItem(i).getData()));
							}
							writer.flush();
						} catch (IOException ex) {
							log.error("保存聊天记录到文本文件失败");
						} finally {
							try {
								if(writer != null)
									writer.close();
							} catch (IOException e1) {
							}
						}
					}
				}
			}
		);
		// 添加菜单显示事件监听器
		recordMenu.addMenuListener(
			new MenuAdapter() {
				public void menuShown(MenuEvent e) {
					recordMenu.getItem(0).setEnabled(recordTable.getSelectionIndex() != -1);
				}
			}
		);
	}

	/**
	 * 初始化界面布局
	 */
	private void initLayout() {
		setLayout(new FormLayout());
		// 显示标签
		Label lblDisplay = new Label(this, SWT.NONE);
		lblDisplay.setText(LumaQQ.getResourceString("record.viewer.label.display"));
		FormData fd = new FormData();
		fd.left = new FormAttachment(0, 0);
		fd.top = new FormAttachment(0, 0);
		lblDisplay.setLayoutData(fd);
		// 年标签
		lblYear = new Label(this, SWT.LEFT);
		lblYear.setText(String.valueOf(year));
		fd = new FormData();
		fd.left = new FormAttachment(lblDisplay, 5, SWT.RIGHT);
		fd.top = new FormAttachment(0, 0);
		lblYear.setLayoutData(fd);
		Label lblYearChar = new Label(this, SWT.NONE);
		lblYearChar.setText(LumaQQ.getResourceString("record.viewer.label.year"));
		fd = new FormData();
		fd.left = new FormAttachment(lblYear, 0, SWT.RIGHT);
		fd.top = new FormAttachment(0, 0);
		lblYearChar.setLayoutData(fd);
		// 调整年的上按钮
		Button btnYearUp = new Button(this, SWT.ARROW | SWT.UP);
		fd = new FormData();
		fd.left = new FormAttachment(lblYearChar, 1, SWT.RIGHT);
		fd.right = new FormAttachment(lblYearChar, 21, SWT.RIGHT);
		fd.top = new FormAttachment(0, 0);
		fd.bottom = new FormAttachment(0, 10);
		btnYearUp.setLayoutData(fd);
		btnYearUp.addSelectionListener(
			new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					if(year > 0) {
						year--;
						lblYear.setText(String.valueOf(year));
						if(!chkDisplayAll.getSelection())
							refreshRecord(false);						
					}
				}
			}
		);
		// 调整年的下按钮
		Button btnYearDown = new Button(this, SWT.ARROW | SWT.DOWN);
		fd = new FormData();
		fd.left = new FormAttachment(lblYearChar, 1, SWT.RIGHT);
		fd.right = new FormAttachment(lblYearChar, 21, SWT.RIGHT);
		fd.top = new FormAttachment(btnYearUp, 0, SWT.BOTTOM);
		fd.bottom = new FormAttachment(btnYearUp, 10, SWT.BOTTOM);
		btnYearDown.setLayoutData(fd);
		btnYearDown.addSelectionListener(
			new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					if(year < 9999) {
						year++;
						lblYear.setText(String.valueOf(year));
						if(!chkDisplayAll.getSelection())
							refreshRecord(false);	
					}
				}
			}
		);
		// 月标签
		lblMonth = new Label(this, SWT.RIGHT);
		lblMonth.setText(String.valueOf(month));
		fd = new FormData();
		fd.left = new FormAttachment(btnYearUp, 5, SWT.RIGHT);
		fd.right = new FormAttachment(btnYearUp, 25, SWT.RIGHT);
		fd.top = new FormAttachment(0, 0);
		lblMonth.setLayoutData(fd);
		Label lblMonthChar = new Label(this, SWT.NONE);
		lblMonthChar.setText(LumaQQ.getResourceString("record.viewer.label.month"));
		fd = new FormData();
		fd.left = new FormAttachment(lblMonth, 0, SWT.RIGHT);
		fd.top = new FormAttachment(0, 0);
		lblMonthChar.setLayoutData(fd);
		// 调整月的上按钮
		Button btnMonthUp = new Button(this, SWT.ARROW | SWT.UP);
		fd = new FormData();
		fd.left = new FormAttachment(lblMonthChar, 1, SWT.RIGHT);

⌨️ 快捷键说明

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