PageRenderTime 42ms CodeModel.GetById 18ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/WebVox/src/com/marvin/webvox/ErrorConsoleView.java

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