• 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             public void modifyText(ModifyEvent arg0) {
137                 DialogStatus status = validateDialog();
138                 mOkButton.setEnabled(status.valid);
139                 setErrorMessage(status.message);
140             }
141         };
142         mFilterNameText.addModifyListener(m);
143         mTagFilterText.addModifyListener(m);
144         mTextFilterText.addModifyListener(m);
145         mPidFilterText.addModifyListener(m);
146         mAppNameFilterText.addModifyListener(m);
147 
148         return c;
149     }
150 
151 
152     @Override
createButtonsForButtonBar(Composite parent)153     protected void createButtonsForButtonBar(Composite parent) {
154         super.createButtonsForButtonBar(parent);
155 
156         mOkButton = getButton(IDialogConstants.OK_ID);
157 
158         DialogStatus status = validateDialog();
159         mOkButton.setEnabled(status.valid);
160     }
161 
162     /**
163      * A tuple that specifies whether the current state of the inputs
164      * on the dialog is valid or not. If it is not valid, the message
165      * field stores the reason why it isn't.
166      */
167     private final class DialogStatus {
168         final boolean valid;
169         final String message;
170 
DialogStatus(boolean isValid, String errMessage)171         private DialogStatus(boolean isValid, String errMessage) {
172             valid = isValid;
173             message = errMessage;
174         }
175     }
176 
validateDialog()177     private DialogStatus validateDialog() {
178         /* check that there is some name for the filter */
179         if (mFilterNameText.getText().trim().equals("")) {
180             return new DialogStatus(false,
181                     "Please provide a name for this filter.");
182         }
183 
184         /* if a pid is provided, it should be a +ve integer */
185         String pidText = mPidFilterText.getText().trim();
186         if (pidText.trim().length() > 0) {
187             int pid = 0;
188             try {
189                 pid = Integer.parseInt(pidText);
190             } catch (NumberFormatException e) {
191                 return new DialogStatus(false,
192                         "PID should be a positive integer.");
193             }
194 
195             if (pid < 0) {
196                 return new DialogStatus(false,
197                         "PID should be a positive integer.");
198             }
199         }
200 
201         /* tag field must use a valid regex pattern */
202         String tagText = mTagFilterText.getText().trim();
203         if (tagText.trim().length() > 0) {
204             try {
205                 Pattern.compile(tagText);
206             } catch (PatternSyntaxException e) {
207                 return new DialogStatus(false,
208                         "Invalid regex used in tag field: " + e.getMessage());
209             }
210         }
211 
212         /* text field must use a valid regex pattern */
213         String messageText = mTextFilterText.getText().trim();
214         if (messageText.trim().length() > 0) {
215             try {
216                 Pattern.compile(messageText);
217             } catch (PatternSyntaxException e) {
218                 return new DialogStatus(false,
219                         "Invalid regex used in text field: " + e.getMessage());
220             }
221         }
222 
223         /* app name field must use a valid regex pattern */
224         String appNameText = mAppNameFilterText.getText().trim();
225         if (appNameText.trim().length() > 0) {
226             try {
227                 Pattern.compile(appNameText);
228             } catch (PatternSyntaxException e) {
229                 return new DialogStatus(false,
230                         "Invalid regex used in application name field: " + e.getMessage());
231             }
232         }
233 
234         return new DialogStatus(true, null);
235     }
236 
createSeparator(Composite c)237     private void createSeparator(Composite c) {
238         Label l = new Label(c, SWT.SEPARATOR | SWT.HORIZONTAL);
239         GridData gd = new GridData(GridData.FILL_HORIZONTAL);
240         gd.horizontalSpan = 2;
241         l.setLayoutData(gd);
242     }
243 
createLabel(Composite c, String text)244     private void createLabel(Composite c, String text) {
245         Label l = new Label(c, SWT.NONE);
246         l.setText(text);
247         GridData gd = new GridData();
248         gd.horizontalAlignment = SWT.RIGHT;
249         l.setLayoutData(gd);
250     }
251 
252     @Override
okPressed()253     protected void okPressed() {
254         /* save values from the widgets before the shell is closed. */
255         mFilterName = mFilterNameText.getText();
256         mTag = mTagFilterText.getText();
257         mText = mTextFilterText.getText();
258         mLogLevel = mLogLevelCombo.getText();
259         mPid = mPidFilterText.getText();
260         mAppName = mAppNameFilterText.getText();
261 
262         super.okPressed();
263     }
264 
265     /**
266      * Obtain the name for this filter.
267      * @return user provided filter name, maybe empty.
268      */
getFilterName()269     public String getFilterName() {
270         return mFilterName;
271     }
272 
273     /**
274      * Obtain the tag regex to filter by.
275      * @return user provided tag regex, maybe empty.
276      */
getTag()277     public String getTag() {
278         return mTag;
279     }
280 
281     /**
282      * Obtain the text regex to filter by.
283      * @return user provided tag regex, maybe empty.
284      */
getText()285     public String getText() {
286         return mText;
287     }
288 
289     /**
290      * Obtain user provided PID to filter by.
291      * @return user provided pid, maybe empty.
292      */
getPid()293     public String getPid() {
294         return mPid;
295     }
296 
297     /**
298      * Obtain user provided application name to filter by.
299      * @return user provided app name regex, maybe empty
300      */
getAppName()301     public String getAppName() {
302         return mAppName;
303     }
304 
305     /**
306      * Obtain log level to filter by.
307      * @return log level string.
308      */
getLogLevel()309     public String getLogLevel() {
310         return mLogLevel;
311     }
312 
313     /**
314      * Obtain the string representation of all supported log levels.
315      * @return an array of strings, each representing a certain log level.
316      */
getLogLevels()317     public static List<String> getLogLevels() {
318         List<String> logLevels = new ArrayList<String>();
319 
320         for (LogLevel l : LogLevel.values()) {
321             logLevels.add(l.getStringValue());
322         }
323 
324         return logLevels;
325     }
326 }
327