View Javadoc
1   package org.argeo.tracker.ui.dialogs;
2   
3   import static javax.jcr.Property.JCR_DESCRIPTION;
4   import static javax.jcr.Property.JCR_TITLE;
5   import static org.argeo.connect.util.ConnectJcrUtils.get;
6   import static org.argeo.eclipse.ui.EclipseUiUtils.isEmpty;
7   
8   import java.util.Calendar;
9   
10  import javax.jcr.Node;
11  import javax.jcr.Property;
12  import javax.jcr.RepositoryException;
13  
14  import org.argeo.connect.UserAdminService;
15  import org.argeo.connect.core.OfficeRole;
16  import org.argeo.connect.ui.ConnectUiUtils;
17  import org.argeo.connect.ui.widgets.DateText;
18  import org.argeo.connect.ui.widgets.GroupDropDown;
19  import org.argeo.connect.util.ConnectJcrUtils;
20  import org.argeo.eclipse.ui.EclipseUiUtils;
21  import org.argeo.jcr.JcrUtils;
22  import org.argeo.tracker.TrackerException;
23  import org.argeo.tracker.TrackerNames;
24  import org.argeo.tracker.TrackerService;
25  import org.argeo.tracker.TrackerTypes;
26  import org.argeo.tracker.ui.controls.ProjectDropDown;
27  import org.eclipse.jface.dialogs.MessageDialog;
28  import org.eclipse.jface.wizard.Wizard;
29  import org.eclipse.jface.wizard.WizardPage;
30  import org.eclipse.swt.SWT;
31  import org.eclipse.swt.events.FocusAdapter;
32  import org.eclipse.swt.events.FocusEvent;
33  import org.eclipse.swt.events.FocusListener;
34  import org.eclipse.swt.events.SelectionAdapter;
35  import org.eclipse.swt.events.SelectionEvent;
36  import org.eclipse.swt.layout.GridData;
37  import org.eclipse.swt.layout.GridLayout;
38  import org.eclipse.swt.widgets.Button;
39  import org.eclipse.swt.widgets.Composite;
40  import org.eclipse.swt.widgets.Control;
41  import org.eclipse.swt.widgets.Label;
42  import org.eclipse.swt.widgets.Text;
43  
44  /** Dialog to simply configure a milestone */
45  public class ConfigureMilestoneWizard extends Wizard {
46  
47  	// Context
48  	private final UserAdminService userAdminService;
49  	private final TrackerService trackerService;
50  	private final Node project;
51  	private final Node milestone;
52  
53  	// Ease implementation
54  	private Node chosenProject;
55  
56  	// UI objects
57  	private ProjectDropDown projectDD;
58  	private Text titleTxt;
59  	private GroupDropDown managerDD;
60  	private GroupDropDown defaultAssigneeDD;
61  	private DateText targetDateCmp;
62  	private Label isVersionLbl;
63  	private Button isVersionBtn;
64  	private Label versionIdLbl;
65  	private Text versionIdTxt;
66  	private Label releaseDateLbl;
67  	private DateText releaseDateCmp;
68  	private Text descTxt;
69  
70  	public ConfigureMilestoneWizard(UserAdminService userAdminService, TrackerService trackerService, Node milestone) {
71  		this.userAdminService = userAdminService;
72  		this.trackerService = trackerService;
73  		this.milestone = milestone;
74  		try {
75  			if (milestone.hasProperty(TrackerNames.TRACKER_PROJECT_UID)) {
76  				project = trackerService.getEntityByUid(milestone.getSession(), null,
77  						milestone.getProperty(TrackerNames.TRACKER_PROJECT_UID).getString());
78  			} else
79  				project = null;
80  		} catch (RepositoryException e) {
81  			throw new TrackerException("Cannot retrieve project for " + milestone, e);
82  		}
83  	}
84  
85  	@Override
86  	public void addPages() {
87  		setWindowTitle("Milestone configuration");
88  		MainPage page = new MainPage("Main page");
89  		addPage(page);
90  	}
91  
92  	@Override
93  	public boolean performFinish() {
94  		String msg = null;
95  		String title = titleTxt.getText();
96  
97  		boolean isVersion = isVersionBtn.getSelection();
98  		String versionId = versionIdTxt != null && !versionIdTxt.isDisposed() ? versionIdTxt.getText() : null;
99  		Calendar releaseDate = releaseDateCmp != null && !releaseDateCmp.isDisposed() ? releaseDateCmp.getCalendar()
100 				: null;
101 		if (chosenProject == null)
102 			msg = "Please pick up a project";
103 		else if (isEmpty(title))
104 			msg = "Please give at least a title";
105 		else if (isVersion && (EclipseUiUtils.isEmpty(versionId) || releaseDate == null)) {
106 			msg = "You have to provide a version ID *and* a release date to mark this milestone as version";
107 		}
108 
109 		if (msg != null) {
110 			MessageDialog.openError(getShell(), "Uncomplete information", msg);
111 			return false;
112 		}
113 
114 		try {
115 			trackerService.configureMilestone(milestone, chosenProject, null, title, descTxt.getText(),
116 					managerDD.getText(), defaultAssigneeDD.getText(), targetDateCmp.getCalendar());
117 
118 			if (isVersion) {
119 				if (!milestone.isNodeType(TrackerTypes.TRACKER_VERSION))
120 					milestone.addMixin(TrackerTypes.TRACKER_VERSION);
121 				milestone.setProperty(TrackerNames.TRACKER_ID, versionId);
122 				milestone.setProperty(TrackerNames.TRACKER_RELEASE_DATE, releaseDate);
123 			}
124 
125 			if (milestone.getSession().hasPendingChanges())
126 				JcrUtils.updateLastModified(milestone);
127 			return true;
128 		} catch (RepositoryException e1) {
129 			throw new TrackerException("Unable to create version with ID " + title + " on " + project, e1);
130 		}
131 	}
132 
133 	@Override
134 	public boolean canFinish() {
135 		if (EclipseUiUtils.isEmpty(titleTxt.getText()) || chosenProject == null)
136 			return false;
137 		else
138 			return true;
139 	}
140 
141 	@Override
142 	public boolean performCancel() {
143 		return true;
144 	}
145 
146 	private class MainPage extends WizardPage {
147 		private static final long serialVersionUID = 3061153468301727903L;
148 
149 		private Text projectTxt;
150 
151 		public MainPage(String pageName) {
152 			super(pageName);
153 			setMessage("Please complete below information");
154 		}
155 
156 		public void createControl(final Composite parent) {
157 			parent.setLayout(new GridLayout(4, false));
158 			FocusListener fl = getFocusListener();
159 
160 			// Project
161 			ConnectUiUtils.createBoldLabel(parent, "Project");
162 			projectTxt = new Text(parent, SWT.BORDER);
163 			projectTxt.setMessage("Choose relevant project");
164 			GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
165 			gd.horizontalSpan = 3;
166 			projectTxt.setLayoutData(gd);
167 
168 			if (project == null) {
169 				projectDD = new ProjectDropDown(ConnectJcrUtils.getSession(milestone), projectTxt, false);
170 
171 				projectTxt.addFocusListener(new FocusAdapter() {
172 					private static final long serialVersionUID = 1719432159240562984L;
173 
174 					@Override
175 					public void focusLost(FocusEvent event) {
176 						Node project = projectDD.getChosenProject();
177 						if (project == null)
178 							setErrorMessage("Choose a valid project");
179 						else {
180 							setErrorMessage(null);
181 							afterProjectSet(project, false);
182 						}
183 					}
184 				});
185 			} else
186 				projectTxt.setEditable(false);
187 
188 			createLabel(parent, "Milestone Name", SWT.CENTER);
189 			titleTxt = new Text(parent, SWT.BORDER);
190 			titleTxt.setMessage("A clear name");
191 			titleTxt.setLayoutData(EclipseUiUtils.fillWidth(3));
192 			titleTxt.addFocusListener(fl);
193 
194 			createLabel(parent, "Manager", SWT.CENTER);
195 			Text managerTxt = new Text(parent, SWT.BORDER);
196 			managerTxt.setMessage("Choose a group");
197 			managerTxt.setLayoutData(EclipseUiUtils.fillWidth());
198 			managerDD = new GroupDropDown(managerTxt, userAdminService, OfficeRole.coworker.dn());
199 
200 			createLabel(parent, "Default Assignee", SWT.CENTER);
201 			Text defaultAssigneeTxt = new Text(parent, SWT.BORDER);
202 			defaultAssigneeTxt.setMessage("Choose a group");
203 			defaultAssigneeTxt.setLayoutData(EclipseUiUtils.fillWidth());
204 			defaultAssigneeDD = new GroupDropDown(defaultAssigneeTxt, userAdminService, OfficeRole.coworker.dn());
205 
206 			createLabel(parent, "Target Date", SWT.CENTER);
207 			targetDateCmp = new DateText(parent, SWT.NO_FOCUS);
208 			targetDateCmp.setLayoutData(EclipseUiUtils.fillWidth());
209 			targetDateCmp.setToolTipText("An optional future due date for this milestone");
210 
211 			// if (ConnectJcrUtils.isNodeType(project,
212 			// TrackerTypes.TRACKER_IT_PROJECT)){
213 			isVersionLbl = createLabel(parent, "Is released version", SWT.CENTER);
214 			isVersionBtn = new Button(parent, SWT.CHECK);
215 
216 			versionIdLbl = createLabel(parent, "Version ID", SWT.CENTER);
217 			versionIdTxt = new Text(parent, SWT.BORDER);
218 			versionIdTxt.setMessage("Major.Minor.Micro: 2.1.37");
219 			versionIdTxt.setToolTipText("The version id syntax must be valid, major and minor are compulsory");
220 			versionIdTxt.setLayoutData(EclipseUiUtils.fillWidth());
221 
222 			releaseDateLbl = createLabel(parent, "Release date", SWT.CENTER);
223 			releaseDateCmp = new DateText(parent, SWT.NO_FOCUS);
224 			releaseDateCmp.setLayoutData(EclipseUiUtils.fillWidth());
225 			releaseDateCmp.setToolTipText("The version's release date");
226 
227 			createLabel(parent, "Description", SWT.TOP);
228 			descTxt = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.WRAP);
229 			gd = EclipseUiUtils.fillWidth(3);
230 			gd.heightHint = 150;
231 			descTxt.setLayoutData(gd);
232 			descTxt.setMessage("An optional description for this milestone");
233 
234 			// Initialise values
235 			String titleStr = get(milestone, JCR_TITLE);
236 			try {
237 				titleTxt.setText(titleStr);
238 				descTxt.setText(get(milestone, JCR_DESCRIPTION));
239 				targetDateCmp.setText(ConnectJcrUtils.getDateValue(milestone, TrackerNames.TRACKER_TARGET_DATE));
240 				if (milestone.hasProperty(TrackerNames.TRACKER_MANAGER))
241 					managerDD.resetDN(milestone.getProperty(TrackerNames.TRACKER_MANAGER).getString());
242 				if (milestone.hasProperty(TrackerNames.TRACKER_DEFAULT_ASSIGNEE))
243 					defaultAssigneeDD.resetDN(milestone.getProperty(TrackerNames.TRACKER_DEFAULT_ASSIGNEE).getString());
244 				if (project != null)
245 					projectTxt.setText(ConnectJcrUtils.get(project, Property.JCR_TITLE));
246 
247 				afterProjectSet(project, ConnectJcrUtils.isNodeType(milestone, TrackerTypes.TRACKER_VERSION));
248 
249 			} catch (RepositoryException e) {
250 				throw new TrackerException("Cannot initialise widgets with existing data for " + milestone, e);
251 			}
252 			if (project == null) {
253 				setControl(projectTxt);
254 				projectTxt.setFocus();
255 			} else if (isEmpty(titleStr)) {
256 				setControl(titleTxt);
257 				titleTxt.setFocus();
258 			} else
259 				setControl(titleTxt);
260 
261 			isVersionBtn.addSelectionListener(new SelectionAdapter() {
262 				private static final long serialVersionUID = -9065523003707104389L;
263 
264 				@Override
265 				public void widgetSelected(SelectionEvent e) {
266 					afterProjectSet(project, isVersionBtn.getSelection());
267 					parent.layout(true, true);
268 				}
269 			});
270 		}
271 
272 		private void afterProjectSet(Node project, boolean isVersion) {
273 			chosenProject = project;
274 			boolean show = chosenProject != null
275 					&& ConnectJcrUtils.isNodeType(project, TrackerTypes.TRACKER_IT_PROJECT);
276 			isVersionLbl.setVisible(show);
277 			isVersionBtn.setVisible(show);
278 			show &= isVersion;
279 
280 			if (ConnectJcrUtils.isNodeType(milestone, TrackerTypes.TRACKER_VERSION)) {
281 				versionIdTxt.setText(ConnectJcrUtils.get(milestone, TrackerNames.TRACKER_ID));
282 				releaseDateCmp.setText(ConnectJcrUtils.getDateValue(milestone, TrackerNames.TRACKER_RELEASE_DATE));
283 			}
284 			showWidget(versionIdLbl, show);
285 			showWidget(versionIdTxt, show);
286 			showWidget(releaseDateLbl, show);
287 			showWidget(releaseDateCmp, show);
288 		}
289 
290 		private void showWidget(Control control, boolean show) {
291 			GridData gd = (GridData) control.getLayoutData();
292 			control.setVisible(show);
293 			if (show)
294 				gd.heightHint = SWT.DEFAULT;
295 			else
296 				gd.heightHint = 0;
297 		}
298 
299 	}
300 
301 	private FocusListener getFocusListener() {
302 		return new FocusAdapter() {
303 			private static final long serialVersionUID = 1L;
304 
305 			@Override
306 			public void focusLost(FocusEvent event) {
307 				getContainer().updateButtons();
308 			}
309 		};
310 	}
311 
312 	private Label createLabel(Composite parent, String label, int verticalAlign) {
313 		Label lbl = new Label(parent, SWT.NONE);
314 		lbl.setText(label);
315 		lbl.setFont(EclipseUiUtils.getBoldFont(parent));
316 		lbl.setLayoutData(new GridData(SWT.LEAD, verticalAlign, false, false));
317 		return lbl;
318 	}
319 }