1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php 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 package com.android.ide.eclipse.adt.internal.editors.layout.properties; 17 18 import com.android.annotations.NonNull; 19 import com.android.ide.eclipse.adt.AdtPlugin; 20 import com.google.common.base.Splitter; 21 22 import org.eclipse.jface.dialogs.IDialogConstants; 23 import org.eclipse.jface.viewers.CheckStateChangedEvent; 24 import org.eclipse.jface.viewers.CheckboxTableViewer; 25 import org.eclipse.jface.viewers.ICheckStateListener; 26 import org.eclipse.jface.viewers.IStructuredContentProvider; 27 import org.eclipse.jface.viewers.Viewer; 28 import org.eclipse.swt.SWT; 29 import org.eclipse.swt.events.KeyEvent; 30 import org.eclipse.swt.events.KeyListener; 31 import org.eclipse.swt.events.SelectionEvent; 32 import org.eclipse.swt.events.SelectionListener; 33 import org.eclipse.swt.graphics.Point; 34 import org.eclipse.swt.layout.GridData; 35 import org.eclipse.swt.widgets.Composite; 36 import org.eclipse.swt.widgets.Control; 37 import org.eclipse.swt.widgets.Shell; 38 import org.eclipse.swt.widgets.Table; 39 import org.eclipse.swt.widgets.TableItem; 40 import org.eclipse.wb.internal.core.utils.execution.ExecutionUtils; 41 import org.eclipse.wb.internal.core.utils.execution.RunnableEx; 42 import org.eclipse.wb.internal.core.utils.ui.dialogs.ResizableDialog; 43 44 import java.util.ArrayList; 45 import java.util.List; 46 47 class FlagXmlPropertyDialog extends ResizableDialog 48 implements IStructuredContentProvider, ICheckStateListener, SelectionListener, KeyListener { 49 private final String mTitle; 50 private final XmlProperty mProperty; 51 private final String[] mFlags; 52 private final boolean mIsRadio; 53 54 private Table mTable; 55 private CheckboxTableViewer mViewer; 56 FlagXmlPropertyDialog( @onNull Shell parentShell, @NonNull String title, boolean isRadio, @NonNull String[] flags, @NonNull XmlProperty property)57 FlagXmlPropertyDialog( 58 @NonNull Shell parentShell, 59 @NonNull String title, 60 boolean isRadio, 61 @NonNull String[] flags, 62 @NonNull XmlProperty property) { 63 super(parentShell, AdtPlugin.getDefault()); 64 mTitle = title; 65 mIsRadio = isRadio; 66 mFlags = flags; 67 mProperty = property; 68 } 69 70 @Override configureShell(Shell newShell)71 protected void configureShell(Shell newShell) { 72 super.configureShell(newShell); 73 newShell.setText(mTitle); 74 } 75 76 @Override createDialogArea(Composite parent)77 protected Control createDialogArea(Composite parent) { 78 Composite container = (Composite) super.createDialogArea(parent); 79 80 mViewer = CheckboxTableViewer.newCheckList(container, 81 SWT.BORDER | SWT.FULL_SELECTION | SWT.HIDE_SELECTION); 82 mTable = mViewer.getTable(); 83 mTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); 84 85 Composite workaround = PropertyFactory.addWorkaround(container); 86 if (workaround != null) { 87 workaround.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1)); 88 } 89 90 mViewer.setContentProvider(this); 91 mViewer.setInput(mFlags); 92 93 String current = mProperty.getStringValue(); 94 if (current != null) { 95 Object[] checked = null; 96 if (mIsRadio) { 97 checked = new String[] { current }; 98 } else { 99 List<String> flags = new ArrayList<String>(); 100 for (String s : Splitter.on('|').omitEmptyStrings().trimResults().split(current)) { 101 flags.add(s); 102 } 103 checked = flags.toArray(new String[flags.size()]); 104 } 105 mViewer.setCheckedElements(checked); 106 } 107 if (mFlags.length > 0) { 108 mTable.setSelection(0); 109 } 110 111 if (mIsRadio) { 112 // Enforce single-item selection 113 mViewer.addCheckStateListener(this); 114 } 115 mTable.addSelectionListener(this); 116 mTable.addKeyListener(this); 117 118 return container; 119 } 120 121 @Override createButtonsForButtonBar(Composite parent)122 protected void createButtonsForButtonBar(Composite parent) { 123 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); 124 createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); 125 } 126 127 @Override getDefaultSize()128 protected Point getDefaultSize() { 129 return new Point(450, 400); 130 } 131 132 @Override okPressed()133 protected void okPressed() { 134 // Apply the value 135 ExecutionUtils.runLog(new RunnableEx() { 136 @Override 137 public void run() throws Exception { 138 StringBuilder sb = new StringBuilder(30); 139 for (Object o : mViewer.getCheckedElements()) { 140 if (sb.length() > 0) { 141 sb.append('|'); 142 } 143 sb.append((String) o); 144 } 145 String value = sb.length() > 0 ? sb.toString() : null; 146 mProperty.setValue(value); 147 } 148 }); 149 150 // close dialog 151 super.okPressed(); 152 } 153 154 // ---- Implements IStructuredContentProvider ---- 155 156 @Override getElements(Object inputElement)157 public Object[] getElements(Object inputElement) { 158 return (Object []) inputElement; 159 } 160 161 @Override dispose()162 public void dispose() { 163 } 164 165 @Override inputChanged(Viewer viewer, Object oldInput, Object newInput)166 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 167 } 168 169 // ---- Implements ICheckStateListener ---- 170 171 @Override checkStateChanged(CheckStateChangedEvent event)172 public void checkStateChanged(CheckStateChangedEvent event) { 173 // Try to disable other elements that conflict with this 174 boolean isChecked = event.getChecked(); 175 if (isChecked) { 176 Object selected = event.getElement(); 177 for (Object other : mViewer.getCheckedElements()) { 178 if (other != selected) { 179 mViewer.setChecked(other, false); 180 } 181 } 182 } else { 183 184 } 185 } 186 187 // ---- Implements SelectionListener ---- 188 189 @Override widgetSelected(SelectionEvent e)190 public void widgetSelected(SelectionEvent e) { 191 } 192 193 @Override widgetDefaultSelected(SelectionEvent e)194 public void widgetDefaultSelected(SelectionEvent e) { 195 if (e.item instanceof TableItem) { 196 TableItem item = (TableItem) e.item; 197 item.setChecked(!item.getChecked()); 198 } 199 } 200 201 // ---- Implements KeyListener ---- 202 203 @Override keyPressed(KeyEvent e)204 public void keyPressed(KeyEvent e) { 205 // Let space toggle checked state 206 if (e.keyCode == ' ' /* SWT.SPACE requires Eclipse 3.7 */) { 207 if (mTable.getSelectionCount() == 1) { 208 TableItem item = mTable.getSelection()[0]; 209 item.setChecked(!item.getChecked()); 210 } 211 } 212 } 213 214 @Override keyReleased(KeyEvent e)215 public void keyReleased(KeyEvent e) { 216 } 217 } 218