OSDN Git Service

eclair snapshot
[android-x86/packages-apps-Browser.git] / src / com / android / browser / ErrorConsoleView.java
1 /*
2  * Copyright (C) 2009 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.browser;
18
19 import android.content.Context;
20 import android.database.DataSetObserver;
21 import android.util.AttributeSet;
22 import android.view.LayoutInflater;
23 import android.view.View;
24 import android.view.ViewGroup;
25 import android.view.View.OnClickListener;
26 import android.webkit.WebView;
27 import android.widget.Button;
28 import android.widget.EditText;
29 import android.widget.LinearLayout;
30 import android.widget.ListView;
31 import android.widget.TextView;
32 import android.widget.TwoLineListItem;
33
34 import java.util.Vector;
35
36 /* package */ class ErrorConsoleView extends LinearLayout {
37
38     /**
39      * Define some constants to describe the visibility of the error console.
40      */
41     public static final int SHOW_MINIMIZED = 0;
42     public static final int SHOW_MAXIMIZED = 1;
43     public static final int SHOW_NONE      = 2;
44
45     private TextView mConsoleHeader;
46     private ErrorConsoleListView mErrorList;
47     private LinearLayout mEvalJsViewGroup;
48     private EditText mEvalEditText;
49     private Button mEvalButton;
50     private WebView mWebView;
51     private int mCurrentShowState = SHOW_NONE;
52
53     private boolean mSetupComplete = false;
54
55     // Before we've been asked to display the console, cache any messages that should
56     // be added to the console. Then when we do display the console, add them to the view
57     // then.
58     private Vector<ErrorConsoleMessage> mErrorMessageCache;
59
60     public ErrorConsoleView(Context context) {
61         super(context);
62     }
63
64     public ErrorConsoleView(Context context, AttributeSet attributes) {
65         super(context, attributes);
66     }
67
68     private void commonSetupIfNeeded() {
69         if (mSetupComplete) {
70             return;
71         }
72
73         LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
74                 Context.LAYOUT_INFLATER_SERVICE);
75         inflater.inflate(R.layout.error_console, this);
76
77         // Get references to each ui element.
78         mConsoleHeader = (TextView) findViewById(R.id.error_console_header_id);
79         mErrorList = (ErrorConsoleListView) findViewById(R.id.error_console_list_id);
80         mEvalJsViewGroup = (LinearLayout) findViewById(R.id.error_console_eval_view_group_id);
81         mEvalEditText = (EditText) findViewById(R.id.error_console_eval_text_id);
82         mEvalButton = (Button) findViewById(R.id.error_console_eval_button_id);
83
84         mEvalButton.setOnClickListener(new OnClickListener() {
85             public void onClick(View v) {
86                 // Send the javascript to be evaluated to webkit as a javascript: url
87                 // TODO: Can we expose access to webkit's JS interpreter here and evaluate it that
88                 // way? Note that this is called on the UI thread so we will need to post a message
89                 // to the WebCore thread to implement this.
90                 if (mWebView != null) {
91                     mWebView.loadUrl("javascript:" + mEvalEditText.getText());
92                 }
93
94                 mEvalEditText.setText("");
95             }
96         });
97
98         // Make clicking on the console title bar min/maximse it.
99         mConsoleHeader.setOnClickListener(new OnClickListener() {
100             public void onClick(View v) {
101                 if (mCurrentShowState == SHOW_MINIMIZED) {
102                     showConsole(SHOW_MAXIMIZED);
103                 } else {
104                     showConsole(SHOW_MINIMIZED);
105                 }
106             }
107         });
108
109         // Add any cached messages to the list now that we've assembled the view.
110         if (mErrorMessageCache != null) {
111             for (ErrorConsoleMessage msg : mErrorMessageCache) {
112                 mErrorList.addErrorMessage(msg.getMessage(), msg.getSourceID(), msg.getLineNumber());
113             }
114             mErrorMessageCache.clear();
115         }
116
117         mSetupComplete = true;
118     }
119
120     /**
121      * Adds a message to the set of messages the console uses.
122      */
123     public void addErrorMessage(String msg, String sourceId, int lineNumber) {
124         if (mSetupComplete) {
125             mErrorList.addErrorMessage(msg, sourceId, lineNumber);
126         } else {
127             if (mErrorMessageCache == null) {
128                 mErrorMessageCache = new Vector<ErrorConsoleMessage>();
129             }
130             mErrorMessageCache.add(new ErrorConsoleMessage(msg, sourceId, lineNumber));
131         }
132     }
133
134     /**
135      * Removes all error messages from the console.
136      */
137     public void clearErrorMessages() {
138         if (mSetupComplete) {
139             mErrorList.clearErrorMessages();
140         } else if (mErrorMessageCache != null) {
141             mErrorMessageCache.clear();
142         }
143     }
144
145     /**
146      * Returns the current number of errors displayed in the console.
147      */
148     public int numberOfErrors() {
149         if (mSetupComplete) {
150             return mErrorList.getCount();
151         } else {
152             return (mErrorMessageCache == null) ? 0 : mErrorMessageCache.size();
153         }
154     }
155
156     /**
157      * Sets the webview that this console is associated with. Currently this is used so
158      * we can call into webkit to evaluate JS expressions in the console.
159      */
160     public void setWebView(WebView webview) {
161         mWebView = webview;
162     }
163
164     /**
165      * Sets the visibility state of the console.
166      */
167     public void showConsole(int show_state) {
168         commonSetupIfNeeded();
169         switch (show_state) {
170             case SHOW_MINIMIZED:
171                 mConsoleHeader.setVisibility(View.VISIBLE);
172                 mConsoleHeader.setText(R.string.error_console_header_text_minimized);
173                 mErrorList.setVisibility(View.GONE);
174                 mEvalJsViewGroup.setVisibility(View.GONE);
175                 break;
176
177             case SHOW_MAXIMIZED:
178                 mConsoleHeader.setVisibility(View.VISIBLE);
179                 mConsoleHeader.setText(R.string.error_console_header_text_maximized);
180                 mErrorList.setVisibility(View.VISIBLE);
181                 mEvalJsViewGroup.setVisibility(View.VISIBLE);
182                 break;
183
184             case SHOW_NONE:
185                 mConsoleHeader.setVisibility(View.GONE);
186                 mErrorList.setVisibility(View.GONE);
187                 mEvalJsViewGroup.setVisibility(View.GONE);
188                 break;
189         }
190         mCurrentShowState = show_state;
191     }
192
193     /**
194      * Returns the current visibility state of the console.
195      */
196     public int getShowState() {
197         if (mSetupComplete) {
198             return mCurrentShowState;
199         } else {
200             return SHOW_NONE;
201         }
202     }
203
204     /**
205      * This class extends ListView to implement the View that will actually display the set of
206      * errors encountered on the current page.
207      */
208     private static class ErrorConsoleListView extends ListView {
209         // An adapter for this View that contains a list of error messages.
210         private ErrorConsoleMessageList mConsoleMessages;
211
212         public ErrorConsoleListView(Context context, AttributeSet attributes) {
213             super(context, attributes);
214             mConsoleMessages = new ErrorConsoleMessageList(context);
215             setAdapter(mConsoleMessages);
216         }
217
218         public void addErrorMessage(String msg, String sourceId, int lineNumber) {
219             mConsoleMessages.add(msg, sourceId, lineNumber);
220             setSelection(mConsoleMessages.getCount());
221         }
222
223         public void clearErrorMessages() {
224             mConsoleMessages.clear();
225         }
226
227         /**
228          * This class is an adapter for ErrorConsoleListView that contains the error console
229          * message data.
230          */
231         private class ErrorConsoleMessageList extends android.widget.BaseAdapter
232                 implements android.widget.ListAdapter {
233
234             private Vector<ErrorConsoleMessage> mMessages;
235             private LayoutInflater mInflater;
236
237             public ErrorConsoleMessageList(Context context) {
238                 mMessages = new Vector<ErrorConsoleMessage>();
239                 mInflater = (LayoutInflater)context.getSystemService(
240                         Context.LAYOUT_INFLATER_SERVICE);
241             }
242
243             /**
244              * Add a new message to the list and update the View.
245              */
246             public void add(String msg, String sourceID, int lineNumber) {
247                 mMessages.add(new ErrorConsoleMessage(msg, sourceID, lineNumber));
248                 notifyDataSetChanged();
249             }
250
251             /**
252              * Remove all messages from the list and update the view.
253              */
254             public void clear() {
255                 mMessages.clear();
256                 notifyDataSetChanged();
257             }
258
259             @Override
260             public boolean areAllItemsEnabled() {
261                 return false;
262             }
263
264             @Override
265             public boolean isEnabled(int position) {
266                 return false;
267             }
268
269             public long getItemId(int position) {
270                 return position;
271             }
272
273             public Object getItem(int position) {
274                 return mMessages.get(position);
275             }
276
277             public int getCount() {
278                 return mMessages.size();
279             }
280
281             @Override
282             public boolean hasStableIds() {
283                 return true;
284             }
285
286             /**
287              * Constructs a TwoLineListItem for the error at position.
288              */
289             public View getView(int position, View convertView, ViewGroup parent) {
290                 View view;
291                 ErrorConsoleMessage error = mMessages.get(position);
292
293                 if (error == null) {
294                     return null;
295                 }
296
297                 if (convertView == null) {
298                     view = mInflater.inflate(android.R.layout.two_line_list_item, parent, false);
299                 } else {
300                     view = convertView;
301                 }
302
303                 TextView headline = (TextView) view.findViewById(android.R.id.text1);
304                 TextView subText = (TextView) view.findViewById(android.R.id.text2);
305                 headline.setText(error.getSourceID() + ":" + error.getLineNumber());
306                 subText.setText(error.getMessage());
307                 return view;
308             }
309
310         }
311     }
312
313     /**
314      * This class holds the data for a single error message in the console.
315      */
316     private static class ErrorConsoleMessage {
317         private String mMessage;
318         private String mSourceID;
319         private int mLineNumber;
320
321         public ErrorConsoleMessage(String msg, String sourceID, int lineNumber) {
322             mMessage = msg;
323             mSourceID = sourceID;
324             mLineNumber = lineNumber;
325         }
326
327         public String getMessage() {
328             return mMessage;
329         }
330
331         public String getSourceID() {
332             return mSourceID;
333         }
334
335         public int getLineNumber() {
336             return mLineNumber;
337         }
338     }
339 }