001: /*******************************************************************************
002: * Copyright (c) 2000, 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.parts;
011:
012: import org.eclipse.pde.internal.ui.editor.FormLayoutFactory;
013: import org.eclipse.swt.SWT;
014: import org.eclipse.swt.events.FocusAdapter;
015: import org.eclipse.swt.events.FocusEvent;
016: import org.eclipse.swt.events.KeyAdapter;
017: import org.eclipse.swt.events.KeyEvent;
018: import org.eclipse.swt.events.ModifyEvent;
019: import org.eclipse.swt.events.ModifyListener;
020: import org.eclipse.swt.events.SelectionAdapter;
021: import org.eclipse.swt.events.SelectionEvent;
022: import org.eclipse.swt.layout.GridData;
023: import org.eclipse.swt.layout.GridLayout;
024: import org.eclipse.swt.widgets.Button;
025: import org.eclipse.swt.widgets.Composite;
026: import org.eclipse.swt.widgets.Control;
027: import org.eclipse.swt.widgets.Layout;
028: import org.eclipse.swt.widgets.Text;
029: import org.eclipse.ui.forms.IFormColors;
030: import org.eclipse.ui.forms.widgets.FormToolkit;
031: import org.eclipse.ui.forms.widgets.Hyperlink;
032: import org.eclipse.ui.forms.widgets.TableWrapData;
033: import org.eclipse.ui.forms.widgets.TableWrapLayout;
034:
035: /**
036: * The helper class for creating entry fields with label and text. Optionally,
037: * a button can be added after the text. The attached listener reacts to all
038: * the events. Entring new text makes the entry 'dirty', but only when 'commit'
039: * is called is 'valueChanged' method called (and only if 'dirty' flag is set).
040: * This allows delayed commit.
041: */
042: public class FormEntry {
043: private Control fLabel;
044: private Text fText;
045: private Button fBrowse;
046: private String fValue = ""; //$NON-NLS-1$
047: private boolean fDirty;
048: boolean fIgnoreModify = false;
049: private IFormEntryListener fListener;
050:
051: public static final int F_DEFAULT_TEXT_WIDTH_HINT = 100;
052:
053: /**
054: * The default constructor. Call 'createControl' to make it.
055: *
056: */
057: public FormEntry(Composite parent, FormToolkit toolkit,
058: String labelText, int style) {
059: createControl(parent, toolkit, labelText, style, null, false,
060: 0, 0);
061: }
062:
063: /**
064: * This constructor create all the controls right away.
065: *
066: * @param parent
067: * @param toolkit
068: * @param labelText
069: * @param browseText
070: * @param linkLabel
071: */
072: public FormEntry(Composite parent, FormToolkit toolkit,
073: String labelText, String browseText, boolean linkLabel) {
074: this (parent, toolkit, labelText, browseText, linkLabel, 0);
075: }
076:
077: public FormEntry(Composite parent, FormToolkit toolkit,
078: String labelText, String browseText, boolean linkLabel,
079: int indent) {
080: createControl(parent, toolkit, labelText, SWT.SINGLE,
081: browseText, linkLabel, indent, 0);
082: }
083:
084: public FormEntry(Composite parent, FormToolkit toolkit,
085: String labelText, int indent, int tcolspan) {
086: createControl(parent, toolkit, labelText, SWT.SINGLE, null,
087: false, indent, tcolspan);
088: }
089:
090: /**
091: * Create all the controls in the provided parent.
092: *
093: * @param parent
094: * @param toolkit
095: * @param labelText
096: * @param span
097: * @param browseText
098: * @param linkLabel
099: */
100: private void createControl(Composite parent, FormToolkit toolkit,
101: String labelText, int style, String browseText,
102: boolean linkLabel, int indent, int tcolspan) {
103: if (linkLabel) {
104: Hyperlink link = toolkit.createHyperlink(parent, labelText,
105: SWT.NULL);
106: fLabel = link;
107: } else {
108: if (labelText != null) {
109: fLabel = toolkit.createLabel(parent, labelText);
110: fLabel.setForeground(toolkit.getColors().getColor(
111: IFormColors.TITLE));
112: }
113: }
114: fText = toolkit.createText(parent, "", style); //$NON-NLS-1$
115: addListeners();
116: if (browseText != null) {
117: fBrowse = toolkit
118: .createButton(parent, browseText, SWT.PUSH);
119: fBrowse.addSelectionListener(new SelectionAdapter() {
120: public void widgetSelected(SelectionEvent e) {
121: if (fListener != null)
122: fListener.browseButtonSelected(FormEntry.this );
123: }
124: });
125: }
126: fillIntoGrid(parent, indent, tcolspan);
127: // Set the default text width hint and let clients modify accordingly
128: // after the fact
129: setTextWidthHint(F_DEFAULT_TEXT_WIDTH_HINT);
130: }
131:
132: public void setEditable(boolean editable) {
133: fText.setEditable(editable);
134: if (fLabel instanceof Hyperlink)
135: ((Hyperlink) fLabel).setUnderlined(editable);
136:
137: if (fBrowse != null)
138: fBrowse.setEnabled(editable);
139: }
140:
141: private void fillIntoGrid(Composite parent, int indent, int tcolspan) {
142: Layout layout = parent.getLayout();
143: int tspan;
144: if (layout instanceof GridLayout) {
145: int span = ((GridLayout) layout).numColumns;
146: if (tcolspan > 0)
147: tspan = tcolspan;
148: else
149: tspan = fBrowse != null ? span - 2 : span - 1;
150: GridData gd;
151: if (fLabel != null) {
152: gd = new GridData(GridData.VERTICAL_ALIGN_CENTER);
153: gd.horizontalIndent = indent;
154: fLabel.setLayoutData(gd);
155: }
156: gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
157: gd.horizontalSpan = tspan;
158: if (fLabel != null) {
159: gd.horizontalIndent = FormLayoutFactory.CONTROL_HORIZONTAL_INDENT;
160: }
161: gd.grabExcessHorizontalSpace = (tspan == 1);
162: gd.widthHint = 10;
163: fText.setLayoutData(gd);
164: if (fBrowse != null) {
165: gd = new GridData(GridData.VERTICAL_ALIGN_CENTER);
166: fBrowse.setLayoutData(gd);
167: }
168: } else if (layout instanceof TableWrapLayout) {
169: int span = ((TableWrapLayout) layout).numColumns;
170: if (tcolspan > 0)
171: tspan = tcolspan;
172: else
173: tspan = fBrowse != null ? span - 2 : span - 1;
174: TableWrapData td;
175: if (fLabel != null) {
176: td = new TableWrapData();
177: td.valign = TableWrapData.MIDDLE;
178: td.indent = indent;
179: fLabel.setLayoutData(td);
180: }
181: td = new TableWrapData(TableWrapData.FILL);
182: td.colspan = tspan;
183: if (fLabel != null) {
184: td.indent = FormLayoutFactory.CONTROL_HORIZONTAL_INDENT;
185: }
186: td.grabHorizontal = (tspan == 1);
187: td.valign = TableWrapData.MIDDLE;
188: fText.setLayoutData(td);
189: if (fBrowse != null) {
190: td = new TableWrapData(TableWrapData.FILL);
191: td.valign = TableWrapData.MIDDLE;
192: fBrowse.setLayoutData(td);
193: }
194: }
195: }
196:
197: /**
198: * Attaches the listener for the entry.
199: *
200: * @param listener
201: */
202: public void setFormEntryListener(IFormEntryListener listener) {
203: if (fLabel != null && fLabel instanceof Hyperlink) {
204: if (this .fListener != null)
205: ((Hyperlink) fLabel)
206: .removeHyperlinkListener(this .fListener);
207: if (listener != null)
208: ((Hyperlink) fLabel).addHyperlinkListener(listener);
209: }
210: this .fListener = listener;
211: }
212:
213: private void addListeners() {
214: fText.addKeyListener(new KeyAdapter() {
215: public void keyReleased(KeyEvent e) {
216: keyReleaseOccured(e);
217: }
218: });
219: fText.addModifyListener(new ModifyListener() {
220: public void modifyText(ModifyEvent e) {
221: editOccured(e);
222: }
223: });
224: fText.addFocusListener(new FocusAdapter() {
225: public void focusGained(FocusEvent e) {
226: if (fListener != null)
227: fListener.focusGained(FormEntry.this );
228: }
229:
230: public void focusLost(FocusEvent e) {
231: if (fDirty)
232: commit();
233: }
234: });
235: }
236:
237: /**
238: * If dirty, commits the text in the widget to the value and notifies the
239: * listener. This call clears the 'dirty' flag.
240: *
241: */
242: public void commit() {
243: if (fDirty) {
244: fValue = fText.getText();
245: //if (value.length()==0)
246: //value = null;
247: //notify
248: if (fListener != null)
249: fListener.textValueChanged(this );
250: }
251: fDirty = false;
252: }
253:
254: public void cancelEdit() {
255: fDirty = false;
256: }
257:
258: private void editOccured(ModifyEvent e) {
259: if (fIgnoreModify)
260: return;
261: fDirty = true;
262: if (fListener != null)
263: fListener.textDirty(this );
264: }
265:
266: /**
267: * Returns the text control.
268: *
269: * @return
270: */
271: public Text getText() {
272: return fText;
273: }
274:
275: public Control getLabel() {
276: return fLabel;
277: }
278:
279: /**
280: * Returns the browse button control.
281: * @return
282: */
283: public Button getButton() {
284: return fBrowse;
285: }
286:
287: /**
288: * Returns the current entry value. If the entry is dirty and was not
289: * commited, the value may be different from the text in the widget.
290: *
291: * @return
292: */
293: public String getValue() {
294: return fValue.trim();
295: }
296:
297: /**
298: * Returns true if the text has been modified.
299: *
300: * @return
301: */
302: public boolean isDirty() {
303: return fDirty;
304: }
305:
306: private void keyReleaseOccured(KeyEvent e) {
307: if (e.character == '\r') {
308: // commit value
309: if (fDirty)
310: commit();
311: } else if (e.character == '\u001b') { // Escape character
312: if (!fValue.equals(fText.getText()))
313: fText.setText(fValue != null ? fValue : ""); // restore old //$NON-NLS-1$
314: fDirty = false;
315: }
316: if (fListener != null)
317: fListener.selectionChanged(FormEntry.this );
318: }
319:
320: /**
321: * Sets the value of this entry.
322: *
323: * @param value
324: */
325: public void setValue(String value) {
326: if (fText != null)
327: fText.setText(value != null ? value : ""); //$NON-NLS-1$
328: this .fValue = (value != null) ? value : ""; //$NON-NLS-1$
329: }
330:
331: /**
332: * Sets the value of this entry with the possibility to turn the
333: * notification off.
334: *
335: * @param value
336: * @param blockNotification
337: */
338: public void setValue(String value, boolean blockNotification) {
339: fIgnoreModify = blockNotification;
340: setValue(value);
341: fIgnoreModify = false;
342: }
343:
344: public void setVisible(boolean visible) {
345: if (fLabel != null)
346: fLabel.setVisible(visible);
347: if (fText != null)
348: fText.setVisible(visible);
349: if (fBrowse != null)
350: fBrowse.setVisible(visible);
351: }
352:
353: /**
354: * If GridData was used, set the width hint. If TableWrapData was used
355: * set the max width. If no layout data was specified, this method does
356: * nothing.
357: * @param width
358: */
359: public void setTextWidthHint(int width) {
360: Object data = getText().getLayoutData();
361: if (data == null) {
362: return;
363: } else if (data instanceof GridData) {
364: ((GridData) data).widthHint = width;
365: } else if (data instanceof TableWrapData) {
366: ((TableWrapData) data).maxWidth = width;
367: }
368: }
369: }
|