diff options
| author | Kevin Sawicki | 2011-04-11 21:10:43 +0000 |
|---|---|---|
| committer | Chris Aniszczyk | 2011-04-12 13:25:24 +0000 |
| commit | 4c78b556af5df75a90f1012ef8cbca3e090cd067 (patch) | |
| tree | 43ab3acedc7e83ef10681d91525dd097b63d684a | |
| parent | d241156d43d00974118233c9db949aed65ee234f (diff) | |
| download | egit-github-4c78b556af5df75a90f1012ef8cbca3e090cd067.tar.gz egit-github-4c78b556af5df75a90f1012ef8cbca3e090cd067.tar.xz egit-github-4c78b556af5df75a90f1012ef8cbca3e090cd067.zip | |
Migrate query page to support new filter parameters
Change-Id: I0d9645e5030b9ab909d869b5c3b9a53b46fc3bc1
Signed-off-by: Kevin Sawicki <kevin@github.com>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
4 files changed, 414 insertions, 65 deletions
diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryConnectorUI.java b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryConnectorUI.java index eda7565f..cf97d5c9 100644 --- a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryConnectorUI.java +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryConnectorUI.java @@ -22,6 +22,7 @@ import org.eclipse.jface.text.hyperlink.IHyperlink; import org.eclipse.jface.text.hyperlink.URLHyperlink;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.mylyn.github.internal.GitHub;
+import org.eclipse.mylyn.github.internal.GitHubRepositoryConnector;
import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
import org.eclipse.mylyn.tasks.core.ITaskMapping;
import org.eclipse.mylyn.tasks.core.TaskRepository;
@@ -39,7 +40,17 @@ import org.eclipse.mylyn.tasks.ui.wizards.RepositoryQueryWizard; public class GitHubRepositoryConnectorUI extends AbstractRepositoryConnectorUi {
private final Pattern issuePattern = Pattern.compile("(?:([a-zA-Z0-9_\\.-]+)(?:/([a-zA-Z0-9_\\.-]+))?)?\\#(\\d+)");
-
+
+ /**
+ * Get core repository connector
+ *
+ * @return connector
+ */
+ public static GitHubRepositoryConnector getCoreConnector() {
+ return (GitHubRepositoryConnector) TasksUi
+ .getRepositoryConnector(GitHub.CONNECTOR_KIND);
+ }
+
/**
*
*
diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryQueryPage.java b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryQueryPage.java index b55e72a5..48ed47fc 100644 --- a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryQueryPage.java +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryQueryPage.java @@ -12,108 +12,361 @@ *******************************************************************************/ package org.eclipse.mylyn.github.ui.internal; +import java.lang.reflect.InvocationTargetException; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.mylyn.commons.net.Policy; +import org.eclipse.mylyn.github.internal.GitHubRepositoryConnector; +import org.eclipse.mylyn.github.internal.IssueService; +import org.eclipse.mylyn.github.internal.LabelComparator; +import org.eclipse.mylyn.github.internal.Milestone; +import org.eclipse.mylyn.github.internal.QueryUtils; import org.eclipse.mylyn.tasks.core.IRepositoryQuery; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositoryQueryPage; import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; /** - * GitHub connector specific extensions. + * GitHub issue repository query page class. */ public class GitHubRepositoryQueryPage extends AbstractRepositoryQueryPage { - private static final String ATTR_QUERY_TEXT = "queryText"; + private Button openButton; + private Button closedButton; + private Text titleText; + private Text assigneeText; + private Text mentionText; + private Combo milestoneCombo; + private CheckboxTableViewer labelsViewer; + private List<Milestone> milestones; - private static final String ATTR_STATUS = "status"; + private SelectionListener completeListener = new SelectionAdapter() { - private Text queryText = null; + public void widgetSelected(SelectionEvent e) { + setPageComplete(isPageComplete()); + } - private Combo status = null; + }; /** + * @param pageName * @param taskRepository * @param query */ - public GitHubRepositoryQueryPage(final TaskRepository taskRepository, - final IRepositoryQuery query) { - super("GitHub", taskRepository, query); - setTitle("GitHub search query parameters"); - setDescription("Valid search query parameters entered."); + public GitHubRepositoryQueryPage(String pageName, + TaskRepository taskRepository, IRepositoryQuery query) { + super(pageName, taskRepository, query); + setDescription(Messages.GitHubRepositoryQueryPage_Description); setPageComplete(false); } - @Override - public String getQueryTitle() { - return "GitHub Query"; + /** + * @param taskRepository + * @param query + */ + public GitHubRepositoryQueryPage(TaskRepository taskRepository, + IRepositoryQuery query) { + this("issueQueryPage", taskRepository, query); //$NON-NLS-1$ } - @Override - public void applyTo(IRepositoryQuery query) { - String statusString = status.getText(); - String queryString = queryText.getText(); - - String summary = statusString; - summary += " issues"; - if (queryString!=null && queryString.trim().length() > 0) { - summary += " matching "+queryString; - } - query.setSummary(summary); - query.setAttribute(ATTR_STATUS, statusString); - query.setAttribute(ATTR_QUERY_TEXT, queryString); + private void createLabelsArea(Composite parent) { + Group labelsArea = new Group(parent, SWT.NONE); + labelsArea.setText(Messages.GitHubRepositoryQueryPage_LabelsLabel); + GridDataFactory.fillDefaults().grab(true, true).applyTo(labelsArea); + GridLayoutFactory.swtDefaults().applyTo(labelsArea); + + labelsViewer = CheckboxTableViewer.newCheckList(labelsArea, SWT.BORDER + | SWT.V_SCROLL | SWT.H_SCROLL); + GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, 80) + .applyTo(labelsViewer.getControl()); + labelsViewer.setContentProvider(ArrayContentProvider.getInstance()); + labelsViewer.setLabelProvider(new LabelProvider() { + + public String getText(Object element) { + return ((org.eclipse.mylyn.github.internal.Label) element) + .getName(); + } + + }); + labelsViewer + .addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + setPageComplete(isPageComplete()); + } + }); } /** - * - * + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout gridLayout = new GridLayout(2, false); - gridLayout.marginTop = 20; - gridLayout.marginLeft = 25; - gridLayout.verticalSpacing = 8; - gridLayout.horizontalSpacing = 8; - composite.setLayout(gridLayout); - - - // create the status option combo box - new Label(composite, SWT.NONE).setText("Status:"); - status = new Combo(composite, SWT.READ_ONLY); - String[] queryValues = new String[] { "all", "open", "closed" }; - status.setItems(queryValues); - status.select(0); - String queryModelStatus = getQuery()==null?null:getQuery().getAttribute(ATTR_STATUS); - if (queryModelStatus != null) { - for (int x = 0;x<queryValues.length;++x) { - if (queryValues[x].equals(queryModelStatus)) { - status.select(x); - break; + Composite displayArea = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false) + .applyTo(displayArea); + GridDataFactory.fillDefaults().grab(true, true).applyTo(displayArea); + + if (!inSearchContainer()) { + Composite titleArea = new Composite(displayArea, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(titleArea); + GridDataFactory.fillDefaults().grab(true, false).span(2, 1) + .applyTo(titleArea); + + new Label(titleArea, SWT.NONE) + .setText(Messages.GitHubRepositoryQueryPage_TitleLabel); + titleText = new Text(titleArea, SWT.SINGLE | SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(titleText); + titleText.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent e) { + setPageComplete(isPageComplete()); } - } + }); + } + + Composite leftArea = new Composite(displayArea, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(leftArea); + GridDataFactory.fillDefaults().grab(true, true).applyTo(leftArea); + + Composite statusArea = new Composite(leftArea, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false) + .applyTo(statusArea); + GridDataFactory.fillDefaults().grab(true, false).span(2, 1) + .applyTo(statusArea); + + new Label(statusArea, SWT.NONE) + .setText(Messages.GitHubRepositoryQueryPage_StatusLabel); + + openButton = new Button(statusArea, SWT.CHECK); + openButton.setSelection(true); + openButton.setText(Messages.GitHubRepositoryQueryPage_StatusOpen); + openButton.addSelectionListener(this.completeListener); + + closedButton = new Button(statusArea, SWT.CHECK); + closedButton.setSelection(true); + closedButton.setText(Messages.GitHubRepositoryQueryPage_StatusClosed); + closedButton.addSelectionListener(this.completeListener); + + Label milestonesLabel = new Label(leftArea, SWT.NONE); + milestonesLabel + .setText(Messages.GitHubRepositoryQueryPage_MilestoneLabel); + + milestoneCombo = new Combo(leftArea, SWT.DROP_DOWN | SWT.READ_ONLY); + GridDataFactory.fillDefaults().grab(true, false) + .applyTo(milestoneCombo); + + Label assigneeLabel = new Label(leftArea, SWT.NONE); + assigneeLabel.setText(Messages.GitHubRepositoryQueryPage_AssigneeLabel); + + assigneeText = new Text(leftArea, SWT.BORDER | SWT.SINGLE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(assigneeText); + + Label mentionLabel = new Label(leftArea, SWT.NONE); + mentionLabel.setText(Messages.GitHubRepositoryQueryPage_MentionsLabel); + + mentionText = new Text(leftArea, SWT.BORDER | SWT.SINGLE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(mentionText); + + createLabelsArea(displayArea); + + loadRepository(); + + initialize(); + setControl(displayArea); + } + + private void initialize() { + IRepositoryQuery query = getQuery(); + if (query == null) + return; + + titleText.setText(query.getSummary()); + labelsViewer.setCheckedElements(QueryUtils.getAttributes( + IssueService.FILTER_LABELS, query).toArray()); + List<String> status = QueryUtils.getAttributes( + IssueService.FILTER_STATE, query); + closedButton.setSelection(status.contains(IssueService.STATE_CLOSED)); + openButton.setSelection(status.contains(IssueService.STATE_OPEN)); + } + + private boolean updateLabels() { + if (this.labelsViewer.getControl().isDisposed()) + return false; + + GitHubRepositoryConnector connector = GitHubRepositoryConnectorUI + .getCoreConnector(); + TaskRepository repository = getTaskRepository(); + boolean hasLabels = connector.hasCachedLabels(repository); + if (hasLabels) { + List<org.eclipse.mylyn.github.internal.Label> labels = connector + .getLabels(repository); + Collections.sort(labels, new LabelComparator()); + this.labelsViewer.setInput(labels); } + return hasLabels; + } + + private boolean updateMilestones() { + if (this.milestoneCombo.isDisposed()) + return false; + + GitHubRepositoryConnector connector = GitHubRepositoryConnectorUI + .getCoreConnector(); + TaskRepository repository = getTaskRepository(); + boolean hasMilestones = connector.hasCachedMilestones(repository); + if (hasMilestones) { + this.milestones = connector.getMilestones(repository); + this.milestoneCombo.removeAll(); + this.milestoneCombo + .add(Messages.GitHubRepositoryQueryPage_MilestoneNone); + for (Milestone milestone : milestones) + this.milestoneCombo.add(milestone.getTitle()); + + this.milestoneCombo.select(0); + } + return hasMilestones; + } - // create the query entry box - new Label(composite, SWT.NONE).setText("Query text:"); - queryText = new Text(composite, SWT.BORDER); - GridData gridData = new GridData(); - gridData.widthHint = 250; - queryText.setLayoutData(gridData); - String queryModelText = getQuery()==null?null:getQuery().getAttribute(ATTR_QUERY_TEXT); - queryText.setText(queryModelText==null?"":queryModelText); + private void refreshRepository() { + try { + getContainer().run(true, true, new IRunnableWithProgress() { + + public void run(IProgressMonitor monitor) + throws InvocationTargetException, InterruptedException { + Policy.monitorFor(monitor); + monitor.beginTask("", 2); //$NON-NLS-1$ + try { + GitHubRepositoryConnector connector = GitHubRepositoryConnectorUI + .getCoreConnector(); + TaskRepository repository = getTaskRepository(); + + monitor.setTaskName(Messages.GitHubRepositoryQueryPage_TaskLoadingLabels); + connector.refreshLabels(repository); + monitor.worked(1); + + monitor.setTaskName(Messages.GitHubRepositoryQueryPage_TaskLoadingMilestones); + connector.refreshMilestones(repository); + monitor.done(); + + PlatformUI.getWorkbench().getDisplay() + .asyncExec(new Runnable() { + + public void run() { + updateLabels(); + updateMilestones(); + initialize(); + } + }); + } catch (CoreException e) { + throw new InvocationTargetException(e); + } + } + }); + } catch (InvocationTargetException e) { + Throwable target = e.getTargetException(); + if (target instanceof CoreException) { + IStatus status = ((CoreException) target).getStatus(); + ErrorDialog.openError(getShell(), + Messages.GitHubRepositoryQueryPage_ErrorLoading, + target.getLocalizedMessage(), status); + } + } catch (InterruptedException ignore) { + // Ignore + } + } - setControl(composite); + private void loadRepository() { + boolean labelsLoaded = updateLabels(); + boolean milestonesLoaded = updateMilestones(); + if (!labelsLoaded || !milestonesLoaded) + refreshRepository(); } - @Override + /** + * @see org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositoryQueryPage#isPageComplete() + */ public boolean isPageComplete() { - setErrorMessage(null); - return true; + boolean complete = super.isPageComplete(); + if (complete) { + String message = null; + if (!openButton.getSelection() && !closedButton.getSelection()) + message = Messages.GitHubRepositoryQueryPage_ErrorStatus; + + setErrorMessage(message); + complete = message == null; + } + return complete; + } + + /** + * @see org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositoryQueryPage#getQueryTitle() + */ + public String getQueryTitle() { + return this.titleText != null ? this.titleText.getText() : null; } + /** + * @see org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositoryQueryPage#applyTo(org.eclipse.mylyn.tasks.core.IRepositoryQuery) + */ + public void applyTo(IRepositoryQuery query) { + query.setSummary(getQueryTitle()); + + List<String> statuses = new LinkedList<String>(); + if (openButton.getSelection()) + statuses.add(IssueService.STATE_OPEN); + if (closedButton.getSelection()) + statuses.add(IssueService.STATE_CLOSED); + QueryUtils.setAttribute(IssueService.FILTER_STATE, statuses, query); + + String assignee = this.assigneeText.getText().trim(); + if (assignee.length() > 0) + query.setAttribute(IssueService.FILTER_ASSIGNEE, assignee); + else + query.setAttribute(IssueService.FILTER_ASSIGNEE, null); + + String mentions = this.mentionText.getText().trim(); + if (assignee.length() > 0) + query.setAttribute(IssueService.FILTER_MENTIONED, mentions); + else + query.setAttribute(IssueService.FILTER_MENTIONED, null); + + int milestoneSelected = this.milestoneCombo.getSelectionIndex() - 1; + if (milestoneSelected >= 0) + query.setAttribute(IssueService.FILTER_MILESTONE, Integer + .toString(this.milestones.get(milestoneSelected) + .getNumber())); + else + query.setAttribute(IssueService.FILTER_MILESTONE, null); + + List<String> labels = new LinkedList<String>(); + for (Object label : labelsViewer.getCheckedElements()) + labels.add(label.toString()); + QueryUtils.setAttribute(IssueService.FILTER_LABELS, labels, query); + } } diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/Messages.java b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/Messages.java new file mode 100644 index 00000000..c34c79e6 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/Messages.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2011 GitHub Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Kevin Sawicki (GitHub Inc.) - initial API and implementation + *******************************************************************************/ +package org.eclipse.mylyn.github.ui.internal; + +import org.eclipse.osgi.util.NLS; + +/** + * NLS + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.mylyn.github.ui.internal.messages"; //$NON-NLS-1$ + + /** */ + public static String GitHubRepositoryQueryPage_ErrorLoading; + + /** */ + public static String GitHubRepositoryQueryPage_AssigneeLabel; + + /** */ + public static String GitHubRepositoryQueryPage_Description; + + /** */ + public static String GitHubRepositoryQueryPage_ErrorStatus; + + /** */ + public static String GitHubRepositoryQueryPage_LabelsLabel; + + /** */ + public static String GitHubRepositoryQueryPage_MentionsLabel; + + /** */ + public static String GitHubRepositoryQueryPage_MilestoneLabel; + + /** */ + public static String GitHubRepositoryQueryPage_MilestoneNone; + + /** */ + public static String GitHubRepositoryQueryPage_StatusClosed; + + /** */ + public static String GitHubRepositoryQueryPage_StatusLabel; + + /** */ + public static String GitHubRepositoryQueryPage_StatusOpen; + + /** */ + public static String GitHubRepositoryQueryPage_TaskLoadingLabels; + + /** */ + public static String GitHubRepositoryQueryPage_TaskLoadingMilestones; + + /** */ + public static String GitHubRepositoryQueryPage_TitleLabel; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/messages.properties b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/messages.properties new file mode 100644 index 00000000..2459e374 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/messages.properties @@ -0,0 +1,14 @@ +GitHubRepositoryQueryPage_ErrorLoading=Error loading labels and milestones +GitHubRepositoryQueryPage_AssigneeLabel=Assigned to: +GitHubRepositoryQueryPage_Description=Issue query settings +GitHubRepositoryQueryPage_ErrorStatus=Select a status +GitHubRepositoryQueryPage_LabelsLabel=Labels +GitHubRepositoryQueryPage_MentionsLabel=Mentioning: +GitHubRepositoryQueryPage_MilestoneLabel=Milestone: +GitHubRepositoryQueryPage_MilestoneNone=None +GitHubRepositoryQueryPage_StatusClosed=Closed +GitHubRepositoryQueryPage_StatusLabel=Status: +GitHubRepositoryQueryPage_StatusOpen=Open +GitHubRepositoryQueryPage_TaskLoadingLabels=Loading labels +GitHubRepositoryQueryPage_TaskLoadingMilestones=Loading milestones +GitHubRepositoryQueryPage_TitleLabel=Title: |
