Home | History | Annotate | Download | only in ddms
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.ide.eclipse.monitor.ddms;
     18 
     19 import com.android.ddmuilib.TableHelper;
     20 import com.android.ide.eclipse.ddms.DdmsPlugin;
     21 
     22 import org.eclipse.swt.SWT;
     23 import org.eclipse.swt.events.SelectionAdapter;
     24 import org.eclipse.swt.events.SelectionEvent;
     25 import org.eclipse.swt.graphics.Rectangle;
     26 import org.eclipse.swt.layout.GridData;
     27 import org.eclipse.swt.layout.GridLayout;
     28 import org.eclipse.swt.widgets.Button;
     29 import org.eclipse.swt.widgets.Composite;
     30 import org.eclipse.swt.widgets.Dialog;
     31 import org.eclipse.swt.widgets.Display;
     32 import org.eclipse.swt.widgets.Event;
     33 import org.eclipse.swt.widgets.Listener;
     34 import org.eclipse.swt.widgets.Shell;
     35 import org.eclipse.swt.widgets.Table;
     36 import org.eclipse.swt.widgets.TableItem;
     37 
     38 import java.util.ArrayList;
     39 import java.util.HashMap;
     40 import java.util.Map;
     41 import java.util.Set;
     42 
     43 /**
     44  * Dialog to configure the static debug ports.
     45  *
     46  */
     47 public class StaticPortConfigDialog extends Dialog {
     48 
     49     /** Preference name for the 0th column width */
     50     private static final String PREFS_DEVICE_COL = "spcd.deviceColumn"; //$NON-NLS-1$
     51 
     52     /** Preference name for the 1st column width */
     53     private static final String PREFS_APP_COL = "spcd.AppColumn"; //$NON-NLS-1$
     54 
     55     /** Preference name for the 2nd column width */
     56     private static final String PREFS_PORT_COL = "spcd.PortColumn"; //$NON-NLS-1$
     57 
     58     private static final int COL_DEVICE = 0;
     59     private static final int COL_APPLICATION = 1;
     60     private static final int COL_PORT = 2;
     61 
     62 
     63     private static final int DLG_WIDTH = 500;
     64     private static final int DLG_HEIGHT = 300;
     65 
     66     private Shell mShell;
     67     private Shell mParent;
     68 
     69     private Table mPortTable;
     70 
     71     /**
     72      * Array containing the list of already used static port to avoid
     73      * duplication.
     74      */
     75     private ArrayList<Integer> mPorts = new ArrayList<Integer>();
     76 
     77     /**
     78      * Basic constructor.
     79      * @param parent
     80      */
     81     public StaticPortConfigDialog(Shell parent) {
     82         super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
     83     }
     84 
     85     /**
     86      * Open and display the dialog. This method returns only when the
     87      * user closes the dialog somehow.
     88      *
     89      */
     90     public void open() {
     91         createUI();
     92 
     93         if (mParent == null || mShell == null) {
     94             return;
     95         }
     96 
     97         updateFromStore();
     98 
     99         // Set the dialog size.
    100         mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
    101         Rectangle r = mParent.getBounds();
    102         // get the center new top left.
    103         int cx = r.x + r.width/2;
    104         int x = cx - DLG_WIDTH / 2;
    105         int cy = r.y + r.height/2;
    106         int y = cy - DLG_HEIGHT / 2;
    107         mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
    108 
    109         mShell.pack();
    110 
    111         // actually open the dialog
    112         mShell.open();
    113 
    114         // event loop until the dialog is closed.
    115         Display display = mParent.getDisplay();
    116         while (!mShell.isDisposed()) {
    117             if (!display.readAndDispatch())
    118                 display.sleep();
    119         }
    120     }
    121 
    122     /**
    123      * Creates the dialog ui.
    124      */
    125     private void createUI() {
    126         mParent = getParent();
    127         mShell = new Shell(mParent, getStyle());
    128         mShell.setText("Static Port Configuration");
    129 
    130         mShell.setLayout(new GridLayout(1, true));
    131 
    132         mShell.addListener(SWT.Close, new Listener() {
    133             @Override
    134             public void handleEvent(Event event) {
    135                 event.doit = true;
    136             }
    137         });
    138 
    139         // center part with the list on the left and the buttons
    140         // on the right.
    141         Composite main = new Composite(mShell, SWT.NONE);
    142         main.setLayoutData(new GridData(GridData.FILL_BOTH));
    143         main.setLayout(new GridLayout(2, false));
    144 
    145         // left part: list view
    146         mPortTable = new Table(main, SWT.SINGLE | SWT.FULL_SELECTION);
    147         mPortTable.setLayoutData(new GridData(GridData.FILL_BOTH));
    148         mPortTable.setHeaderVisible(true);
    149         mPortTable.setLinesVisible(true);
    150 
    151         TableHelper.createTableColumn(mPortTable, "Device Serial Number",
    152                 SWT.LEFT, "emulator-5554", //$NON-NLS-1$
    153                 PREFS_DEVICE_COL, DdmsPlugin.getDefault().getPreferenceStore());
    154 
    155         TableHelper.createTableColumn(mPortTable, "Application Package",
    156                 SWT.LEFT, "com.android.samples.phone", //$NON-NLS-1$
    157                 PREFS_APP_COL, DdmsPlugin.getDefault().getPreferenceStore());
    158 
    159         TableHelper.createTableColumn(mPortTable, "Debug Port",
    160                 SWT.RIGHT, "Debug Port", //$NON-NLS-1$
    161                 PREFS_PORT_COL, DdmsPlugin.getDefault().getPreferenceStore());
    162 
    163         // right part: buttons
    164         Composite buttons = new Composite(main, SWT.NONE);
    165         buttons.setLayoutData(new GridData(GridData.FILL_VERTICAL));
    166         buttons.setLayout(new GridLayout(1, true));
    167 
    168         Button newButton = new Button(buttons, SWT.NONE);
    169         newButton.setText("New...");
    170         newButton.addSelectionListener(new SelectionAdapter() {
    171             @Override
    172             public void widgetSelected(SelectionEvent e) {
    173                 StaticPortEditDialog dlg = new StaticPortEditDialog(mShell,
    174                         mPorts);
    175                 if (dlg.open()) {
    176                     // get the text
    177                     String device = dlg.getDeviceSN();
    178                     String app = dlg.getAppName();
    179                     int port = dlg.getPortNumber();
    180 
    181                     // add it to the list
    182                     addEntry(device, app, port);
    183                 }
    184             }
    185         });
    186 
    187         final Button editButton = new Button(buttons, SWT.NONE);
    188         editButton.setText("Edit...");
    189         editButton.setEnabled(false);
    190         editButton.addSelectionListener(new SelectionAdapter() {
    191             @Override
    192             public void widgetSelected(SelectionEvent e) {
    193                 int index = mPortTable.getSelectionIndex();
    194                 String oldDeviceName = getDeviceName(index);
    195                 String oldAppName = getAppName(index);
    196                 String oldPortNumber = getPortNumber(index);
    197                 StaticPortEditDialog dlg = new StaticPortEditDialog(mShell,
    198                         mPorts, oldDeviceName, oldAppName, oldPortNumber);
    199                 if (dlg.open()) {
    200                     // get the text
    201                     String deviceName = dlg.getDeviceSN();
    202                     String app = dlg.getAppName();
    203                     int port = dlg.getPortNumber();
    204 
    205                     // add it to the list
    206                     replaceEntry(index, deviceName, app, port);
    207                 }
    208             }
    209         });
    210 
    211         final Button deleteButton = new Button(buttons, SWT.NONE);
    212         deleteButton.setText("Delete");
    213         deleteButton.setEnabled(false);
    214         deleteButton.addSelectionListener(new SelectionAdapter() {
    215             @Override
    216             public void widgetSelected(SelectionEvent e) {
    217                 int index = mPortTable.getSelectionIndex();
    218                 removeEntry(index);
    219             }
    220         });
    221 
    222         // bottom part with the ok/cancel
    223         Composite bottomComp = new Composite(mShell, SWT.NONE);
    224         bottomComp.setLayoutData(new GridData(
    225                 GridData.HORIZONTAL_ALIGN_CENTER));
    226         bottomComp.setLayout(new GridLayout(2, true));
    227 
    228         Button okButton = new Button(bottomComp, SWT.NONE);
    229         okButton.setText("OK");
    230         okButton.addSelectionListener(new SelectionAdapter() {
    231             @Override
    232             public void widgetSelected(SelectionEvent e) {
    233                 updateStore();
    234                 mShell.close();
    235             }
    236         });
    237 
    238         Button cancelButton = new Button(bottomComp, SWT.NONE);
    239         cancelButton.setText("Cancel");
    240         cancelButton.addSelectionListener(new SelectionAdapter() {
    241             @Override
    242             public void widgetSelected(SelectionEvent e) {
    243                 mShell.close();
    244             }
    245         });
    246 
    247         mPortTable.addSelectionListener(new SelectionAdapter() {
    248             @Override
    249             public void widgetSelected(SelectionEvent e) {
    250                 // get the selection index
    251                 int index = mPortTable.getSelectionIndex();
    252 
    253                 boolean enabled = index != -1;
    254                 editButton.setEnabled(enabled);
    255                 deleteButton.setEnabled(enabled);
    256             }
    257         });
    258 
    259         mShell.pack();
    260 
    261     }
    262 
    263     /**
    264      * Add a new entry in the list.
    265      * @param deviceName the serial number of the device
    266      * @param appName java package for the application
    267      * @param portNumber port number
    268      */
    269     private void addEntry(String deviceName, String appName, int portNumber) {
    270         // create a new item for the table
    271         TableItem item = new TableItem(mPortTable, SWT.NONE);
    272 
    273         item.setText(COL_DEVICE, deviceName);
    274         item.setText(COL_APPLICATION, appName);
    275         item.setText(COL_PORT, Integer.toString(portNumber));
    276 
    277         // add the port to the list of port number used.
    278         mPorts.add(portNumber);
    279     }
    280 
    281     /**
    282      * Remove an entry from the list.
    283      * @param index The index of the entry to be removed
    284      */
    285     private void removeEntry(int index) {
    286         // remove from the ui
    287         mPortTable.remove(index);
    288 
    289         // and from the port list.
    290         mPorts.remove(index);
    291     }
    292 
    293     /**
    294      * Replace an entry in the list with new values.
    295      * @param index The index of the item to be replaced
    296      * @param deviceName the serial number of the device
    297      * @param appName The new java package for the application
    298      * @param portNumber The new port number.
    299      */
    300     private void replaceEntry(int index, String deviceName, String appName, int portNumber) {
    301         // get the table item by index
    302         TableItem item = mPortTable.getItem(index);
    303 
    304         // set its new value
    305         item.setText(COL_DEVICE, deviceName);
    306         item.setText(COL_APPLICATION, appName);
    307         item.setText(COL_PORT, Integer.toString(portNumber));
    308 
    309         // and replace the port number in the port list.
    310         mPorts.set(index, portNumber);
    311     }
    312 
    313 
    314     /**
    315      * Returns the device name for a specific index
    316      * @param index The index
    317      * @return the java package name of the application
    318      */
    319     private String getDeviceName(int index) {
    320         TableItem item = mPortTable.getItem(index);
    321         return item.getText(COL_DEVICE);
    322     }
    323 
    324     /**
    325      * Returns the application name for a specific index
    326      * @param index The index
    327      * @return the java package name of the application
    328      */
    329     private String getAppName(int index) {
    330         TableItem item = mPortTable.getItem(index);
    331         return item.getText(COL_APPLICATION);
    332     }
    333 
    334     /**
    335      * Returns the port number for a specific index
    336      * @param index The index
    337      * @return the port number
    338      */
    339     private String getPortNumber(int index) {
    340         TableItem item = mPortTable.getItem(index);
    341         return item.getText(COL_PORT);
    342     }
    343 
    344     /**
    345      * Updates the ui from the value in the preference store.
    346      */
    347     private void updateFromStore() {
    348         // get the map from the debug port manager
    349         DebugPortProvider provider = DebugPortProvider.getInstance();
    350         Map<String, Map<String, Integer>> map = provider.getPortList();
    351 
    352         // we're going to loop on the keys and fill the table.
    353         Set<String> deviceKeys = map.keySet();
    354 
    355         for (String deviceKey : deviceKeys) {
    356             Map<String, Integer> deviceMap = map.get(deviceKey);
    357             if (deviceMap != null) {
    358                 Set<String> appKeys = deviceMap.keySet();
    359 
    360                 for (String appKey : appKeys) {
    361                     Integer port = deviceMap.get(appKey);
    362                     if (port != null) {
    363                         addEntry(deviceKey, appKey, port);
    364                     }
    365                 }
    366             }
    367         }
    368     }
    369 
    370     /**
    371      * Update the store from the content of the ui.
    372      */
    373     private void updateStore() {
    374         // create a new Map object and fill it.
    375         HashMap<String, Map<String, Integer>> map = new HashMap<String, Map<String, Integer>>();
    376 
    377         int count = mPortTable.getItemCount();
    378 
    379         for (int i = 0 ; i < count ; i++) {
    380             TableItem item = mPortTable.getItem(i);
    381             String deviceName = item.getText(COL_DEVICE);
    382 
    383             Map<String, Integer> deviceMap = map.get(deviceName);
    384             if (deviceMap == null) {
    385                 deviceMap = new HashMap<String, Integer>();
    386                 map.put(deviceName, deviceMap);
    387             }
    388 
    389             deviceMap.put(item.getText(COL_APPLICATION), Integer.valueOf(item.getText(COL_PORT)));
    390         }
    391 
    392         // set it in the store through the debug port manager.
    393         DebugPortProvider provider = DebugPortProvider.getInstance();
    394         provider.setPortList(map);
    395     }
    396 }
    397