package kr.kdev.dg1s.biowiki.ui.posts; import android.app.Activity; import android.content.Intent; import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.util.SparseBooleanArray; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast; import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.SherlockListActivity; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; import org.xmlpull.v1.XmlPullParserException; 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; import kr.kdev.dg1s.biowiki.BioWiki; import kr.kdev.dg1s.biowiki.R; import kr.kdev.dg1s.biowiki.models.Blog; import kr.kdev.dg1s.biowiki.models.CategoryNode; import kr.kdev.dg1s.biowiki.ui.PullToRefreshHelper; import kr.kdev.dg1s.biowiki.ui.PullToRefreshHelper.RefreshListener; import kr.kdev.dg1s.biowiki.util.AppLog; import kr.kdev.dg1s.biowiki.util.ListScrollPositionManager; import kr.kdev.dg1s.biowiki.util.NetworkUtils; import kr.kdev.dg1s.biowiki.util.StringUtils; import kr.kdev.dg1s.biowiki.util.ToastUtils; import uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout; public class SelectCategoriesActivity extends SherlockListActivity { final Runnable mUpdateResults = new Runnable() { public void run() { mPullToRefreshHelper.setRefreshing(false); if (finalResult.equals("addCategory_success")) { populateOrFetchCategories(); if (!isFinishing()) { ToastUtils.showToast(SelectCategoriesActivity.this, R.string.adding_cat_success, ToastUtils.Duration.SHORT); } } else if (finalResult.equals("addCategory_failed")) { if (!isFinishing()) { ToastUtils.showToast(SelectCategoriesActivity.this, R.string.adding_cat_failed, ToastUtils.Duration.LONG); } } else if (finalResult.equals("gotCategories")) { populateOrFetchCategories(); } else if (finalResult.equals("FAIL")) { if (!isFinishing()) { ToastUtils.showToast(SelectCategoriesActivity.this, R.string.category_refresh_error, ToastUtils.Duration.LONG); } } } }; private final Handler mHandler = new Handler(); public String categoryErrorMsg = ""; String finalResult = ""; XMLRPCClientInterface mClient; private Blog blog; private ListView mListView; private ListScrollPositionManager mListScrollPositionManager; private PullToRefreshHelper mPullToRefreshHelper; private HashSet<String> mSelectedCategories; private CategoryNode mCategories; private ArrayList<CategoryNode> mCategoryLevels; private Map<String, Integer> mCategoryNames = new HashMap<String, Integer>(); @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.select_categories); setTitle(getResources().getString(R.string.select_categories)); ActionBar actionBar = getSupportActionBar(); actionBar.setHomeButtonEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true); mListView = getListView(); mListScrollPositionManager = new ListScrollPositionManager(mListView, false); mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); mListView.setItemsCanFocus(false); 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"); try { blog = BioWiki.wpDB.instantiateBlogByLocalId(blogId); } catch (Exception e) { 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>(); } // pull to refresh setup mPullToRefreshHelper = new PullToRefreshHelper(this, (PullToRefreshLayout) findViewById(R.id.ptr_layout), new RefreshListener() { @Override public void onRefreshStarted(View view) { if (!NetworkUtils.checkConnection(getBaseContext())) { mPullToRefreshHelper.setRefreshing(false); return; } refreshCategories(); } } ); populateOrFetchCategories(); } private void populateCategoryList() { 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); this.setListAdapter(categoryAdapter); if (mSelectedCategories != null) { ListView lv = getListView(); for (String selectedCategory : mSelectedCategories) { if (mCategoryNames.keySet().contains(selectedCategory)) { lv.setItemChecked(mCategoryNames.get(selectedCategory), true); } } } mListScrollPositionManager.restoreScrollOffset(); } private void populateOrFetchCategories() { mCategories = CategoryNode.createCategoryTreeFromDB(blog.getLocalTableBlogId()); if (mCategories.getChildren().size() > 0) { populateCategoryList(); } else { mPullToRefreshHelper.setRefreshing(true); refreshCategories(); } } /** * 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("wp.getCategories", 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 BioWiki.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); BioWiki.wpDB.insertCategory(blog.getLocalTableBlogId(), convertedCategoryID, convertedCategoryParentID, categoryName); } returnMessage = "gotCategories"; } else { returnMessage = "FAIL"; } return returnMessage; } /** * function addCategory * * @param String category_name * @return * @description Adds a new blank_linearlayout */ 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("wp.newCategory", 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 blank_linearlayout // Initialize the blank_linearlayout 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 blank_linearlayout into database BioWiki.wpDB.insertCategory(blog.getLocalTableBlogId(), category_id, parent_id, new_category_name); returnString = "addCategory_success"; // auto select new blank_linearlayout 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 blank_linearlayout // 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 blank_linearlayout name already exists if (!mCategoryNames.keySet().contains(category_name)) { 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 = getSupportMenuInflater(); 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) { 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(), "blank_linearlayout", category_id}; mClient = XMLRPCFactory.instantiate(blog.getUri(), blog.getHttpuser(), blog.getHttppassword()); try { result = (Map<?, ?>) mClient.call("wp.getTerm", 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() { mListScrollPositionManager.saveScrollOffset(); updateSelectedCategoryList(); Thread th = new Thread() { public void run() { finalResult = fetchCategories(); mHandler.post(mUpdateResults); } }; th.start(); } @Override public void onConfigurationChanged(Configuration newConfig) { // ignore orientation change super.onConfigurationChanged(newConfig); } @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) { if (Build.VERSION.SDK_INT >= 11) { return listView.getCheckedItemCount(); } else { int count = 0; for (int i = listView.getCount() - 1; i >= 0; i--) if (listView.isItemChecked(i)) count++; return count; } } }