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