/** * <p>Copyright: Copyright (c) 2009</p> * <p>Company: �������ӹɷ����޹�˾</p> */ package com.hundsun.ares.studio.ui.search; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IAdaptable; 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.search.ui.ISearchPage; import org.eclipse.search.ui.ISearchPageContainer; 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.layout.RowData; import org.eclipse.swt.layout.RowLayout; 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.IWorkingSet; import com.hundsun.ares.studio.core.ARESCore; import com.hundsun.ares.studio.core.IARESElement; import com.hundsun.ares.studio.core.IARESProject; import com.hundsun.ares.studio.ui.ARESUI; /** * * @author liaogc */ public class ARESSearchPage extends DialogPage implements ISearchPage { private final static String STORE_CASE_SENSITIVE = "CASE_SENSITIVE"; private final static String STORE_HISTORY_SIZE = "HISTORY_SIZE"; private final static String PAGE_NAME = "ARESTableDesignSearchPage"; private final static String STORE_SEARCH_RES_TYPES = "SEARCH_RES_TYPES"; private final static String STORE_SEARCH_ITEMS = "SEARCH_ITEMS"; private final static String STORE_HISTORY = "HISTORY"; private static final int HISTORY_SIZE = 12; private IDialogSettings dialogSettings; private ISearchPageContainer container; private List<SearchPatternData> previousSearchPatterns = new ArrayList<SearchPatternData>(); private List<Button> btSearchResTypes = new ArrayList<Button>(); private List<Button> btSearchItems = new ArrayList<Button>(); private Combo pattern; private Button caseSensitive; private boolean isCaseSensitive; private boolean fFirstTime= true; /* (non-Javadoc) * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ @Override public void createControl(Composite parent) { initializeDialogUnits(parent); readConfiguration(); Composite result= new Composite(parent, SWT.NONE); GridLayout layout= new GridLayout(2, false); layout.horizontalSpacing= 10; result.setLayout(layout); Control expressionComposite= createExpression(result); expressionComposite.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1)); Label separator= new Label(result, SWT.NONE); separator.setVisible(false); GridData data= new GridData(GridData.FILL, GridData.FILL, false, false, 2, 1); data.heightHint= convertHeightInCharsToPixels(1) / 3; separator.setLayoutData(data); Control searchResTypes = createSearchResTypes(result); GridData resTypeGridData = new GridData(GridData.FILL, GridData.FILL, true, false, 2, 1); int resSize = SearcherUitl.getSearchCResTypes().size(); int hRes = (((int)Math.sqrt(resSize))+1)* 20 ; resTypeGridData.heightHint = hRes ; searchResTypes.setLayoutData(resTypeGridData); Control searchItems = createSearchItems(result); GridData searchItemsData = new GridData(GridData.FILL, GridData.FILL, true, false, 2, 1); int itemsSize = SearcherUitl.getSearchItems().size(); int hItem = (((int)Math.sqrt(itemsSize))+1)* 20 ; searchItemsData.heightHint = hItem ; searchItems.setLayoutData(searchItemsData); setControl(result); Dialog.applyDialogFont(result); } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean) */ @Override public void setVisible(boolean visible) { if (visible && pattern != null) { if (fFirstTime) { fFirstTime= false; // Set item and text here to prevent page from resizing pattern.setItems(getPreviousSearchPatterns()); if (!initializePatternControl()) { //��ʼ�������� if (!initializePatternControl()) { pattern.select(0); handlePatternSelected(pattern.getSelectionIndex()); } } } pattern.setFocus(); } updateOKStatus(); super.setVisible(visible); } private boolean initializePatternControl() { ISelection selection= container.getSelection(); if (selection instanceof ITextSelection && !selection.isEmpty()) { String text= ((ITextSelection) selection).getText(); if (StringUtils.isNotBlank(text)) { pattern.setText(insertEscapeChars(text)); return true; } } return false; } private String insertEscapeChars(String text) { if (text == null || text.equals("")) //$NON-NLS-1$ return ""; //$NON-NLS-1$ StringBuffer sbIn= new StringBuffer(text); BufferedReader reader= new BufferedReader(new StringReader(text)); int lengthOfFirstLine= 0; try { lengthOfFirstLine= reader.readLine().length(); } catch (IOException ex) { return ""; //$NON-NLS-1$ } StringBuffer sbOut= new StringBuffer(lengthOfFirstLine + 5); int i= 0; while (i < lengthOfFirstLine) { char ch= sbIn.charAt(i); if (ch == '*' || ch == '?' || ch == '\\') sbOut.append("\\"); //$NON-NLS-1$ sbOut.append(ch); i++; } return sbOut.toString(); } /* (non-Javadoc) * @see org.eclipse.search.ui.ISearchPage#performAction() */ @Override public boolean performAction() { return performNewSearch(); } /* (non-Javadoc) * @see org.eclipse.search.ui.ISearchPage#setContainer(org.eclipse.search.ui.ISearchPageContainer) */ @Override public void setContainer(ISearchPageContainer container) { this.container = container; } private Control createExpression(Composite parent) { Composite result= new Composite(parent, SWT.NONE); GridLayout layout= new GridLayout(3, false); layout.marginWidth= 0; layout.marginHeight= 0; result.setLayout(layout); // Pattern text + info Label label= new Label(result, SWT.LEFT); label.setText("�����ı���* = �����ַ�����? = �����ַ���"); label.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false, 3, 1)); // Pattern combo pattern= new Combo(result, SWT.SINGLE | SWT.BORDER); // String[] patterns = getPreviousSearchPatterns(); // pattern.setItems(patterns); /*if(patterns.length>0){ pattern.select(0); }*/ pattern.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handlePatternSelected(pattern.getSelectionIndex()); updateOKStatus(); } } ); pattern.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { doPatternModified(); updateOKStatus(); } }); // TextFieldNavigationHandler.install(fPattern); GridData data= new GridData(GridData.FILL, GridData.FILL, true, false, 2, 1); data.widthHint= convertWidthInCharsToPixels(50); pattern.setLayoutData(data); // Ignore case checkbox caseSensitive = new Button(result, SWT.CHECK); caseSensitive.setText("��Сд���� "); caseSensitive.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { isCaseSensitive= caseSensitive.getSelection(); } }); caseSensitive.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false, 1, 1)); caseSensitive.setSelection(this.isCaseSensitive); return result; } /** * ���֮ǰ������pattern * @return */ private String[] getPreviousSearchPatterns() { // Search results are not persistent int patternCount= previousSearchPatterns.size(); String [] patterns= new String[patternCount]; for (int i= 0; i < patternCount; i++) patterns[i]= previousSearchPatterns.get(i).getPattern(); return patterns; } /** * ������µ������� * @return */ private String[] getLastSearchItems() { try { return getDialogSettings().getArray(STORE_SEARCH_ITEMS); } catch (Exception e) { return new String[0]; } } /** * ���������Դ�������� * @return */ private String[] getLastSearchResTypes() { try { return getDialogSettings().getArray(STORE_SEARCH_RES_TYPES); } catch (Exception e) { return new String[0]; } } /** * ����������Դ���� * @param parent * @return */ private Control createSearchResTypes(Composite parent) { Group result= new Group(parent, SWT.NONE); result.setText("������Դ"); RowLayout rowLayout = new RowLayout(SWT.VERTICAL); //rowLayout.justify = true; result.setLayout(rowLayout); List<String>cResTypes = SearcherUitl.getSearchCResTypes(); for(String resCType:cResTypes){ final Button btResType = createRowButton(result, SWT.CHECK, resCType, resCType, false); btResType.addSelectionListener(new SelectionAdapter(){ /* (non-Javadoc) * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(SelectionEvent e) { handlePatternSelected(); } } ); btSearchResTypes.add(btResType); } //setSelectResTypes(getLastSearchResTypes()); //Label filler= new Label(result, SWT.NONE); //filler.setVisible(false); //filler.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1)); return result; } /** * ������������� * @param parent * @return */ private Control createSearchItems(Composite parent) { Group result= new Group(parent, SWT.NONE); RowLayout rowLayout = new RowLayout(SWT.VERTICAL); //rowLayout.justify = true; result.setLayout(rowLayout); result.setLayoutData(rowLayout); result.setText("������"); List<String> searchItems= SearcherUitl.getSearchItems(); for(String item:searchItems){ Button btItem = createRowButton(result, SWT.CHECK, item, item, false); btSearchItems.add(btItem); } //setSearchItems(getLastSearchItems()); return result; } /** * ����Button * @param parent * @param style * @param text * @param data * @param isSelected * @return */ private Button createButton(Composite parent, int style, String text, Object data, boolean isSelected) { Button button= new Button(parent, style); button.setText(text); button.setData(data); //button.setLayoutData(new GridData()); button.setSelection(isSelected); return button; } /** * ����Button * @param parent * @param style * @param text * @param data * @param isSelected * @return */ private Button createRowButton(Composite parent, int style, String text, Object data, boolean isSelected) { Button button= new Button(parent, style); button.setText(text); button.setData(data); button.setLayoutData(new RowData()); button.setSelection(isSelected); return button; } /** * ����������Դ���� * @param searchResTypes */ private void setSelectResTypes(String[] searchResTypes){ if(searchResTypes!=null){ for(String resType:searchResTypes){ for(Button bt :this.btSearchResTypes){ if(StringUtils.equals(bt.getText(), resType)){ bt.setSelection(true); } } } } } /** * ���������� * @param searchItems */ private void setSearchItems(String[] searchItems){ if(searchItems!=null){ for(String searchItem:searchItems){ for(Button bt :this.btSearchItems){ if(StringUtils.equals(bt.getText(), searchItem)){ bt.setSelection(true); } } } } } /** * ���������Դ���� * @return */ private String[] getSearchResTypes(){ List<String> searchResTypes = new ArrayList<String>(); for(Button bt :this.btSearchResTypes){ if(bt.getSelection()){ searchResTypes.add(bt.getText()); } } return searchResTypes.toArray(new String[searchResTypes.size()]); } /** * ��������� * @return */ private String[] getSearchItems(){ List<String> searchItems = new ArrayList<String>(); for(Button bt :this.btSearchItems){ if(bt.getSelection()&&bt.isEnabled()){ searchItems.add(bt.getText()); } } return searchItems.toArray(new String[searchItems.size()]); } /** * ���� * @return */ private boolean performNewSearch() { SearchPatternData data = getPatternData(); String[] searchResTypes = data.getSearchResTypes(); String[] searchItems = data.getSearchItems(); Set<IARESElement> scope = new HashSet<IARESElement>(); switch (getContainer().getSelectedScope()) { case ISearchPageContainer.WORKSPACE_SCOPE: IProject project[] = ResourcesPlugin.getWorkspace().getRoot().getProjects(); for (IProject p : project) { if(p.isOpen()){ IARESProject aresProject = ARESCore.create(p); if (aresProject != null) { scope.add(aresProject); } } } break; case ISearchPageContainer.SELECTION_SCOPE: ISelection sel= getContainer().getSelection(); if (sel instanceof IStructuredSelection && !sel.isEmpty()) { Iterator iter= ((IStructuredSelection) sel).iterator(); while (iter.hasNext()) { Object curr= iter.next(); if (curr instanceof IARESElement) { scope.add((IARESElement)curr); } else if (curr instanceof IResource) { IARESElement e = ARESCore.create((IResource)curr); if (e != null) { scope.add(e); } } } } break; case ISearchPageContainer.SELECTED_PROJECTS_SCOPE: String[] projectNames= getContainer().getSelectedProjectNames(); for (int i = 0; i < projectNames.length; i++) { IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject(projectNames[i]); if(p.isOpen()){ IARESProject aresProject = ARESCore.create(ResourcesPlugin.getWorkspace().getRoot().getProject(projectNames[i])); if (aresProject != null) { scope.add(aresProject); } } } break; case ISearchPageContainer.WORKING_SET_SCOPE: IWorkingSet[] workingSets = getContainer().getSelectedWorkingSets(); // should not happen -s just to be sure if (workingSets == null || workingSets.length < 1) return false; for (int i = 0; i < workingSets.length; i++) { if (workingSets[i].isAggregateWorkingSet() && workingSets[i].isEmpty()) { for (IProject p : ResourcesPlugin.getWorkspace().getRoot().getProjects()) { if(p.isOpen()){ IARESProject aresProject = ARESCore.create(p); if (aresProject != null) { scope.add(aresProject); } } } break; } for (IAdaptable adapt : workingSets[i].getElements()) { Object obj = adapt.getAdapter(IResource.class); if (obj != null) { IARESElement element = ARESCore.create((IResource)obj); if (element != null) scope.add(element); } } } break; } final ARESSearchQuery areaSearchJob = new ARESSearchQuery(pattern.getText(), isCaseSensitive,Arrays.asList(searchResTypes), Arrays.asList(searchItems), scope.toArray(new IARESElement[0])); NewSearchUI.runQueryInBackground(areaSearchJob); return true; } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.DialogPage#dispose() */ @Override public void dispose() { //���л���ѡ���� if(StringUtils.isNotBlank(this.pattern.getText())){ writeConfiguration(); } super.dispose(); } /** * Return search pattern data and update previous searches. * An existing entry will be updated. * @return the pattern data */ private SearchPatternData getPatternData() { String pattern= getPattern(); SearchPatternData match= findInPrevious(pattern); if (match != null) { previousSearchPatterns.remove(match); } match= new SearchPatternData( getSearchResTypes(), pattern, caseSensitive.getSelection(), getContainer().getSelectedScope(), getContainer().getSelectedWorkingSets(), getSearchItems() ); previousSearchPatterns.add(0, match); // insert on top return match; } private SearchPatternData findInPrevious(String pattern) { for (Iterator<SearchPatternData> iter= previousSearchPatterns.iterator(); iter.hasNext();) { SearchPatternData element = iter.next(); if (pattern.equals(element.getPattern())) { return element; } } return null; } /** * ��ȡǰһ������������ */ private void readConfiguration() { IDialogSettings s= getDialogSettings(); //isCaseSensitive = s.getBoolean(STORE_CASE_SENSITIVE); try { int historySize= s.getInt(STORE_HISTORY_SIZE); for (int i= 0; i < historySize; i++) { IDialogSettings histSettings= s.getSection(STORE_HISTORY + i); if (histSettings != null) { SearchPatternData data= SearchPatternData.create(histSettings); if (data != null) { previousSearchPatterns.add(data); } } } } catch (NumberFormatException e) { // ignore } } /** * Stores the current configuration in the dialog store. */ private void writeConfiguration() { IDialogSettings s = getDialogSettings(); s.put(STORE_CASE_SENSITIVE, isCaseSensitive); s.put(STORE_SEARCH_RES_TYPES, getSearchResTypes()); s.put(STORE_SEARCH_ITEMS, getSearchItems()); int historySize= Math.min(previousSearchPatterns.size(), HISTORY_SIZE); s.put(STORE_HISTORY_SIZE, historySize); for (int i= 0; i < historySize; i++) { IDialogSettings histSettings = s.addNewSection(STORE_HISTORY + i); SearchPatternData data = previousSearchPatterns.get(i); data.store(histSettings); } } /** * Returns the page settings for this Java search page. * * @return the page settings to be used */ private IDialogSettings getDialogSettings() { if (dialogSettings == null) { dialogSettings= ARESUI.getDefault().getDialogSettingsSection(PAGE_NAME); } return dialogSettings; } /** * ѡ����ǰ��������ʱ����ǰ�ĸ�ѡ����ָ� * @param selectionIndex */ private void handlePatternSelected(int selectionIndex) { if (selectionIndex < 0 || selectionIndex >= previousSearchPatterns.size()) return; SearchPatternData initialData= (SearchPatternData) previousSearchPatterns.get(selectionIndex); setSelectResTypes(initialData.getSearchResTypes()); setSearchItems(initialData.getSearchItems()); pattern.setText(initialData.getPattern()); isCaseSensitive= initialData.isCaseSensitive(); caseSensitive.setSelection(initialData.isCaseSensitive()); if (initialData.getWorkingSets() != null) getContainer().setSelectedWorkingSets(initialData.getWorkingSets()); else getContainer().setSelectedScope(initialData.getScope()); } /** * ���û�ѡ��ͬ����Դ����ѡ��ʱ,��Ӧ��������Ҫ����Ӧ�ı仯 */ private void handlePatternSelected(){ List<String> cResTypes = SearcherUitl.getSearchCResTypes(); List<String> selectedResTypes = new ArrayList<String>(); /*�������ѡ�����������*/ for(String resCType:cResTypes){ for(Button btResType:btSearchResTypes){ if(btResType.getSelection()&& StringUtils.equals(resCType, btResType.getText())){ if(!selectedResTypes.contains(resCType)){ selectedResTypes.add(resCType); } } } } /*�����������������������������*/ List<String> enableSearceItem = SearcherUitl.getSearchItemsByResTypes(selectedResTypes); for(Button searchItem:btSearchItems){ if(enableSearceItem.contains(searchItem.getText())){ searchItem.setEnabled(true); }else{ searchItem.setEnabled(false); } } } final void updateOKStatus() { boolean isValid= isValidSearchPattern(); getContainer().setPerformActionEnabled(isValid); } /** * �Ƿ��ǺϷ����������� * @return */ private boolean isValidSearchPattern() { if (getPattern().length() == 0) { return false; } return true; } private void doPatternModified() { } private String getPattern() { return pattern.getText(); } /** * Returns the search page's container. * @return the search page container */ private ISearchPageContainer getContainer() { return container; } }