Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 133764
Collapse All | Expand All

(-)plugin.xml (+14 lines)
Lines 33-37 Link Here
33
		 </description>
33
		 </description>
34
      </decorator>
34
      </decorator>
35
   </extension>
35
   </extension>
36
   <extension
37
         point="org.eclipse.ui.editors">
38
      <editor
39
            class="org.eclipse.mylar.internal.jira.ui.JiraTaskEditor"
40
            default="false"
41
            id="org.eclipse.mylar.jira.JiraTaskEditor"
42
            name="Jira Task Editor"/>
43
   </extension>
44
   <extension
45
         point="org.eclipse.mylar.tasklist.editors">
46
      <editorFactory
47
            class="org.eclipse.mylar.internal.jira.ui.JiraTaskEditorFactory"
48
            id="org.eclipse.mylar.jira.ui.JiraTaskEditorFactory"/>
49
   </extension>
36
50
37
</plugin>
51
</plugin>
(-)src/org/eclipse/mylar/internal/jira/JiraServerFacade.java (-11 / +2 lines)
Lines 20-26 Link Here
20
import org.eclipse.mylar.provisional.tasklist.TaskRepository;
20
import org.eclipse.mylar.provisional.tasklist.TaskRepository;
21
import org.tigris.jira.core.JiraCorePlugin;
21
import org.tigris.jira.core.JiraCorePlugin;
22
import org.tigris.jira.core.ServerManager;
22
import org.tigris.jira.core.ServerManager;
23
import org.tigris.jira.core.service.CachedRpcJiraServer;
24
import org.tigris.jira.core.service.JiraServer;
23
import org.tigris.jira.core.service.JiraServer;
25
import org.tigris.jira.core.service.exceptions.AuthenticationException;
24
import org.tigris.jira.core.service.exceptions.AuthenticationException;
26
import org.tigris.jira.core.service.exceptions.ServiceUnavailableException;
25
import org.tigris.jira.core.service.exceptions.ServiceUnavailableException;
Lines 57-63 Link Here
57
						repository.getUserName(), repository.getPassword());
56
						repository.getUserName(), repository.getPassword());
58
				serverManager.addServer(server);
57
				serverManager.addServer(server);
59
			}
58
			}
60
			server.login();
61
			return server;
59
			return server;
62
		} catch (ServiceUnavailableException sue) {
60
		} catch (ServiceUnavailableException sue) {
63
			throw sue;
61
			throw sue;
Lines 117-127 Link Here
117
		String serverHostname = getServerHost(repository);
115
		String serverHostname = getServerHost(repository);
118
		JiraServer server = serverManager.getServer(serverHostname);
116
		JiraServer server = serverManager.getServer(serverHostname);
119
		if (server != null) {
117
		if (server != null) {
120
			removeServer(server);
118
			server.refreshDetails();
121
			server = serverManager.createServer(serverHostname, repository.getUrl(), false,
122
					repository.getUserName(), repository.getPassword());
123
			serverManager.addServer(server);
124
			server.login(); 
125
		}
119
		}
126
	}
120
	}
127
	
121
	
Lines 135-144 Link Here
135
	/** Returns true if all of the serverURL, user name, and password are valid */
129
	/** Returns true if all of the serverURL, user name, and password are valid */
136
	public boolean validateServerAndCredentials(String serverUrl, String user, String password) {
130
	public boolean validateServerAndCredentials(String serverUrl, String user, String password) {
137
		try {
131
		try {
138
			// TODO: use test method on ServerManager
132
			serverManager.testConnection(serverUrl, user, password);
139
			CachedRpcJiraServer jiraServer = new CachedRpcJiraServer("ConnectionTest", serverUrl, false, user, password);
140
			jiraServer.login();
141
			jiraServer.logout();
142
		} catch (Exception e) {
133
		} catch (Exception e) {
143
			return false;
134
			return false;
144
		}
135
		}
(-)src/org/eclipse/mylar/internal/jira/JiraQueryHit.java (-1 / +1 lines)
Lines 47-53 Link Here
47
			if (existingTask instanceof JiraTask) {
47
			if (existingTask instanceof JiraTask) {
48
				task = (JiraTask) existingTask;
48
				task = (JiraTask) existingTask;
49
			} else { 
49
			} else { 
50
				task = new JiraTask(getHandleIdentifier(), description, true);
50
				task = new JiraTask(getHandleIdentifier(), issue.getKey(), description, true);
51
				MylarTaskListPlugin.getTaskListManager().getTaskList().addTask(task);
51
				MylarTaskListPlugin.getTaskListManager().getTaskList().addTask(task);
52
			}
52
			}
53
		}
53
		}
(-)src/org/eclipse/mylar/internal/jira/JiraTaskExternalizer.java (-1 / +11 lines)
Lines 64-69 Link Here
64
	private static final String KEY_FILTER_DESCRIPTION = "FilterDesc";
64
	private static final String KEY_FILTER_DESCRIPTION = "FilterDesc";
65
65
66
	private static final String KEY_FILTER_CUSTOM = "FilterCustom";
