OSDN Git Service

Deprecate fill_parent and introduce match_parent.
[android-x86/packages-apps-Browser.git] / src / com / android / browser / AddBookmarkPage.java
1 /*
2  * Copyright (C) 2006 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.app.Activity;
20 import android.content.ContentResolver;
21 import android.content.Intent;
22 import android.content.res.Resources;
23 import android.database.Cursor;
24 import android.graphics.Bitmap;
25 import android.net.ParseException;
26 import android.net.WebAddress;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.os.Message;
30 import android.provider.Browser;
31 import android.view.View;
32 import android.view.Window;
33 import android.widget.EditText;
34 import android.widget.TextView;
35 import android.widget.Toast;
36
37 import java.net.URI;
38 import java.net.URISyntaxException;
39 import java.util.Date;
40
41 public class AddBookmarkPage extends Activity {
42
43     private final String LOGTAG = "Bookmarks";
44
45     private EditText    mTitle;
46     private EditText    mAddress;
47     private TextView    mButton;
48     private View        mCancelButton;
49     private boolean     mEditingExisting;
50     private Bundle      mMap;
51     private String      mTouchIconUrl;
52     private Bitmap      mThumbnail;
53     private String      mOriginalUrl;
54
55     // Message IDs
56     private static final int SAVE_BOOKMARK = 100;
57
58     private Handler mHandler;
59
60     private View.OnClickListener mSaveBookmark = new View.OnClickListener() {
61         public void onClick(View v) {
62             if (save()) {
63                 finish();
64             }
65         }
66     };
67
68     private View.OnClickListener mCancel = new View.OnClickListener() {
69         public void onClick(View v) {
70             finish();
71         }
72     };
73
74     protected void onCreate(Bundle icicle) {
75         super.onCreate(icicle);
76         requestWindowFeature(Window.FEATURE_LEFT_ICON);
77         setContentView(R.layout.browser_add_bookmark);
78         setTitle(R.string.save_to_bookmarks);
79         getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.ic_list_bookmark);
80         
81         String title = null;
82         String url = null;
83         mMap = getIntent().getExtras();
84         if (mMap != null) {
85             Bundle b = mMap.getBundle("bookmark");
86             if (b != null) {
87                 mMap = b;
88                 mEditingExisting = true;
89                 setTitle(R.string.edit_bookmark);
90             }
91             title = mMap.getString("title");
92             url = mOriginalUrl = mMap.getString("url");
93             mTouchIconUrl = mMap.getString("touch_icon_url");
94             mThumbnail = (Bitmap) mMap.getParcelable("thumbnail");
95         }
96
97         mTitle = (EditText) findViewById(R.id.title);
98         mTitle.setText(title);
99         mAddress = (EditText) findViewById(R.id.address);
100         mAddress.setText(url);
101
102         View.OnClickListener accept = mSaveBookmark;
103         mButton = (TextView) findViewById(R.id.OK);
104         mButton.setOnClickListener(accept);
105
106         mCancelButton = findViewById(R.id.cancel);
107         mCancelButton.setOnClickListener(mCancel);
108         
109         if (!getWindow().getDecorView().isInTouchMode()) {
110             mButton.requestFocus();
111         }
112     }
113
114     /**
115      * Runnable to save a bookmark, so it can be performed in its own thread.
116      */
117     private class SaveBookmarkRunnable implements Runnable {
118         private Message mMessage;
119         public SaveBookmarkRunnable(Message msg) {
120             mMessage = msg;
121         }
122         public void run() {
123             // Unbundle bookmark data.
124             Bundle bundle = mMessage.getData();
125             String title = bundle.getString("title");
126             String url = bundle.getString("url");
127             boolean invalidateThumbnail = bundle.getBoolean(
128                     "invalidateThumbnail");
129             Bitmap thumbnail = invalidateThumbnail ? null
130                     : (Bitmap) bundle.getParcelable("thumbnail");
131             String touchIconUrl = bundle.getString("touchIconUrl");
132
133             // Save to the bookmarks DB.
134             try {
135                 final ContentResolver cr = getContentResolver();
136                 Bookmarks.addBookmark(null, cr, url, title, thumbnail, true);
137                 if (touchIconUrl != null) {
138                     final Cursor c
139                             = BrowserBookmarksAdapter.queryBookmarksForUrl(cr,
140                             null, url, true);
141                     new DownloadTouchIcon(cr, c, url).execute(mTouchIconUrl);
142                 }
143                 mMessage.arg1 = 1;
144             } catch (IllegalStateException e) {
145                 mMessage.arg1 = 0;
146             }
147             mMessage.sendToTarget();
148         }
149     }
150
151     private void createHandler() {
152         if (mHandler == null) {
153             mHandler = new Handler() {
154                 @Override
155                 public void handleMessage(Message msg) {
156                     switch (msg.what) {
157                         case SAVE_BOOKMARK:
158                             if (1 == msg.arg1) {
159                                 Toast.makeText(AddBookmarkPage.this, R.string.bookmark_saved,
160                                         Toast.LENGTH_LONG).show();
161                             } else {
162                                 Toast.makeText(AddBookmarkPage.this, R.string.bookmark_not_saved,
163                                         Toast.LENGTH_LONG).show();
164                             }
165                             break;
166                     }
167                 }
168             };
169         }
170     }
171
172     /**
173      * Parse the data entered in the dialog and post a message to update the bookmarks database.
174      */
175     boolean save() {
176         createHandler();
177
178         String title = mTitle.getText().toString().trim();
179         String unfilteredUrl = 
180                 BrowserActivity.fixUrl(mAddress.getText().toString());
181         boolean emptyTitle = title.length() == 0;
182         boolean emptyUrl = unfilteredUrl.trim().length() == 0;
183         Resources r = getResources();
184         if (emptyTitle || emptyUrl) {
185             if (emptyTitle) {
186                 mTitle.setError(r.getText(R.string.bookmark_needs_title));
187             }
188             if (emptyUrl) {
189                 mAddress.setError(r.getText(R.string.bookmark_needs_url));
190             }
191             return false;
192         }
193         String url = unfilteredUrl.trim();
194         try {
195             // We allow bookmarks with a javascript: scheme, but these will in most cases
196             // fail URI parsing, so don't try it if that's the kind of bookmark we have.
197
198             if (!url.toLowerCase().startsWith("javascript:")) {
199                 URI uriObj = new URI(url);
200                 String scheme = uriObj.getScheme();
201                 if (!Bookmarks.urlHasAcceptableScheme(url)) {
202                     // If the scheme was non-null, let the user know that we
203                     // can't save their bookmark. If it was null, we'll assume
204                     // they meant http when we parse it in the WebAddress class.
205                     if (scheme != null) {
206                         mAddress.setError(r.getText(R.string.bookmark_cannot_save_url));
207                         return false;
208                     }
209                     WebAddress address;
210                     try {
211                         address = new WebAddress(unfilteredUrl);
212                     } catch (ParseException e) {
213                         throw new URISyntaxException("", "");
214                     }
215                     if (address.mHost.length() == 0) {
216                         throw new URISyntaxException("", "");
217                     }
218                     url = address.toString();
219                 }
220             }
221         } catch (URISyntaxException e) {
222             mAddress.setError(r.getText(R.string.bookmark_url_not_valid));
223             return false;
224         }
225
226         if (mEditingExisting) {
227             mMap.putString("title", title);
228             mMap.putString("url", url);
229             mMap.putBoolean("invalidateThumbnail", !url.equals(mOriginalUrl));
230             setResult(RESULT_OK, (new Intent()).setAction(
231                     getIntent().toString()).putExtras(mMap));
232         } else {
233             // Post a message to write to the DB.
234             Bundle bundle = new Bundle();
235             bundle.putString("title", title);
236             bundle.putString("url", url);
237             bundle.putParcelable("thumbnail", mThumbnail);
238             bundle.putBoolean("invalidateThumbnail", !url.equals(mOriginalUrl));
239             bundle.putString("touchIconUrl", mTouchIconUrl);
240             Message msg = Message.obtain(mHandler, SAVE_BOOKMARK);
241             msg.setData(bundle);
242             // Start a new thread so as to not slow down the UI
243             Thread t = new Thread(new SaveBookmarkRunnable(msg));
244             t.start();
245             setResult(RESULT_OK);
246         }
247         return true;
248     }
249 }