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