1 package sourceforge.org.qmc2.options.editor.ui.dialogs;
2 
3 import java.util.ArrayList;
4 import java.util.List;
5 
6 import org.eclipse.jface.dialogs.IInputValidator;
7 import org.eclipse.jface.dialogs.IMessageProvider;
8 import org.eclipse.jface.dialogs.InputDialog;
9 import org.eclipse.jface.dialogs.TitleAreaDialog;
10 import org.eclipse.jface.viewers.ArrayContentProvider;
11 import org.eclipse.jface.viewers.ISelection;
12 import org.eclipse.jface.viewers.IStructuredSelection;
13 import org.eclipse.jface.viewers.LabelProvider;
14 import org.eclipse.jface.viewers.TableViewer;
15 import org.eclipse.jface.window.Window;
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.events.ModifyEvent;
18 import org.eclipse.swt.events.ModifyListener;
19 import org.eclipse.swt.events.SelectionAdapter;
20 import org.eclipse.swt.events.SelectionEvent;
21 import org.eclipse.swt.layout.FillLayout;
22 import org.eclipse.swt.layout.GridData;
23 import org.eclipse.swt.layout.GridLayout;
24 import org.eclipse.swt.layout.RowData;
25 import org.eclipse.swt.layout.RowLayout;
26 import org.eclipse.swt.widgets.Button;
27 import org.eclipse.swt.widgets.Combo;
28 import org.eclipse.swt.widgets.Composite;
29 import org.eclipse.swt.widgets.Control;
30 import org.eclipse.swt.widgets.Label;
31 import org.eclipse.swt.widgets.Shell;
32 import org.eclipse.swt.widgets.Text;
33 
34 import sourceforge.org.qmc2.options.editor.model.ComboOption;
35 import sourceforge.org.qmc2.options.editor.model.Option;
36 import sourceforge.org.qmc2.options.editor.model.Option.OptionType;
37 
38 public class AddOptionDialog extends TitleAreaDialog {
39 
40 	private Option option;
41 
42 	private static final String defaultMessage = "Create a new option in QMC2 template file";
43 
44 	private Text optionNameText;
45 
46 	private Text descriptionText;
47 
48 	private Text defaultValueText;
49 
50 	private Combo defaultValueCombo;
51 
52 	private Combo optionType;
53 
54 	private TableViewer viewer;
55 
56 	private List<String> choices = new ArrayList<String>();
57 
AddOptionDialog(Shell parentShell, Option option)58 	public AddOptionDialog(Shell parentShell, Option option) {
59 		super(parentShell);
60 		this.option = option;
61 	}
62 
63 	@Override
createDialogArea(Composite parent)64 	protected Control createDialogArea(Composite parent) {
65 		final Composite mainComposite = new Composite(
66 				(Composite) super.createDialogArea(parent), SWT.NONE);
67 		mainComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
68 		mainComposite.setLayout(new GridLayout(3, false));
69 
70 		Label sectionName = new Label(mainComposite, SWT.NONE);
71 		sectionName.setText("Name: ");
72 		sectionName.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false,
73 				1, 1));
74 
75 		optionNameText = new Text(mainComposite, SWT.BORDER);
76 		optionNameText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true,
77 				false, 2, 1));
78 		if (option != null) {
79 			optionNameText.setText(option.getName());
80 		}
81 		optionNameText.addModifyListener(new ModifyListener() {
82 
83 			@Override
84 			public void modifyText(ModifyEvent arg0) {
85 				validate();
86 			}
87 		});
88 
89 		Label description = new Label(mainComposite, SWT.NONE);
90 		description.setText("Description: ");
91 		description.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false,
92 				1, 1));
93 
94 		descriptionText = new Text(mainComposite, SWT.BORDER);
95 		descriptionText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true,
96 				false, 2, 1));
97 		if (option != null) {
98 			descriptionText.setText(option.getDescription("us"));
99 		}
100 		descriptionText.addModifyListener(new ModifyListener() {
101 
102 			@Override
103 			public void modifyText(ModifyEvent arg0) {
104 				validate();
105 			}
106 		});
107 
108 		Label optionTypeLabel = new Label(mainComposite, SWT.NONE);
109 		optionTypeLabel.setText("Type: ");
110 		optionTypeLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false,
111 				false, 1, 1));
112 
113 		optionType = new Combo(mainComposite, SWT.SINGLE | SWT.READ_ONLY);
114 		optionType.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,
115 				2, 1));
116 		String existingType = "";
117 		if (option != null) {
118 			existingType = option.getType();
119 		}
120 		int index = 0;
121 		for (OptionType type : OptionType.values()) {
122 			if (!type.equals(OptionType.UNKNOWN)) {
123 				String currentType = type.name().toLowerCase();
124 				optionType.add(currentType);
125 				if (currentType.equals(existingType)) {
126 					optionType.select(index);
127 				}
128 				index++;
129 			}
130 		}
131 		if (optionType.getSelectionIndex() < 0) {
132 			optionType.select(0);
133 		}
134 
135 		final Composite viewerArea = new Composite(mainComposite, SWT.NONE);
136 		viewerArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true,
137 				3, 1));
138 		viewerArea.setLayout(new FillLayout());
139 
140 		final Label defaultValueLabel = new Label(mainComposite, SWT.NONE);
141 		defaultValueLabel.setText("Default Value: ");
142 		defaultValueLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false,
143 				false, 1, 1));
144 
145 		defaultValueText = new Text(mainComposite, SWT.BORDER);
146 		defaultValueText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true,
147 				false, 2, 1));
148 		if (option != null) {
149 			defaultValueText.setText(option.getDefaultValue());
150 		}
151 		defaultValueText.addModifyListener(new ModifyListener() {
152 
153 			@Override
154 			public void modifyText(ModifyEvent arg0) {
155 				validate();
156 			}
157 		});
158 
159 		final Label defaultValueLabel2 = new Label(mainComposite, SWT.NONE);
160 		defaultValueLabel2.setText("Default Value: ");
161 		defaultValueLabel2.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false,
162 				false, 1, 1));
163 		defaultValueLabel2.setVisible(false);
164 
165 		defaultValueCombo = new Combo(mainComposite, SWT.BORDER | SWT.READ_ONLY
166 				| SWT.SINGLE);
167 		defaultValueCombo.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true,
168 				false, 2, 1));
169 		if (option != null) {
170 			defaultValueCombo.setText(option.getDefaultValue());
171 		}
172 		defaultValueCombo.addModifyListener(new ModifyListener() {
173 
174 			@Override
175 			public void modifyText(ModifyEvent arg0) {
176 				validate();
177 			}
178 		});
179 		defaultValueCombo.setVisible(false);
180 
181 		optionType.addSelectionListener(new SelectionAdapter() {
182 			@Override
183 			public void widgetSelected(SelectionEvent e) {
184 				if (optionType.getText().equals(
185 						OptionType.COMBO.name().toLowerCase())) {
186 					Composite viewerComposite = new Composite(viewerArea,
187 							SWT.NONE);
188 					viewerComposite.setLayout(new GridLayout(2, false));
189 					createViewer(viewerComposite);
190 					defaultValueLabel2.setVisible(true);
191 					defaultValueCombo.setVisible(true);
192 					defaultValueLabel.setVisible(false);
193 					defaultValueText.setVisible(false);
194 					mainComposite.layout(true, true);
195 					mainComposite.getShell().setSize(
196 							mainComposite.getShell().computeSize(
197 									mainComposite.getShell().getSize().x - 4,
198 									SWT.DEFAULT));
199 				} else {
200 					for (Control child : viewerArea.getChildren()) {
201 						child.dispose();
202 					}
203 					defaultValueLabel2.setVisible(false);
204 					defaultValueCombo.setVisible(false);
205 					defaultValueLabel.setVisible(true);
206 					defaultValueText.setVisible(true);
207 					mainComposite.layout(true, true);
208 					mainComposite.getShell().setSize(
209 							mainComposite.getShell().computeSize(
210 									mainComposite.getShell().getSize().x - 4,
211 									SWT.DEFAULT));
212 				}
213 			}
214 		});
215 
216 		setTitle("Add Option");
217 		setMessage(defaultMessage);
218 
219 		return mainComposite;
220 	}
221 
createViewer(Composite parent)222 	private void createViewer(Composite parent) {
223 		viewer = new TableViewer(parent, SWT.V_SCROLL | SWT.H_SCROLL
224 				| SWT.MULTI | SWT.READ_ONLY | SWT.BORDER);
225 
226 		viewer.getTable().setLayoutData(
227 				new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
228 
229 		Composite buttonsComposite = new Composite(parent, SWT.NONE);
230 		buttonsComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false,
231 				false, 1, 1));
232 		RowLayout rowLayout = new RowLayout(SWT.VERTICAL);
233 		rowLayout.pack = false;
234 		buttonsComposite.setLayout(rowLayout);
235 
236 		viewer.setLabelProvider(new LabelProvider());
237 		viewer.setContentProvider(new ArrayContentProvider());
238 		viewer.setInput(choices);
239 
240 		Button add = new Button(buttonsComposite, SWT.PUSH);
241 		add.setText("Add Choice...");
242 		add.setLayoutData(new RowData());
243 		add.addSelectionListener(new SelectionAdapter() {
244 			public void widgetSelected(SelectionEvent e) {
245 				InputDialog choiceDialog = new InputDialog(getShell(),
246 						"Add choice", "Input choice value", "",
247 						new IInputValidator() {
248 
249 							@Override
250 							public String isValid(String newText) {
251 								String message = null;
252 								if (newText.isEmpty()) {
253 									message = "You must enter a non empty value";
254 								}
255 								return message;
256 							}
257 						});
258 				if (choiceDialog.open() == Window.OK) {
259 					choices.add(choiceDialog.getValue());
260 					viewer.refresh();
261 				}
262 				updateDefaultValueCombo();
263 			};
264 
265 		});
266 
267 		Button remove = new Button(buttonsComposite, SWT.PUSH);
268 		remove.setText("Remove Choice...");
269 		remove.setLayoutData(new RowData());
270 		remove.addSelectionListener(new SelectionAdapter() {
271 			@Override
272 			public void widgetSelected(SelectionEvent e) {
273 				ISelection selection = viewer.getSelection();
274 				if (selection instanceof IStructuredSelection) {
275 					IStructuredSelection sselection = (IStructuredSelection) selection;
276 					for (Object o : sselection.toArray()) {
277 						choices.remove(o);
278 					}
279 					viewer.refresh();
280 				}
281 				updateDefaultValueCombo();
282 			}
283 		});
284 
285 	}
286 
updateDefaultValueCombo()287 	private void updateDefaultValueCombo() {
288 		String selected = defaultValueCombo.getText();
289 		defaultValueCombo.removeAll();
290 		int i = 0;
291 		for (String choice : choices) {
292 			defaultValueCombo.add(choice);
293 			if (choice.equals(selected)) {
294 				defaultValueCombo.select(i);
295 			}
296 			i++;
297 		}
298 		if (defaultValueCombo.getSelectionIndex() < 0) {
299 			defaultValueCombo.select(0);
300 		}
301 	}
302 
validate()303 	private void validate() {
304 		String errorMessage = null;
305 		int errorStatus = IMessageProvider.NONE;
306 		if (optionNameText.getText() == null
307 				|| optionNameText.getText().trim().length() == 0) {
308 			errorMessage = "You must enter a valid section name";
309 			errorStatus = IMessageProvider.ERROR;
310 		} else if (optionNameText.getText().contains(" ")) {
311 			errorMessage = "The section name must not contain whitespaces";
312 			errorStatus = IMessageProvider.ERROR;
313 		}
314 
315 		if (errorMessage == null
316 				&& (descriptionText.getText() == null || descriptionText
317 						.getText().trim().length() == 0)) {
318 			errorMessage = "You must enter a valid description";
319 			errorStatus = IMessageProvider.ERROR;
320 		}
321 
322 		setMessage(errorStatus == IMessageProvider.ERROR ? errorMessage
323 				: defaultMessage, errorStatus);
324 		if (getButton(OK) != null) {
325 			getButton(OK).setEnabled(errorStatus != IMessageProvider.ERROR);
326 		}
327 	}
328 
329 	@Override
isResizable()330 	protected boolean isResizable() {
331 		return true;
332 	}
333 
334 	@Override
okPressed()335 	protected void okPressed() {
336 		if (option == null) {
337 			if (optionType.getText().equals(
338 					OptionType.COMBO.name().toLowerCase())) {
339 				option = new ComboOption(optionNameText.getText(),
340 						optionType.getText(), defaultValueText.getText());
341 				((ComboOption) option).setChoices(choices);
342 			} else {
343 				option = new Option(optionNameText.getText(),
344 						optionType.getText(), defaultValueText.getText());
345 			}
346 		}
347 		option.setName(optionNameText.getText());
348 		option.setDescription("us", descriptionText.getText());
349 		option.setDefaultValue(defaultValueText.getText());
350 		option.setType(optionType.getText());
351 
352 		super.okPressed();
353 	}
354 
getOption()355 	public Option getOption() {
356 		return option;
357 	}
358 
359 }
360