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