Java tutorial
/******************************************************************************* * Copyright (c) 2000, 2008 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 * Juerg Billeter, juergbi@ethz.ch - 47136 Search view should show match objects * Ulrich Etter, etteru@ethz.ch - 47136 Search view should show match objects * Roman Fuchs, fuchsro@ethz.ch - 47136 Search view should show match objects *******************************************************************************/ package com.nokia.carbide.search.system.internal.ui.text; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.StringReader; import java.net.URI; import java.util.ArrayList; import java.util.Iterator; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; 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.DirectoryDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.DialogPage; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.fieldassist.ComboContentAdapter; import org.eclipse.jface.resource.JFaceColors; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.FindReplaceDocumentAdapterContentProposalProvider; import org.eclipse.search.ui.ISearchPage; import org.eclipse.search.ui.ISearchPageContainer; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter; import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; import org.eclipse.ui.ide.FileStoreEditorInput; import com.nokia.carbide.search.system.internal.ui.ISearchHelpContextIds; import com.nokia.carbide.search.system.internal.ui.SearchMessages; import com.nokia.carbide.search.system.internal.ui.SearchPlugin; import com.nokia.carbide.search.system.internal.ui.util.FileTypeEditor; import com.nokia.carbide.search.system.internal.ui.util.SWTUtil; import com.nokia.carbide.search.system.ui.ISearchQuery; import com.nokia.carbide.search.system.ui.ISearchResultPage; import com.nokia.carbide.search.system.ui.ISearchResultViewPart; import com.nokia.carbide.search.system.ui.NewSearchUI; import com.nokia.carbide.search.system.ui.text.FileTextSearchScope; import com.nokia.carbide.search.system.ui.text.TextSearchQueryProvider; import com.nokia.carbide.search.system.ui.text.TextSearchQueryProvider.TextSearchInput; public class TextSearchPage extends DialogPage implements ISearchPage {//, IReplacePage { private static final int HISTORY_SIZE = 12; public static final String EXTENSION_POINT_ID = "com.nokia.carbide.search.system.internal.ui.text.TextSearchPage"; //$NON-NLS-1$ // Dialog store id constants private static final String PAGE_NAME = "TextSearchPage"; //$NON-NLS-1$ private static final String STORE_CASE_SENSITIVE = "CASE_SENSITIVE"; //$NON-NLS-1$ private static final String STORE_IS_REG_EX_SEARCH = "REG_EX_SEARCH"; //$NON-NLS-1$ private static final String STORE_SEARCH_DERIVED = "SEARCH_DERIVED"; //$NON-NLS-1$ private static final String STORE_ADDED_FILENAMES = "ADDED_FILENAMES"; //$NON-NLS-1$ private static final String STORE_ADDED_FOLDERS = "ADDED_FOLDERS"; //$NON-NLS-1$ private static final String STORE_INCLUDE_SUBFOLDERS = "INCLUDE_SUBFOLDERS"; //$NON-NLS-1$ private static final String STORE_INCLUDE_HIDDEN = "INCLUDE_HIDDEN"; //$NON-NLS-1$ private static final String STORE_HISTORY = "HISTORY"; //$NON-NLS-1$ private static final String STORE_HISTORY_SIZE = "HISTORY_SIZE"; //$NON-NLS-1$ // a list to hold previous search data private ArrayList<SearchPatternData> fPreviousSearchPatterns = new ArrayList<SearchPatternData>(); // search utility // private SystemSearchUtil fUtil; // flag to indicate whether showing the dialog for the first time private boolean fFirstTime = true; private boolean fIsCaseSensitive; private boolean fIsRegExSearch; private boolean fIncludeSubfolders; private boolean fIncludeHidden; private boolean fSearchDerived = false; private boolean fIncludeArchives = false; private ArrayList<String> fFileExtensions = new ArrayList<String>(); private ArrayList<String> fFolders = new ArrayList<String>(); private Combo fPattern; private Button fIsCaseSensitiveCheckbox; private Combo fExtensions; private Button fIsRegExCheckbox; private CLabel fStatusLabel; private Combo fFolder; private Button fIncludeSubfoldersCheckbox; private Button fIncludeHiddenCheckbox; private Button fIncludeArchivesCheckbox; // folder name editor private FolderNameEditor folderNameEditor; // search page fContainer private ISearchPageContainer fContainer; private FileTypeEditor fFileTypeEditor; private ContentAssistCommandAdapter fPatterFieldContentAssist; private static class SearchPatternData { public final boolean isCaseSensitive; public final boolean isRegExSearch; public final String textPattern; public final String[] fileNamePatterns; public final int scope; public final String folderName; public final boolean includeSubfolders; public final boolean includeHidden; public final boolean includeArchives; private static final String STORE_DATA_TEXT_PATTERN = "textPattern"; //$NON-NLS-1$ private static final String STORE_DATA_CASE_SENSITIVE = "caseSensitive"; //$NON-NLS-1$ private static final String STORE_DATA_STRING_REGEX = "regExSearch"; //$NON-NLS-1$ private static final String STORE_DATA_FILE_NAMES = "fileNames"; //$NON-NLS-1$ private static final String STORE_DATA_SCOPE = "scope"; //$NON-NLS-1$ private static final String STORE_DATA_FOLDER_NAME = "folderName"; //$NON-NLS-1$ private static final String STORE_DATA_INCLUDE_SUBFOLDERS = "includeSubfolders"; //$NON-NLS-1$ private static final String STORE_DATA_INCLUDE_HIDDEN = "includeHidden"; //$NON-NLS-1$ private static final String STORE_DATA_INCLUDE_ARCHIVES = "includeArchives"; //$NON-NLS-1$ public SearchPatternData(String textPattern, boolean isCaseSensitive, boolean isRegExSearch, String[] fileNamePatterns, int scope, String folderName, boolean includeSubfolders, boolean includeHidden, boolean includeArchives) { Assert.isNotNull(fileNamePatterns); this.isCaseSensitive = isCaseSensitive; this.isRegExSearch = isRegExSearch; this.textPattern = textPattern; this.fileNamePatterns = fileNamePatterns; this.scope = scope; this.folderName = folderName; // can be null this.includeSubfolders = includeSubfolders; this.includeHidden = includeHidden; this.includeArchives = includeArchives; } public void store(IDialogSettings settings) { settings.put(STORE_DATA_CASE_SENSITIVE, isCaseSensitive); //$NON-NLS-1$ settings.put(STORE_DATA_STRING_REGEX, isRegExSearch); //$NON-NLS-1$ settings.put(STORE_DATA_TEXT_PATTERN, textPattern); //$NON-NLS-1$ settings.put(STORE_DATA_FILE_NAMES, fileNamePatterns); //$NON-NLS-1$ settings.put(STORE_DATA_SCOPE, scope); //$NON-NLS-1$ settings.put(STORE_DATA_FOLDER_NAME, folderName); settings.put(STORE_DATA_INCLUDE_SUBFOLDERS, includeSubfolders); settings.put(STORE_DATA_INCLUDE_HIDDEN, includeHidden); settings.put(STORE_DATA_INCLUDE_ARCHIVES, includeArchives); } public static SearchPatternData create(IDialogSettings settings) { String textPattern = settings.get(STORE_DATA_TEXT_PATTERN); //$NON-NLS-1$ String[] fileNamePatterns = settings.getArray(STORE_DATA_FILE_NAMES); //$NON-NLS-1$ if (fileNamePatterns == null) { fileNamePatterns = new String[0]; } String folderName = settings.get(STORE_DATA_FOLDER_NAME); try { int scope = settings.getInt(STORE_DATA_SCOPE); //$NON-NLS-1$ boolean isRegExSearch = settings.getBoolean(STORE_DATA_STRING_REGEX); //$NON-NLS-1$ boolean isCaseSensitive = settings.getBoolean(STORE_DATA_CASE_SENSITIVE); //$NON-NLS-1$ boolean includeSubfolders = settings.getBoolean(STORE_DATA_INCLUDE_SUBFOLDERS); //$NON-NLS-1$ boolean includeHidden = settings.getBoolean(STORE_DATA_INCLUDE_HIDDEN); //$NON-NLS-1$ boolean includeArchives = settings.getBoolean(STORE_DATA_INCLUDE_ARCHIVES); //$NON-NLS-1$ return new SearchPatternData(textPattern, isCaseSensitive, isRegExSearch, fileNamePatterns, scope, folderName, includeSubfolders, includeHidden, includeArchives); } catch (NumberFormatException e) { return null; } } } private static class TextSearchPageInput extends TextSearchInput { private final String fSearchText; private final boolean fIsCaseSensitive; private final boolean fIsRegEx; private final FileTextSearchScope fScope; public TextSearchPageInput(String searchText, boolean isCaseSensitive, boolean isRegEx, FileTextSearchScope scope) { fSearchText = searchText; fIsCaseSensitive = isCaseSensitive; fIsRegEx = isRegEx; fScope = scope; } public String getSearchText() { return fSearchText; } public boolean isCaseSensitiveSearch() { return fIsCaseSensitive; } public boolean isRegExSearch() { return fIsRegEx; } public FileTextSearchScope getScope() { return fScope; } } //---- Action Handling ------------------------------------------------ private ISearchQuery newQuery() throws CoreException { SearchPatternData data = getPatternData(); TextSearchPageInput input = new TextSearchPageInput(data.textPattern, data.isCaseSensitive, data.isRegExSearch, createTextSearchScope(data.folderName, data.includeSubfolders, data.includeHidden, data.includeArchives)); return TextSearchQueryProvider.getPreferred().createQuery(input); } public boolean performAction() { try { NewSearchUI.runQueryInBackground(newQuery()); } catch (CoreException e) { ErrorDialog.openError(getShell(), SearchMessages.TextSearchPage_replace_searchproblems_title, SearchMessages.TextSearchPage_replace_searchproblems_message, e.getStatus()); return false; } return true; } /* (non-Javadoc) * @see com.nokia.carbide.search.system.ui.IReplacePage#performReplace() */ public boolean performReplace() { try { IStatus status = NewSearchUI.runQueryInForeground(getContainer().getRunnableContext(), newQuery()); if (status.matches(IStatus.CANCEL)) { return false; } if (!status.isOK()) { ErrorDialog.openError(getShell(), SearchMessages.TextSearchPage_replace_searchproblems_title, SearchMessages.TextSearchPage_replace_runproblem_message, status); } Display.getCurrent().asyncExec(new Runnable() { public void run() { ISearchResultViewPart view = NewSearchUI.activateSearchResultView(); if (view != null) { ISearchResultPage page = view.getActivePage(); if (page instanceof FileSearchPage) { FileSearchPage filePage = (FileSearchPage) page; Object[] elements = filePage.getInput().getElements(); IFileStore[] files = new IFileStore[elements.length]; System.arraycopy(elements, 0, files, 0, files.length); new ReplaceAction2(filePage, files).run(); } } } }); return true; } catch (CoreException e) { ErrorDialog.openError(getShell(), SearchMessages.TextSearchPage_replace_searchproblems_title, SearchMessages.TextSearchPage_replace_querycreationproblem_message, e.getStatus()); return false; } } private String getPattern() { return fPattern.getText(); } // system search does not use the regular scope widgets private FileTextSearchScope createTextSearchScope(String folderName, boolean includeSubfolders, boolean includeHidden, boolean includeArchives) { return FileTextSearchScope.newSystemScope(folderName, getExtensions(), folderName, includeSubfolders, includeHidden, includeArchives); } private SearchPatternData findInPrevious(String pattern) { for (Iterator<SearchPatternData> iter = fPreviousSearchPatterns.iterator(); iter.hasNext();) { SearchPatternData element = (SearchPatternData) iter.next(); if (pattern.equals(element.textPattern)) { return element; } } return null; } /** * Return search pattern data and update previous searches. * An existing entry will be updated. * @return the search pattern data */ private SearchPatternData getPatternData() { SearchPatternData match = findInPrevious(fPattern.getText()); if (match != null) { fPreviousSearchPatterns.remove(match); } match = new SearchPatternData(getPattern(), isCaseSensitive(), fIsRegExCheckbox.getSelection(), getExtensions(), com.nokia.carbide.search.system.ui.ISearchPageContainer.SYSTEM_SCOPE, fFolder.getText(), fIncludeSubfoldersCheckbox.getSelection(), fIncludeHiddenCheckbox.getSelection(), fIncludeArchivesCheckbox != null ? fIncludeArchivesCheckbox.getSelection() : false); fPreviousSearchPatterns.add(0, match); return match; } private String[] getPreviousExtensions() { return (String[]) fFileExtensions.toArray(new String[fFileExtensions.size()]); } private String[] getPreviousSearchPatterns() { int size = fPreviousSearchPatterns.size(); String[] patterns = new String[size]; for (int i = 0; i < size; i++) patterns[i] = ((SearchPatternData) fPreviousSearchPatterns.get(i)).textPattern; return patterns; } private String[] getPreviousFolders() { return (String[]) fFolders.toArray(new String[fFolders.size()]); } private String[] getExtensions() { return fFileTypeEditor.getFileTypes(); } private boolean isCaseSensitive() { return fIsCaseSensitiveCheckbox.getSelection(); } /* * Implements method from IDialogPage */ public void setVisible(boolean visible) { if (visible && fPattern != null) { if (fFirstTime) { fFirstTime = false; // Set item and text here to prevent page from resizing fPattern.setItems(getPreviousSearchPatterns()); String[] values = getPreviousExtensions(); if (values != null) fExtensions.setItems(values); values = getPreviousFolders(); if (values != null) fFolder.setItems(values); if (!initializePatternControl()) { fPattern.select(0); fExtensions.setText("*"); //$NON-NLS-1$ fFolder.select(0); fIncludeSubfoldersCheckbox.setSelection(true); fIncludeSubfolders = true; handleWidgetSelected(); } } fPattern.setFocus(); } updateOKStatus(); super.setVisible(visible); } final void updateOKStatus() { boolean regexStatus = validateRegex(); boolean hasFilePattern = fExtensions.getText().length() > 0; getContainer().setPerformActionEnabled(isFolderNameValid() && regexStatus && hasFilePattern); } //---- Widget creation ------------------------------------------------ public void createControl(Composite parent) { // compute horizontal and vertical units initializeDialogUnits(parent); // read configuration readConfiguration(); // main composite Composite result = new Composite(parent, SWT.NONE); result.setFont(parent.getFont()); GridLayout layout = new GridLayout(2, false); result.setLayout(layout); // create controls for search string addTextPatternControls(result); 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); // create controls for file names addFileNameControls(result); separator = new Label(result, SWT.NONE); separator.setVisible(false); data = new GridData(GridData.FILL, GridData.FILL, false, false, 2, 1); data.heightHint = convertHeightInCharsToPixels(1) / 3; separator.setLayoutData(data); // create controls for folder name addFolderControls(result); setControl(result); Dialog.applyDialogFont(result); PlatformUI.getWorkbench().getHelpSystem().setHelp(result, ISearchHelpContextIds.TEXT_SEARCH_PAGE); } // inner class to handle folder name editing private class FolderNameEditor extends SelectionAdapter implements DisposeListener { // holds info for each item in the folder combo private Combo folderCombo; private Button browseButton; /** * Constructor for folder name editor. * @param folderCombo the folder name combo. * @param browseButton the folder browse button. */ private FolderNameEditor(Combo folderCombo, Button browseButton) { this.folderCombo = folderCombo; this.browseButton = browseButton; // add dispose listeners to both the combo and the button // we make them null when they are disposed for cleanup to occur folderCombo.addDisposeListener(this); browseButton.addDisposeListener(this); // add selection listener to the browse button browseButton.addSelectionListener(this); } /** * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) */ public void widgetDisposed(DisposeEvent e) { if (e.widget == folderCombo) { folderCombo = null; } else if (e.widget == browseButton) { browseButton = null; } } /** * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected(SelectionEvent e) { if (e.widget == browseButton) { // get the shell from the page Shell shell = TextSearchPage.this.getShell(); DirectoryDialog folder = new DirectoryDialog(shell); String filterPath = fFolder.getText(); if (filterPath != null) folder.setFilterPath(filterPath); folder.setMessage(SearchMessages.TextSearchPage_browseToFolder); String selectedFilePath = folder.open(); if (selectedFilePath != null) { setFolderText(selectedFilePath); } } } /** * Sets the folder name combo text. Also sets the profile name, connection name and folder path. * @param profileName the profile name. */ private void setFolderText(String folderPath) { fFolder.setText(folderPath); } } private boolean validateRegex() { if (fIsRegExCheckbox.getSelection()) { try { Pattern.compile(fPattern.getText()); } catch (PatternSyntaxException e) { String locMessage = e.getLocalizedMessage(); int i = 0; while (i < locMessage.length() && "\n\r".indexOf(locMessage.charAt(i)) == -1) { //$NON-NLS-1$ i++; } statusMessage(true, locMessage.substring(0, i)); // only take first line return false; } statusMessage(false, ""); //$NON-NLS-1$ } else { statusMessage(false, SearchMessages.SearchPage_containingText_hint); } return true; } /** * Returns whether folder name is valid. * @return <code>true</code> if folder name is not <code>null</code> or empty, <code>false</code> otherwise. */ private boolean isFolderNameValid() { String folderName = fFolder.getText(); if (folderName == null || folderName.trim().length() == 0) { return false; } File file = new File(folderName); return file.exists() && file.isDirectory(); } private void addTextPatternControls(Composite group) { // grid layout with 2 columns // Info text Label label = new Label(group, SWT.LEAD); label.setText(SearchMessages.TextSearchPage_searchString); label.setToolTipText(SearchMessages.TextSearchPage_searchStringToolTip); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); label.setFont(group.getFont()); // Pattern combo fPattern = new Combo(group, SWT.SINGLE | SWT.BORDER); fPattern.setToolTipText(SearchMessages.TextSearchPage_enterOrSelectToolTip); // Not done here to prevent page from resizing // fPattern.setItems(getPreviousSearchPatterns()); fPattern.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleWidgetSelected(); updateOKStatus(); } }); // add some listeners for regex syntax checking fPattern.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { updateOKStatus(); } }); fPattern.setFont(group.getFont()); GridData data = new GridData(GridData.FILL, GridData.FILL, true, false, 1, 1); data.widthHint = convertWidthInCharsToPixels(50); fPattern.setLayoutData(data); ComboContentAdapter contentAdapter = new ComboContentAdapter(); FindReplaceDocumentAdapterContentProposalProvider findProposer = new FindReplaceDocumentAdapterContentProposalProvider( true); fPatterFieldContentAssist = new ContentAssistCommandAdapter(fPattern, contentAdapter, findProposer, ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, new char[] { '\\', '[', '(' }, true); fPatterFieldContentAssist.setEnabled(fIsRegExSearch); fIsCaseSensitiveCheckbox = new Button(group, SWT.CHECK); fIsCaseSensitiveCheckbox.setText(SearchMessages.SearchPage_caseSensitive); fIsCaseSensitiveCheckbox.setToolTipText(SearchMessages.TextSearchPage_caseSensitiveToolTip); fIsCaseSensitiveCheckbox.setSelection(fIsCaseSensitive); fIsCaseSensitiveCheckbox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { fIsCaseSensitive = fIsCaseSensitiveCheckbox.getSelection(); } }); fIsCaseSensitiveCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); fIsCaseSensitiveCheckbox.setFont(group.getFont()); // Text line which explains the special characters fStatusLabel = new CLabel(group, SWT.LEAD); fStatusLabel.setToolTipText(""); fStatusLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); fStatusLabel.setFont(group.getFont()); fStatusLabel.setAlignment(SWT.LEFT); fStatusLabel.setText(SearchMessages.SearchPage_containingText_hint); // RegEx checkbox fIsRegExCheckbox = new Button(group, SWT.CHECK); fIsRegExCheckbox.setText(SearchMessages.SearchPage_regularExpression); fIsRegExCheckbox.setSelection(fIsRegExSearch); fIsRegExCheckbox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { fIsRegExSearch = fIsRegExCheckbox.getSelection(); updateOKStatus(); writeConfiguration(); fPatterFieldContentAssist.setEnabled(fIsRegExSearch); } }); fIsRegExCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); fIsRegExCheckbox.setFont(group.getFont()); } private void handleWidgetSelected() { int selectionIndex = fPattern.getSelectionIndex(); if (selectionIndex < 0 || selectionIndex >= fPreviousSearchPatterns.size()) return; SearchPatternData patternData = (SearchPatternData) fPreviousSearchPatterns.get(selectionIndex); if (patternData == null || !fPattern.getText().equals(patternData.textPattern)) return; // set case sensitive fIsCaseSensitiveCheckbox.setSelection(patternData.isCaseSensitive); // set string regex fIsRegExCheckbox.setSelection(patternData.isRegExSearch); // set search string properties fPattern.setText(patternData.textPattern); // set types list fFileTypeEditor.setFileTypes(patternData.fileNamePatterns); // set working sets getContainer().setSelectedScope(patternData.scope); // set the system folder properties folderNameEditor.setFolderText(patternData.folderName); // set search subfolders fIncludeSubfoldersCheckbox.setSelection(patternData.includeSubfolders); // set search hidden files fIncludeHiddenCheckbox.setSelection(patternData.includeHidden); // set search archives // fIncludeArchivesCheckbox.setSelection(patternData.includeArchives); } private boolean initializePatternControl() { ISelection selection = getSelection(); if (selection instanceof ITextSelection && !selection.isEmpty()) { String text = ((ITextSelection) selection).getText(); if (text != null) { fPattern.setText(insertEscapeChars(text)); if (getPreviousExtensions().length > 0) { fExtensions.setText(getPreviousExtensions()[0]); } else { String extension = getExtensionFromEditor(); if (extension != null) fExtensions.setText(extension); else fExtensions.setText("*"); //$NON-NLS-1$ } if (getPreviousFolders().length > 0) { fFolder.setText(getPreviousFolders()[0]); } 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(); } private String getExtensionFromEditor() { IEditorPart ep = SearchPlugin.getActivePage().getActiveEditor(); if (ep != null) { Object elem = ep.getEditorInput(); if (elem instanceof IFileEditorInput) { String extension = ((IFileEditorInput) elem).getFile().getFileExtension(); if (extension == null) return ((IFileEditorInput) elem).getFile().getName(); return "*." + extension; //$NON-NLS-1$ } else if (elem instanceof FileStoreEditorInput) { FileStoreEditorInput input = (FileStoreEditorInput) elem; URI uri = input.getURI(); String extension = uri.getPath(); if (extension.contains(".")) { //$NON-NLS-1$ extension = extension.substring(extension.lastIndexOf('.')); } else if (extension.replace('\\', '/').contains("/")) { //$NON-NLS-1$ extension = extension.substring(extension.replace('\\', '/').lastIndexOf('/')); } } } return null; } private void addFileNameControls(Composite group) { // grid layout with 2 columns // Line with label, combo and button Label label = new Label(group, SWT.LEAD); label.setText(SearchMessages.SearchPage_fileNamePatterns_text); label.setToolTipText(SearchMessages.TextSearchPage_fileNamePatterns); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); label.setFont(group.getFont()); fExtensions = new Combo(group, SWT.SINGLE | SWT.BORDER); fExtensions.setToolTipText(SearchMessages.TextSearchPage_enterOrSelectFileNamePatternsToolTip); if (getPreviousExtensions().length > 0) { fExtensions.setText(getPreviousExtensions()[0]); } fExtensions.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { updateOKStatus(); } }); GridData data = new GridData(GridData.FILL, GridData.FILL, true, false, 1, 1); data.widthHint = convertWidthInCharsToPixels(50); fExtensions.setLayoutData(data); fExtensions.setFont(group.getFont()); Button button = new Button(group, SWT.PUSH); button.setText(SearchMessages.SearchPage_browse); GridData gridData = new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1); gridData.widthHint = SWTUtil.getButtonWidthHint(button); button.setLayoutData(gridData); button.setFont(group.getFont()); fFileTypeEditor = new FileTypeEditor(fExtensions, button); // Text line which explains the special characters Label description = new Label(group, SWT.LEAD); description.setText(SearchMessages.SearchPage_fileNamePatterns_hint); description.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); description.setFont(group.getFont()); } /** * Adds controls to specify folder name. */ private void addFolderControls(Composite group) { // grid layout with 2 columns // Line with label, combo and button Label label = new Label(group, SWT.LEFT); label.setText(SearchMessages.TextSearchPage_folder); label.setToolTipText(SearchMessages.TextSearchPage_folderPath); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); label.setFont(group.getFont()); fFolder = new Combo(group, SWT.SINGLE | SWT.BORDER); fFolder.setToolTipText(SearchMessages.TextSearchPage_folderPathToolTip); fFolder.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { updateOKStatus(); } }); GridData data = new GridData(GridData.FILL, GridData.FILL, true, false, 1, 1); data.widthHint = convertWidthInCharsToPixels(50); fFolder.setLayoutData(data); fFolder.setFont(group.getFont()); // browse types button Button button = new Button(group, SWT.PUSH); button.setText(SearchMessages.TextSearchPage_browse); button.setToolTipText(SearchMessages.TextSearchPage_browseToolTip); GridData gridData = new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1); gridData.widthHint = SWTUtil.getButtonWidthHint(button); button.setLayoutData(gridData); button.setFont(group.getFont()); // create the folder name editor folderNameEditor = new FolderNameEditor(fFolder, button); // line up the checkbox new Label(group, SWT.NONE).setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1)); // checkbox for search in subfolders fIncludeSubfoldersCheckbox = new Button(group, SWT.CHECK); fIncludeSubfoldersCheckbox.setText(SearchMessages.TextSearchPage_searchSubfolders); fIncludeSubfoldersCheckbox.setToolTipText(SearchMessages.TextSearchPage_searchSubfoldersToolTip); fIncludeSubfoldersCheckbox.setSelection(fIncludeSubfolders); fIncludeSubfoldersCheckbox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { fIncludeSubfolders = fIncludeSubfoldersCheckbox.getSelection(); updateOKStatus(); } }); fIncludeSubfoldersCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); fIncludeSubfoldersCheckbox.setFont(group.getFont()); // line up the checkbox new Label(group, SWT.NONE).setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1)); // checkbox for search in subfolders fIncludeHiddenCheckbox = new Button(group, SWT.CHECK); fIncludeHiddenCheckbox.setText(SearchMessages.TextSearchPage_hiddenFiles); fIncludeHiddenCheckbox.setToolTipText(SearchMessages.TextSearchPage_hiddenFilesToolTip); fIncludeHiddenCheckbox.setSelection(fIncludeHidden); fIncludeHiddenCheckbox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { fIncludeHidden = fIncludeHiddenCheckbox.getSelection(); updateOKStatus(); } }); fIncludeHiddenCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); fIncludeHiddenCheckbox.setFont(group.getFont()); } /** * Sets the search page's container. * @param container the container to set */ public void setContainer(ISearchPageContainer container) { fContainer = container; } private ISearchPageContainer getContainer() { return fContainer; } private ISelection getSelection() { return fContainer.getSelection(); } //--------------- Configuration handling -------------- /* (non-Javadoc) * @see org.eclipse.jface.dialogs.DialogPage#dispose() */ public void dispose() { writeConfiguration(); super.dispose(); } /** * Returns the page settings for this Text search page. * * @return the page settings to be used */ private IDialogSettings getDialogSettings() { return SearchPlugin.getDefault().getDialogSettingsSection(PAGE_NAME); } /** * Initializes itself from the stored page settings. */ private void readConfiguration() { IDialogSettings s = getDialogSettings(); fIsCaseSensitive = s.getBoolean(STORE_CASE_SENSITIVE); fIsRegExSearch = s.getBoolean(STORE_IS_REG_EX_SEARCH); fSearchDerived = s.getBoolean(STORE_SEARCH_DERIVED); fIncludeSubfolders = s.getBoolean(STORE_INCLUDE_SUBFOLDERS); fIncludeHidden = s.getBoolean(STORE_INCLUDE_HIDDEN); String[] values; values = s.getArray(STORE_ADDED_FILENAMES); fFileExtensions.clear(); for (int i = 0; values != null && i < values.length; i++) fFileExtensions.add(values[i]); values = s.getArray(STORE_ADDED_FOLDERS); fFolders.clear(); for (int i = 0; values != null && i < values.length; i++) fFolders.add(values[i]); 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) { fPreviousSearchPatterns.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, fIsCaseSensitive); s.put(STORE_IS_REG_EX_SEARCH, fIsRegExSearch); s.put(STORE_SEARCH_DERIVED, fSearchDerived); s.put(STORE_INCLUDE_SUBFOLDERS, fIncludeSubfolders); s.put(STORE_INCLUDE_HIDDEN, fIncludeHidden); boolean matchFound; // add the current folder to the start of the list; // if it's in the list twice, remove the second time String folder = fFolder.getText(); fFolder.add(folder, 0); for (int i = 1; i < fFolder.getItemCount(); i++) { if (fFolder.getItem(i).equals(folder)) { fFolder.remove(i); break; } } // if there are too many members, remove the highest indexed element // not associated with a search pattern if (fFolder.getItemCount() > HISTORY_SIZE + 2) { matchFound = true; int size = fPreviousSearchPatterns.size(); for (int j = fFolder.getItemCount() - 1; j > 0 && matchFound; j--) { matchFound = false; String currentFolder = fFolder.getItem(j); for (int i = 0; i < size && !matchFound; i++) { SearchPatternData data = (SearchPatternData) fPreviousSearchPatterns.get(i); matchFound = currentFolder.equals(data.folderName); } if (matchFound) { fFolder.remove(j); break; } } } s.put(STORE_ADDED_FOLDERS, fFolder.getItems()); // add the current file extension to the start of the list; // if it's in the list twice, remove the second time String fileExtensions = fFileTypeEditor.getFileTypesString(); fFileExtensions.add(0, fileExtensions); for (int i = 1; i < fFileExtensions.size(); i++) { if (fileExtensions.equals(fFileExtensions.get(i))) { fFileExtensions.remove(i); break; } } // if there are too many members, remove the highest indexed element // not associated with a search pattern if (fFileExtensions.size() >= HISTORY_SIZE + 2) { matchFound = true; int size = fPreviousSearchPatterns.size(); for (int j = fFileExtensions.size() - 1; j > 0 && matchFound; j--) { matchFound = false; String currentExtension = fFileExtensions.get(j); for (int i = 0; i < size && !matchFound; i++) { SearchPatternData data = (SearchPatternData) fPreviousSearchPatterns.get(i); matchFound = currentExtension.equals(FileTypeEditor.typesToString(data.fileNamePatterns)); } if (matchFound) { fFileExtensions.remove(j); break; } } } String[] extensions = new String[fFileExtensions.size()]; for (int i = 0; i < fFileExtensions.size(); i++) extensions[i] = fFileExtensions.get(i); s.put(STORE_ADDED_FILENAMES, extensions); int historySize = Math.min(fPreviousSearchPatterns.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 = ((SearchPatternData) fPreviousSearchPatterns.get(i)); data.store(histSettings); } } private void statusMessage(boolean error, String message) { fStatusLabel.setText(message); if (error) fStatusLabel.setForeground(JFaceColors.getErrorText(fStatusLabel.getDisplay())); else fStatusLabel.setForeground(null); } }