Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1178)

Side by Side Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/bookmark/SelectBookmarkFolderFragment.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser.bookmark;
6
7 import static org.chromium.chrome.browser.ChromeBrowserProviderClient.INVALID_BO OKMARK_ID;
8
9 import android.content.Context;
10 import android.content.res.Resources;
11 import android.graphics.Typeface;
12 import android.graphics.drawable.BitmapDrawable;
13 import android.os.Bundle;
14 import android.util.Log;
15 import android.view.LayoutInflater;
16 import android.view.View;
17 import android.view.View.OnClickListener;
18 import android.view.ViewGroup;
19 import android.widget.ArrayAdapter;
20 import android.widget.Button;
21 import android.widget.ListView;
22 import android.widget.TextView;
23
24 import com.google.android.apps.chrome.R;
25
26 import org.chromium.base.ApiCompatibilityUtils;
27 import org.chromium.base.VisibleForTesting;
28 import org.chromium.chrome.browser.ChromeBrowserProvider.BookmarkNode;
29 import org.chromium.chrome.browser.ChromeBrowserProvider.Type;
30 import org.chromium.chrome.browser.ChromeBrowserProviderClient;
31 import org.chromium.chrome.browser.widget.TintedDrawable;
32 import org.chromium.sync.AndroidSyncSettings;
33 import org.chromium.ui.base.LocalizationUtils;
34
35 /**
36 * The user interface for selecting a bookmark folder.
37 */
38 public class SelectBookmarkFolderFragment extends AsyncTaskFragment implements O nClickListener {
39 /**
40 * Defines the constants used as arguments to this fragment.
41 * @see android.app.Fragment#setArguments(Bundle)
42 */
43 private static class Arguments {
44 private Arguments() {}
45
46 public static final String ALLOW_FOLDER_ADDITION = "allowAdd";
47 public static final String FOLDER_ID_TO_SELECT = "selectedFolder";
48 public static final String IS_FOLDER = "isFolder";
49 }
50
51 private Button mNewFolderButton;
52
53 private ListView mFoldersList;
54 private FolderListAdapter mFoldersAdapter;
55 private TextView mEmptyFoldersView;
56
57 private boolean mAllowFolderAddition;
58 private long mFolderIdToSelect;
59 // Used to determine if a bookmark's or a folder's parent is being changed.
60 private boolean mIsFolder;
61
62 private OnActionListener mActionListener;
63
64 /**
65 * The maximum depth that will be indented. Folders with a depth greater th an this will
66 * all appear at this same depth.
67 */
68 private int mMaximumFolderIndentDepth = 8;
69
70 /**
71 * Constructs a new fragment in charge of handling bookmark folder selection .
72 * @param allowFolderAddition Whether this fragment should allow additional folders to be added
73 * as children.
74 * @param folderIdToSelect The ID of the folder to select when shown initial ly.
75 * @return The selection fragment.
76 */
77 public static SelectBookmarkFolderFragment newInstance(
78 boolean allowFolderAddition, long folderIdToSelect, boolean isFolder ) {
79 SelectBookmarkFolderFragment fragment = new SelectBookmarkFolderFragment ();
80 Bundle arguments = new Bundle();
81 arguments.putBoolean(Arguments.ALLOW_FOLDER_ADDITION, allowFolderAdditio n);
82 arguments.putLong(Arguments.FOLDER_ID_TO_SELECT, folderIdToSelect);
83 arguments.putBoolean(Arguments.IS_FOLDER, isFolder);
84 fragment.setArguments(arguments);
85 return fragment;
86 }
87
88 /**
89 * Retrieves the current action listener for this fragment.
90 * Used by testing to intercept calls as a proxy.
91 */
92 @VisibleForTesting
93 public OnActionListener getOnActionListenerForTest() {
94 return mActionListener;
95 }
96
97 /**
98 * Sets the action listener for this fragment.
99 * @param listener The listener to be set.
100 */
101 public void setOnActionListener(OnActionListener listener) {
102 mActionListener = listener;
103 }
104
105 @Override
106 public void onCreate(Bundle savedInstanceState) {
107 super.onCreate(savedInstanceState);
108
109 mAllowFolderAddition = getArguments().getBoolean(Arguments.ALLOW_FOLDER_ ADDITION);
110 mFolderIdToSelect = getArguments().getLong(
111 Arguments.FOLDER_ID_TO_SELECT, INVALID_BOOKMARK_ID);
112 mIsFolder = getArguments().getBoolean(Arguments.IS_FOLDER);
113 }
114
115 @Override
116 public View onCreateView(LayoutInflater inflater, ViewGroup container,
117 Bundle savedInstanceState) {
118 View contentView = inflater.inflate(R.layout.select_bookmark_folder, con tainer, false);
119
120 mNewFolderButton = (Button) contentView.findViewById(R.id.new_folder_btn );
121 if (mAllowFolderAddition) {
122 mNewFolderButton.setOnClickListener(this);
123 } else {
124 mNewFolderButton.setVisibility(View.GONE);
125 }
126
127 mFoldersList = (ListView) contentView.findViewById(R.id.bookmark_folder_ list);
128 mEmptyFoldersView = (TextView) contentView.findViewById(R.id.empty_folde rs);
129 mFoldersList.setEmptyView(mEmptyFoldersView);
130
131 if (mFoldersAdapter != null) mFoldersList.setAdapter(mFoldersAdapter);
132 return contentView;
133 }
134
135 @Override
136 public void onActivityCreated(Bundle savedInstanceState) {
137 super.onActivityCreated(savedInstanceState);
138
139 if (mFoldersAdapter == null) {
140 mFoldersAdapter = new FolderListAdapter(getActivity().getApplication Context());
141 mFoldersList.setAdapter(mFoldersAdapter);
142
143 long selectedFolder = INVALID_BOOKMARK_ID;
144 if (savedInstanceState == null) {
145 // Only use the folder ID passed in from the intent if the activ ity is not being
146 // restored. During restoration, the ListView will handle resel ecting the
147 // previously selected entity and we do not want to override tha t with the initial
148 // value.
149 selectedFolder = mFolderIdToSelect;
150 }
151
152 loadAllFolders(selectedFolder);
153 } else {
154 if (!areFoldersLoaded()) {
155 loadAllFolders(mFolderIdToSelect);
156 }
157 }
158
159 mMaximumFolderIndentDepth =
160 getResources().getInteger(R.integer.select_bookmark_folder_max_d epth_indent);
161 }
162
163 @Override
164 public void onClick(View v) {
165 if (mActionListener == null) {
166 Log.d(getClass().getName(), "No OnResultListener specified -- onClic k == NoOp");
167 return;
168 }
169 if (v == mNewFolderButton) {
170 long parentId = INVALID_BOOKMARK_ID;
171 String parentName = null;
172 for (int i = 0; i < mFoldersAdapter.getCount(); i++) {
173 FolderListEntry selectedFolder = mFoldersAdapter.getItem(i);
174 if (selectedFolder.mFolder.id() == mFolderIdToSelect) {
175 parentId = selectedFolder.mFolder.id();
176 parentName = selectedFolder.mFolder.name();
177 }
178 }
179 mActionListener.triggerNewFolderCreation(parentId, parentName);
180 }
181 }
182
183 /**
184 * @return Whether or not the bookmark folders have been loaded asynchronous ly yet.
185 */
186 @VisibleForTesting
187 public boolean areFoldersLoaded() {
188 return mFoldersAdapter.getCount() > 0;
189 }
190
191 private void loadAllFolders(long folderId) {
192 if (isFragmentAsyncTaskRunning()) return;
193 runFragmentAsyncTask(new LoadAllFoldersTask(folderId),
194 getActivity().getString(R.string.loading_bookmark));
195 }
196
197 private void handleLoadAllFolders(BookmarkNode result, long selectedFolderId ,
198 boolean syncEnabled) {
199 if (getActivity() == null || getActivity().isFinishing()) return;
200
201 mFoldersAdapter.clear();
202 if (result == null) {
203 mEmptyFoldersView.setText(R.string.bookmark_folder_tree_error);
204 } else {
205 mEmptyFoldersView.setText(R.string.no_bookmark_folders);
206
207 // The root node is just a placeholder, so directly add it's childre n.
208 for (BookmarkNode child : result.children()) {
209 if (!syncEnabled) {
210 Type type = child.type();
211 if (type == Type.BOOKMARK_BAR || type == Type.OTHER_NODE) {
212 continue;
213 }
214 }
215 addFolderItem(child, 0, selectedFolderId);
216 }
217 }
218 }
219
220 private void addFolderItem(BookmarkNode folder, int depth, long selectedFold erId) {
221 boolean isSelectedFolder = (folder.id() == selectedFolderId);
222 mFoldersAdapter.add(new FolderListEntry(folder, depth, isSelectedFolder) );
223 // Hiding sub folders will prevent current folder to be moved under a su b folder.
224 if (folder.id() != selectedFolderId || !mIsFolder) {
225 for (BookmarkNode child : folder.children()) {
226 addFolderItem(child, depth + 1, selectedFolderId);
227 }
228 }
229 }
230
231 /**
232 * Data object used in the list adapter.
233 */
234 private static class FolderListEntry {
235 final BookmarkNode mFolder;
236 final int mDepth;
237 final boolean mIsSelectedFolder;
238
239 FolderListEntry(BookmarkNode folder, int depth, boolean isSelectedFolder ) {
240 mFolder = folder;
241 mDepth = depth;
242 mIsSelectedFolder = isSelectedFolder;
243 }
244
245 @Override
246 public String toString() {
247 return mFolder.name();
248 }
249 }
250
251 /**
252 * List adapter for the folder selection view.
253 */
254 private class FolderListAdapter extends ArrayAdapter<FolderListEntry> {
255 private final int mDefaultPaddingLeft;
256 private final int mPaddingLeftInc;
257
258 public FolderListAdapter(Context context) {
259 super(context, R.layout.select_bookmark_folder_item);
260
261 Resources resources = context.getResources();
262 mDefaultPaddingLeft =
263 resources.getDimensionPixelSize(R.dimen.select_bookmark_fold er_item_left);
264 mPaddingLeftInc =
265 resources.getDimensionPixelSize(R.dimen.select_bookmark_fold er_item_inc_left);
266 }
267
268 @Override
269 public View getView(int position, View convertView, ViewGroup parent) {
270 TextView view = (TextView) super.getView(position, convertView, pare nt);
271 final FolderListEntry entry = getItem(position);
272
273 BitmapDrawable icon = TintedDrawable.constructTintedDrawable(
274 getResources(), R.drawable.eb_others);
275 ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBound s(
276 view, icon, null, null, null);
277
278 // TODO: For folders that exceed the maximum depth, come up with a U I treatment to
279 // give some indication of that.
280 int paddingLeft = mDefaultPaddingLeft
281 + Math.min(entry.mDepth, mMaximumFolderIndentDepth) * mPaddi ngLeftInc;
282 if (LocalizationUtils.isLayoutRtl()) {
283 view.setPadding(0, 0, paddingLeft, 0);
284 } else {
285 view.setPadding(paddingLeft, 0, 0, 0);
286 }
287 view.setTypeface(null, entry.mIsSelectedFolder ? Typeface.BOLD : Typ eface.NORMAL);
288 view.setBackgroundResource(R.drawable.btn_bg_holo);
289 view.setOnClickListener(new OnClickListener() {
290 @Override
291 public void onClick(View v) {
292 executeFolderSelection(entry.mFolder.id(), entry.mFolder.nam e());
293 }
294 });
295 return view;
296 }
297
298 @Override
299 public long getItemId(int position) {
300 return getCount() > 0 ? getItem(position).mFolder.id() : -1;
301 }
302
303 @Override
304 public boolean hasStableIds() {
305 return true;
306 }
307 }
308
309 /**
310 * Select the folder to be used for the Add/Edit Fragment.
311 * @param folderId Id of the selected folder.
312 * @param folderName Name of the selected folder.
313 */
314 public void executeFolderSelection(long folderId, String folderName) {
315 getFragmentManager().popBackStackImmediate();
316 ((AddEditBookmarkFragment) getTargetFragment()).setParentFolderInfo(
317 folderId, folderName);
318 }
319
320 /**
321 * Asynchronously retrieves all the bookmark folders that the user can edit,
322 * showing a progress dialog if the task takes too long.
323 */
324 private class LoadAllFoldersTask extends FragmentAsyncTask {
325 private final Context mContext;
326 private final long mFolderId;
327 private BookmarkNode mResult;
328
329 LoadAllFoldersTask(long folderId) {
330 mContext = getActivity().getApplicationContext();
331 mFolderId = folderId;
332 }
333
334 @Override
335 protected void runBackgroundTask() {
336 mResult = ChromeBrowserProviderClient.getEditableBookmarkFolderHiera rchy(mContext);
337 }
338
339 @Override
340 protected void onTaskFinished() {
341 handleLoadAllFolders(mResult, mFolderId, AndroidSyncSettings.isSyncE nabled(mContext));
342 }
343
344 @Override
345 protected void setDependentUIEnabled(boolean enabled) {
346 mNewFolderButton.setEnabled(enabled);
347 }
348 }
349
350 /**
351 * Listener to handle actions triggered by this fragment.
352 */
353 public static interface OnActionListener {
354 /**
355 * Triggered when the user asks to create a new subfolder.
356 * @param selectedFolderId The currently selected folder ID, which shoul d be used as the
357 * default parent of the newly added folder.
358 * @param selectedFolderName The currently selected folder name.
359 */
360 public void triggerNewFolderCreation(long selectedFolderId, String selec tedFolderName);
361 }
362 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698