blob: 94282fbcc741d3ba7e4670833dac5ca8b2f9dfdd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2009 QNX Software Systems 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:
* QNX - Initial API and implementation
* IBM Corporation
*******************************************************************************/
/* -- ST-Origin --
* Source folder: org.eclipse.cdt.ui/src
* Class: org.eclipse.cdt.internal.ui.search.PDOMSearchPage
* Version: 1.9
*/
package org.eclipse.ptp.internal.rdt.ui.search;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.PatternSyntaxException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.internal.ui.search.CSearchMessages;
import org.eclipse.cdt.internal.ui.search.CSearchUtil;
import org.eclipse.cdt.internal.ui.search.PDOMSearchPatternQuery;
import org.eclipse.cdt.internal.ui.util.Messages;
import org.eclipse.cdt.internal.ui.util.RowLayouter;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.DialogPage;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ptp.internal.rdt.core.model.Scope;
import org.eclipse.ptp.internal.rdt.core.search.RemoteSearchQuery;
import org.eclipse.ptp.internal.rdt.ui.RDTHelpContextIds;
import org.eclipse.ptp.rdt.core.resources.RemoteNature;
import org.eclipse.ptp.rdt.core.services.IRDTServiceConstants;
import org.eclipse.ptp.rdt.ui.UIPlugin;
import org.eclipse.ptp.rdt.ui.serviceproviders.IIndexServiceProvider2;
import org.eclipse.ptp.services.core.IService;
import org.eclipse.ptp.services.core.IServiceConfiguration;
import org.eclipse.ptp.services.core.IServiceModelManager;
import org.eclipse.ptp.services.core.IServiceProvider;
import org.eclipse.ptp.services.core.ServiceModelManager;
import org.eclipse.search.ui.ISearchPage;
import org.eclipse.search.ui.ISearchPageContainer;
import org.eclipse.search.ui.ISearchQuery;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.swt.SWT;
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.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.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;
public class RemoteSearchPage extends DialogPage implements ISearchPage {
public static final String EXTENSION_ID = UIPlugin.PLUGIN_ID + ".searchPage"; //$NON-NLS-1$
//Dialog store id constants
private final static String PAGE_NAME = "PDOMSearchPage"; //$NON-NLS-1$
private final static String STORE_CASE_SENSITIVE = "caseSensitive"; //$NON-NLS-1$
private final static String STORE_PREVIOUS_PATTERNS = "previousPatterns"; //$NON-NLS-1$
private final static String STORE_SEARCH_FLAGS = "searchFlags"; //$NON-NLS-1$
/** Preference key for external marker enablement */
public final static String EXTERNALMATCH_ENABLED = "externMatchEnable"; //$NON-NLS-1$
/** Preference key for external marker visibilty */
public final static String EXTERNALMATCH_VISIBLE = "externMatchVisible"; //$NON-NLS-1$
private static final String[] searchForText= {
CSearchMessages.CSearchPage_searchFor_classStruct,
CSearchMessages.CSearchPage_searchFor_function,
CSearchMessages.CSearchPage_searchFor_variable,
CSearchMessages.CSearchPage_searchFor_union,
CSearchMessages.CSearchPage_searchFor_method,
CSearchMessages.CSearchPage_searchFor_field,
CSearchMessages.CSearchPage_searchFor_enum,
CSearchMessages.CSearchPage_searchFor_enumr,
CSearchMessages.CSearchPage_searchFor_namespace,
CSearchMessages.CSearchPage_searchFor_typedef,
CSearchMessages.CSearchPage_searchFor_macro,
CSearchMessages.CSearchPage_searchFor_any
};
// These must be in the same order as the Text
private static final Integer[] searchForData = {
new Integer(PDOMSearchPatternQuery.FIND_CLASS_STRUCT),
new Integer(PDOMSearchPatternQuery.FIND_FUNCTION),
new Integer(PDOMSearchPatternQuery.FIND_VARIABLE),
new Integer(PDOMSearchPatternQuery.FIND_UNION),
new Integer(PDOMSearchPatternQuery.FIND_METHOD),
new Integer(PDOMSearchPatternQuery.FIND_FIELD),
new Integer(PDOMSearchPatternQuery.FIND_ENUM),
new Integer(PDOMSearchPatternQuery.FIND_ENUMERATOR),
new Integer(PDOMSearchPatternQuery.FIND_NAMESPACE),
new Integer(PDOMSearchPatternQuery.FIND_TYPEDEF),
new Integer(PDOMSearchPatternQuery.FIND_MACRO),
new Integer(PDOMSearchPatternQuery.FIND_ALL_TYPES)
};
// the index of FIND_ALL_TYPES
private static final int searchAllButtonIndex = searchForData.length - 1;
private static String[] limitToText = {
CSearchMessages.CSearchPage_limitTo_declarations,
CSearchMessages.CSearchPage_limitTo_definitions,
CSearchMessages.CSearchPage_limitTo_references,
CSearchMessages.CSearchPage_limitTo_allOccurrences
};
// Must be in the same order as the text
private static Integer[] limitToData = {
new Integer(RemoteSearchQuery.FIND_DECLARATIONS),
new Integer(RemoteSearchQuery.FIND_DEFINITIONS),
new Integer(RemoteSearchQuery.FIND_REFERENCES),
new Integer(RemoteSearchQuery.FIND_ALL_OCCURANCES),
};
// The index of FIND_ALL_OCCURANCES
private static final int limitToAllButtonIndex = limitToData.length - 1;
private Combo patternCombo;
private String[] previousPatterns;
private Button caseSensitiveButton;
private Button[] searchForButtons;
private Button[] limitToButtons;
private boolean firstTime = true;
private IStructuredSelection structuredSelection;
private ITextSelection textSelection;
private ISearchPageContainer pageContainer;
private IStatusLineManager fLineManager;
private static ICProject getProject(Object object) {
if (object instanceof ICElement)
return ((ICElement)object).getCProject();
else if (object instanceof IResource) {
return CoreModel.getDefault().create(((IResource)object).getProject());
}
else
return null;
}
public boolean performAction() {
fLineManager.setErrorMessage(null);
boolean isCaseSensitive = caseSensitiveButton.getSelection();
// get the pattern and turn it into a regular expression
String patternStr = patternCombo.getText();
// Get search flags
int searchFlags = 0;
if (searchForButtons[searchAllButtonIndex].getSelection())
searchFlags |= PDOMSearchPatternQuery.FIND_ALL_TYPES;
else {
for (int i = 0; i < searchForButtons.length; ++i) {
if (searchForButtons[i].getSelection())
searchFlags |= ((Integer)searchForButtons[i].getData()).intValue();
}
}
for (int i = 0; i < limitToButtons.length; ++i) {
if (limitToButtons[i].getSelection())
searchFlags |= ((Integer)limitToButtons[i].getData()).intValue();
}
// get the list of elements for the scope
List elements = new ArrayList();
String scopeDescription = ""; //$NON-NLS-1$
switch (getContainer().getSelectedScope()) {
case ISearchPageContainer.SELECTED_PROJECTS_SCOPE:
if (structuredSelection != null) {
scopeDescription = CSearchMessages.ProjectScope;
for (Iterator i = structuredSelection.iterator(); i.hasNext();) {
ICProject project = getProject(i.next());
if (project != null)
elements.add(project);
}
}
break;
case ISearchPageContainer.SELECTION_SCOPE:
if( structuredSelection != null) {
scopeDescription = CSearchMessages.SelectionScope;
for (Iterator i = structuredSelection.iterator(); i.hasNext();) {
Object obj = i.next();
if (obj instanceof IResource)
elements.add(CoreModel.getDefault().create((IResource)obj));
else if (obj instanceof ICElement)
elements.add(obj);
}
break;
}
break;
case ISearchPageContainer.WORKSPACE_SCOPE:
scopeDescription = CSearchMessages.WorkspaceScope;
// Don't add anything
break;
case ISearchPageContainer.WORKING_SET_SCOPE:
IWorkingSet[] workingSets= getContainer().getSelectedWorkingSets();
scopeDescription = Messages.format(CSearchMessages.WorkingSetScope, CSearchUtil.toString(workingSets));
for (int i = 0; i < workingSets.length; ++i) {
IAdaptable[] wsElements = workingSets[i].getElements();
for (int j = 0; j < wsElements.length; ++j) {
ICProject project = getProject(wsElements[j]);
if (project != null)
elements.add(project);
}
}
break;
}
ICElement[] scope
= elements.isEmpty()
? null
: (ICElement[])elements.toArray(new ICElement[elements.size()]);
try {
// TODO: Where are we going to find an IProject when doing a global search?
IProject project = null;
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
for (IProject p : projects) {
try {
if (p.isOpen() && p.hasNature(RemoteNature.REMOTE_NATURE_ID)) {
project = p;
}
} catch (CoreException e) {
CUIPlugin.log(e);
}
}
if (project == null) {
return false;
}
IServiceModelManager smm = ServiceModelManager.getInstance();
IServiceConfiguration serviceConfig = smm.getActiveConfiguration(project);
IService indexingService = smm.getService(IRDTServiceConstants.SERVICE_C_INDEX);
IServiceProvider serviceProvider = serviceConfig.getServiceProvider(indexingService);
if (!(serviceProvider instanceof IIndexServiceProvider2)) {
return false;
}
ISearchService service = ((IIndexServiceProvider2) serviceProvider).getSearchService();
ISearchQuery job = service.createSearchPatternQuery(Scope.WORKSPACE_ROOT_SCOPE, scope, scopeDescription, patternStr, isCaseSensitive, searchFlags);
NewSearchUI.activateSearchResultView();
NewSearchUI.runQueryInBackground(job);
} catch (PatternSyntaxException e) {
fLineManager.setErrorMessage(CSearchMessages.PDOMSearch_query_pattern_error);
return false;
}
// Save our settings
IDialogSettings settings = getDialogSettings();
settings.put(STORE_CASE_SENSITIVE, isCaseSensitive);
if (previousPatterns == null)
previousPatterns = new String[] { patternStr };
else {
// Add only if we don't have it already
boolean addit = true;
for (int i = 0; i < previousPatterns.length; ++i) {
if (patternStr.equals(previousPatterns[i])) {
addit = false;
break;
}
}
if (addit) {
// Insert it into the beginning of the list
String[] newPatterns = new String[previousPatterns.length + 1];
System.arraycopy(previousPatterns, 0, newPatterns, 1, previousPatterns.length);
newPatterns[0] = patternStr;
previousPatterns = newPatterns;
}
}
settings.put(STORE_PREVIOUS_PATTERNS, previousPatterns);
settings.put(STORE_SEARCH_FLAGS, searchFlags);
return true;
}
public void createControl(Composite parent) {
initializeDialogUnits( parent );
GridData gd;
Composite result = new Composite( parent, SWT.NONE );
GridLayout layout = new GridLayout( 2, false );
layout.horizontalSpacing = 10;
result.setLayout( layout );
result.setLayoutData( new GridData(GridData.FILL_HORIZONTAL) );
RowLayouter layouter = new RowLayouter( layout.numColumns );
gd = new GridData();
gd.horizontalAlignment = GridData.FILL;
gd.verticalAlignment = GridData.VERTICAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_FILL;
layouter.setDefaultGridData( gd, 0 );
layouter.setDefaultGridData( gd, 1 );
layouter.setDefaultSpan();
layouter.perform( createExpression(result) );
layouter.perform( createSearchFor(result), createLimitTo(result), -1 );
setControl( result );
fLineManager = getStatusLineManager();
Dialog.applyDialogFont( result );
PlatformUI.getWorkbench().getHelpSystem().setHelp(result, RDTHelpContextIds.REMOTE_C_CPP_SEARCH);
}
private IStatusLineManager getStatusLineManager(){
IWorkbenchWindow wbWindow= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (wbWindow != null) {
IWorkbenchPage page= wbWindow.getActivePage();
if (page != null) {
IWorkbenchPartSite workbenchSite = page.getActivePart().getSite();
if (workbenchSite instanceof IViewSite){
return ((IViewSite) workbenchSite).getActionBars().getStatusLineManager();
}
else if (workbenchSite instanceof IEditorSite){
return ((IEditorSite) workbenchSite).getActionBars().getStatusLineManager();
}
}
}
return null;
}
private Control createExpression( Composite parent ) {
Composite result = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
result.setLayout(layout);
GridData gd = new GridData( GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL );
gd.horizontalSpan = 2;
gd.horizontalIndent = 0;
result.setLayoutData( gd );
// Pattern text + info
Label label = new Label( result, SWT.LEFT );
label.setText( CSearchMessages.CSearchPage_expression_label );
gd = new GridData( GridData.BEGINNING );
gd.horizontalSpan = 2;
label.setLayoutData( gd );
// Pattern combo
patternCombo = new Combo( result, SWT.SINGLE | SWT.BORDER );
patternCombo.addSelectionListener( new SelectionAdapter() {
public void widgetSelected( SelectionEvent e ) {
//handlePatternSelected();
}
});
patternCombo.addModifyListener( new ModifyListener() {
public void modifyText( ModifyEvent e ) {
setPerformActionEnabled();
}
});
gd = new GridData( GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL );
gd.horizontalIndent = -gd.horizontalIndent;
patternCombo.setLayoutData( gd );
// Ignore case checkbox
caseSensitiveButton= new Button(result, SWT.CHECK);
caseSensitiveButton.setText(CSearchMessages.CSearchPage_expression_caseSensitive);
gd= new GridData();
caseSensitiveButton.setLayoutData(gd);
caseSensitiveButton.addSelectionListener( new SelectionAdapter() {
public void widgetSelected( SelectionEvent e ) {
// isCaseSensitive = caseSensitiveButton.getSelection();
setPerformActionEnabled();
}
});
return result;
}
private Control createLimitTo( Composite parent ) {
Group result = new Group(parent, SWT.NONE);
result.setText( CSearchMessages.CSearchPage_limitTo_label );
GridLayout layout = new GridLayout();
layout.numColumns = 2;
result.setLayout( layout );
limitToButtons = new Button[limitToText.length];
for( int i = 0; i < limitToText.length; i++ ){
Button button = new Button(result, SWT.RADIO);
button.setText( limitToText[i] );
button.setData( limitToData[i] );
limitToButtons[i] = button;
}
return result;
}
private Control createSearchFor(Composite parent) {
Group result= new Group(parent, SWT.NONE);
result.setText(CSearchMessages.CSearchPage_searchFor_label);
GridLayout layout= new GridLayout();
layout.numColumns= 3;
result.setLayout(layout);
SelectionAdapter searchForSelectionAdapter = new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
Button me = (Button)event.widget;
if (me == searchForButtons[searchAllButtonIndex]) {
if (me.getSelection()) {
for (int i = 0; i < searchForButtons.length; ++i) {
if (i != searchAllButtonIndex) {
searchForButtons[i].setSelection(true);
searchForButtons[i].setEnabled(false);
}
}
} else {
for (int i = 0; i < searchForButtons.length; ++i) {
if (i != searchAllButtonIndex) {
searchForButtons[i].setSelection(false);
searchForButtons[i].setEnabled(true);
}
}
}
}
setPerformActionEnabled();
}
};
searchForButtons= new Button[searchForText.length];
for (int i= 0; i < searchForText.length; i++) {
Button button= new Button(result, SWT.CHECK);
button.setText(searchForText[i]);
button.setData(searchForData[i]);
button.addSelectionListener(searchForSelectionAdapter);
searchForButtons[i]= button;
}
return result;
}
public void setContainer(ISearchPageContainer container) {
pageContainer = container;
}
private ISearchPageContainer getContainer() {
return pageContainer;
}
private void setPerformActionEnabled() {
boolean enable = true;
// Need a text string to search
if (patternCombo.getText().length() == 0)
enable = false;
// Need a type
boolean any = false;
for (int i = 0; i < searchForButtons.length; ++i)
if (searchForButtons[i].getSelection()) {
any = true;
break;
}
if (!any)
enable = false;
getContainer().setPerformActionEnabled(enable);
}
private IDialogSettings getDialogSettings() {
IDialogSettings settings = CUIPlugin.getDefault().getDialogSettings();
IDialogSettings searchSettings = settings.getSection( PAGE_NAME );
if( searchSettings == null )
searchSettings = settings.addNewSection( PAGE_NAME );
return searchSettings;
}
public void setVisible(boolean visible) {
if (visible) {
if (firstTime) {
firstTime= false;
IDialogSettings settings = getDialogSettings();
int searchFlags = PDOMSearchPatternQuery.FIND_ALL_TYPES | RemoteSearchQuery.FIND_ALL_OCCURANCES;
try {
searchFlags = settings.getInt(STORE_SEARCH_FLAGS);
} catch (NumberFormatException e) {
// was uninitialized, assume the defaults
}
previousPatterns = settings.getArray(STORE_PREVIOUS_PATTERNS);
if (previousPatterns != null)
patternCombo.setItems(previousPatterns);
// Initialize the selection
ISelection selection = getContainer().getSelection();
if (selection instanceof IStructuredSelection) {
structuredSelection = (IStructuredSelection)selection;
Object obj = structuredSelection.getFirstElement();
if (obj instanceof ICElement) {
ICElement element = (ICElement)obj;
patternCombo.setText(element.getElementName());
// Clear the type flags so we can set them correctly for what we have selected
searchFlags = searchFlags & ~PDOMSearchPatternQuery.FIND_ALL_TYPES;
switch (element.getElementType()) {
case ICElement.C_CLASS:
case ICElement.C_STRUCT:
searchFlags |= PDOMSearchPatternQuery.FIND_CLASS_STRUCT;
break;
case ICElement.C_FUNCTION:
searchFlags |= PDOMSearchPatternQuery.FIND_FUNCTION;
break;
case ICElement.C_VARIABLE:
searchFlags |= PDOMSearchPatternQuery.FIND_VARIABLE;
break;
case ICElement.C_UNION:
searchFlags |= PDOMSearchPatternQuery.FIND_UNION;
break;
case ICElement.C_METHOD:
searchFlags |= PDOMSearchPatternQuery.FIND_METHOD;
break;
case ICElement.C_FIELD:
searchFlags |= PDOMSearchPatternQuery.FIND_FIELD;
break;
case ICElement.C_ENUMERATION:
searchFlags |= PDOMSearchPatternQuery.FIND_ENUM;
break;
case ICElement.C_ENUMERATOR:
searchFlags |= PDOMSearchPatternQuery.FIND_ENUMERATOR;
break;
case ICElement.C_NAMESPACE:
searchFlags |= PDOMSearchPatternQuery.FIND_NAMESPACE;
break;
case ICElement.C_TYPEDEF:
searchFlags |= PDOMSearchPatternQuery.FIND_TYPEDEF;
break;
case ICElement.C_MACRO:
searchFlags |= PDOMSearchPatternQuery.FIND_MACRO;
break;
default:
// Not sure, set to all
searchFlags |= PDOMSearchPatternQuery.FIND_ALL_TYPES;
patternCombo.setText(""); //$NON-NLS-1$
}
}
} else if (selection instanceof ITextSelection) {
textSelection = (ITextSelection)selection;
patternCombo.setText(textSelection.getText());
// TODO it might be good to do a selection parse to ensure that
// the selection is valid.
}
caseSensitiveButton.setSelection(settings.getBoolean(STORE_CASE_SENSITIVE));
if ((searchFlags & PDOMSearchPatternQuery.FIND_ALL_TYPES) == PDOMSearchPatternQuery.FIND_ALL_TYPES) {
searchForButtons[searchAllButtonIndex].setSelection(true);
for (int i = 0; i < searchForButtons.length; ++i) {
if (i != searchAllButtonIndex) {
searchForButtons[i].setSelection(true);
searchForButtons[i].setEnabled(false);
}
}
} else {
searchForButtons[searchAllButtonIndex].setSelection(false);
for (int i = 0; i < searchForButtons.length; ++i) {
if (i != searchAllButtonIndex) {
searchForButtons[i].setSelection(
(searchFlags & ((Integer)searchForButtons[i].getData()).intValue()) != 0);
}
}
}
if ((searchFlags & RemoteSearchQuery.FIND_ALL_OCCURANCES) == RemoteSearchQuery.FIND_ALL_OCCURANCES) {
limitToButtons[limitToAllButtonIndex].setSelection(true);
} else {
limitToButtons[limitToAllButtonIndex].setSelection(false);
for (int i = 0; i < limitToButtons.length - 2; ++i) {
limitToButtons[i].setSelection(
(searchFlags & ((Integer)limitToButtons[i].getData()).intValue()) != 0);
}
}
}
patternCombo.setFocus();
setPerformActionEnabled();
}
super.setVisible(visible);
}
}