001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.editor.target;
011:
012: import java.lang.reflect.InvocationTargetException;
013: import java.util.Locale;
014: import java.util.StringTokenizer;
015: import java.util.TreeSet;
016:
017: import org.eclipse.core.runtime.IProgressMonitor;
018: import org.eclipse.core.runtime.Platform;
019: import org.eclipse.jface.operation.IRunnableWithProgress;
020: import org.eclipse.pde.core.IModelChangedEvent;
021: import org.eclipse.pde.internal.core.itarget.IEnvironmentInfo;
022: import org.eclipse.pde.internal.core.itarget.ITarget;
023: import org.eclipse.pde.internal.core.itarget.ITargetModel;
024: import org.eclipse.pde.internal.ui.PDEPlugin;
025: import org.eclipse.pde.internal.ui.PDEUIMessages;
026: import org.eclipse.pde.internal.ui.editor.FormLayoutFactory;
027: import org.eclipse.pde.internal.ui.editor.PDEFormPage;
028: import org.eclipse.pde.internal.ui.editor.PDESection;
029: import org.eclipse.pde.internal.ui.parts.ComboPart;
030: import org.eclipse.swt.SWT;
031: import org.eclipse.swt.custom.CCombo;
032: import org.eclipse.swt.events.FocusAdapter;
033: import org.eclipse.swt.events.FocusEvent;
034: import org.eclipse.swt.events.ModifyEvent;
035: import org.eclipse.swt.events.ModifyListener;
036: import org.eclipse.swt.layout.GridData;
037: import org.eclipse.swt.layout.GridLayout;
038: import org.eclipse.swt.widgets.Combo;
039: import org.eclipse.swt.widgets.Composite;
040: import org.eclipse.swt.widgets.Control;
041: import org.eclipse.swt.widgets.Label;
042: import org.eclipse.ui.PlatformUI;
043: import org.eclipse.ui.forms.IFormColors;
044: import org.eclipse.ui.forms.widgets.FormToolkit;
045: import org.eclipse.ui.forms.widgets.Section;
046:
047: public class EnvironmentSection extends PDESection {
048:
049: private ComboPart fOSCombo;
050: private ComboPart fWSCombo;
051: private ComboPart fNLCombo;
052: private ComboPart fArchCombo;
053:
054: private TreeSet fNLChoices;
055: private TreeSet fOSChoices;
056: private TreeSet fWSChoices;
057: private TreeSet fArchChoices;
058: private boolean LOCALES_INITIALIZED = false;
059:
060: public EnvironmentSection(PDEFormPage page, Composite parent) {
061: super (page, parent, Section.DESCRIPTION);
062: createClient(getSection(), page.getEditor().getToolkit());
063: }
064:
065: protected void createClient(Section section, FormToolkit toolkit) {
066: section.setLayout(FormLayoutFactory.createClearGridLayout(
067: false, 1));
068: section.setText(PDEUIMessages.EnvironmentSection_title);
069: section
070: .setDescription(PDEUIMessages.EnvironmentSection_description);
071: GridData data = new GridData(GridData.FILL_HORIZONTAL);
072: data.verticalAlignment = SWT.TOP;
073: data.horizontalSpan = 2;
074: section.setLayoutData(data);
075:
076: Composite client = toolkit.createComposite(section);
077: client.setLayout(FormLayoutFactory
078: .createSectionClientGridLayout(true, 2));
079: client.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
080:
081: Composite left = toolkit.createComposite(client);
082: left.setLayout(new GridLayout(2, false));
083: GridLayout layout = FormLayoutFactory.createClearGridLayout(
084: false, 2);
085: layout.horizontalSpacing = layout.verticalSpacing = 5;
086: left.setLayout(layout);
087: left.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
088:
089: IEnvironmentInfo orgEnv = getEnvironment();
090: initializeChoices(orgEnv);
091:
092: Label label = toolkit.createLabel(left,
093: PDEUIMessages.EnvironmentSection_operationSystem);
094: label.setForeground(toolkit.getColors().getColor(
095: IFormColors.TITLE));
096:
097: fOSCombo = new ComboPart();
098: fOSCombo.createControl(left, toolkit, SWT.SINGLE | SWT.BORDER);
099: fOSCombo.getControl().setLayoutData(
100: new GridData(GridData.FILL_HORIZONTAL));
101: fOSCombo.setItems((String[]) fOSChoices
102: .toArray(new String[fOSChoices.size()]));
103:
104: label = toolkit.createLabel(left,
105: PDEUIMessages.EnvironmentSection_windowingSystem);
106: label.setForeground(toolkit.getColors().getColor(
107: IFormColors.TITLE));
108:
109: fWSCombo = new ComboPart();
110: fWSCombo.createControl(left, toolkit, SWT.SINGLE | SWT.BORDER);
111: fWSCombo.getControl().setLayoutData(
112: new GridData(GridData.FILL_HORIZONTAL));
113: fWSCombo.setItems((String[]) fWSChoices
114: .toArray(new String[fWSChoices.size()]));
115:
116: Composite right = toolkit.createComposite(client);
117: layout = FormLayoutFactory.createClearGridLayout(false, 2);
118: layout.verticalSpacing = layout.horizontalSpacing = 5;
119: right.setLayout(layout);
120: right.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
121:
122: label = toolkit.createLabel(right,
123: PDEUIMessages.EnvironmentSection_architecture);
124: label.setForeground(toolkit.getColors().getColor(
125: IFormColors.TITLE));
126:
127: fArchCombo = new ComboPart();
128: fArchCombo.createControl(right, toolkit, SWT.SINGLE
129: | SWT.BORDER);
130: fArchCombo.getControl().setLayoutData(
131: new GridData(GridData.FILL_HORIZONTAL));
132: fArchCombo.setItems((String[]) fArchChoices
133: .toArray(new String[fArchChoices.size()]));
134:
135: label = toolkit.createLabel(right,
136: PDEUIMessages.EnvironmentSection_locale);
137: label.setForeground(toolkit.getColors().getColor(
138: IFormColors.TITLE));
139:
140: fNLCombo = new ComboPart();
141: fNLCombo.createControl(right, toolkit, SWT.SINGLE | SWT.BORDER
142: | SWT.H_SCROLL);
143: fNLCombo.getControl().setLayoutData(
144: new GridData(GridData.FILL_HORIZONTAL));
145: fNLCombo.setItems((String[]) fNLChoices
146: .toArray(new String[fNLChoices.size()]));
147:
148: refresh();
149:
150: fOSCombo.addModifyListener(new ModifyListener() {
151: public void modifyText(ModifyEvent e) {
152: getEnvironment().setOS(getText(fOSCombo));
153: }
154: });
155: fWSCombo.addModifyListener(new ModifyListener() {
156: public void modifyText(ModifyEvent e) {
157: getEnvironment().setWS(getText(fWSCombo));
158: }
159: });
160: fArchCombo.addModifyListener(new ModifyListener() {
161: public void modifyText(ModifyEvent e) {
162: getEnvironment().setArch(getText(fArchCombo));
163: }
164: });
165: fNLCombo.getControl().addFocusListener(new FocusAdapter() {
166: public void focusGained(FocusEvent event) {
167: // if we haven't gotten all the values for the NL's, display a busy cursor to the user while we find them.
168: if (!LOCALES_INITIALIZED) {
169: try {
170: PlatformUI.getWorkbench().getProgressService()
171: .busyCursorWhile(
172: new IRunnableWithProgress() {
173: public void run(
174: IProgressMonitor monitor) {
175: initializeAllLocales();
176: LOCALES_INITIALIZED = true;
177: }
178: });
179: } catch (InvocationTargetException e) {
180: PDEPlugin.log(e);
181: } catch (InterruptedException e) {
182: PDEPlugin.log(e);
183: }
184: }
185:
186: // first time through, we should have a max item count of 1.
187: // On the first time through, we need to set the new values, and also attach the listener
188: // If we attached the listener initially, when we call setItems(..), it would make the editor dirty (when the user didn't change anything)
189: if (fNLCombo.getItemCount() < 3) {
190: String current = fNLCombo.getSelection();
191: if (!fNLCombo.getControl().isDisposed()) {
192: fNLCombo
193: .setItems((String[]) fNLChoices
194: .toArray(new String[fNLChoices
195: .size()]));
196: fNLCombo.setText(current);
197: }
198:
199: fNLCombo.addModifyListener(new ModifyListener() {
200: public void modifyText(ModifyEvent e) {
201: String value = getText(fNLCombo);
202: int index = value.indexOf("-"); //$NON-NLS-1$
203: if (index > 0)
204: value = value.substring(0, index);
205: getEnvironment().setNL(value.trim());
206: }
207: });
208: }
209:
210: }
211: });
212:
213: toolkit.paintBordersFor(client);
214: section.setClient(client);
215:
216: // Register to be notified when the model changes
217: getModel().addModelChangedListener(this );
218: }
219:
220: /* (non-Javadoc)
221: * @see org.eclipse.pde.internal.ui.editor.PDESection#modelChanged(org.eclipse.pde.core.IModelChangedEvent)
222: */
223: public void modelChanged(IModelChangedEvent e) {
224: // No need to call super, handling world changed event here
225: if (e.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
226: handleModelEventWorldChanged(e);
227: }
228: }
229:
230: /**
231: * @param event
232: */
233: private void handleModelEventWorldChanged(IModelChangedEvent event) {
234: // Perform the refresh
235: refresh();
236: }
237:
238: /* (non-Javadoc)
239: * @see org.eclipse.ui.forms.AbstractFormPart#dispose()
240: */
241: public void dispose() {
242: ITargetModel model = getModel();
243: if (model != null) {
244: model.removeModelChangedListener(this );
245: }
246: super .dispose();
247: }
248:
249: private void initializeChoices(IEnvironmentInfo orgEnv) {
250: fOSChoices = new TreeSet();
251: String[] os = Platform.knownOSValues();
252: for (int i = 0; i < os.length; i++)
253: fOSChoices.add(os[i]);
254: fOSChoices.add(""); //$NON-NLS-1$
255: String fileValue = orgEnv.getOS();
256: if (fileValue != null)
257: fOSChoices.add(fileValue);
258:
259: fWSChoices = new TreeSet();
260: String[] ws = Platform.knownWSValues();
261: for (int i = 0; i < ws.length; i++)
262: fWSChoices.add(ws[i]);
263: fWSChoices.add(""); //$NON-NLS-1$
264: fileValue = orgEnv.getWS();
265: if (fileValue != null)
266: fWSChoices.add(fileValue);
267:
268: fArchChoices = new TreeSet();
269: String[] arch = Platform.knownOSArchValues();
270: for (int i = 0; i < arch.length; i++)
271: fArchChoices.add(arch[i]);
272: fArchChoices.add(""); //$NON-NLS-1$
273: fileValue = orgEnv.getArch();
274: if (fileValue != null)
275: fArchChoices.add(fileValue);
276:
277: fNLChoices = new TreeSet();
278: fNLChoices.add(""); //$NON-NLS-1$
279: }
280:
281: private void initializeAllLocales() {
282: String[] nl = getLocales();
283: for (int i = 0; i < nl.length; i++)
284: fNLChoices.add(nl[i]);
285: String fileValue = getEnvironment().getNL();
286: if (fileValue != null)
287: fNLChoices.add(expandLocaleName(fileValue));
288: LOCALES_INITIALIZED = true;
289: }
290:
291: private static String[] getLocales() {
292: Locale[] locales = Locale.getAvailableLocales();
293: String[] result = new String[locales.length];
294: for (int i = 0; i < locales.length; i++) {
295: Locale locale = locales[i];
296: StringBuffer buffer = new StringBuffer();
297: buffer.append(locale.toString());
298: buffer.append(" - "); //$NON-NLS-1$
299: buffer.append(locale.getDisplayName());
300: result[i] = buffer.toString();
301: }
302: return result;
303: }
304:
305: private String expandLocaleName(String name) {
306: String language = ""; //$NON-NLS-1$
307: String country = ""; //$NON-NLS-1$
308: String variant = ""; //$NON-NLS-1$
309:
310: StringTokenizer tokenizer = new StringTokenizer(name, "_"); //$NON-NLS-1$
311: if (tokenizer.hasMoreTokens())
312: language = tokenizer.nextToken();
313: if (tokenizer.hasMoreTokens())
314: country = tokenizer.nextToken();
315: if (tokenizer.hasMoreTokens())
316: variant = tokenizer.nextToken();
317:
318: Locale locale = new Locale(language, country, variant);
319: return locale.toString() + " - " + locale.getDisplayName(); //$NON-NLS-1$
320: }
321:
322: private String getText(ComboPart combo) {
323: Control control = combo.getControl();
324: if (control instanceof Combo)
325: return ((Combo) control).getText();
326: return ((CCombo) control).getText();
327: }
328:
329: private IEnvironmentInfo getEnvironment() {
330: IEnvironmentInfo info = getTarget().getEnvironment();
331: if (info == null) {
332: info = getModel().getFactory().createEnvironment();
333: getTarget().setEnvironment(info);
334: }
335: return info;
336: }
337:
338: private ITarget getTarget() {
339: return getModel().getTarget();
340: }
341:
342: private ITargetModel getModel() {
343: return (ITargetModel) getPage().getPDEEditor()
344: .getAggregateModel();
345: }
346:
347: public void refresh() {
348: IEnvironmentInfo orgEnv = getEnvironment();
349: String presetValue = (orgEnv.getOS() == null) ? "" : orgEnv.getOS(); //$NON-NLS-1$
350: fOSCombo.setText(presetValue);
351: presetValue = (orgEnv.getWS() == null) ? "" : orgEnv.getWS(); //$NON-NLS-1$
352: fWSCombo.setText(presetValue);
353: presetValue = (orgEnv.getArch() == null) ? "" : orgEnv.getArch(); //$NON-NLS-1$
354: fArchCombo.setText(presetValue);
355: presetValue = (orgEnv.getNL() == null) ? "" : expandLocaleName(orgEnv.getNL()); //$NON-NLS-1$
356: fNLCombo.setText(presetValue);
357:
358: super .refresh();
359: }
360:
361: protected void updateChoices() {
362: if (LOCALES_INITIALIZED)
363: return;
364: // prevent NPE Mike found, which we can't reproduce. Somehow we call initializeAllLocales before the ITargetModel exists.
365: if (getModel() == null)
366: return;
367: // kick off thread in backgroud to find the NL values
368: new Thread(new Runnable() {
369: public void run() {
370: initializeAllLocales();
371: }
372: }).start();
373: }
374:
375: }
|