View Javadoc
1   package org.argeo.tracker.e4.parts;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import javax.jcr.Node;
7   import javax.jcr.NodeIterator;
8   import javax.jcr.Property;
9   import javax.jcr.RepositoryException;
10  import javax.jcr.Session;
11  
12  import org.argeo.activities.ActivitiesNames;
13  import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
14  import org.argeo.cms.ui.eclipse.forms.FormToolkit;
15  import org.argeo.cms.ui.eclipse.forms.IManagedForm;
16  import org.argeo.cms.util.CmsUtils;
17  import org.argeo.connect.util.ConnectJcrUtils;
18  import org.argeo.connect.util.XPathUtils;
19  import org.argeo.eclipse.ui.EclipseUiUtils;
20  import org.argeo.jcr.JcrUtils;
21  import org.argeo.tracker.TrackerException;
22  import org.argeo.tracker.TrackerService;
23  import org.argeo.tracker.TrackerTypes;
24  import org.argeo.tracker.ui.TrackerLps;
25  import org.eclipse.jface.viewers.ColumnLabelProvider;
26  import org.eclipse.swt.SWT;
27  import org.eclipse.swt.events.SelectionAdapter;
28  import org.eclipse.swt.events.SelectionEvent;
29  import org.eclipse.swt.layout.GridData;
30  import org.eclipse.swt.layout.GridLayout;
31  import org.eclipse.swt.widgets.Button;
32  import org.eclipse.swt.widgets.Composite;
33  import org.eclipse.swt.widgets.Label;
34  import org.eclipse.swt.widgets.Text;
35  
36  public class CommentListFormPart extends Composite {
37  	private static final long serialVersionUID = -8671301499186962746L;
38  
39  	private final IManagedForm managedForm;
40  	private final TrackerService trackerService;
41  	private final Node task;
42  
43  	public CommentListFormPart(IManagedForm managedForm, Composite parent, int style, TrackerService trackerService,
44  			Node task) {
45  		super(parent, style);
46  		this.managedForm = managedForm;
47  		this.trackerService = trackerService;
48  		this.task = task;
49  
50  		this.setLayout(new GridLayout());
51  		Section section = createCommentSection(this);
52  		section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
53  	}
54  
55  	// THE COMMENT LIST
56  	private Section createCommentSection(Composite parent) {
57  		FormToolkit tk = managedForm.getToolkit();
58  		Section section = TrackerUiUtils.addFormSection(tk, parent, "Comments");
59  
60  		Composite body = ((Composite) section.getClient());
61  		body.setLayout(new GridLayout());
62  		body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
63  
64  		Composite newCommentCmp = new Composite(body, SWT.NO_FOCUS);
65  		newCommentCmp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
66  		GridLayout layout = new GridLayout();
67  		layout.numColumns = 2;
68  		newCommentCmp.setLayout(layout);
69  
70  		// Add a new comment fields
71  		final Text newCommentTxt = new Text(newCommentCmp, SWT.MULTI | SWT.WRAP | SWT.BORDER);
72  		GridData twd = new GridData(SWT.FILL, SWT.FILL, true, true);
73  		twd.heightHint = 200;
74  		newCommentTxt.setLayoutData(twd);
75  
76  		newCommentTxt.setMessage("Enter a new comment...");
77  //		newCommentTxt.addFocusListener(new FocusListener() {
78  //			private static final long serialVersionUID = 1L;
79  //
80  //			@Override
81  //			public void focusLost(FocusEvent event) {
82  //				String currText = newCommentTxt.getText();
83  //				if (EclipseUiUtils.isEmpty(currText)) {
84  //					GridData twd = ((GridData) newCommentTxt.getLayoutData());
85  //					twd.heightHint = SWT.DEFAULT;
86  //					body.layout(true, true);
87  //					managedForm.reflow(true);
88  //				}
89  //			}
90  //
91  //			@Override
92  //			public void focusGained(FocusEvent event) {
93  //				GridData twd = ((GridData) newCommentTxt.getLayoutData());
94  //				twd.heightHint = 200;
95  //				body.layout(true, true);
96  //				managedForm.reflow(true);
97  //			}
98  //		});
99  		Button okBtn = new Button(newCommentCmp, SWT.BORDER | SWT.PUSH | SWT.BOTTOM);
100 		okBtn.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, false));
101 		okBtn.setText("OK");
102 
103 		// Existing comment list
104 		final Composite commentsCmp = new Composite(body, SWT.NO_FOCUS);
105 		commentsCmp.setLayout(new GridLayout());
106 		commentsCmp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
107 
108 		SectionPart part = new SectionPart(section) {
109 
110 			private ColumnLabelProvider lp = new TrackerLps().new IssueCommentOverviewLabelProvider();
111 
112 			@Override
113 			public void refresh() {
114 				if (commentsCmp.isDisposed())
115 					return;
116 				CmsUtils.clear(commentsCmp);
117 
118 				List<Node> comments = getComments();
119 				for (Node comment : comments)
120 					addCommentCmp(commentsCmp, lp, null, comment);
121 
122 				parent.layout(true, true);
123 				super.refresh();
124 			}
125 		};
126 		part.initialize(managedForm);
127 		managedForm.addPart(part);
128 
129 		okBtn.addSelectionListener(new SelectionAdapter() {
130 			private static final long serialVersionUID = -5295361445564398576L;
131 
132 			@Override
133 			public void widgetSelected(SelectionEvent e) {
134 				String newTag = newCommentTxt.getText();
135 				if (EclipseUiUtils.notEmpty(newTag)) {
136 					Session tmpSession = null;
137 					try {
138 						// We use a new session that is saved
139 						String issuePath = task.getPath();
140 						tmpSession = task.getSession().getRepository().login();
141 						Node issueExt = tmpSession.getNode(issuePath);
142 						trackerService.addComment(issueExt, newTag);
143 						tmpSession.save();
144 						task.getSession().refresh(true);
145 					} catch (RepositoryException re) {
146 						throw new TrackerException("Unable to add comment " + newTag + " on " + task, re);
147 					} finally {
148 						JcrUtils.logoutQuietly(tmpSession);
149 					}
150 					part.refresh();
151 					// part.markDirty();
152 				}
153 				// Reset the "new comment" field
154 				newCommentTxt.setText("");
155 				// okBtn.setFocus();
156 				GridData twd = ((GridData) newCommentTxt.getLayoutData());
157 				twd.heightHint = SWT.DEFAULT;
158 				newCommentTxt.getParent().layout(true, true);
159 				managedForm.reflow(true);
160 			}
161 		});
162 		return section;
163 	}
164 
165 	private List<Node> getComments() {
166 		List<Node> comments = new ArrayList<Node>();
167 		try {
168 			StringBuilder builder = new StringBuilder();
169 			builder.append(XPathUtils.descendantFrom(task.getPath()));
170 			builder.append("//element(*, ");
171 			builder.append(TrackerTypes.TRACKER_COMMENT);
172 			builder.append(")");
173 			builder.append("order by @").append(ActivitiesNames.ACTIVITIES_ACTIVITY_DATE);
174 			builder.append(", @").append(Property.JCR_CREATED);
175 			builder.append(" descending");
176 			NodeIterator nit = XPathUtils.createQuery(task.getSession(), builder.toString()).execute().getNodes();
177 			while (nit.hasNext())
178 				comments.add(nit.nextNode());
179 		} catch (RepositoryException re) {
180 			throw new TrackerException("Unable retrieve comments for " + task, re);
181 		}
182 		return comments;
183 	}
184 
185 	private void addCommentCmp(Composite parent, ColumnLabelProvider lp, AbstractFormPart formPart, Node comment) {
186 		// retrieve properties
187 		String description = ConnectJcrUtils.get(comment, Property.JCR_DESCRIPTION);
188 
189 		Composite commentCmp = new Composite(parent, SWT.NO_FOCUS);
190 		commentCmp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
191 		commentCmp.setLayout(new GridLayout());
192 
193 		// First line
194 		Label overviewLabel = new Label(commentCmp, SWT.WRAP);
195 		overviewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
196 		overviewLabel.setText(lp.getText(comment));
197 		overviewLabel.setFont(EclipseUiUtils.getBoldFont(parent));
198 
199 		// Second line: description
200 		Label descLabel = new Label(commentCmp, SWT.WRAP);
201 		descLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
202 		descLabel.setText(description);
203 
204 		// third line: separator
205 		Label sepLbl = new Label(commentCmp, SWT.HORIZONTAL | SWT.SEPARATOR);
206 		sepLbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
207 	}
208 }