66
	private static final String KEY_FILTER_CUSTOM = "FilterCustom";
67
	
68
	private static final String KEY_KEY = "Key";
67
69
68
	
70
	
69
	public boolean canReadQuery(Node node) {
71
	public boolean canReadQuery(Node node) {
Lines 204-209 Link Here
204
	
206
	
205
	public Element createTaskElement(ITask task, Document doc, Element parent) {
207
	public Element createTaskElement(ITask task, Document doc, Element parent) {
206
		Element node = super.createTaskElement(task, doc, parent);
208
		Element node = super.createTaskElement(task, doc, parent);
209
		
210
		node.setAttribute(KEY_KEY, ((JiraTask)task).getKey());
207
		return node; 
211
		return node; 
208
	}
212
	}
209
213
Lines 214-219 Link Here
214
		Element element = (Element) node;
218
		Element element = (Element) node;
215
		String handle;
219
		String handle;
216
		String label;
220
		String label;
221
		String key;
217
		if (element.hasAttribute(KEY_HANDLE)) {
222
		if (element.hasAttribute(KEY_HANDLE)) {
218
			handle = element.getAttribute(KEY_HANDLE);
223
			handle = element.getAttribute(KEY_HANDLE);
219
		} else {
224
		} else {
Lines 224-230 Link Here
224
		} else {
229
		} else {
225
			throw new TaskExternalizationException("Description not stored for bug report");
230
			throw new TaskExternalizationException("Description not stored for bug report");
226
		}
231
		}
227
		JiraTask task = new JiraTask(handle, label, false);  
232
		if (element.hasAttribute(KEY_KEY)) {
233
			key = element.getAttribute(KEY_KEY);
234
		} else {
235
			throw new TaskExternalizationException("Key not stored on bug report");
236
		}
237
		JiraTask task = new JiraTask(handle, key, label, false);  
228
		readTaskInfo(task, taskList, element, parent, category);
238
		readTaskInfo(task, taskList, element, parent, category);
229
 
239
 
230
		// TODO: remove, should be done by readTaskInfo
240
		// TODO: remove, should be done by readTaskInfo
(-)src/org/eclipse/mylar/internal/jira/MylarJiraPlugin.java (-1 / +12 lines)
Lines 12-17 Link Here
12
package org.eclipse.mylar.internal.jira;
12
package org.eclipse.mylar.internal.jira;
13
13
14
import org.eclipse.jface.resource.ImageDescriptor;
14
import org.eclipse.jface.resource.ImageDescriptor;
15
import org.eclipse.jface.resource.ImageRegistry;
15
import org.eclipse.ui.plugin.AbstractUIPlugin;
16
import org.eclipse.ui.plugin.AbstractUIPlugin;
16
import org.osgi.framework.BundleContext;
17
import org.osgi.framework.BundleContext;
17
18
Lines 62-67 Link Here
62
	 * @return the image descriptor
63
	 * @return the image descriptor
63
	 */
64
	 */
64
	public static ImageDescriptor getImageDescriptor(String path) {
65
	public static ImageDescriptor getImageDescriptor(String path) {
65
		return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.mylar.sandbox.jira", path);
66
		return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.mylar.jira", path);
67
	}
68
69
	/* (non-Javadoc)
70
	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry)
71
	 */
72
	@Override
73
	protected void initializeImageRegistry(ImageRegistry reg) {
74
		reg.put("icons/obj16/comment.gif", getImageDescriptor("icons/obj16/comment.gif"));
75
		reg.put("icons/obj16/jira.png", getImageDescriptor("icons/obj16/jira.png"));
76
		
66
	}
77
	}
67
}
78
}
(-)src/org/eclipse/mylar/internal/jira/JiraTask.java (-1 / +11 lines)
Lines 20-25 Link Here
20
 */
20
 */
