From af61d7692ef895192816a1c38f420c52423389e7 Mon Sep 17 00:00:00 2001 From: Siva Velusamy Date: Tue, 5 Jun 2012 16:59:02 -0700 Subject: Move base class for FindDialog to a common location. Change-Id: Ie3b2e424a7dc9df73aca1c7914497f1c9a126901 --- .../android/ddmuilib/AbstractBufferFindTarget.java | 117 +++++++++++++++++++ .../src/com/android/ddmuilib/FindDialog.java | 124 +++++++++++++++++++++ .../src/com/android/ddmuilib/IFindTarget.java | 21 ++++ .../com/android/ddmuilib/logcat/FindDialog.java | 123 -------------------- .../com/android/ddmuilib/logcat/IFindTarget.java | 21 ---- .../com/android/ddmuilib/logcat/LogCatPanel.java | 4 +- .../ddmuilib/logcat/RollingBufferFindTarget.java | 115 ------------------- .../ddmuilib/logcat/RollingBufferFindTest.java | 4 +- 8 files changed, 268 insertions(+), 261 deletions(-) create mode 100644 ddms/libs/ddmuilib/src/com/android/ddmuilib/AbstractBufferFindTarget.java create mode 100644 ddms/libs/ddmuilib/src/com/android/ddmuilib/FindDialog.java create mode 100644 ddms/libs/ddmuilib/src/com/android/ddmuilib/IFindTarget.java delete mode 100644 ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/FindDialog.java delete mode 100644 ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/IFindTarget.java delete mode 100644 ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/RollingBufferFindTarget.java diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/AbstractBufferFindTarget.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/AbstractBufferFindTarget.java new file mode 100644 index 0000000..13a787a --- /dev/null +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/AbstractBufferFindTarget.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ddmuilib; + +import java.util.regex.Pattern; + +/** + * {@link AbstractBufferFindTarget} implements methods to find items inside a buffer. It takes + * care of the logic to search backwards/forwards in the buffer, wrapping around when necessary. + * The actual contents of the buffer should be provided by the classes that extend this. + */ +public abstract class AbstractBufferFindTarget implements IFindTarget { + private int mCurrentSearchIndex; + + // Single element cache of the last search regex + private Pattern mLastSearchPattern; + private String mLastSearchText; + + @Override + public boolean findAndSelect(String text, boolean isNewSearch, boolean searchForward) { + boolean found = false; + int maxIndex = getItemCount(); + + synchronized (this) { + // Find starting index for this search + if (isNewSearch) { + // for new searches, start from an appropriate place as provided by the delegate + mCurrentSearchIndex = getStartingIndex(); + } else { + // for ongoing searches (finding next match for the same term), continue from + // the current result index + mCurrentSearchIndex = getNext(mCurrentSearchIndex, searchForward, maxIndex); + } + + // Create a regex pattern based on the search term. + Pattern pattern; + if (text.equals(mLastSearchText)) { + pattern = mLastSearchPattern; + } else { + pattern = Pattern.compile(text, Pattern.CASE_INSENSITIVE); + mLastSearchPattern = pattern; + mLastSearchText = text; + } + + // Iterate through the list of items. The search ends if we have gone through + // all items once. + int index = mCurrentSearchIndex; + do { + String msgText = getItem(mCurrentSearchIndex); + if (msgText != null && pattern.matcher(msgText).find()) { + found = true; + break; + } + + mCurrentSearchIndex = getNext(mCurrentSearchIndex, searchForward, maxIndex); + } while (index != mCurrentSearchIndex); // loop through entire contents once + } + + if (found) { + selectAndReveal(mCurrentSearchIndex); + } + + return found; + } + + /** Indicate that the log buffer has scrolled by certain number of elements */ + public void scrollBy(int delta) { + synchronized (this) { + if (mCurrentSearchIndex > 0) { + mCurrentSearchIndex = Math.max(0, mCurrentSearchIndex - delta); + } + } + } + + private int getNext(int index, boolean searchForward, int max) { + // increment or decrement index + index = searchForward ? index + 1 : index - 1; + + // take care of underflow + if (index == -1) { + index = max - 1; + } + + // ..and overflow + if (index == max) { + index = 0; + } + + return index; + } + + /** Obtain the number of items in the buffer */ + public abstract int getItemCount(); + + /** Obtain the item at given index */ + public abstract String getItem(int index); + + /** Select and reveal the item at given index */ + public abstract void selectAndReveal(int index); + + /** Obtain the index from which search should begin */ + public abstract int getStartingIndex(); +} diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/FindDialog.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/FindDialog.java new file mode 100644 index 0000000..6370be4 --- /dev/null +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/FindDialog.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ddmuilib; + + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +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.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * {@link FindDialog} provides a text box where users can enter text that should be + * searched for in the target editor/view. The buttons "Find Previous" and "Find Next" + * allow users to search forwards/backwards. This dialog simply provides a front end for the user + * and the actual task of searching is delegated to the {@link IFindTarget}. + */ +public class FindDialog extends Dialog { + private Label mStatusLabel; + private Button mFindNext; + private Button mFindPrevious; + private final IFindTarget mTarget; + private Text mSearchText; + private String mPreviousSearchText; + + private final static int FIND_NEXT_ID = IDialogConstants.CLIENT_ID; + private final static int FIND_PREVIOUS_ID = IDialogConstants.CLIENT_ID + 1; + + public FindDialog(Shell shell, IFindTarget target) { + super(shell); + + mTarget = target; + + setShellStyle((getShellStyle() & ~SWT.APPLICATION_MODAL) | SWT.MODELESS); + setBlockOnOpen(true); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite panel = new Composite(parent, SWT.NONE); + panel.setLayout(new GridLayout(2, false)); + panel.setLayoutData(new GridData(GridData.FILL_BOTH)); + + Label lblMessage = new Label(panel, SWT.NONE); + lblMessage.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblMessage.setText("Find:"); + + mSearchText = new Text(panel, SWT.BORDER); + mSearchText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + mSearchText.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + boolean hasText = !mSearchText.getText().trim().isEmpty(); + mFindNext.setEnabled(hasText); + mFindPrevious.setEnabled(hasText); + } + }); + + mStatusLabel = new Label(panel, SWT.NONE); + mStatusLabel.setForeground(getShell().getDisplay().getSystemColor(SWT.COLOR_DARK_RED)); + GridData gd = new GridData(); + gd.horizontalSpan = 2; + gd.grabExcessHorizontalSpace = true; + mStatusLabel.setLayoutData(gd); + + return panel; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, false); + mFindNext = createButton(parent, FIND_NEXT_ID, "Find Next", false); + mFindPrevious = createButton(parent, FIND_PREVIOUS_ID, "Find Previous", /* default */ true); + mFindNext.setEnabled(false); + mFindPrevious.setEnabled(false); + } + + @Override + protected void buttonPressed(int buttonId) { + if (buttonId == IDialogConstants.CLOSE_ID) { + close(); + return; + } + + if (buttonId == FIND_PREVIOUS_ID || buttonId == FIND_NEXT_ID) { + if (mTarget != null) { + String searchText = mSearchText.getText(); + boolean newSearch = !searchText.equals(mPreviousSearchText); + mPreviousSearchText = searchText; + boolean searchForward = buttonId == FIND_NEXT_ID; + + boolean hasMatches = mTarget.findAndSelect(searchText, newSearch, searchForward); + if (!hasMatches) { + mStatusLabel.setText("String not found"); + mStatusLabel.pack(); + } else { + mStatusLabel.setText(""); + } + } + } + } +} diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/IFindTarget.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/IFindTarget.java new file mode 100644 index 0000000..9aa6943 --- /dev/null +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/IFindTarget.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ddmuilib; + +public interface IFindTarget { + boolean findAndSelect(String text, boolean isNewSearch, boolean searchForward); +} diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/FindDialog.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/FindDialog.java deleted file mode 100644 index cfd1ee8..0000000 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/FindDialog.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ddmuilib.logcat; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -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.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * {@link FindDialog} provides a text box where users can enter text that should be - * searched for in the list of logcat messages. The buttons "Find Previous" and "Find Next" - * allow users to search forwards/backwards. This dialog simply provides a front end for the user - * and the actual task of searching is delegated to the {@link IFindTarget}. - */ -public class FindDialog extends Dialog { - private Label mStatusLabel; - private Button mFindNext; - private Button mFindPrevious; - private final IFindTarget mTarget; - private Text mSearchText; - private String mPreviousSearchText; - - private final static int FIND_NEXT_ID = IDialogConstants.CLIENT_ID; - private final static int FIND_PREVIOUS_ID = IDialogConstants.CLIENT_ID + 1; - - public FindDialog(Shell shell, IFindTarget target) { - super(shell); - - mTarget = target; - - setShellStyle((getShellStyle() & ~SWT.APPLICATION_MODAL) | SWT.MODELESS); - setBlockOnOpen(true); - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite panel = new Composite(parent, SWT.NONE); - panel.setLayout(new GridLayout(2, false)); - panel.setLayoutData(new GridData(GridData.FILL_BOTH)); - - Label lblMessage = new Label(panel, SWT.NONE); - lblMessage.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); - lblMessage.setText("Find:"); - - mSearchText = new Text(panel, SWT.BORDER); - mSearchText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); - mSearchText.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - boolean hasText = !mSearchText.getText().trim().isEmpty(); - mFindNext.setEnabled(hasText); - mFindPrevious.setEnabled(hasText); - } - }); - - mStatusLabel = new Label(panel, SWT.NONE); - mStatusLabel.setForeground(getShell().getDisplay().getSystemColor(SWT.COLOR_DARK_RED)); - GridData gd = new GridData(); - gd.horizontalSpan = 2; - gd.grabExcessHorizontalSpace = true; - mStatusLabel.setLayoutData(gd); - - return panel; - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, false); - mFindNext = createButton(parent, FIND_NEXT_ID, "Find Next", false); - mFindPrevious = createButton(parent, FIND_PREVIOUS_ID, "Find Previous", /* default */ true); - mFindNext.setEnabled(false); - mFindPrevious.setEnabled(false); - } - - @Override - protected void buttonPressed(int buttonId) { - if (buttonId == IDialogConstants.CLOSE_ID) { - close(); - return; - } - - if (buttonId == FIND_PREVIOUS_ID || buttonId == FIND_NEXT_ID) { - if (mTarget != null) { - String searchText = mSearchText.getText(); - boolean newSearch = !searchText.equals(mPreviousSearchText); - mPreviousSearchText = searchText; - boolean searchForward = buttonId == FIND_NEXT_ID; - - boolean hasMatches = mTarget.findAndSelect(searchText, newSearch, searchForward); - if (!hasMatches) { - mStatusLabel.setText("String not found"); - mStatusLabel.pack(); - } else { - mStatusLabel.setText(""); - } - } - } - } -} diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/IFindTarget.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/IFindTarget.java deleted file mode 100644 index f27c53e..0000000 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/IFindTarget.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ddmuilib.logcat; - -public interface IFindTarget { - boolean findAndSelect(String text, boolean isNewSearch, boolean searchForward); -} diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogCatPanel.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogCatPanel.java index 06952f9..e7dcec9 100644 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogCatPanel.java +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogCatPanel.java @@ -21,9 +21,11 @@ import com.android.ddmlib.IDevice; import com.android.ddmlib.Log.LogLevel; import com.android.ddmuilib.ITableFocusListener; import com.android.ddmuilib.ITableFocusListener.IFocusedTableActivator; +import com.android.ddmuilib.FindDialog; import com.android.ddmuilib.ImageLoader; import com.android.ddmuilib.SelectionDependentPanel; import com.android.ddmuilib.TableHelper; +import com.android.ddmuilib.AbstractBufferFindTarget; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.MenuManager; @@ -1443,7 +1445,7 @@ public final class LogCatPanel extends SelectionDependentPanel mAssertColor.dispose(); } - private class LogcatFindTarget extends RollingBufferFindTarget { + private class LogcatFindTarget extends AbstractBufferFindTarget { @Override public void selectAndReveal(int index) { mTable.deselectAll(); diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/RollingBufferFindTarget.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/RollingBufferFindTarget.java deleted file mode 100644 index b353a13..0000000 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/RollingBufferFindTarget.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ddmuilib.logcat; - -import java.util.regex.Pattern; - -/** - * {@link RollingBufferFindTarget} implements methods to find items inside a circular buffer. - */ -public abstract class RollingBufferFindTarget implements IFindTarget { - private int mCurrentSearchIndex; - - // Single element cache of the last search regex - private Pattern mLastSearchPattern; - private String mLastSearchText; - - @Override - public boolean findAndSelect(String text, boolean isNewSearch, boolean searchForward) { - boolean found = false; - int maxIndex = getItemCount(); - - synchronized (this) { - // Find starting index for this search - if (isNewSearch) { - // for new searches, start from an appropriate place as provided by the delegate - mCurrentSearchIndex = getStartingIndex(); - } else { - // for ongoing searches (finding next match for the same term), continue from - // the current result index - mCurrentSearchIndex = getNext(mCurrentSearchIndex, searchForward, maxIndex); - } - - // Create a regex pattern based on the search term. - Pattern pattern; - if (text.equals(mLastSearchText)) { - pattern = mLastSearchPattern; - } else { - pattern = Pattern.compile(text, Pattern.CASE_INSENSITIVE); - mLastSearchPattern = pattern; - mLastSearchText = text; - } - - // Iterate through the list of items. The search ends if we have gone through - // all items once. - int index = mCurrentSearchIndex; - do { - String msgText = getItem(mCurrentSearchIndex); - if (msgText != null && pattern.matcher(msgText).find()) { - found = true; - break; - } - - mCurrentSearchIndex = getNext(mCurrentSearchIndex, searchForward, maxIndex); - } while (index != mCurrentSearchIndex); // loop through entire contents once - } - - if (found) { - selectAndReveal(mCurrentSearchIndex); - } - - return found; - } - - /** Indicate that the log buffer has scrolled by certain number of elements */ - public void scrollBy(int delta) { - synchronized (this) { - if (mCurrentSearchIndex > 0) { - mCurrentSearchIndex = Math.max(0, mCurrentSearchIndex - delta); - } - } - } - - private int getNext(int index, boolean searchForward, int max) { - // increment or decrement index - index = searchForward ? index + 1 : index - 1; - - // take care of underflow - if (index == -1) { - index = max - 1; - } - - // ..and overflow - if (index == max) { - index = 0; - } - - return index; - } - - /** Obtain the number of items in the buffer */ - public abstract int getItemCount(); - - /** Obtain the item at given index */ - public abstract String getItem(int index); - - /** Select and reveal the item at given index */ - public abstract void selectAndReveal(int index); - - /** Obtain the index from which search should begin */ - public abstract int getStartingIndex(); -} diff --git a/ddms/libs/ddmuilib/tests/src/com/android/ddmuilib/logcat/RollingBufferFindTest.java b/ddms/libs/ddmuilib/tests/src/com/android/ddmuilib/logcat/RollingBufferFindTest.java index 7afac24..32a36c4 100644 --- a/ddms/libs/ddmuilib/tests/src/com/android/ddmuilib/logcat/RollingBufferFindTest.java +++ b/ddms/libs/ddmuilib/tests/src/com/android/ddmuilib/logcat/RollingBufferFindTest.java @@ -16,13 +16,15 @@ package com.android.ddmuilib.logcat; +import com.android.ddmuilib.AbstractBufferFindTarget; + import junit.framework.TestCase; import java.util.Arrays; import java.util.List; public class RollingBufferFindTest extends TestCase { - public class FindTarget extends RollingBufferFindTarget { + public class FindTarget extends AbstractBufferFindTarget { private int mSelectedItem = -1; private int mItemReadCount = 0; private List mItems = Arrays.asList( -- cgit v1.1