📄 messageslideshell.java
字号:
/*
* Created on Mar 7, 2006 10:42:32 PM
* Copyright (C) 2006 Aelitis, All Rights Reserved.
*
* 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.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*/
package org.gudy.azureus2.ui.swt.shells;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.*;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.logging.LogEvent;
import org.gudy.azureus2.core3.logging.LogIDs;
import org.gudy.azureus2.core3.logging.Logger;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.ui.swt.ImageRepository;
import org.gudy.azureus2.ui.swt.Messages;
import org.gudy.azureus2.ui.swt.Utils;
import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
/**
*
* +=====================================+
* | +----+ |
* | |Icon| Big Bold Title |
* | +----+ |
* | Wrapping message text |
* | with optional URL links |
* | +-----+ |
* | |BGImg| XX more slideys.. |
* | | Icon| Closing in XX secs |
* | +-----+ [HideAll] [Details] [Hide] |
* +=====================================+
*
* @author TuxPaper
* @created Mar 7, 2006
*
*/
public class MessageSlideShell {
private static boolean USE_SWT32_BG_SET = true;
private static final boolean DEBUG = false;
private final static String REGEX_URLHTML = "<A HREF=\"(.+?)\">(.+?)</A>";
/** Slide until there's this much gap between shell and edge of screen */
private final static int EDGE_GAP = 0;
/** Width used when BG image can't be loaded */
private final static int SHELL_DEF_WIDTH = 280;
/** Standard height of the shell. Shell may grow depending on text */
private final static int SHELL_MIN_HEIGHT = 150;
/** Maximimum height of popup. If text is too long, the full text will be
* put into details.
*/
private final static int SHELL_MAX_HEIGHT = 330;
/** Width of the details shell */
private final static int DETAILS_WIDTH = 550;
/** Height of the details shell */
private final static int DETAILS_HEIGHT = 180;
/** Synchronization for popupList */
private final static AEMonitor monitor = new AEMonitor("slidey_mon");
/** List of all popups ever created */
private static ArrayList historyList = new ArrayList();
/** Current popup being displayed */
private static int currentPopupIndex = -1;
/** Shell for popup */
private Shell shell;
/** Composite in shell */
private Composite cShell;
/** popup could and closing in xx seconds label */
private Label lblCloseIn;
/** Button that hides all slideys in the popupList. Visible only when there's
* more than 1 slidey
*/
private Button btnHideAll;
/** Button to move to next message. Text changes from "Hide" to "Next"
* appropriately.
*/
private Button btnNext;
/** paused state of auto-close delay */
private boolean bDelayPaused = false;
/** List of SWT objects needing disposal */
private ArrayList disposeList = new ArrayList();
/** Text to put into details popup */
private String sDetails;
/** Position this popup is in the history list */
private int idxHistory;
/** Open a popup using resource keys for title/text
*
* @param display Display to create the shell on
* @param iconID SWT.ICON_* constant for icon in top left
* @param keyPrefix message bundle key prefix used to get title and text.
* Title will be keyPrefix + ".title", and text will be set to
* keyPrefix + ".text"
* @param details actual text for details (not a key)
* @param textParams any parameters for text
*
* @note Display moved to end to remove conflict in constructors
*/
public MessageSlideShell(Display display, int iconID, String keyPrefix,
String details, String[] textParams) {
this(display, iconID, MessageText.getString(keyPrefix + ".title"),
MessageText.getString(keyPrefix + ".text", textParams), details);
}
/**
* Open Mr Slidey
*
* @param display Display to create the shell on
* @param iconID SWT.ICON_* constant for icon in top left
* @param title Text to put in the title
* @param text Text to put in the body
* @param details Text displayed when the Details button is pressed. Null
* for disabled Details button.
*/
public MessageSlideShell(Display display, int iconID, String title,
String text, String details) {
try {
monitor.enter();
PopupParams popupParams = new PopupParams(iconID, title, text, details);
historyList.add(popupParams);
if (currentPopupIndex < 0) {
create(display, popupParams, true);
}
} catch (Exception e) {
Logger.log(new LogEvent(LogIDs.GUI, "Mr. Slidey Init", e));
disposeShell(shell);
Utils.disposeSWTObjects(disposeList);
} finally {
monitor.exit();
}
}
private MessageSlideShell(Display display, PopupParams popupParams,
boolean bSlide) {
create(display, popupParams, bSlide);
}
private void create(final Display display, final PopupParams popupParams,
boolean bSlide) {
GridData gridData;
int shellWidth;
int style = SWT.ON_TOP;
boolean bDisableSliding = COConfigurationManager.getBooleanParameter("GUI_SWT_DisableAlertSliding");
if (bDisableSliding) {
bSlide = false;
style = SWT.NONE;
}
if (DEBUG)
System.out.println("create " + (bSlide ? "SlideIn" : "") + ";"
+ historyList.indexOf(popupParams) + ";");
idxHistory = historyList.indexOf(popupParams);
// 2 Assertions
if (idxHistory < 0) {
System.err.println("Not in popup history list");
return;
}
if (currentPopupIndex == idxHistory) {
System.err.println("Trying to open already opened!! " + idxHistory);
return;
}
try {
monitor.enter();
currentPopupIndex = idxHistory;
} finally {
monitor.exit();
}
if (DEBUG)
System.out.println("set currIdx = " + idxHistory);
sDetails = popupParams.details;
// Load Images
// Disable BG Image on OSX
Image imgPopup;
if (Constants.isOSX && (SWT.getVersion() < 3221 || !USE_SWT32_BG_SET)) {
USE_SWT32_BG_SET = false;
imgPopup = null;
} else {
imgPopup = ImageRepository.getImage("popup");
}
Rectangle imgPopupBounds;
if (imgPopup != null) {
shellWidth = imgPopup.getBounds().width;
imgPopupBounds = imgPopup.getBounds();
} else {
shellWidth = SHELL_DEF_WIDTH;
imgPopupBounds = null;
}
Image imgIcon = null;
switch (popupParams.iconID) {
case SWT.ICON_ERROR:
imgIcon = ImageRepository.getImage("error");
break;
case SWT.ICON_WARNING:
imgIcon = ImageRepository.getImage("warning");
break;
case SWT.ICON_INFORMATION:
imgIcon = ImageRepository.getImage("info");
break;
default:
imgIcon = null;
break;
}
// if there's a link, or the info is non-information,
// disable timer and mouse watching
bDelayPaused = UrlUtils.parseHTMLforURL(popupParams.text) != null
|| popupParams.iconID != SWT.ICON_INFORMATION || !bSlide;
// Pause the auto-close delay when mouse is over slidey
// This will be applies to every control
final MouseTrackAdapter mouseAdapter = bDelayPaused ? null
: new MouseTrackAdapter() {
public void mouseEnter(MouseEvent e) {
bDelayPaused = true;
}
public void mouseExit(MouseEvent e) {
bDelayPaused = false;
}
};
// Create shell & widgets
if (bDisableSliding) {
UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
if (uiFunctions != null) {
Shell mainShell = uiFunctions.getMainShell();
if (mainShell != null) {
shell = new Shell(mainShell, style);
}
}
}
if (shell == null) {
shell = new Shell(display, style);
}
if (USE_SWT32_BG_SET) {
try {
shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
} catch (NoSuchMethodError e) {
// Ignore
} catch (NoSuchFieldError e2) {
// ignore
}
}
Utils.setShellIcon(shell);
shell.setText(popupParams.title);
FormLayout shellLayout = new FormLayout();
shell.setLayout(shellLayout);
cShell = new Composite(shell, SWT.NULL);
GridLayout layout = new GridLayout(3, false);
cShell.setLayout(layout);
FormData formData = new FormData();
formData.left = new FormAttachment(0, 0);
formData.right = new FormAttachment(100, 0);
cShell.setLayoutData(formData);
Label lblIcon = new Label(cShell, SWT.NONE);
lblIcon.setImage(imgIcon);
lblIcon.setLayoutData(new GridData());
Label lblTitle = new Label(cShell, SWT.getVersion() < 3100 ? SWT.NONE
: SWT.WRAP);
gridData = new GridData(GridData.FILL_HORIZONTAL);
if (SWT.getVersion() < 3100)
gridData.widthHint = 140;
lblTitle.setLayoutData(gridData);
lblTitle.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
lblTitle.setText(popupParams.title);
FontData[] fontData = lblTitle.getFont().getFontData();
fontData[0].setStyle(SWT.BOLD);
fontData[0].setHeight((int) (fontData[0].getHeight() * 1.5));
Font boldFont = new Font(display, fontData);
disposeList.add(boldFont);
lblTitle.setFont(boldFont);
final Button btnDetails = new Button(cShell, SWT.TOGGLE);
btnDetails.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
Messages.setLanguageText(btnDetails, "popup.error.details");
gridData = new GridData();
btnDetails.setLayoutData(gridData);
btnDetails.addListener(SWT.MouseUp, new Listener() {
public void handleEvent(Event arg0) {
try {
boolean bShow = btnDetails.getSelection();
if (bShow) {
Shell detailsShell = new Shell(display, SWT.BORDER | SWT.ON_TOP);
Utils.setShellIcon(detailsShell);
detailsShell.setLayout(new FillLayout());
StyledText textDetails = new StyledText(detailsShell, SWT.READ_ONLY
| SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
textDetails.setBackground(display.getSystemColor(SWT.COLOR_LIST_BACKGROUND));
textDetails.setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
textDetails.setWordWrap(true);
textDetails.setText(sDetails);
detailsShell.layout();
Rectangle shellBounds = shell.getBounds();
detailsShell.setBounds(shellBounds.x + shellBounds.width
- DETAILS_WIDTH, shellBounds.y - DETAILS_HEIGHT, DETAILS_WIDTH,
DETAILS_HEIGHT);
detailsShell.open();
shell.setData("detailsShell", detailsShell);
shell.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
Shell detailsShell = (Shell) shell.getData("detailsShell");
if (detailsShell != null && !detailsShell.isDisposed()) {
detailsShell.dispose();
}
}
});
// disable auto-close on opening of details
bDelayPaused = true;
removeMouseTrackListener(shell, mouseAdapter);
} else {
Shell detailsShell = (Shell) shell.getData("detailsShell");
if (detailsShell != null && !detailsShell.isDisposed()) {
detailsShell.dispose();
}
}
} catch (Exception e) {
Logger.log(new LogEvent(LogIDs.GUI, "Mr. Slidey DetailsButton", e));
}
}
});
try {
Link linkLabel = new Link(cShell, SWT.WRAP);
gridData = new GridData(GridData.FILL_BOTH);
gridData.horizontalSpan = 3;
linkLabel.setLayoutData(gridData);
linkLabel.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
linkLabel.setText(popupParams.text);
linkLabel.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (e.text.endsWith(".torrent"))
TorrentOpener.openTorrent(e.text);
else
Utils.launch(e.text);
}
});
Matcher matcher = Pattern
.compile(REGEX_URLHTML, Pattern.CASE_INSENSITIVE).matcher(
popupParams.text);
String tooltip = null;
while (matcher.find()) {
if (tooltip == null)
tooltip = "";
else
tooltip += "\n";
tooltip += matcher.group(2) + ": " + matcher.group(1);
}
linkLabel.setToolTipText(tooltip);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -