📄 mainwindow.java
字号:
/*
* Created on Jun 25, 2003
* Modified Apr 13, 2004 by Alon Rohter
* Modified Apr 17, 2004 by Olivier Chalouhi (OSX system menu)
* Copyright (C) 2003, 2004, 2005, 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.mainwindow;
import com.aelitis.azureus.core.AzureusCore;
import com.aelitis.azureus.core.AzureusCoreException;
import com.aelitis.azureus.core.AzureusCoreListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.config.ParameterListener;
import org.gudy.azureus2.core3.config.impl.TransferSpeedValidator;
import org.gudy.azureus2.core3.download.DownloadManager;
import org.gudy.azureus2.core3.download.DownloadManagerListener;
import org.gudy.azureus2.core3.global.GlobalManager;
import org.gudy.azureus2.core3.global.GlobalManagerListener;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.core3.security.SESecurityManager;
import org.gudy.azureus2.core3.stats.transfer.OverallStats;
import org.gudy.azureus2.core3.stats.transfer.StatsFactory;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.plugins.PluginEvent;
import org.gudy.azureus2.plugins.PluginView;
import org.gudy.azureus2.plugins.network.ConnectionManager;
import org.gudy.azureus2.plugins.update.*;
import org.gudy.azureus2.ui.swt.*;
import org.gudy.azureus2.ui.swt.URLTransfer;
import org.gudy.azureus2.ui.swt.components.ColorUtils;
import org.gudy.azureus2.ui.swt.components.shell.ShellManager;
import org.gudy.azureus2.ui.swt.config.wizard.ConfigureWizard;
import org.gudy.azureus2.ui.swt.donations.DonationWindow2;
import org.gudy.azureus2.ui.swt.maketorrent.NewTorrentWizard;
import org.gudy.azureus2.ui.swt.plugins.UISWTPluginView;
import org.gudy.azureus2.ui.swt.plugins.UISWTView;
import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
import org.gudy.azureus2.ui.swt.sharing.progress.ProgressWindow;
import org.gudy.azureus2.ui.swt.update.UpdateProgressWindow;
import org.gudy.azureus2.ui.swt.update.UpdateWindow;
import org.gudy.azureus2.ui.swt.views.*;
import org.gudy.azureus2.ui.swt.views.configsections.ConfigSectionConnection;
import org.gudy.azureus2.ui.swt.views.stats.StatsView;
import org.gudy.azureus2.ui.swt.welcome.WelcomeWindow;
import org.gudy.azureus2.ui.swt.wizard.WizardListener;
import org.gudy.azureus2.ui.systray.SystemTraySWT;
import java.util.*;
/**
* @author Olivier
* Runnable : so that GUI initialization is done via asyncExec(this)
* STProgressListener : To make it visible once initialization is done
*/
public class
MainWindow
extends AERunnable
implements GlobalManagerListener, DownloadManagerListener,
ParameterListener, IconBarEnabler, AzureusCoreListener,
AEDiagnosticsEvidenceGenerator
{
private static final LogIDs LOGID = LogIDs.GUI;
private static MainWindow window;
private Initializer initializer;
private GUIUpdater updater;
private AzureusCore azureus_core;
//Package visibility for GUIUpdater
GlobalManager globalManager;
//NICO handle swt on macosx
public static boolean isAlreadyDead = false;
public static boolean isDisposeFromListener = false;
private Display display;
private Shell mainWindow;
private MainMenu mainMenu;
private IconBar iconBar;
private boolean useCustomTab;
private Composite folder;
private UpdateWindow updateWindow;
private Composite statusArea;
Composite statusBar;
StackLayout layoutStatusArea;
CLabel statusText;
private String statusTextKey = "";
private String statusImageKey = null;
private Composite statusUpdate;
private Label statusUpdateLabel;
private ProgressBar statusUpdateProgressBar;
//Package visibility for GUIUpdater
CLabel ipBlocked;
CLabel srStatus;
CLabel natStatus;
CLabel dhtStatus;
CLabel statusDown;
CLabel statusUp;
private TrayWindow tray;
SystemTraySWT systemTraySWT;
private HashMap downloadViews;
private AEMonitor downloadViews_mon = new AEMonitor( "MainWindow:dlviews" );
HashMap downloadBars;
AEMonitor downloadBars_mon = new AEMonitor( "MainWindow:dlbars" );
private Tab mytorrents;
private Tab my_tracker_tab;
private Tab my_shares_tab;
private Tab stats_tab;
private Tab console;
private Tab config;
private ConfigView config_view;
private ArrayList update_stack = new ArrayList();
protected AEMonitor this_mon = new AEMonitor( "MainWindow" );
/**
* Warning status icon identifier
*/
public static final String STATUS_ICON_WARN = "sb_warning";
private UISWTInstanceImpl uiSWTInstanceImpl;
private ArrayList events;
public
MainWindow(
AzureusCore _azureus_core,
Initializer _initializer,
ArrayList events)
{
try{
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "MainWindow start"));
AEDiagnostics.addEvidenceGenerator( this );
azureus_core = _azureus_core;
globalManager = azureus_core.getGlobalManager();
initializer = _initializer;
display = SWTThread.getInstance().getDisplay();
window = this;
initializer.addListener(this);
this.events = events;
display.syncExec(this);
}catch( AzureusCoreException e ){
Debug.printStackTrace( e );
}
}
public void runSupport() {
try{
useCustomTab = COConfigurationManager.getBooleanParameter("useCustomTab");
COConfigurationManager.addParameterListener( "config.style.useSIUnits", this );
mytorrents = null;
my_tracker_tab = null;
console = null;
config = null;
config_view = null;
downloadViews = new HashMap();
downloadBars = new HashMap();
//The Main Window
mainWindow = new Shell(display, SWT.RESIZE | SWT.BORDER | SWT.CLOSE | SWT.MAX | SWT.MIN);
mainWindow.setText("Azureus"); //$NON-NLS-1$
Utils.setShellIcon(mainWindow);
// register window
ShellManager.sharedManager().addWindow(mainWindow);
mainMenu = new MainMenu(this);
try {
createDropTarget(mainWindow);
} catch (Throwable e) {
Logger.log(new LogEvent(LOGID, "Drag and Drop not available", e));
}
FormLayout mainLayout = new FormLayout();
FormData formData;
mainLayout.marginHeight = 0;
mainLayout.marginWidth = 0;
try {
mainLayout.spacing = 0;
} catch (NoSuchFieldError e) { /* Pre SWT 3.0 */ }
mainWindow.setLayout(mainLayout);
Label separator = new Label(mainWindow,SWT.SEPARATOR | SWT.HORIZONTAL);
formData = new FormData();
formData.top = new FormAttachment(0, 0); // 2 params for Pre SWT 3.0
formData.left = new FormAttachment(0, 0); // 2 params for Pre SWT 3.0
formData.right = new FormAttachment(100, 0); // 2 params for Pre SWT 3.0
separator.setLayoutData(formData);
this.iconBar = new IconBar(mainWindow);
this.iconBar.setCurrentEnabler(this);
formData = new FormData();
formData.top = new FormAttachment(separator);
formData.left = new FormAttachment(0, 0); // 2 params for Pre SWT 3.0
formData.right = new FormAttachment(100, 0); // 2 params for Pre SWT 3.0
this.iconBar.setLayoutData(formData);
separator = new Label(mainWindow,SWT.SEPARATOR | SWT.HORIZONTAL);
formData = new FormData();
formData.top = new FormAttachment(iconBar.getCoolBar());
formData.left = new FormAttachment(0, 0); // 2 params for Pre SWT 3.0
formData.right = new FormAttachment(100, 0); // 2 params for Pre SWT 3.0
separator.setLayoutData(formData);
if(!useCustomTab) {
folder = new TabFolder(mainWindow, SWT.V_SCROLL);
} else {
folder = new CTabFolder(mainWindow, SWT.CLOSE | SWT.FLAT);
final Color bg = ColorUtils.getShade(folder.getBackground(), (Constants.isOSX) ? -25 : -6);
final Color fg = ColorUtils.getShade(folder.getForeground(), (Constants.isOSX) ? 25 : 6);
folder.setBackground(bg);
folder.setForeground(fg);
((CTabFolder)folder).setBorderVisible(false);
folder.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent event) {
bg.dispose();
fg.dispose();
}
});
}
Tab.setFolder(folder);
folder.getDisplay().addFilter(SWT.KeyDown, new Listener() {
public void handleEvent(Event event) {
// Another window has control, skip filter
Control focus_control = display.getFocusControl();
if (focus_control != null && focus_control.getShell() != mainWindow)
return;
int key = event.character;
if ((event.stateMask & SWT.MOD1) != 0 && event.character <= 26
&& event.character > 0)
key += 'a' - 1;
// ESC or CTRL+F4 closes current Tab
if (key == SWT.ESC
|| (event.keyCode == SWT.F4 && event.stateMask == SWT.CTRL)) {
Tab.closeCurrent();
event.doit = false;
} else if (event.keyCode == SWT.F6
|| (event.character == SWT.TAB && (event.stateMask & SWT.CTRL) != 0)) {
// F6 or Ctrl-Tab selects next Tab
// On Windows the tab key will not reach this filter, as it is
// processed by the traversal TRAVERSE_TAB_NEXT. It's unknown
// what other OSes do, so the code is here in case we get TAB
if ((event.stateMask & SWT.SHIFT) == 0) {
event.doit = false;
Tab.selectNextTab(true);
// Shift+F6 or Ctrl+Shift+Tab selects previous Tab
} else if (event.stateMask == SWT.SHIFT) {
Tab.selectNextTab(false);
event.doit = false;
}
} else if (key == 'l' && (event.stateMask & SWT.MOD1) != 0) {
// Ctrl-L: Open URL
OpenTorrentWindow.invokeURLPopup(mainWindow, globalManager);
event.doit = false;
}
}
});
SelectionAdapter selectionAdapter = new SelectionAdapter() {
public void widgetSelected(final SelectionEvent event) {
if(display != null && ! display.isDisposed())
Utils.execSWTThread(new AERunnable() {
public void runSupport() {
if(useCustomTab) {
CTabItem item = (CTabItem) event.item;
if(item != null && ! item.isDisposed() && ! folder.isDisposed()) {
try {
((CTabFolder)folder).setSelection(item);
Control control = item.getControl();
if (control != null) {
control.setVisible(true);
control.setFocus();
}
} catch(Throwable e) {
Debug.printStackTrace( e );
//Do nothing
}
}
}
iconBar.setCurrentEnabler(MainWindow.this);
}
});
}
};
if(!useCustomTab) {
((TabFolder)folder).addSelectionListener(selectionAdapter);
} else {
try {
((CTabFolder)folder).setMinimumCharacters( 75 );
} catch (Exception e) {
Logger.log(new LogEvent(LOGID, "Can't set MIN_TAB_WIDTH", e));
}
//try {
/// TabFolder2ListenerAdder.add((CTabFolder)folder);
//} catch (NoClassDefFoundError e) {
((CTabFolder)folder).addCTabFolderListener(new CTabFolderAdapter() {
public void itemClosed(CTabFolderEvent event) {
Tab.closed((CTabItem) event.item);
event.doit = true;
((CTabItem) event.item).dispose();
}
});
//}
((CTabFolder)folder).addSelectionListener(selectionAdapter);
try {
((CTabFolder)folder).setSelectionBackground(
new Color[] {display.getSystemColor(SWT.COLOR_LIST_BACKGROUND),
display.getSystemColor(SWT.COLOR_LIST_BACKGROUND),
display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND) },
new int[] {10, 90}, true);
} catch (NoSuchMethodError e) {
/** < SWT 3.0M8 **/
((CTabFolder)folder).setSelectionBackground(new Color[] {display.getSystemColor(SWT.COLOR_LIST_BACKGROUND) },
new int[0]);
}
((CTabFolder)folder).setSelectionForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
try {
/* Pre 3.0M8 doesn't have Simple-mode (it's always simple mode)
in 3.0M9, it was called setSimpleTab(boolean)
in 3.0RC1, it's called setSimple(boolean)
Prepare for the future, and use setSimple()
*/
((CTabFolder)folder).setSimple(!COConfigurationManager.getBooleanParameter("GUI_SWT_bFancyTab"));
} catch (NoSuchMethodError e) {
/** < SWT 3.0RC1 **/
}
}
final int borderFlag = (Constants.isOSX) ? SWT.NONE : SWT.SHADOW_IN;
statusBar = new Composite(mainWindow, SWT.NONE);
formData = new FormData();
formData.top = new FormAttachment(separator);
formData.bottom = new FormAttachment(statusBar);
formData.left = new FormAttachment(0, 0); // 2 params for Pre SWT 3.0
formData.right = new FormAttachment(100, 0); // 2 params for Pre SWT 3.0
folder.setLayoutData(formData);
GridLayout layout_status = new GridLayout();
layout_status.numColumns = 7;
layout_status.horizontalSpacing = 0;
layout_status.verticalSpacing = 0;
layout_status.marginHeight = 0;
if (Constants.isOSX) {
// OSX has a resize widget on the bottom right. It's about 15px wide.
try {
layout_status.marginRight = 15;
} catch (NoSuchFieldError e) {
// Pre SWT 3.1
layout_status.marginWidth = 15;
}
} else {
layout_status.marginWidth = 0;
}
statusBar.setLayout(layout_status);
GridData gridData;
//Composite with StackLayout
statusArea = new Composite(statusBar, SWT.NONE);
gridData = new GridData(GridData.FILL_BOTH);
statusArea.setLayoutData(gridData);
layoutStatusArea = new StackLayout();
statusArea.setLayout(layoutStatusArea);
//Either the Status Text
statusText = new CLabel(statusArea, borderFlag);
gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
statusText.setLayoutData(gridData);
// This is the highest image displayed on the statusbar
int imageHeight = ImageRepository.getImage(STATUS_ICON_WARN).getBounds().height;
GC gc = new GC(statusText);
// add 6, because CLabel forces a 3 pixel indent
int height = Math.max(imageHeight, gc.getFontMetrics().getHeight()) + 6;
gc.dispose();
formData = new FormData();
formData.height = height;
formData.bottom = new FormAttachment(100, 0); // 2 params for Pre SWT 3.0
formData.left = new FormAttachment(0, 0); // 2 params for Pre SWT 3.0
formData.right = new FormAttachment(100, 0); // 2 params for Pre SWT 3.0
statusBar.setLayoutData(formData);
Listener listener = new Listener() {
public void handleEvent(Event e) {
if(updateWindow != null) {
updateWindow.show();
}
}
};
statusText.addListener(SWT.MouseUp,listener);
statusText.addListener(SWT.MouseDoubleClick,listener);
//Or a composite with a label, a progressBar and a button
statusUpdate = new Composite(statusArea, SWT.NULL);
gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
statusUpdate.setLayoutData(gridData);
GridLayout layoutStatusUpdate = new GridLayout(2, false);
layoutStatusUpdate.marginHeight = 0;
layoutStatusUpdate.marginWidth = 0;
statusUpdate.setLayout(layoutStatusUpdate);
statusUpdateLabel = new Label(statusUpdate,SWT.NULL);
gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
statusUpdateLabel.setLayoutData(gridData);
Messages.setLanguageText(statusUpdateLabel, "MainWindow.statusText.checking");
Messages.setLanguageText(statusUpdateLabel,"MainWindow.status.update.tooltip");
statusUpdateLabel.addMouseListener(new MouseAdapter() {
public void mouseDoubleClick(MouseEvent arg0) {
showUpdateProgressWindow();
}
});
final int progressFlag = (Constants.isOSX) ? SWT.INDETERMINATE : SWT.HORIZONTAL;
statusUpdateProgressBar = new ProgressBar(statusUpdate ,progressFlag);
gridData = new GridData(GridData.FILL_BOTH);
statusUpdateProgressBar.setLayoutData(gridData);
Messages.setLanguageText(statusUpdateProgressBar,"MainWindow.status.update.tooltip");
statusUpdateProgressBar.addMouseListener(new MouseAdapter() {
public void mouseDoubleClick(MouseEvent arg0) {
showUpdateProgressWindow();
}
});
layoutStatusArea.topControl = statusText;
statusBar.layout();
srStatus = new CLabelPadding(statusBar,borderFlag);
srStatus.setText( MessageText.getString("SpeedView.stats.ratio" ));
COConfigurationManager.addAndFireParameterListener(
"Status Area Show SR",
new ParameterListener()
{
public void parameterChanged(String parameterName)
{
srStatus.setVisible( COConfigurationManager.getBooleanParameter(parameterName,true));
statusBar.layout();
}
});
natStatus = new CLabelPadding(statusBar,borderFlag);
natStatus.setText( "" );
COConfigurationManager.addAndFireParameterListener(
"Status Area Show NAT",
new ParameterListener()
{
public void parameterChanged(String parameterName)
{
natStatus.setVisible( COConfigurationManager.getBooleanParameter(parameterName,true));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -