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
45 public class ConfigureMilestoneWizard extends Wizard {
46
47
48 private final UserAdminService userAdminService;
49 private final TrackerService trackerService;
50 private final Node project;
51 private final Node milestone;
52
53
54 private Node chosenProject;
55
56
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
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
212
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
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 }