| /* |
| * Copyright (C) 2009 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.browser; |
| |
| import android.content.Context; |
| import android.database.DataSetObserver; |
| import android.graphics.Color; |
| import android.util.AttributeSet; |
| import android.view.LayoutInflater; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.view.View.OnClickListener; |
| import android.webkit.ConsoleMessage; |
| import android.webkit.WebView; |
| import android.widget.Button; |
| import android.widget.EditText; |
| import android.widget.LinearLayout; |
| import android.widget.ListView; |
| import android.widget.TextView; |
| import android.widget.TwoLineListItem; |
| |
| import java.util.Vector; |
| |
| /* package */ class ErrorConsoleView extends LinearLayout { |
| |
| /** |
| * Define some constants to describe the visibility of the error console. |
| */ |
| public static final int SHOW_MINIMIZED = 0; |
| public static final int SHOW_MAXIMIZED = 1; |
| public static final int SHOW_NONE = 2; |
| |
| private TextView mConsoleHeader; |
| private ErrorConsoleListView mErrorList; |
| private LinearLayout mEvalJsViewGroup; |
| private EditText mEvalEditText; |
| private Button mEvalButton; |
| private WebView mWebView; |
| private int mCurrentShowState = SHOW_NONE; |
| |
| private boolean mSetupComplete = false; |
| |
| // Before we've been asked to display the console, cache any messages that should |
| // be added to the console. Then when we do display the console, add them to the view |
| // then. |
| private Vector<ConsoleMessage> mErrorMessageCache; |
| |
| public ErrorConsoleView(Context context) { |
| super(context); |
| } |
| |
| public ErrorConsoleView(Context context, AttributeSet attributes) { |
| super(context, attributes); |
| } |
| |
| private void commonSetupIfNeeded() { |
| if (mSetupComplete) { |
| return; |
| } |
| |
| LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( |
| Context.LAYOUT_INFLATER_SERVICE); |
| inflater.inflate(R.layout.error_console, this); |
| |
| // Get references to each ui element. |
| mConsoleHeader = (TextView) findViewById(R.id.error_console_header_id); |
| mErrorList = (ErrorConsoleListView) findViewById(R.id.error_console_list_id); |
| mEvalJsViewGroup = (LinearLayout) findViewById(R.id.error_console_eval_view_group_id); |
| mEvalEditText = (EditText) findViewById(R.id.error_console_eval_text_id); |
| mEvalButton = (Button) findViewById(R.id.error_console_eval_button_id); |
| |
| mEvalButton.setOnClickListener(new OnClickListener() { |
| public void onClick(View v) { |
| // Send the javascript to be evaluated to webkit as a javascript: url |
| // TODO: Can we expose access to webkit's JS interpreter here and evaluate it that |
| // way? Note that this is called on the UI thread so we will need to post a message |
| // to the WebCore thread to implement this. |
| if (mWebView != null) { |
| mWebView.loadUrl("javascript:" + mEvalEditText.getText()); |
| } |
| |
| mEvalEditText.setText(""); |
| } |
| }); |
| |
| // Make clicking on the console title bar min/maximse it. |
| mConsoleHeader.setOnClickListener(new OnClickListener() { |
| public void onClick(View v) { |
| if (mCurrentShowState == SHOW_MINIMIZED) { |
| showConsole(SHOW_MAXIMIZED); |
| } else { |
| showConsole(SHOW_MINIMIZED); |
| } |
| } |
| }); |
| |
| // Add any cached messages to the list now that we've assembled the view. |
| if (mErrorMessageCache != null) { |
| for (ConsoleMessage msg : mErrorMessageCache) { |
| mErrorList.addErrorMessage(msg); |
| } |
| mErrorMessageCache.clear(); |
| } |
| |
| mSetupComplete = true; |
| } |
| |
| /** |
| * Adds a message to the set of messages the console uses. |
| */ |
| public void addErrorMessage(ConsoleMessage consoleMessage) { |
| if (mSetupComplete) { |
| mErrorList.addErrorMessage(consoleMessage); |
| } else { |
| if (mErrorMessageCache == null) { |
| mErrorMessageCache = new Vector<ConsoleMessage>(); |
| } |
| mErrorMessageCache.add(consoleMessage); |
| } |
| } |
| |
| /** |
| * Removes all error messages from the console. |
| */ |
| public void clearErrorMessages() { |
| if (mSetupComplete) { |
| mErrorList.clearErrorMessages(); |
| } else if (mErrorMessageCache != null) { |
| mErrorMessageCache.clear(); |
| } |
| } |
| |
| /** |
| * Returns the current number of errors displayed in the console. |
| */ |
| public int numberOfErrors() { |
| if (mSetupComplete) { |
| return mErrorList.getCount(); |
| } else { |
| return (mErrorMessageCache == null) ? 0 : mErrorMessageCache.size(); |
| } |
| } |
| |
| /** |
| * Sets the webview that this console is associated with. Currently this is used so |
| * we can call into webkit to evaluate JS expressions in the console. |
| */ |
| public void setWebView(WebView webview) { |
| mWebView = webview; |
| } |
| |
| /** |
| * Sets the visibility state of the console. |
| */ |
| public void showConsole(int show_state) { |
| commonSetupIfNeeded(); |
| switch (show_state) { |
| case SHOW_MINIMIZED: |
| mConsoleHeader.setVisibility(View.VISIBLE); |
| mConsoleHeader.setText(R.string.error_console_header_text_minimized); |
| mErrorList.setVisibility(View.GONE); |
| mEvalJsViewGroup.setVisibility(View.GONE); |
| break; |
| |
| case SHOW_MAXIMIZED: |
| mConsoleHeader.setVisibility(View.VISIBLE); |
| mConsoleHeader.setText(R.string.error_console_header_text_maximized); |
| mErrorList.setVisibility(View.VISIBLE); |
| mEvalJsViewGroup.setVisibility(View.VISIBLE); |
| break; |
| |
| case SHOW_NONE: |
| mConsoleHeader.setVisibility(View.GONE); |
| mErrorList.setVisibility(View.GONE); |
| mEvalJsViewGroup.setVisibility(View.GONE); |
| break; |
| } |
| mCurrentShowState = show_state; |
| } |
| |
| /** |
| * Returns the current visibility state of the console. |
| */ |
| public int getShowState() { |
| if (mSetupComplete) { |
| return mCurrentShowState; |
| } else { |
| return SHOW_NONE; |
| } |
| } |
| |
| /** |
| * This class extends ListView to implement the View that will actually display the set of |
| * errors encountered on the current page. |
| */ |
| private static class ErrorConsoleListView extends ListView { |
| // An adapter for this View that contains a list of error messages. |
| private ErrorConsoleMessageList mConsoleMessages; |
| |
| public ErrorConsoleListView(Context context, AttributeSet attributes) { |
| super(context, attributes); |
| mConsoleMessages = new ErrorConsoleMessageList(context); |
| setAdapter(mConsoleMessages); |
| } |
| |
| public void addErrorMessage(ConsoleMessage consoleMessage) { |
| mConsoleMessages.add(consoleMessage); |
| setSelection(mConsoleMessages.getCount()); |
| } |
| |
| public void clearErrorMessages() { |
| mConsoleMessages.clear(); |
| } |
| |
| /** |
| * This class is an adapter for ErrorConsoleListView that contains the error console |
| * message data. |
| */ |
| private static class ErrorConsoleMessageList extends android.widget.BaseAdapter |
| implements android.widget.ListAdapter { |
| |
| private Vector<ConsoleMessage> mMessages; |
| private LayoutInflater mInflater; |
| |
| public ErrorConsoleMessageList(Context context) { |
| mMessages = new Vector<ConsoleMessage>(); |
| mInflater = (LayoutInflater)context.getSystemService( |
| Context.LAYOUT_INFLATER_SERVICE); |
| } |
| |
| /** |
| * Add a new message to the list and update the View. |
| */ |
| public void add(ConsoleMessage consoleMessage) { |
| mMessages.add(consoleMessage); |
| notifyDataSetChanged(); |
| } |
| |
| /** |
| * Remove all messages from the list and update the view. |
| */ |
| public void clear() { |
| mMessages.clear(); |
| notifyDataSetChanged(); |
| } |
| |
| @Override |
| public boolean areAllItemsEnabled() { |
| return false; |
| } |
| |
| @Override |
| public boolean isEnabled(int position) { |
| return false; |
| } |
| |
| public long getItemId(int position) { |
| return position; |
| } |
| |
| public Object getItem(int position) { |
| return mMessages.get(position); |
| } |
| |
| public int getCount() { |
| return mMessages.size(); |
| } |
| |
| @Override |
| public boolean hasStableIds() { |
| return true; |
| } |
| |
| /** |
| * Constructs a TwoLineListItem for the error at position. |
| */ |
| public View getView(int position, View convertView, ViewGroup parent) { |
| View view; |
| ConsoleMessage error = mMessages.get(position); |
| |
| if (error == null) { |
| return null; |
| } |
| |
| if (convertView == null) { |
| view = mInflater.inflate(android.R.layout.two_line_list_item, parent, false); |
| } else { |
| view = convertView; |
| } |
| |
| TextView headline = (TextView) view.findViewById(android.R.id.text1); |
| TextView subText = (TextView) view.findViewById(android.R.id.text2); |
| headline.setText(error.sourceId() + ":" + error.lineNumber()); |
| subText.setText(error.message()); |
| switch (error.messageLevel()) { |
| case ERROR: |
| subText.setTextColor(Color.RED); |
| break; |
| case WARNING: |
| // Orange |
| subText.setTextColor(Color.rgb(255,192,0)); |
| break; |
| case TIP: |
| subText.setTextColor(Color.BLUE); |
| break; |
| default: |
| subText.setTextColor(Color.LTGRAY); |
| break; |
| } |
| return view; |
| } |
| |
| } |
| } |
| } |