📄 utils.java
字号:
/*
* File : Utils.java
* Created : 25 sept. 2003 16:15:07
* By : Olivier
*
* Azureus - a Java Bittorrent client
*
* 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.
*
* 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 ( see the LICENSE file ).
*
* 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 org.gudy.azureus2.ui.swt;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.dnd.*;
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.graphics.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
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.util.AERunnable;
import org.gudy.azureus2.core3.util.Constants;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.ui.swt.mainwindow.Colors;
import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
import org.gudy.azureus2.ui.swt.views.utils.VerticalAligner;
/**
* @author Olivier
*
*/
public class Utils {
/** Some platforms expand the last column to fit the remaining width of
* the table.
*/
public static final boolean LAST_TABLECOLUMN_EXPANDS = Constants.isLinux;
public static final boolean isGTK = SWT.getPlatform().equals("gtk");
private static final boolean DIRECT_SETCHECKED = !Constants.isOSX
|| SWT.getVersion() >= 3212;
public static void disposeComposite(Composite composite,boolean disposeSelf) {
if(composite == null || composite.isDisposed())
return;
Control[] controls = composite.getChildren();
for(int i = 0 ; i < controls.length ; i++) {
Control control = controls[i];
if(control != null && ! control.isDisposed()) {
if(control instanceof Composite) {
disposeComposite((Composite) control,true);
}
try {
control.dispose();
} catch (SWTException e) {
Debug.printStackTrace( e );
}
}
}
// It's possible that the composite was destroyed by the child
if (!composite.isDisposed() && disposeSelf)
try {
composite.dispose();
} catch (SWTException e) {
Debug.printStackTrace( e );
}
}
public static void disposeComposite(Composite composite) {
disposeComposite(composite,true);
}
/**
* Dispose of a list of SWT objects
*
* @param disposeList
*/
public static void disposeSWTObjects(List disposeList) {
boolean bResourceObjectExists = SWT.getVersion() >= 3129;
for (int i = 0; i < disposeList.size(); i++) {
Object o = disposeList.get(i);
if (o instanceof Widget && !((Widget) o).isDisposed())
((Widget) o).dispose();
else if (bResourceObjectExists && (o instanceof Resource)
&& !((Resource) o).isDisposed())
((Resource) o).dispose();
else {
try {
// For Pre-SWT 3.1
if ((o instanceof Cursor) && !((Cursor)o).isDisposed()) {
((Cursor)o).dispose();
} else if ((o instanceof Font) && !((Font)o).isDisposed()) {
((Font)o).dispose();
} else if ((o instanceof GC) && !((GC)o).isDisposed()) {
((GC)o).dispose();
} else if ((o instanceof Image) && !((Image)o).isDisposed()) {
((Image)o).dispose();
} else if ((o instanceof Region) && !((Region)o).isDisposed()) {
((Region)o).dispose(); // 3.0
} else if ((o instanceof TextLayout) && !((TextLayout)o).isDisposed()) {
((TextLayout) o).dispose(); // 3.0
}
} catch (NoClassDefFoundError e) {
// ignore
}
// Path, Pattern, Transform are all 3.1, which will be instances of
// Resource
}
}
disposeList.clear();
}
/**
* Initializes the URL dialog with http://
* If a valid link is found in the clipboard, it will be inserted
* and the size (and location) of the dialog is adjusted.
* @param shell to set the dialog location if needed
* @param gridData to adjust the dialog with
* @param url the URL text control
*
* @author Rene Leonhardt
*/
public static void
setTextLinkFromClipboard(
final Shell shell, final Text url, boolean accept_magnets ) {
String link = getLinkFromClipboard(shell.getDisplay(),accept_magnets);
if (link != null)
url.setText(link);
}
/**
* <p>Gets an URL from the clipboard if a valid URL for downloading has been copied.</p>
* <p>The supported protocols currently are http, https, and magnet.</p>
* @param display
* @return first valid link from clipboard, else "http://"
*/
public static String
getLinkFromClipboard(
Display display,
boolean accept_magnets )
{
final String[] prefixes = new String[] {"http://", "https://", "magnet:?", "magnet://?" };
final Clipboard cb = new Clipboard(display);
final TextTransfer transfer = TextTransfer.getInstance();
String data = (String)cb.getContents(transfer);
if (data != null) {
data = data.trim();
for(int i = 0; i < (accept_magnets?prefixes.length:2 ); i++) {
final int begin = data.indexOf(prefixes[i]);
if (begin >= 0) {
final int end = data.indexOf("\n", begin + prefixes[i].length());
final String stringURL = (end >= 0) ? data.substring(begin, end - 1) : data.substring(begin);
try {
final URL parsedURL = new URL(stringURL);
return parsedURL.toExternalForm();
} catch (MalformedURLException e1) {
}
}
}
if ( accept_magnets && data.length() == 40 ){
for (int i=0;i<data.length();i++){
if ( "0123456789abcdefABCDEF".indexOf( data.charAt(i)) == -1 ){
return( prefixes[0] );
}
}
// accept raw hash of 40 hex chars
return( data );
}
}
return prefixes[0];
}
public static void
centreWindow(
Shell shell )
{
Rectangle displayRect;
try {
displayRect = shell.getMonitor().getClientArea();
} catch (NoSuchMethodError e) {
displayRect = shell.getDisplay().getClientArea();
}
Rectangle shellRect = shell.getBounds();
if (shellRect.width > displayRect.width - 100)
shellRect.width = displayRect.width - 100;
if (shellRect.height > displayRect.height - 64)
shellRect.height = displayRect.height - 100;
shellRect.x = (displayRect.width - shellRect.width) / 2;
shellRect.y = (displayRect.height - shellRect.height) / 2;
shell.setBounds(shellRect);
}
/**
* Centers a window relative to a control. That is to say, the window will be located at the center of the control.
* @param window
* @param control
*/
public static void centerWindowRelativeTo(final Shell window, final Control control)
{
final Rectangle bounds = control.getBounds();
final Point shellSize = window.getSize();
window.setLocation(
bounds.x + (bounds.width / 2) - shellSize.x / 2,
bounds.y + (bounds.height / 2) - shellSize.y / 2
);
}
/**
* @param control the control (usually a Shell) to add the DropTarget
* @param url the Text control where to set the link text
*
* @author Rene Leonhardt
*/
public static void createURLDropTarget(final Control control, final Text url) {
DropTarget dropTarget = new DropTarget(control, DND.DROP_DEFAULT | DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK);
dropTarget.setTransfer(new Transfer[] { URLTransfer.getInstance()});
dropTarget.addDropListener(new DropTargetAdapter() {
public void dropAccept(DropTargetEvent event) {
event.currentDataType = URLTransfer.pickBestType(event.dataTypes,
event.currentDataType);
}
public void dragOver(DropTargetEvent event) {
if ((event.operations & DND.DROP_LINK) > 0)
event.detail = DND.DROP_LINK;
else if ((event.operations & DND.DROP_COPY) > 0)
event.detail = DND.DROP_COPY;
}
public void drop(DropTargetEvent event) {
if (((URLTransfer.URLType)event.data).linkURL != null)
url.setText(((URLTransfer.URLType)event.data).linkURL);
}
});
}
/**
* Force label to use more vertical space if wrapped and in a GridLayout
* Place this listener on the _parent_ of the label
* See Eclipse SWT Bug #9866 (GridLayout does not handle wrapped Label properly)
* This workaround only works for labels who:
* - horizontally span their whole parent
* (ie. the parent has 3 columns, the label must span 3 columns)
* - GridData style has GridData.FILL_HORIZONTAL
* - Label style has SWT.WRAP
*
* @author TuxPaper
* @note Bug 9866 fixed in 3105 and later
*/
public static class LabelWrapControlListener extends ControlAdapter{
public void controlResized(ControlEvent e){
if (SWT.getVersion() >= 3105)
return;
Composite parent = (Composite)e.widget;
Control children[] = parent.getChildren();
if (children.length > 0) {
GridLayout parentLayout = (GridLayout)parent.getLayout();
if (parentLayout != null) {
Point size;
int marginWidth = parentLayout.marginWidth;
Composite grandParent = parent.getParent();
if (grandParent instanceof ScrolledComposite) {
Composite greatGP = grandParent.getParent();
if (greatGP != null) {
size = greatGP.getSize();
if (greatGP.getLayout() instanceof GridLayout) {
marginWidth += ((GridLayout)greatGP.getLayout()).marginWidth;
}
} else {
// not tested
size = grandParent.getSize();
}
if (grandParent.getLayout() instanceof GridLayout) {
marginWidth += ((GridLayout)grandParent.getLayout()).marginWidth;
}
ScrollBar sb = grandParent.getVerticalBar();
if (sb != null) {
// I don't know why, but we have to remove one
size.x -= sb.getSize().x + 1;
}
} else
size = parent.getSize();
boolean oneChanged = false;
for (int i = 0; i < children.length; i++) {
if ((children[i] instanceof Label) &&
(children[i].getStyle() & SWT.WRAP) == SWT.WRAP) {
GridData gd = (GridData)children[i].getLayoutData();
if (gd != null &&
gd.horizontalAlignment == GridData.FILL) {
if (gd.horizontalSpan == parentLayout.numColumns) {
gd.widthHint = size.x - 2 * marginWidth;
oneChanged = true;
} else {
Point pt = children[i].getLocation();
gd.widthHint = size.x - pt.x - (2 * marginWidth);
oneChanged = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -