e795bcc761166d54e5c3680a022534920b546de3
[taxeditor.git] / taxeditor-store / src / main / java / eu / etaxonomy / taxeditor / dialogs / NewReferenceInputDialog.java
1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package eu.etaxonomy.taxeditor.dialogs;
12
13 import java.util.Arrays;
14 import java.util.List;
15
16 import org.apache.log4j.Logger;
17 import org.eclipse.jface.dialogs.Dialog;
18 import org.eclipse.jface.dialogs.IDialogConstants;
19 import org.eclipse.jface.dialogs.IInputValidator;
20 import org.eclipse.jface.resource.StringConverter;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.events.ModifyEvent;
23 import org.eclipse.swt.events.ModifyListener;
24 import org.eclipse.swt.layout.GridData;
25 import org.eclipse.swt.widgets.Button;
26 import org.eclipse.swt.widgets.Combo;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Control;
29 import org.eclipse.swt.widgets.Label;
30 import org.eclipse.swt.widgets.Shell;
31 import org.eclipse.swt.widgets.Text;
32
33 import eu.etaxonomy.cdm.model.reference.Article;
34 import eu.etaxonomy.cdm.model.reference.Book;
35 import eu.etaxonomy.cdm.model.reference.BookSection;
36 import eu.etaxonomy.cdm.model.reference.CdDvd;
37 import eu.etaxonomy.cdm.model.reference.Database;
38 import eu.etaxonomy.cdm.model.reference.Generic;
39 import eu.etaxonomy.cdm.model.reference.InProceedings;
40 import eu.etaxonomy.cdm.model.reference.Journal;
41 import eu.etaxonomy.cdm.model.reference.Patent;
42 import eu.etaxonomy.cdm.model.reference.PersonalCommunication;
43 import eu.etaxonomy.cdm.model.reference.PrintSeries;
44 import eu.etaxonomy.cdm.model.reference.Proceedings;
45 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
46 import eu.etaxonomy.cdm.model.reference.ReferenceType;
47 import eu.etaxonomy.cdm.model.reference.Report;
48 import eu.etaxonomy.cdm.model.reference.Thesis;
49 import eu.etaxonomy.cdm.model.reference.WebPage;
50
51 /**
52 * A simple input dialog for soliciting an input string from the user.
53 * <p>
54 * This concrete dialog class can be instantiated as is, or further subclassed as
55 * required.
56 * </p>
57 */
58 public class NewReferenceInputDialog extends Dialog {
59 private static final Logger logger = Logger
60 .getLogger(NewReferenceInputDialog.class);
61
62 /**
63 * The title of the dialog.
64 */
65 private String title;
66
67 /**
68 * The message to display, or <code>null</code> if none.
69 */
70 private String message;
71
72 /**
73 * The input value; the empty string by default.
74 */
75 private String value = "";//$NON-NLS-1$
76
77 /**
78 * The input validator, or <code>null</code> if none.
79 */
80 private IInputValidator validator;
81
82 /**
83 * Ok button widget.
84 */
85 private Button okButton;
86
87 /**
88 * Input text widget.
89 */
90 private Text refText;
91
92 /**
93 * Error message label widget.
94 */
95 private Text errorMessageText;
96
97 /**
98 * Error message string.
99 */
100 private String errorMessage;
101
102 private String message2;
103
104 private ReferenceBase reference = null;
105
106 /**
107 * Creates an input dialog with OK and Cancel buttons. Note that the dialog
108 * will have no visual representation (no widgets) until it is told to open.
109 * <p>
110 * Note that the <code>open</code> method blocks for input dialogs.
111 * </p>
112 *
113 * @param parentShell
114 * the parent shell, or <code>null</code> to create a top-level
115 * shell
116 * @param dialogTitle
117 * the dialog title, or <code>null</code> if none
118 * @param dialogMessage
119 * the dialog message, or <code>null</code> if none
120 * @param initialValue
121 * the initial input value, or <code>null</code> if none
122 * (equivalent to the empty string)
123 * @param validator
124 * an input validator, or <code>null</code> if none
125 */
126 public NewReferenceInputDialog(Shell parentShell) {
127 super(parentShell);
128 this.title = "Create reference";
129 this.message = "Choose a reference type:";
130 this.message2 = "Enter a title cache:";
131 }
132
133 /*
134 * (non-Javadoc) Method declared on Dialog.
135 */
136 protected void buttonPressed(int buttonId) {
137 if (buttonId == IDialogConstants.OK_ID) {
138 createReference();
139 value = refText.getText();
140 } else {
141 value = null;
142 }
143 super.buttonPressed(buttonId);
144 }
145
146 /**
147 *
148 */
149 private void createReference() {
150 String key = refCombo.getText();
151 // TODO replace w more generic method when cdmlib matures accordingly
152 if (ReferenceType.Article.getMessage().equals(key)) {
153 reference = Article.NewInstance();
154 }
155 if (ReferenceType.Book.getMessage().equals(key)) {
156 reference = Book.NewInstance();
157 }
158 if (ReferenceType.BookSection.getMessage().equals(key)) {
159 reference = BookSection.NewInstance();
160 }
161 if (ReferenceType.CdDvd.getMessage().equals(key)) {
162 reference = CdDvd.NewInstance();
163 }
164 if (ReferenceType.Database.getMessage().equals(key)) {
165 reference = Database.NewInstance();
166 }
167 if (ReferenceType.Generic.getMessage().equals(key)) {
168 reference = Generic.NewInstance();
169 }
170 if (ReferenceType.InProceedings.getMessage().equals(key)) {
171 reference = InProceedings.NewInstance();
172 }
173 if (ReferenceType.Journal.getMessage().equals(key)) {
174 reference = Journal.NewInstance();
175 }
176 if (ReferenceType.Map.getMessage().equals(key)) {
177 reference = eu.etaxonomy.cdm.model.reference.Map.NewInstance();
178 }
179 if (ReferenceType.Patent.getMessage().equals(key)) {
180 reference = Patent.NewInstance();
181 }
182 if (ReferenceType.PersonalCommunication.getMessage().equals(key)) {
183 reference = PersonalCommunication.NewInstance();
184 }
185 if (ReferenceType.PrintSeries.getMessage().equals(key)) {
186 reference = PrintSeries.NewInstance();
187 }
188 if (ReferenceType.Proceedings.getMessage().equals(key)) {
189 reference = Proceedings.NewInstance();
190 }
191 if (ReferenceType.Report.getMessage().equals(key)) {
192 reference = Report.NewInstance();
193 }
194 if (ReferenceType.Thesis.getMessage().equals(key)) {
195 reference = Thesis.NewInstance();
196 }
197 if (ReferenceType.WebPage.getMessage().equals(key)) {
198 reference = WebPage.NewInstance();
199 }
200 if (reference != null) {
201 reference.setTitleCache(refText.getText());
202 }
203 }
204
205 /*
206 * (non-Javadoc)
207 *
208 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
209 */
210 protected void configureShell(Shell shell) {
211 super.configureShell(shell);
212 if (title != null) {
213 shell.setText(title);
214 }
215 }
216
217 /*
218 * (non-Javadoc)
219 *
220 * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
221 */
222 protected void createButtonsForButtonBar(Composite parent) {
223 // create OK and Cancel buttons by default
224 okButton = createButton(parent, IDialogConstants.OK_ID,
225 IDialogConstants.OK_LABEL, true);
226 createButton(parent, IDialogConstants.CANCEL_ID,
227 IDialogConstants.CANCEL_LABEL, false);
228 //do this here because setting the text will set enablement on the ok
229 // button
230 refText.setFocus();
231 if (value != null) {
232 refText.setText(value);
233 refText.selectAll();
234 }
235 }
236
237 private Combo refCombo;
238
239 private List<ReferenceType> refTypes;
240
241 /*
242 * (non-Javadoc) Method declared on Dialog.
243 */
244 protected Control createDialogArea(Composite parent) {
245 // create composite
246 Composite composite = (Composite) super.createDialogArea(parent);
247 // create message
248 Label label = new Label(composite, SWT.WRAP);
249 label.setText(message);
250 GridData data = new GridData(GridData.GRAB_HORIZONTAL
251 | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL
252 | GridData.VERTICAL_ALIGN_CENTER);
253 data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
254 label.setLayoutData(data);
255 label.setFont(parent.getFont());
256 refCombo = new Combo(composite, SWT.NONE | SWT.READ_ONLY);
257 refCombo.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
258 | GridData.HORIZONTAL_ALIGN_FILL));
259 refCombo.addModifyListener(new ModifyListener() {
260 public void modifyText(ModifyEvent e) {
261 validateInput();
262 }
263 });
264 // create message
265 Label label2 = new Label(composite, SWT.WRAP);
266 label2.setText(message2);
267 GridData data2 = new GridData(GridData.GRAB_HORIZONTAL
268 | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL
269 | GridData.VERTICAL_ALIGN_CENTER);
270 data2.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
271 label2.setLayoutData(data);
272 label2.setFont(parent.getFont());
273 // create text
274 refText = new Text(composite, getInputTextStyle());
275 refText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
276 | GridData.HORIZONTAL_ALIGN_FILL));
277 refText.addModifyListener(new ModifyListener() {
278 public void modifyText(ModifyEvent e) {
279 validateInput();
280 }
281 });
282 errorMessageText = new Text(composite, SWT.READ_ONLY | SWT.WRAP);
283 errorMessageText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
284 | GridData.HORIZONTAL_ALIGN_FILL));
285 errorMessageText.setBackground(errorMessageText.getDisplay()
286 .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
287 // Set the error message text
288 // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=66292
289 setErrorMessage(errorMessage);
290 applyDialogFont(composite);
291
292 populateReferences();
293
294 return composite;
295 }
296
297 /**
298 *
299 */
300 private void populateReferences() {
301 refTypes = Arrays.asList(ReferenceType.values());
302 for (ReferenceType type : refTypes) {
303 refCombo.add(type.getMessage());
304 }
305 refCombo.select(0);
306 }
307
308 /**
309 * Returns the error message label.
310 *
311 * @return the error message label
312 * @deprecated use setErrorMessage(String) instead
313 */
314 protected Label getErrorMessageLabel() {
315 return null;
316 }
317
318 /**
319 * Returns the ok button.
320 *
321 * @return the ok button
322 */
323 protected Button getOkButton() {
324 return okButton;
325 }
326
327 /**
328 * Returns the text area.
329 *
330 * @return the text area
331 */
332 protected Text getText() {
333 return refText;
334 }
335
336 /**
337 * Returns the validator.
338 *
339 * @return the validator
340 */
341 protected IInputValidator getValidator() {
342 return validator;
343 }
344
345 /**
346 * Validates the input.
347 * <p>
348 * The default implementation of this framework method delegates the request
349 * to the supplied input validator object; if it finds the input invalid,
350 * the error message is displayed in the dialog's message line. This hook
351 * method is called whenever the text changes in the input field.
352 * </p>
353 */
354 protected void validateInput() {
355 String errorMessage = null;
356 if (validator != null) {
357 errorMessage = validator.isValid(refText.getText());
358 }
359 // Bug 16256: important not to treat "" (blank error) the same as null
360 // (no error)
361 setErrorMessage(errorMessage);
362 }
363
364 /**
365 * Sets or clears the error message.
366 * If not <code>null</code>, the OK button is disabled.
367 *
368 * @param errorMessage
369 * the error message, or <code>null</code> to clear
370 * @since 3.0
371 */
372 public void setErrorMessage(String errorMessage) {
373 this.errorMessage = errorMessage;
374 if (errorMessageText != null && !errorMessageText.isDisposed()) {
375 errorMessageText.setText(errorMessage == null ? " \n " : errorMessage); //$NON-NLS-1$
376 // Disable the error message text control if there is no error, or
377 // no error text (empty or whitespace only). Hide it also to avoid
378 // color change.
379 // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=130281
380 boolean hasError = errorMessage != null && (StringConverter.removeWhiteSpaces(errorMessage)).length() > 0;
381 errorMessageText.setEnabled(hasError);
382 errorMessageText.setVisible(hasError);
383 errorMessageText.getParent().update();
384 // Access the ok button by id, in case clients have overridden button creation.
385 // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=113643
386 Control button = getButton(IDialogConstants.OK_ID);
387 if (button != null) {
388 button.setEnabled(errorMessage == null);
389 }
390 }
391 }
392
393 /**
394 * Returns the style bits that should be used for the input text field.
395 * Defaults to a single line entry. Subclasses may override.
396 *
397 * @return the integer style bits that should be used when creating the
398 * input text
399 *
400 * @since 3.4
401 */
402 protected int getInputTextStyle() {
403 return SWT.SINGLE | SWT.BORDER;
404 }
405
406 /**
407 * @return
408 */
409 public ReferenceBase getReference() {
410 return reference;
411 }
412 }