blob: 9d7e59cd4b9bc6f2d295c2763cc2a6cef383f671 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.search2.internal.ui;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.ui.dialogs.SelectionDialog;
import org.eclipse.search.internal.ui.SearchPlugin;
import org.eclipse.search.internal.ui.SearchPreferencePage;
import org.eclipse.search.internal.ui.util.SWTUtil;
import org.eclipse.search.ui.ISearchQuery;
import org.eclipse.search.ui.ISearchResult;
/**
* Dialog that shows a list of items with icon and label.
*/
public class SearchHistorySelectionDialog extends SelectionDialog {
private static final int REMOVE_ID= IDialogConstants.CLIENT_ID+1;
private static final int WIDTH_IN_CHARACTERS= 55;
private List<ISearchResult> fInput;
private final List<ISearchResult> fRemovedEntries;
private TableViewer fViewer;
private Button fRemoveButton;
private boolean fIsOpenInNewView;
private Link fLink;
private static class HistoryConfigurationDialog extends StatusDialog {
private static final int DEFAULT_ID= 100;
private int fHistorySize;
private Text fHistorySizeTextField;
private final List<ISearchResult> fCurrentList;
private final List<ISearchResult> fCurrentRemoves;
public HistoryConfigurationDialog(Shell parent, List<ISearchResult> currentList, List<ISearchResult> removedEntries) {
super(parent);
fCurrentList= currentList;
fCurrentRemoves= removedEntries;
setTitle(SearchMessages.SearchHistorySelectionDialog_history_size_title);
fHistorySize= SearchPreferencePage.getHistoryLimit();
setHelpAvailable(false);
}
@Override
protected boolean isResizable() {
return true;
}
/*
* Overrides method from Dialog
*/
@Override
protected Control createDialogArea(Composite container) {
Composite ancestor= (Composite) super.createDialogArea(container);
GridLayout layout= (GridLayout) ancestor.getLayout();
layout.numColumns= 2;
ancestor.setLayout(layout);
Label limitText= new Label(ancestor, SWT.NONE);
limitText.setText(SearchMessages.SearchHistorySelectionDialog_history_size_description);
limitText.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
fHistorySizeTextField= new Text(ancestor, SWT.BORDER | SWT.RIGHT);
fHistorySizeTextField.setTextLimit(2);
fHistorySizeTextField.setText(String.valueOf(fHistorySize));
fHistorySizeTextField.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
validateDialogState();
}
});
GridData gridData= new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
gridData.widthHint= convertWidthInCharsToPixels(6);
fHistorySizeTextField.setLayoutData(gridData);
fHistorySizeTextField.setSelection(0, fHistorySizeTextField.getText().length());
applyDialogFont(ancestor);
return ancestor;
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
createButton(parent, DEFAULT_ID, SearchMessages.SearchHistorySelectionDialog_restore_default_button, false);
super.createButtonsForButtonBar(parent);
}
@Override
protected void buttonPressed(int buttonId) {
if (buttonId == DEFAULT_ID) {
IPreferenceStore store= SearchPlugin.getDefault().getPreferenceStore();
fHistorySizeTextField.setText(store.getDefaultString(SearchPreferencePage.LIMIT_HISTORY));
validateDialogState();
}
super.buttonPressed(buttonId);
}
protected final boolean validateDialogState() {
IStatus status= null;
try {
String historySize= fHistorySizeTextField.getText();
int size= Integer.parseInt(historySize);
if (size < 1 || size >= 100) {
status= new Status(IStatus.ERROR, SearchPlugin.getID(), IStatus.ERROR, SearchMessages.SearchHistorySelectionDialog_history_size_error, null);
} else {
fHistorySize= size;
}
} catch (NumberFormatException e) {
status= new Status(IStatus.ERROR, SearchPlugin.getID(), IStatus.ERROR, SearchMessages.SearchHistorySelectionDialog_history_size_error, null);
}
if (status == null) {
status= Status.OK_STATUS;
}
updateStatus(status);
return !status.matches(IStatus.ERROR);
}
@Override
protected void okPressed() {
IPreferenceStore store= SearchPlugin.getDefault().getPreferenceStore();
store.setValue(SearchPreferencePage.LIMIT_HISTORY, fHistorySize);
// establish history size
for (int i= fCurrentList.size() - 1; i >= fHistorySize; i--) {
fCurrentRemoves.add(fCurrentList.get(i));
fCurrentList.remove(i);
}
super.okPressed();
}
}
private static final class SearchesLabelProvider extends LabelProvider {
private ArrayList<Image> fImages= new ArrayList<>();
@Override
public String getText(Object element) {
return ((ISearchResult)element).getLabel();
}
@Override
public Image getImage(Object element) {
ImageDescriptor imageDescriptor= ((ISearchResult)element).getImageDescriptor();
if (imageDescriptor == null)
return null;
Image image= imageDescriptor.createImage();
fImages.add(image);
return image;
}
@Override
public void dispose() {
Iterator<Image> iter= fImages.iterator();
while (iter.hasNext())
iter.next().dispose();
fImages= null;
}
}
public SearchHistorySelectionDialog(Shell parent, List<ISearchResult> input) {
super(parent);
setTitle(SearchMessages.SearchesDialog_title);
setMessage(SearchMessages.SearchesDialog_message);
fInput= input;
fRemovedEntries= new ArrayList<>();
setHelpAvailable(false);
}
/**
* @return the isOpenInNewView
*/
public boolean isOpenInNewView() {
return fIsOpenInNewView;
}
@Override
protected IDialogSettings getDialogBoundsSettings() {
return SearchPlugin.getDefault().getDialogSettingsSection("DialogBounds_SearchHistorySelectionDialog"); //$NON-NLS-1$
}
@Override
protected int getDialogBoundsStrategy() {
return DIALOG_PERSISTSIZE;
}
/*
* Overrides method from Dialog
*/
@Override
protected Label createMessageArea(Composite composite) {
Composite parent= new Composite(composite, SWT.NONE);
GridLayout layout= new GridLayout();
layout.numColumns= 2;
layout.marginHeight= 0;
layout.marginWidth= 0;
parent.setLayout(layout);
parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Label label = new Label(parent,SWT.WRAP);
label.setText(getMessage());
GridData gd= new GridData(GridData.FILL_HORIZONTAL);
//gd.widthHint= convertWidthInCharsToPixels(WIDTH_IN_CHARACTERS);
label.setLayoutData(gd);
applyDialogFont(label);
return label;
}
@Override
public void create() {
super.create();
List<?> initialSelection= getInitialElementSelections();
if (initialSelection != null)
fViewer.setSelection(new StructuredSelection(initialSelection));
validateDialogState();
}
/*
* Overrides method from Dialog
*/
@Override
protected Control createDialogArea(Composite container) {
Composite ancestor= (Composite) super.createDialogArea(container);
createMessageArea(ancestor);
Composite parent= new Composite(ancestor, SWT.NONE);
GridLayout layout= new GridLayout();
layout.numColumns= 2;
layout.marginHeight= 0;
layout.marginWidth= 0;
parent.setLayout(layout);
parent.setLayoutData(new GridData(GridData.FILL_BOTH));
fViewer= new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION);
fViewer.setContentProvider(new ArrayContentProvider());
final Table table= fViewer.getTable();
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseDoubleClick(MouseEvent e) {
okPressed();
}
});
fViewer.setLabelProvider(new SearchesLabelProvider());
GridData gd= new GridData(GridData.FILL_BOTH);
gd.heightHint= convertHeightInCharsToPixels(15);
gd.widthHint= convertWidthInCharsToPixels(WIDTH_IN_CHARACTERS);
table.setLayoutData(gd);
fRemoveButton= new Button(parent, SWT.PUSH);
fRemoveButton.setText(SearchMessages.SearchesDialog_remove_label);
fRemoveButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
buttonPressed(REMOVE_ID);
}
});
fRemoveButton.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false));
SWTUtil.setButtonDimensionHint(fRemoveButton);
fViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
validateDialogState();
}
});
fLink= new Link(parent, SWT.NONE);
configureHistoryLink();
fLink.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
HistoryConfigurationDialog dialog= new HistoryConfigurationDialog(getShell(), fInput, fRemovedEntries);
if (dialog.open() == Window.OK) {
fViewer.refresh();
configureHistoryLink();
}
}
});
fLink.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
applyDialogFont(ancestor);
// set input & selections last, so all the widgets are created.
fViewer.setInput(fInput);
fViewer.getTable().setFocus();
return ancestor;
}
private void configureHistoryLink() {
int historyLimit= SearchPreferencePage.getHistoryLimit();
fLink.setText(Messages.format(SearchMessages.SearchHistorySelectionDialog_configure_link_label, new Integer(historyLimit)));
}
protected final void validateDialogState() {
IStructuredSelection sel= (IStructuredSelection) fViewer.getSelection();
int elementsSelected= sel.toList().size();
fRemoveButton.setEnabled(elementsSelected > 0);
Button okButton= getOkButton();
if (okButton != null) {
okButton.setEnabled(elementsSelected == 1);
}
Button openInNewButton= getButton(IDialogConstants.OPEN_ID);
if (openInNewButton != null) {
openInNewButton.setEnabled(elementsSelected == 1);
}
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OPEN_LABEL, true);
createButton(parent, IDialogConstants.OPEN_ID, SearchMessages.SearchHistorySelectionDialog_open_in_new_button, false);
createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
}
@Override
protected void buttonPressed(int buttonId) {
if (buttonId == REMOVE_ID) {
IStructuredSelection selection= (IStructuredSelection) fViewer.getSelection();
Iterator<?> searchResults= selection.iterator();
while (searchResults.hasNext()) {
ISearchResult curr= (ISearchResult) searchResults.next();
fRemovedEntries.add(curr);
fInput.remove(curr);
fViewer.remove(curr);
}
if (fViewer.getSelection().isEmpty() && !fInput.isEmpty()) {
fViewer.setSelection(new StructuredSelection(fInput.get(0)));
}
return;
}
if (buttonId == IDialogConstants.OPEN_ID) {
fIsOpenInNewView= true;
buttonId= IDialogConstants.OK_ID;
}
super.buttonPressed(buttonId);
}
/*
* Overrides method from Dialog
*/
@Override
protected void okPressed() {
// Build a list of selected children.
ISelection selection= fViewer.getSelection();
if (selection instanceof IStructuredSelection)
setResult(((IStructuredSelection) fViewer.getSelection()).toList());
// remove queries
for (Iterator<ISearchResult> iter= fRemovedEntries.iterator(); iter.hasNext();) {
ISearchResult result= iter.next();
ISearchQuery query= result.getQuery();
if (query != null) { // must not be null: invalid implementation of a search query
InternalSearchUI.getInstance().removeQuery(query);
}
}
super.okPressed();
}
}