• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.ddmuilib.logcat;
17 
18 import com.android.ddmlib.Log.LogLevel;
19 
20 import org.eclipse.jface.dialogs.IDialogConstants;
21 import org.eclipse.jface.dialogs.TitleAreaDialog;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.events.ModifyEvent;
24 import org.eclipse.swt.events.ModifyListener;
25 import org.eclipse.swt.layout.GridData;
26 import org.eclipse.swt.layout.GridLayout;
27 import org.eclipse.swt.widgets.Button;
28 import org.eclipse.swt.widgets.Combo;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.swt.widgets.Label;
32 import org.eclipse.swt.widgets.Shell;
33 import org.eclipse.swt.widgets.Text;
34 
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.regex.Pattern;
38 import java.util.regex.PatternSyntaxException;
39 
40 /**
41  * Dialog used to create or edit settings for a logcat filter.
42  */
43 public final class LogCatFilterSettingsDialog extends TitleAreaDialog {
44     private static final String TITLE = "Logcat Message Filter Settings";
45     private static final String DEFAULT_MESSAGE =
46             "Filter logcat messages by the source's tag, pid or minimum log level.\n"
47             + "Empty fields will match all messages.";
48 
49     private String mFilterName;
50     private String mTag;
51     private String mText;
52     private String mPid;
53     private String mAppName;
54     private String mLogLevel;
55 
56     private Text mFilterNameText;
57     private Text mTagFilterText;
58     private Text mTextFilterText;
59     private Text mPidFilterText;
60     private Text mAppNameFilterText;
61     private Combo mLogLevelCombo;
62     private Button mOkButton;
63 
64     /**
65      * Construct the filter settings dialog with default values for all fields.
66      * @param parentShell .
67      */
LogCatFilterSettingsDialog(Shell parentShell)68     public LogCatFilterSettingsDialog(Shell parentShell) {
69         super(parentShell);
70         setDefaults("", "", "", "", "", LogLevel.VERBOSE);
71     }
72 
73     /**
74      * Set the default values to show when the dialog is opened.
75      * @param filterName name for the filter.
76      * @param tag value for filter by tag
77      * @param text value for filter by text
78      * @param pid value for filter by pid
79      * @param appName value for filter by app name
80      * @param level value for filter by log level
81      */
setDefaults(String filterName, String tag, String text, String pid, String appName, LogLevel level)82     public void setDefaults(String filterName, String tag, String text, String pid, String appName,
83             LogLevel level) {
84         mFilterName = filterName;
85         mTag = tag;
86         mText = text;
87         mPid = pid;
88         mAppName = appName;
89         mLogLevel = level.getStringValue();
90     }
91 
92     @Override
createDialogArea(Composite shell)93     protected Control createDialogArea(Composite shell) {
94         setTitle(TITLE);
95         setMessage(DEFAULT_MESSAGE);
96 
97         Composite parent = (Composite) super.createDialogArea(shell);
98         Composite c = new Composite(parent, SWT.BORDER);
99         c.setLayout(new GridLayout(2, false));
100         c.setLayoutData(new GridData(GridData.FILL_BOTH));
101 
102         createLabel(c, "Filter Name:");
103         mFilterNameText = new Text(c, SWT.BORDER);
104         mFilterNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
105         mFilterNameText.setText(mFilterName);
106 
107         createSeparator(c);
108 
109         createLabel(c, "by Log Tag:");
110         mTagFilterText = new Text(c, SWT.BORDER);
111         mTagFilterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
112         mTagFilterText.setText(mTag);
113 
114         createLabel(c, "by Log Message:");
115         mTextFilterText = new Text(c, SWT.BORDER);
116         mTextFilterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
117         mTextFilterText.setText(mText);
118 
119         createLabel(c, "by PID:");
120         mPidFilterText = new Text(c, SWT.BORDER);
121         mPidFilterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
122         mPidFilterText.setText(mPid);
123 
124         createLabel(c, "by Application Name:");
125         mAppNameFilterText = new Text(c, SWT.BORDER);
126         mAppNameFilterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
127         mAppNameFilterText.setText(mAppName);
128 
129         createLabel(c, "by Log Level:");
130         mLogLevelCombo = new Combo(c, SWT.READ_ONLY | SWT.DROP_DOWN);
131         mLogLevelCombo.setItems(getLogLevels().toArray(new String[0]));
132         mLogLevelCombo.select(getLogLevels().indexOf(mLogLevel));
133 
134         /* call validateDialog() whenever user modifies any text field */
135         ModifyListener m = new ModifyListener() {
136             @Override
137             public void modifyText(ModifyEvent arg0) {
138                 DialogStatus status = validateDialog();
139                 mOkButton.setEnabled(status.valid);
140                 setErrorMessage(status.message);
141             }
142         };
143         mFilterNameText.addModifyListener(m);
144         mTagFilterText.addModifyListener(m);
145         mTextFilterText.addModifyListener(m);
146         mPidFilterText.addModifyListener(m);
147         mAppNameFilterText.addModifyListener(m);
148 
149         return c;
150     }
151 
152 
153     @Override
createButtonsForButtonBar(Composite parent)154     protected void createButtonsForButtonBar(Composite parent) {
155         super.createButtonsForButtonBar(parent);
156 
157         mOkButton = getButton(IDialogConstants.OK_ID);
158 
159         DialogStatus status = validateDialog();
160         mOkButton.setEnabled(status.valid);
161     }
162 
163     /**
164      * A tuple that specifies whether the current state of the inputs
165      * on the dialog is valid or not. If it is not valid, the message
166      * field stores the reason why it isn't.
167      */
168     private final class DialogStatus {
169         final boolean valid;
170         final String message;
171 
DialogStatus(boolean isValid, String errMessage)172         private DialogStatus(boolean isValid, String errMessage) {
173             valid = isValid;
174             message = errMessage;
175         }
176     }
177 
validateDialog()178     private DialogStatus validateDialog() {
179         /* check that there is some name for the filter */
180         if (mFilterNameText.getText().trim().equals("")) {
181             return new DialogStatus(false,
182                     "Please provide a name for this filter.");
183         }
184 
185         /* if a pid is provided, it should be a +ve integer */
186         String pidText = mPidFilterText.getText().trim();
187         if (pidText.trim().length() > 0) {
188             int pid = 0;
189             try {
190                 pid = Integer.parseInt(pidText);
191             } catch (NumberFormatException e) {
192                 return new DialogStatus(false,
193                         "PID should be a positive integer.");
194             }
195 
196             if (pid < 0) {
197                 return new DialogStatus(false,
198                         "PID should be a positive integer.");
199             }
200         }
201 
202         /* tag field must use a valid regex pattern */
203         String tagText = mTagFilterText.getText().trim();
204         if (tagText.trim().length() > 0) {
205             try {
206                 Pattern.compile(tagText);
207             } catch (PatternSyntaxException e) {
208                 return new DialogStatus(false,
209                         "Invalid regex used in tag field: " + e.getMessage());
210             }
211         }
212 
213         /* text field must use a valid regex pattern */
214         String messageText = mTextFilterText.getText().trim();
215         if (messageText.trim().length() > 0) {
216             try {
217                 Pattern.compile(messageText);
218             } catch (PatternSyntaxException e) {
219                 return new DialogStatus(false,
220                         "Invalid regex used in text field: " + e.getMessage());
221             }
222         }
223 
224         /* app name field must use a valid regex pattern */
225         String appNameText = mAppNameFilterText.getText().trim();
226         if (appNameText.trim().length() > 0) {
227             try {
228                 Pattern.compile(appNameText);
229             } catch (PatternSyntaxException e) {
230                 return new DialogStatus(false,
231                         "Invalid regex used in application name field: " + e.getMessage());
232             }
233         }
234 
235         return new DialogStatus(true, null);
236     }
237 
createSeparator(Composite c)238     private void createSeparator(Composite c) {
239         Label l = new Label(c, SWT.SEPARATOR | SWT.HORIZONTAL);
240         GridData gd = new GridData(GridData.FILL_HORIZONTAL);
241         gd.horizontalSpan = 2;
242         l.setLayoutData(gd);
243     }
244 
createLabel(Composite c, String text)245     private void createLabel(Composite c, String text) {
246         Label l = new Label(c, SWT.NONE);
247         l.setText(text);
248         GridData gd = new GridData();
249         gd.horizontalAlignment = SWT.RIGHT;
250         l.setLayoutData(gd);
251     }
252 
253     @Override
okPressed()254     protected void okPressed() {
255         /* save values from the widgets before the shell is closed. */
256         mFilterName = mFilterNameText.getText();
257         mTag = mTagFilterText.getText();
258         mText = mTextFilterText.getText();
259         mLogLevel = mLogLevelCombo.getText();
260         mPid = mPidFilterText.getText();
261         mAppName = mAppNameFilterText.getText();
262 
263         super.okPressed();
264     }
265 
266     /**
267      * Obtain the name for this filter.
268      * @return user provided filter name, maybe empty.
269      */
getFilterName()270     public String getFilterName() {
271         return mFilterName;
272     }
273 
274     /**
275      * Obtain the tag regex to filter by.
276      * @return user provided tag regex, maybe empty.
277      */
getTag()278     public String getTag() {
279         return mTag;
280     }
281 
282     /**
283      * Obtain the text regex to filter by.
284      * @return user provided tag regex, maybe empty.
285      */
getText()286     public String getText() {
287         return mText;
288     }
289 
290     /**
291      * Obtain user provided PID to filter by.
292      * @return user provided pid, maybe empty.
293      */
getPid()294     public String getPid() {
295         return mPid;
296     }
297 
298     /**
299      * Obtain user provided application name to filter by.
300      * @return user provided app name regex, maybe empty
301      */
getAppName()302     public String getAppName() {
303         return mAppName;
304     }
305 
306     /**
307      * Obtain log level to filter by.
308      * @return log level string.
309      */
getLogLevel()310     public String getLogLevel() {
311         return mLogLevel;
312     }
313 
314     /**
315      * Obtain the string representation of all supported log levels.
316      * @return an array of strings, each representing a certain log level.
317      */
getLogLevels()318     public static List<String> getLogLevels() {
319         List<String> logLevels = new ArrayList<String>();
320 
321         for (LogLevel l : LogLevel.values()) {
322             logLevels.add(l.getStringValue());
323         }
324 
325         return logLevels;
326     }
327 }
328