/******************************************************************************* * Copyright (c) 2004, 2013 Tasktop Technologies and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * https://www.eclipse.org/legal/epl-2.0 * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * Tasktop Technologies - initial API and implementation * Frank Becker - improvements *******************************************************************************/ package org.eclipse.mylyn.internal.bugzilla.ui.search; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.fieldassist.ComboContentAdapter; import org.eclipse.jface.fieldassist.ContentProposalAdapter; import org.eclipse.jface.fieldassist.ControlDecoration; import org.eclipse.jface.fieldassist.FieldDecoration; import org.eclipse.jface.fieldassist.FieldDecorationRegistry; import org.eclipse.jface.fieldassist.IContentProposalProvider; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.mylyn.commons.ui.dialogs.AbstractInPlaceDialog; import org.eclipse.mylyn.commons.ui.dialogs.IInPlaceDialogListener; import org.eclipse.mylyn.commons.ui.dialogs.InPlaceDialogEvent; import org.eclipse.mylyn.commons.workbench.InPlaceCheckBoxTreeDialog; import org.eclipse.mylyn.commons.workbench.WorkbenchUtil; import org.eclipse.mylyn.commons.workbench.forms.SectionComposite; import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute; import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCustomField; import org.eclipse.mylyn.internal.bugzilla.core.BugzillaRepositoryConnector; import org.eclipse.mylyn.internal.bugzilla.core.BugzillaSearch; import org.eclipse.mylyn.internal.bugzilla.core.BugzillaSearch.Entry; import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants; import org.eclipse.mylyn.internal.bugzilla.core.RepositoryConfiguration; import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin; import org.eclipse.mylyn.tasks.core.IRepositoryQuery; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.ui.TasksUi; import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositoryQueryPage2; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; 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.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; /** * Bugzilla search page * * @author Mik Kersten (hardening of prototype) * @author Frank Becker */ public class BugzillaSearchPage extends AbstractRepositoryQueryPage2 implements Listener { private static final int HEIGHT_ATTRIBUTE_COMBO = 30; private static ArrayList previousSummaryPatterns = new ArrayList(20); private static ArrayList previousEmailPatterns = new ArrayList(20); private static ArrayList previousEmailPatterns2 = new ArrayList(20); private static ArrayList previousCommentPatterns = new ArrayList(20); private static ArrayList previousKeywords = new ArrayList(20); private static ArrayList previousWhiteboardPatterns = new ArrayList(20); private boolean firstTime = true; private IDialogSettings fDialogSettings; private static final String[] patternOperationText = { Messages.BugzillaSearchPage_OperationText_allwordssubstr, Messages.BugzillaSearchPage_OperationText_anywordssubstr, Messages.BugzillaSearchPage_OperationText_substring, Messages.BugzillaSearchPage_OperationText_casesubstring, Messages.BugzillaSearchPage_OperationText_allwords, Messages.BugzillaSearchPage_OperationText_anywords, Messages.BugzillaSearchPage_OperationText_regexp, Messages.BugzillaSearchPage_OperationText_notregexp }; private static final String[] patternOperationValues = { "allwordssubstr", "anywordssubstr", "substring", "casesubstring", "allwords", "anywords", "regexp", "notregexp" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ private static final String[] emailOperationText = { Messages.BugzillaSearchPage_EmailOperation_substring, Messages.BugzillaSearchPage_EmailOperation_exact, Messages.BugzillaSearchPage_EmailOperation_notequals, Messages.BugzillaSearchPage_EmailOperation_regexp, Messages.BugzillaSearchPage_EmailOperation_notregexp }; private static final String[] emailOperationValues = { "substring", "exact", "notequals", "regexp", "notregexp" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ private static final String[] keywordOperationText = { Messages.BugzillaSearchPage_all, Messages.BugzillaSearchPage_any, Messages.BugzillaSearchPage_none }; private static final String[] keywordOperationValues = { "allwords", "anywords", "nowords" }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ private static final String[] emailRoleValues = { "emailassigned_to1", "emailreporter1", "emailcc1", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ "emaillongdesc1", "emailqa_contact1" }; //$NON-NLS-1$ //$NON-NLS-2$ private static final String[] emailRoleValues2 = { "emailassigned_to2", "emailreporter2", "emailcc2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ "emaillongdesc2", "emailqa_contact2" }; //$NON-NLS-1$ //$NON-NLS-2$ private static final ArrayList chartFieldTextDefault = new ArrayList() { private static final long serialVersionUID = 1974092160992399001L; { add(Messages.BugzillaSearchPage_Field_Noop); add(Messages.BugzillaSearchPage_Field_Alias); add(Messages.BugzillaSearchPage_Field_AssignedTo); add(Messages.BugzillaSearchPage_Field_Attachment_creator); add(Messages.BugzillaSearchPage_Field_Attachment_data); add(Messages.BugzillaSearchPage_Field_Attachment_description); add(Messages.BugzillaSearchPage_Field_Attachment_filename); add(Messages.BugzillaSearchPage_Field_Attachment_is_a_URL); add(Messages.BugzillaSearchPage_Field_Attachment_is_obsolete); add(Messages.BugzillaSearchPage_Field_Attachment_is_patch); add(Messages.BugzillaSearchPage_Field_Attachment_is_private); add(Messages.BugzillaSearchPage_Field_Attachment_mime_type); add(Messages.BugzillaSearchPage_Field_Blocks); add(Messages.BugzillaSearchPage_Field_Bug); add(Messages.BugzillaSearchPage_Field_CC); add(Messages.BugzillaSearchPage_Field_CC_Accessible); add(Messages.BugzillaSearchPage_Field_Classification); add(Messages.BugzillaSearchPage_Field_Comment); add(Messages.BugzillaSearchPage_Field_Comment_is_private); add(Messages.BugzillaSearchPage_Field_Commenter); add(Messages.BugzillaSearchPage_Field_Component); add(Messages.BugzillaSearchPage_Field_Content); add(Messages.BugzillaSearchPage_Field_Creation_date); add(Messages.BugzillaSearchPage_Field_Days_since_bug_changed); add(Messages.BugzillaSearchPage_Field_Depends_on); add(Messages.BugzillaSearchPage_Field_drop_down_custom_field); add(Messages.BugzillaSearchPage_Field_Ever_Confirmed); add(Messages.BugzillaSearchPage_Field_Flag); add(Messages.BugzillaSearchPage_Field_Flag_Requestee); add(Messages.BugzillaSearchPage_Field_Flag_Setter); add(Messages.BugzillaSearchPage_Field_free_text_custom_field); add(Messages.BugzillaSearchPage_Field_Group); add(Messages.BugzillaSearchPage_Field_Keywords); add(Messages.BugzillaSearchPage_Field_Last_changed_date); add(Messages.BugzillaSearchPage_Field_OS_Version); add(Messages.BugzillaSearchPage_Field_Platform); add(Messages.BugzillaSearchPage_Field_Priority); add(Messages.BugzillaSearchPage_Field_Product); add(Messages.BugzillaSearchPage_Field_QAContact); add(Messages.BugzillaSearchPage_Field_ReportedBy); add(Messages.BugzillaSearchPage_Field_Reporter_Accessible); add(Messages.BugzillaSearchPage_Field_Resolution); add(Messages.BugzillaSearchPage_Field_Severity); add(Messages.BugzillaSearchPage_Field_Status); add(Messages.BugzillaSearchPage_Field_Status_Whiteboard); add(Messages.BugzillaSearchPage_Field_Summary); add(Messages.BugzillaSearchPage_Field_Target_Milestone); add(Messages.BugzillaSearchPage_Field_Time_Since_Assignee_Touched); add(Messages.BugzillaSearchPage_Field_URL); add(Messages.BugzillaSearchPage_Field_Version); add(Messages.BugzillaSearchPage_Field_Votes); } }; private static final ArrayList chartFieldValuesDefault = new ArrayList() { private static final long serialVersionUID = 9135403539678279982L; { add("noop"); //$NON-NLS-1$ add("alias"); //$NON-NLS-1$ add("assigned_to"); //$NON-NLS-1$ add("attachments.submitter"); //$NON-NLS-1$ add("attach_data.thedata"); //$NON-NLS-1$ add("attachments.description"); //$NON-NLS-1$ add("attachments.filename"); //$NON-NLS-1$ add("attachments.isurl"); //$NON-NLS-1$ add("attachments.isobsolete"); //$NON-NLS-1$ add("attachments.ispatch"); //$NON-NLS-1$ add("attachments.isprivate"); //$NON-NLS-1$ add("attachments.mimetype"); //$NON-NLS-1$ add("blocked"); //$NON-NLS-1$ add("bug_id"); //$NON-NLS-1$ add("cc"); //$NON-NLS-1$ add("cclist_accessible"); //$NON-NLS-1$ add("classification"); //$NON-NLS-1$ add("longdesc"); //$NON-NLS-1$ add("longdescs.isprivate"); //$NON-NLS-1$ add("commenter"); //$NON-NLS-1$ add("component"); //$NON-NLS-1$ add("content"); //$NON-NLS-1$ add("creation_ts"); //$NON-NLS-1$ add("days_elapsed"); //$NON-NLS-1$ add("dependson"); //$NON-NLS-1$ add("cf_dropdown"); //$NON-NLS-1$ add("everconfirmed"); //$NON-NLS-1$ add("flagtypes.name"); //$NON-NLS-1$ add("requestees.login_name"); //$NON-NLS-1$ add("setters.login_name"); //$NON-NLS-1$ add("cf_freetext"); //$NON-NLS-1$ add("bug_group"); //$NON-NLS-1$ add("keywords"); //$NON-NLS-1$ add("delta_ts"); //$NON-NLS-1$ add("op_sys"); //$NON-NLS-1$ add("rep_platform"); //$NON-NLS-1$ add("priority"); //$NON-NLS-1$ add("product"); //$NON-NLS-1$ add("qa_contact"); //$NON-NLS-1$ add("reporter"); //$NON-NLS-1$ add("reporter_accessible"); //$NON-NLS-1$ add("resolution"); //$NON-NLS-1$ add("bug_severity"); //$NON-NLS-1$ add("bug_status"); //$NON-NLS-1$ add("status_whiteboard"); //$NON-NLS-1$ add("short_desc"); //$NON-NLS-1$ add("target_milestone"); //$NON-NLS-1$ add("owner_idle_time"); //$NON-NLS-1$ add("bug_file_loc"); //$NON-NLS-1$ add("version"); //$NON-NLS-1$ add("votes"); //$NON-NLS-1$ } }; private static final String[] chartOperationText = { Messages.BugzillaSearchPage_Operation_Noop, Messages.BugzillaSearchPage_Operation_is_equal_to, Messages.BugzillaSearchPage_Operation_is_not_equal_to, Messages.BugzillaSearchPage_Operation_is_equal_to_any_of_the_strings, Messages.BugzillaSearchPage_Operation_contains_the_string, Messages.BugzillaSearchPage_Operation_contains_the_string_exact_case, Messages.BugzillaSearchPage_Operation_does_not_contain_the_string, Messages.BugzillaSearchPage_Operation_contains_any_of_the_strings, Messages.BugzillaSearchPage_Operation_contains_all_of_the_strings, Messages.BugzillaSearchPage_Operation_contains_none_of_the_strings, Messages.BugzillaSearchPage_Operation_contains_regexp, Messages.BugzillaSearchPage_Operation_does_not_contain_regexp, Messages.BugzillaSearchPage_Operation_is_less_than, Messages.BugzillaSearchPage_Operation_is_greater_than, Messages.BugzillaSearchPage_Operation_contains_any_of_he_words, Messages.BugzillaSearchPage_Operation_contains_all_of_the_words, Messages.BugzillaSearchPage_Operation_contains_none_of_the_words, Messages.BugzillaSearchPage_Operation_changed_before, Messages.BugzillaSearchPage_Operation_changed_after, Messages.BugzillaSearchPage_Operation_changed_from, Messages.BugzillaSearchPage_Operation_changed_to, Messages.BugzillaSearchPage_Operation_changed_by, Messages.BugzillaSearchPage_Operation_matches }; private static final String[] chartOperationValues = { "noop", "equals", "notequals", "anyexact", "substring", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ "casesubstring", "notsubstring", "anywordssubstr", "allwordssubstr", "nowordssubstr", "regexp", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ "notregexp", "lessthan", "greaterthan", "anywords", "allwords", "nowords", "changedbefore", "changedafter", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ "changedfrom", "changedto", "changedby", "matches" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ private final static String REGEXP_CHART_EXPR = "(field|type|value)([0-9]+)-([0-9]+)-([0-9]+)"; //$NON-NLS-1$ private static final Pattern PATTERN_CHART_EXPR = Pattern.compile(REGEXP_CHART_EXPR, Pattern.CASE_INSENSITIVE); private final static String REGEXP_CHART_NEGATE = "(negate)([0-9]+)"; //$NON-NLS-1$ private static final Pattern PATTERN_CHART_NEGATE = Pattern.compile(REGEXP_CHART_NEGATE, Pattern.CASE_INSENSITIVE); private IRepositoryQuery originalQuery = null; protected boolean restoring = false; private boolean restoreQueryOptions = true; protected Combo summaryPattern; protected Combo summaryOperation; protected List product; protected List os; protected List hardware; protected List priority; protected List severity; protected List resolution; protected List status; protected Combo commentOperation; protected Combo commentPattern; protected List component; protected List version; protected List target; protected Combo emailOperation; protected Combo emailOperation2; protected Combo emailPattern; protected Combo emailPattern2; protected Button[] emailButtons; protected Button[] emailButtons2; private Combo keywords; private Combo keywordsOperation; protected Combo whiteboardPattern; private Combo whiteboardOperation; protected Text daysText; protected String[] chartFieldText; protected String[] chartFieldValues; /** Index of the saved query to run */ protected int selIndex; // Dialog store taskId constants protected final static String PAGE_NAME = "BugzillaSearchPage"; //$NON-NLS-1$ private final FormToolkit toolkit; private ExpandableComposite moreOptionsSection; private ExpandableComposite chartSection; private SectionComposite scrolledComposite; private final ArrayList charts = new ArrayList(1); private final ArrayList errorDecorations = new ArrayList(); private class ChartControls { private final Combo field; private final Combo operation; private final Combo value; public ChartControls(Combo field, Combo operation, Combo value) { super(); this.field = field; this.operation = operation; this.value = value; } public Combo getField() { return field; } public Combo getOperation() { return operation; } public Combo getValue() { return value; } } private final ArrayList>> chartControls = new ArrayList>>(); private final ArrayList