21
public class JiraTask extends AbstractRepositoryTask {
21
public class JiraTask extends AbstractRepositoryTask {
22
22
23
	private final String key;
24
23
	public enum PriorityLevel {
25
	public enum PriorityLevel {
24
		BLOCKER, CRITICAL, MAJOR, MINOR, TRIVIAL;
26
		BLOCKER, CRITICAL, MAJOR, MINOR, TRIVIAL;
25
27
Lines 87-94 Link Here
87
	/**
89
	/**
88
	 * The handle is also the task's Jira url
90
	 * The handle is also the task's Jira url
89
	 */
91
	 */
90
	public JiraTask(String handle, String label, boolean newTask) {
92
	public JiraTask(String handle, String key, String label, boolean newTask) {
91
		super(handle, label, newTask);
93
		super(handle, label, newTask);
94
		this.key = key;
92
	}
95
	}
93
96
94
	@Override
97
	@Override
Lines 104-107 Link Here
104
	public String getRepositoryKind() {
107
	public String getRepositoryKind() {
105
		return MylarJiraPlugin.REPOSITORY_KIND;
108
		return MylarJiraPlugin.REPOSITORY_KIND;
106
	}
109
	}
110
	
111
	/**
112
	 * @return the key
113
	 */
114
	public String getKey() {
115
		return this.key;
116
	}
107
}
117
}
(-)META-INF/MANIFEST.MF (-1 / +2 lines)
Lines 13-19 Link Here
13
 org.eclipse.mylar.tasklist,
13
 org.eclipse.mylar.tasklist,
14
 org.eclipse.mylar.core,
14
 org.eclipse.mylar.core,
15
 org.tigris.jira.core;bundle-version="[0.8.0,1.0.0)",
15
 org.tigris.jira.core;bundle-version="[0.8.0,1.0.0)",
16
 org.tigris.jira.core.soap;bundle-version="[0.8.0,1.0.0)"
16
 org.tigris.jira.core.soap;bundle-version="[0.8.0,1.0.0)",
17
 org.eclipse.ui.forms
17
Eclipse-AutoStart: true
18
Eclipse-AutoStart: true
18
Bundle-RequiredExecutionEnvironment: J2SE-1.5
19
Bundle-RequiredExecutionEnvironment: J2SE-1.5
19
Export-Package: org.eclipse.mylar.internal.jira,
20
Export-Package: org.eclipse.mylar.internal.jira,
(-)src/org/eclipse/mylar/internal/jira/ui/JiraTaskEditorFactory.java (+56 lines)
Added Link Here
1
package org.eclipse.mylar.internal.jira.ui;
2
3
import org.eclipse.mylar.internal.jira.JiraTask;
4
import org.eclipse.mylar.internal.tasklist.ui.ITaskEditorFactory;
5
import org.eclipse.mylar.internal.tasklist.ui.editors.MylarTaskEditor;
6
import org.eclipse.mylar.provisional.tasklist.ITask;
7
import org.eclipse.ui.IEditorInput;
8
import org.eclipse.ui.IEditorPart;
9
10
public class JiraTaskEditorFactory implements ITaskEditorFactory {
11
12
	public JiraTaskEditorFactory() {
13
	}
14
15
	/* (non-Javadoc)
16
	 * @see org.eclipse.mylar.internal.tasklist.ui.ITaskEditorFactory#canCreateEditorFor(org.eclipse.mylar.provisional.tasklist.ITask)
17
	 */
18
	public boolean canCreateEditorFor(ITask task) {
19
		return task instanceof JiraTask;
20
	}
21
22
	/* (non-Javadoc)
23
	 * @see org.eclipse.mylar.internal.tasklist.ui.ITaskEditorFactory#createEditor(org.eclipse.mylar.internal.tasklist.ui.editors.MylarTaskEditor)
24
	 */
25
	public IEditorPart createEditor(MylarTaskEditor parentEditor) {
26
		return new JiraTaskEditor();
27
	}
28
29
	/* (non-Javadoc)
30
	 * @see org.eclipse.mylar.internal.tasklist.ui.ITaskEditorFactory#createEditorInput(org.eclipse.mylar.provisional.tasklist.ITask)
31
	 */
32
	public IEditorInput createEditorInput(ITask task) {
33
		return new JiraIssueEditorInput((JiraTask) task);
34
	}
35
36
	/* (non-Javadoc)
37
	 * @see org.eclipse.mylar.internal.tasklist.ui.ITaskEditorFactory#getTitle()
38
	 */
39
	public String getTitle() {
40
		return "Jira";
41
	}
42
43
	/* (non-Javadoc)
44
	 * @see org.eclipse.mylar.internal.tasklist.ui.ITaskEditorFactory#notifyEditorActivationChange(org.eclipse.ui.IEditorPart)
45
	 */
46
	public void notifyEditorActivationChange(IEditorPart editor) {
47
	}
48
49
	/* (non-Javadoc)
50
	 * @see org.eclipse.mylar.internal.tasklist.ui.ITaskEditorFactory#providesOutline()
51
	 */
52
	public boolean providesOutline() {
53
		return true;
54
	}
55
56
}
(-)icons/obj16/comment.gif (+2 lines)
Added Link Here
1
GIF89a³3ŒÅääå{»å‰‰‰ÌÌÌ»»»xxxäÿÿ¯¯®¨ÔÿöööÜÝÜÿÿÿÿñÜÆÅÅÿÿÿ!ù,_ðdª­B  GhL(2Â!x[lK‰I)t`ßíÿ
2
`èÑÈ$ÒWñ-žÐ'Ó¨Àᦾ‚v«enh.Wmã	Åò«lðøƒj@ÈïsZïíùrvx;
(-)src/org/eclipse/mylar/internal/jira/ui/JiraTaskEditor.java (+429 lines)
Added Link Here
1
package org.eclipse.mylar.internal.jira.ui;
2
3
import java.text.DateFormat;
4
import java.util.HashMap;
5
import java.util.Map;
6
7
import org.eclipse.core.runtime.IProgressMonitor;
8
import org.eclipse.jface.layout.GridDataFactory;
9
import org.eclipse.jface.resource.JFaceResources;
10
import org.eclipse.jface.wizard.WizardDialog;
11
import org.eclipse.mylar.internal.jira.JiraServerFacade;
12
import org.eclipse.mylar.internal.jira.JiraTask;
13
import org.eclipse.mylar.internal.jira.MylarJiraPlugin;
14
import org.eclipse.mylar.internal.tasklist.ui.editors.MylarTaskEditor;
15
import org.eclipse.mylar.provisional.tasklist.AbstractRepositoryTask;
16
import org.eclipse.mylar.provisional.tasklist.MylarTaskListPlugin;
17
import org.eclipse.mylar.provisional.tasklist.TaskRepository;
18
import org.eclipse.swt.SWT;
19
import org.eclipse.swt.custom.CLabel;
20
import org.eclipse.swt.custom.ScrolledComposite;
21
import org.eclipse.swt.events.ControlAdapter;
22
import org.eclipse.swt.events.ControlEvent;
23
import org.eclipse.swt.events.ModifyEvent;
24
import org.eclipse.swt.events.ModifyListener;
25
import org.eclipse.swt.events.SelectionAdapter;
26
import org.eclipse.swt.events.SelectionEvent;
27
import org.eclipse.swt.graphics.Font;
28
import org.eclipse.swt.graphics.Image;
29
import org.eclipse.swt.graphics.Point;
30
import org.eclipse.swt.layout.FillLayout;
31
import org.eclipse.swt.layout.GridData;
32
import org.eclipse.swt.layout.GridLayout;
33
import org.eclipse.swt.widgets.Composite;
34
import org.eclipse.swt.widgets.Control;
35
import org.eclipse.swt.widgets.Label;
36
import org.eclipse.swt.widgets.Link;
37
import org.eclipse.swt.widgets.Text;
38
import org.eclipse.ui.IEditorInput;
39
import org.eclipse.ui.IEditorSite;
40
import org.eclipse.ui.PartInitException;
41
import org.eclipse.ui.forms.events.ExpansionAdapter;
42
import org.eclipse.ui.forms.events.ExpansionEvent;
43
import org.eclipse.ui.forms.events.IExpansionListener;
44
import org.eclipse.ui.forms.widgets.ExpandableComposite;
45
import org.eclipse.ui.forms.widgets.Form;
46
import org.eclipse.ui.forms.widgets.FormToolkit;
47
import org.eclipse.ui.forms.widgets.ImageHyperlink;
48
import org.eclipse.ui.forms.widgets.ScrolledForm;
49
import org.eclipse.ui.forms.widgets.Section;
50
import org.eclipse.ui.internal.forms.widgets.FormUtil;
51
import org.eclipse.ui.part.EditorPart;
52
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
53
import org.tigris.jira.core.model.Comment;
54
import org.tigris.jira.core.model.Issue;
55
import org.tigris.jira.core.model.Status;
56
import org.tigris.jira.core.service.JiraServer;
57
58
/**
59
 * @author Brock Janiczak
60
 */
61
public class JiraTaskEditor extends EditorPart {
62
63
	private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);
64
	
65
	private JiraIssueEditorInput input;
66
	private Text comment;
67
	private boolean isDirty = false;
68
	private Image commentImage;
69
	private Font commentFont;
70
	
71
	private Map commentToControlMap = new HashMap();
72
73
	private JiraServer server;
74
	private Issue issue;
75
76
	private ScrolledComposite sc;
77
78
	private Section commentsSection;
79
	
80
	/**
81
	 * 
82
	 */
83
	public JiraTaskEditor() {
84
//		commentImage = MylarJiraPlugin.getImageDescriptor("icons/ctool16/comment.gif").createImage();
85
//		commentFont = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT);
86
	}
87
	
88
	/* (non-Javadoc)
89
	 * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
90
	 */
91
	public void doSave(IProgressMonitor monitor) {
92
		server.addCommentToIssue(issue, comment.getText());
93
		comment.setText("");
94
		isDirty = false;
95
	}
96
97
	/* (non-Javadoc)
98
	 * @see org.eclipse.ui.part.EditorPart#doSaveAs()
99
	 */
100
	public void doSaveAs() {
101
	}
102
103
	/* (non-Javadoc)
104
	 * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
105
	 */
106
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
107
		this.input = (JiraIssueEditorInput)input;
108
		setSite(site);
109
		setInput(input);
110
		setPartName(this.input.getName());
111
		JiraTask task = this.input.getTask();
112
		TaskRepository repository = MylarTaskListPlugin.getRepositoryManager().getRepository(task.getRepositoryKind(), task.getRepositoryUrl());
113
		server = JiraServerFacade.getDefault().getJiraServer(repository);
114
		issue = server.getIssue(task.getKey());
115
		
116
	}
117
118
	/* (non-Javadoc)
119
	 * @see org.eclipse.ui.part.EditorPart#isDirty()
120
	 */
121
	public boolean isDirty() {
122
		int charCount = comment.getCharCount();
123
		isDirty = charCount > 0;
124
		return isDirty;
125
	}
126
127
	/* (non-Javadoc)
128
	 * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
129
	 */
130
	public boolean isSaveAsAllowed() {
131
		return false;
132
	}
133
134
	
135
	/* (non-Javadoc)
136
	 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
137
	 */
138
	public void createPartControl(Composite parent) {
139
		FormToolkit toolkit = new FormToolkit(getSite().getShell().getDisplay());
140
		
141
		Form form = toolkit.createForm(parent);
142
		form.setText(issue.getKey() + ": " + issue.getSummary());
143
		
144
		GridLayout formLayout = new GridLayout(1, true);
145
		
146
		final Composite formBody = form.getBody();
147
		formBody.setLayout(formLayout);
148
		
149
		Section summarySection = toolkit.createSection(formBody, ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE);
150
		summarySection.setText("Summary");
151
		summarySection.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
152
		
153
		Composite summary = toolkit.createComposite(summarySection);
154
		summary.setLayout(new GridLayout(6, false));
155
156
		Label lblCreated = toolkit.createLabel(summary, "Created:");
157
		lblCreated.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
158
		Label created = toolkit.createLabel(summary, DATE_FORMAT.format(issue.getCreated()));
159
		
160
		Label lblUpdated = toolkit.createLabel(summary, "Updated:");
161
		lblUpdated.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
162
		Label updated = toolkit.createLabel(summary, DATE_FORMAT.format(issue.getUpdated()));
163
		
164
		if (issue.getDue() != null) {
165
			Label lblDue= toolkit.createLabel(summary, "Due:");
166
			lblDue.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
167
			Label due= toolkit.createLabel(summary, DATE_FORMAT.format(issue.getDue()));
168
		} else {
169
			Label spacer = toolkit.createLabel(summary, "");
170
			spacer.setLayoutData(GridDataFactory.fillDefaults().span(2,1).create());
171
		}
172
		
173
		
174
		Label lblStatus = toolkit.createLabel(summary, "Status:");
175
		lblStatus.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
176
		Label status = toolkit.createLabel(summary, issue.getStatus().getName());
177
		
178
		Label lblResolution = toolkit.createLabel(summary, "Resolution:");
179
		lblResolution.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
180
		if (issue.getResolution() != null) {
181
			Label resolution = toolkit.createLabel(summary, issue.getResolution().getName());
182
			resolution.setToolTipText(issue.getResolution().getDescription());
183
		} else {
184
			Label resolution = toolkit.createLabel(summary, "Unresolved");
185
		}
186
187
		Label lblPriority = toolkit.createLabel(summary, "Priority:");
188
		lblPriority.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
189
		if (issue.getPriority() != null) {
190
			Label priority = toolkit.createLabel(summary, issue.getPriority().getName());
191
			priority.setToolTipText(issue.getPriority().getDescription());
192
		} else {
193
			Label priority = toolkit.createLabel(summary, "No Priority");
194
		}
195
	
196
		Label lblReporter = toolkit.createLabel(summary, "Reporter:");
197
		lblReporter.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
198
		Label reporter = toolkit.createLabel(summary, issue.getReporter());
199
		
200
		Label lblAssignee = toolkit.createLabel(summary, "Assignee");
201
		lblAssignee.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
202
		Label assignee = toolkit.createLabel(summary, issue.getAssignee());
203
		
204
		// spacer
205
		Label spacer2 = toolkit.createLabel(summary, "");
206
		spacer2.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).create());
207
		
208
		StringBuffer sbComponents = new StringBuffer();
209
		if (issue.getComponents().length > 0) {
210
			for (int i = 0; i < issue.getComponents().length; i++) {
211
				if (i != 0) {
212
					sbComponents.append(", ");
213
				}
214
				
215
				sbComponents.append(issue.getComponents()[i].getName());
216
			}
217
		} else {
218
			sbComponents.append("None");
219
		}
220
		
221
		Label lblComponents = toolkit.createLabel(summary, "Components");
222
		lblComponents.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
223
		Label components = toolkit.createLabel(summary, sbComponents.toString());
224
		
225
		
226
		StringBuffer sbAffectsVersions = new StringBuffer();
227
		if (issue.getReportedVersions().length > 0) {
228
			for (int i = 0; i < issue.getReportedVersions().length; i++) {
229
				if (i != 0) {
230
					sbAffectsVersions.append(", ");
231
				}
232
				
233
				sbAffectsVersions.append(issue.getReportedVersions()[i].getName());
234
			}
235
		} else {
236
			sbAffectsVersions.append("None");
237
		}
238
		
239
		Label lblAffectsVersion = toolkit.createLabel(summary, "Affects Versions");
240
		lblAffectsVersion.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
241
		Label affectsVersions = toolkit.createLabel(summary, sbAffectsVersions.toString());
242
		
243
		
244
		StringBuffer sbFixVersions = new StringBuffer();
245
		if (issue.getFixVersions().length > 0) {
246
			for (int i = 0; i < issue.getFixVersions().length; i++) {
247
				if (i != 0) {
248
					sbFixVersions.append(", ");
249
				}
250
				
251
				sbFixVersions.append(issue.getFixVersions()[i].getName());
252
			}
253
		} else {
254
			sbFixVersions.append("None");
255
		}
256
		
257
		Label lblFixVersions = toolkit.createLabel(summary, "Fix Versions");
258
		lblFixVersions.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
259
		Label fixVersions = toolkit.createLabel(summary, sbFixVersions.toString());
260
		
261
		summarySection.setClient(summary);
262
		
263
		// created, updated, due (optional)
264
		
265
		final Section descriptionSection = toolkit.createSection(formBody, ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE);
266
		descriptionSection.setExpanded(true);
267
		descriptionSection.setText("Description");
268
		final GridData dgd = GridDataFactory.fillDefaults().grab(true, false).create();
269
		descriptionSection.setLayoutData(dgd);
270
		
271
		Composite c = toolkit.createComposite(descriptionSection);
272
		GridLayout gl = new GridLayout(1, true);
273
		gl.marginHeight = 0;
274
		gl.marginWidth = 0;
275
		c.setLayout(gl);
276
		
277
		Text description = toolkit.createText(c, issue.getDescription(), SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
278
		description.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).minSize(200, 80).hint(200, 80).create());
279
		
280
		description.setText(issue.getDescription());
281
		description.setEditable(false);
282
		description.setFont(JFaceResources.getTextFont());
283
		descriptionSection.setClient(c);
284
		
285
		commentsSection = toolkit.createSection(formBody, ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE);
286
		commentsSection.setExpanded(true);
287
		ImageHyperlink sortOrder = toolkit.createImageHyperlink(commentsSection, SWT.NONE);
288
		sortOrder.setText("Direction");
289
		
290
		commentsSection.setTextClient(sortOrder);
291
		commentsSection.setText("Comments");
292
		commentsSection.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
293
294
		sc = new ScrolledComposite(commentsSection, SWT.H_SCROLL | SWT.V_SCROLL);
295
		sc.setExpandHorizontal(true);
296
        sc.setExpandVertical(true);
297
        
298
		sc.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
299
		
300
		final Composite c1 = toolkit.createComposite(sc);
301
		GridLayout commentsLayout = new GridLayout(1, true);
302
		commentsLayout.marginWidth = 0;
303
		commentsLayout.marginHeight = 0;
304
		
305
		c1.setLayout(commentsLayout);
306
		
307
		for (int i = 0; i < issue.getComments().length; i++) {
308
			Comment comment = issue.getComments()[i];
309
			
310
			ExpandableComposite expandableComposite = toolkit.createExpandableComposite(c1, ExpandableComposite.TREE_NODE);
311
			expandableComposite.setText("Comment by " + comment.getAuthor() + " [" + DATE_FORMAT.format(comment.getCreated()) + "]");
312
			expandableComposite.setLayout(new FillLayout(SWT.HORIZONTAL));
313
			expandableComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
314
			
315
			Text t = toolkit.createText(expandableComposite, comment.getComment(), SWT.MULTI | SWT.WRAP);
316
			t.setEditable(false);
317
			t.setFont(JFaceResources.getTextFont());
318
			
319
			expandableComposite.setClient(t);
320
			expandableComposite.addExpansionListener(new ExpansionAdapter() {
321
			
322
				@Override
323
				public void expansionStateChanged(ExpansionEvent e) {
324
					sc.layout(true, true);
325
				}
326
			
327
			});
328
			commentToControlMap.put(comment, expandableComposite);
329
			
330
			t.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
331
			
332
			if (i == issue.getComments().length - 1) {
333
				expandableComposite.setExpanded(true);
334
			}
335
		
336
		}
337
		
338
		commentsSection.setClient(sc);
339
		
340
		sc.addControlListener(new ControlAdapter() {
341
			
342
			public void controlResized(ControlEvent e) {
343
				Point size = c1.computeSize(sc.getClientArea().width, SWT.DEFAULT);
344
				sc.setMinSize(size);
345
			}
346
		
347
		});
348
		
349
		final Section commentSection = toolkit.createSection(formBody, ExpandableComposite.TWISTIE | ExpandableComposite.TITLE_BAR);
350
		commentSection.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
351
		commentSection.setText("Add Comment");
352
		commentSection.setExpanded(false);
353
		commentSection.addExpansionListener(new ExpansionAdapter() {
354
		
355
			public void expansionStateChanged(ExpansionEvent e) {
356
				formBody.layout(true);
357
			}
358
		});
359
		
360
		final Composite commentArea = toolkit.createComposite(commentSection);
361
		GridLayout commentAreaLayout = new GridLayout(1, false);
362
		commentAreaLayout.marginHeight = 0;
363
		commentAreaLayout.marginWidth = 0;
364
		commentAreaLayout.verticalSpacing = 0;
365
		commentAreaLayout.horizontalSpacing = 0;
366
		commentArea.setLayout(commentAreaLayout);
367
		
368
		commentSection.setClient(commentArea);
369
		
370
		comment = new Text(commentArea, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
371
		comment.setFont(JFaceResources.getTextFont());
372
		final GridData commentGd = new GridData(SWT.FILL, SWT.FILL, true, false);
373
		commentGd.heightHint = 80;
374
		comment.setLayoutData(commentGd);
375
		
376
		comment.addModifyListener(new ModifyListener() {
377
		
378
			public void modifyText(ModifyEvent e) {
379
				int charCount = comment.getCharCount();
380
				if ((isDirty && charCount == 0) || (!isDirty && charCount > 0)) {
381
					firePropertyChange(PROP_DIRTY);
382
				}
383
			}
384
		
385
		});
386
		sc.setContent(c1);
387
		sc.setMinSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
388
	}
389
390
	public void revealComment(Comment comment) {
391
		Control control = (Control) this.commentToControlMap.get(comment);
392
		if (control != null) {
393
			commentsSection.setExpanded(true);
394
			((ExpandableComposite)control).setExpanded(true);
395
			// XXX Clone or create a new version of this
396
			FormUtil.ensureVisible(sc, control);
397
			sc.layout(true, true);
398
		}
399
	}
400
	
401
	/* (non-Javadoc)
402
	 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
403
	 */
404
	public void setFocus() {
405
	}
406
	
407
	/* (non-Javadoc)
408
	 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
409
	 */
410
	public void dispose() {
411
		super.dispose();
412
//		commentImage.dispose();
413
		
414
		// Don't dispose JFace resources
415
//		commentFont.dispose();
416
	}
417
	
418
	/* (non-Javadoc)
419
	 * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class)
420
	 */
421
	public Object getAdapter(Class adapter) {
422
		if (IContentOutlinePage.class.equals(adapter)) {
423
			return new JiraIssueContentOutlinePage(this, this.issue);
424
		}
425
		
426
		return super.getAdapter(adapter);
427
	}
428
	
429
}
(-)src/org/eclipse/mylar/internal/jira/ui/JiraIssueContentOutlinePage.java (+136 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 Jira Dashboard project.
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
 *    Brock Janiczak - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.mylar.internal.jira.ui;
12
13
import java.text.DateFormat;
14
import java.util.ArrayList;
15
import java.util.Arrays;
16
import java.util.List;
17
18
import org.eclipse.jface.viewers.IOpenListener;
19
import org.eclipse.jface.viewers.IStructuredSelection;
20
import org.eclipse.jface.viewers.ITreeContentProvider;
21
import org.eclipse.jface.viewers.LabelProvider;
22
import org.eclipse.jface.viewers.OpenEvent;
23
import org.eclipse.jface.viewers.TreeViewer;
24
import org.eclipse.jface.viewers.Viewer;
25
import org.eclipse.mylar.internal.jira.MylarJiraPlugin;
26
import org.eclipse.swt.graphics.Image;
27
import org.eclipse.swt.widgets.Composite;
28
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
29
import org.tigris.jira.core.model.Comment;
30
import org.tigris.jira.core.model.Issue;
31
32
/**
33
 * @author Brock Janiczak
34
 */
35
public class JiraIssueContentOutlinePage extends ContentOutlinePage {
36
37
	private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
38
	
39
	private final Issue issue;
40
41
	private Image commentImage;
42
	private Image jiraImage;
43
44
	private final JiraTaskEditor editor;
45
	
46
	public JiraIssueContentOutlinePage(Issue issue) {
47
		this(null, issue);
48
	}
49
	
50
	public JiraIssueContentOutlinePage(JiraTaskEditor editor, Issue issue) {
51
		this.editor = editor;
52
		this.issue = issue;
53
		commentImage = MylarJiraPlugin.getDefault().getImageRegistry().get("icons/obj16/comment.gif");
54
		jiraImage = MylarJiraPlugin.getDefault().getImageRegistry().get("icons/obj16/jira.png");
55
	}
56
	
57
	/* (non-Javadoc)
58
	 * @see org.eclipse.ui.views.contentoutline.ContentOutlinePage#createControl(org.eclipse.swt.widgets.Composite)
59
	 */
60
	public void createControl(Composite parent) {
61
		super.createControl(parent);
62
		
63
		TreeViewer treeViewer = getTreeViewer();
64
		
65
		treeViewer.setContentProvider(new ITreeContentProvider() {
66
		
67
			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
68
			}
69
		
70
			public void dispose() {
71
			}
72
		
73
			public Object[] getElements(Object inputElement) {
74
				List elements = new ArrayList();
75
				elements.add(issue.getSummary());
76
				elements.addAll(Arrays.asList(issue.getComments()));
77
				
78
				// root elements are summary, environment, description and "comments"
79
				
80
				return elements.toArray();
81
			}
82
		
83
			public boolean hasChildren(Object element) {
84
				// "comments" has children
85
				return false;
86
			}
87
		
88
			public Object getParent(Object element) {
89
				return null;
90
			}
91
		
92
			public Object[] getChildren(Object parentElement) {
93
				// Get all of the comments from the comment list
94
				return new Object[0];
95
			}
96
		
97
		});
98
		treeViewer.setLabelProvider(new LabelProvider() {
99
		
100
			public String getText(Object element) {
101
				if (element instanceof Comment) {
102
					Comment comment = (Comment)element;
103
					return DATE_FORMAT.format(comment.getCreated()) + " " + comment.getAuthor();
104
				}
105
				return super.getText(element);
106
			}
107
		
108
			public Image getImage(Object element) {
109
				if (element instanceof Comment) {
110
					return commentImage;
111
				} else {
112
					// TODO the summary should be a placeholder object
113
					return jiraImage;
114
				}
115
			}
116
		
117
		});
118
		
119
		treeViewer.addOpenListener(new IOpenListener() {
120
		
121
			public void open(OpenEvent event) {
122
				if (editor == null) {
123
					return;
124
				}
125
				
126
				Object selection = ((IStructuredSelection)event.getSelection()).getFirstElement();
127
				if (selection instanceof Comment) {
128
					editor.revealComment((Comment)selection);
129
				}
130
			}
131
		
132
		});
133
		treeViewer.setInput(issue);
134
	}
135
	
136
}
(-)src/org/eclipse/mylar/internal/jira/ui/JiraIssueEditorInput.java (+98 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005 Jira Dashboard project.
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
 *    Brock Janiczak - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.mylar.internal.jira.ui;
12
13
import org.eclipse.core.runtime.Platform;
14
import org.eclipse.jface.resource.ImageDescriptor;
15
import org.eclipse.mylar.internal.jira.JiraTask;
16
import org.eclipse.ui.IEditorInput;
17
import org.eclipse.ui.IPersistableElement;
18
19
public class JiraIssueEditorInput implements IEditorInput {
20
21
	private final JiraTask task;
22
23
	public JiraIssueEditorInput(JiraTask task) {
24
		this.task = task;
25
	}
26
	
27
	/* (non-Javadoc)
28
	 * @see org.eclipse.ui.IEditorInput#exists()
29
	 */
30
	public boolean exists() {
31
		return false;
32
	}
33
34
	/* (non-Javadoc)
35
	 * @see org.eclipse.ui.IEditorInput#getImageDescriptor()
36
	 */
37
	public ImageDescriptor getImageDescriptor() {
38
		return null;
39
	}
40
41
	/* (non-Javadoc)
42
	 * @see org.eclipse.ui.IEditorInput#getName()
43
	 */
44
	public String getName() {
45
		return task.getHandleIdentifier();
46
	}
47
48
	/* (non-Javadoc)
49
	 * @see org.eclipse.ui.IEditorInput#getPersistable()
50
	 */
51
	public IPersistableElement getPersistable() {
52
		return null;
53
	}
54
55
	/* (non-Javadoc)
56
	 * @see org.eclipse.ui.IEditorInput#getToolTipText()
57
	 */
58
	public String getToolTipText() {
59
		return task.getDescription();
60
	}
61
62
	/* (non-Javadoc)
63
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
64
	 */
65
	public Object getAdapter(Class adapter) {
66
		return Platform.getAdapterManager().getAdapter(this, adapter);
67
	}
68
	
69
	/* (non-Javadoc)
70
	 * @see java.lang.Object#equals(java.lang.Object)
71
	 */
72
	@Override
73
	public boolean equals(Object obj) {
74
		if (!(obj instanceof JiraIssueEditorInput)) {
75
			return false;
76
		}
77
		
78
		JiraIssueEditorInput that = (JiraIssueEditorInput) obj;
79
		return (this.task.getHandleIdentifier().equals(that.task.getHandleIdentifier()) &&
80
				this.task.getRepositoryUrl().equals(that.task.getRepositoryUrl()));
81
	}
82
	
83
	/* (non-Javadoc)
84
	 * @see java.lang.Object#hashCode()
85
	 */
86
	@Override
87
	public int hashCode() {
88
		return this.task.getHandleIdentifier().hashCode() + this.task.getRepositoryUrl().hashCode();
89
	}
90
	
91
	/**
92
	 * @return the task
93
	 */
94
	public JiraTask getTask() {
95
		return this.task;
96
	}
97
98
}
(-)icons/obj16/jira.png (+5 lines)
Added Link Here
1
‰PNG
2
3
4
IHDR(-SsBITÛáOà<PLTE3fßåìp?©@fŒ¿ÌÙ@pÿÿÿŸ²Å_Ÿ!Mz?¦¼ïòõÏÙâ0YƒPs–¯¿Ï™²ÐÙãï÷÷`€ 0Sè´	pHYsÒÝ~ü tEXtSoftwareMacromedia Fireworks MX»‘*$tEXtCreation Time09/22/04\áýA?IDATxœM?… C;•"QÂýïúÇäGšA¶—¬Ð¥)éÛÁÎyðì:_ èdÎd‡ˆJá”P#jã¢VÁân÷íÞÅ<ZH…È,)´aڞô6û³F¬Æì€®ø6IäX?ÊH‚,`+û,Ŷ?$p©^ã‚ü
5
½…IEND®B`‚

Return to bug 133764