blob: a9b0cd45e0cc67dc6c70a08b3ac069751ecf7cf7 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ide.eclipse.monitor.ddms;
import com.android.ddmlib.IDevice;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import java.util.ArrayList;
/**
* Small dialog box to edit a static port number.
*/
public class StaticPortEditDialog extends Dialog {
private static final int DLG_WIDTH = 400;
private static final int DLG_HEIGHT = 200;
private Shell mParent;
private Shell mShell;
private boolean mOk = false;
private String mAppName;
private String mPortNumber;
private Button mOkButton;
private Label mWarning;
/** List of ports already in use */
private ArrayList<Integer> mPorts;
/** This is the port being edited. */
private int mEditPort = -1;
private String mDeviceSn;
/**
* Creates a dialog with empty fields.
* @param parent The parent Shell
* @param ports The list of already used port numbers.
*/
public StaticPortEditDialog(Shell parent, ArrayList<Integer> ports) {
super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
mPorts = ports;
mDeviceSn = IDevice.FIRST_EMULATOR_SN;
}
/**
* Creates a dialog with predefined values.
* @param shell The parent shell
* @param ports The list of already used port numbers.
* @param oldDeviceSN the device serial number to display
* @param oldAppName The application name to display
* @param oldPortNumber The port number to display
*/
public StaticPortEditDialog(Shell shell, ArrayList<Integer> ports,
String oldDeviceSN, String oldAppName, String oldPortNumber) {
this(shell, ports);
mDeviceSn = oldDeviceSN;
mAppName = oldAppName;
mPortNumber = oldPortNumber;
mEditPort = Integer.valueOf(mPortNumber);
}
/**
* Opens the dialog. The method will return when the user closes the dialog
* somehow.
*
* @return true if ok was pressed, false if cancelled.
*/
public boolean open() {
createUI();
if (mParent == null || mShell == null) {
return false;
}
mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
Rectangle r = mParent.getBounds();
// get the center new top left.
int cx = r.x + r.width/2;
int x = cx - DLG_WIDTH / 2;
int cy = r.y + r.height/2;
int y = cy - DLG_HEIGHT / 2;
mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
mShell.open();
Display display = mParent.getDisplay();
while (!mShell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
return mOk;
}
public String getDeviceSN() {
return mDeviceSn;
}
public String getAppName() {
return mAppName;
}
public int getPortNumber() {
return Integer.valueOf(mPortNumber);
}
private void createUI() {
mParent = getParent();
mShell = new Shell(mParent, getStyle());
mShell.setText("Static Port");
mShell.setLayout(new GridLayout(1, false));
mShell.addListener(SWT.Close, new Listener() {
@Override
public void handleEvent(Event event) {
}
});
// center part with the edit field
Composite main = new Composite(mShell, SWT.NONE);
main.setLayoutData(new GridData(GridData.FILL_BOTH));
main.setLayout(new GridLayout(2, false));
Label l0 = new Label(main, SWT.NONE);
l0.setText("Device Name:");
final Text deviceSNText = new Text(main, SWT.SINGLE | SWT.BORDER);
deviceSNText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
if (mDeviceSn != null) {
deviceSNText.setText(mDeviceSn);
}
deviceSNText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
mDeviceSn = deviceSNText.getText().trim();
validate();
}
});
Label l = new Label(main, SWT.NONE);
l.setText("Application Name:");
final Text appNameText = new Text(main, SWT.SINGLE | SWT.BORDER);
if (mAppName != null) {
appNameText.setText(mAppName);
}
appNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
appNameText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
mAppName = appNameText.getText().trim();
validate();
}
});
Label l2 = new Label(main, SWT.NONE);
l2.setText("Debug Port:");
final Text debugPortText = new Text(main, SWT.SINGLE | SWT.BORDER);
if (mPortNumber != null) {
debugPortText.setText(mPortNumber);
}
debugPortText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
debugPortText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
mPortNumber = debugPortText.getText().trim();
validate();
}
});
// warning label
Composite warningComp = new Composite(mShell, SWT.NONE);
warningComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
warningComp.setLayout(new GridLayout(1, true));
mWarning = new Label(warningComp, SWT.NONE);
mWarning.setText("");
mWarning.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
// bottom part with the ok/cancel
Composite bottomComp = new Composite(mShell, SWT.NONE);
bottomComp
.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
bottomComp.setLayout(new GridLayout(2, true));
mOkButton = new Button(bottomComp, SWT.NONE);
mOkButton.setText("OK");
mOkButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mOk = true;
mShell.close();
}
});
mOkButton.setEnabled(false);
mShell.setDefaultButton(mOkButton);
Button cancelButton = new Button(bottomComp, SWT.NONE);
cancelButton.setText("Cancel");
cancelButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mShell.close();
}
});
validate();
}
/**
* Validates the content of the 2 text fields and enable/disable "ok", while
* setting up the warning/error message.
*/
private void validate() {
// first we reset the warning dialog. This allows us to latter
// display warnings.
mWarning.setText(""); //$NON-NLS-1$
// check the device name field is not empty
if (mDeviceSn == null || mDeviceSn.length() == 0) {
mWarning.setText("Device name missing.");
mOkButton.setEnabled(false);
return;
}
// check the application name field is not empty
if (mAppName == null || mAppName.length() == 0) {
mWarning.setText("Application name missing.");
mOkButton.setEnabled(false);
return;
}
String packageError = "Application name must be a valid Java package name.";
// validate the package name as well. It must be a fully qualified
// java package.
String[] packageSegments = mAppName.split("\\."); //$NON-NLS-1$
for (String p : packageSegments) {
if (p.matches("^[a-zA-Z][a-zA-Z0-9]*") == false) { //$NON-NLS-1$
mWarning.setText(packageError);
mOkButton.setEnabled(false);
return;
}
// lets also display a warning if the package contains upper case
// letters.
if (p.matches("^[a-z][a-z0-9]*") == false) { //$NON-NLS-1$
mWarning.setText("Lower case is recommended for Java packages.");
}
}
// the split will not detect the last char being a '.'
// so we test it manually
if (mAppName.charAt(mAppName.length()-1) == '.') {
mWarning.setText(packageError);
mOkButton.setEnabled(false);
return;
}
// now we test the package name field is not empty.
if (mPortNumber == null || mPortNumber.length() == 0) {
mWarning.setText("Port Number missing.");
mOkButton.setEnabled(false);
return;
}
// then we check it only contains digits.
if (mPortNumber.matches("[0-9]*") == false) { //$NON-NLS-1$
mWarning.setText("Port Number invalid.");
mOkButton.setEnabled(false);
return;
}
// get the int from the port number to validate
long port = Long.valueOf(mPortNumber);
if (port >= 32767) {
mOkButton.setEnabled(false);
return;
}
// check if its in the list of already used ports
if (port != mEditPort) {
for (Integer i : mPorts) {
if (port == i.intValue()) {
mWarning.setText("Port already in use.");
mOkButton.setEnabled(false);
return;
}
}
}
// at this point there's not error, so we enable the ok button.
mOkButton.setEnabled(true);
}
}