1 /*
2  * Copyright (C) 2007 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 
17 package com.android.ide.eclipse.ddms.views;
18 
19 import com.android.ddmlib.Log.LogLevel;
20 import com.android.ddmuilib.ImageLoader;
21 import com.android.ddmuilib.logcat.LogColors;
22 import com.android.ddmuilib.logcat.LogFilter;
23 import com.android.ddmuilib.logcat.LogPanel;
24 import com.android.ddmuilib.logcat.LogPanel.ILogFilterStorageManager;
25 import com.android.ddmuilib.logcat.LogPanel.LogCatViewInterface;
26 import com.android.ide.eclipse.ddms.CommonAction;
27 import com.android.ide.eclipse.ddms.DdmsPlugin;
28 import com.android.ide.eclipse.ddms.i18n.Messages;
29 import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
30 
31 import org.eclipse.core.resources.IFile;
32 import org.eclipse.core.resources.IMarker;
33 import org.eclipse.core.runtime.CoreException;
34 import org.eclipse.core.runtime.Status;
35 import org.eclipse.jface.action.Action;
36 import org.eclipse.jface.action.IAction;
37 import org.eclipse.jface.action.IMenuManager;
38 import org.eclipse.jface.action.IToolBarManager;
39 import org.eclipse.jface.action.Separator;
40 import org.eclipse.jface.preference.IPreferenceStore;
41 import org.eclipse.swt.dnd.Clipboard;
42 import org.eclipse.swt.graphics.Color;
43 import org.eclipse.swt.graphics.Font;
44 import org.eclipse.swt.graphics.FontData;
45 import org.eclipse.swt.widgets.Composite;
46 import org.eclipse.swt.widgets.Display;
47 import org.eclipse.ui.IActionBars;
48 import org.eclipse.ui.IPerspectiveRegistry;
49 import org.eclipse.ui.IWorkbench;
50 import org.eclipse.ui.IWorkbenchPage;
51 import org.eclipse.ui.IWorkbenchWindow;
52 import org.eclipse.ui.PlatformUI;
53 import org.eclipse.ui.WorkbenchException;
54 import org.eclipse.ui.actions.ActionFactory;
55 import org.eclipse.ui.ide.IDE;
56 
57 import java.util.ArrayList;
58 
59 /**
60  * The log cat view displays log output from the current device selection.
61  */
62 public final class OldLogCatView extends SelectionDependentViewPart implements LogCatViewInterface {
63 
64     public static final String ID = "com.android.ide.eclipse.ddms.views.OldLogCatView"; //$NON-NLS-1$
65 
66     private static final String PREFS_COL_TIME =
67             DdmsPlugin.PLUGIN_ID + ".logcat.time"; //$NON-NLS-1$
68     private static final String PREFS_COL_LEVEL =
69             DdmsPlugin.PLUGIN_ID + ".logcat.level"; //$NON-NLS-1$
70     private static final String PREFS_COL_PID =
71             DdmsPlugin.PLUGIN_ID + ".logcat.pid"; //$NON-NLS-1$
72     private static final String PREFS_COL_TAG =
73             DdmsPlugin.PLUGIN_ID + ".logcat.tag"; //$NON-NLS-1$
74     private static final String PREFS_COL_MESSAGE =
75             DdmsPlugin.PLUGIN_ID + ".logcat.message"; //$NON-NLS-1$
76 
77     private static final String PREFS_FILTERS =
78             DdmsPlugin.PLUGIN_ID + ".logcat.filters"; //$NON-NLS-1$
79 
80     public static final String CHOICE_METHOD_DECLARATION =
81             DdmsPlugin.PLUGIN_ID + ".logcat.MethodDeclaration"; //$NON-NLS-1$
82     public static final String CHOICE_ERROR_LINE =
83             DdmsPlugin.PLUGIN_ID + ".logcat.ErrorLine"; //$NON-NLS-1$
84 
85     /* Default values for the switch of perspective. */
86     public static final boolean DEFAULT_SWITCH_PERSPECTIVE = true;
87     public static final String DEFAULT_PERSPECTIVE_ID = "org.eclipse.jdt.ui.JavaPerspective"; //$NON-NLS-1$
88     private static OldLogCatView sThis;
89     private LogPanel mLogPanel;
90 
91     private CommonAction mCreateFilterAction;
92     private CommonAction mDeleteFilterAction;
93     private CommonAction mEditFilterAction;
94     private CommonAction mExportAction;
95 
96     private CommonAction[] mLogLevelActions;
97     private String[] mLogLevelIcons = {
98             "v.png", //$NON-NLS-1S
99             "d.png", //$NON-NLS-1S
100             "i.png", //$NON-NLS-1S
101             "w.png", //$NON-NLS-1S
102             "e.png", //$NON-NLS-1S
103     };
104 
105     private Action mClearAction;
106 
107     private Clipboard mClipboard;
108 
109     /**
110      * An implementation of {@link ILogFilterStorageManager} to bridge to the
111      * eclipse preference store, and saves the log filters.
112      */
113     private final class FilterStorage implements ILogFilterStorageManager {
114 
115         @Override
getFilterFromStore()116         public LogFilter[] getFilterFromStore() {
117             String filterPrefs = DdmsPlugin.getDefault().getPreferenceStore().getString(
118                     PREFS_FILTERS);
119 
120             // split in a string per filter
121             String[] filters = filterPrefs.split("\\|"); //$NON-NLS-1$
122 
123             ArrayList<LogFilter> list =
124                     new ArrayList<LogFilter>(filters.length);
125 
126             for (String f : filters) {
127                 if (f.length() > 0) {
128                     LogFilter logFilter = new LogFilter();
129                     if (logFilter.loadFromString(f)) {
130                         list.add(logFilter);
131                     }
132                 }
133             }
134 
135             return list.toArray(new LogFilter[list.size()]);
136         }
137 
138         @Override
saveFilters(LogFilter[] filters)139         public void saveFilters(LogFilter[] filters) {
140             StringBuilder sb = new StringBuilder();
141             for (LogFilter f : filters) {
142                 String filterString = f.toString();
143                 sb.append(filterString);
144                 sb.append('|');
145             }
146 
147             DdmsPlugin.getDefault().getPreferenceStore().setValue(PREFS_FILTERS, sb.toString());
148         }
149 
150         @Override
requiresDefaultFilter()151         public boolean requiresDefaultFilter() {
152             return true;
153         }
154     }
155 
OldLogCatView()156     public OldLogCatView() {
157         sThis = this;
158         LogPanel.PREFS_TIME = PREFS_COL_TIME;
159         LogPanel.PREFS_LEVEL = PREFS_COL_LEVEL;
160         LogPanel.PREFS_PID = PREFS_COL_PID;
161         LogPanel.PREFS_TAG = PREFS_COL_TAG;
162         LogPanel.PREFS_MESSAGE = PREFS_COL_MESSAGE;
163     }
164 
165     /**
166      * Returns the singleton instance.
167      */
getInstance()168     public static OldLogCatView getInstance() {
169         return sThis;
170     }
171 
172     /**
173      * Sets the display font.
174      *
175      * @param font The font.
176      */
setFont(Font font)177     public static void setFont(Font font) {
178         if (sThis != null && sThis.mLogPanel != null) {
179             sThis.mLogPanel.setFont(font);
180         }
181     }
182 
183     @Override
createPartControl(Composite parent)184     public void createPartControl(Composite parent) {
185         Display d = parent.getDisplay();
186         LogColors colors = new LogColors();
187 
188         ImageLoader loader = ImageLoader.getDdmUiLibLoader();
189 
190         colors.infoColor = new Color(d, 0, 127, 0);
191         colors.debugColor = new Color(d, 0, 0, 127);
192         colors.errorColor = new Color(d, 255, 0, 0);
193         colors.warningColor = new Color(d, 255, 127, 0);
194         colors.verboseColor = new Color(d, 0, 0, 0);
195 
196         mCreateFilterAction = new CommonAction(Messages.LogCatView_Create_Filter) {
197             @Override
198             public void run() {
199                 mLogPanel.addFilter();
200             }
201         };
202         mCreateFilterAction.setToolTipText(Messages.LogCatView_Create_Filter_Tooltip);
203         mCreateFilterAction.setImageDescriptor(loader.loadDescriptor("add.png")); //$NON-NLS-1$
204 
205         mEditFilterAction = new CommonAction(Messages.LogCatView_Edit_Filter) {
206             @Override
207             public void run() {
208                 mLogPanel.editFilter();
209             }
210         };
211         mEditFilterAction.setToolTipText(Messages.LogCatView_Edit_Filter_Tooltip);
212         mEditFilterAction.setImageDescriptor(loader.loadDescriptor("edit.png")); //$NON-NLS-1$
213 
214         mDeleteFilterAction = new CommonAction(Messages.LogCatView_Delete_Filter) {
215             @Override
216             public void run() {
217                 mLogPanel.deleteFilter();
218             }
219         };
220         mDeleteFilterAction.setToolTipText(Messages.LogCatView_Delete_Filter_Tooltip);
221         mDeleteFilterAction.setImageDescriptor(loader.loadDescriptor("delete.png")); //$NON-NLS-1$
222 
223         mExportAction = new CommonAction(Messages.LogCatView_Export_Selection_As_Text) {
224             @Override
225             public void run() {
226                 mLogPanel.save();
227             }
228         };
229         mExportAction.setToolTipText(Messages.LogCatView_Export_Selection_As_Text_Tooltip);
230         mExportAction.setImageDescriptor(loader.loadDescriptor("save.png")); //$NON-NLS-1$
231 
232         LogLevel[] levels = LogLevel.values();
233         mLogLevelActions = new CommonAction[mLogLevelIcons.length];
234         for (int i = 0; i < mLogLevelActions.length; i++) {
235             String name = levels[i].getStringValue();
236             mLogLevelActions[i] = new CommonAction(name, IAction.AS_CHECK_BOX) {
237                 @Override
238                 public void run() {
239                     // disable the other actions and record current index
240                     for (int j = 0; j < mLogLevelActions.length; j++) {
241                         Action a = mLogLevelActions[j];
242                         if (a == this) {
243                             a.setChecked(true);
244 
245                             // set the log level
246                             mLogPanel.setCurrentFilterLogLevel(j + 2);
247                         } else {
248                             a.setChecked(false);
249                         }
250                     }
251                 }
252             };
253 
254             mLogLevelActions[i].setToolTipText(name);
255             mLogLevelActions[i].setImageDescriptor(loader.loadDescriptor(mLogLevelIcons[i]));
256         }
257 
258         mClearAction = new Action(Messages.LogCatView_Clear_Log) {
259             @Override
260             public void run() {
261                 mLogPanel.clear();
262             }
263         };
264         mClearAction.setImageDescriptor(loader.loadDescriptor("clear.png")); //$NON-NLS-1$
265 
266         // now create the log view
267         mLogPanel = new LogPanel(colors, new FilterStorage(), LogPanel.FILTER_MANUAL);
268         mLogPanel.setLogCatViewInterface(this);
269         mLogPanel.setActions(mDeleteFilterAction, mEditFilterAction, mLogLevelActions);
270 
271         // get the font
272         String fontStr = DdmsPlugin.getDefault().getPreferenceStore().getString(
273                 PreferenceInitializer.ATTR_LOGCAT_FONT);
274         if (fontStr != null) {
275             FontData data = new FontData(fontStr);
276 
277             if (fontStr != null) {
278                 mLogPanel.setFont(new Font(parent.getDisplay(), data));
279             }
280         }
281 
282         mLogPanel.createPanel(parent);
283         setSelectionDependentPanel(mLogPanel);
284 
285         // place the actions.
286         placeActions();
287 
288         // setup the copy action
289         mClipboard = new Clipboard(d);
290         IActionBars actionBars = getViewSite().getActionBars();
291         actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), new Action(
292                 Messages.LogCatView_Copy) {
293             @Override
294             public void run() {
295                 mLogPanel.copy(mClipboard);
296             }
297         });
298 
299         // setup the select all action
300         actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
301                 new Action(Messages.LogCatView_Select_All) {
302                     @Override
303                     public void run() {
304                         mLogPanel.selectAll();
305                     }
306                 });
307     }
308 
309     @Override
dispose()310     public void dispose() {
311         mLogPanel.stopLogCat(true);
312         mClipboard.dispose();
313     }
314 
315     @Override
setFocus()316     public void setFocus() {
317         mLogPanel.setFocus();
318     }
319 
320     /**
321      * Place the actions in the ui.
322      */
placeActions()323     private void placeActions() {
324         IActionBars actionBars = getViewSite().getActionBars();
325 
326         // first in the menu
327         IMenuManager menuManager = actionBars.getMenuManager();
328         menuManager.add(mCreateFilterAction);
329         menuManager.add(mEditFilterAction);
330         menuManager.add(mDeleteFilterAction);
331         menuManager.add(new Separator());
332         menuManager.add(mClearAction);
333         menuManager.add(new Separator());
334         menuManager.add(mExportAction);
335 
336         // and then in the toolbar
337         IToolBarManager toolBarManager = actionBars.getToolBarManager();
338         for (CommonAction a : mLogLevelActions) {
339             toolBarManager.add(a);
340         }
341         toolBarManager.add(new Separator());
342         toolBarManager.add(mCreateFilterAction);
343         toolBarManager.add(mEditFilterAction);
344         toolBarManager.add(mDeleteFilterAction);
345         toolBarManager.add(new Separator());
346         toolBarManager.add(mClearAction);
347     }
348 
openFile(IFile file, IMarker marker)349     void openFile(IFile file, IMarker marker) {
350         try {
351             IWorkbenchPage page = getViewSite().getWorkbenchWindow()
352                     .getActivePage();
353             if (page != null) {
354                 IDE.openEditor(page, marker);
355                 marker.delete();
356             }
357         } catch (CoreException e) {
358             Status s = new Status(Status.ERROR, DdmsPlugin.PLUGIN_ID, e.getMessage(), e);
359             DdmsPlugin.getDefault().getLog().log(s);
360         }
361     }
362 
switchPerspective()363     void switchPerspective() {
364         IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
365         if (store.getBoolean(PreferenceInitializer.ATTR_SWITCH_PERSPECTIVE)) {
366             IWorkbench workbench = PlatformUI.getWorkbench();
367             IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
368             IPerspectiveRegistry perspectiveRegistry = workbench.getPerspectiveRegistry();
369             String perspectiveId = store.getString(PreferenceInitializer.ATTR_PERSPECTIVE_ID);
370             if (perspectiveId != null
371                     && perspectiveId.length() > 0
372                     && perspectiveRegistry.findPerspectiveWithId(perspectiveId) != null) {
373                 try {
374                     workbench.showPerspective(perspectiveId, window);
375                 } catch (WorkbenchException e) {
376                     e.printStackTrace();
377                 }
378             }
379         }
380     }
381 
382     @Override
onDoubleClick()383     public void onDoubleClick() {
384     }
385 }
386