1 /* 2 * Copyright (C) 2008 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 17 package com.android.ide.eclipse.adt.internal.ui; 18 19 import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier; 20 import com.android.ide.eclipse.adt.internal.resources.configurations.DockModeQualifier; 21 import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration; 22 import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier; 23 import com.android.ide.eclipse.adt.internal.resources.configurations.LanguageQualifier; 24 import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier; 25 import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationStateQualifier; 26 import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier; 27 import com.android.ide.eclipse.adt.internal.resources.configurations.NightModeQualifier; 28 import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier; 29 import com.android.ide.eclipse.adt.internal.resources.configurations.RegionQualifier; 30 import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier; 31 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier; 32 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier; 33 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier; 34 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier; 35 import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier; 36 import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier; 37 import com.android.ide.eclipse.adt.internal.resources.configurations.VersionQualifier; 38 import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; 39 import com.android.sdklib.resources.Density; 40 import com.android.sdklib.resources.DockMode; 41 import com.android.sdklib.resources.Keyboard; 42 import com.android.sdklib.resources.KeyboardState; 43 import com.android.sdklib.resources.Navigation; 44 import com.android.sdklib.resources.NavigationState; 45 import com.android.sdklib.resources.NightMode; 46 import com.android.sdklib.resources.ResourceEnum; 47 import com.android.sdklib.resources.ScreenOrientation; 48 import com.android.sdklib.resources.ScreenRatio; 49 import com.android.sdklib.resources.ScreenSize; 50 import com.android.sdklib.resources.TouchScreen; 51 52 import org.eclipse.jface.viewers.ILabelProviderListener; 53 import org.eclipse.jface.viewers.ISelection; 54 import org.eclipse.jface.viewers.ISelectionChangedListener; 55 import org.eclipse.jface.viewers.IStructuredContentProvider; 56 import org.eclipse.jface.viewers.IStructuredSelection; 57 import org.eclipse.jface.viewers.ITableLabelProvider; 58 import org.eclipse.jface.viewers.SelectionChangedEvent; 59 import org.eclipse.jface.viewers.StructuredSelection; 60 import org.eclipse.jface.viewers.TableViewer; 61 import org.eclipse.jface.viewers.Viewer; 62 import org.eclipse.swt.SWT; 63 import org.eclipse.swt.custom.StackLayout; 64 import org.eclipse.swt.events.ControlAdapter; 65 import org.eclipse.swt.events.ControlEvent; 66 import org.eclipse.swt.events.FocusAdapter; 67 import org.eclipse.swt.events.FocusEvent; 68 import org.eclipse.swt.events.ModifyEvent; 69 import org.eclipse.swt.events.ModifyListener; 70 import org.eclipse.swt.events.SelectionAdapter; 71 import org.eclipse.swt.events.SelectionEvent; 72 import org.eclipse.swt.events.SelectionListener; 73 import org.eclipse.swt.events.VerifyEvent; 74 import org.eclipse.swt.events.VerifyListener; 75 import org.eclipse.swt.graphics.Image; 76 import org.eclipse.swt.graphics.Rectangle; 77 import org.eclipse.swt.layout.GridData; 78 import org.eclipse.swt.layout.GridLayout; 79 import org.eclipse.swt.widgets.Button; 80 import org.eclipse.swt.widgets.Combo; 81 import org.eclipse.swt.widgets.Composite; 82 import org.eclipse.swt.widgets.Label; 83 import org.eclipse.swt.widgets.Table; 84 import org.eclipse.swt.widgets.TableColumn; 85 import org.eclipse.swt.widgets.Text; 86 87 import java.util.ArrayList; 88 import java.util.HashMap; 89 90 /** 91 * Custom UI widget to let user build a Folder configuration. 92 * <p/> 93 * To use this, instantiate somewhere in the UI and then: 94 * <ul> 95 * <li>Use {@link #setConfiguration(String)} or {@link #setConfiguration(FolderConfiguration)}. 96 * <li>Retrieve the configuration using {@link #getConfiguration(FolderConfiguration)}. 97 * </ul> 98 */ 99 public class ConfigurationSelector extends Composite { 100 101 public static final int WIDTH_HINT = 600; 102 public static final int HEIGHT_HINT = 250; 103 104 private Runnable mOnChangeListener; 105 106 private TableViewer mFullTableViewer; 107 private TableViewer mSelectionTableViewer; 108 private Button mAddButton; 109 private Button mRemoveButton; 110 private StackLayout mStackLayout; 111 112 private boolean mOnRefresh = false; 113 114 private final FolderConfiguration mBaseConfiguration = new FolderConfiguration(); 115 private final FolderConfiguration mSelectedConfiguration = new FolderConfiguration(); 116 117 private final HashMap<Class<? extends ResourceQualifier>, QualifierEditBase> mUiMap = 118 new HashMap<Class<? extends ResourceQualifier>, QualifierEditBase>(); 119 private final boolean mDeviceMode; 120 private Composite mQualifierEditParent; 121 private IQualifierFilter mQualifierFilter; 122 123 /** 124 * Basic of {@link VerifyListener} to only accept digits. 125 */ 126 private static class DigitVerifier implements VerifyListener { verifyText(VerifyEvent e)127 public void verifyText(VerifyEvent e) { 128 // check for digit only. 129 for (int i = 0 ; i < e.text.length(); i++) { 130 char letter = e.text.charAt(i); 131 if (letter < '0' || letter > '9') { 132 e.doit = false; 133 return; 134 } 135 } 136 } 137 } 138 139 /** 140 * Implementation of {@link VerifyListener} for Country Code qualifiers. 141 */ 142 public static class MobileCodeVerifier extends DigitVerifier { 143 @Override verifyText(VerifyEvent e)144 public void verifyText(VerifyEvent e) { 145 super.verifyText(e); 146 147 // basic tests passed? 148 if (e.doit) { 149 // check the max 3 digits. 150 if (e.text.length() - e.end + e.start + 151 ((Text)e.getSource()).getText().length() > 3) { 152 e.doit = false; 153 } 154 } 155 } 156 } 157 158 /** 159 * Implementation of {@link VerifyListener} for the Language and Region qualifiers. 160 */ 161 public static class LanguageRegionVerifier implements VerifyListener { verifyText(VerifyEvent e)162 public void verifyText(VerifyEvent e) { 163 // check for length 164 if (e.text.length() - e.end + e.start + ((Combo)e.getSource()).getText().length() > 2) { 165 e.doit = false; 166 return; 167 } 168 169 // check for lower case only. 170 for (int i = 0 ; i < e.text.length(); i++) { 171 char letter = e.text.charAt(i); 172 if ((letter < 'a' || letter > 'z') && (letter < 'A' || letter > 'Z')) { 173 e.doit = false; 174 return; 175 } 176 } 177 } 178 } 179 180 /** 181 * Implementation of {@link VerifyListener} for the Pixel Density qualifier. 182 */ 183 public static class DensityVerifier extends DigitVerifier { } 184 185 /** 186 * Implementation of {@link VerifyListener} for the Screen Dimension qualifier. 187 */ 188 public static class DimensionVerifier extends DigitVerifier { } 189 190 /** 191 * Enum for the state of the configuration being created. 192 */ 193 public enum ConfigurationState { 194 OK, INVALID_CONFIG, REGION_WITHOUT_LANGUAGE; 195 } 196 197 /** 198 * A filter for {@link ResourceQualifier}. 199 * @see ConfigurationSelector#setQualifierFilter(IQualifierFilter) 200 */ 201 public interface IQualifierFilter { 202 /** 203 * Returns true of the qualifier is accepted. 204 */ accept(ResourceQualifier qualifier)205 boolean accept(ResourceQualifier qualifier); 206 } 207 208 /** 209 * Creates the selector. 210 * 211 * If the device mode is <code>true</code> then the configuration selector only 212 * allows to create configuration that are valid on a device (as opposed to resource 213 * configuration). 214 * For instance {@link Density#NODPI} is a valid qualifier for a resource configuration but 215 * this is not valid on a device. 216 * @param parent the composite parent. 217 * @param deviceMode the device mode. 218 */ ConfigurationSelector(Composite parent, boolean deviceMode)219 public ConfigurationSelector(Composite parent, boolean deviceMode) { 220 super(parent, SWT.NONE); 221 mDeviceMode = deviceMode; 222 223 mBaseConfiguration.createDefault(); 224 225 GridLayout gl = new GridLayout(4, false); 226 gl.marginWidth = gl.marginHeight = 0; 227 setLayout(gl); 228 229 // first column is the first table 230 final Table fullTable = new Table(this, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER); 231 fullTable.setLayoutData(new GridData(GridData.FILL_BOTH)); 232 fullTable.setHeaderVisible(true); 233 fullTable.setLinesVisible(true); 234 235 // create the column 236 final TableColumn fullTableColumn = new TableColumn(fullTable, SWT.LEFT); 237 // set the header 238 fullTableColumn.setText("Available Qualifiers"); 239 240 fullTable.addControlListener(new ControlAdapter() { 241 @Override 242 public void controlResized(ControlEvent e) { 243 Rectangle r = fullTable.getClientArea(); 244 fullTableColumn.setWidth(r.width); 245 } 246 }); 247 248 mFullTableViewer = new TableViewer(fullTable); 249 mFullTableViewer.setContentProvider(new QualifierContentProvider()); 250 mFullTableViewer.setLabelProvider(new QualifierLabelProvider( 251 false /* showQualifierValue */)); 252 mFullTableViewer.setInput(mBaseConfiguration); 253 mFullTableViewer.addSelectionChangedListener(new ISelectionChangedListener() { 254 public void selectionChanged(SelectionChangedEvent event) { 255 ISelection selection = event.getSelection(); 256 if (selection instanceof IStructuredSelection) { 257 IStructuredSelection structSelection = (IStructuredSelection)selection; 258 Object first = structSelection.getFirstElement(); 259 260 if (first instanceof ResourceQualifier) { 261 mAddButton.setEnabled(true); 262 return; 263 } 264 } 265 266 mAddButton.setEnabled(false); 267 } 268 }); 269 270 // 2nd column is the left/right arrow button 271 Composite buttonComposite = new Composite(this, SWT.NONE); 272 gl = new GridLayout(1, false); 273 gl.marginWidth = gl.marginHeight = 0; 274 buttonComposite.setLayout(gl); 275 buttonComposite.setLayoutData(new GridData(GridData.FILL_VERTICAL)); 276 277 new Composite(buttonComposite, SWT.NONE); 278 mAddButton = new Button(buttonComposite, SWT.BORDER | SWT.PUSH); 279 mAddButton.setText("->"); 280 mAddButton.setEnabled(false); 281 mAddButton.addSelectionListener(new SelectionAdapter() { 282 @Override 283 public void widgetSelected(SelectionEvent e) { 284 IStructuredSelection selection = 285 (IStructuredSelection)mFullTableViewer.getSelection(); 286 287 Object first = selection.getFirstElement(); 288 if (first instanceof ResourceQualifier) { 289 ResourceQualifier qualifier = (ResourceQualifier)first; 290 291 mBaseConfiguration.removeQualifier(qualifier); 292 mSelectedConfiguration.addQualifier(qualifier); 293 294 mFullTableViewer.refresh(); 295 mSelectionTableViewer.refresh(); 296 mSelectionTableViewer.setSelection(new StructuredSelection(qualifier), true); 297 298 onChange(false /* keepSelection */); 299 } 300 } 301 }); 302 303 mRemoveButton = new Button(buttonComposite, SWT.BORDER | SWT.PUSH); 304 mRemoveButton.setText("<-"); 305 mRemoveButton.setEnabled(false); 306 mRemoveButton.addSelectionListener(new SelectionAdapter() { 307 @Override 308 public void widgetSelected(SelectionEvent e) { 309 IStructuredSelection selection = 310 (IStructuredSelection)mSelectionTableViewer.getSelection(); 311 312 Object first = selection.getFirstElement(); 313 if (first instanceof ResourceQualifier) { 314 ResourceQualifier qualifier = (ResourceQualifier)first; 315 316 mSelectedConfiguration.removeQualifier(qualifier); 317 mBaseConfiguration.addQualifier(qualifier); 318 319 mFullTableViewer.refresh(); 320 mSelectionTableViewer.refresh(); 321 322 onChange(false /* keepSelection */); 323 } 324 } 325 }); 326 327 // 3rd column is the selected config table 328 final Table selectionTable = new Table(this, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER); 329 selectionTable.setLayoutData(new GridData(GridData.FILL_BOTH)); 330 selectionTable.setHeaderVisible(true); 331 selectionTable.setLinesVisible(true); 332 333 // create the column 334 final TableColumn selectionTableColumn = new TableColumn(selectionTable, SWT.LEFT); 335 // set the header 336 selectionTableColumn.setText("Chosen Qualifiers"); 337 338 selectionTable.addControlListener(new ControlAdapter() { 339 @Override 340 public void controlResized(ControlEvent e) { 341 Rectangle r = selectionTable.getClientArea(); 342 selectionTableColumn.setWidth(r.width); 343 } 344 }); 345 mSelectionTableViewer = new TableViewer(selectionTable); 346 mSelectionTableViewer.setContentProvider(new QualifierContentProvider()); 347 mSelectionTableViewer.setLabelProvider(new QualifierLabelProvider( 348 true /* showQualifierValue */)); 349 mSelectionTableViewer.setInput(mSelectedConfiguration); 350 mSelectionTableViewer.addSelectionChangedListener(new ISelectionChangedListener() { 351 public void selectionChanged(SelectionChangedEvent event) { 352 // ignore selection changes during resfreshes in some cases. 353 if (mOnRefresh) { 354 return; 355 } 356 357 ISelection selection = event.getSelection(); 358 if (selection instanceof IStructuredSelection) { 359 IStructuredSelection structSelection = (IStructuredSelection)selection; 360 361 if (structSelection.isEmpty() == false) { 362 Object first = structSelection.getFirstElement(); 363 364 if (first instanceof ResourceQualifier) { 365 mRemoveButton.setEnabled(true); 366 367 QualifierEditBase composite = mUiMap.get(first.getClass()); 368 369 if (composite != null) { 370 composite.setQualifier((ResourceQualifier)first); 371 } 372 373 mStackLayout.topControl = composite; 374 mQualifierEditParent.layout(); 375 376 return; 377 } 378 } else { 379 mStackLayout.topControl = null; 380 mQualifierEditParent.layout(); 381 } 382 } 383 384 mRemoveButton.setEnabled(false); 385 } 386 }); 387 388 // 4th column is the detail of the selected qualifier 389 mQualifierEditParent = new Composite(this, SWT.NONE); 390 mQualifierEditParent.setLayout(mStackLayout = new StackLayout()); 391 mQualifierEditParent.setLayoutData(new GridData(GridData.FILL_VERTICAL)); 392 393 // create the UI for all the qualifiers, and associate them to the ResourceQualifer class. 394 mUiMap.put(CountryCodeQualifier.class, new MCCEdit(mQualifierEditParent)); 395 mUiMap.put(NetworkCodeQualifier.class, new MNCEdit(mQualifierEditParent)); 396 mUiMap.put(LanguageQualifier.class, new LanguageEdit(mQualifierEditParent)); 397 mUiMap.put(RegionQualifier.class, new RegionEdit(mQualifierEditParent)); 398 mUiMap.put(ScreenSizeQualifier.class, new ScreenSizeEdit(mQualifierEditParent)); 399 mUiMap.put(ScreenRatioQualifier.class, new ScreenRatioEdit(mQualifierEditParent)); 400 mUiMap.put(ScreenOrientationQualifier.class, new OrientationEdit(mQualifierEditParent)); 401 mUiMap.put(DockModeQualifier.class, new DockModeEdit(mQualifierEditParent)); 402 mUiMap.put(NightModeQualifier.class, new NightModeEdit(mQualifierEditParent)); 403 mUiMap.put(PixelDensityQualifier.class, new PixelDensityEdit(mQualifierEditParent)); 404 mUiMap.put(TouchScreenQualifier.class, new TouchEdit(mQualifierEditParent)); 405 mUiMap.put(KeyboardStateQualifier.class, new KeyboardEdit(mQualifierEditParent)); 406 mUiMap.put(TextInputMethodQualifier.class, new TextInputEdit(mQualifierEditParent)); 407 mUiMap.put(NavigationStateQualifier.class, new NavigationStateEdit(mQualifierEditParent)); 408 mUiMap.put(NavigationMethodQualifier.class, new NavigationEdit(mQualifierEditParent)); 409 mUiMap.put(ScreenDimensionQualifier.class, new ScreenDimensionEdit(mQualifierEditParent)); 410 mUiMap.put(VersionQualifier.class, new VersionEdit(mQualifierEditParent)); 411 } 412 413 /** 414 * Sets a {@link IQualifierFilter}. If non null, this will restrict the qualifiers that 415 * can be chosen. 416 * @param filter the filter to set. 417 */ setQualifierFilter(IQualifierFilter filter)418 public void setQualifierFilter(IQualifierFilter filter) { 419 mQualifierFilter = filter; 420 } 421 422 /** 423 * Sets a listener to be notified when the configuration changes. 424 * @param listener A {@link Runnable} whose <code>run()</code> method is called when the 425 * configuration is changed. The method is called from the UI thread. 426 */ setOnChangeListener(Runnable listener)427 public void setOnChangeListener(Runnable listener) { 428 mOnChangeListener = listener; 429 } 430 431 /** 432 * Initialize the UI with a given {@link FolderConfiguration}. This must 433 * be called from the UI thread. 434 * @param config The configuration. 435 */ setConfiguration(FolderConfiguration config)436 public void setConfiguration(FolderConfiguration config) { 437 mSelectedConfiguration.set(config, true /*nonFakeValuesOnly*/); 438 mSelectionTableViewer.refresh(); 439 440 // create the base config, which is the default config minus the qualifiers 441 // in SelectedConfiguration 442 mBaseConfiguration.substract(mSelectedConfiguration); 443 mFullTableViewer.refresh(); 444 } 445 446 /** 447 * Initialize the UI with the configuration represented by a resource folder name. 448 * This must be called from the UI thread. 449 * 450 * @param folderSegments the segments of the folder name, 451 * split using {@link FolderConfiguration#QUALIFIER_SEP}. 452 * @return true if success, or false if the folder name is not a valid name. 453 */ setConfiguration(String[] folderSegments)454 public boolean setConfiguration(String[] folderSegments) { 455 FolderConfiguration config = ResourceManager.getInstance().getConfig(folderSegments); 456 457 if (config == null) { 458 return false; 459 } 460 461 setConfiguration(config); 462 463 return true; 464 } 465 466 /** 467 * Initialize the UI with the configuration represented by a resource folder name. 468 * This must be called from the UI thread. 469 * @param folderName the name of the folder. 470 * @return true if success, or false if the folder name is not a valid name. 471 */ setConfiguration(String folderName)472 public boolean setConfiguration(String folderName) { 473 // split the name of the folder in segments. 474 String[] folderSegments = folderName.split(FolderConfiguration.QUALIFIER_SEP); 475 476 return setConfiguration(folderSegments); 477 } 478 479 /** 480 * Gets the configuration as setup by the widget. 481 * @param config the {@link FolderConfiguration} object to be filled with the information 482 * from the UI. 483 */ getConfiguration(FolderConfiguration config)484 public void getConfiguration(FolderConfiguration config) { 485 config.set(mSelectedConfiguration); 486 } 487 488 /** 489 * Returns the state of the configuration being edited/created. 490 */ getState()491 public ConfigurationState getState() { 492 if (mSelectedConfiguration.getInvalidQualifier() != null) { 493 return ConfigurationState.INVALID_CONFIG; 494 } 495 496 if (mSelectedConfiguration.checkRegion() == false) { 497 return ConfigurationState.REGION_WITHOUT_LANGUAGE; 498 } 499 500 return ConfigurationState.OK; 501 } 502 503 /** 504 * Returns the first invalid qualifier of the configuration being edited/created, 505 * or <code>null<code> if they are all valid (or if none exists). 506 * <p/>If {@link #getState()} return {@link ConfigurationState#INVALID_CONFIG} then this will 507 * not return <code>null</code>. 508 */ getInvalidQualifier()509 public ResourceQualifier getInvalidQualifier() { 510 return mSelectedConfiguration.getInvalidQualifier(); 511 } 512 513 /** 514 * Handle changes in the configuration. 515 * @param keepSelection if <code>true</code> attemps to avoid triggering selection change in 516 * {@link #mSelectedConfiguration}. 517 */ onChange(boolean keepSelection)518 private void onChange(boolean keepSelection) { 519 ISelection selection = null; 520 if (keepSelection) { 521 mOnRefresh = true; 522 selection = mSelectionTableViewer.getSelection(); 523 } 524 525 mSelectionTableViewer.refresh(true); 526 527 if (keepSelection) { 528 mSelectionTableViewer.setSelection(selection); 529 mOnRefresh = false; 530 } 531 532 if (mOnChangeListener != null) { 533 mOnChangeListener.run(); 534 } 535 } 536 fillCombo(Combo combo, ResourceEnum[] resEnums)537 private void fillCombo(Combo combo, ResourceEnum[] resEnums) { 538 for (ResourceEnum resEnum : resEnums) { 539 // only add the enum if: 540 // device mode is false OR (device mode is true and) it's a valid device value. 541 // Also, always ignore fake values. 542 if ((mDeviceMode == false || resEnum.isValidValueForDevice()) && 543 resEnum.isFakeValue() == false) { 544 combo.add(resEnum.getShortDisplayValue()); 545 } 546 } 547 } 548 549 /** 550 * Content provider around a {@link FolderConfiguration}. 551 */ 552 private class QualifierContentProvider implements IStructuredContentProvider { 553 554 private FolderConfiguration mInput; 555 QualifierContentProvider()556 public QualifierContentProvider() { 557 } 558 dispose()559 public void dispose() { 560 // pass 561 } 562 getElements(Object inputElement)563 public Object[] getElements(Object inputElement) { 564 // default easy case 565 if (mQualifierFilter == null) { 566 return mInput.getQualifiers(); 567 } 568 569 // in this case we have to compute the list 570 ArrayList<ResourceQualifier> list = new ArrayList<ResourceQualifier>(); 571 for (ResourceQualifier qual : mInput.getQualifiers()) { 572 if (mQualifierFilter.accept(qual)) { 573 list.add(qual); 574 } 575 } 576 577 return list.toArray(); 578 } 579 inputChanged(Viewer viewer, Object oldInput, Object newInput)580 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 581 mInput = null; 582 if (newInput instanceof FolderConfiguration) { 583 mInput = (FolderConfiguration)newInput; 584 } 585 } 586 } 587 588 /** 589 * Label provider for {@link ResourceQualifier} objects. 590 */ 591 private static class QualifierLabelProvider implements ITableLabelProvider { 592 593 private final boolean mShowQualifierValue; 594 QualifierLabelProvider(boolean showQualifierValue)595 public QualifierLabelProvider(boolean showQualifierValue) { 596 mShowQualifierValue = showQualifierValue; 597 } 598 getColumnText(Object element, int columnIndex)599 public String getColumnText(Object element, int columnIndex) { 600 // only one column, so we can ignore columnIndex 601 if (element instanceof ResourceQualifier) { 602 if (mShowQualifierValue) { 603 String value = ((ResourceQualifier)element).getShortDisplayValue(); 604 if (value.length() == 0) { 605 return String.format("%1$s (?)", 606 ((ResourceQualifier)element).getShortName()); 607 } else { 608 return value; 609 } 610 611 } else { 612 return ((ResourceQualifier)element).getShortName(); 613 } 614 } 615 616 return null; 617 } 618 getColumnImage(Object element, int columnIndex)619 public Image getColumnImage(Object element, int columnIndex) { 620 // only one column, so we can ignore columnIndex 621 if (element instanceof ResourceQualifier) { 622 return ((ResourceQualifier)element).getIcon(); 623 } 624 625 return null; 626 } 627 addListener(ILabelProviderListener listener)628 public void addListener(ILabelProviderListener listener) { 629 // pass 630 } 631 dispose()632 public void dispose() { 633 // pass 634 } 635 isLabelProperty(Object element, String property)636 public boolean isLabelProperty(Object element, String property) { 637 // pass 638 return false; 639 } 640 removeListener(ILabelProviderListener listener)641 public void removeListener(ILabelProviderListener listener) { 642 // pass 643 } 644 } 645 646 /** 647 * Base class for Edit widget for {@link ResourceQualifier}. 648 */ 649 private abstract static class QualifierEditBase extends Composite { 650 QualifierEditBase(Composite parent, String title)651 public QualifierEditBase(Composite parent, String title) { 652 super(parent, SWT.NONE); 653 setLayout(new GridLayout(1, false)); 654 655 new Label(this, SWT.NONE).setText(title); 656 } 657 setQualifier(ResourceQualifier qualifier)658 public abstract void setQualifier(ResourceQualifier qualifier); 659 } 660 661 /** 662 * Edit widget for {@link CountryCodeQualifier}. 663 */ 664 private class MCCEdit extends QualifierEditBase { 665 666 private Text mText; 667 MCCEdit(Composite parent)668 public MCCEdit(Composite parent) { 669 super(parent, CountryCodeQualifier.NAME); 670 671 mText = new Text(this, SWT.BORDER); 672 mText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 673 mText.addVerifyListener(new MobileCodeVerifier()); 674 mText.addModifyListener(new ModifyListener() { 675 public void modifyText(ModifyEvent e) { 676 onTextChange(); 677 } 678 }); 679 680 mText.addFocusListener(new FocusAdapter() { 681 @Override 682 public void focusLost(FocusEvent e) { 683 onTextChange(); 684 } 685 }); 686 687 new Label(this, SWT.NONE).setText("(3 digit code)"); 688 } 689 onTextChange()690 private void onTextChange() { 691 String value = mText.getText(); 692 693 if (value.length() == 0) { 694 // empty string, means a qualifier with no value. 695 // Since the qualifier classes are immutable, and we don't want to 696 // remove the qualifier from the configuration, we create a new default one. 697 mSelectedConfiguration.setCountryCodeQualifier(new CountryCodeQualifier()); 698 } else { 699 try { 700 CountryCodeQualifier qualifier = CountryCodeQualifier.getQualifier( 701 CountryCodeQualifier.getFolderSegment(Integer.parseInt(value))); 702 if (qualifier != null) { 703 mSelectedConfiguration.setCountryCodeQualifier(qualifier); 704 } else { 705 // Failure! Looks like the value is wrong 706 // (for instance not exactly 3 digits). 707 mSelectedConfiguration.setCountryCodeQualifier(new CountryCodeQualifier()); 708 } 709 } catch (NumberFormatException nfe) { 710 // Looks like the code is not a number. This should not happen since the text 711 // field has a VerifyListener that prevents it. 712 mSelectedConfiguration.setCountryCodeQualifier(new CountryCodeQualifier()); 713 } 714 } 715 716 // notify of change 717 onChange(true /* keepSelection */); 718 } 719 720 @Override setQualifier(ResourceQualifier qualifier)721 public void setQualifier(ResourceQualifier qualifier) { 722 CountryCodeQualifier q = (CountryCodeQualifier)qualifier; 723 724 mText.setText(Integer.toString(q.getCode())); 725 } 726 } 727 728 /** 729 * Edit widget for {@link NetworkCodeQualifier}. 730 */ 731 private class MNCEdit extends QualifierEditBase { 732 private Text mText; 733 MNCEdit(Composite parent)734 public MNCEdit(Composite parent) { 735 super(parent, NetworkCodeQualifier.NAME); 736 737 mText = new Text(this, SWT.BORDER); 738 mText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 739 mText.addVerifyListener(new MobileCodeVerifier()); 740 mText.addModifyListener(new ModifyListener() { 741 public void modifyText(ModifyEvent e) { 742 onTextChange(); 743 } 744 }); 745 mText.addFocusListener(new FocusAdapter() { 746 @Override 747 public void focusLost(FocusEvent e) { 748 onTextChange(); 749 } 750 }); 751 752 new Label(this, SWT.NONE).setText("(1-3 digit code)"); 753 } 754 onTextChange()755 private void onTextChange() { 756 String value = mText.getText(); 757 758 if (value.length() == 0) { 759 // empty string, means a qualifier with no value. 760 // Since the qualifier classes are immutable, and we don't want to 761 // remove the qualifier from the configuration, we create a new default one. 762 mSelectedConfiguration.setNetworkCodeQualifier(new NetworkCodeQualifier()); 763 } else { 764 try { 765 NetworkCodeQualifier qualifier = NetworkCodeQualifier.getQualifier( 766 NetworkCodeQualifier.getFolderSegment(Integer.parseInt(value))); 767 if (qualifier != null) { 768 mSelectedConfiguration.setNetworkCodeQualifier(qualifier); 769 } else { 770 // Failure! Looks like the value is wrong 771 // (for instance not exactly 3 digits). 772 mSelectedConfiguration.setNetworkCodeQualifier(new NetworkCodeQualifier()); 773 } 774 } catch (NumberFormatException nfe) { 775 // Looks like the code is not a number. This should not happen since the text 776 // field has a VerifyListener that prevents it. 777 mSelectedConfiguration.setNetworkCodeQualifier(new NetworkCodeQualifier()); 778 } 779 } 780 781 // notify of change 782 onChange(true /* keepSelection */); 783 } 784 785 @Override setQualifier(ResourceQualifier qualifier)786 public void setQualifier(ResourceQualifier qualifier) { 787 NetworkCodeQualifier q = (NetworkCodeQualifier)qualifier; 788 789 mText.setText(Integer.toString(q.getCode())); 790 } 791 } 792 793 /** 794 * Edit widget for {@link LanguageQualifier}. 795 */ 796 private class LanguageEdit extends QualifierEditBase { 797 private Combo mLanguage; 798 LanguageEdit(Composite parent)799 public LanguageEdit(Composite parent) { 800 super(parent, LanguageQualifier.NAME); 801 802 mLanguage = new Combo(this, SWT.DROP_DOWN); 803 mLanguage.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 804 mLanguage.addVerifyListener(new LanguageRegionVerifier()); 805 mLanguage.addSelectionListener(new SelectionListener() { 806 public void widgetDefaultSelected(SelectionEvent e) { 807 onLanguageChange(); 808 } 809 public void widgetSelected(SelectionEvent e) { 810 onLanguageChange(); 811 } 812 }); 813 mLanguage.addModifyListener(new ModifyListener() { 814 public void modifyText(ModifyEvent e) { 815 onLanguageChange(); 816 } 817 }); 818 819 new Label(this, SWT.NONE).setText("(2 letter code)"); 820 } 821 onLanguageChange()822 private void onLanguageChange() { 823 // update the current config 824 String value = mLanguage.getText(); 825 826 if (value.length() == 0) { 827 // empty string, means no qualifier. 828 // Since the qualifier classes are immutable, and we don't want to 829 // remove the qualifier from the configuration, we create a new default one. 830 mSelectedConfiguration.setLanguageQualifier(new LanguageQualifier()); 831 } else { 832 LanguageQualifier qualifier = null; 833 String segment = LanguageQualifier.getFolderSegment(value); 834 if (segment != null) { 835 qualifier = LanguageQualifier.getQualifier(segment); 836 } 837 838 if (qualifier != null) { 839 mSelectedConfiguration.setLanguageQualifier(qualifier); 840 } else { 841 // Failure! Looks like the value is wrong (for instance a one letter string). 842 mSelectedConfiguration.setLanguageQualifier(new LanguageQualifier()); 843 } 844 } 845 846 // notify of change 847 onChange(true /* keepSelection */); 848 } 849 850 @Override setQualifier(ResourceQualifier qualifier)851 public void setQualifier(ResourceQualifier qualifier) { 852 LanguageQualifier q = (LanguageQualifier)qualifier; 853 854 String value = q.getValue(); 855 if (value != null) { 856 mLanguage.setText(value); 857 } 858 } 859 } 860 861 /** 862 * Edit widget for {@link RegionQualifier}. 863 */ 864 private class RegionEdit extends QualifierEditBase { 865 private Combo mRegion; 866 RegionEdit(Composite parent)867 public RegionEdit(Composite parent) { 868 super(parent, RegionQualifier.NAME); 869 870 mRegion = new Combo(this, SWT.DROP_DOWN); 871 mRegion.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 872 mRegion.addVerifyListener(new LanguageRegionVerifier()); 873 mRegion.addSelectionListener(new SelectionListener() { 874 public void widgetDefaultSelected(SelectionEvent e) { 875 onRegionChange(); 876 } 877 public void widgetSelected(SelectionEvent e) { 878 onRegionChange(); 879 } 880 }); 881 mRegion.addModifyListener(new ModifyListener() { 882 public void modifyText(ModifyEvent e) { 883 onRegionChange(); 884 } 885 }); 886 887 new Label(this, SWT.NONE).setText("(2 letter code)"); 888 } 889 onRegionChange()890 private void onRegionChange() { 891 // update the current config 892 String value = mRegion.getText(); 893 894 if (value.length() == 0) { 895 // empty string, means no qualifier. 896 // Since the qualifier classes are immutable, and we don't want to 897 // remove the qualifier from the configuration, we create a new default one. 898 mSelectedConfiguration.setRegionQualifier(new RegionQualifier()); 899 } else { 900 RegionQualifier qualifier = null; 901 String segment = RegionQualifier.getFolderSegment(value); 902 if (segment != null) { 903 qualifier = RegionQualifier.getQualifier(segment); 904 } 905 906 if (qualifier != null) { 907 mSelectedConfiguration.setRegionQualifier(qualifier); 908 } else { 909 // Failure! Looks like the value is wrong (for instance a one letter string). 910 mSelectedConfiguration.setRegionQualifier(new RegionQualifier()); 911 } 912 } 913 914 // notify of change 915 onChange(true /* keepSelection */); 916 } 917 918 @Override setQualifier(ResourceQualifier qualifier)919 public void setQualifier(ResourceQualifier qualifier) { 920 RegionQualifier q = (RegionQualifier)qualifier; 921 922 String value = q.getValue(); 923 if (value != null) { 924 mRegion.setText(q.getValue()); 925 } 926 } 927 } 928 929 /** 930 * Edit widget for {@link ScreenSizeQualifier}. 931 */ 932 private class ScreenSizeEdit extends QualifierEditBase { 933 934 private Combo mSize; 935 ScreenSizeEdit(Composite parent)936 public ScreenSizeEdit(Composite parent) { 937 super(parent, ScreenSizeQualifier.NAME); 938 939 mSize = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); 940 fillCombo(mSize, ScreenSize.values()); 941 942 mSize.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 943 mSize.addSelectionListener(new SelectionListener() { 944 public void widgetDefaultSelected(SelectionEvent e) { 945 onScreenSizeChange(); 946 } 947 public void widgetSelected(SelectionEvent e) { 948 onScreenSizeChange(); 949 } 950 }); 951 } 952 onScreenSizeChange()953 protected void onScreenSizeChange() { 954 // update the current config 955 int index = mSize.getSelectionIndex(); 956 957 if (index != -1) { 958 mSelectedConfiguration.setScreenSizeQualifier(new ScreenSizeQualifier( 959 ScreenSize.getByIndex(index))); 960 } else { 961 // empty selection, means no qualifier. 962 // Since the qualifier classes are immutable, and we don't want to 963 // remove the qualifier from the configuration, we create a new default one. 964 mSelectedConfiguration.setScreenSizeQualifier( 965 new ScreenSizeQualifier()); 966 } 967 968 // notify of change 969 onChange(true /* keepSelection */); 970 } 971 972 @Override setQualifier(ResourceQualifier qualifier)973 public void setQualifier(ResourceQualifier qualifier) { 974 ScreenSizeQualifier q = (ScreenSizeQualifier)qualifier; 975 976 ScreenSize value = q.getValue(); 977 if (value == null) { 978 mSize.clearSelection(); 979 } else { 980 mSize.select(ScreenSize.getIndex(value)); 981 } 982 } 983 } 984 985 /** 986 * Edit widget for {@link ScreenRatioQualifier}. 987 */ 988 private class ScreenRatioEdit extends QualifierEditBase { 989 990 private Combo mRatio; 991 ScreenRatioEdit(Composite parent)992 public ScreenRatioEdit(Composite parent) { 993 super(parent, ScreenRatioQualifier.NAME); 994 995 mRatio = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); 996 fillCombo(mRatio, ScreenRatio.values()); 997 998 mRatio.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 999 mRatio.addSelectionListener(new SelectionListener() { 1000 public void widgetDefaultSelected(SelectionEvent e) { 1001 onScreenRatioChange(); 1002 } 1003 public void widgetSelected(SelectionEvent e) { 1004 onScreenRatioChange(); 1005 } 1006 }); 1007 } 1008 onScreenRatioChange()1009 protected void onScreenRatioChange() { 1010 // update the current config 1011 int index = mRatio.getSelectionIndex(); 1012 1013 if (index != -1) { 1014 mSelectedConfiguration.setScreenRatioQualifier(new ScreenRatioQualifier( 1015 ScreenRatio.getByIndex(index))); 1016 } else { 1017 // empty selection, means no qualifier. 1018 // Since the qualifier classes are immutable, and we don't want to 1019 // remove the qualifier from the configuration, we create a new default one. 1020 mSelectedConfiguration.setScreenRatioQualifier( 1021 new ScreenRatioQualifier()); 1022 } 1023 1024 // notify of change 1025 onChange(true /* keepSelection */); 1026 } 1027 1028 @Override setQualifier(ResourceQualifier qualifier)1029 public void setQualifier(ResourceQualifier qualifier) { 1030 ScreenRatioQualifier q = (ScreenRatioQualifier)qualifier; 1031 1032 ScreenRatio value = q.getValue(); 1033 if (value == null) { 1034 mRatio.clearSelection(); 1035 } else { 1036 mRatio.select(ScreenRatio.getIndex(value)); 1037 } 1038 } 1039 } 1040 1041 /** 1042 * Edit widget for {@link ScreenOrientationQualifier}. 1043 */ 1044 private class OrientationEdit extends QualifierEditBase { 1045 1046 private Combo mOrientation; 1047 OrientationEdit(Composite parent)1048 public OrientationEdit(Composite parent) { 1049 super(parent, ScreenOrientationQualifier.NAME); 1050 1051 mOrientation = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); 1052 fillCombo(mOrientation, ScreenOrientation.values()); 1053 1054 mOrientation.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1055 mOrientation.addSelectionListener(new SelectionListener() { 1056 public void widgetDefaultSelected(SelectionEvent e) { 1057 onOrientationChange(); 1058 } 1059 public void widgetSelected(SelectionEvent e) { 1060 onOrientationChange(); 1061 } 1062 }); 1063 } 1064 onOrientationChange()1065 protected void onOrientationChange() { 1066 // update the current config 1067 int index = mOrientation.getSelectionIndex(); 1068 1069 if (index != -1) { 1070 mSelectedConfiguration.setScreenOrientationQualifier(new ScreenOrientationQualifier( 1071 ScreenOrientation.getByIndex(index))); 1072 } else { 1073 // empty selection, means no qualifier. 1074 // Since the qualifier classes are immutable, and we don't want to 1075 // remove the qualifier from the configuration, we create a new default one. 1076 mSelectedConfiguration.setScreenOrientationQualifier( 1077 new ScreenOrientationQualifier()); 1078 } 1079 1080 // notify of change 1081 onChange(true /* keepSelection */); 1082 } 1083 1084 @Override setQualifier(ResourceQualifier qualifier)1085 public void setQualifier(ResourceQualifier qualifier) { 1086 ScreenOrientationQualifier q = (ScreenOrientationQualifier)qualifier; 1087 1088 ScreenOrientation value = q.getValue(); 1089 if (value == null) { 1090 mOrientation.clearSelection(); 1091 } else { 1092 mOrientation.select(ScreenOrientation.getIndex(value)); 1093 } 1094 } 1095 } 1096 1097 /** 1098 * Edit widget for {@link DockModeQualifier}. 1099 */ 1100 private class DockModeEdit extends QualifierEditBase { 1101 1102 private Combo mDockMode; 1103 DockModeEdit(Composite parent)1104 public DockModeEdit(Composite parent) { 1105 super(parent, DockModeQualifier.NAME); 1106 1107 mDockMode = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); 1108 fillCombo(mDockMode, DockMode.values()); 1109 1110 mDockMode.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1111 mDockMode.addSelectionListener(new SelectionListener() { 1112 public void widgetDefaultSelected(SelectionEvent e) { 1113 onDockModeChange(); 1114 } 1115 public void widgetSelected(SelectionEvent e) { 1116 onDockModeChange(); 1117 } 1118 }); 1119 } 1120 onDockModeChange()1121 protected void onDockModeChange() { 1122 // update the current config 1123 int index = mDockMode.getSelectionIndex(); 1124 1125 if (index != -1) { 1126 mSelectedConfiguration.setDockModeQualifier( 1127 new DockModeQualifier(DockMode.getByIndex(index))); 1128 } else { 1129 // empty selection, means no qualifier. 1130 // Since the qualifier classes are immutable, and we don't want to 1131 // remove the qualifier from the configuration, we create a new default one. 1132 mSelectedConfiguration.setDockModeQualifier(new DockModeQualifier()); 1133 } 1134 1135 // notify of change 1136 onChange(true /* keepSelection */); 1137 } 1138 1139 @Override setQualifier(ResourceQualifier qualifier)1140 public void setQualifier(ResourceQualifier qualifier) { 1141 DockModeQualifier q = (DockModeQualifier)qualifier; 1142 1143 DockMode value = q.getValue(); 1144 if (value == null) { 1145 mDockMode.clearSelection(); 1146 } else { 1147 mDockMode.select(DockMode.getIndex(value)); 1148 } 1149 } 1150 } 1151 1152 /** 1153 * Edit widget for {@link NightModeQualifier}. 1154 */ 1155 private class NightModeEdit extends QualifierEditBase { 1156 1157 private Combo mNightMode; 1158 NightModeEdit(Composite parent)1159 public NightModeEdit(Composite parent) { 1160 super(parent, NightModeQualifier.NAME); 1161 1162 mNightMode = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); 1163 fillCombo(mNightMode, NightMode.values()); 1164 1165 mNightMode.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1166 mNightMode.addSelectionListener(new SelectionListener() { 1167 public void widgetDefaultSelected(SelectionEvent e) { 1168 onNightModeChange(); 1169 } 1170 public void widgetSelected(SelectionEvent e) { 1171 onNightModeChange(); 1172 } 1173 }); 1174 } 1175 onNightModeChange()1176 protected void onNightModeChange() { 1177 // update the current config 1178 int index = mNightMode.getSelectionIndex(); 1179 1180 if (index != -1) { 1181 mSelectedConfiguration.setNightModeQualifier( 1182 new NightModeQualifier(NightMode.getByIndex(index))); 1183 } else { 1184 // empty selection, means no qualifier. 1185 // Since the qualifier classes are immutable, and we don't want to 1186 // remove the qualifier from the configuration, we create a new default one. 1187 mSelectedConfiguration.setNightModeQualifier(new NightModeQualifier()); 1188 } 1189 1190 // notify of change 1191 onChange(true /* keepSelection */); 1192 } 1193 1194 @Override setQualifier(ResourceQualifier qualifier)1195 public void setQualifier(ResourceQualifier qualifier) { 1196 NightModeQualifier q = (NightModeQualifier)qualifier; 1197 1198 NightMode value = q.getValue(); 1199 if (value == null) { 1200 mNightMode.clearSelection(); 1201 } else { 1202 mNightMode.select(NightMode.getIndex(value)); 1203 } 1204 } 1205 } 1206 1207 1208 /** 1209 * Edit widget for {@link PixelDensityQualifier}. 1210 */ 1211 private class PixelDensityEdit extends QualifierEditBase { 1212 private Combo mDensity; 1213 PixelDensityEdit(Composite parent)1214 public PixelDensityEdit(Composite parent) { 1215 super(parent, PixelDensityQualifier.NAME); 1216 1217 mDensity = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); 1218 fillCombo(mDensity, Density.values()); 1219 1220 mDensity.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1221 mDensity.addSelectionListener(new SelectionListener() { 1222 public void widgetDefaultSelected(SelectionEvent e) { 1223 onDensityChange(); 1224 } 1225 public void widgetSelected(SelectionEvent e) { 1226 onDensityChange(); 1227 } 1228 }); 1229 } 1230 onDensityChange()1231 private void onDensityChange() { 1232 // update the current config 1233 int index = mDensity.getSelectionIndex(); 1234 1235 if (index != -1) { 1236 mSelectedConfiguration.setPixelDensityQualifier(new PixelDensityQualifier( 1237 Density.getByIndex(index))); 1238 } else { 1239 // empty selection, means no qualifier. 1240 // Since the qualifier classes are immutable, and we don't want to 1241 // remove the qualifier from the configuration, we create a new default one. 1242 mSelectedConfiguration.setPixelDensityQualifier( 1243 new PixelDensityQualifier()); 1244 } 1245 1246 // notify of change 1247 onChange(true /* keepSelection */); 1248 } 1249 1250 @Override setQualifier(ResourceQualifier qualifier)1251 public void setQualifier(ResourceQualifier qualifier) { 1252 PixelDensityQualifier q = (PixelDensityQualifier)qualifier; 1253 1254 Density value = q.getValue(); 1255 if (value == null) { 1256 mDensity.clearSelection(); 1257 } else { 1258 mDensity.select(Density.getIndex(value)); 1259 } 1260 } 1261 } 1262 1263 /** 1264 * Edit widget for {@link TouchScreenQualifier}. 1265 */ 1266 private class TouchEdit extends QualifierEditBase { 1267 1268 private Combo mTouchScreen; 1269 TouchEdit(Composite parent)1270 public TouchEdit(Composite parent) { 1271 super(parent, TouchScreenQualifier.NAME); 1272 1273 mTouchScreen = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); 1274 fillCombo(mTouchScreen, TouchScreen.values()); 1275 1276 mTouchScreen.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1277 mTouchScreen.addSelectionListener(new SelectionListener() { 1278 public void widgetDefaultSelected(SelectionEvent e) { 1279 onTouchChange(); 1280 } 1281 public void widgetSelected(SelectionEvent e) { 1282 onTouchChange(); 1283 } 1284 }); 1285 } 1286 onTouchChange()1287 protected void onTouchChange() { 1288 // update the current config 1289 int index = mTouchScreen.getSelectionIndex(); 1290 1291 if (index != -1) { 1292 mSelectedConfiguration.setTouchTypeQualifier(new TouchScreenQualifier( 1293 TouchScreen.getByIndex(index))); 1294 } else { 1295 // empty selection, means no qualifier. 1296 // Since the qualifier classes are immutable, and we don't want to 1297 // remove the qualifier from the configuration, we create a new default one. 1298 mSelectedConfiguration.setTouchTypeQualifier(new TouchScreenQualifier()); 1299 } 1300 1301 // notify of change 1302 onChange(true /* keepSelection */); 1303 } 1304 1305 @Override setQualifier(ResourceQualifier qualifier)1306 public void setQualifier(ResourceQualifier qualifier) { 1307 TouchScreenQualifier q = (TouchScreenQualifier)qualifier; 1308 1309 TouchScreen value = q.getValue(); 1310 if (value == null) { 1311 mTouchScreen.clearSelection(); 1312 } else { 1313 mTouchScreen.select(TouchScreen.getIndex(value)); 1314 } 1315 } 1316 } 1317 1318 /** 1319 * Edit widget for {@link KeyboardStateQualifier}. 1320 */ 1321 private class KeyboardEdit extends QualifierEditBase { 1322 1323 private Combo mKeyboardState; 1324 KeyboardEdit(Composite parent)1325 public KeyboardEdit(Composite parent) { 1326 super(parent, KeyboardStateQualifier.NAME); 1327 1328 mKeyboardState = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); 1329 fillCombo(mKeyboardState, KeyboardState.values()); 1330 1331 mKeyboardState.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1332 mKeyboardState.addSelectionListener(new SelectionListener() { 1333 public void widgetDefaultSelected(SelectionEvent e) { 1334 onKeyboardChange(); 1335 } 1336 public void widgetSelected(SelectionEvent e) { 1337 onKeyboardChange(); 1338 } 1339 }); 1340 } 1341 onKeyboardChange()1342 protected void onKeyboardChange() { 1343 // update the current config 1344 int index = mKeyboardState.getSelectionIndex(); 1345 1346 if (index != -1) { 1347 mSelectedConfiguration.setKeyboardStateQualifier(new KeyboardStateQualifier( 1348 KeyboardState.getByIndex(index))); 1349 } else { 1350 // empty selection, means no qualifier. 1351 // Since the qualifier classes are immutable, and we don't want to 1352 // remove the qualifier from the configuration, we create a new default one. 1353 mSelectedConfiguration.setKeyboardStateQualifier( 1354 new KeyboardStateQualifier()); 1355 } 1356 1357 // notify of change 1358 onChange(true /* keepSelection */); 1359 } 1360 1361 @Override setQualifier(ResourceQualifier qualifier)1362 public void setQualifier(ResourceQualifier qualifier) { 1363 KeyboardStateQualifier q = (KeyboardStateQualifier)qualifier; 1364 1365 KeyboardState value = q.getValue(); 1366 if (value == null) { 1367 mKeyboardState.clearSelection(); 1368 } else { 1369 mKeyboardState.select(KeyboardState.getIndex(value)); 1370 } 1371 } 1372 } 1373 1374 /** 1375 * Edit widget for {@link TextInputMethodQualifier}. 1376 */ 1377 private class TextInputEdit extends QualifierEditBase { 1378 1379 private Combo mTextInput; 1380 TextInputEdit(Composite parent)1381 public TextInputEdit(Composite parent) { 1382 super(parent, TextInputMethodQualifier.NAME); 1383 1384 mTextInput = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); 1385 fillCombo(mTextInput, Keyboard.values()); 1386 1387 mTextInput.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1388 mTextInput.addSelectionListener(new SelectionListener() { 1389 public void widgetDefaultSelected(SelectionEvent e) { 1390 onTextInputChange(); 1391 } 1392 public void widgetSelected(SelectionEvent e) { 1393 onTextInputChange(); 1394 } 1395 }); 1396 } 1397 onTextInputChange()1398 protected void onTextInputChange() { 1399 // update the current config 1400 int index = mTextInput.getSelectionIndex(); 1401 1402 if (index != -1) { 1403 mSelectedConfiguration.setTextInputMethodQualifier(new TextInputMethodQualifier( 1404 Keyboard.getByIndex(index))); 1405 } else { 1406 // empty selection, means no qualifier. 1407 // Since the qualifier classes are immutable, and we don't want to 1408 // remove the qualifier from the configuration, we create a new default one. 1409 mSelectedConfiguration.setTextInputMethodQualifier( 1410 new TextInputMethodQualifier()); 1411 } 1412 1413 // notify of change 1414 onChange(true /* keepSelection */); 1415 } 1416 1417 @Override setQualifier(ResourceQualifier qualifier)1418 public void setQualifier(ResourceQualifier qualifier) { 1419 TextInputMethodQualifier q = (TextInputMethodQualifier)qualifier; 1420 1421 Keyboard value = q.getValue(); 1422 if (value == null) { 1423 mTextInput.clearSelection(); 1424 } else { 1425 mTextInput.select(Keyboard.getIndex(value)); 1426 } 1427 } 1428 } 1429 1430 /** 1431 * Edit widget for {@link NavigationStateQualifier}. 1432 */ 1433 private class NavigationStateEdit extends QualifierEditBase { 1434 1435 private Combo mNavigationState; 1436 NavigationStateEdit(Composite parent)1437 public NavigationStateEdit(Composite parent) { 1438 super(parent, NavigationStateQualifier.NAME); 1439 1440 mNavigationState = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); 1441 fillCombo(mNavigationState, NavigationState.values()); 1442 1443 mNavigationState.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1444 mNavigationState.addSelectionListener(new SelectionListener() { 1445 public void widgetDefaultSelected(SelectionEvent e) { 1446 onNavigationChange(); 1447 } 1448 public void widgetSelected(SelectionEvent e) { 1449 onNavigationChange(); 1450 } 1451 }); 1452 } 1453 onNavigationChange()1454 protected void onNavigationChange() { 1455 // update the current config 1456 int index = mNavigationState.getSelectionIndex(); 1457 1458 if (index != -1) { 1459 mSelectedConfiguration.setNavigationStateQualifier( 1460 new NavigationStateQualifier(NavigationState.getByIndex(index))); 1461 } else { 1462 // empty selection, means no qualifier. 1463 // Since the qualifier classes are immutable, and we don't want to 1464 // remove the qualifier from the configuration, we create a new default one. 1465 mSelectedConfiguration.setNavigationStateQualifier(new NavigationStateQualifier()); 1466 } 1467 1468 // notify of change 1469 onChange(true /* keepSelection */); 1470 } 1471 1472 @Override setQualifier(ResourceQualifier qualifier)1473 public void setQualifier(ResourceQualifier qualifier) { 1474 NavigationStateQualifier q = (NavigationStateQualifier)qualifier; 1475 1476 NavigationState value = q.getValue(); 1477 if (value == null) { 1478 mNavigationState.clearSelection(); 1479 } else { 1480 mNavigationState.select(NavigationState.getIndex(value)); 1481 } 1482 } 1483 } 1484 1485 1486 /** 1487 * Edit widget for {@link NavigationMethodQualifier}. 1488 */ 1489 private class NavigationEdit extends QualifierEditBase { 1490 1491 private Combo mNavigation; 1492 NavigationEdit(Composite parent)1493 public NavigationEdit(Composite parent) { 1494 super(parent, NavigationMethodQualifier.NAME); 1495 1496 mNavigation = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY); 1497 fillCombo(mNavigation, Navigation.values()); 1498 1499 mNavigation.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1500 mNavigation.addSelectionListener(new SelectionListener() { 1501 public void widgetDefaultSelected(SelectionEvent e) { 1502 onNavigationChange(); 1503 } 1504 public void widgetSelected(SelectionEvent e) { 1505 onNavigationChange(); 1506 } 1507 }); 1508 } 1509 onNavigationChange()1510 protected void onNavigationChange() { 1511 // update the current config 1512 int index = mNavigation.getSelectionIndex(); 1513 1514 if (index != -1) { 1515 mSelectedConfiguration.setNavigationMethodQualifier(new NavigationMethodQualifier( 1516 Navigation.getByIndex(index))); 1517 } else { 1518 // empty selection, means no qualifier. 1519 // Since the qualifier classes are immutable, and we don't want to 1520 // remove the qualifier from the configuration, we create a new default one. 1521 mSelectedConfiguration.setNavigationMethodQualifier( 1522 new NavigationMethodQualifier()); 1523 } 1524 1525 // notify of change 1526 onChange(true /* keepSelection */); 1527 } 1528 1529 @Override setQualifier(ResourceQualifier qualifier)1530 public void setQualifier(ResourceQualifier qualifier) { 1531 NavigationMethodQualifier q = (NavigationMethodQualifier)qualifier; 1532 1533 Navigation value = q.getValue(); 1534 if (value == null) { 1535 mNavigation.clearSelection(); 1536 } else { 1537 mNavigation.select(Navigation.getIndex(value)); 1538 } 1539 } 1540 } 1541 1542 /** 1543 * Edit widget for {@link ScreenDimensionQualifier}. 1544 */ 1545 private class ScreenDimensionEdit extends QualifierEditBase { 1546 1547 private Text mSize1; 1548 private Text mSize2; 1549 ScreenDimensionEdit(Composite parent)1550 public ScreenDimensionEdit(Composite parent) { 1551 super(parent, ScreenDimensionQualifier.NAME); 1552 1553 ModifyListener modifyListener = new ModifyListener() { 1554 public void modifyText(ModifyEvent e) { 1555 onSizeChange(); 1556 } 1557 }; 1558 1559 FocusAdapter focusListener = new FocusAdapter() { 1560 @Override 1561 public void focusLost(FocusEvent e) { 1562 onSizeChange(); 1563 } 1564 }; 1565 1566 mSize1 = new Text(this, SWT.BORDER); 1567 mSize1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1568 mSize1.addVerifyListener(new DimensionVerifier()); 1569 mSize1.addModifyListener(modifyListener); 1570 mSize1.addFocusListener(focusListener); 1571 1572 mSize2 = new Text(this, SWT.BORDER); 1573 mSize2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1574 mSize2.addVerifyListener(new DimensionVerifier()); 1575 mSize2.addModifyListener(modifyListener); 1576 mSize2.addFocusListener(focusListener); 1577 } 1578 onSizeChange()1579 private void onSizeChange() { 1580 // update the current config 1581 String size1 = mSize1.getText(); 1582 String size2 = mSize2.getText(); 1583 1584 if (size1.length() == 0 || size2.length() == 0) { 1585 // if one of the strings is empty, reset to no qualifier. 1586 // Since the qualifier classes are immutable, and we don't want to 1587 // remove the qualifier from the configuration, we create a new default one. 1588 mSelectedConfiguration.setScreenDimensionQualifier(new ScreenDimensionQualifier()); 1589 } else { 1590 ScreenDimensionQualifier qualifier = ScreenDimensionQualifier.getQualifier(size1, 1591 size2); 1592 1593 if (qualifier != null) { 1594 mSelectedConfiguration.setScreenDimensionQualifier(qualifier); 1595 } else { 1596 // Failure! Looks like the value is wrong, reset the qualifier 1597 // Since the qualifier classes are immutable, and we don't want to 1598 // remove the qualifier from the configuration, we create a new default one. 1599 mSelectedConfiguration.setScreenDimensionQualifier( 1600 new ScreenDimensionQualifier()); 1601 } 1602 } 1603 1604 // notify of change 1605 onChange(true /* keepSelection */); 1606 } 1607 1608 @Override setQualifier(ResourceQualifier qualifier)1609 public void setQualifier(ResourceQualifier qualifier) { 1610 ScreenDimensionQualifier q = (ScreenDimensionQualifier)qualifier; 1611 1612 mSize1.setText(Integer.toString(q.getValue1())); 1613 mSize2.setText(Integer.toString(q.getValue2())); 1614 } 1615 } 1616 1617 /** 1618 * Edit widget for {@link VersionQualifier}. 1619 */ 1620 private class VersionEdit extends QualifierEditBase { 1621 private Text mText; 1622 VersionEdit(Composite parent)1623 public VersionEdit(Composite parent) { 1624 super(parent, VersionQualifier.NAME); 1625 1626 mText = new Text(this, SWT.BORDER); 1627 mText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 1628 mText.addVerifyListener(new MobileCodeVerifier()); 1629 mText.addModifyListener(new ModifyListener() { 1630 public void modifyText(ModifyEvent e) { 1631 onVersionChange(); 1632 } 1633 }); 1634 mText.addFocusListener(new FocusAdapter() { 1635 @Override 1636 public void focusLost(FocusEvent e) { 1637 onVersionChange(); 1638 } 1639 }); 1640 1641 new Label(this, SWT.NONE).setText("(Platform API level)"); 1642 } 1643 onVersionChange()1644 private void onVersionChange() { 1645 String value = mText.getText(); 1646 1647 if (value.length() == 0) { 1648 // empty string, means a qualifier with no value. 1649 // Since the qualifier classes are immutable, and we don't want to 1650 // remove the qualifier from the configuration, we create a new default one. 1651 mSelectedConfiguration.setVersionQualifier(new VersionQualifier()); 1652 } else { 1653 try { 1654 VersionQualifier qualifier = VersionQualifier.getQualifier( 1655 VersionQualifier.getFolderSegment(Integer.parseInt(value))); 1656 if (qualifier != null) { 1657 mSelectedConfiguration.setVersionQualifier(qualifier); 1658 } else { 1659 // Failure! Looks like the value is wrong 1660 mSelectedConfiguration.setVersionQualifier(new VersionQualifier()); 1661 } 1662 } catch (NumberFormatException nfe) { 1663 // Looks like the code is not a number. This should not happen since the text 1664 // field has a VerifyListener that prevents it. 1665 mSelectedConfiguration.setVersionQualifier(new VersionQualifier()); 1666 } 1667 } 1668 1669 // notify of change 1670 onChange(true /* keepSelection */); 1671 } 1672 1673 @Override setQualifier(ResourceQualifier qualifier)1674 public void setQualifier(ResourceQualifier qualifier) { 1675 VersionQualifier q = (VersionQualifier)qualifier; 1676 1677 mText.setText(Integer.toString(q.getVersion())); 1678 } 1679 } 1680 1681 } 1682