📄 sendimtabwindow.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;
import static edu.tsinghua.lumaqq.resource.Messages.*;
import java.util.HashMap;
import java.util.Map;
import edu.tsinghua.lumaqq.LumaQQ;
import edu.tsinghua.lumaqq.models.Cluster;
import edu.tsinghua.lumaqq.models.Model;
import edu.tsinghua.lumaqq.models.User;
import edu.tsinghua.lumaqq.qq.packets.in.ReceiveIMPacket;
import edu.tsinghua.lumaqq.resource.Colors;
import edu.tsinghua.lumaqq.resource.Resources;
import edu.tsinghua.lumaqq.widgets.qstyle.Slat;
import edu.tsinghua.lumaqq.widgets.record.ClusterRecordProvider;
import edu.tsinghua.lumaqq.widgets.record.FriendRecordProvider;
import edu.tsinghua.lumaqq.widgets.record.IRecordProvider;
import edu.tsinghua.lumaqq.widgets.record.RecordViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabFolder2Adapter;
import org.eclipse.swt.custom.CTabFolderEvent;
import org.eclipse.swt.custom.CTabItem;
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.ShellAdapter;
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.FillLayout;
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.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
/**
* 标签页方式的消息发送窗口
*
* @author luma
*/
public class SendIMTabWindow extends Window {
/**
* <pre>
* 闪烁图标
* </pre>
*
* @author luma
*/
private class Blink implements Runnable {
private boolean flag;
private volatile boolean stop;
private Image blinkImage;
public Blink() {
stop = true;
}
public void setBlinkImage(Image image) {
blinkImage = image;
stop = false;
flag = true;
}
public void run() {
try {
if(flag) {
getShell().setImage(blinkImage);
if(LumaQQ.IS_GTK)
((BorderStyler)getShell().getData(BorderStyler.STYLER)).repaintTitleBar();
} else {
getShell().setImage(res.getImage(Resources.icoBlank));
if(LumaQQ.IS_GTK)
((BorderStyler)getShell().getData(BorderStyler.STYLER)).repaintTitleBar();
}
flag = !flag;
if(!stop)
main.getDisplay().timerExec(500, this);
else {
getShell().setImage(res.getImage(Resources.icoMessage));
if(LumaQQ.IS_GTK)
((BorderStyler)getShell().getData(BorderStyler.STYLER)).repaintTitleBar();
}
} catch (Exception e) {
// 这个操作可能会抛出SWTException,如果组件已经dispose的话,
// 所以我们需要捕捉这个异常,不然程序可能崩溃
}
}
public void setStop(boolean stop) {
this.stop = stop;
}
public boolean isStop() {
return stop;
}
}
private MainShell main;
private Resources res;
private Menu enterMenu;
private RecordViewer viewer;
private CTabFolder folder;
private IIMContainer activeContainer;
private Blink blinkRunnable;
private boolean active;
// model到tab的注册表
private Map<Model, CTabItem> model2tab;
// model到container的注册表
private Map<Model, IIMContainer> model2container;
// id到model的注册表
private Map<Integer, Model> id2model;
// key advisor
private IContainerKeyHandler keyHandler = new IContainerKeyHandler() {
public void onKeyDown(int modifier, int keyChar) {
if((modifier & SWT.MOD3) != 0) {
switch(keyChar) {
case 'H':
showRecord();
break;
case 'C':
closeActiveContainer();
break;
case 'Q':
nextUnreadTab();
break;
case SWT.ARROW_RIGHT:
nextTab();
break;
case SWT.ARROW_LEFT:
previousTab();
break;
}
}
}
};
/**
* 构造函数
*
* @param main
* MainShell对象
*/
public SendIMTabWindow(MainShell main) {
super(main.getShell());
this.main = main;
this.res = Resources.getInstance();
model2tab = new HashMap<Model, CTabItem>();
model2container = new HashMap<Model, IIMContainer>();
id2model = new HashMap<Integer, Model>();
blinkRunnable = new Blink();
blinkRunnable.setBlinkImage(res.getImage(Resources.icoDialog));
active = false;
setBlockOnOpen(false);
}
/**
* 关闭当前tab
*/
protected void closeActiveContainer() {
CTabItem tab = folder.getSelection();
if(tab == null)
return;
IIMContainer container = (IIMContainer)tab.getControl();
clearContainerRegistry(container);
tab.dispose();
if(folder.getItemCount() == 0) {
closeWindow();
}
}
/**
* 初始化使用Enter键的菜单
*/
private void initEnterMenu() {
enterMenu = new Menu(getShell(), SWT.POP_UP);
// 使用Enter键菜单
final MenuItem miEnter = new MenuItem(enterMenu, SWT.RADIO);
miEnter.setText(im_menu_use_enter);
miEnter.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
main.getOptionHelper().setUseEnterInTalkMode(true);
resetEnterKey(true);
}
});
// 使用Ctrl + Enter键菜单
final MenuItem miCtrlEnter = new MenuItem(enterMenu, SWT.RADIO);
miCtrlEnter.setText(im_menu_use_ctrl_enter);
miCtrlEnter.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
main.getOptionHelper().setUseEnterInTalkMode(false);
resetEnterKey(false);
}
});
// 添加菜单显示事件监听器
enterMenu.addMenuListener(new MenuAdapter() {
public void menuShown(MenuEvent e) {
boolean b = main.getOptionHelper().isUseEnterInTalkMode();
miEnter.setSelection(b);
miCtrlEnter.setSelection(!b);
}
});
}
/**
* 重设消息快捷键
*
* @param b
* true表示使用Enter发送消息
*/
protected void resetEnterKey(boolean b) {
for(IIMContainer container : model2container.values())
container.setUseEnter(b);
}
@Override
protected void configureShell(Shell newShell) {
newShell.setText("LumaQQ - " + main.getMyModel().qq);
newShell.setImage(res.getImage(Resources.icoMessage));
newShell.addShellListener(new ShellAdapter() {
@Override
public void shellClosed(ShellEvent e) {
main.getShellRegistry().deregisterSendIMTabWindow();
for(IIMContainer container : model2container.values()) {
main.getClient().removeQQListener(container);
container.release();
}
}
@Override
public void shellDeactivated(ShellEvent e) {
active = false;
}
@Override
public void shellActivated(ShellEvent e) {
active = true;
stopBlinkImage();
}
});
if(LumaQQ.IS_GTK) {
BorderStyler styler = new BorderStyler(main);
styler.setShowMaxButton(true);
styler.setHideWhenMinimize(false);
styler.decorateShell(newShell);
}
}
@Override
protected void constrainShellSize() {
getShell().setSize(500, 470);
}
public void closeWindow() {
getShell().close();
}
@Override
protected Control createContents(Composite parent) {
Composite container = null;
if(LumaQQ.IS_GTK) {
container = ((BorderStyler)getShell().getData(BorderStyler.STYLER)).getCenter();
} else {
parent.setLayout(new FillLayout());
container = (Composite)super.createContents(parent);
}
GridLayout layout = new GridLayout();
container.setLayout(layout);
container.setBackground(Colors.MAINSHELL_BACKGROUND);
folder = new CTabFolder(container, SWT.FLAT | SWT.TOP | SWT.CLOSE);
folder.setLayoutData(new GridData(GridData.FILL_BOTH));
folder.setBackground(Colors.MAINSHELL_BACKGROUND);
folder.setSelectionBackground(Colors.LOGIN_BACKGROUND);
folder.setUnselectedCloseVisible(false);
folder.addCTabFolder2Listener(new CTabFolder2Adapter() {
@Override
public void close(CTabFolderEvent e) {
CTabItem tab = (CTabItem)e.item;
IIMContainer container = (IIMContainer)tab.getControl();
clearContainerRegistry(container);
// 如果是最后一个tab,关闭窗口
if(folder.getItemCount() == 1) {
e.doit = false;
closeWindow();
}
}
});
folder.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onTabSelection();
}
});
// 按钮区
Composite buttonContainer = new Composite(container, SWT.NONE);
buttonContainer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
layout = new GridLayout(5, false);
layout.marginHeight = layout.marginWidth = layout.verticalSpacing = layout.horizontalSpacing = 0;
buttonContainer.setLayout(layout);
buttonContainer.setBackground(container.getBackground());
Slat btnRecord = new Slat(buttonContainer);
btnRecord.setText(button_record_accel);
btnRecord.setLayoutData(new GridData());
btnRecord.addMouseListener(new MouseAdapter() {
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();
}
});
Slat btnNextTab = new Slat(buttonContainer);
btnNextTab.setText(button_next_tab);
GridData gd = new GridData();
gd.horizontalIndent = 3;
btnNextTab.setLayoutData(gd);
btnNextTab.addMouseListener(new MouseAdapter() {
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;
}
nextTab();
}
});
Slat btnClose = new Slat(buttonContainer);
btnClose.setText(button_close_accel);
gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
gd.grabExcessHorizontalSpace = true;
btnClose.setLayoutData(gd);
btnClose.addMouseListener(new MouseAdapter() {
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;
}
getShell().close();
}
});
final Slat btnSend = new Slat(buttonContainer);
btnSend.setText(button_send_accel);
gd = new GridData();
gd.horizontalIndent = 3;
btnSend.setLayoutData(gd);
btnSend.addMouseListener(new MouseAdapter() {
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;
}
IIMContainer container = getActiveContainer();
if(container == null)
return;
container.send();
}
});
Slat btnDropDown = new Slat(buttonContainer, SWT.CENTER);
btnDropDown.setText("↓");
gd = new GridData();
gd.horizontalIndent = 1;
btnDropDown.setLayoutData(gd);
btnDropDown.addMouseListener(new MouseAdapter() {
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;
}
// 设置菜单位置
Rectangle bound = btnSend.getBounds();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -