diff options
Diffstat (limited to 'WordPress/src/main/java/org/wordpress/android/ui/posts/SelectCategoriesActivity.java')
-rw-r--r-- | WordPress/src/main/java/org/wordpress/android/ui/posts/SelectCategoriesActivity.java | 415 |
1 files changed, 415 insertions, 0 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/SelectCategoriesActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/SelectCategoriesActivity.java new file mode 100644 index 000000000..aedf94767 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/SelectCategoriesActivity.java @@ -0,0 +1,415 @@ +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(); + } +} |