| package org.wordpress.android.ui.posts; |
| |
| import android.app.Activity; |
| import android.content.Intent; |
| import android.os.Bundle; |
| import android.os.Handler; |
| import android.support.v7.app.ActionBar; |
| import android.support.v7.app.AppCompatActivity; |
| import android.util.SparseBooleanArray; |
| import android.view.Menu; |
| import android.view.MenuInflater; |
| import android.view.MenuItem; |
| import android.view.View; |
| import android.widget.AdapterView; |
| import android.widget.ListView; |
| import android.widget.TextView; |
| import android.widget.Toast; |
| |
| import org.wordpress.android.R; |
| import org.wordpress.android.WordPress; |
| import org.wordpress.android.models.Blog; |
| import org.wordpress.android.models.CategoryNode; |
| import org.wordpress.android.util.AppLog; |
| import org.wordpress.android.util.NetworkUtils; |
| import org.wordpress.android.util.StringUtils; |
| import org.wordpress.android.util.ToastUtils; |
| import org.wordpress.android.util.ToastUtils.Duration; |
| import org.wordpress.android.util.helpers.ListScrollPositionManager; |
| import org.wordpress.android.util.helpers.SwipeToRefreshHelper; |
| import org.wordpress.android.util.helpers.SwipeToRefreshHelper.RefreshListener; |
| import org.wordpress.android.util.widgets.CustomSwipeRefreshLayout; |
| import org.xmlpull.v1.XmlPullParserException; |
| import org.xmlrpc.android.ApiHelper.Method; |
| import org.xmlrpc.android.XMLRPCClientInterface; |
| import org.xmlrpc.android.XMLRPCException; |
| import org.xmlrpc.android.XMLRPCFactory; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| |
| public class SelectCategoriesActivity extends AppCompatActivity { |
| String finalResult = ""; |
| private final Handler mHandler = new Handler(); |
| private Blog blog; |
| private ListView mListView; |
| private TextView mEmptyView; |
| private ListScrollPositionManager mListScrollPositionManager; |
| private SwipeToRefreshHelper mSwipeToRefreshHelper; |
| private HashSet<String> mSelectedCategories; |
| private CategoryNode mCategories; |
| private ArrayList<CategoryNode> mCategoryLevels; |
| private Map<String, Integer> mCategoryNames = new HashMap<String, Integer>(); |
| XMLRPCClientInterface mClient; |
| |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| setContentView(R.layout.select_categories); |
| setTitle(getResources().getString(R.string.select_categories)); |
| |
| ActionBar actionBar = getSupportActionBar(); |
| if (actionBar != null) { |
| actionBar.setHomeButtonEnabled(true); |
| actionBar.setDisplayHomeAsUpEnabled(true); |
| } |
| |
| mListView = (ListView)findViewById(android.R.id.list); |
| mListScrollPositionManager = new ListScrollPositionManager(mListView, false); |
| mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); |
| mListView.setItemsCanFocus(false); |
| |
| mEmptyView = (TextView) findViewById(R.id.empty_view); |
| mListView.setEmptyView(mEmptyView); |
| |
| mListView.setOnItemClickListener(new AdapterView.OnItemClickListener(){ |
| @Override |
| public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { |
| if (getCheckedItemCount(mListView) > 1) { |
| boolean uncategorizedNeedToBeSelected = false; |
| for (int i = 0; i < mCategoryLevels.size(); i++) { |
| if (mCategoryLevels.get(i).getName().equalsIgnoreCase("uncategorized")) { |
| mListView.setItemChecked(i, uncategorizedNeedToBeSelected); |
| } |
| } |
| } |
| } |
| }); |
| |
| mSelectedCategories = new HashSet<String>(); |
| |
| Bundle extras = getIntent().getExtras(); |
| if (extras != null) { |
| int blogId = extras.getInt("id"); |
| blog = WordPress.wpDB.instantiateBlogByLocalId(blogId); |
| if (blog == null) { |
| Toast.makeText(this, getResources().getText(R.string.blog_not_found), Toast.LENGTH_SHORT).show(); |
| finish(); |
| } |
| if (extras.containsKey("categories")) { |
| mSelectedCategories = (HashSet<String>) extras.getSerializable("categories"); |
| } |
| } |
| if (mSelectedCategories == null) { |
| mSelectedCategories = new HashSet<String>(); |
| } |
| |
| // swipe to refresh setup |
| mSwipeToRefreshHelper = new SwipeToRefreshHelper(this, (CustomSwipeRefreshLayout) findViewById(R.id.ptr_layout), |
| new RefreshListener() { |
| @Override |
| public void onRefreshStarted() { |
| if (!NetworkUtils.checkConnection(getBaseContext())) { |
| mSwipeToRefreshHelper.setRefreshing(false); |
| return; |
| } |
| refreshCategories(); |
| } |
| }); |
| |
| populateCategoryList(); |
| |
| if (NetworkUtils.isNetworkAvailable(this)) { |
| mEmptyView.setText(R.string.empty_list_default); |
| if (isCategoryListEmpty()) { |
| refreshCategories(); |
| } |
| } else { |
| mEmptyView.setText(R.string.no_network_title); |
| } |
| } |
| |
| private boolean isCategoryListEmpty() { |
| if (mListView.getAdapter() != null) { |
| return mListView.getAdapter().isEmpty(); |
| } else { |
| return true; |
| } |
| } |
| |
| private void populateCategoryList() { |
| mCategories = CategoryNode.createCategoryTreeFromDB(blog.getLocalTableBlogId()); |
| mCategoryLevels = CategoryNode.getSortedListOfCategoriesFromRoot(mCategories); |
| for (int i = 0; i < mCategoryLevels.size(); i++) { |
| mCategoryNames.put(StringUtils.unescapeHTML(mCategoryLevels.get(i).getName()), i); |
| } |
| |
| CategoryArrayAdapter categoryAdapter = new CategoryArrayAdapter(this, R.layout.categories_row, mCategoryLevels); |
| mListView.setAdapter(categoryAdapter); |
| if (mSelectedCategories != null) { |
| for (String selectedCategory : mSelectedCategories) { |
| if (mCategoryNames.keySet().contains(selectedCategory)) { |
| mListView.setItemChecked(mCategoryNames.get(selectedCategory), true); |
| } |
| } |
| } |
| mListScrollPositionManager.restoreScrollOffset(); |
| } |
| |
| final Runnable mUpdateResults = new Runnable() { |
| public void run() { |
| mSwipeToRefreshHelper.setRefreshing(false); |
| if (finalResult.equals("addCategory_success")) { |
| populateCategoryList(); |
| if (!isFinishing()) { |
| ToastUtils.showToast(SelectCategoriesActivity.this, R.string.adding_cat_success, Duration.SHORT); |
| } |
| } else if (finalResult.equals("addCategory_failed")) { |
| if (!isFinishing()) { |
| ToastUtils.showToast(SelectCategoriesActivity.this, R.string.adding_cat_failed, Duration.LONG); |
| } |
| } else if (finalResult.equals("gotCategories")) { |
| populateCategoryList(); |
| } else if (finalResult.equals("FAIL")) { |
| if (!isFinishing()) { |
| ToastUtils.showToast(SelectCategoriesActivity.this, R.string.category_refresh_error, Duration.LONG); |
| } |
| } |
| } |
| }; |
| |
| /** |
| * Gets the categories via a xmlrpc call |
| * @return result message |
| */ |
| public String fetchCategories() { |
| String returnMessage; |
| Object result[] = null; |
| Object[] params = {blog.getRemoteBlogId(), blog.getUsername(), blog.getPassword(),}; |
| mClient = XMLRPCFactory.instantiate(blog.getUri(), blog.getHttpuser(), blog.getHttppassword()); |
| boolean success = false; |
| try { |
| result = (Object[]) mClient.call(Method.GET_CATEGORIES, params); |
| success = true; |
| } catch (XMLRPCException e) { |
| AppLog.e(AppLog.T.POSTS, e); |
| } catch (IOException e) { |
| AppLog.e(AppLog.T.POSTS, e); |
| } catch (XmlPullParserException e) { |
| AppLog.e(AppLog.T.POSTS, e); |
| } |
| |
| if (success) { |
| // wipe out the categories table |
| WordPress.wpDB.clearCategories(blog.getLocalTableBlogId()); |
| |
| for (Object aResult : result) { |
| Map<?, ?> curHash = (Map<?, ?>) aResult; |
| String categoryName = curHash.get("categoryName").toString(); |
| String categoryID = curHash.get("categoryId").toString(); |
| String categoryParentID = curHash.get("parentId").toString(); |
| int convertedCategoryID = Integer.parseInt(categoryID); |
| int convertedCategoryParentID = Integer.parseInt(categoryParentID); |
| WordPress.wpDB.insertCategory(blog.getLocalTableBlogId(), convertedCategoryID, convertedCategoryParentID, categoryName); |
| } |
| returnMessage = "gotCategories"; |
| } else { |
| returnMessage = "FAIL"; |
| } |
| return returnMessage; |
| } |
| |
| public String addCategory(final String category_name, String category_slug, String category_desc, int parent_id) { |
| // Return string |
| String returnString = "addCategory_failed"; |
| |
| // Save selected categories |
| updateSelectedCategoryList(); |
| mListScrollPositionManager.saveScrollOffset(); |
| |
| // Store the parameters for wp.addCategory |
| Map<String, Object> struct = new HashMap<String, Object>(); |
| struct.put("name", category_name); |
| struct.put("slug", category_slug); |
| struct.put("description", category_desc); |
| struct.put("parent_id", parent_id); |
| mClient = XMLRPCFactory.instantiate(blog.getUri(), blog.getHttpuser(), blog.getHttppassword()); |
| Object[] params = { blog.getRemoteBlogId(), blog.getUsername(), blog.getPassword(), struct }; |
| |
| Object result = null; |
| try { |
| result = mClient.call(Method.NEW_CATEGORY, params); |
| } catch (XMLRPCException e) { |
| AppLog.e(AppLog.T.POSTS, e); |
| } catch (IOException e) { |
| AppLog.e(AppLog.T.POSTS, e); |
| } catch (XmlPullParserException e) { |
| AppLog.e(AppLog.T.POSTS, e); |
| } |
| |
| if (result != null) { |
| // Category successfully created. "result" is the ID of the new category |
| // Initialize the category database |
| // Convert "result" (= category_id) from type Object to int |
| int category_id = Integer.parseInt(result.toString()); |
| |
| // Fetch canonical name, can't to do this asynchronously because the new category_name is needed for |
| // insertCategory |
| final String new_category_name = getCanonicalCategoryName(category_id); |
| if (new_category_name == null) { |
| return returnString; |
| } |
| final Activity that = this; |
| if (!new_category_name.equals(category_name)) { |
| mHandler.post(new Runnable() { |
| @Override |
| public void run() { |
| Toast.makeText(that, String.format(String.valueOf(getText(R.string.category_automatically_renamed)), |
| category_name, new_category_name), Toast.LENGTH_LONG).show(); |
| } |
| }); |
| } |
| |
| // Insert the new category into database |
| WordPress.wpDB.insertCategory(blog.getLocalTableBlogId(), category_id, parent_id, new_category_name); |
| returnString = "addCategory_success"; |
| // auto select new category |
| mSelectedCategories.add(new_category_name); |
| } |
| |
| return returnString; |
| } |
| |
| @Override |
| protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
| super.onActivityResult(requestCode, resultCode, data); |
| if (data != null) { |
| final Bundle extras = data.getExtras(); |
| |
| switch (requestCode) { |
| case 0: // Add category |
| // Does the user want to continue, or did he press "dismiss"? |
| if (extras.getString("continue").equals("TRUE")) { |
| // Get name, slug and desc from Intent |
| final String category_name = extras.getString("category_name"); |
| final String category_slug = extras.getString("category_slug"); |
| final String category_desc = extras.getString("category_desc"); |
| final int parent_id = extras.getInt("parent_id"); |
| |
| // Check if the category name already exists |
| if (!mCategoryNames.keySet().contains(category_name)) { |
| mSwipeToRefreshHelper.setRefreshing(true); |
| Thread th = new Thread() { |
| public void run() { |
| finalResult = addCategory(category_name, category_slug, category_desc, parent_id); |
| mHandler.post(mUpdateResults); |
| } |
| }; |
| th.start(); |
| } |
| break; |
| } |
| }// end null check |
| } |
| } |
| |
| @Override |
| public boolean onCreateOptionsMenu(Menu menu) { |
| super.onCreateOptionsMenu(menu); |
| MenuInflater inflater = getMenuInflater(); |
| inflater.inflate(R.menu.categories, menu); |
| return true; |
| } |
| |
| @Override |
| public boolean onOptionsItemSelected(final MenuItem item) { |
| int itemId = item.getItemId(); |
| if (itemId == R.id.menu_new_category) { |
| if (NetworkUtils.checkConnection(this)) { |
| Bundle bundle = new Bundle(); |
| bundle.putInt("id", blog.getLocalTableBlogId()); |
| Intent i = new Intent(SelectCategoriesActivity.this, AddCategoryActivity.class); |
| i.putExtras(bundle); |
| startActivityForResult(i, 0); |
| } |
| return true; |
| } else if (itemId == android.R.id.home) { |
| saveAndFinish(); |
| return true; |
| } |
| |
| return super.onOptionsItemSelected(item); |
| } |
| |
| private String getCanonicalCategoryName(int category_id) { |
| String new_category_name = null; |
| Map<?, ?> result = null; |
| Object[] params = { blog.getRemoteBlogId(), blog.getUsername(), blog.getPassword(), "category", category_id }; |
| mClient = XMLRPCFactory.instantiate(blog.getUri(), blog.getHttpuser(), blog.getHttppassword()); |
| try { |
| result = (Map<?, ?>) mClient.call(Method.GET_TERM, params); |
| } catch (XMLRPCException e) { |
| AppLog.e(AppLog.T.POSTS, e); |
| } catch (IOException e) { |
| AppLog.e(AppLog.T.POSTS, e); |
| } catch (XmlPullParserException e) { |
| AppLog.e(AppLog.T.POSTS, e); |
| } |
| |
| if (result != null) { |
| if (result.containsKey("name")) { |
| new_category_name = result.get("name").toString(); |
| } |
| } |
| return new_category_name; |
| } |
| |
| private void refreshCategories() { |
| mSwipeToRefreshHelper.setRefreshing(true); |
| mListScrollPositionManager.saveScrollOffset(); |
| updateSelectedCategoryList(); |
| Thread th = new Thread() { |
| public void run() { |
| finalResult = fetchCategories(); |
| mHandler.post(mUpdateResults); |
| } |
| }; |
| th.start(); |
| } |
| |
| @Override |
| public void onBackPressed() { |
| saveAndFinish(); |
| super.onBackPressed(); |
| } |
| |
| private void updateSelectedCategoryList() { |
| SparseBooleanArray selectedItems = mListView.getCheckedItemPositions(); |
| for (int i = 0; i < selectedItems.size(); i++) { |
| String currentName = StringUtils.unescapeHTML(mCategoryLevels.get(selectedItems.keyAt(i)).getName()); |
| if (selectedItems.get(selectedItems.keyAt(i))) { |
| mSelectedCategories.add(currentName); |
| } else { |
| mSelectedCategories.remove(currentName); |
| } |
| } |
| } |
| |
| private void saveAndFinish() { |
| Bundle bundle = new Bundle(); |
| updateSelectedCategoryList(); |
| bundle.putSerializable("selectedCategories", new ArrayList<String>(mSelectedCategories)); |
| Intent mIntent = new Intent(); |
| mIntent.putExtras(bundle); |
| setResult(RESULT_OK, mIntent); |
| finish(); |
| } |
| |
| private int getCheckedItemCount(ListView listView) { |
| return listView.getCheckedItemCount(); |
| } |
| } |