|
Lines 9-14
Link Here
|
| 9 |
|
9 |
|
| 10 |
import java.lang.reflect.InvocationTargetException; |
10 |
import java.lang.reflect.InvocationTargetException; |
| 11 |
import java.net.MalformedURLException; |
11 |
import java.net.MalformedURLException; |
|
|
12 |
import java.util.ArrayList; |
| 12 |
import java.util.HashMap; |
13 |
import java.util.HashMap; |
| 13 |
import java.util.Map; |
14 |
import java.util.Map; |
| 14 |
|
15 |
|
|
Lines 23-28
Link Here
|
| 23 |
import org.eclipse.mylyn.internal.trac.core.TracRepositoryQuery; |
24 |
import org.eclipse.mylyn.internal.trac.core.TracRepositoryQuery; |
| 24 |
import org.eclipse.mylyn.internal.trac.core.model.TracSearch; |
25 |
import org.eclipse.mylyn.internal.trac.core.model.TracSearch; |
| 25 |
import org.eclipse.mylyn.internal.trac.core.model.TracSearchFilter; |
26 |
import org.eclipse.mylyn.internal.trac.core.model.TracSearchFilter; |
|
|
27 |
import org.eclipse.mylyn.internal.trac.core.model.TracTicketField; |
| 26 |
import org.eclipse.mylyn.internal.trac.core.model.TracSearchFilter.CompareOperator; |
28 |
import org.eclipse.mylyn.internal.trac.core.model.TracSearchFilter.CompareOperator; |
| 27 |
import org.eclipse.mylyn.internal.trac.ui.TracUiPlugin; |
29 |
import org.eclipse.mylyn.internal.trac.ui.TracUiPlugin; |
| 28 |
import org.eclipse.mylyn.monitor.core.StatusHandler; |
30 |
import org.eclipse.mylyn.monitor.core.StatusHandler; |
|
Lines 32-41
Link Here
|
| 32 |
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin; |
34 |
import org.eclipse.mylyn.tasks.ui.TasksUiPlugin; |
| 33 |
import org.eclipse.mylyn.tasks.ui.search.AbstractRepositoryQueryPage; |
35 |
import org.eclipse.mylyn.tasks.ui.search.AbstractRepositoryQueryPage; |
| 34 |
import org.eclipse.swt.SWT; |
36 |
import org.eclipse.swt.SWT; |
|
|
37 |
import org.eclipse.swt.custom.ScrolledComposite; |
| 35 |
import org.eclipse.swt.events.KeyEvent; |
38 |
import org.eclipse.swt.events.KeyEvent; |
| 36 |
import org.eclipse.swt.events.KeyListener; |
39 |
import org.eclipse.swt.events.KeyListener; |
|
|
40 |
import org.eclipse.swt.events.ModifyEvent; |
| 41 |
import org.eclipse.swt.events.ModifyListener; |
| 37 |
import org.eclipse.swt.events.SelectionAdapter; |
42 |
import org.eclipse.swt.events.SelectionAdapter; |
| 38 |
import org.eclipse.swt.events.SelectionEvent; |
43 |
import org.eclipse.swt.events.SelectionEvent; |
|
|
44 |
import org.eclipse.swt.events.SelectionListener; |
| 39 |
import org.eclipse.swt.layout.GridData; |
45 |
import org.eclipse.swt.layout.GridData; |
| 40 |
import org.eclipse.swt.layout.GridLayout; |
46 |
import org.eclipse.swt.layout.GridLayout; |
| 41 |
import org.eclipse.swt.widgets.Button; |
47 |
import org.eclipse.swt.widgets.Button; |
|
Lines 43-51
Link Here
|
| 43 |
import org.eclipse.swt.widgets.Composite; |
49 |
import org.eclipse.swt.widgets.Composite; |
| 44 |
import org.eclipse.swt.widgets.Control; |
50 |
import org.eclipse.swt.widgets.Control; |
| 45 |
import org.eclipse.swt.widgets.Display; |
51 |
import org.eclipse.swt.widgets.Display; |
| 46 |
import org.eclipse.swt.widgets.Group; |
|
|
| 47 |
import org.eclipse.swt.widgets.Label; |
52 |
import org.eclipse.swt.widgets.Label; |
| 48 |
import org.eclipse.swt.widgets.List; |
|
|
| 49 |
import org.eclipse.swt.widgets.Text; |
53 |
import org.eclipse.swt.widgets.Text; |
| 50 |
import org.eclipse.ui.PlatformUI; |
54 |
import org.eclipse.ui.PlatformUI; |
| 51 |
import org.eclipse.ui.progress.IProgressService; |
55 |
import org.eclipse.ui.progress.IProgressService; |
|
Lines 55-60
Link Here
|
| 55 |
* |
59 |
* |
| 56 |
* @author Steffen Pingel |
60 |
* @author Steffen Pingel |
| 57 |
*/ |
61 |
*/ |
|
|
62 |
|
| 58 |
public class TracCustomQueryPage extends AbstractRepositoryQueryPage { |
63 |
public class TracCustomQueryPage extends AbstractRepositoryQueryPage { |
| 59 |
|
64 |
|
| 60 |
private static final String TITLE = "Enter query parameters"; |
65 |
private static final String TITLE = "Enter query parameters"; |
|
Lines 63-78
Link Here
|
| 63 |
|
68 |
|
| 64 |
private static final String TITLE_QUERY_TITLE = "Query Title:"; |
69 |
private static final String TITLE_QUERY_TITLE = "Query Title:"; |
| 65 |
|
70 |
|
| 66 |
private static final String[] DEFAULT_STATUS_SELECTION = new String[] { "new", "assigned", "reopened", }; |
|
|
| 67 |
|
| 68 |
private TracRepositoryQuery query; |
71 |
private TracRepositoryQuery query; |
| 69 |
|
72 |
|
| 70 |
private Text titleText; |
73 |
private Text titleText; |
| 71 |
|
74 |
|
| 72 |
private static final int PRODUCT_HEIGHT = 60; |
|
|
| 73 |
|
| 74 |
private static final int STATUS_HEIGHT = 40; |
| 75 |
|
| 76 |
protected final static String PAGE_NAME = "TracSearchPage"; //$NON-NLS-1$ |
75 |
protected final static String PAGE_NAME = "TracSearchPage"; //$NON-NLS-1$ |
| 77 |
|
76 |
|
| 78 |
private static final String SEARCH_URL_ID = PAGE_NAME + ".SEARCHURL"; |
77 |
private static final String SEARCH_URL_ID = PAGE_NAME + ".SEARCHURL"; |
|
Lines 81-117
Link Here
|
| 81 |
|
80 |
|
| 82 |
protected Combo repositoryCombo = null; |
81 |
protected Combo repositoryCombo = null; |
| 83 |
|
82 |
|
| 84 |
private TextSearchField summaryField; |
|
|
| 85 |
|
| 86 |
private TextSearchField descriptionField; |
| 87 |
|
| 88 |
private ListSearchField componentField; |
| 89 |
|
| 90 |
private ListSearchField versionField; |
| 91 |
|
| 92 |
private ListSearchField milestoneField; |
| 93 |
|
| 94 |
private ListSearchField priorityField; |
| 95 |
|
| 96 |
private ListSearchField typeField; |
| 97 |
|
| 98 |
private ListSearchField resolutionField; |
| 99 |
|
| 100 |
private ListSearchField statusField; |
| 101 |
|
| 102 |
private Button updateButton; |
83 |
private Button updateButton; |
| 103 |
|
84 |
|
| 104 |
private TextSearchField keywordsField; |
85 |
private Map<String, String> ticketFieldsLabelToName; |
| 105 |
|
86 |
|
| 106 |
private Map<String, SearchField> searchFieldByName = new HashMap<String, SearchField>(); |
87 |
private Map<String, TracTicketField> allTicketFieldsByName; |
| 107 |
|
88 |
|
| 108 |
private boolean firstTime = true; |
89 |
private Map<String, SearchField> selectedSearchFieldByName = new HashMap<String, SearchField>(); |
| 109 |
|
90 |
|
| 110 |
// private UserSearchField ownerField; |
91 |
private boolean firstTime = true; |
| 111 |
// |
92 |
|
| 112 |
// private UserSearchField reporterField; |
93 |
private Composite optionsContainer; |
| 113 |
// |
94 |
|
| 114 |
// private UserSearchField ccField; |
95 |
private Combo filterCombo; |
| 115 |
|
96 |
|
| 116 |
public TracCustomQueryPage(TaskRepository repository, AbstractRepositoryQuery query) { |
97 |
public TracCustomQueryPage(TaskRepository repository, AbstractRepositoryQuery query) { |
| 117 |
super(TITLE); |
98 |
super(TITLE); |
|
Lines 129-134
Link Here
|
| 129 |
|
110 |
|
| 130 |
@Override |
111 |
@Override |
| 131 |
public void createControl(Composite parent) { |
112 |
public void createControl(Composite parent) { |
|
|
113 |
updateAttributesFromRepository(false); |
| 132 |
Composite control = new Composite(parent, SWT.NONE); |
114 |
Composite control = new Composite(parent, SWT.NONE); |
| 133 |
GridData gd = new GridData(GridData.FILL_BOTH); |
115 |
GridData gd = new GridData(GridData.FILL_BOTH); |
| 134 |
control.setLayoutData(gd); |
116 |
control.setLayoutData(gd); |
|
Lines 140-158
Link Here
|
| 140 |
control.setLayout(layout); |
122 |
control.setLayout(layout); |
| 141 |
|
123 |
|
| 142 |
createTitleGroup(control); |
124 |
createTitleGroup(control); |
| 143 |
|
|
|
| 144 |
summaryField = new TextSearchField("summary"); |
| 145 |
summaryField.createControls(control, "Summary"); |
| 146 |
|
| 147 |
descriptionField = new TextSearchField("description"); |
| 148 |
descriptionField.createControls(control, "Description"); |
| 149 |
|
| 150 |
keywordsField = new TextSearchField("keywords"); |
| 151 |
keywordsField.createControls(control, "Keywords"); |
| 152 |
|
| 153 |
createOptionsGroup(control); |
125 |
createOptionsGroup(control); |
| 154 |
|
126 |
createAddFilterGroup(control); |
| 155 |
createUserGroup(control); |
127 |
createUpdateButton(control); |
| 156 |
|
128 |
|
| 157 |
if (query != null) { |
129 |
if (query != null) { |
| 158 |
titleText.setText(query.getSummary()); |
130 |
titleText.setText(query.getSummary()); |
|
Lines 162-167
Link Here
|
| 162 |
setControl(control); |
134 |
setControl(control); |
| 163 |
} |
135 |
} |
| 164 |
|
136 |
|
|
|
137 |
private void createAddFilterGroup(Composite parent) { |
| 138 |
GridLayout layout; |
| 139 |
GridData gd; |
| 140 |
|
| 141 |
Composite composite = new Composite(parent, SWT.NONE); |
| 142 |
layout = new GridLayout(2, false); |
| 143 |
composite.setLayout(layout); |
| 144 |
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| 145 |
gd = new GridData(GridData.BEGINNING | GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL); |
| 146 |
gd.horizontalSpan = 4; |
| 147 |
composite.setLayoutData(gd); |
| 148 |
|
| 149 |
Label label = new Label(composite, SWT.LEFT); |
| 150 |
label.setText("Select to add filter: "); |
| 151 |
label.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, false)); |
| 152 |
|
| 153 |
// condition |
| 154 |
filterCombo = new Combo(composite, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); |
| 155 |
filterCombo.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); |
| 156 |
|
| 157 |
filterCombo.add(""); |
| 158 |
for (String fieldLabel : ticketFieldsLabelToName.keySet()) |
| 159 |
filterCombo.add(fieldLabel); |
| 160 |
|
| 161 |
filterCombo.addModifyListener(new ModifyListener() { |
| 162 |
public void modifyText(ModifyEvent e) { |
| 163 |
if (filterCombo.getText().length() > 0) { |
| 164 |
TracTicketField field = allTicketFieldsByName.get(ticketFieldsLabelToName.get(filterCombo.getText())); |
| 165 |
addFieldToPage(field); |
| 166 |
} |
| 167 |
} |
| 168 |
}); |
| 169 |
} |
| 170 |
|
| 171 |
|
| 172 |
protected SearchField addFieldToPage(TracTicketField field) { |
| 173 |
// TODO Auto-generated method stub |
| 174 |
SearchField searchField = null; |
| 175 |
if ((field.getType() == TracTicketField.Type.TEXT) || (field.getType() == TracTicketField.Type.TEXTAREA)) { |
| 176 |
searchField = new TextSearchField(field.getName()); |
| 177 |
selectedSearchFieldByName.put(field.getName(), searchField); |
| 178 |
((TextSearchField)searchField).createControls(optionsContainer, field.getLabel()); |
| 179 |
} |
| 180 |
if (field.getType() == TracTicketField.Type.CHECKBOX) { |
| 181 |
searchField = new CheckSearchField(field.getName()); |
| 182 |
selectedSearchFieldByName.put(field.getName(), searchField); |
| 183 |
((CheckSearchField)searchField).createControls(optionsContainer, field.getLabel()); |
| 184 |
} |
| 185 |
if (field.getType() == TracTicketField.Type.SELECT || (field.getType() == TracTicketField.Type.RADIO)) { |
| 186 |
searchField = new ListSearchField(field.getName()); |
| 187 |
selectedSearchFieldByName.put(field.getName(), searchField); |
| 188 |
((ListSearchField)searchField).createControls(optionsContainer, field.getLabel()); |
| 189 |
} |
| 190 |
|
| 191 |
filterCombo.remove(field.getLabel()); |
| 192 |
filterCombo.select(0); |
| 193 |
updateScrollPane(); |
| 194 |
return searchField; |
| 195 |
|
| 196 |
} |
| 197 |
|
| 198 |
private void updateScrollPane() { |
| 199 |
//optionsContainer.setSize(optionsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT)); |
| 200 |
((ScrolledComposite)optionsContainer.getParent()).setMinHeight(optionsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); |
| 201 |
optionsContainer.layout(); |
| 202 |
} |
| 203 |
|
| 165 |
@Override |
204 |
@Override |
| 166 |
public boolean canFlipToNextPage() { |
205 |
public boolean canFlipToNextPage() { |
| 167 |
return false; |
206 |
return false; |
|
Lines 170-176
Link Here
|
| 170 |
private void restoreWidgetValues(TracSearch search) { |
209 |
private void restoreWidgetValues(TracSearch search) { |
| 171 |
java.util.List<TracSearchFilter> filters = search.getFilters(); |
210 |
java.util.List<TracSearchFilter> filters = search.getFilters(); |
| 172 |
for (TracSearchFilter filter : filters) { |
211 |
for (TracSearchFilter filter : filters) { |
| 173 |
SearchField field = searchFieldByName.get(filter.getFieldName()); |
212 |
SearchField field = selectedSearchFieldByName.get(filter.getFieldName()); |
|
|
213 |
if (field == null) |
| 214 |
field = addFieldToPage(allTicketFieldsByName.get(filter.getFieldName())); |
| 174 |
if (field != null) { |
215 |
if (field != null) { |
| 175 |
field.setFilter(filter); |
216 |
field.setFilter(filter); |
| 176 |
} else { |
217 |
} else { |
|
Lines 185-194
Link Here
|
| 185 |
} |
226 |
} |
| 186 |
|
227 |
|
| 187 |
Label titleLabel = new Label(control, SWT.NONE); |
228 |
Label titleLabel = new Label(control, SWT.NONE); |
|
|
229 |
titleLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); |
| 188 |
titleLabel.setText(TITLE_QUERY_TITLE); |
230 |
titleLabel.setText(TITLE_QUERY_TITLE); |
| 189 |
|
231 |
|
| 190 |
titleText = new Text(control, SWT.BORDER); |
232 |
titleText = new Text(control, SWT.BORDER); |
| 191 |
GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL); |
233 |
GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); |
| 192 |
gd.horizontalSpan = 3; |
234 |
gd.horizontalSpan = 3; |
| 193 |
titleText.setLayoutData(gd); |
235 |
titleText.setLayoutData(gd); |
| 194 |
titleText.addKeyListener(new KeyListener() { |
236 |
titleText.addKeyListener(new KeyListener() { |
|
Lines 203-301
Link Here
|
| 203 |
} |
245 |
} |
| 204 |
|
246 |
|
| 205 |
protected Control createOptionsGroup(Composite control) { |
247 |
protected Control createOptionsGroup(Composite control) { |
| 206 |
Group group = new Group(control, SWT.NONE); |
|
|
| 207 |
// group.setText("Ticket Attributes"); |
| 208 |
GridLayout layout = new GridLayout(); |
| 209 |
layout.numColumns = 1; |
| 210 |
group.setLayout(layout); |
| 211 |
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); |
248 |
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); |
| 212 |
gd.horizontalSpan = 4; |
249 |
gd.horizontalSpan = 5; |
| 213 |
group.setLayoutData(gd); |
|
|
| 214 |
|
| 215 |
createProductAttributes(group); |
| 216 |
createTicketAttributes(group); |
| 217 |
createUpdateButton(group); |
| 218 |
|
| 219 |
return group; |
| 220 |
} |
| 221 |
|
| 222 |
protected void createUserGroup(Composite control) { |
| 223 |
UserSearchField userField = new UserSearchField(); |
| 224 |
userField.createControls(control); |
| 225 |
} |
| 226 |
|
250 |
|
| 227 |
/** |
251 |
ScrolledComposite sc = new ScrolledComposite(control, SWT.V_SCROLL); |
| 228 |
* Creates the area for selection on product attributes component/version/milestone. |
252 |
sc.setLayoutData(gd); |
| 229 |
*/ |
|
|
| 230 |
protected Control createProductAttributes(Composite control) { |
| 231 |
Composite group = new Composite(control, SWT.NONE); |
| 232 |
GridLayout layout = new GridLayout(); |
253 |
GridLayout layout = new GridLayout(); |
| 233 |
layout.numColumns = 3; |
254 |
layout.numColumns = 1; |
| 234 |
group.setLayout(layout); |
255 |
layout.marginHeight = layout.marginWidth = 0; |
| 235 |
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); |
256 |
sc.setLayout(layout); |
| 236 |
gd.horizontalSpan = 1; |
257 |
|
| 237 |
group.setLayoutData(gd); |
258 |
Composite innerComposite = new Composite(sc, SWT.NONE); |
| 238 |
|
259 |
innerComposite.setLayout(new GridLayout(5, false)); |
| 239 |
Label label = new Label(group, SWT.LEFT); |
260 |
sc.setContent(innerComposite); |
| 240 |
label.setText("Component"); |
261 |
sc.setExpandHorizontal(true); |
| 241 |
|
262 |
sc.setExpandVertical(true); |
| 242 |
label = new Label(group, SWT.LEFT); |
263 |
sc.setMinHeight(300); |
| 243 |
label.setText("Version"); |
264 |
|
| 244 |
|
265 |
optionsContainer = innerComposite; |
| 245 |
label = new Label(group, SWT.LEFT); |
266 |
return innerComposite; |
| 246 |
label.setText("Milestone"); |
|
|
| 247 |
|
| 248 |
componentField = new ListSearchField("component"); |
| 249 |
componentField.createControls(group, PRODUCT_HEIGHT); |
| 250 |
|
| 251 |
versionField = new ListSearchField("version"); |
| 252 |
versionField.createControls(group, PRODUCT_HEIGHT); |
| 253 |
|
| 254 |
milestoneField = new ListSearchField("milestone"); |
| 255 |
milestoneField.createControls(group, PRODUCT_HEIGHT); |
| 256 |
|
| 257 |
return group; |
| 258 |
} |
267 |
} |
|
|
268 |
|
| 259 |
|
269 |
|
| 260 |
/** |
270 |
/** |
| 261 |
* Creates the area for selection of ticket attributes status/resolution/priority. |
271 |
* Creates the area for update attributes button. |
| 262 |
*/ |
272 |
*/ |
| 263 |
protected Control createTicketAttributes(Composite control) { |
|
|
| 264 |
Composite group = new Composite(control, SWT.NONE); |
| 265 |
GridLayout layout = new GridLayout(); |
| 266 |
layout.numColumns = 4; |
| 267 |
group.setLayout(layout); |
| 268 |
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); |
| 269 |
gd.horizontalSpan = 1; |
| 270 |
group.setLayoutData(gd); |
| 271 |
|
| 272 |
Label label = new Label(group, SWT.LEFT); |
| 273 |
label.setText("Status"); |
| 274 |
|
| 275 |
label = new Label(group, SWT.LEFT); |
| 276 |
label.setText("Resolution"); |
| 277 |
|
| 278 |
label = new Label(group, SWT.LEFT); |
| 279 |
label.setText("Type"); |
| 280 |
|
| 281 |
label = new Label(group, SWT.LEFT); |
| 282 |
label.setText("Priority"); |
| 283 |
|
| 284 |
statusField = new ListSearchField("status"); |
| 285 |
statusField.createControls(group, STATUS_HEIGHT); |
| 286 |
|
| 287 |
resolutionField = new ListSearchField("resolution"); |
| 288 |
resolutionField.createControls(group, STATUS_HEIGHT); |
| 289 |
|
| 290 |
typeField = new ListSearchField("type"); |
| 291 |
typeField.createControls(group, STATUS_HEIGHT); |
| 292 |
|
| 293 |
priorityField = new ListSearchField("priority"); |
| 294 |
priorityField.createControls(group, STATUS_HEIGHT); |
| 295 |
|
| 296 |
return group; |
| 297 |
} |
| 298 |
|
| 299 |
protected Control createUpdateButton(final Composite control) { |
273 |
protected Control createUpdateButton(final Composite control) { |
| 300 |
Composite group = new Composite(control, SWT.NONE); |
274 |
Composite group = new Composite(control, SWT.NONE); |
| 301 |
GridLayout layout = new GridLayout(2, false); |
275 |
GridLayout layout = new GridLayout(2, false); |
|
Lines 350-363
Link Here
|
| 350 |
} |
324 |
} |
| 351 |
|
325 |
|
| 352 |
private void initializePage() { |
326 |
private void initializePage() { |
| 353 |
updateAttributesFromRepository(false); |
327 |
updateAttributesFromRepository(true); |
| 354 |
boolean restored = (query != null); |
328 |
boolean restored = (query != null); |
| 355 |
if (inSearchContainer()) { |
329 |
if (inSearchContainer()) { |
| 356 |
restored |= restoreWidgetValues(); |
330 |
restored |= restoreWidgetValues(); |
| 357 |
} |
331 |
} |
| 358 |
// initialize with default values |
332 |
// initialize with default values |
| 359 |
if (!restored) { |
333 |
if (!restored) { |
| 360 |
statusField.selectItems(DEFAULT_STATUS_SELECTION); |
334 |
//statusField.selectItems(DEFAULT_STATUS_SELECTION); |
| 361 |
} |
335 |
} |
| 362 |
} |
336 |
} |
| 363 |
|
337 |
|
|
Lines 372-378
Link Here
|
| 372 |
} |
346 |
} |
| 373 |
} |
347 |
} |
| 374 |
|
348 |
|
| 375 |
private void updateAttributesFromRepository(final boolean force) { |
349 |
private ITracClient updateClientData(final boolean force) { |
| 376 |
TracRepositoryConnector connector = (TracRepositoryConnector) TasksUiPlugin.getRepositoryManager() |
350 |
TracRepositoryConnector connector = (TracRepositoryConnector) TasksUiPlugin.getRepositoryManager() |
| 377 |
.getRepositoryConnector(TracCorePlugin.REPOSITORY_KIND); |
351 |
.getRepositoryConnector(TracCorePlugin.REPOSITORY_KIND); |
| 378 |
final ITracClient client; |
352 |
final ITracClient client; |
|
Lines 380-386
Link Here
|
| 380 |
client = connector.getClientManager().getRepository(repository); |
354 |
client = connector.getClientManager().getRepository(repository); |
| 381 |
} catch (MalformedURLException e) { |
355 |
} catch (MalformedURLException e) { |
| 382 |
StatusHandler.displayStatus("Error updating attributes", TracCorePlugin.toStatus(e, repository)); |
356 |
StatusHandler.displayStatus("Error updating attributes", TracCorePlugin.toStatus(e, repository)); |
| 383 |
return; |
357 |
return null; |
| 384 |
} |
358 |
} |
| 385 |
|
359 |
|
| 386 |
if (!client.hasAttributes() || force) { |
360 |
if (!client.hasAttributes() || force) { |
|
Lines 405-424
Link Here
|
| 405 |
} |
379 |
} |
| 406 |
} catch (InvocationTargetException e) { |
380 |
} catch (InvocationTargetException e) { |
| 407 |
StatusHandler.displayStatus("Error updating attributes", TracCorePlugin.toStatus(e.getCause(), repository)); |
381 |
StatusHandler.displayStatus("Error updating attributes", TracCorePlugin.toStatus(e.getCause(), repository)); |
| 408 |
return; |
382 |
return null; |
| 409 |
} catch (InterruptedException e) { |
383 |
} catch (InterruptedException e) { |
| 410 |
return; |
384 |
return null; |
| 411 |
} |
385 |
} |
| 412 |
} |
386 |
} |
|
|
387 |
return client; |
| 413 |
|
388 |
|
| 414 |
statusField.setValues(client.getTicketStatus()); |
389 |
} |
| 415 |
resolutionField.setValues(client.getTicketResolutions()); |
390 |
private void updateAttributesFromRepository(final boolean force) { |
| 416 |
typeField.setValues(client.getTicketTypes()); |
391 |
ITracClient client = updateClientData(force); |
| 417 |
priorityField.setValues(client.getPriorities()); |
392 |
TracTicketField[] ticketFields = client.getTicketFields(); |
| 418 |
|
393 |
ticketFieldsLabelToName = new HashMap<String, String>(); |
| 419 |
componentField.setValues(client.getComponents()); |
394 |
allTicketFieldsByName = new HashMap<String, TracTicketField>(); |
| 420 |
versionField.setValues(client.getVersions()); |
395 |
for (TracTicketField tf : ticketFields) { |
| 421 |
milestoneField.setValues(client.getMilestones()); |
396 |
ticketFieldsLabelToName.put(tf.getLabel(), tf.getName()); |
|
|
397 |
allTicketFieldsByName.put(tf.getName(), tf); |
| 398 |
} |
| 399 |
for (SearchField searchField : selectedSearchFieldByName.values()) |
| 400 |
if (searchField instanceof ListSearchField) |
| 401 |
//((ListSearchField)searchField).setValues(allTicketFieldsByName.get(ticketFieldsLabelToName.get(searchField.getFieldName())).getOptions()); |
| 402 |
((ListSearchField)searchField).setValues(allTicketFieldsByName.get(searchField.getFieldName()).getOptions()); |
| 403 |
//TODO: Refresh selectable attributes |
| 422 |
} |
404 |
} |
| 423 |
|
405 |
|
| 424 |
public TaskRepository getRepository() { |
406 |
public TaskRepository getRepository() { |
|
Lines 449-455
Link Here
|
| 449 |
|
431 |
|
| 450 |
private TracSearch getTracSearch() { |
432 |
private TracSearch getTracSearch() { |
| 451 |
TracSearch search = new TracSearch(); |
433 |
TracSearch search = new TracSearch(); |
| 452 |
for (SearchField field : searchFieldByName.values()) { |
434 |
for (SearchField field : selectedSearchFieldByName.values()) { |
| 453 |
TracSearchFilter filter = field.getFilter(); |
435 |
TracSearchFilter filter = field.getFilter(); |
| 454 |
if (filter != null) { |
436 |
if (filter != null) { |
| 455 |
search.addFilter(filter); |
437 |
search.addFilter(filter); |
|
Lines 516-532
Link Here
|
| 516 |
IDialogSettings settings = getDialogSettings(); |
498 |
IDialogSettings settings = getDialogSettings(); |
| 517 |
settings.put(SEARCH_URL_ID + repoId, getTracSearch().toUrl()); |
499 |
settings.put(SEARCH_URL_ID + repoId, getTracSearch().toUrl()); |
| 518 |
} |
500 |
} |
|
|
501 |
|
| 519 |
|
502 |
|
| 520 |
private abstract class SearchField { |
503 |
private abstract class SearchField { |
| 521 |
|
504 |
|
| 522 |
protected String fieldName; |
505 |
protected String fieldName; |
|
|
506 |
|
| 507 |
protected ArrayList<Control> controlList= new ArrayList<Control>(); |
| 523 |
|
508 |
|
| 524 |
public SearchField(String fieldName) { |
509 |
public SearchField(String fieldName) { |
| 525 |
this.fieldName = fieldName; |
510 |
this.fieldName = fieldName; |
| 526 |
|
511 |
|
| 527 |
if (fieldName != null) { |
512 |
if (fieldName != null) { |
| 528 |
assert !searchFieldByName.containsKey(fieldName); |
513 |
assert !selectedSearchFieldByName.containsKey(fieldName); |
| 529 |
searchFieldByName.put(fieldName, this); |
514 |
selectedSearchFieldByName.put(fieldName, this); |
| 530 |
} |
515 |
} |
| 531 |
} |
516 |
} |
| 532 |
|
517 |
|
|
Lines 534-539
Link Here
|
| 534 |
return fieldName; |
519 |
return fieldName; |
| 535 |
} |
520 |
} |
| 536 |
|
521 |
|
|
|
522 |
protected Button placeRemoveButton(Composite parent) { |
| 523 |
Button removeButton = new Button(parent, SWT.PUSH); |
| 524 |
removeButton.setText("Remove"); |
| 525 |
removeButton.setLayoutData(new GridData(SWT.END, SWT.BEGINNING, false, false)); |
| 526 |
controlList.add(removeButton); |
| 527 |
removeButton.addSelectionListener(new SelectionListener() { |
| 528 |
|
| 529 |
public void widgetDefaultSelected(SelectionEvent e) { |
| 530 |
// TODO Auto-generated method stub |
| 531 |
widgetSelected(e); |
| 532 |
} |
| 533 |
|
| 534 |
public void widgetSelected(SelectionEvent e) { |
| 535 |
// TODO Auto-generated method stub |
| 536 |
selectedSearchFieldByName.remove(getFieldName()); |
| 537 |
for (Control con : controlList) |
| 538 |
con.dispose(); |
| 539 |
filterCombo.add(allTicketFieldsByName.get(getFieldName()).getLabel()); |
| 540 |
updateScrollPane(); |
| 541 |
} |
| 542 |
|
| 543 |
}); |
| 544 |
return removeButton; |
| 545 |
} |
| 546 |
|
| 537 |
public abstract TracSearchFilter getFilter(); |
547 |
public abstract TracSearchFilter getFilter(); |
| 538 |
|
548 |
|
| 539 |
public abstract void setFilter(TracSearchFilter filter); |
549 |
public abstract void setFilter(TracSearchFilter filter); |
|
Lines 559-564
Link Here
|
| 559 |
if (labelText != null) { |
569 |
if (labelText != null) { |
| 560 |
label = new Label(parent, SWT.LEFT); |
570 |
label = new Label(parent, SWT.LEFT); |
| 561 |
label.setText(labelText); |
571 |
label.setText(labelText); |
|
|
572 |
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); |
| 573 |
controlList.add(label); |
| 562 |
} |
574 |
} |
| 563 |
|
575 |
|
| 564 |
conditionCombo = new Combo(parent, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); |
576 |
conditionCombo = new Combo(parent, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); |
|
Lines 566-571
Link Here
|
| 566 |
conditionCombo.add(op.toString()); |
578 |
conditionCombo.add(op.toString()); |
| 567 |
} |
579 |
} |
| 568 |
conditionCombo.setText(compareOperators[0].toString()); |
580 |
conditionCombo.setText(compareOperators[0].toString()); |
|
|
581 |
controlList.add(conditionCombo); |
| 569 |
|
582 |
|
| 570 |
searchText = new Text(parent, SWT.BORDER); |
583 |
searchText = new Text(parent, SWT.BORDER); |
| 571 |
GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); |
584 |
GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); |
|
Lines 574-579
Link Here
|
| 574 |
gd.horizontalSpan = 2; |
587 |
gd.horizontalSpan = 2; |
| 575 |
} |
588 |
} |
| 576 |
searchText.setLayoutData(gd); |
589 |
searchText.setLayoutData(gd); |
|
|
590 |
controlList.add(searchText); |
| 591 |
|
| 592 |
placeRemoveButton(parent); |
| 593 |
; |
| 577 |
} |
594 |
} |
| 578 |
|
595 |
|
| 579 |
public CompareOperator getCondition() { |
596 |
public CompareOperator getCondition() { |
|
Lines 625-778
Link Here
|
| 625 |
|
642 |
|
| 626 |
} |
643 |
} |
| 627 |
|
644 |
|
| 628 |
private class ListSearchField extends SearchField { |
645 |
private class CheckSearchField extends SearchField { |
| 629 |
|
646 |
|
| 630 |
private List list; |
647 |
protected Button searchCheck; |
| 631 |
|
648 |
|
| 632 |
public ListSearchField(String fieldName) { |
649 |
private Label label; |
|
|
650 |
|
| 651 |
public CheckSearchField(String fieldName) { |
| 633 |
super(fieldName); |
652 |
super(fieldName); |
| 634 |
} |
653 |
} |
| 635 |
|
654 |
|
| 636 |
public void setValues(Object[] items) { |
655 |
public void createControls(Composite parent, String labelText) { |
| 637 |
// preserve selected values |
656 |
if (labelText != null) { |
| 638 |
TracSearchFilter filter = getFilter(); |
657 |
label = new Label(parent, SWT.LEFT); |
|
|
658 |
label.setText(labelText); |
| 659 |
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); |
| 660 |
controlList.add(label); |
| 661 |
} |
| 639 |
|
662 |
|
| 640 |
list.removeAll(); |
663 |
searchCheck = new Button(parent, SWT.CHECK|SWT.LEFT); |
| 641 |
if (items != null) { |
664 |
//if (labelText != null) |
| 642 |
list.setEnabled(true); |
665 |
// searchCheck.setText(labelText); |
| 643 |
for (Object item : items) { |
666 |
GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); |
| 644 |
list.add(item.toString()); |
667 |
gd.horizontalSpan = 3; |
| 645 |
} |
668 |
searchCheck.setLayoutData(gd); |
|
|
669 |
controlList.add(searchCheck); |
| 670 |
|
| 671 |
placeRemoveButton(parent); |
| 646 |
|
672 |
|
| 647 |
// restore selected values |
|
|
| 648 |
if (filter != null) { |
| 649 |
setFilter(filter); |
| 650 |
} |
| 651 |
} else { |
| 652 |
list.setEnabled(false); |
| 653 |
} |
| 654 |
} |
673 |
} |
| 655 |
|
674 |
|
| 656 |
public void createControls(Composite parent, int height) { |
675 |
public int getSearchState() { |
| 657 |
list = new List(parent, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER); |
676 |
if (searchCheck.getSelection()) |
| 658 |
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); |
677 |
return 1; |
| 659 |
gd.heightHint = height; |
678 |
else |
| 660 |
list.setLayoutData(gd); |
679 |
return 0; |
|
|
680 |
} |
| 681 |
|
| 682 |
public void setSearchState(int state) { |
| 683 |
if (state != 0) |
| 684 |
searchCheck.setSelection(true); |
| 685 |
else |
| 686 |
searchCheck.setSelection(false); |
| 661 |
} |
687 |
} |
| 662 |
|
688 |
|
| 663 |
@Override |
689 |
@Override |
| 664 |
public TracSearchFilter getFilter() { |
690 |
public TracSearchFilter getFilter() { |
| 665 |
int[] indicies = list.getSelectionIndices(); |
|
|
| 666 |
if (indicies.length == 0) { |
| 667 |
return null; |
| 668 |
} |
| 669 |
|
| 670 |
TracSearchFilter newFilter = new TracSearchFilter(getFieldName()); |
691 |
TracSearchFilter newFilter = new TracSearchFilter(getFieldName()); |
| 671 |
newFilter.setOperator(CompareOperator.IS); |
692 |
newFilter.setOperator(CompareOperator.IS); |
| 672 |
for (int i : indicies) { |
693 |
newFilter.addValue(String.valueOf(getSearchState())); |
| 673 |
newFilter.addValue(list.getItem(i)); |
|
|
| 674 |
} |
| 675 |
return newFilter; |
694 |
return newFilter; |
| 676 |
} |
695 |
} |
| 677 |
|
696 |
|
| 678 |
@Override |
697 |
@Override |
| 679 |
public void setFilter(TracSearchFilter filter) { |
698 |
public void setFilter(TracSearchFilter filter) { |
| 680 |
list.deselectAll(); |
|
|
| 681 |
java.util.List<String> values = filter.getValues(); |
699 |
java.util.List<String> values = filter.getValues(); |
| 682 |
for (String item : values) { |
700 |
setSearchState(Integer.parseInt(values.get(0))); |
| 683 |
int i = list.indexOf(item); |
|
|
| 684 |
if (i != -1) { |
| 685 |
list.select(i); |
| 686 |
} else { |
| 687 |
list.add(item, 0); |
| 688 |
list.select(0); |
| 689 |
} |
| 690 |
} |
| 691 |
} |
701 |
} |
| 692 |
|
702 |
|
| 693 |
public void selectItems(String[] items) { |
703 |
public void setFieldName(String fieldName) { |
| 694 |
list.deselectAll(); |
704 |
this.fieldName = fieldName; |
| 695 |
for (String item : items) { |
|
|
| 696 |
int i = list.indexOf(item); |
| 697 |
if (i != -1) { |
| 698 |
list.select(i); |
| 699 |
} |
| 700 |
} |
| 701 |
} |
705 |
} |
| 702 |
|
706 |
|
| 703 |
} |
707 |
} |
| 704 |
|
708 |
|
| 705 |
private class UserSearchField extends SearchField { |
709 |
private class ListSearchField extends SearchField { |
| 706 |
|
|
|
| 707 |
private TextSearchField textField; |
| 708 |
|
| 709 |
private Combo userCombo; |
| 710 |
|
710 |
|
| 711 |
public UserSearchField() { |
711 |
private ArrayList<Combo> combos = new ArrayList<Combo>(); |
| 712 |
super(null); |
712 |
|
|
|
713 |
private Composite container; |
| 714 |
|
| 715 |
public ListSearchField(String fieldName) { |
| 716 |
super(fieldName); |
| 717 |
} |
| 713 |
|
718 |
|
| 714 |
textField = new TextSearchField(null); |
719 |
public void setValues(Object[] items) { |
|
|
720 |
// preserve selected values |
| 721 |
TracSearchFilter filter = getFilter(); |
| 722 |
for (Combo combo : combos) { |
| 723 |
combo.removeAll(); |
| 724 |
if (items != null) { |
| 725 |
combo.setEnabled(true); |
| 726 |
for (Object item : items) { |
| 727 |
combo.add(item.toString()); |
| 728 |
} |
| 715 |
|
729 |
|
| 716 |
new UserSelectionSearchField("owner", 0); |
730 |
// restore selected values |
|
|
731 |
if (filter != null) { |
| 732 |
setFilter(filter); |
| 733 |
} |
| 734 |
} else { |
| 735 |
combo.setEnabled(false); |
| 736 |
} |
| 737 |
} |
| 738 |
} |
| 717 |
|
739 |
|
| 718 |
new UserSelectionSearchField("reporter", 1); |
740 |
public void createControls(Composite parent, String caption) { |
|
|
741 |
GridData gd; |
| 742 |
|
| 743 |
if (caption != null) { |
| 744 |
Label label = new Label(parent, SWT.NONE); |
| 745 |
label.setText(caption); |
| 746 |
gd = new GridData(SWT.END, SWT.CENTER, false, false); |
| 747 |
label.setLayoutData(gd); |
| 748 |
controlList.add(label); |
| 749 |
} |
| 750 |
|
| 751 |
container = new Composite(parent, SWT.NONE); |
| 752 |
gd = new GridData(SWT.FILL, SWT.FILL, true, false); |
| 753 |
gd.horizontalSpan = 3; |
| 754 |
container.setLayoutData(gd); |
| 755 |
GridLayout layout = new GridLayout(3, false); |
| 756 |
layout.marginHeight = layout.marginWidth = 0; |
| 757 |
container.setLayout(layout); |
| 758 |
controlList.add(container); |
| 759 |
|
| 760 |
Label isLabel = new Label(container, SWT.NONE); |
| 761 |
isLabel.setText("is"); |
| 762 |
gd = new GridData(SWT.END, SWT.CENTER, false, false); |
| 763 |
gd.verticalIndent = 5; |
| 764 |
isLabel.setLayoutData(gd); |
| 765 |
Combo combo = new Combo(container, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); |
| 766 |
combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| 767 |
combo.setItems(allTicketFieldsByName.get(getFieldName()).getOptions()); |
| 768 |
combos.add(combo); |
| 769 |
|
| 770 |
Button addButton = new Button(container, SWT.PUSH); |
| 771 |
addButton.setText("+"); |
| 772 |
gd = new GridData(SWT.FILL, SWT.FILL, false, false); |
| 773 |
addButton.setLayoutData(gd); |
| 774 |
addButton.addSelectionListener(new SelectionListener() { |
| 775 |
|
| 776 |
public void widgetDefaultSelected(SelectionEvent e) { |
| 777 |
// TODO Auto-generated method stub |
| 778 |
widgetSelected(e); |
| 779 |
} |
| 719 |
|
780 |
|
| 720 |
new UserSelectionSearchField("cc", 2); |
781 |
public void widgetSelected(SelectionEvent e) { |
| 721 |
} |
782 |
// TODO Auto-generated method stub |
|
|
783 |
addCombo(); |
| 784 |
updateScrollPane(); |
| 785 |
} |
| 786 |
|
| 787 |
}); |
| 788 |
|
| 789 |
|
| 790 |
placeRemoveButton(parent); |
| 791 |
} |
| 792 |
|
| 793 |
private Combo addCombo() { |
| 794 |
final Label orLabel = new Label(container, SWT.NONE); |
| 795 |
orLabel.setText("or"); |
| 796 |
orLabel.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); |
| 797 |
|
| 798 |
final Combo combo = new Combo(container, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); |
| 799 |
combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| 800 |
combo.setItems(allTicketFieldsByName.get(getFieldName()).getOptions()); |
| 801 |
combos.add(combo); |
| 802 |
|
| 803 |
final Button remButton = new Button(container, SWT.PUSH); |
| 804 |
remButton.setText("-"); |
| 805 |
remButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); |
| 806 |
remButton.addSelectionListener(new SelectionListener() { |
| 807 |
|
| 808 |
private Label tempLabel = orLabel; |
| 809 |
private Combo tempCombo = combo; |
| 810 |
private Button tempButton = remButton; |
| 811 |
|
| 812 |
public void widgetDefaultSelected(SelectionEvent e) { |
| 813 |
// TODO Auto-generated method stub |
| 814 |
widgetSelected(e); |
| 815 |
} |
| 722 |
|
816 |
|
| 723 |
public void createControls(Composite parent) { |
817 |
public void widgetSelected(SelectionEvent e) { |
| 724 |
userCombo = new Combo(parent, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); |
818 |
// TODO Auto-generated method stub |
| 725 |
userCombo.add("Owner"); |
819 |
combos.remove(tempCombo); |
| 726 |
userCombo.add("Reporter"); |
820 |
tempLabel.dispose(); |
| 727 |
userCombo.add("CC"); |
821 |
tempCombo.dispose(); |
| 728 |
userCombo.select(0); |
822 |
tempButton.dispose(); |
|
|
823 |
updateScrollPane(); |
| 824 |
} |
| 825 |
|
| 826 |
}); |
| 827 |
return combo; |
| 729 |
|
828 |
|
| 730 |
textField.createControls(parent, null); |
|
|
| 731 |
} |
829 |
} |
| 732 |
|
830 |
|
| 733 |
@Override |
831 |
@Override |
| 734 |
public TracSearchFilter getFilter() { |
832 |
public TracSearchFilter getFilter() { |
| 735 |
return null; |
833 |
TracSearchFilter newFilter = new TracSearchFilter(getFieldName()); |
|
|
834 |
newFilter.setOperator(CompareOperator.IS); |
| 835 |
for (Combo combo : combos) { |
| 836 |
newFilter.addValue(combo.getText()); |
| 837 |
} |
| 838 |
return newFilter; |
| 736 |
} |
839 |
} |
| 737 |
|
840 |
|
| 738 |
@Override |
841 |
@Override |
| 739 |
public void setFilter(TracSearchFilter filter) { |
842 |
public void setFilter(TracSearchFilter filter) { |
|
|
843 |
selectItems(filter.getValues().toArray(new String[]{})); |
| 740 |
} |
844 |
} |
| 741 |
|
845 |
|
| 742 |
private void setSelection(int index) { |
846 |
public void selectItems(String[] items) { |
| 743 |
userCombo.select(index); |
847 |
Combo combo; |
| 744 |
} |
848 |
for (int i = 0; i < items.length; i++) { |
| 745 |
|
849 |
if (combos.size() <= i || combos.size() == 0) { |
| 746 |
private int getSelection() { |
850 |
combo = addCombo(); |
| 747 |
return userCombo.getSelectionIndex(); |
851 |
} else { |
| 748 |
} |
852 |
combo = combos.get(i); |
| 749 |
|
|
|
| 750 |
class UserSelectionSearchField extends SearchField { |
| 751 |
|
| 752 |
private int index; |
| 753 |
|
| 754 |
public UserSelectionSearchField(String fieldName, int index) { |
| 755 |
super(fieldName); |
| 756 |
|
| 757 |
this.index = index; |
| 758 |
} |
| 759 |
|
| 760 |
@Override |
| 761 |
public TracSearchFilter getFilter() { |
| 762 |
if (index == getSelection()) { |
| 763 |
textField.setFieldName(fieldName); |
| 764 |
return textField.getFilter(); |
| 765 |
} |
853 |
} |
| 766 |
return null; |
854 |
combo.select(combo.indexOf(items[i])); |
| 767 |
} |
855 |
} |
| 768 |
|
|
|
| 769 |
@Override |
| 770 |
public void setFilter(TracSearchFilter filter) { |
| 771 |
textField.setFieldName(fieldName); |
| 772 |
textField.setFilter(filter); |
| 773 |
setSelection(index); |
| 774 |
} |
| 775 |
|
| 776 |
} |
856 |
} |
| 777 |
|
857 |
|
| 778 |
} |
858 |
} |